Пример #1
0
def ini_sort(and_keys):
    lines = ed.get_text_all().splitlines()
    if not lines: return
    lines = ini_sort_content(lines, and_keys)
    if not lines: return
    ed.set_text_all('\n'.join(lines))
    ed.set_caret(0, 0)
    msg_status(_('Sorted ini lines'))
Пример #2
0
def do_line_op(op, keep_blanks=False):

    res = get_input()
    if not res: return
    lines, is_all, line1, line2 = res

    if op == 'shuffle':
        lines = get_shuffle(lines)

    elif op == 'reverse':
        lines = reversed(lines)

    elif op == 'delete_blanks':
        lines = [s for s in lines if s.strip()]

    elif op == 'delete_blanks_adjacent':
        for i in reversed(range(len(lines))):
            if i > 0 and lines[i].strip() == '' and lines[i - 1].strip() == '':
                del lines[i]

    elif op == 'delete_dups':
        for i in range(len(lines) - 1, 0, -1):
            for j in range(i - 1, -1, -1):
                if lines[i] == lines[j]:
                    if lines[i] or not keep_blanks:
                        del lines[i]
                        break

    elif op == 'delete_dups_origins':
        dups = get_dups(lines, False)
        for i in reversed(range(len(lines))):
            if lines[i] in dups:
                del lines[i]

    elif op == 'delete_dups_adjacent':
        for i in reversed(range(len(lines))):
            if i > 0 and lines[i] == lines[i - 1]:
                del lines[i]

    else:
        msg_status(_('Unknown operation: ') + op)
        return

    set_output(lines, is_all, line1, line2)
    msg_status(_('Lines operation: ') + op)
Пример #3
0
def do_sort_emails():
    def _key(s):
        if not _ok_email(s):
            return ('', s)
        n = s.find('@')
        return (s[n:], s[:n])

    lines = [ed.get_text_line(i) for i in range(ed.get_line_count())]
    lines = [s for s in lines if s]

    ok = [s for s in lines if _ok_email(s)]
    if not ok:
        msg_status(_('No e-mails in text'))
        return

    lines = sorted(lines, key=_key)
    ed.set_text_all('\n'.join(lines) + '\n')
    msg_status(_('Sorted text as email list'))
Пример #4
0
def get_input():

    if ed.get_prop(PROP_RO): return

    max_cnt = 5000
    try:
        s = ini_read(fn_ini, op_section, 'max_lines', '')
        max_cnt = max(int(s), max_cnt)
    except:
        pass

    op_sort_all = ini_read(fn_ini, op_section, 'allow_all', '0') == '1'

    if ed.get_line_count() > max_cnt:
        msg_box(
            _('Document has too many lines. Plugin Sort will not work. Current value of option [sort] max_lines in "settings/plugins.ini" is %d.\n\nInstead of Sort plugin, use CudaText built-in commands: "(without undo) sort...".'
              ) % max_cnt, MB_OK + MB_ICONERROR)
        return

    is_all = False
    nlines = ed.get_line_count()
    line1, line2 = ed_get_sel_lines()

    if line1 < 0:
        if op_sort_all:
            is_all = True
        else:
            msg_status(_('Needed multiline selection'))
            return
    elif line1 >= line2:
        msg_status(_('Needed multiline selection'))
        return

    if is_all:
        lines = ed_get_text_all()
    else:
        #add last empty line
        if ed.get_text_line(nlines - 1) != '':
            ed.set_text_line(-1, '')
        lines = [ed.get_text_line(i) for i in range(line1, line2 + 1)]

    return lines, is_all, line1, line2
Пример #5
0
    def wrap_abbrev(self):

        if ed.get_prop(PROP_RO): return

        x0, y0, x1, y1 = ed.get_carets()[0]
        if (y0, x0) > (y1, x1):
            x0, y0, x1, y1 = x1, y1, x0, y0

        text_sel = ed.get_text_sel()
        if not text_sel:
            msg_status(_('Text not selected'))
            return

        abr = dlg_input(_('Emmet abbreviation:'), 'div')
        if not abr:
            return

        res = emmet(EMMET_WRAP, abr, get_syntax(), text_sel)
        if res:
            do_insert_result(x0, y0, x1, y1, res)
Пример #6
0
def do_extract_op(op):

    res = get_input()
    if not res: return
    lines, is_all, line1, line2 = res

    if op == 'dups':
        lines = get_dups(lines, False)
    elif op == 'dups_nocase':
        lines = get_dups(lines, True)
    elif op == 'unique':
        lines = get_uniq(lines)
    else:
        msg_status(_('Unknown operation: ') + op)
        return

    if not lines:
        msg_status(_('Cannot extract any lines'))
        return

    file_open('')
    ed_set_tab_title(op)
    ed_set_text_all(lines)
    msg_status(_('Extract lines: ') + op)
Пример #7
0
def do_expand_abbrev(abr):

    res = emmet(EMMET_EXPAND, abr, get_syntax())
    if res and res[0]:
        s = res[0]
        cnt = 0
        while True:
            n = s.find('|')
            if n < 0:
                break
            s = s[:n] + tabstop(cnt) + s[n + 1:]
            cnt += 1

        return s

    msg_status(_('Cannot expand Emmet abbreviation: ') + abr)
Пример #8
0
    def expand_ex(self, with_msg):

        abr = find_abr()
        if not abr:
            if with_msg:
                msg_status(_('Cannot find Emmet abbreviation'))
            return

        text = do_expand_abbrev(abr)
        if not text:
            return

        x0, y0, x1, y1 = ed.get_carets()[0]
        xstart = max(0, x0 - len(abr))

        do_insert_result(xstart, y0, x0, y0, text)
        return False
Пример #9
0
def do_sort(is_reverse,
            is_nocase,
            del_dups=False,
            del_blanks=True,
            is_numeric=False,
            offset1=-1,
            offset2=-1):

    res = get_input()
    if not res: return
    lines, is_all, line1, line2 = res

    if del_blanks:
        lines = [s for s in lines if s.strip()]
    if del_dups:
        lines = list(set(lines))

    def _key(item):
        s = item
        if is_nocase:
            s = s.lower()

        if (offset1 >= 0) or (offset2 >= 0):
            s = ed_convert_tabs_to_spaces(s)
            if offset2 >= 0: s = s[:offset2]
            if offset1 >= 0: s = s[offset1:]

        #numeric must be after offsets
        if is_numeric:
            num, text = get_num_and_text(s.lstrip())
            #print('parts "%s": %d %s' % (s, num, text))
            s = '%20.20d ' % num + text

        return s

    lines = sorted(lines, key=_key, reverse=is_reverse)
    set_output(lines, is_all, line1, line2)

    text = _('Sorted') \
        + (', '+_('all text') if is_all else '') \
        + (', '+_('reverse') if is_reverse else '') \
        + (', '+_('ignore case') if is_nocase else '') \
        + (', '+_('numeric') if is_numeric else '') \
        + (', '+_('offsets') + ' %d..%d' % (offset1, offset2) if (offset1>=0) or (offset2>=0) else '')
    msg_status(text)
Пример #10
0
    def __init__(self, do_expand, do_insert):

        self.do_expand = do_expand
        self.do_insert = do_insert

        self.h = dlg_proc(0, DLG_CREATE)
        dlg_proc(self.h,
                 DLG_PROP_SET,
                 prop={
                     'w': W_all,
                     'h': H_all,
                     'cap': _('Emmet preview dialog'),
                     'border': DBORDER_SIZE,
                     'w_min': 300,
                     'h_min': 150,
                 })

        n = dlg_proc(self.h, DLG_CTL_ADD, prop='label')
        dlg_proc(self.h,
                 DLG_CTL_PROP_SET,
                 index=n,
                 prop={
                     'name': 'label1',
                     'cap': _('Abbreviation:'),
                     'x': 6,
                     'y': 6,
                 })

        n = dlg_proc(self.h, DLG_CTL_ADD, prop='button')
        dlg_proc(
            self.h,
            DLG_CTL_PROP_SET,
            index=n,
            prop={
                'name': 'btn_ok',
                'y': 26,
                'w': 90,
                'a_r': ('', ']'),
                'a_l': None,
                'sp_r': 6,
                'cap': _('Insert'),
                'ex0': True,  #default for Enter
                'on_change': self.on_ok_click,
            })

        n = dlg_proc(self.h, DLG_CTL_ADD, prop='button')
        dlg_proc(self.h,
                 DLG_CTL_PROP_SET,
                 index=n,
                 prop={
                     'name': 'btn_copy',
                     'a_l': ('btn_ok', '['),
                     'a_r': ('btn_ok', ']'),
                     'a_t': ('btn_ok', ']'),
                     'sp_t': 6,
                     'cap': _('Copy'),
                     'on_change': self.on_copy_click,
                 })

        n = dlg_proc(self.h, DLG_CTL_ADD, prop='edit')
        dlg_proc(self.h,
                 DLG_CTL_PROP_SET,
                 index=n,
                 prop={
                     'name': 'input',
                     'x': 6,
                     'y': 26,
                     'a_r': ('btn_ok', '['),
                     'sp_r': 6,
                     'act': True,
                     'on_change': self.on_edit_change,
                     'tab_order': 0,
                 })

        n = dlg_proc(self.h, DLG_CTL_ADD, prop='memo')
        dlg_proc(
            self.h,
            DLG_CTL_PROP_SET,
            index=n,
            prop={
                'name': 'preview',
                'ex0': True,  #read only
                'a_l': ('', '['),
                'a_t': ('input', ']'),
                'a_r': ('input', ']'),
                'a_b': ('', ']'),
                'sp_t': 6,
                'sp_b': 6,
                'sp_l': 6,
            })
Пример #11
0
    def help(self):

        webbrowser.open_new_tab('file://' + filename_help)
        msg_status(_('Opened browser'))
Пример #12
0
def do_dialog():
    size_x = 330
    size_y = 240
    id_rev = 0
    id_nocase = 1
    id_del_dup = 2
    id_del_sp = 3
    id_numeric = 4
    id_offset1 = 7
    id_offset2 = 9
    id_ok = 10

    op_rev = ini_read(fn_ini, op_section, 'reverse', '0')
    op_nocase = ini_read(fn_ini, op_section, 'ignore_case', '0')
    op_del_dup = ini_read(fn_ini, op_section, 'del_dups', '1')
    op_del_sp = ini_read(fn_ini, op_section, 'del_blanks', '1')
    op_numeric = ini_read(fn_ini, op_section, 'numeric', '0')

    op_offset1, op_offset2 = get_offsets()

    c1 = chr(1)
    text = '\n'.join([
        c1.join([
            'type=check', 'pos=6,6,300,0',
            'cap=' + _('&Sort descending (reverse)'), 'val=' + op_rev
        ]),
        c1.join([
            'type=check', 'pos=6,30,300,0', 'cap=' + _('&Ignore case'),
            'val=' + op_nocase
        ]),
        c1.join([
            'type=check', 'pos=6,54,300,0',
            'cap=' + _('Delete d&uplicate lines'), 'val=' + op_del_dup
        ]),
        c1.join([
            'type=check', 'pos=6,78,300,0', 'cap=' + _('Delete &blank lines'),
            'val=' + op_del_sp
        ]),
        c1.join([
            'type=check', 'pos=6,102,300,0',
            'cap=' + _('Numeric (treat beginning as number)'),
            'val=' + op_numeric
        ]),
        c1.join([
            'type=label', 'pos=6,130,300,0',
            'cap=' + _('Sort only by substring, offsets 0-based:')
        ]),
        c1.join(['type=label', 'pos=30,152,130,0', 'cap=' + _('&From:')]),
        c1.join([
            'type=spinedit', 'pos=30,170,110,0', 'props=-1,5000,1',
            'val=' + str(op_offset1)
        ]),
        c1.join(['type=label', 'pos=120,152,230,0', 'cap=' + _('&To:')]),
        c1.join([
            'type=spinedit', 'pos=120,170,200,0', 'props=-1,5000,1',
            'val=' + str(op_offset2)
        ]),
        c1.join(
            ['type=button', 'pos=60,210,160,0', 'cap=' + _('OK'), 'props=1']),
        c1.join(['type=button', 'pos=164,210,264,0', 'cap=' + _('Cancel')]),
    ])

    res = dlg_custom(_('Sort'), size_x, size_y, text)
    if res is None: return
    btn, text = res
    if btn != id_ok: return
    text = text.splitlines()

    ini_write(fn_ini, op_section, 'reverse', text[id_rev])
    ini_write(fn_ini, op_section, 'ignore_case', text[id_nocase])
    ini_write(fn_ini, op_section, 'del_dups', text[id_del_dup])
    ini_write(fn_ini, op_section, 'del_blanks', text[id_del_sp])
    ini_write(fn_ini, op_section, 'numeric', text[id_numeric])

    is_rev = text[id_rev] == '1'
    is_nocase = text[id_nocase] == '1'
    is_del_dup = text[id_del_dup] == '1'
    is_del_sp = text[id_del_sp] == '1'
    is_numeric = text[id_numeric] == '1'
    offset1 = int(text[id_offset1])
    offset2 = int(text[id_offset2])

    if (offset1 >= 0) and (offset2 >= 0) and (offset1 >= offset2):
        msg_show_error(_('Incorrect offsets: {}..{}').format(offset1, offset2))
        return

    return (is_rev, is_nocase, is_del_dup, is_del_sp, is_numeric, offset1,
            offset2)