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')))))
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()
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
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]])
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')))))
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)
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)
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))
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)
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()
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)
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)
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
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)
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
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
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)
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])
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)
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