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')))))
 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')))))
 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')))))
示例#4
0
 def _activate_near_tab(self, gap):
     pass;                  #LOG and log('gap={}',gap)
     eds     = [app.Editor(h) for h in app.ed_handles()]
     if 1==len(eds):    return
     gtes    = [(e.get_prop(app.PROP_INDEX_GROUP), e.get_prop(app.PROP_INDEX_TAB), e) for e in eds]
     gtes    = list(enumerate(sorted(gtes)))
     group   = ed.get_prop(app.PROP_INDEX_GROUP)
     t_ind   = ed.get_prop(app.PROP_INDEX_TAB)
     for g_ind, (g, t, e) in gtes:
         if g==group and t==t_ind:
             g_ind   = (g_ind+gap) % len(gtes)
             gtes[g_ind][1][2].focus()
示例#5
0
    def duplicate(self):
        if ed.get_prop(app.PROP_RO): return

        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)
        ed.set_caret(cCrt, rCrt, cEnd, rEnd)
    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
示例#7
0
 def move_backward(self):
     tab_id  = ed.get_prop(app.PROP_TAB_ID) # уникальный ID вкладки
     if  tab_id not in self.poses or \
         self.poses[tab_id]==0:
         pass;              #LOG and log('skip: no tab or no more to back',())
         return 
     self.poses[tab_id] -= 1
     self._move_caret(self.history[tab_id][self.poses[tab_id]])
示例#8
0
 def move_forward(self):
     tab_id  = ed.get_prop(app.PROP_TAB_ID) # уникальный ID вкладки
     if  tab_id not in self.poses or \
         self.poses[tab_id]>=(len(self.history[tab_id])-1):
         pass;              #LOG and log('skip: no tab or no more to forw',())
         return 
     self.poses[tab_id] += 1
     self._move_caret(self.history[tab_id][self.poses[tab_id]])
 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')))))
 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')))))
示例#11
0
def get_ovrd_ed_opts(ed):
    ans = collections.OrderedDict()
    ans["tab_size"] = ed.get_prop(app.PROP_TAB_SIZE)
    ans["tab_spaces"] = ed.get_prop(app.PROP_TAB_SPACES)
    ans["wrap_mode"] = ed.get_prop(app.PROP_WRAP)
    ans["unprinted_show"] = ed.get_prop(app.PROP_UNPRINTED_SHOW)
    ans["unprinted_spaces"] = ed.get_prop(app.PROP_UNPRINTED_SPACES)
    ans["unprinted_ends"] = ed.get_prop(app.PROP_UNPRINTED_ENDS)
    ans["unprinted_end_details"] = ed.get_prop(app.PROP_UNPRINTED_END_DETAILS)
    return ans
    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 move_tab(how=''):
    group = ed.get_prop(app.PROP_INDEX_GROUP)
    gr_cnt = 0
    for h in app.ed_handles():
        edH = app.Editor(h)
        if (group == edH.get_prop(app.PROP_INDEX_GROUP)
                and gr_cnt < edH.get_prop(app.PROP_INDEX_TAB)):
            gr_cnt = edH.get_prop(app.PROP_INDEX_TAB)
    gr_cnt += 1
    old_pos = ed.get_prop(app.PROP_INDEX_TAB)
    new_pos = None
    if how == '':
        new_pos = app.dlg_input(_(f'New position (max={gr_cnt})'),
                                str(old_pos + 1))
        if new_pos is None: return
        new_pos = max(0, min(gr_cnt, int(new_pos) - 1))
    else:
        step = -1 if how == 'l' else 1
        new_pos = (old_pos + step) % gr_cnt
    if new_pos == old_pos: return
    ed.set_prop(app.PROP_INDEX_TAB, str(new_pos))
 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')))))
    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 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 to_tab_ask_num():
    while True:
        grp_num = app.dlg_input(
            _('What tab number to activate? Input: [group:]number'), '')
        if grp_num is None: return
        if re.match(r'(\d:)?\d+', grp_num):
            break
    me_grp = ed.get_prop(app.PROP_INDEX_GROUP)
    grp = int(grp_num.split(':')[0]) - 1 if ':' in grp_num else me_grp
    num = int(
        grp_num.split(':')[1]) - 1 if ':' in grp_num else int(grp_num) - 1
    for h in app.ed_handles():
        ed_ = app.Editor(h)
        if grp == ed_.get_prop(app.PROP_INDEX_GROUP) and \
           num == ed_.get_prop(app.PROP_INDEX_TAB):
            ed_.focus()
    app.msg_status(f(_('No tab "{}"'), grp_num))
示例#18
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)
示例#19
0
def close_tab_from_other_group(what_grp='next'):
    if app.app_api_version() < '1.0.139': return app.msg_status(NEED_UPDATE)
    grps = apx.get_groups_count()
    if 1 == grps: return
    me_grp = ed.get_prop(app.PROP_INDEX_GROUP)
    cl_grp  = (me_grp+1)%grps \
                if what_grp=='next' else \
              (me_grp-1)%grps
    if not [
            h for h in app.ed_handles()
            if app.Editor(h).get_prop(app.PROP_INDEX_GROUP) == cl_grp
    ]:
        return app.msg_status(_('No files in group'))
    cl_ed = app.ed_group(cl_grp)
    cl_ed.focus()
    cl_ed.cmd(cmds.cmd_FileClose)
    me_ed = app.ed_group(me_grp)
    me_ed.focus()
示例#20
0
def _activate_tab_other_group(what_tab='next', what_grp='next'):
    grps = apx.get_groups_count()
    if 1 == grps: return
    me_grp = ed.get_prop(app.PROP_INDEX_GROUP)
    op_grp  = (me_grp+1)%grps \
                if what_grp=='next' else \
              (me_grp-1)%grps
    op_hs = [
        h for h in app.ed_handles()
        if app.Editor(h).get_prop(app.PROP_INDEX_GROUP) == op_grp
    ]
    if len(op_hs) < 2: return
    op_ed = app.ed_group(op_grp)
    op_ind = op_ed.get_prop(app.PROP_INDEX_TAB)
    op_ind  = (op_ind+1)%len(op_hs)     if what_tab=='next' else \
              (op_ind-1)%len(op_hs)     if what_tab=='prev' else \
              0                         if what_tab=='frst' else \
              len(op_hs)-1              if what_tab=='last' else \
              op_ind
    app.Editor(op_hs[op_ind]).focus()
    me_ed = app.ed_group(me_grp)
    me_ed.focus()
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)
示例#22
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)
示例#23
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])
    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
示例#25
0
    def dlg_config(self):
        ''' Show dlg for change macros list.
        '''
        if app.app_api_version() < FROM_API_VERSION:
            return app.msg_status('Need update CudaText')
        keys_json = app.app_path(app.APP_DIR_SETTINGS) + os.sep + 'keys.json'
        keys = apx._json_loads(
            open(keys_json).read()) if os.path.exists(keys_json) else {}
        GAP = 5

        ids = [mcr['id'] for mcr in self.macros]
        mcr_ind = ids.index(
            self.last_mcr_id) if self.last_mcr_id in ids else -1
        pass
        LOG and log('self.last_mcr_id, mcr_ind={}',
                    (self.last_mcr_id, mcr_ind))
        times = 1
        waits = 5
        chngs = '0'
        endln = '0'
        while True:
            (WD_LST, HT_LST) = (self.dlg_prs.get('w_list', 300),
                                self.dlg_prs.get('h_list', 500))
            (WD_ACTS, HT_ACTS) = (self.dlg_prs.get('w_acts', 300),
                                  self.dlg_prs.get('h_acts', 500))
            (WD_BTN, HT_BTN) = (self.dlg_prs.get('w_btn', 150), 24)
            l_btn = GAP + WD_LST + GAP

            vw_acts = (WD_ACTS > 0)
            WD_ACTS = max(0, WD_ACTS)
            rec_on = ed.get_prop(app.PROP_MACRO_REC)
            lmcrs = len(self.macros)
            pass
            LOG and log('mcr_ind,vw_acts,rec_on={}',
                        (mcr_ind, vw_acts, rec_on))

            nmkys = []
            for mcr in self.macros:
                mcr_cid = 'cuda_macros,run,{}'.format(mcr['id'])
                mcr_keys = keys.get(mcr_cid, {})
                kys = '/'.join([
                    ' * '.join(mcr_keys.get('s1', [])),
                    ' * '.join(mcr_keys.get('s2', []))
                ]).strip('/')
                nmkys += [mcr['nm'] + (' [' + kys + ']' if kys else '')]

            mcr_acts = ''
            if vw_acts and mcr_ind in range(lmcrs):
                mcr = self.macros[mcr_ind]
                mcr_acts = '\t'.join(['# ' + nmkys[mcr_ind]] + mcr['evl'])

            ans = app.dlg_custom(
                'Macros',
                GAP + WD_LST + GAP + WD_BTN + GAP + WD_ACTS + GAP,
                GAP + HT_LST + GAP,
                '\n'.join([] + [
                    C1.join([
                        'type=listbox',
                        POS_FMT(l=GAP, t=GAP, r=GAP + WD_LST, b=GAP + HT_LST),
                        'items=' + '\t'.join(nmkys),
                        'val=' + str(mcr_ind)  # start sel
                        ,
                        'en=' + str(0 if rec_on else 1)  # enabled
                    ]  # i=0
                            )
                ] + ([
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 1 + HT_BTN * 0,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=&View actions...',
                        'props=' +
                        str(0 if rec_on or 0 == lmcrs else 1)  # default
                        ,
                        'en=' +
                        str(0 if rec_on or 0 == lmcrs else 1)  # enabled
                    ]  # i=1
                            )
                ] if vw_acts else []) + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 2 + HT_BTN * 1,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=Hot&keys...',
                        'en=' +
                        str(0 if rec_on or 0 == lmcrs else 1)  # enabled
                    ]  # i=2 if vw_acts else i=1
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 3 + HT_BTN * 2,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=Re&name...',
                        'en=' +
                        str(0 if rec_on or 0 == lmcrs else 1)  # enabled
                    ]  # i=3 if vw_acts else i=2
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 4 + HT_BTN * 3,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=&Delete...',
                        'en=' +
                        str(0 if rec_on or 0 == lmcrs else 1)  # enabled
                    ]  # i=4 if vw_acts else i=3
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 6 + HT_BTN * 5,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=&Run!',
                        'props=' +
                        str(1 if not vw_acts and not rec_on else 0)  # default
                        ,
                        'en=' +
                        str(0 if rec_on or 0 == lmcrs else 1)  # enabled
                    ]  # i=5 if vw_acts else i=4
                            )
                ] + [
                    C1.join([
                        'type=label',
                        POS_FMT(l=l_btn,
                                t=GAP * 7 + HT_BTN * 6 + 3,
                                r=l_btn + int(WD_BTN / 3),
                                b=0), 'cap=&Times'
                    ]  # i=6 if vw_acts else i=5
                            )
                ] + [
                    C1.join([
                        'type=spinedit',
                        POS_FMT(l=l_btn + int(WD_BTN / 3) + GAP,
                                t=GAP * 7 + HT_BTN * 6,
                                r=l_btn + WD_BTN,
                                b=0),
                        'val=' + str(times),
                        'props=0,{},1'.format(self.dlg_prs.get('times', 1000)),
                        'en=' + str(0 if rec_on else 1)  # enabled
                    ]  # i=7 if vw_acts else i=6
                            )
                ] + [
                    C1.join([
                        'type=label',
                        POS_FMT(l=l_btn,
                                t=GAP * 8 + HT_BTN * 7 + 3,
                                r=l_btn + int(WD_BTN / 3),
                                b=0), 'cap=&Wait'
                    ]  # i=8 if vw_acts else i=7
                            )
                ] + [
                    C1.join([
                        'type=spinedit',
                        POS_FMT(l=l_btn + int(WD_BTN / 3) + GAP,
                                t=GAP * 8 + HT_BTN * 7,
                                r=l_btn + WD_BTN - 40,
                                b=0),
                        'val=' + str(waits),
                        'props=1,3600,1',
                        'en=' + str(0 if rec_on else 1)  # enabled
                    ]  # i=9 if vw_acts else i=8
                            )
                ] + [
                    C1.join([
                        'type=label',
                        POS_FMT(l=l_btn + WD_BTN - 40 + GAP,
                                t=GAP * 8 + HT_BTN * 7 + 3,
                                r=l_btn + WD_BTN,
                                b=0), 'cap=sec'
                    ]  # i=10 if vw_acts else i=9
                            )
                ] + [
                    C1.join([
                        'type=check',
                        POS_FMT(l=l_btn,
                                t=GAP * 9 + HT_BTN * 8,
                                r=l_btn + WD_BTN,
                                b=0), 'cap=While text c&hanges', 'val=' + chngs
                    ]  # i=11 if vw_acts else i=10
                            )
                ] + [
                    C1.join([
                        'type=check',
                        POS_FMT(l=l_btn,
                                t=GAP * 10 + HT_BTN * 9,
                                r=l_btn + WD_BTN,
                                b=0), 'cap=Until c&aret on last line', 'val=' +
                        endln
                    ]  # i=12 if vw_acts else i=11
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 12 + HT_BTN * 11,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap={}'.format(
                            '&Stop record' if rec_on else '&Start record'),
                        'props=' +
                        str(1 if rec_on or 0 == lmcrs else 0)  # default
                    ]  # i=13 if vw_acts else i=12
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP * 13 + HT_BTN * 12,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=Canc&el record',
                        'en=' + str(1 if rec_on else 0)  # enabled
                    ]  # i=14 if vw_acts else i=13
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=HT_LST - HT_BTN * 2,
                                r=l_btn + WD_BTN,
                                b=0),
                        'cap=C&ustom...',
                        'en=' + str(0 if rec_on else 1)  # enabled
                    ]  # i=15 if vw_acts else i=14
                            )
                ] + [
                    C1.join([
                        'type=button',
                        POS_FMT(l=l_btn,
                                t=GAP + HT_LST - HT_BTN * 1,
                                r=l_btn + WD_BTN,
                                b=0), 'cap=&Close'
                    ]  # i=16 if vw_acts else i=15
                            )
                ] + ([
                    C1.join([
                        'type=memo',
                        POS_FMT(l=GAP + WD_LST + GAP + WD_BTN + GAP,
                                t=GAP,
                                r=GAP + WD_LST + GAP + WD_BTN + GAP + WD_ACTS,
                                b=GAP + HT_ACTS),
                        'val=' + mcr_acts,
                        'props=1,1,1'  # ro,mono,border
                    ]  # i=17
                            )
                ] if vw_acts else [])),
                apx.icase(
                    vw_acts and not rec_on,
                    0  # View
                    ,
                    not vw_acts and not rec_on,
                    0  # View
                    ,
                    vw_acts and rec_on,
                    11,
                    not vw_acts and rec_on,
                    10))  # start focus
            pass
            LOG and log('ans={}', ans)
            if ans is None: break  #while
            (ans_i, vals) = ans
            ans_s = apx.icase(
                False, '', vw_acts and ans_i == 1, 'view', vw_acts
                and ans_i == 2, 'hotkeys', not vw_acts and ans_i == 1,
                'hotkeys', vw_acts and ans_i == 3, 'rename', not vw_acts
                and ans_i == 2, 'rename', vw_acts and ans_i == 4, 'delete',
                not vw_acts and ans_i == 3, 'delete', vw_acts and ans_i == 5,
                'run', not vw_acts and ans_i == 4, 'run', vw_acts
                and ans_i == 12, 'rec', not vw_acts and ans_i == 7, 'rec',
                vw_acts and ans_i == 14, 'cancel', not vw_acts and ans_i == 13,
                'cancel', vw_acts and ans_i == 15, 'custom', not vw_acts
                and ans_i == 14, 'custom', vw_acts and ans_i == 16, 'close',
                not vw_acts and ans_i == 15, 'close', '?')
            mcr_ind = int(vals.splitlines()[0])
            times = int(vals.splitlines()[7 if vw_acts else 6])
            waits = int(vals.splitlines()[9 if vw_acts else 8])
            chngs = vals.splitlines()[11 if vw_acts else 10]
            endln = vals.splitlines()[12 if vw_acts else 11]
            pass
            LOG and log('mcr_ind,times,waits,chngs,endln={}',
                        (mcr_ind, times, waits, chngs, endln))

            if 0 != lmcrs and mcr_ind in range(lmcrs):
                mcr = self.macros[mcr_ind]
                self.last_mcr_id = mcr['id']

            if ans_s == 'close': break  #while
            if ans_s == 'custom':  #Custom
                custs = app.dlg_input_ex(
                    5, 'Custom dialog Macros',
                    'Height of macro list (min 450)',
                    str(self.dlg_prs.get('h_list', 400)),
                    'Width of macro list (min 200)',
                    str(self.dlg_prs.get('w_list', 500)),
                    'Width of action list (min 200, <=0-hide)',
                    str(self.dlg_prs.get('w_acts',
                                         500)), 'Width of buttons (min 150)',
                    str(self.dlg_prs.get('w_btn',
                                         150)), 'Max run times (min 100)',
                    str(self.dlg_prs.get('times', 1000)))
                if custs is not None:
                    self.dlg_prs['h_list'] = max(450, int(custs[0]))
                    self.dlg_prs['h_acts'] = self.dlg_prs['h_list']
                    self.dlg_prs['w_list'] = max(200, int(custs[1]))
                    self.dlg_prs['w_acts'] = max(200, int(
                        custs[2])) if int(custs[2]) > 0 else int(custs[2])
                    self.dlg_prs['w_btn'] = max(150, int(custs[3]))
                    self.dlg_prs['times'] = max(100, int(custs[4]))
                    open(MACROS_JSON, 'w').write(
                        json.dumps(
                            {
                                'ver': JSON_FORMAT_VER,
                                'list': self.macros,
                                'dlg_prs': self.dlg_prs
                            },
                            indent=4))
                continue  #while

            if mcr_ind not in range(lmcrs):
                app.msg_box('Select macro', app.MB_OK)
                continue  #while

            what = ''
            changed = False
            if False: pass

            elif ans_s == 'view':  #View
                continue  #while

            elif ans_s == 'rename':  #Rename
                mcr_nm = app.dlg_input(
                    'New name for: {}'.format(nmkys[mcr_ind]), mcr['nm'])
                if mcr_nm is None or mcr_nm == mcr['nm']: continue  #while
                while mcr_nm in [mcr['nm'] for mcr in self.macros]:
                    app.msg_box(
                        'Select other name.\nMacro names now are:\n\n' +
                        '\n'.join(nmkys), app.MB_OK)
                    mcr_nm = app.dlg_input(
                        'New name for: {}'.format(nmkys[mcr_ind]), mcr_nm)
                    if mcr_nm is None or mcr_nm == mcr['nm']:
                        break  #while mcr_nm
                if mcr_nm is None or mcr_nm == mcr['nm']: continue  #while
                what = 'rename'
                mcr['nm'] = mcr_nm
                changed = True

            elif ans_s == 'delete':  #Del
                if app.msg_box('Delete macro\n    {}'.format(nmkys[mcr_ind]),
                               app.MB_YESNO) != app.ID_YES:
                    continue  #while
                what = 'delete:' + str(mcr['id'])
                del self.macros[mcr_ind]
                mcr_ind = min(mcr_ind, len(self.macros) - 1)
                changed = True

            elif ans_s == 'hotkeys':  #Hotkeys
                app.dlg_hotkeys('cuda_macros,run,' + str(mcr['id']))
                keys = apx._json_loads(open(
                    keys_json).read()) if os.path.exists(keys_json) else {}
                changed = True

            elif ans_s == 'run':  #Run
                if (times == 0 and waits == 0 and chngs == '0'
                        and endln == '0'):
                    app.msg_box('Select stop condition', app.MB_OK)
                    continue
                self.run(mcr['id'], max(0, times), max(0, waits), chngs == '1',
                         endln == '1')
                return

            elif ans_s == 'rec' and not rec_on:  #Start record
                return ed.cmd(cmds.cmd_MacroStart)
            elif ans_s == 'rec' and rec_on:  #Stop record
                self.need_dlg = True
                return ed.cmd(
                    cmds.cmd_MacroStop
                )  # Return for clear rec-mode in StatusBar, will recall from on_macro
            elif ans_s == 'cancel' and rec_on:  #Cancel record
                return ed.cmd(cmds.cmd_MacroCancel
                              )  # Return for clear rec-mode in StatusBar

            if changed:
                self._do_acts(what)
示例#26
0
def do_report(fn):
    lex = ed.get_prop(app.PROP_LEXER_CARET)
    def_json = os.path.join(apx.get_def_setting_dir(), "default.json")
    usr_json = os.path.join(app.app_path(app.APP_DIR_SETTINGS), "user.json")
    lex_json = os.path.join(app.app_path(app.APP_DIR_SETTINGS), "lexer {}.json".format(lex))

    #   def_opts    = apx.get_app_default_opts()
    #   pass;                       LOG and log('?? get_app_default_opts')
    #   def_opts    = apx.get_app_default_opts(         object_pairs_hook=collections.OrderedDict)

    #   if 'font_name' != list(def_opts.keys())[0]:
    #       pass;                   apx.log('Not natural order')
    #       return False

    def_opts = apx._get_file_opts(def_json, {}, object_pairs_hook=collections.OrderedDict)
    usr_opts = apx._get_file_opts(usr_json, {}, object_pairs_hook=collections.OrderedDict)
    lex_opts = apx._get_file_opts(lex_json, {}, object_pairs_hook=collections.OrderedDict)

    def_opts = pickle.loads(pickle.dumps(def_opts))  # clone to pop
    usr_opts = pickle.loads(pickle.dumps(usr_opts))  # clone to pop
    lex_opts = pickle.loads(pickle.dumps(lex_opts))  # clone to pop

    fil_opts = get_ovrd_ed_opts(ed)
    cmt_opts = {}
    # Find Commentary for def opts in def file
    # Rely: _commentary_ is some (0+) lines between opt-line and prev opt-line
    def_body = open(def_json).read()
    def_body = def_body.replace("\r\n", "\n").replace("\r", "\n")
    def_body = def_body[def_body.find("{") + 1 :]  # Cut head with start '{'
    def_body = def_body.lstrip()
    for opt in def_opts.keys():
        pos_opt = def_body.find('"{}"'.format(opt))
        cmt = def_body[:pos_opt].strip()
        cmt = re.sub("^\s*//", "", cmt, flags=re.M)
        cmt = cmt.strip()
        cmt_opts[opt] = html.escape(cmt)
        def_body = def_body[def_body.find("\n", pos_opt) + 1 :]  # Cut the opt

    with open(fn, "w", encoding="utf8") as f:
        f.write(RPT_HEAD)
        f.write("<h4>Hign priority: editor options</h4>")
        f.write("<table>\n")
        f.write("<tr>\n")
        f.write("<th>Option name</th>\n")
        f.write("<th>Value in<br>default</th>\n")
        f.write("<th>Value in<br>user</th>\n")
        f.write("<th>Value in<br>lexer<br>{}</th>\n".format(lex))
        f.write(
            '<th title="{}">Value in<br>file<br>{}</th>\n'.format(
                ed.get_filename(), os.path.basename(ed.get_filename())
            )
        )
        f.write("<th>Comment</th>\n")
        f.write("</tr>\n")
        for opt in fil_opts.keys():
            winner = "def"
            winner = "usr" if opt in usr_opts else winner
            winner = "lex" if opt in lex_opts else winner
            winner = "fil" if opt in fil_opts else winner
            f.write("<tr>\n")
            f.write("<td>{}</td>\n".format(opt))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "def" else "nxt", def_opts.get(opt, "")))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "usr" else "nxt", usr_opts.get(opt, "")))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "lex" else "nxt", lex_opts.get(opt, "")))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "fil" else "nxt", fil_opts.get(opt, "")))
            f.write("<td><pre>{}</pre></td>\n".format(cmt_opts.get(opt, "")))
            f.write("</tr>\n")
            def_opts.pop(opt, None)
            usr_opts.pop(opt, None)
            lex_opts.pop(opt, None)
        f.write("</table><br/>\n")
        f.write("<h4>Overridden default options</h4>")
        f.write("<table>\n")
        f.write("<tr>\n")
        f.write("<th>Option name</th>\n")
        f.write("<th>Value in<br>default</th>\n")
        f.write("<th>Value in<br>user</th>\n")
        f.write("<th>Value in<br>lexer<br>{}</th>\n".format(lex))
        f.write("<th>Comment</th>\n")
        f.write("</tr>\n")
        for opt in def_opts.keys():
            winner = "def"
            winner = "usr" if opt in usr_opts else winner
            winner = "lex" if opt in lex_opts else winner
            winner = "fil" if opt in fil_opts else winner
            f.write("<tr>\n")
            f.write("<td>{}</td>\n".format(opt))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "def" else "nxt", def_opts.get(opt, "")))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "usr" else "nxt", usr_opts.get(opt, "")))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "lex" else "nxt", lex_opts.get(opt, "")))
            f.write("<td><pre>{}</pre></td>\n".format(cmt_opts.get(opt, "")))
            f.write("</tr>\n")
            usr_opts.pop(opt, None)
            lex_opts.pop(opt, None)
        f.write("</table><br/>\n")
        f.write("<h4>Overridden user-only options</h4>")
        f.write("<table>\n")
        f.write("<tr>\n")
        f.write("<th>Option name</th>\n")
        f.write("<th>Value in<br>user</th>\n")
        f.write("<th>Value in<br>lexer<br>{}</th>\n".format(lex))
        f.write("<th>Comment</th>\n")
        f.write("</tr>\n")
        for opt in usr_opts.keys():
            winner = "usr"
            winner = "lex" if opt in lex_opts else winner
            f.write("<tr>\n")
            f.write("<td>{}</td>\n".format(opt))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "usr" else "nxt", usr_opts.get(opt, "")))
            f.write('<td class="{}">{}</td>\n'.format("win" if winner == "lex" else "nxt", lex_opts.get(opt, "")))
            f.write("<td><pre>{}</pre></td>\n".format(cmt_opts.get(opt, "")))
            f.write("</tr>\n")
            lex_opts.pop(opt, None)
        for opt in lex_opts.keys():
            winner = "lex"
            f.write("<tr>\n")
            f.write("<td>{}</td>\n".format(opt))
            f.write('<td class="{}"></td>  \n'.format("non"))
            f.write('<td class="{}">{}</td>\n'.format("win", lex_opts.get(opt, "")))
            f.write("<td><pre>{}</pre></td>\n".format(cmt_opts.get(opt, "")))
            f.write("</tr>\n")
            lex_opts.pop(opt, None)
        f.write("</table><br/>\n")
        f.write(RPT_FOOT)
        return True
示例#27
0
    def dlg_config(self):
        ''' Show dlg for change macros list.
        '''
        if app.app_api_version()<FROM_API_VERSION:  return app.msg_status(_('Need update CudaText'))
        keys_json   = app.app_path(app.APP_DIR_SETTINGS)+os.sep+'keys.json'
        keys        = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {}
        
        ids     = [mcr['id'] for mcr in self.macros]
        mcr_ind = ids.index(self.last_mcr_id) if self.last_mcr_id in ids else -1
        pass;                   LOG and log('self.last_mcr_id, mcr_ind={}',(self.last_mcr_id,mcr_ind))
        times   = 1
        waits   = 5
        chngs   = '0'
        endln   = '0'
        while True:
            WD_LST, \
            HT_LST  = (self.dlg_prs.get('w_list', 300)
                      ,self.dlg_prs.get('h_list', 500))
            WD_ACTS,\
            HT_ACTS = (self.dlg_prs.get('w_acts', 300)
                      ,self.dlg_prs.get('h_acts', 500))
            WD_BTN, \
            HT_BTN  = (self.dlg_prs.get('w_btn', 150), 24)
            WD_BTN_3= int(WD_BTN/3)
            l_btn   = GAP+WD_LST+GAP
            l_acts  = GAP+WD_LST+GAP+WD_BTN+GAP
            
            vw_acts = (WD_ACTS>0)
            WD_ACTS = max(0, WD_ACTS)
            rec_on  = ed.get_prop(app.PROP_MACRO_REC)
            lmcrs   = len(self.macros)
            pass;               LOG and log('mcr_ind,vw_acts,rec_on={}',(mcr_ind,vw_acts,rec_on))

            nmkys   = []
            for mcr in self.macros:
                mcr_cid = 'cuda_macros,run,{}'.format(mcr['id'])
                mcr_keys= keys.get(mcr_cid, {})
                kys     = '/'.join([' * '.join(mcr_keys.get('s1', []))
                                   ,' * '.join(mcr_keys.get('s2', []))
                                   ]).strip('/')
                nmkys  += [mcr['nm'] + (' ['+kys+']' if kys else '')]

            mcr_acts= ['']
#           mcr_acts= ''
            if vw_acts and mcr_ind in range(lmcrs):
                mcr     = self.macros[mcr_ind]
                mcr_acts=           ['# '+nmkys[mcr_ind]] + mcr['evl']
#               mcr_acts= '\t'.join(['# '+nmkys[mcr_ind]] + mcr['evl'])

            def_stst    = '1' if                     rec_on or 0==lmcrs else '0'
            n_edable    = '0' if                     rec_on or 0==lmcrs else '1'
            n_vwable    = '1' if not vw_acts and not rec_on else '0'
            only_rec_off= '0' if                     rec_on else '1'
            only_rec_on = '1' if                     rec_on else '0'
            tims_props  = '0,{},1'.format(self.dlg_prs.get('times',  1000))
            stst_cap    = _('&Stop record') if       rec_on else _('&Start record')
            cnts        = ([]
 +[dict(cid='mrcs'   ,tp='lbx'  ,t=GAP  ,h=HT_LST       ,l=GAP                  ,w=WD_LST   ,items=nmkys                            ,en=only_rec_off    )]
 +(                                                                                                     
  [dict(cid='view'   ,tp='bt'   ,t=GAP* 1+HT_BTN* 0     ,l=l_btn                ,w=WD_BTN   ,cap=_('&View actions') ,props=n_edable,en=n_edable         )]  # default
  if vw_acts else [])                                                                                     
 +[dict(cid='keys'   ,tp='bt'   ,t=GAP* 2+HT_BTN* 1     ,l=l_btn                ,w=WD_BTN   ,cap=_('Hot&keys...')                   ,en=n_edable        )]
 +[dict(cid='renm'   ,tp='bt'   ,t=GAP* 3+HT_BTN* 2     ,l=l_btn                ,w=WD_BTN   ,cap=_('Re&name...')                    ,en=n_edable        )]
 +[dict(cid='del'    ,tp='bt'   ,t=GAP* 4+HT_BTN* 3     ,l=l_btn                ,w=WD_BTN   ,cap=_('&Delete...')                    ,en=n_edable        )]
 +[dict(cid='run'    ,tp='bt'   ,t=GAP* 6+HT_BTN* 5     ,l=l_btn                ,w=WD_BTN   ,cap=_('&Run!')         ,props=n_vwable ,en=n_edable        )]  # default
 +[dict(              tp='lb'   ,tid='times'            ,l=l_btn                ,w=WD_BTN_3 ,cap=_('&Times')                                            )]
 +[dict(cid='times'  ,tp='sp-ed',t=GAP* 7+HT_BTN* 6     ,l=l_btn+WD_BTN_3+GAP   ,r=l_btn+WD_BTN                     ,props=tims_props,en=only_rec_off   )]  # min,max,step
 +[dict(              tp='lb'   ,tid='waits'            ,l=l_btn                ,w=WD_BTN_3 ,cap=_('&Wait')                                             )]
 +[dict(cid='waits'  ,tp='sp-ed',t=GAP* 8+HT_BTN* 7     ,l=l_btn+WD_BTN_3+GAP   ,r=l_btn+WD_BTN-40                  ,props='1,3600,1',en=only_rec_off   )]  # min,max,step
 +[dict(              tp='lb'   ,tid='waits'            ,l=l_btn+WD_BTN-40+GAP  ,w=WD_BTN   ,cap=_('sec')                                               )]
 +[dict(cid='chngs'  ,tp='ch'   ,t=GAP* 9+HT_BTN* 8     ,l=l_btn                ,w=WD_BTN   ,cap=_('While text c&hanges')                               )]
 +[dict(cid='endln'  ,tp='ch'   ,t=GAP*10+HT_BTN* 9     ,l=l_btn                ,w=WD_BTN   ,cap=_('Until c&aret on last line')                         )]
 +[dict(cid='stst'   ,tp='bt'   ,t=GAP*12+HT_BTN*11     ,l=l_btn                ,w=WD_BTN   ,cap=stst_cap           ,props=def_stst                     )]
 +[dict(cid='canc'   ,tp='bt'   ,t=GAP*13+HT_BTN*12     ,l=l_btn                ,w=WD_BTN   ,cap=_('Canc&el record')                ,en=only_rec_on     )]
 +[dict(cid='adju'   ,tp='bt'   ,t=    HT_LST-HT_BTN*2  ,l=l_btn                ,w=WD_BTN   ,cap=_('Ad&just...')                    ,en=only_rec_off    )]
 +[dict(cid='-'      ,tp='bt'   ,t=GAP+HT_LST-HT_BTN*1  ,l=l_btn                ,w=WD_BTN   ,cap=_('Close')                                             )]
 +(
  [dict(cid='acts'   ,tp='me'   ,t=GAP  ,h=HT_ACTS      ,l=l_acts               ,w=WD_ACTS                          ,props='1,1,1'                      )]  # ro,mono,border
  if vw_acts else [])
                    )
            vals    = dict( mrcs=mcr_ind
                           ,times=times
                           ,waits=waits
                           ,chngs=chngs
                           ,endln=endln
                        )
            if vw_acts: vals.update(
                      dict( acts=mcr_acts
                        ))
            btn,    \
            vals,   \
            chds    = dlg_wrapper(_('Macros'), GAP+WD_LST+GAP+WD_BTN+GAP+WD_ACTS+GAP,GAP+HT_LST+GAP, cnts, vals, focus_cid='mrcs')
            if btn is None or btn=='-': return
            mcr_ind = vals['mrcs']
            times   = vals['times']
            waits   = vals['waits']
            chngs   = vals['chngs']
            endln   = vals['endln']
            pass;               LOG and log('mcr_ind,times,waits,chngs,endln={}',(mcr_ind,times,waits,chngs,endln))

            if 0!=lmcrs and mcr_ind in range(lmcrs):
                mcr     = self.macros[mcr_ind]
                self.last_mcr_id = mcr['id']
            
#           if ans_s=='close':  break #while
            if btn=='adju': #ans_s=='custom': #Custom
                custs   = app.dlg_input_ex(5, _('Custom dialog Macros')
                    , _('Height of macro list (min 450)')          , str(self.dlg_prs.get('h_list', 400))
                    , _('Width of macro list (min 200)')           , str(self.dlg_prs.get('w_list', 500))
                    , _('Width of action list (min 200, <=0-hide)'), str(self.dlg_prs.get('w_acts', 500))
                    , _('Width of buttons (min 150)')              , str(self.dlg_prs.get('w_btn',  150))
                    , _('Max run times (min 100)')                 , str(self.dlg_prs.get('times',  1000))
                    )
                if custs is not None:
                    self.dlg_prs['h_list']  = max(450, int(custs[0]));  self.dlg_prs['h_acts'] = self.dlg_prs['h_list']
                    self.dlg_prs['w_list']  = max(200, int(custs[1]))
                    self.dlg_prs['w_acts']  = max(200, int(custs[2])) if int(custs[2])>0 else int(custs[2])
                    self.dlg_prs['w_btn']   = max(150, int(custs[3]))
                    self.dlg_prs['times']   = max(100, int(custs[4]))
                    open(MACROS_JSON, 'w').write(json.dumps({'ver':JSON_FORMAT_VER, 'list':self.macros, 'dlg_prs':self.dlg_prs}, indent=4))
                continue #while
            
            if mcr_ind not in range(lmcrs):
                app.msg_box(_('Select macro'), app.MB_OK)
                continue #while
            
            what    = ''
            changed = False
            if False:pass
                
            elif btn=='view': #ans_s=='view': #View
                continue #while

            elif btn=='renm': #ans_s=='rename': #Rename
                mcr_nm      = app.dlg_input(_('New name for: {}').format(nmkys[mcr_ind])
                                           ,mcr['nm'])
                if mcr_nm is None or mcr_nm==mcr['nm']:     continue #while
                while mcr_nm in [mcr['nm'] for mcr in self.macros]:
                    app.msg_box(_('Select other name.\nMacro names now are:\n\n')+'\n'.join(nmkys), app.MB_OK)
                    mcr_nm  = app.dlg_input(_('New name for: {}').format(nmkys[mcr_ind])
                                           ,mcr_nm)
                    if mcr_nm is None or mcr_nm==mcr['nm']: break #while mcr_nm
                if mcr_nm is None or mcr_nm==mcr['nm']:     continue #while
                what        = 'rename'
                mcr['nm']   = mcr_nm
                changed = True
                
            elif btn=='del': #ans_s=='delete': #Del
                if app.msg_box( _('Delete macro\n    {}').format(nmkys[mcr_ind])
                              , app.MB_YESNO)!=app.ID_YES:  continue #while
                what    = 'delete:'+str(mcr['id'])
                del self.macros[mcr_ind]
                mcr_ind = min(mcr_ind, len(self.macros)-1)
                changed = True
                
            elif btn=='keys': #ans_s=='hotkeys': #Hotkeys
                app.dlg_hotkeys('cuda_macros,run,'+str(mcr['id']))
                keys    = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {}
                changed = True

            elif btn=='run': #ans_s=='run': #Run
                if (times==0 
                and waits==0
                and chngs=='0'
                and endln=='0'):
                    app.msg_box(_('Select stop condition'), app.MB_OK)
                    continue
                self.run(mcr['id'], max(0, times), max(0, waits), chngs=='1', endln=='1')
                return

            elif btn=='stst'     and not rec_on: #Start record
#           elif ans_s=='rec'    and not rec_on: #Start record
                return ed.cmd(cmds.cmd_MacroStart)
            elif btn=='stst'     and     rec_on: #Stop record
#           elif ans_s=='rec'    and     rec_on: #Stop record
                self.need_dlg = True
                return ed.cmd(cmds.cmd_MacroStop)       # Return for clear rec-mode in StatusBar, will recall from on_macro
            elif btn=='canc'     and     rec_on: #Cancel record
#           elif ans_s=='cancel' and     rec_on: #Cancel record
                return ed.cmd(cmds.cmd_MacroCancel)     # Return for clear rec-mode in StatusBar
                
            if changed:
                self._do_acts(what)
def _get_occurrences(ignore_min_len=False):
    """
    Gets a tuple (items, text, is_selection, x1, y1) containing all the
    occurrences for the selected word or for the word under current caret.
    param: ignore_min_len works only with selections.
    """
    global occurrences

    lex = ed.get_prop(app.PROP_LEXER_FILE)

    if not lex:
        lex = '-'
    if not is_lexer_ok(lex):
        return

    if ed.get_line_count() > opt.MAX_LINES:
        return

    current_text = _get_current_text()
    if not current_text: return

    text, caret_pos, is_selection = current_text

    log('Looking occurrences for text: "' + text + '"')

    if is_selection:
        if not ignore_min_len:
            if not opt.SEL_ALLOW_WHITE_SPACE: text = text.strip()
            if not text: return
            if len(text) < opt.MIN_LEN: return

        case_sensitive = opt.SEL_CASE_SENSITIVE
        words_only     = opt.SEL_WORDS_ONLY
        whole_words    = opt.SEL_WHOLE_WORDS if opt.SEL_WORDS_ONLY else False
    else:
        case_sensitive = opt.CARET_CASE_SENSITIVE
        words_only     = True
        whole_words    = opt.CARET_WHOLE_WORDS

    # Validate if current text is a 'valid word' for current lexer
    if words_only and not is_word(text, lex):
        log("Current text refused because is not a valid word")
        return

    # caret_pos have the information with sorted values
    x1, y1 = caret_pos[:2]

    # Validate if the searching word is the same of the previous occurrences
    if len(occurrences) > 0:
        prev_items = occurrences[0]
        prev_text = occurrences[1]
        if prev_text == text and (x1, y1) in prev_items:
            log("Returning previous occurrences")
            return prev_items, text, is_selection, x1, y1

    items = find_all_occurrences(text, case_sensitive, whole_words)

    if not items or (len(items) == 1 and items[0] == (x1, y1)):
        return

    return items, text, is_selection, x1, y1
示例#29
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)
示例#30
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])
示例#31
0
    def dlg_config(self):
        ''' Show dlg for change macros list.
        '''
        if app.app_api_version()<FROM_API_VERSION:  return app.msg_status('Need update CudaText')
        keys_json   = app.app_path(app.APP_DIR_SETTINGS)+os.sep+'keys.json'
        keys        = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {}
        GAP     = 5
        
        ids     = [mcr['id'] for mcr in self.macros]
        mcr_ind = ids.index(self.last_mcr_id) if self.last_mcr_id in ids else -1
        pass;                   LOG and log('self.last_mcr_id, mcr_ind={}',(self.last_mcr_id,mcr_ind))
        times   = 1
        waits   = 5
        chngs   = '0'
        endln   = '0'
        while True:
            (WD_LST
            ,HT_LST)= (self.dlg_prs.get('w_list', 300)
                      ,self.dlg_prs.get('h_list', 500))
            (WD_ACTS
            ,HT_ACTS)=(self.dlg_prs.get('w_acts', 300)
                      ,self.dlg_prs.get('h_acts', 500))
            (WD_BTN
            ,HT_BTN)= (self.dlg_prs.get('w_btn', 150), 24)
            l_btn   = GAP+WD_LST+GAP
            
            vw_acts = (WD_ACTS>0)
            WD_ACTS = max(0, WD_ACTS)
            rec_on  = ed.get_prop(app.PROP_MACRO_REC)
            lmcrs   = len(self.macros)
            pass;               LOG and log('mcr_ind,vw_acts,rec_on={}',(mcr_ind,vw_acts,rec_on))

            nmkys   = []
            for mcr in self.macros:
                mcr_cid = 'cuda_macros,run,{}'.format(mcr['id'])
                mcr_keys= keys.get(mcr_cid, {})
                kys     = '/'.join([' * '.join(mcr_keys.get('s1', []))
                                   ,' * '.join(mcr_keys.get('s2', []))
                                   ]).strip('/')
                nmkys  += [mcr['nm'] + (' ['+kys+']' if kys else '')]

            mcr_acts= ''
            if vw_acts and mcr_ind in range(lmcrs):
                mcr     = self.macros[mcr_ind]
                mcr_acts= '\t'.join(['# '+nmkys[mcr_ind]] + mcr['evl'])

            ans = app.dlg_custom('Macros'   ,GAP+WD_LST+GAP+WD_BTN+GAP+WD_ACTS+GAP,GAP+HT_LST+GAP, '\n'.join([]
            +[C1.join(['type=listbox'   ,POS_FMT(l=GAP,    t=GAP,           r=GAP+WD_LST,   b=GAP+HT_LST)
                      ,'items=' +'\t'.join(nmkys)
                      ,'val='   +str(mcr_ind)  # start sel
                      ,'en='    +str(0 if rec_on else 1)        # enabled
                      ] # i=0
             )]
            +([C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP*1+HT_BTN*0,    r=l_btn+WD_BTN, b=0)
                      ,'cap=&View actions...'
                      ,'props=' +str(0 if    rec_on or 0==lmcrs else 1)    # default
                      ,'en='    +str(0 if    rec_on or 0==lmcrs else 1)    # enabled
                      ] # i=1
             )] if vw_acts else [])
            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP*2+HT_BTN*1,    r=l_btn+WD_BTN, b=0)
                      ,'cap=Hot&keys...'
                      ,'en='    +str(0 if    rec_on or 0==lmcrs else 1)     # enabled
                      ] # i=2 if vw_acts else i=1
             )]
            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP*3+HT_BTN*2,    r=l_btn+WD_BTN, b=0)
                      ,'cap=Re&name...'
                      ,'en='    +str(0 if    rec_on or 0==lmcrs else 1)     # enabled
                      ] # i=3 if vw_acts else i=2
             )]
            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP*4+HT_BTN*3,    r=l_btn+WD_BTN, b=0)
                      ,'cap=&Delete...'
                      ,'en='    +str(0 if    rec_on or 0==lmcrs else 1)     # enabled
                      ] # i=4 if vw_acts else i=3
             )]

            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,                   t=GAP*6+HT_BTN*5,    r=l_btn+WD_BTN, b=0)
                      ,'cap=&Run!'
                      ,'props=' +str(1 if not vw_acts and not rec_on else 0)     # default
                      ,'en='    +str(0 if    rec_on or 0==lmcrs else 1)     # enabled
                      ] # i=5 if vw_acts else i=4
             )]
            +[C1.join(['type=label'     ,POS_FMT(l=l_btn,                   t=GAP*7+HT_BTN*6+3, r=l_btn+int(WD_BTN/3),b=0)
                      ,'cap=&Times'
                      ] # i=6 if vw_acts else i=5
             )]
            +[C1.join(['type=spinedit'  ,POS_FMT(l=l_btn+int(WD_BTN/3)+GAP, t=GAP*7+HT_BTN*6,   r=l_btn+WD_BTN, b=0)
                      ,'val='   +str(times)
                      ,'props=0,{},1'.format(self.dlg_prs.get('times',  1000))
                      ,'en='    +str(0 if    rec_on else 1)     # enabled
                      ] # i=7 if vw_acts else i=6
             )]
            +[C1.join(['type=label'     ,POS_FMT(l=l_btn,                   t=GAP*8+HT_BTN*7+3, r=l_btn+int(WD_BTN/3),b=0)
                      ,'cap=&Wait'
                      ] # i=8 if vw_acts else i=7
             )]
            +[C1.join(['type=spinedit'  ,POS_FMT(l=l_btn+int(WD_BTN/3)+GAP, t=GAP*8+HT_BTN*7,   r=l_btn+WD_BTN-40, b=0)
                      ,'val='   +str(waits)
                      ,'props=1,3600,1'
                      ,'en='    +str(0 if    rec_on else 1)     # enabled
                      ] # i=9 if vw_acts else i=8
             )]
            +[C1.join(['type=label'     ,POS_FMT(l=l_btn+WD_BTN-40+GAP,     t=GAP*8+HT_BTN*7+3, r=l_btn+WD_BTN,b=0)
                      ,'cap=sec'
                      ] # i=10 if vw_acts else i=9
             )]
            +[C1.join(['type=check'     ,POS_FMT(l=l_btn,                   t=GAP*9+HT_BTN*8, r=l_btn+WD_BTN,b=0)
                      ,'cap=While text c&hanges'
                      ,'val='   +chngs
                      ] # i=11 if vw_acts else i=10
             )]
            +[C1.join(['type=check'     ,POS_FMT(l=l_btn,                   t=GAP*10+HT_BTN*9, r=l_btn+WD_BTN,b=0)
                      ,'cap=Until c&aret on last line'
                      ,'val='   +endln
                      ] # i=12 if vw_acts else i=11
             )]

            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP*12+HT_BTN*11,    r=l_btn+WD_BTN, b=0)
                      ,'cap={}'.format('&Stop record' if rec_on else '&Start record')
                      ,'props=' +str(1 if    rec_on or 0==lmcrs else 0)     # default
                      ] # i=13 if vw_acts else i=12
             )]
            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP*13+HT_BTN*12,    r=l_btn+WD_BTN, b=0)
                      ,'cap=Canc&el record'
                      ,'en='    +str(1 if    rec_on else 0)     # enabled
                      ] # i=14 if vw_acts else i=13
             )]

            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=    HT_LST-HT_BTN*2, r=l_btn+WD_BTN, b=0)
                      ,'cap=C&ustom...'
                      ,'en='    +str(0 if    rec_on else 1)     # enabled
                      ] # i=15 if vw_acts else i=14
             )]
            +[C1.join(['type=button'    ,POS_FMT(l=l_btn,  t=GAP+HT_LST-HT_BTN*1, r=l_btn+WD_BTN, b=0)
                      ,'cap=&Close'
                      ] # i=16 if vw_acts else i=15
             )]
            +([C1.join(['type=memo'      ,POS_FMT(l=GAP+WD_LST+GAP+WD_BTN+GAP,   t=GAP,  r=GAP+WD_LST+GAP+WD_BTN+GAP+WD_ACTS, b=GAP+HT_ACTS)
                      ,'val='+mcr_acts
                      ,'props=1,1,1'    # ro,mono,border
                      ] # i=17
             )] if vw_acts else [])
            ), apx.icase(    vw_acts and not rec_on, 0  # View
                        ,not vw_acts and not rec_on, 0  # View
                        ,    vw_acts and     rec_on, 11
                        ,not vw_acts and     rec_on, 10
                        ))    # start focus
            pass;               LOG and log('ans={}',ans)
            if ans is None:  break #while
            (ans_i
            ,vals)  = ans
            ans_s   = apx.icase(False,''
                       ,vw_acts and ans_i==1, 'view'
                       ,vw_acts and ans_i==2, 'hotkeys' ,not vw_acts and ans_i==1, 'hotkeys'
                       ,vw_acts and ans_i==3, 'rename'  ,not vw_acts and ans_i==2, 'rename' 
                       ,vw_acts and ans_i==4, 'delete'  ,not vw_acts and ans_i==3, 'delete' 
                       ,vw_acts and ans_i==5, 'run'     ,not vw_acts and ans_i==4, 'run'    
                       ,vw_acts and ans_i==12,'rec'     ,not vw_acts and ans_i==7, 'rec'    
                       ,vw_acts and ans_i==14,'cancel'  ,not vw_acts and ans_i==13,'cancel' 
                       ,vw_acts and ans_i==15,'custom'  ,not vw_acts and ans_i==14,'custom' 
                       ,vw_acts and ans_i==16,'close'   ,not vw_acts and ans_i==15,'close'  
                       ,'?')
            mcr_ind = int(vals.splitlines()[0])
            times   = int(vals.splitlines()[ 7 if vw_acts else  6])
            waits   = int(vals.splitlines()[ 9 if vw_acts else  8])
            chngs   =     vals.splitlines()[11 if vw_acts else 10]
            endln   =     vals.splitlines()[12 if vw_acts else 11]
            pass;               LOG and log('mcr_ind,times,waits,chngs,endln={}',(mcr_ind,times,waits,chngs,endln))

            if 0!=lmcrs and mcr_ind in range(lmcrs):
                mcr     = self.macros[mcr_ind]
                self.last_mcr_id = mcr['id']
            
            if ans_s=='close':  break #while
            if ans_s=='custom': #Custom
                custs   = app.dlg_input_ex(5, 'Custom dialog Macros'
                    , 'Height of macro list (min 450)'          , str(self.dlg_prs.get('h_list', 400))
                    , 'Width of macro list (min 200)'           , str(self.dlg_prs.get('w_list', 500))
                    , 'Width of action list (min 200, <=0-hide)', str(self.dlg_prs.get('w_acts', 500))
                    , 'Width of buttons (min 150)'              , str(self.dlg_prs.get('w_btn',  150))
                    , 'Max run times (min 100)'                 , str(self.dlg_prs.get('times',  1000))
                    )
                if custs is not None:
                    self.dlg_prs['h_list']  = max(450, int(custs[0]));  self.dlg_prs['h_acts'] = self.dlg_prs['h_list']
                    self.dlg_prs['w_list']  = max(200, int(custs[1]))
                    self.dlg_prs['w_acts']  = max(200, int(custs[2])) if int(custs[2])>0 else int(custs[2])
                    self.dlg_prs['w_btn']   = max(150, int(custs[3]))
                    self.dlg_prs['times']   = max(100, int(custs[4]))
                    open(MACROS_JSON, 'w').write(json.dumps({'ver':JSON_FORMAT_VER, 'list':self.macros, 'dlg_prs':self.dlg_prs}, indent=4))
                continue #while
            
            if mcr_ind not in range(lmcrs):
                app.msg_box('Select macro', app.MB_OK)
                continue #while
            
            what    = ''
            changed = False
            if False:pass
                
            elif ans_s=='view': #View
                continue #while

            elif ans_s=='rename': #Rename
                mcr_nm      = app.dlg_input('New name for: {}'.format(nmkys[mcr_ind])
                                           ,mcr['nm'])
                if mcr_nm is None or mcr_nm==mcr['nm']:     continue #while
                while mcr_nm in [mcr['nm'] for mcr in self.macros]:
                    app.msg_box('Select other name.\nMacro names now are:\n\n'+'\n'.join(nmkys), app.MB_OK)
                    mcr_nm  = app.dlg_input('New name for: {}'.format(nmkys[mcr_ind])
                                           ,mcr_nm)
                    if mcr_nm is None or mcr_nm==mcr['nm']: break #while mcr_nm
                if mcr_nm is None or mcr_nm==mcr['nm']:     continue #while
                what        = 'rename'
                mcr['nm']   = mcr_nm
                changed = True
                
            elif ans_s=='delete': #Del
                if app.msg_box( 'Delete macro\n    {}'.format(nmkys[mcr_ind])
                              , app.MB_YESNO)!=app.ID_YES:  continue #while
                what    = 'delete:'+str(mcr['id'])
                del self.macros[mcr_ind]
                mcr_ind = min(mcr_ind, len(self.macros)-1)
                changed = True
                
            elif ans_s=='hotkeys': #Hotkeys
                app.dlg_hotkeys('cuda_macros,run,'+str(mcr['id']))
                keys    = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {}
                changed = True

            elif ans_s=='run': #Run
                if (times==0 
                and waits==0
                and chngs=='0'
                and endln=='0'):
                    app.msg_box('Select stop condition', app.MB_OK)
                    continue
                self.run(mcr['id'], max(0, times), max(0, waits), chngs=='1', endln=='1')
                return

            elif ans_s=='rec'    and not rec_on: #Start record
                return ed.cmd(cmds.cmd_MacroStart)
            elif ans_s=='rec'    and     rec_on: #Stop record
                self.need_dlg = True
                return ed.cmd(cmds.cmd_MacroStop)       # Return for clear rec-mode in StatusBar, will recall from on_macro
            elif ans_s=='cancel' and     rec_on: #Cancel record
                return ed.cmd(cmds.cmd_MacroCancel)     # Return for clear rec-mode in StatusBar
                
            if changed:
                self._do_acts(what)
示例#32
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])
    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