Пример #1
0
    def duplicate(self):
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(DUPLICATION))

        crts = ed.get_carets()
        if len(crts) > 1:
            return app.msg_status(ONLY_SINGLE_CRT.format(DUPLICATION))

        (cCrt, rCrt, cEnd, rEnd) = crts[0]
        bEmpSel = -1 == rEnd
        bUseFLn = get_opt('duplicate_full_line_if_no_sel', True)
        bSkip = get_opt('duplicate_move_down', True)
        if bEmpSel:
            if not bUseFLn:
                return
            # Dup whole row
            row_txt = ed.get_text_line(rCrt)
            ed.insert(0, rCrt, row_txt + '\n')

            # Move crt to next row
            if bSkip and (rCrt + 1) < ed.get_line_count():
                _move_caret_down(cCrt, rCrt)
            return

        (rFr, cFr), (rTo, cTo) = minmax((rCrt, cCrt), (rEnd, cEnd))
        pass
        #LOG and log('(cFr , rFr , cTo , rTo) ={}',(cFr , rFr , cTo , rTo))
        sel_txt = ed.get_text_substr(cFr, rFr, cTo, rTo)
        pass
        #LOG and log('sel_txt={}',repr(sel_txt))
        ed.insert(cFr, rFr, sel_txt)
Пример #2
0
 def _jump_to_ibm(self, what):
     ibms,   \
     msg     = self._ibms_in_tab(ed, self.bm_signs)
     if not ibms and msg: return app.msg_status(msg)
     if not ibms: return app.msg_status(_('No in-text bookmarks'))
     rCrt = ed.get_carets()[0][1]
     if  1==len(ibms) \
     and rCrt==ibms[0][1]:
         return app.msg_status(_('No more bookmarks'))
     line_ns = [
         line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms
     ]
     if self.wrap:
         line_ns = [-line_ns[-1]] + line_ns + [line_ns[0] + 0xFFFFFFFF]
     line_cns = [
         line_n for line_n in line_ns
         if (line_n > rCrt if what == 'next' else line_n < rCrt)
     ]
     if not line_cns: return app.msg_status(_('No bookmark for jump'))
     line_n = min(line_cns) if what == 'next' else max(line_cns)
     line_n = -line_n if line_n < 0 else line_n
     line_n = line_n - 0xFFFFFFFF if line_n >= 0xFFFFFFFF else line_n
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(
             app.PROP_LINE_BOTTOM)):
         ed.set_prop(
             app.PROP_LINE_TOP,
             str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Пример #3
0
    def duplicate(self):
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(DUPLICATION))

        crts    = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format(DUPLICATION))

        (cCrt, rCrt, cEnd, rEnd)    = crts[0]
        if -1==cEnd:
            # Empty sel -- dup whole row
            row_txt    = ed.get_text_line(rCrt)
            ed.insert(0, rCrt, row_txt+'\n')

            # Move crt to next row
            if (rCrt+1)<ed.get_line_count():
                colCrt  = pos2pos(cCrt  , rCrt,   'smb2col')
                smbCrt1 = pos2pos(colCrt, rCrt+1, 'col2smb')
                ed.set_caret(smbCrt1, rCrt+1)
            return

        (rFr, cFr), (rTo, cTo)  = minmax((rCrt, cCrt), (rEnd, cEnd))
        #pass;                   LOG and log('(cCrt, rCrt, cEnd, rEnd)={}',(cCrt, rCrt, cEnd, rEnd))
        pass;                   LOG and log('(cFr , rFr , cTo , rTo) ={}',(cFr , rFr , cTo , rTo))
        sel_txt = ed.get_text_substr(cFr, rFr, cTo, rTo)
        pass;                   LOG and log('sel_txt={}',repr(sel_txt))
        ed.insert(cFr, rFr, sel_txt)
        if -1==rEnd: # or rCrt==rEnd:
            # Move crt to next row
            colCrt  = pos2pos(cCrt  , rCrt,   'smb2col')
            smbCrt1 = pos2pos(colCrt, rCrt+1, 'col2smb')
            ed.set_caret(smbCrt1, rCrt+1)
Пример #4
0
 def dlg_ibms_in_tab(self):
     ibms,   \
     msg     = self._ibms_in_tab(ed, self.bm_signs)
     if not ibms and msg:    return app.msg_status(msg)
     if not ibms:            return app.msg_status(_('No in-text bookmarks'))
     line_max= max([line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms])
     ln_wd   = len(str(line_max))
     pass;                  #LOG and log('ln_wd={}',(ln_wd))
     ibms    = [(bm_msg, line_n, f('{} {}', str(1+line_n).rjust(ln_wd, ' '), line_s)) 
             for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     pass;                  #LOG and log('ibms=¶{}',pf(ibms))
     rCrt    = ed.get_carets()[0][1]
     near    = min([(abs(line_n-rCrt), ind) 
             for ind, (bm_msg, line_n, line_s) in enumerate(ibms)])[1]
     if self.show_wo_alt:
         ans = app.dlg_menu(app.MENU_LIST, '\n'.join(
                 [f('{}\t{}', line_nd, bm_msg) for bm_msg, line_n, line_nd in ibms]
             ), near)
     else:
         ans = app.dlg_menu(app.MENU_LIST_ALT, '\n'.join(
                 [f('{}\t{}', bm_msg, line_nd) for bm_msg, line_n, line_nd in ibms]
             ), near)
     if ans is None:     return
     bm_msg, line_n, line_nd    = ibms[ans]
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(app.PROP_LINE_BOTTOM)):
         ed.set_prop(app.PROP_LINE_TOP, str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Пример #5
0
 def replace_all_sel_to_cb(self):
     pass;                   LOG and log('ok',)
     pass;                   return
     crts    = ed.get_carets()
     if len(crts)>1:
         return app.msg_status(ONLY_SINGLE_CRT.format('Command'))
     (cCrt, rCrt, cEnd, rEnd)    = crts[0]
    def do_conv(self, mode):
        carets = ed.get_carets()
        num_carets = len(carets)
        num_formats = 0

        for caret in carets:
            x, y, nlen, text = get_word_info(caret)

            if text == "" and num_carets == 1:
                msg_status("Place caret under a word")
                return

            if text == "":
                continue

            text2 = do_conv_string(text, mode)

            if text == text2 and num_carets == 1:
                msg_status("Word is already formatted: " + MODES_STR[mode])
                return

            if text == text2:
                continue

            ed.replace(x, y, x + nlen, y, text2)
            ed.set_caret(x, y, x + len(text2), y, app.CARET_ADD)
            num_formats += 1

        msg_status(
            str(num_formats) + " " +
            ("word" if num_formats <= 1 else "carets") + " formatted: " +
            MODES_STR[mode])
Пример #7
0
    def duplicate(self):
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(DUPLICATION))

        crts    = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format(DUPLICATION))

        (cCrt, rCrt, cEnd, rEnd)    = crts[0]
        bEmpSel = -1==rEnd
        bUseFLn = get_opt('duplicate_full_line_if_no_sel', True)
        bSkip   = get_opt('duplicate_move_down', True)
        if bEmpSel:
            if not bUseFLn:
                return
            # Dup whole row
            row_txt    = ed.get_text_line(rCrt)
            ed.insert(0, rCrt, row_txt+'\n')

            # Move crt to next row
            if bSkip and (rCrt+1)<ed.get_line_count():
                _move_caret_down(cCrt, rCrt)
            return

        (rFr, cFr), (rTo, cTo)  = minmax((rCrt, cCrt), (rEnd, cEnd))
        pass;                  #LOG and log('(cFr , rFr , cTo , rTo) ={}',(cFr , rFr , cTo , rTo))
        sel_txt = ed.get_text_substr(cFr, rFr, cTo, rTo)
        pass;                  #LOG and log('sel_txt={}',repr(sel_txt))
        ed.insert(cFr, rFr, sel_txt)
Пример #8
0
    def _subst(self, which, wdex):
        """ Do completion.
            Params
                which   Which variant to use
                            'next' / 'prev' / '#N'
                wdex    What list to use
                            'word' / 'expr' / 'curr'
        """
        pass
        #LOG and log('which, wdex={}',(which, wdex))
        if wdex!='curr' and \
           not self._prep_sess(wdex):
            return
        if not self.sess.bids:
            return app.msg_status(_('No in-text completions'))
        shft = 1 if which == 'next' else -1 if which == 'prev' else 0
        bids_i  = int(which)                if which.isdigit()  else \
                  self.sess.bids_i + shft   if self.incr_bfr    else \
                  self.sess.bids_i
        bids_i = bids_i % len(self.sess.bids)
        sub_s = self.sess.bids[bids_i]
        add_s = sub_s[len(self.sess.src_what):]
        pass
        #LOG and log('i, sub_s, add_s={}',(bids_i, sub_s, add_s))

        if self.sess.added:
            ed.cmd(cmds.cCommand_Undo)
            pass
            #LOG and log('undo mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row)))
        ed.delete(self.sess.src_kill_b, self.sess.row, self.sess.src_kill_e,
                  self.sess.row)
        pass
        #LOG and log('kill mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row)))
        ed.insert(self.sess.src_what_e, self.sess.row, add_s)
        pass
        #LOG and log('insr mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row)))
        self.sess.added = True
        if False: pass
        elif self.sess.sel_sub == 'be':
            ed.set_caret(self.sess.src_what_e + len(add_s), self.sess.row,
                         self.sess.src_what_b, self.sess.row)
        elif self.sess.sel_sub == 'eb':
            ed.set_caret(self.sess.src_what_b, self.sess.row,
                         self.sess.src_what_e + len(add_s), self.sess.row)
        else:
            ed.set_caret(self.sess.src_what_e + len(add_s), self.sess.row)
#           ed.set_caret(self.sess.src_crt,                 self.sess.row)
        self.sess.pre_mver = ed.get_prop(app.PROP_MODIFIED_VERSION)
        self.sess.pre_crt0 = ed.get_carets()[0]

        #       next_i      = (self.sess.bids_i+shft) % len(self.sess.bids)
        #       next_info   = '' if 1==len(self.sess.bids) else \
        #                     f(_('. Next #{}: "{}"'), next_i, self.sess.bids[next_i][:50])
        #       app.msg_status(f(_('In-text completion #{} ({}){}'), 1+self.sess.bids_i, len(self.sess.bids), next_info))
        app.msg_status(
            f(_('In-text completion #{} ({})'), 1 + self.sess.bids_i,
              len(self.sess.bids)))
        #       shft                = 1 if which=='next' or which[0]=='#' else -1
        self.sess.bids_i = bids_i
        self.incr_bfr = True
def process_ocurrences(sel_occurrences=False):
    global occurrences

    ed.attr(app.MARKERS_DELETE_BY_TAG, MARKTAG)
    app.msg_status('')

    if sel_occurrences:
        # In this part of the events, occurrences variable must have data.
        # If not, force matches considering no min length selection.
        if len(occurrences) == 0 and opt.MARK_IGNORE_MIN_LEN:
            log("No previous occurrences information")
            res = _get_occurrences(sel_occurrences)

            if not res:
                occurrences = ()
                return
            else:
                occurrences = res

        return occurrences

    else:

        # The highlight function on_caret event only works with one caret.
        if len(ed.get_carets()) != 1: return

        res = _get_occurrences()

        if res is None:
            occurrences = ()
            return
        else:
            occurrences = res

        return occurrences
Пример #10
0
 def dlg_ibms_in_tabs(self):
     ibms    = []
     for h_tab in app.ed_handles(): 
         ted     = app.Editor(h_tab)
         t_ibms, \
         msg     = self._ibms_in_tab(ted, self.bm_signs)
         ibms   += t_ibms
        #for h_tab
     if not ibms:    return app.msg_status(_('No in-text bookmarks in tabs'))
     line_max= max([line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms])
     ln_wd   = len(str(line_max))
     ibms    = [(tab_id, line_n, bm_msg, f('{} {}', str(1+line_n).rjust(ln_wd, ' '), line_s), tab_info) 
                 for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     tid     = ed.get_prop(app.PROP_TAB_ID)
     rCrt    = ed.get_carets()[0][1]
     near    = min([(abs(line_n-rCrt) if tid==tab_id else 0xFFFFFF, ind) 
                 for ind, (tab_id, line_n, bm_msg, line_s, tab_info) in enumerate(ibms)])[1]
     ans     = app.dlg_menu(app.MENU_LIST_ALT, '\n'.join(
                 [f('({}) {}\t{}', tab_info, bm_msg, line_s) for tab_id, line_n, bm_msg, line_s, tab_info in ibms]
             ), near)
     if ans is None: return
     tab_id, line_n, bm_msg, line_s, tab_info    = ibms[ans]
     ted     = apx.get_tab_by_id(tab_id)
     ted.focus()
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(app.PROP_LINE_BOTTOM)):
         ed.set_prop(app.PROP_LINE_TOP, str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Пример #11
0
    def do_insert(self, s):

        x, y, x1, y1 = ed.get_carets()[0]
        if y1 >= 0:
            if (y, x) > (y1, x1):
                x, y, x1, y1 = x1, y1, x, y
            ed.set_caret(x, y)
            ed.replace(x, y, x1, y1, s)
        else:
            ed.insert(x, y, s)

        app.msg_status('Date/time inserted')
Пример #12
0
    def add_ibm(self):
        lxr         = ed.get_prop(app.PROP_LEXER_FILE)
        lxr         = lxr if lxr else NO_LXR_SIGN
#       if lxr not in self.lxr2cmnt:    return app.msg_status(f(_('Cannot add in-text bookmark into document with Lexer {}. No to-end-of-line comment.'), lxr))
        if lxr not in self.lxr2cmnt:    return app.msg_status(f(_('Cannot add in-text bookmark: no line-comments defined for lexer {}.'), lxr))
        cmnt        = self.lxr2cmnt[lxr]
        bm_msg      = app.dlg_input(_('Enter message for in-text bookmark. Empty is good.'), '')
        if bm_msg is None:              return
        (cCrt, rCrt
        ,cEnd, rEnd)= ed.get_carets()[0]
        line_s      = ed.get_text_line( rCrt)
        ed.set_text_line(               rCrt, line_s + cmnt + self.bm_sign + ' ' + bm_msg)
Пример #13
0
    def _subst(self, which, wdex):
        """ Do completion.
            Params
                which   Which variant to use
                            'next' / 'prev' / '#N'
                wdex    What list to use
                            'word' / 'expr' / 'curr'
        """
        pass;                  #LOG and log('which, wdex={}',(which, wdex))
        if wdex!='curr' and \
           not self._prep_sess(wdex): return
        if not self.sess.bids:
            return app.msg_status(_('No in-text completions'))
        shft                = 1 if which=='next' else -1 if which=='prev' else 0
        bids_i  = int(which)                if which.isdigit()  else \
                  self.sess.bids_i + shft   if self.incr_bfr    else \
                  self.sess.bids_i
        bids_i  = bids_i % len(self.sess.bids)
        sub_s   = self.sess.bids[bids_i]
        add_s   = sub_s[len(self.sess.src_what):]
        pass;                  #LOG and log('i, sub_s, add_s={}',(bids_i, sub_s, add_s))

        if self.sess.added:
            ed.cmd(cmds.cCommand_Undo)
            pass;              #LOG and log('undo mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row)))
        ed.delete(       self.sess.src_kill_b,              self.sess.row
                        ,self.sess.src_kill_e,              self.sess.row)
        pass;                  #LOG and log('kill mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row)))
        ed.insert(       self.sess.src_what_e,              self.sess.row,  add_s)
        pass;                  #LOG and log('insr mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row)))
        self.sess.added     = True
        if False:pass
        elif self.sess.sel_sub=='be':
            ed.set_caret(self.sess.src_what_e+len(add_s),   self.sess.row
                        ,self.sess.src_what_b,              self.sess.row)
        elif self.sess.sel_sub=='eb':
            ed.set_caret(self.sess.src_what_b,              self.sess.row
                        ,self.sess.src_what_e+len(add_s),   self.sess.row)
        else:
            ed.set_caret(self.sess.src_what_e+len(add_s),   self.sess.row)
#           ed.set_caret(self.sess.src_crt,                 self.sess.row)
        self.sess.pre_mver  = ed.get_prop(app.PROP_MODIFIED_VERSION)
        self.sess.pre_crt0  = ed.get_carets()[0]
        
#       next_i      = (self.sess.bids_i+shft) % len(self.sess.bids)
#       next_info   = '' if 1==len(self.sess.bids) else \
#                     f(_('. Next #{}: "{}"'), next_i, self.sess.bids[next_i][:50])
#       app.msg_status(f(_('In-text completion #{} ({}){}'), 1+self.sess.bids_i, len(self.sess.bids), next_info))
        app.msg_status(f(_('In-text completion #{} ({})'),   1+self.sess.bids_i, len(self.sess.bids)))
#       shft                = 1 if which=='next' or which[0]=='#' else -1
        self.sess.bids_i    = bids_i
        self.incr_bfr       = True
Пример #14
0
def tree_path_to_status():
    pass;                  #log('?',())
    path_l, gap = _get_best_tree_path(ed.get_carets()[0][1])
    if not path_l:  return
    ID_TREE = app.app_proc(app.PROC_SIDEPANEL_GET_CONTROL, 'Code tree')
    if not ID_TREE: return
    id_sel  = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_SELECTED)
    id_need = path_l[-1][0]
    if id_need != id_sel:
        app.tree_proc(ID_TREE, app.TREE_ITEM_SELECT, id_need)
    path    = '['+ '] / ['.join([cap.rstrip(':')[:40] for (nid,cap) in path_l]) + ']'
    return app.msg_status_alt(
        path if gap==0 else f('[{:+}] {}', -gap, path)
    , 10)
Пример #15
0
 def open_selected(self):
     pass;                  #LOG and log('ok',)
     bs_dir  = os.path.dirname(ed.get_filename())
     crts    = ed.get_carets()
     for (cCrt, rCrt, cEnd, rEnd) in crts:
         if -1==cEnd: continue
         if rCrt!=rEnd: continue
         (rTx1, cTx1), (rTx2, cTx2) = apx.minmax((rCrt, cCrt), (rEnd, cEnd))
         selTx   = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
         op_file = os.path.join(bs_dir, selTx)
         if not os.path.exists(op_file):
             app.msg_status(NO_FILE_FOR_OPEN.format(op_file))
             continue
         op_ed   = _file_open(op_file)
         op_ed.focus()
Пример #16
0
 def add_ibm(self):
     lxr = ed.get_prop(app.PROP_LEXER_FILE)
     lxr = lxr if lxr else NO_LXR_SIGN
     #       if lxr not in self.lxr2cmnt:    return app.msg_status(f(_('Cannot add in-text bookmark into document with Lexer {}. No to-end-of-line comment.'), lxr))
     if lxr not in self.lxr2cmnt:
         return app.msg_status(
             f(
                 _('Cannot add in-text bookmark: no line-comments defined for lexer {}.'
                   ), lxr))
     cmnt = self.lxr2cmnt[lxr]
     bm_msg = app.dlg_input(
         _('Enter message for in-text bookmark. Empty is good.'), '')
     if bm_msg is None: return
     (cCrt, rCrt, cEnd, rEnd) = ed.get_carets()[0]
     line_s = ed.get_text_line(rCrt)
     ed.set_text_line(rCrt, line_s + cmnt + self.bm_sign + ' ' + bm_msg)
Пример #17
0
    def run(self, mcr_id, times=1, waits=0, while_chngs=False, till_endln=False):
        ''' Main (and single) way to run any macro
        '''
        pass;                   LOG and log('mcr_id, times, waits, while_chngs, till_endln={}',(mcr_id, times, waits, while_chngs, till_endln))
        mcr     = self.mcr4id.get(str(mcr_id))
        if mcr is None:
            pass;               LOG and log('no id',)
            return app.msg_status(_('No macros: {}').format(mcr_id))
        cmds4eval   = ';'.join(mcr['evl'])
        pass;                   LOG and log('nm, cmds4eval={}',(mcr['nm'], cmds4eval))
        how_t       = 'wait'
        rp_ctrl     = self.tm_ctrl.get('rp_ctrl', 1000)                     # testing one of 1000 execution
        tm_wait     = waits if waits>0 else self.tm_ctrl.get('tm_wait', 10) # sec
        start_t     = datetime.datetime.now()
        pre_body    = '' if not while_chngs else ed.get_text_all()
        for rp in range(times if times>0 else 0xffffffff):
            exec(cmds4eval)
            if till_endln and ed.get_carets()[0][1] == ed.get_line_count()-1:
                pass;           LOG and log('break endln',)
                break   #for rp
            if while_chngs:
                new_body    = ed.get_text_all()
                if pre_body == new_body:    
                    pass;       LOG and log('break no change',)
                    break   #for rp
                pre_body    = new_body
            if  (how_t=='wait'
            and (rp_ctrl-1) == rp % rp_ctrl
            and tm_wait < (datetime.datetime.now()-start_t).seconds):
                cnts    = ([
  dict(              tp='lb'    ,t=GAP          ,l=GAP  ,w=400   ,cap=_('Macro "{}" playback time is too long'.format(mcr['nm'])))
 ,dict(cid='wait'   ,tp='bt'    ,t=GAP*2+25*1   ,l=GAP  ,w=400   ,cap=_('Wait &another {} sec').format(tm_wait)  ,props='1'      )   # default
 ,dict(cid='cont'   ,tp='bt'    ,t=GAP*3+25*2   ,l=GAP  ,w=400   ,cap=_('Continue &without control')                             )
 ,dict(cid='stop'   ,tp='bt'    ,t=GAP*6+25*3   ,l=GAP  ,w=300   ,cap=_('&Cancel playback [ESC]')                                )
                        ])
                btn,vals,chds= dlg_wrapper(_('Playback macro'), GAP*2+400, GAP*7+4*25, cnts, {})
                if btn is None or btn=='stop':
                    pass;       LOG and log('break by user',)
                    app.msg_status(_('Cancel playback macro: {}'.format(mcr['nm'])))
                    break   #for rp
                if btn=='cont': #ans=='cont':
                    how_t   = 'work'
                if btn=='wait': #ans=='wait':
                    start_t = datetime.datetime.now()
           #for rp
        self.last_mcr_id = mcr_id
Пример #18
0
 def dlg_ibms_in_tabs(self):
     ibms = []
     for h_tab in app.ed_handles():
         ted = app.Editor(h_tab)
         t_ibms, \
         msg     = self._ibms_in_tab(ted, self.bm_signs)
         ibms += t_ibms
     #for h_tab
     if not ibms: return app.msg_status(_('No in-text bookmarks in tabs'))
     line_max = max(
         [line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms])
     ln_wd = len(str(line_max))
     ibms = [(tab_id, line_n, bm_msg,
              f('{} {}',
                str(1 + line_n).rjust(ln_wd, ' '), line_s), tab_info)
             for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     tid = ed.get_prop(app.PROP_TAB_ID)
     rCrt = ed.get_carets()[0][1]
     near = min([(abs(line_n - rCrt) if tid == tab_id else 0xFFFFFF, ind)
                 for ind, (tab_id, line_n, bm_msg, line_s,
                           tab_info) in enumerate(ibms)])[1]
     ans = dlg_menu(
         (app.DMENU_LIST if self.show_wo_alt else app.DMENU_LIST_ALT) +
         app.DMENU_EDITORFONT + app.DMENU_CENTERED,
         w=900,
         h=800,
         cap=f(_('In-text bookmarks (all tabs): {}'), len(ibms)),
         its=[
             f('({}) {}', tab_info, bm_msg)
             for tab_id, line_n, bm_msg, line_s, tab_info in ibms
         ] if self.show_wo_alt else [
             f('({}) {}\t{}', tab_info, bm_msg, line_s)
             for tab_id, line_n, bm_msg, line_s, tab_info in ibms
         ],
         sel=near)
     if ans is None: return
     tab_id, line_n, bm_msg, line_s, tab_info = ibms[ans]
     ted = apx.get_tab_by_id(tab_id)
     ted.focus()
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(
             app.PROP_LINE_BOTTOM)):
         ed.set_prop(
             app.PROP_LINE_TOP,
             str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Пример #19
0
    def cmt_toggle_stream(self):
        ''' '''
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(COMMENTING))
        lex     = ed.get_prop(app.PROP_LEXER_CARET)
        (bgn
        ,end)   = self._get_cmt_pair(lex)
        if not bgn:
            return app.msg_status(CMT_NO_STRM_4LEX.format(lex))
        crts    = ed.get_carets()
        pass;                   LOG and log('lex, get_carets()={}', (lex, crts))
        pass;                   LOG and log('bgn,end={}', (bgn,end))
        for icrt, (c1, r1, c2, r2) in enumerate(crts):
            pass;               LOG and log('(r1, c1), (r2, c2)={}', ((r1, c1), (r2, c2)))
            if -1==c2:
                # Empty sel
                continue
            (r1, c1), (r2, c2) = minmax((r1, c1), (r2, c2))
            pass;               LOG and log('(r1, c1), (r2, c2)={}', ((r1, c1), (r2, c2)))
            selTx   = ed.get_text_substr(c1, r1, c2, r2)
            cmted   = selTx.startswith(bgn) and selTx.endswith(end)
            pass;               LOG and log('cmted, selTx={}', (cmted, selTx))

            if False:pass
            elif not cmted and r1==r2:
                # Comment ON, sel into one row
                ed.insert(c2, r2, end)
                ed.insert(c1, r1, bgn)
                ed.set_caret(c1, r1, c2+len(bgn)+len(end), r2, app.CARET_SET_INDEX+icrt)
            elif not cmted and r1!=r2:
                # Comment ON, sel ends on diff rows
                ed.insert(c2, r2, end)
                ed.insert(c1, r1, bgn)
                ed.set_caret(c1, r1, c2         +len(end), r2, app.CARET_SET_INDEX+icrt)

            elif cmted and r1==r2:
                # Comment OFF, sel into one row
                ed.delete(c2-len(end), r2, c2, r2)
                ed.delete(c1, r1, c1+len(bgn), r1)
                ed.set_caret(c1, r1, c2-len(bgn)-len(end), r2, app.CARET_SET_INDEX+icrt)
            elif cmted and r1!=r2:
                # Comment OFF, sel ends on diff rows
                ed.delete(c2-len(end), r2, c2, r2)
                ed.delete(c1, r1, c1+len(bgn), r1)
                ed.set_caret(c1, r1, c2         -len(end), r2, app.CARET_SET_INDEX+icrt)
Пример #20
0
    def jump_to_matching_bracket(self):
        ''' Jump single (only!) caret to matching bracket.
            Pairs: [] {} () <> «»
        '''
        pass;                  #LOG and log('')
        crts    = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format('Command'))
        (cCrt, rCrt, cEnd, rEnd)    = crts[0]
        if cEnd!=-1:
            return app.msg_status(ONLY_FOR_NO_SEL.format('Command'))

        (c_opn, c_cls
        ,col, row)  = find_matching_char(ed, cCrt, rCrt)

        if c_opn!='' and -1!=col:
            pass;              #LOG and log('set_caret(col, row)={}', (col, row))
            ed.set_caret(col, row)
        else:
            return app.msg_status(NO_PAIR_BRACKET.format(c_opn))
Пример #21
0
 def _jump_to_ibm(self, what):
     ibms,   \
     msg     = self._ibms_in_tab(ed, self.bm_signs)
     if not ibms and msg:    return app.msg_status(msg)
     if not ibms:            return app.msg_status(_('No in-text bookmarks'))
     rCrt    = ed.get_carets()[0][1]
     if  1==len(ibms) \
     and rCrt==ibms[0][1]:   return app.msg_status(_('No more bookmarks'))
     line_ns = [line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     if self.wrap:
         line_ns = [-line_ns[-1]] + line_ns + [line_ns[0]+0xFFFFFFFF]
     line_cns= [line_n for line_n in line_ns 
                 if (line_n>rCrt if what=='next' else line_n<rCrt)]
     if not line_cns:        return app.msg_status(_('No bookmark for jump'))
     line_n  = min(line_cns)         if what=='next'         else max(line_cns)
     line_n  = -line_n               if line_n<0             else line_n
     line_n  =  line_n-0xFFFFFFFF    if line_n>=0xFFFFFFFF   else line_n
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(app.PROP_LINE_BOTTOM)):
         ed.set_prop(app.PROP_LINE_TOP, str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Пример #22
0
 def dlg_ibms_in_tab(self):
     ibms,   \
     msg     = self._ibms_in_tab(ed, self.bm_signs)
     if not ibms and msg: return app.msg_status(msg)
     if not ibms: return app.msg_status(_('No in-text bookmarks'))
     line_max = max(
         [line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms])
     ln_wd = len(str(line_max))
     pass
     #LOG and log('ln_wd={}',(ln_wd))
     pass
     #LOG and log('self.show_wo_alt={}',(self.show_wo_alt))
     ibms = [(bm_msg, line_n,
              f('{} {}',
                str(1 + line_n).rjust(ln_wd, ' '), line_s))
             for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     pass
     #LOG and log('ibms=¶{}',pf(ibms))
     rCrt = ed.get_carets()[0][1]
     near = min([(abs(line_n - rCrt), ind)
                 for ind, (bm_msg, line_n, line_s) in enumerate(ibms)])[1]
     ans = dlg_menu(
         (app.DMENU_LIST if self.show_wo_alt else app.DMENU_LIST_ALT) +
         app.DMENU_EDITORFONT,
         w=900,
         cap=f(_('Tab in-text bookmarks: {}'), len(ibms)),
         its=[
             f('{}\t{}', line_nd, bm_msg)
             for bm_msg, line_n, line_nd in ibms
         ] if self.show_wo_alt else
         [f('{}\t{}', bm_msg, line_nd) for bm_msg, line_n, line_nd in ibms],
         sel=near)
     if ans is None: return
     bm_msg, line_n, line_nd = ibms[ans]
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(
             app.PROP_LINE_BOTTOM)):
         ed.set_prop(
             app.PROP_LINE_TOP,
             str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Пример #23
0
 def on_caret(self, ed_self):
     if self.skip_rec:
         self.skip_rec = False
         return 
         
     crts    = ed.get_carets()
     if len(crts)>1:
         pass;              #LOG and log('skip: many carets',())
         return 
     new_item= HistItem(*crts[0])
     pass;                  #LOG and log('new_item={}',(new_item))
     tab_id  = ed_self.get_prop(app.PROP_TAB_ID) # уникальный ID вкладки
     if tab_id not in self.history:
         self.history[tab_id]    = [new_item]
         self.poses[  tab_id]    = 0
         pass;              #LOG and log('new tab',())
         return 
     hist,   \
     pos     = self.history[tab_id] \
             , self.poses[  tab_id]
     
     pre_item= hist[pos]
     if abs(pre_item.y - new_item.y) > GAP_SIZE:
         # Дальний скачок
         # - Начать новое наращивание истории
         # - Запомнить текущую каретку (или выделение) для последующего перехода
         del hist[pos+1:]
         hist    += [new_item]
         self.poses[tab_id] = pos+1
         if len(hist)>HIST_MAX:
             del hist[0]
             self.poses[tab_id] -= 1
         pass;              #LOG and log('long gap pos,hist={}',(self.poses[tab_id], hist))
     else:
         # Ближний скачок
         # - Изменяем данные о текущем положении в истории
         # - Сохраняем возможность для forward-перехода
         pass;              #LOG and log('short gap',())
         hist[pos]   = new_item
def get_word_under_caret():
    """
    Gets a tuple (word_under_caret, (x1, y1, x2, y2)) containing the word under
    the current caret.
    """

    lex = ed.get_prop(app.PROP_LEXER_CARET)

    carets = ed.get_carets()

    # In this point the "one caret" rule is valid, so x2 and y2 is equal to -1
    # and there is no a selection
    x1, y1 = carets[0][:2]

    current_line = get_line(y1)
    # if len(current_line) > opt.MAX_LINE_LEN: return

    n_x1 = n_x2 = x1

    if current_line:
        if x1 > 0 and is_word(current_line[x1 - 1], lex):
            n_x1 = next((i for i in range(x1 - 1, -1, -1)
                         if not is_word(current_line[i], lex)), -1) + 1

        if x1 < len(current_line) and is_word(current_line[x1], lex):
            n_x2 = next((i for i in range(x1 + 1, len(current_line))
                         if not is_word(current_line[i], lex)),
                        len(current_line))

    else: return

    if n_x1 == n_x2:
        return

    word_under_caret = current_line[n_x1: n_x2]

    return word_under_caret, (n_x1, y1, n_x2, y1)
Пример #25
0
    def paste_to_1st_col(self):
        ''' Paste from clipboard without replacement caret/selection
                but only insert before current line
        ''' 
        pass;                  #LOG and log('')
        clip    = app.app_proc(app.PROC_GET_CLIP, '')
        if not clip:    return
        clip    = clip.replace('\r\n', '\n').replace('\r', '\n')
        if not (clip[-1] in '\r\n'):
            clip= clip + '\n'
        rnews   = clip.count('\n')
        crts    = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format('Command'))
        (cCrt, rCrt, cEnd, rEnd)    = crts[0]
        r4ins   = min(rCrt, rCrt if -1==rEnd else rEnd)
        ed.insert(0, r4ins, clip)
        rCrtN   = rCrt+ rnews
        rEndN   = rEnd+(rnews if -1!=rEnd else 0)
        pass;                  #LOG and log('(rCrtN, rEndN)={}',(rCrtN, rEndN))
        ed.set_caret(cCrt, rCrtN
                    ,cEnd, rEndN)
        pass;                   return  ##??
        for icrt, (cCrt, rCrt, cEnd, rEnd) in reversed(list(enumerate(crts))):
#       for icrt, (cCrt, rCrt, cEnd, rEnd) in enumerate(crts):
            pass;              #LOG and log('icrt, (cCrt, rCrt, cEnd, rEnd), rnews={}',(icrt, (cCrt, rCrt, cEnd, rEnd), rnews))
            rCrtA   = rCrt+rnews*icrt
            rEndA   = rEnd+rnews*icrt if -1!=rEnd else -1
            r4ins   = min(rCrt, rCrt if -1==rEnd else rEnd)
            pass;              #LOG and log('(rCrtA, rEndA), r4ins={}',((rCrtA, rEndA), r4ins))
            ed.insert(0, r4ins, clip)
            rCrtN   = rCrt+ rnews
            rEndN   = rEnd+(rnews if -1!=rEnd else 0)
            pass;              #LOG and log('(rCrtN, rEndN)={}',(rCrtN, rEndN))
            ed.set_caret(cCrt, rCrtN
                        ,cEnd, rEndN
                        ,app.CARET_SET_INDEX+icrt)
def _get_current_text():
    caret_pos = ed.get_carets()[0]

    x1, y1, x2, y2 = caret_pos

    is_selection = y2 >= 0

    current_text = ''

    if is_selection:
        if opt.SEL_ALLOW:
            # Sorting caret's values
            if (y1, x1) > (y2, x2):
                x1, x2 = x2, x1
                y1, y2 = y2, y1
                caret_pos = (x1, y1, x2, y2)

            # After sorting y2 always will be greater or equal to y1
            # No multi-line allowed
            if (y2 - y1) > 0: return

            current_text = ed.get_text_sel()
        else:
            return
    else:
        # Sometimes caret can be beyond text end
        temp = get_line(y1)
        if (temp is None) or (len(temp) < x1): return
        # if len(temp) > opt.MAX_LINE_LEN: return

        if opt.CARET_ALLOW:
            temp = get_word_under_caret()
            if not temp: return
            current_text, caret_pos = temp

    return current_text, caret_pos, is_selection
Пример #27
0
def symbol_menu_levels(levels=0):
    pass;                       log4fun=-1== 1  # Order log in the function
    if  app.app_api_version() >= '1.0.277' and \
        ed.get_prop(app.PROP_CODETREE_MODIFIED_VERSION) < ed.get_prop(app.PROP_MODIFIED_VERSION):
        ed.cmd(cmds.cmd_TreeUpdate)
    h_tree = app.app_proc(app.PROC_GET_CODETREE, '')
        
    def tree_items_to_list(props=None, id_node=0, prefix='', more_levels=1000):
        '''Get all tree nodes to "props" starting from id_node (e.g. 0)'''
        props = [] if props is None else props 
        nodes = app.tree_proc(h_tree, app.TREE_ITEM_ENUM, id_node)
        if not nodes:
            nodes = app.tree_proc(h_tree, app.TREE_ITEM_ENUM, id_node)
            if not nodes:
                return 
        for id_kid, cap in nodes:
            prop    = app.tree_proc(h_tree, app.TREE_ITEM_GET_PROPS, id_kid)
            rng     = app.tree_proc(h_tree, app.TREE_ITEM_GET_RANGE, id_kid)
            subs    = prop['sub_items']
            if rng[0]>=0:
                prop['rng'] = rng
                prop['_t']  = f('{}{}\t{}'
                                , prefix
                                , prop['text']
                                , f('{}:{}', 1+rng[1], 1+rng[3]))
                props.append(prop)
            if subs and more_levels:
                # need items with sub_items too
                tree_items_to_list(props, id_kid, prefix+' '*4, more_levels-1)
        return props
       #def tree_items_to_list
    
    old_api     = app.app_api_version() < '1.0.277'
    w           = get_hist('symbols.w', 600)
    h           = get_hist('symbols.h', 550)
    while True:
        props = tree_items_to_list(more_levels=(levels-1 if levels else 1000))
        if not props:
            ed.cmd(cmds.cmd_TreeUpdate)
            props = tree_items_to_list()
            if not props:
                return app.msg_status(_('No items in Code Tree'))

        items       = [p['_t'] for p in props]
        crt_row     = ed.get_carets()[0][1]
        covers      = [(p['rng'][3]-p['rng'][1], n) for n,p in enumerate(props) 
                        if p['rng'][1] <= crt_row <= p['rng'][3]]
        start_item  = min(covers)[1] if covers else 0
        res = dlg_menu(app.MENU_LIST+app.MENU_NO_FULLFILTER+app.MENU_EDITORFONT
            , w=w, h=h
            , sel=start_item
            , cap=_('Code Tree symbols')
                     + f(' ({})'    , len(items))
                     +(f(' (up {})' , levels    ) if levels else '')
            , its=items 
            + ([_('<Update Code Tree>')] if old_api else [])
            + [_('              <All levels>')]
            + [_('              <Only 1 up level>')]
            + [_('              <Only 2 up levels>')]
            + [_('              <Only 3 up levels>')]
            )
        if res is None: return
        if res==len(props) and old_api:
            ed.cmd(cmds.cmd_TreeUpdate)
            continue#while
        if res==0+len(props) + (1 if old_api else 0):
            levels  = 0
            continue#while
        if res==1+len(props) + (1 if old_api else 0):
            levels  = 1
            continue#while
        if res==2+len(props) + (1 if old_api else 0):
            levels  = 2
            continue#while
        if res==3+len(props) + (1 if old_api else 0):
            levels  = 3
            continue#while
        break
       #while
        
    x, y, x1, y1 = props[res]['rng']
    ed.set_caret(x, y)
Пример #28
0
    def cmt_toggle_stream(self):
        ''' '''
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(COMMENTING))
        lex = ed.get_prop(app.PROP_LEXER_CARET)
        ((bgn_sgn, end_sgn), bOnlyLn) = self._get_cmt_pair(lex)
        if not bgn_sgn:
            return app.msg_status(CMT_NO_STRM_4LEX.format(lex))
        bUseFLn = get_opt('comment_full_line_if_no_sel', True)
        crts = ed.get_carets()
        pass
        #LOG and log('lex, get_carets()={}', (lex, crts))
        pass
        #LOG and log('(bgn_sgn,end_sgn),bOnlyLn,bUseFLn={}', ((bgn_sgn,end_sgn),bOnlyLn,bUseFLn))
        for icrt, (cCrt, rCrt, cEnd, rEnd) in enumerate(crts):
            pass
            #LOG and log('(cCrt, rCrt), (cEnd, rEnd)={}', ((cCrt, rCrt), (cEnd, rEnd)))
            bEmpSel = -1 == rEnd
            bDrtSel = -1 == rEnd or (rCrt, cCrt) > (rEnd, cEnd)
            if False: pass
            elif bEmpSel and (bUseFLn or bOnlyLn):
                # Use full line
                line = ed.get_text_line(rCrt)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rCrt), (len(line), rCrt)
            elif bOnlyLn:  # and not bEmpSel
                # Only full lines
                rTx1, rTx2 = minmax(rCrt, rEnd)
                line = ed.get_text_line(rTx2)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rTx1), (len(line), rTx2)
            elif bEmpSel:  # and not bUseFLn and not bOnlyLn
                continue
            else:
                (rTx1, cTx1), (rTx2, cTx2) = minmax((rCrt, cCrt), (rEnd, cEnd))
            selTx = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
            pass
            #LOG and log('(rTx1, cTx1), (rTx2, cTx2), selTx={}', ((rTx1, cTx1), (rTx2, cTx2), repr(selTx)))
            do_uncmt = selTx.startswith(bgn_sgn) and selTx.endswith(end_sgn)
            pass
            #LOG and log('do_uncmt={}', (do_uncmt))

            if False: pass
            elif not do_uncmt and bOnlyLn:
                # Comment!
                ed.insert(0, rTx2 + 1, end_sgn + '\n')  #! true insert sequence
                ed.insert(0, rTx1, bgn_sgn + '\n')  #! true insert sequence
                (cNSel1, rNSel1, cNSel2,
                 rNSel2) = 0, rTx1, len(end_sgn), rTx2 + 2
            elif not do_uncmt:
                # Comment!
                ed.insert(cTx2, rTx2, end_sgn)  #! true insert sequence
                ed.insert(cTx1, rTx1, bgn_sgn)  #! true insert sequence
                if False: pass
                elif rTx1 == rTx2:
                    # sel into one row
                    (cNSel1, rNSel1, cNSel2, rNSel2
                     ) = cTx1, rTx1, cTx2 + len(bgn_sgn) + len(end_sgn), rTx2
                elif rTx1 != rTx2:
                    # sel ends on diff rows
                    (cNSel1, rNSel1, cNSel2,
                     rNSel2) = cTx1, rTx1, cTx2 + len(end_sgn), rTx2

            elif do_uncmt and bOnlyLn:
                # UnComment!
                ed.delete(0, rTx2, 0, rTx2 + 1)  #! true delete sequence
                ed.delete(0, rTx1, 0, rTx1 + 1)  #! true delete sequence
                (cNSel1, rNSel1, cNSel2,
                 rNSel2) = 0, rTx1, len(ed.get_text_line(rTx2 - 2)), rTx2 - 2
            elif do_uncmt:
                # UnComment!
                ed.delete(cTx2 - len(end_sgn), rTx2, cTx2,
                          rTx2)  #! true delete sequence
                ed.delete(cTx1, rTx1, cTx1 + len(bgn_sgn),
                          rTx1)  #! true delete sequence
                if False: pass
                elif rTx1 == rTx2:
                    # sel into one row
                    (cNSel1, rNSel1, cNSel2, rNSel2
                     ) = cTx1, rTx1, cTx2 - len(bgn_sgn) - len(end_sgn), rTx2
                elif rTx1 != rTx2:
                    # sel ends on diff rows
                    (cNSel1, rNSel1, cNSel2,
                     rNSel2) = cTx1, rTx1, cTx2 - len(end_sgn), rTx2

            pass
            #LOG and log('bDrtSel, (cNSel1, rNSel1), (cNSel2, rNSel2)={}', (bDrtSel, (cNSel1, rNSel1), (cNSel2, rNSel2)))
            if bDrtSel:
                ed.set_caret(cNSel2, rNSel2, cNSel1, rNSel1,
                             app.CARET_SET_INDEX + icrt)
            else:
                ed.set_caret(cNSel1, rNSel1, cNSel2, rNSel2,
                             app.CARET_SET_INDEX + icrt)
        #for icrt
        bSkip = get_opt('comment_move_down', True)
        if False: pass
        elif 1 == len(crts) and bEmpSel and bUseFLn and bSkip:
            _move_caret_down(cCrt, rCrt)
            if bOnlyLn and not do_uncmt:
                crt = ed.get_carets()[0]
                _move_caret_down(crt[0], crt[1])
                crt = ed.get_carets()[0]
                _move_caret_down(crt[0], crt[1])
Пример #29
0
    def _prep_sess(self, wdex='word'):
        """ Params
                wdex    Type of sess:   'word' / 'expr'
        """
        crts = ed.get_carets()
        if len(crts) > 1:
            return app.msg_status(_("Command doesnt work with multi-carets"))
        (cCrt, rCrt, cEnd, rEnd) = crts[0]
        if -1 != rEnd and rCrt != rEnd:
            return app.msg_status(
                _("Command doesnt work with multi-line selection"))

        stayed      =   self.sess     \
                    and self.sess.pre_mver == ed.get_prop(app.PROP_MODIFIED_VERSION) \
                    and self.sess.pre_crt0 == crts[0]

        cEnd, rEnd = (cCrt, rCrt) if -1 == rEnd else (cEnd, rEnd)
        sel_be_eb = 'be' if cCrt > cEnd else 'eb' if cCrt < cEnd else ''
        ((rSelB, cSelB), (rSelE, cSelE)) = apx.minmax((rCrt, cCrt),
                                                      (rEnd, cEnd))
        pass
        #LOG and stayed and log('stayed,(wdex,self.sess.wdex)={}',(stayed,(wdex,self.sess.wdex)))
        if stayed and wdex == self.sess.wdex:
            # Sess OK
            return True

        what = ''  # Str to find
        what_b = -1  # Pos what begin
        what_e = -1  # Pos what end
        kill_b = -1  # Pos kill begin
        kill_e = -1  # Pos kill end
        wbnd = True  # Need left word bound
        sel = ''
        if stayed and wdex != self.sess.wdex:
            # Change sess type
            what = self.sess.src_what
            what_b = self.sess.src_what_b
            what_e = self.sess.src_what_e
            kill_b = self.sess.src_kill_b
            kill_e = self.sess.src_kill_e
            wbnd = self.sess.src_wbnd
        if not stayed:
            # New sess
            line = ed.get_text_line(rCrt)
            sel = ed.get_text_sel()
            if sel:
                # Use selection to find
                what = sel
                what_b = cSelB
                what_e = cSelE
                wbnd = 0 == cSelB or line[cSelB - 1].isspace()
            else:
                # Use "chars around caret" to find what
                tx_bfr = line[:cCrt]
                ch_bfr = tx_bfr[-1] if tx_bfr else ' '
                tx_aft = line[cCrt:]
                ch_aft = tx_aft[0] if tx_aft else ' '
                pass
                #LOG and log('ch_bfr,ch_aft,tx_bfr,tx_aft={}',(ch_bfr,ch_aft,tx_bfr,tx_aft))
                shf_l = 0
                shf_r = 0
                if ch_bfr.isalnum() or ch_bfr in self.wdsgns:
                    tx_bfr_r = ''.join(reversed(tx_bfr))
                    shf_l = len(self.base_re.match(tx_bfr_r).group())
                if ch_aft.isalnum() or ch_aft in self.wdsgns:
                    shf_r = len(self.base_re.match(tx_aft).group())
                what_b = cCrt - shf_l
                if self.kill:
                    what_e = cCrt
                    kill_b = cCrt
                    kill_e = cCrt + shf_r
                else:
                    what_e = cCrt + shf_r
                what = line[what_b:what_e]
                pass
                #LOG and log('(shf_l,shf_r), (what_b,what_e), what={}',((shf_l,shf_r), (what_b,what_e), what))

        if not  what \
        or not  what.strip():
            return app.msg_status(_('No data for search'))
        if len(what) < self.min_len:
            return app.msg_status(
                f(_('Need |base|>={}, but |"{}"|=={}'), self.min_len, what,
                  len(what)))
        pass
        #LOG and log('what,wbnd={}',(what,wbnd))

        asword = wdex == 'word'
        asexpr = wdex == 'expr'
        # Make new Sess
        if not stayed:
            pass
            #LOG and log('new sess',())
            self.sess = Command.Sess()
            self.sess.row = rCrt
            self.sess.sel_sub = sel_be_eb
            self.sess.src_crt = cCrt
            self.sess.src_what = what
            self.sess.src_what_b = what_b
            self.sess.src_what_e = what_e
            self.sess.src_kill_b = kill_b
            self.sess.src_kill_e = kill_e
            self.sess.src_wbnd = wbnd
        self.sess.wdex = wdex
        what_re = re.compile('' + (r'\b' if wbnd else '') + re.escape(what) +
                             (self.wdcmpl if asword else self.excmpl))
        #               +  r'[\w'+re.escape(self.wdsgns)+']+')
        pass
        #LOG and log('what_re={}',(what_re.pattern))
        bids_d = OrdDict()
        for line_n in range(ed.get_line_count()):
            if line_n == self.sess.row: continue  #for line_n
            line = ed.get_text_line(line_n)
            if asexpr and self.expair:
                # Find+expand upto close brackets/quotes
                lbids_l = []
                for m in what_re.finditer(line):
                    lbid = m.group(0)

                    ok = False
                    for op, cl in self.opn2cls.items():
                        if op in lbid and lbid.count(op) > lbid.count(
                                cl):  # Try expand to good cl
                            ext_bgn = m.end()
                            ext_end = line.find(cl, ext_bgn)
                            while -1 != ext_end:
                                lbid_ext = lbid + line[ext_bgn:ext_end + 1]
                                if lbid_ext.count(op) == lbid_ext.count(cl):
                                    lbid, ok = lbid_ext, True
                                    break  #while
                                ext_end = line.find(cl, ext_end + 1)
                        if ok: break  #for op
                    #for op
                    ok = False
                    for qu in self.quotes:
                        if qu in lbid and 1 == lbid.count(
                                qu) % 2:  # Try expand to good qu
                            ext_bgn = m.end()
                            ext_end = line.find(qu, ext_bgn)
                            while -1 != ext_end:
                                lbid_ext = lbid + line[ext_bgn:ext_end + 1]
                                if 0 == lbid_ext.count(qu) % 2:
                                    lbid, ok = lbid_ext, True
                                    break  #while
                                ext_end = line.find(cl, ext_end + 1)
                        if ok: break  #for qu
                    #for qu

                    lbids_l.append(lbid)
                #for m
            else:
                # Find only
                lbids_l = what_re.findall(line)
            if lbids_l:
                bids_d.update({
                    bid: line_n
                    for bid in lbids_l
                    if bid not in bids_d or abs(line_n - self.sess.row) < abs(
                        bids_d[bid] - self.sess.row)
                })  # closest
        if not bids_d:
            return app.msg_status(_('No in-text completions'))

        self.sess.bids = list(bids_d.keys())
        self.sess.bids_c = list(bids_d.values())
        self.sess.bids_i= min([(abs(bid_r-self.sess.row), bid_i)
                                for (bid_i,bid_r) in enumerate(self.sess.bids_c)
                              ])[1] \
                            if len(self.sess.bids)>1 and self.near else \
                          0
        self.incr_bfr = False  # Dont increment before use
        pass
        #LOG and log('bids={}',(list(zip(self.sess.bids, self.sess.bids_c))))
        pass
        #LOG and log('sess={}',(self.sess))
        pass
        #return False
        return True
Пример #30
0
    def _cmt_toggle_line(self, cmt_type):
        ''' Add/Remove line comment
            Params
                cmt_type    '1st'    at begin of line
                            'bod'    at first not blank
        '''
        if not _check_API('1.0.107'):    return
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(COMMENTING))

        lex         = ed.get_prop(app.PROP_LEXER_CARET)
        cmt_sgn     = app.lexer_proc(app.LEXER_GET_COMMENT, lex)
        pass;                   LOG and log('lex, cmt_sgn={}', (lex, cmt_sgn))
        if not cmt_sgn:
            return app.msg_status(CMT_NO_LINE_4LEX.format(lex))
        crts        = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format(COMMENTING))

        no_tab      = ed.get_prop(app.PROP_TAB_SPACES)    # only blanks
        opts        = self._get_opts('cmt')
        save_bd_col = no_tab and opts.get('save_body_col', False)
        blnks4cmt   = '\t'.expandtabs(len(cmt_sgn))
        (cCrt, rCrt
        ,cEnd, rEnd)= crts[0]
        (rCmtBgn
        ,rCmtEnd)   = minmax(rCrt, rEnd if -1!=rEnd else rCrt)
        uncmtAll    = ed.get_text_line(rCmtBgn).lstrip().startswith(cmt_sgn)
        pass;                   LOG and log('rCmtBgn,rCmtEnd,uncmtAll={}', (rCmtBgn,rCmtEnd,uncmtAll))
        for rCmt in range(rCmtBgn, rCmtEnd+1):
            line    = ed.get_text_line(rCmt)
            pos_body= line.index(line.lstrip())
            pass;               LOG and log('rCmtBgn,rCmtEnd,uncmtAll={}', (rCmtBgn,rCmtEnd,uncmtAll))
            if uncmtAll:
                # Uncomment!
                if not line[pos_body:].startswith(cmt_sgn):
                    # Already no comment
                    continue
                if save_bd_col:
                    line = line.replace(cmt_sgn, blnks4cmt, 1)
                else:
                    line = line.replace(cmt_sgn, ''       , 1)
            else:
                # Comment!
                if cmt_type=='bod' and line[pos_body:].startswith(cmt_sgn):
                    # Body comment already sets - willnot double it
                    continue
                if False:pass
                elif cmt_type=='1st' and save_bd_col and line.startswith(blnks4cmt) :
                    line = line.replace(blnks4cmt, cmt_sgn, 1)
#               elif cmt_type=='1st' and save_bd_col #  !line.startswith(blnks4cmt) :
                elif cmt_type=='1st':#  !save_bd_col
                    line = cmt_sgn+line
                elif cmt_type=='bod' and save_bd_col and line.startswith(blnks4cmt) :
                    line = line.replace(blnks4cmt, cmt_sgn, 1)
                    line = line[:pos_body-len(cmt_sgn)]+cmt_sgn+line[pos_body:]
#               elif cmt_type=='bod' and save_bd_col #  !line.startswith(blnks4cmt) :
                elif cmt_type=='bod':#  !save_bd_col
                    line = line[:pos_body]             +cmt_sgn+line[pos_body:]

            ed.set_text_line(rCmt, line)
            #for rCmt
        if -1==rEnd and opts.get('skip-line-after', True) and (rCrt+1)<ed.get_line_count():
            colCrt  = pos2pos(cCrt  , rCrt,   'smb2col')
            smbCrt1 = pos2pos(colCrt, rCrt+1, 'col2smb')
            ed.set_caret(smbCrt1, rCrt+1)
Пример #31
0
def find_tree_node():
    pass;                       log4fun=-1==-1  # Order log in the function
    HELP_C  = _('''
Search starts on Enter.
• A found node after current one will be selected.
• All found nodes are remembered and dialog can jump over them by [Shift+]Enter or by menu commands.
• If option "O" (wrapped search) is tuned on:
    - Search continues from the start, when end of the tree is reached
    - Jumps to previous/next nodes are looped too
• Option ".*" (regular expression) allows to use Python reg.ex. See "docs.python.org/3/library/re.html".
• Option "w" (whole words) is ignored if entered string contains not a word.
• If option "Close on success" (in menu) is tuned on, dialog will close after successful search.
• Option "Show full tree path" (in menu) shows in the statusbar the path of the found node (names of all parents).
• Command "Restore initial selection" (in menu) restores only first of initial carets.
    ''').strip()
    ed_crts = ed.get_carets()           # Carets at start
    opts    = d(reex=False,case=False,word=False,wrap=False,hist=[],clos=False,fpth=False)
    opts.update(get_hist('tree.find_node', opts))
    # Scan Tree
    ID_TREE = app.app_proc(app.PROC_SIDEPANEL_GET_CONTROL, 'Code tree')
    if not ID_TREE: return app.msg_status(_('No CodeTree'))
    if not app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, 0):   # 0 is root
        ed.cmd(cmds.cmd_TreeUpdate)                         # Try to build tree
    tree_t  = []        # [{nid:ID, sub:[{nid:ID, sub:{}, cap:'smth', path:['rt','smth']},], cap:'rt', path:[]},]
    tree_p  = []        # [,(ID, 'smth',['rt','smth']),]
    def scan_tree(id_prnt, tree_nds, path_prnt):
        nonlocal tree_p
        kids            = app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, id_prnt)
        if kids is None:    return None
        for nid, cap in kids:
            path        = path_prnt + [cap]
            tree_p     += [(nid, cap, path)]
            sub         = scan_tree(nid, [], path)
        return tree_nds
       #def scan_tree
    scan_tree(0, tree_t, [])    # 0 is root
    pass;                      #log('tree_t={}',pfrm100(tree_t)) if iflog(log4fun,_log4mod) else 0
    pass;                      #log('tree_p={}',pfrm100(tree_p)) if iflog(log4fun,_log4mod) else 0
        
    # How to select node
    def select_node(nid):
        app.tree_proc(ID_TREE, app.TREE_ITEM_SELECT, nid)
        c_min, r_min,   \
        c_max, r_max    = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_RANGE, nid)
        ed.set_caret(c_min, r_min)
       #def select_node
        
    # Ask
    MAX_HIST= apx.get_opt('ui_max_history_edits', 20)
    stbr    = None
    status  = lambda msg:  app.statusbar_proc(stbr, app.STATUSBAR_SET_CELL_TEXT, tag=1, value=msg)
    def add_to_hist(val, lst):
        """ Add/Move val to list head. """
        if val in lst:
            if 0 == lst.index(val):   return lst
            lst.remove(val)
        lst.insert(0, val)
        if len(lst)>MAX_HIST:
            del lst[MAX_HIST:]
        return lst
       #def add_to_hist
    compile_pttn= lambda    pttn_s, reex, case, word: re.compile(
                            pttn_s          if reex else
                      r'\b'+pttn_s+r'\b'    if word and re.match('^\w+$', pttn_s) else
                  re.escape(pttn_s)
                        ,   0 if case else re.I)
        
    prev_wt = None          # Prev what
    ready_l = []            # [(nid,cap|path,ndn)]
    ready_p = -1            # pos in ready_l
    nfnd_st = lambda: status(_('No suitable nodes'))
    ready_st= lambda: status(f('{pos}/{all}:  {cap}', pos=1+ready_p, all=len(ready_l), cap=ready_l[ready_p][1]))
    ready_er= lambda: status(_('Error'))
        
    def do_attr(ag, aid, data=''):
        nonlocal prev_wt
        prev_wt = ''
        return d(fid='what')
    
    def do_menu(ag, aid, data=''):
        def wnen_menu(ag, tag):
            nonlocal opts, prev_wt
            if   tag in ('prev','next'):    return do_next(ag, tag)
            if   tag in ('fpth','clos'):    prev_wt = '';   opts[tag] = not opts[tag]
            elif tag=='help':               app.msg_box(HELP_C, app.MB_OK)
            elif tag=='rest':               ed.set_caret(*ed_crts[0]);      return None
            return []
           #def wnen_menu
        
        ag.show_menu(
            [ d(    tag='help'  ,cap=_('&Help...')
            ),d(                 cap='-'
            ),d(    tag='prev'  ,cap=_('Find &previous')                                ,key='Shift+Enter'
            ),d(    tag='next'  ,cap=_('F&ind next')                                    ,key='Enter'
            ),d(                 cap='-'
            ),d(                 cap=_('&Options')  ,sub=
                [ d(tag='fpth'  ,cap=_('Show full tree path')   ,ch=opts['fpth']
                ),d(tag='clos'  ,cap=_('Close on success')      ,ch=opts['clos']
            )]),d(               cap='-'
            ),d(    tag='rest'  ,cap=_('Restore initial selection and close dialog &=') ,key='Shift+Esc'
            )]
        ,   aid
        ,   cmd4all=wnen_menu                                   # Set cmd=wnen_menu for all nodes
        )
        return d(fid='what')
       #def do_menu
    
    def do_next(ag, aid, data=''):
        if not ready_l:         return d(fid='what')
        nonlocal ready_p
        ready_n = ready_p + (-1 if aid=='prev' else 1)
        ready_n = ready_n % len(ready_l) if opts['wrap'] else max(0, min(len(ready_l)-1, ready_n), 0)
        pass;                  #log('ready_n,ready_p={}',(ready_n,ready_p)) if iflog(log4fun,_log4mod) else 0
        if ready_p == ready_n:  return d(fid='what')
        ready_p = ready_n
        ready_st()
        select_node(ready_l[ready_p][0])
        return d(fid='what')
       #def do_next
    
    def do_find(ag, aid, data=''):
        nonlocal opts, tree_p, prev_wt, ready_l, ready_p
        # What/how/where will search
        what        = ag.val('what')
        if prev_wt==what and ready_l:
            return do_next(ag, 'next')
        prev_wt  = what
        pass;                  #log('what={}',(what)) if iflog(log4fun,_log4mod) else 0
        if not what:
            ready_l, ready_p    = [], -1
            return d(fid='what')
        opts['hist']= add_to_hist(what, opts['hist'])
        opts.update(ag.vals(['reex','case','word','wrap']))
        pass;                  #log('opts={}',(opts)) if iflog(log4fun,_log4mod) else 0
        tree_sid    = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_SELECTED)    # cur
        nodes       = tree_p                                                # To find from top
        if tree_sid and opts['clos']:                                       # To find from cur
            # Trick: [..,i,sid]+[j,..]   switch to   [j,..] or [j,..]+[..,i]  to search first after cur
            nids    = [nid for nid, cap, path in tree_p]
            pos     = nids.index(tree_sid)
            nodes   = tree_p[pos+1:] + (tree_p[:pos] if opts['wrap'] else [])
        # Search
        ready_l = []
        tree_ndn= -1
        try:
            pttn_r  = compile_pttn(what, opts['reex'], opts['case'], opts['word'])
        except:
            ready_er()
            return d(ctrls=[('what',d(items=opts['hist']))]
                    ,fid='what')
        for ndn, (nid, cap, path) in enumerate(nodes):
            if not pttn_r.search(cap):  continue
            if opts['clos']:
                select_node(nid)
                return None         # Close dlg
            ready_l+= [(nid, ' / '.join(path) if opts['fpth'] else cap, ndn)]
            tree_ndn= ndn if ndn==tree_sid else tree_ndn
        pass;                  #log('ready_l={}',(ready_l)) if iflog(log4fun,_log4mod) else 0
        ready_p = -1    if not ready_l  else \
                  0     if not tree_sid else \
                  first_true(enumerate(ready_l), 0, (lambda n_nid_cap_ndn: n_nid_cap_ndn[1][2]>tree_ndn))[0]
        pass;                  #log('ready_p={}',(ready_p)) if iflog(log4fun,_log4mod) else 0
        # Show results
        if ready_p!=-1:
            select_node(ready_l[ready_p][0])
            if opts['clos']:
                return None         # Close dlg
            ready_st()
        else:
            nfnd_st()
        return d(ctrls=[('what',d(items=opts['hist']))]
                ,fid='what')
       #def do_find
    
    def do_key_down(ag, key, data=''):
        scam    = data if data else app.app_proc(app.PROC_GET_KEYSTATE, '')
        pass;                  #log('key,data,scam={}',(key,data,scam)) if iflog(log4fun,_log4mod) else 0
        if 0:pass
        elif (scam,key)==('s',VK_ENTER):        # Shift+Enter
            ag.update(do_next(ag, 'prev'))
        elif (scam,key)==('s',VK_ESCAPE):       # Shift+Esc
            ed.set_caret(*ed_crts[0])
            return None
        else: return [] # Nothing
        return False    # Stop event
       #def do_key_down
    
    ag      = DlgAg(
        form    =dict(cap=_('Find tree node'), w=365, h=58, h_max=58
                     ,on_key_down=do_key_down
                     ,border=app.DBORDER_TOOLSIZE
#                    ,resize=True
                     )
    ,   ctrls   =[0
  ,('find',d(tp='bttn',y=0          ,x=-99      ,w=44   ,cap=''     ,sto=False  ,def_bt=T           ,on=do_find         ))  # Enter
  ,('reex',d(tp='chbt',tid='what'   ,x=5+38*0   ,w=39   ,cap='.&*'  ,hint=_('Regular expression')   ,on=do_attr         ))  # &*
  ,('case',d(tp='chbt',tid='what'   ,x=5+38*1   ,w=39   ,cap='&aA'  ,hint=_('Case sensitive')       ,on=do_attr         ))  # &a
  ,('word',d(tp='chbt',tid='what'   ,x=5+38*2   ,w=39   ,cap='"&w"' ,hint=_('Whole words')          ,on=do_attr         ))  # &w
  ,('wrap',d(tp='chbt',tid='what'   ,x=5+38*3   ,w=39   ,cap='&O'   ,hint=_('Wrapped search')       ,on=do_attr         ))  # &/
  ,('what',d(tp='cmbx',y  =5        ,x=5+38*4+5 ,w=155  ,items=opts['hist']                                     ,a='r>' ))  # 
  ,('menu',d(tp='bttn',tid='what'   ,x=320      ,w=40   ,cap='&='                                   ,on=do_menu ,a='>>' ))  # &=
  ,('stbr',d(tp='stbr'              ,x=0        ,r=365                                  ,ali=ALI_BT             ,a='r>' ))  # 
                ][1:]
    ,   fid     ='what'
    ,   vals    = {k:opts[k] for k in ('reex','case','word','wrap')}
                          #,options={'gen_repro_to_file':'repro_dlg_find_tree_node.py'}
    )
    stbr    = ag.chandle('stbr')
    app.statusbar_proc(stbr, app.STATUSBAR_ADD_CELL             , tag=1)
    app.statusbar_proc(stbr, app.STATUSBAR_SET_CELL_AUTOSTRETCH , tag=1, value=True)
    ag.show(lambda ag: set_hist('tree.find_node', upd_dict(opts, ag.vals(['reex','case','word','wrap']))))
Пример #32
0
def set_nearest_tree_node():
    path_l, gap = _get_best_tree_path(ed.get_carets()[0][1])
    if not path_l:  return
    ID_TREE = app.app_proc(app.PROC_SIDEPANEL_GET_CONTROL, 'Code tree')
    if not ID_TREE: return
    app.tree_proc(ID_TREE, app.TREE_ITEM_SELECT, path_l[-1][0])
Пример #33
0
    def cmt_toggle_stream(self):
        ''' '''
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(f(_('{} works only with normal selection'), _('Commenting')))
        lex     = ed.get_prop(app.PROP_LEXER_CARET)
        ((bgn_sgn
        ,end_sgn)
        ,bOnlyLn)=self._get_cmt_pair(lex)
        if not bgn_sgn:
            return app.msg_status(f(_('No stream comment for lexer "{}"'), lex))
        bUseFLn = apx.get_opt('comment_full_line_if_no_sel', True)
        crts    = ed.get_carets()
        pass;                  #LOG and log('lex, get_carets()={}', (lex, crts))
        pass;                  #LOG and log('(bgn_sgn,end_sgn),bOnlyLn,bUseFLn={}', ((bgn_sgn,end_sgn),bOnlyLn,bUseFLn))
        for icrt, (cCrt, rCrt, cEnd, rEnd) in enumerate(crts):
            pass;              #LOG and log('(cCrt, rCrt), (cEnd, rEnd)={}', ((cCrt, rCrt), (cEnd, rEnd)))
            bEmpSel     = -1==rEnd
            bDrtSel     = -1==rEnd or (rCrt, cCrt)>(rEnd, cEnd)
            if False:pass
            elif bEmpSel and (bUseFLn or bOnlyLn):
                # Use full line
                line        = ed.get_text_line(rCrt)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rCrt), (len(line), rCrt)
            elif bOnlyLn: # and not bEmpSel
                # Only full lines
                rTx1, rTx2  = apx.minmax(rCrt, rEnd)
                line    = ed.get_text_line(rTx2)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rTx1), (len(line), rTx2)
            elif bEmpSel: # and not bUseFLn and not bOnlyLn
                continue
            else:
                (rTx1, cTx1), (rTx2, cTx2) = apx.minmax((rCrt, cCrt), (rEnd, cEnd))
            selTx   = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
            pass;              #LOG and log('(rTx1, cTx1), (rTx2, cTx2), selTx={}', ((rTx1, cTx1), (rTx2, cTx2), repr(selTx)))
            do_uncmt= selTx.startswith(bgn_sgn) and selTx.endswith(end_sgn)
            pass;              #LOG and log('do_uncmt={}', (do_uncmt))

            if False:pass
            elif not do_uncmt and bOnlyLn:
                # Comment!
                ed.insert(0, rTx2+1, end_sgn+'\n')    #! true insert sequence
                ed.insert(0, rTx1,   bgn_sgn+'\n')    #! true insert sequence
                (cNSel1, rNSel1
                ,cNSel2, rNSel2)    = 0, rTx1, len(end_sgn), rTx2+2
            elif not do_uncmt:
                # Comment!
                ed.insert(cTx2, rTx2, end_sgn)        #! true insert sequence
                ed.insert(cTx1, rTx1, bgn_sgn)        #! true insert sequence
                if False:pass
                elif rTx1==rTx2:
                    # sel into one row
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2+len(bgn_sgn)+len(end_sgn), rTx2
                elif rTx1!=rTx2:
                    # sel ends on diff rows
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2             +len(end_sgn), rTx2

            elif do_uncmt and bOnlyLn:
                # UnComment!
                ed.delete(0, rTx2, 0, rTx2+1)    #! true delete sequence
                ed.delete(0, rTx1, 0, rTx1+1)    #! true delete sequence
                (cNSel1, rNSel1
                ,cNSel2, rNSel2)    = 0, rTx1, len(ed.get_text_line(rTx2-2)), rTx2-2
            elif do_uncmt:
                # UnComment!
                ed.delete(cTx2-len(end_sgn), rTx2, cTx2, rTx2)    #! true delete sequence
                ed.delete(cTx1, rTx1, cTx1+len(bgn_sgn), rTx1)    #! true delete sequence
                if False:pass
                elif rTx1==rTx2:
                    # sel into one row
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2-len(bgn_sgn)-len(end_sgn), rTx2
                elif rTx1!=rTx2:
                    # sel ends on diff rows
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2             -len(end_sgn), rTx2

            pass;              #LOG and log('bDrtSel, (cNSel1, rNSel1), (cNSel2, rNSel2)={}', (bDrtSel, (cNSel1, rNSel1), (cNSel2, rNSel2)))
            if bDrtSel:
                ed.set_caret(cNSel2, rNSel2, cNSel1, rNSel1, app.CARET_SET_INDEX+icrt)
            else:
                ed.set_caret(cNSel1, rNSel1, cNSel2, rNSel2, app.CARET_SET_INDEX+icrt)
           #for icrt
        bSkip    = apx.get_opt('comment_move_down', True)
        if False:pass
        elif 1==len(crts) and bEmpSel and bUseFLn and bSkip:
            apx._move_caret_down(cCrt, rCrt)
            if bOnlyLn and not do_uncmt:
                crt=ed.get_carets()[0]; apx._move_caret_down(crt[0], crt[1])
                crt=ed.get_carets()[0]; apx._move_caret_down(crt[0], crt[1])
Пример #34
0
 def run(self, mcr_id, times=1, waits=0, while_chngs=False, till_endln=False):
     ''' Main (and single) way to run any macro
     '''
     pass;                   LOG and log('mcr_id, times, waits, while_chngs, till_endln={}',(mcr_id, times, waits, while_chngs, till_endln))
     mcr     = self.mcr4id.get(str(mcr_id))
     if mcr is None:
         pass;               LOG and log('no id',)
         return app.msg_status('No macros: {}'.format(mcr_id))
     cmds4eval   = ';'.join(mcr['evl'])
     pass;                   LOG and log('nm, cmds4eval={}',(mcr['nm'], cmds4eval))
     how_t       = 'wait'
     rp_ctrl     = self.tm_ctrl.get('rp_ctrl', 1000)                     # testing one of 1000 execution
     tm_wait     = waits if waits>0 else self.tm_ctrl.get('tm_wait', 10) # sec
     start_t     = datetime.datetime.now()
     pre_body    = '' if not while_chngs else ed.get_text_all()
     for rp in range(times if times>0 else 0xffffffff):
         exec(cmds4eval)
         if till_endln and ed.get_carets()[0][1] == ed.get_line_count()-1:
             pass;           LOG and log('break endln',)
             break   #for rp
         if while_chngs:
             new_body    = ed.get_text_all()
             if pre_body == new_body:    
                 pass;       LOG and log('break no change',)
                 break   #for rp
             pre_body    = new_body
         if  (how_t=='wait'
         and (rp_ctrl-1) == rp % rp_ctrl
         and tm_wait < (datetime.datetime.now()-start_t).seconds):
             WD_BTN  = 220
             ans = app.dlg_custom(  'Playback macro', GAP*2+WD_BTN, GAP*7+4*25,  '\n'.join([]
                 +[C1.join(['type=label'     ,POS_FMT(l=GAP,  t=GAP*1+25*0+3,   r=GAP+WD_BTN, b=0)
                           ,'cap=Macro playback time is too long'
                           ] # i=0
                  )]
                 +[C1.join(['type=button'    ,POS_FMT(l=GAP,  t=GAP*2+25*1,    r=GAP+WD_BTN, b=0)
                           ,'cap=Wait &another {} sec'.format(tm_wait)
                           ] # i=1
                  )]
                 +[C1.join(['type=button'    ,POS_FMT(l=GAP,  t=GAP*3+25*2,    r=GAP+WD_BTN, b=0)
                           ,'cap=Continue &without control'
                           ] # i=2
                  )]
                 +[C1.join(['type=button'    ,POS_FMT(l=GAP,  t=GAP*6+25*3,    r=GAP+WD_BTN, b=0)
                           ,'cap=&Cancel playback [ESC]'
                           ] # i=3
                  )]
                 ), 1)    # start focus
             pass;          #LOG and log('ans={}',ans)
             ans     =('break'   if ans is None  else
                       'break'   if ans[0]==3    else
                       'wait'    if ans[0]==1    else
                       'cont'    if ans[0]==2    else 'break')
             if ans=='cont':
                 how_t   = 'work'
             if ans=='wait':
                 start_t = datetime.datetime.now()
             if ans=='break':
                 pass;       LOG and log('break by user',)
                 break   #for rp
        #for rp
     self.last_mcr_id = mcr_id
Пример #35
0
 def find_cb_string(self, updn, bgn_crt_fin='crt'):
     ''' Find clipboard value in text.
         Params
             updn            'up'|'dn' - direction
             bgn_crt_fin     'bgn'|'crt'|'fin' - start point
     '''
     clip    = app.app_proc(app.PROC_GET_CLIP, '')
     if ''==clip:    return
     clip    = clip.replace('\r\n', '\n').replace('\r', '\n')
     pass;                  #LOG and log('clip={}',repr(clip))
     crts    = ed.get_carets()
     if len(crts)>1:
         return app.msg_status(ONLY_SINGLE_CRT.format('Command'))
     # Prepare bgn-, crt-, fin-point
     (cBgn, rBgn)    = (0, 0)
     (cCrt, rCrt
     ,cEnd, rEnd)    = crts[0]
     lst_line_ind    = ed.get_line_count()-1
     lst_line        = ed.get_text_line(lst_line_ind)
     (cFin, rFin)    = (max(0, len(lst_line)-1), lst_line_ind)
     if bgn_crt_fin=='crt':
         # Some cases for natural (not wrap) find
         if updn=='dn' and (cFin, rFin) == (cCrt, rCrt):
             # Caret at finish - immediately find from start
             return self.find_cb_string(updn, bgn_crt_fin='bgn')
         if updn=='up' and (cBgn, rBgn) == (cCrt, rCrt):
             # Caret at start - immediately find from finish
             return self.find_cb_string(updn, bgn_crt_fin='fin')
         if updn=='dn' and (cBgn, rBgn) == (cCrt, rCrt):
             # Caret already at start - switch wrap off
             bgn_crt_fin = 'bgn'
         if updn=='up' and (cFin, rFin) == (cCrt, rCrt):
             # Caret already at finish - switch wrap off
             bgn_crt_fin = 'fin'
     (cPnt, rPnt
     ,cEnd, rEnd)    = apx.icase(False,0
                         ,bgn_crt_fin=='bgn', (cBgn, rBgn, cBgn, rBgn)
                         ,bgn_crt_fin=='crt', (cCrt, rCrt, cEnd, rEnd)
                         ,bgn_crt_fin=='fin', (cFin, rFin, cFin, rFin)
                         )
     # Main part
     if '\n' not in clip:
         # 1) Find inside each line
         row     = rPnt
         line    = ed.get_text_line(row)
         pos     = line.find(clip, cPnt) if updn=='dn' else line.rfind(clip, 0, cPnt)
         while -1==pos:
             row     = apx.icase(updn=='dn', row+1,   updn=='up', row-1,   -1)
             if row<0 or row==ed.get_line_count():
                 break #while
             line    = ed.get_text_line(row)
             pos     = line.find(clip) if updn=='dn' else line.rfind(clip)
         if False:pass
         elif -1==pos  and bgn_crt_fin!='crt':
             return app.msg_status(FIND_FAIL_FOR_STR.format(clip))
         elif -1==pos:#and bgn_crt_fin=='crt'
             # Wrap!
             return self.find_cb_string(updn, bgn_crt_fin=apx.icase(updn=='dn', 'bgn', 'fin'))
         elif updn=='dn':
             ed.set_caret(pos+len(clip), row, pos, row)
         elif updn=='up':
             ed.set_caret(pos, row, pos+len(clip), row)
         return
     # 2) Find m-line
     pass;                  #LOG and log('')
     clpls   = clip.split('\n')
     pass;                  #LOG and log('clpls={}',(clpls))
     clip    = repr(clip)
     if False:pass
     elif updn=='dn':
         found   = False
         row     = max(rPnt, rEnd if rEnd!=-1 else rPnt)
         if row+len(clpls) < ed.get_line_count():
             txtls   = [ed.get_text_line(r) for r in range(row, row+len(clpls))]
             pass;          #LOG and log('txtls={}',(txtls))
             while True:
                 if self._find_cb_string_included_mlines(txtls, clpls):
                     # Found!
                     found   = True
                     break #while
                 row     = row+1
                 pass;          #LOG and log('row={}',(row))
                 if row+len(clpls) >= ed.get_line_count():
                     pass;  #LOG and log('nfnd12',)
                     break #while
                 txtls   = txtls[1:]+[ed.get_text_line(row+len(clpls)-1)]
                 pass;      #LOG and log('txtls={}',(txtls))
                #while
         if False:pass
         elif not found  and bgn_crt_fin!='crt':
             return app.msg_status(FIND_FAIL_FOR_STR.format(clip))
         elif not found:#and bgn_crt_fin=='crt'
             # Wrap!
             return self.find_cb_string(updn, bgn_crt_fin=apx.icase(updn=='dn', 'bgn', 'fin'))
         ed.set_caret(len(clpls[-1]), row+len(clpls)-1, len(txtls[0])-len(clpls[0]), row)
     elif updn=='up':
         found   = False
         row     = min(rPnt, rEnd if rEnd!=-1 else rPnt)
         if row-len(clpls)+1 >= 0:
             txtls   = [ed.get_text_line(r) for r in range(row-len(clpls)+1, row+1)]
             pass;          #LOG and log('txtls={}',(txtls))
             while True:
                 if self._find_cb_string_included_mlines(txtls, clpls):
                     # Found!
                     found   = True
                     break #while
                 row     = row-1
                 pass;          #LOG and log('row={}',(row))
                 if row-len(clpls)+1 < 0:
                     break #while
                 txtls   = [ed.get_text_line(row-len(clpls)+1)]+txtls[:-1]
                 pass;          #LOG and log('txtls={}',(txtls))
                #while
         if False:pass
         elif not found  and bgn_crt_fin!='crt':
             return app.msg_status(FIND_FAIL_FOR_STR.format(clip))
         elif not found:#and bgn_crt_fin=='crt'
             # Wrap!
             return self.find_cb_string(updn, bgn_crt_fin=apx.icase(updn=='dn', 'bgn', 'fin'))
         ed.set_caret(len(clpls[-1]), row, len(txtls[0])-len(clpls[0]), row-len(clpls)+1)
Пример #36
0
    def _prep_sess(self, wdex='word'):
        """ Params
                wdex    Type of sess:   'word' / 'expr'
        """
        crts    = ed.get_carets()
        if len(crts)>1: 
            return app.msg_status(_("Command doesnt work with multi-carets"))
        (cCrt, rCrt
        ,cEnd, rEnd)= crts[0]
        if -1!=rEnd and rCrt!=rEnd:
            return app.msg_status(_("Command doesnt work with multi-line selection"))

        stayed      =   self.sess     \
                    and self.sess.pre_mver == ed.get_prop(app.PROP_MODIFIED_VERSION) \
                    and self.sess.pre_crt0 == crts[0]
        
        cEnd, rEnd  = (cCrt, rCrt) if -1==rEnd else (cEnd, rEnd)
        sel_be_eb   = 'be' if cCrt>cEnd else 'eb' if cCrt<cEnd else ''
        ((rSelB, cSelB)
        ,(rSelE, cSelE))= apx.minmax((rCrt, cCrt), (rEnd, cEnd))
        pass;                  #LOG and stayed and log('stayed,(wdex,self.sess.wdex)={}',(stayed,(wdex,self.sess.wdex)))
        if stayed   and   wdex==self.sess.wdex:
            # Sess OK
            return True

        what        = ''                    # Str to find
        what_b      = -1                    # Pos what begin
        what_e      = -1                    # Pos what end
        kill_b      = -1                    # Pos kill begin
        kill_e      = -1                    # Pos kill end
        wbnd        = True                  # Need left word bound
        sel         = ''
        if stayed   and   wdex!=self.sess.wdex:
            # Change sess type
            what    = self.sess.src_what
            what_b  = self.sess.src_what_b
            what_e  = self.sess.src_what_e
            kill_b  = self.sess.src_kill_b
            kill_e  = self.sess.src_kill_e
            wbnd    = self.sess.src_wbnd
        if not stayed:
            # New sess
            line    = ed.get_text_line(rCrt)
            sel     = ed.get_text_sel()
            if sel:
                # Use selection to find
                what    = sel
                what_b  = cSelB
                what_e  = cSelE
                wbnd    = 0==cSelB or line[cSelB-1].isspace()
            else:
                # Use "chars around caret" to find what
                tx_bfr  = line[:cCrt ]
                ch_bfr  = tx_bfr[-1] if tx_bfr else ' '
                tx_aft  = line[ cCrt:]
                ch_aft  = tx_aft[ 0] if tx_aft else ' '
                pass;          #LOG and log('ch_bfr,ch_aft,tx_bfr,tx_aft={}',(ch_bfr,ch_aft,tx_bfr,tx_aft))
                shf_l   = 0
                shf_r   = 0
                if ch_bfr.isalnum() or ch_bfr in self.wdsgns:
                    tx_bfr_r= ''.join(reversed(tx_bfr))
                    shf_l   = len(self.base_re.match(tx_bfr_r).group())
                if ch_aft.isalnum() or ch_aft in self.wdsgns:
                    shf_r   = len(self.base_re.match(tx_aft).group())
                what_b  = cCrt-shf_l
                if self.kill:
                    what_e  = cCrt
                    kill_b  = cCrt
                    kill_e  = cCrt+shf_r
                else:
                    what_e  = cCrt+shf_r
                what    = line[what_b:what_e]
                pass;          #LOG and log('(shf_l,shf_r), (what_b,what_e), what={}',((shf_l,shf_r), (what_b,what_e), what))
        
        if not  what \
        or not  what.strip():
            return app.msg_status(_('No data for search'))
        if len(what) < self.min_len:
            return app.msg_status(f(_('Need |base|>={}, but |"{}"|=={}'), self.min_len, what, len(what)))
        pass;                  #LOG and log('what,wbnd={}',(what,wbnd))
        
        asword              = wdex=='word'
        asexpr              = wdex=='expr'
        # Make new Sess
        if not stayed:
            pass;              #LOG and log('new sess',())
            self.sess           = Command.Sess()
            self.sess.row       = rCrt
            self.sess.sel_sub   = sel_be_eb
            self.sess.src_crt   = cCrt
            self.sess.src_what  = what
            self.sess.src_what_b= what_b
            self.sess.src_what_e= what_e
            self.sess.src_kill_b= kill_b
            self.sess.src_kill_e= kill_e
            self.sess.src_wbnd  = wbnd
        self.sess.wdex          = wdex
        what_re = re.compile(''
                            + (r'\b' if wbnd else '')
                            + re.escape(what)
                            + (self.wdcmpl if asword else self.excmpl)
                            )
#               +  r'[\w'+re.escape(self.wdsgns)+']+')
        pass;                  #LOG and log('what_re={}',(what_re.pattern))
        bids_d  = OrdDict()
        for line_n in range(ed.get_line_count()):
            if line_n == self.sess.row: continue#for line_n
            line    = ed.get_text_line(line_n)
            if asexpr and self.expair:
                # Find+expand upto close brackets/quotes
                lbids_l = []
                for m in what_re.finditer(line):
                    lbid    = m.group(0)
                    
                    ok      = False
                    for op, cl in self.opn2cls.items():
                        if  op in lbid and  lbid.count(op)      > lbid.count(cl):   # Try expand to good cl
                            ext_bgn = m.end()
                            ext_end = line.find(cl, ext_bgn)
                            while -1!=ext_end:
                                lbid_ext    = lbid + line[ext_bgn:ext_end+1]
                                if          lbid_ext.count(op) == lbid_ext.count(cl):
                                    lbid,ok = lbid_ext, True
                                    break#while
                                ext_end = line.find(cl, ext_end+1)
                        if ok: break#for op
                       #for op
                    ok      = False
                    for qu in self.quotes:
                        if  qu in lbid and  1 == lbid.count(qu)     % 2:            # Try expand to good qu
                            ext_bgn = m.end()
                            ext_end = line.find(qu, ext_bgn)
                            while -1!=ext_end:
                                lbid_ext    = lbid + line[ext_bgn:ext_end+1]
                                if          0 == lbid_ext.count(qu) % 2:
                                    lbid,ok = lbid_ext, True
                                    break#while
                                ext_end = line.find(cl, ext_end+1)
                        if ok: break#for qu
                       #for qu
                    
                    lbids_l.append(lbid)
                   #for m
            else:
                # Find only
                lbids_l = what_re.findall(line)
            if lbids_l:
                bids_d.update({bid:line_n 
                                for bid in lbids_l 
                                if  bid not in bids_d
                                or  abs(line_n-self.sess.row)<abs(bids_d[bid]-self.sess.row)
                              })  # closest
        if not bids_d:
            return app.msg_status(_('No in-text completions'))
            
        self.sess.bids  = list(bids_d.keys())
        self.sess.bids_c= list(bids_d.values())
        self.sess.bids_i= min([(abs(bid_r-self.sess.row), bid_i) 
                                for (bid_i,bid_r) in enumerate(self.sess.bids_c)
                              ])[1] \
                            if len(self.sess.bids)>1 and self.near else \
                          0
        self.incr_bfr   = False  # Dont increment before use
        pass;                  #LOG and log('bids={}',(list(zip(self.sess.bids, self.sess.bids_c))))
        pass;                  #LOG and log('sess={}',(self.sess))
        pass;                  #return False
        return True
Пример #37
0
 def run(self,
         mcr_id,
         times=1,
         waits=0,
         while_chngs=False,
         till_endln=False):
     ''' Main (and single) way to run any macro
     '''
     pass
     LOG and log('mcr_id, times, waits, while_chngs, till_endln={}',
                 (mcr_id, times, waits, while_chngs, till_endln))
     mcr = self.mcr4id.get(str(mcr_id))
     if mcr is None:
         pass
         LOG and log('no id', )
         return app.msg_status('No macros: {}'.format(mcr_id))
     cmds4eval = ';'.join(mcr['evl'])
     pass
     LOG and log('nm, cmds4eval={}', (mcr['nm'], cmds4eval))
     how_t = 'wait'
     rp_ctrl = self.tm_ctrl.get('rp_ctrl',
                                1000)  # testing one of 1000 execution
     tm_wait = waits if waits > 0 else self.tm_ctrl.get('tm_wait',
                                                        10)  # sec
     start_t = datetime.datetime.now()
     pre_body = '' if not while_chngs else ed.get_text_all()
     for rp in range(times if times > 0 else 0xffffffff):
         exec(cmds4eval)
         if till_endln and ed.get_carets()[0][1] == ed.get_line_count() - 1:
             pass
             LOG and log('break endln', )
             break  #for rp
         if while_chngs:
             new_body = ed.get_text_all()
             if pre_body == new_body:
                 pass
                 LOG and log('break no change', )
                 break  #for rp
             pre_body = new_body
         if (how_t == 'wait' and (rp_ctrl - 1) == rp % rp_ctrl and tm_wait <
             (datetime.datetime.now() - start_t).seconds):
             WD_BTN = 220
             ans = app.dlg_custom(
                 'Playback macro',
                 GAP * 2 + WD_BTN,
                 GAP * 7 + 4 * 25,
                 '\n'.join([] + [
                     C1.join([
                         'type=label',
                         POS_FMT(l=GAP,
                                 t=GAP * 1 + 25 * 0 + 3,
                                 r=GAP + WD_BTN,
                                 b=0), 'cap=Macro playback time is too long'
                     ]  # i=0
                             )
                 ] + [
                     C1.join([
                         'type=button',
                         POS_FMT(
                             l=GAP, t=GAP * 2 + 25 * 1, r=GAP + WD_BTN, b=0
                         ), 'cap=Wait &another {} sec'.format(tm_wait)
                     ]  # i=1
                             )
                 ] + [
                     C1.join([
                         'type=button',
                         POS_FMT(
                             l=GAP, t=GAP * 3 + 25 * 2, r=GAP +
                             WD_BTN, b=0), 'cap=Continue &without control'
                     ]  # i=2
                             )
                 ] + [
                     C1.join([
                         'type=button',
                         POS_FMT(
                             l=GAP, t=GAP * 6 + 25 * 3, r=GAP +
                             WD_BTN, b=0), 'cap=&Cancel playback [ESC]'
                     ]  # i=3
                             )
                 ]),
                 1)  # start focus
             pass
             #LOG and log('ans={}',ans)
             ans = ('break'
                    if ans is None else 'break' if ans[0] == 3 else 'wait'
                    if ans[0] == 1 else 'cont' if ans[0] == 2 else 'break')
             if ans == 'cont':
                 how_t = 'work'
             if ans == 'wait':
                 start_t = datetime.datetime.now()
             if ans == 'break':
                 pass
                 LOG and log('break by user', )
                 break  #for rp
     #for rp
     self.last_mcr_id = mcr_id
Пример #38
0
    def cmt_toggle_stream(self):
        ''' '''
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(f(_('{} works only with normal selection'), _('Commenting')))
        lex     = ed.get_prop(app.PROP_LEXER_CARET)
        ((bgn_sgn
        ,end_sgn)
        ,bOnlyLn)=self._get_cmt_pair(lex)
        if not bgn_sgn:
            return app.msg_status(f(_('No stream comment for lexer "{}"'), lex))
        bUseFLn = True
        crts    = ed.get_carets()
        pass;                  #LOG and log('lex, get_carets()={}', (lex, crts))
        pass;                  #LOG and log('(bgn_sgn,end_sgn),bOnlyLn,bUseFLn={}', ((bgn_sgn,end_sgn),bOnlyLn,bUseFLn))
        for icrt, (cCrt, rCrt, cEnd, rEnd) in enumerate(crts):
            pass;              #LOG and log('(cCrt, rCrt), (cEnd, rEnd)={}', ((cCrt, rCrt), (cEnd, rEnd)))
            bEmpSel     = -1==rEnd
            bDrtSel     = -1==rEnd or (rCrt, cCrt)>(rEnd, cEnd)
            bEntireLn   = (rEnd>=0) and (cEnd==0) and (cCrt==0)
            bEntireLn1  = bEntireLn and abs(rEnd-rCrt)==1
            bEntireLn2  = bEntireLn and abs(rEnd-rCrt)>1
            if False:pass
            elif bEmpSel and (bUseFLn or bOnlyLn):
                # Use full line
                line        = ed.get_text_line(rCrt)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rCrt), (len(line), rCrt)
            elif bOnlyLn: # and not bEmpSel
                # Only full lines
                rTx1, rTx2  = apx.minmax(rCrt, rEnd)
                line    = ed.get_text_line(rTx2)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rTx1), (len(line), rTx2)
            elif bEmpSel: # and not bUseFLn and not bOnlyLn
                continue
            else:
                (rTx1, cTx1), (rTx2, cTx2) = apx.minmax((rCrt, cCrt), (rEnd, cEnd))
            selTx   = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
            pass;              #LOG and log('(rTx1, cTx1), (rTx2, cTx2), selTx={}', ((rTx1, cTx1), (rTx2, cTx2), repr(selTx)))
            do_uncmt= selTx.startswith(bgn_sgn) #and selTx.endswith(end_sgn)
                # don't check for ending of selection - for HTML and entire selected line(s)
            pass;              #LOG and log('do_uncmt={}', (do_uncmt))

            if False:pass
            elif not do_uncmt and bOnlyLn:
                # Comment!
                ed.insert(0, rTx2+1, end_sgn+'\n')    #! true insert sequence
                ed.insert(0, rTx1,   bgn_sgn+'\n')    #! true insert sequence
                (cNSel1, rNSel1
                ,cNSel2, rNSel2)    = 0, rTx1, len(end_sgn), rTx2+2

            elif not do_uncmt:
                # Comment!
                if bEntireLn1:
                    s = ed.get_text_line(rTx1)
                    ed.set_text_line(rTx1, bgn_sgn+s+end_sgn)
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2) = (0, rTx1, 0, rTx2)

                elif bEntireLn2:
                    ed.insert(0, rTx2, end_sgn+'\n')
                    ed.insert(0, rTx1, bgn_sgn+'\n')
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2) = (0, rTx1, 0, rTx2+2)

                else:
                    ed.insert(cTx2, rTx2, end_sgn)        #! true insert sequence
                    ed.insert(cTx1, rTx1, bgn_sgn)        #! true insert sequence
                    if False:pass
                    elif rTx1==rTx2:
                        # sel into one row
                        (cNSel1, rNSel1
                        ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2+len(bgn_sgn)+len(end_sgn), rTx2
                    elif rTx1!=rTx2:
                        # sel ends on diff rows
                        (cNSel1, rNSel1
                        ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2             +len(end_sgn), rTx2

            elif do_uncmt and bOnlyLn:
                # UnComment!
                ed.delete(0, rTx2, 0, rTx2+1)    #! true delete sequence
                ed.delete(0, rTx1, 0, rTx1+1)    #! true delete sequence
                (cNSel1, rNSel1
                ,cNSel2, rNSel2)    = 0, rTx1, len(ed.get_text_line(rTx2-2)), rTx2-2

            elif do_uncmt:
                # UnComment!
                if selTx.endswith(end_sgn):
                    ed.delete(cTx2-len(end_sgn), rTx2, cTx2, rTx2)    #! true delete sequence
                    ed.delete(cTx1, rTx1, cTx1+len(bgn_sgn), rTx1)    #! true delete sequence
                    if False:pass
                    elif rTx1==rTx2:
                        # sel into one row
                        (cNSel1, rNSel1
                        ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2-len(bgn_sgn)-len(end_sgn), rTx2
                    elif rTx1!=rTx2:
                        # sel ends on diff rows
                        (cNSel1, rNSel1
                        ,cNSel2, rNSel2)    = cTx1, rTx1, cTx2             -len(end_sgn), rTx2

                elif bEntireLn1:
                    s = ed.get_text_line(rTx1)
                    if s.startswith(bgn_sgn):
                        s = s[len(bgn_sgn):]
                    if s.endswith(end_sgn):
                        s = s[:-len(end_sgn)]
                    ed.set_text_line(rTx1, s)
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2) = (0, rTx1, 0, rTx2)

                elif bEntireLn2:
                    ed.delete(0, rTx2-1, 0, rTx2)
                    ed.delete(0, rTx1, 0, rTx1+1)
                    (cNSel1, rNSel1
                    ,cNSel2, rNSel2) = (0, rTx1, 0, rTx2-2)

            pass;              #LOG and log('bDrtSel, (cNSel1, rNSel1), (cNSel2, rNSel2)={}', (bDrtSel, (cNSel1, rNSel1), (cNSel2, rNSel2)))
            if bDrtSel:
                ed.set_caret(cNSel2, rNSel2, cNSel1, rNSel1, app.CARET_SET_INDEX+icrt)
            else:
                ed.set_caret(cNSel1, rNSel1, cNSel2, rNSel2, app.CARET_SET_INDEX+icrt)
           #for icrt
        bSkip    = apx.get_opt('comment_move_down', True)
        if False:pass
        elif 1==len(crts) and bEmpSel and bUseFLn and bSkip:
            apx._move_caret_down(cCrt, rCrt)
            if bOnlyLn and not do_uncmt:
                crt=ed.get_carets()[0]; apx._move_caret_down(crt[0], crt[1])
                crt=ed.get_carets()[0]; apx._move_caret_down(crt[0], crt[1])