def __init__(self): global MARKER_F_COLOR global MARKER_BG_COLOR global MARKER_BORDER_COLOR global MARK_COLORS global ASK_TO_EXIT MARKER_F_COLOR = theme_color('Id', True) MARKER_BG_COLOR = theme_color('SectionBG4', False) MARKER_BORDER_COLOR = MARKER_F_COLOR ASK_TO_EXIT = get_opt('syncedit_ask_to_exit', True, lev=CONFIG_LEV_USER) MARK_COLORS = get_opt('syncedit_mark_words', True, lev=CONFIG_LEV_USER)
def __init__(self): #NOTE: init if app.app_api_version() < FROM_API_VERSION: return app.msg_status(_('Need update application')) self.wrap = apx.get_opt('intextbookmk_wrap', apx.get_opt('ibm_wrap', True)) self.show_wo_alt = apx.get_opt('intextbookmk_compact_show', apx.get_opt('ibm_compact_show', True)) # self.show_wo_alt= apx.get_opt('intextbookmk_compact_show' , apx.get_opt('ibm_compact_show' , False)) self.unlxr_cmnt = apx.get_opt( 'intextbookmk_no_lexer_comment', apx.get_opt('ibm_no_lexer_comment', '//')) self.bm_signs = apx.get_opt( 'intextbookmk_signs', apx.get_opt('ibm_signs', ['NOTE:', 'NB!', 'TODO:', 'todo:', 'todo.', 'FIX:'])) self.bm_signs = [self.bm_signs] if type( self.bm_signs) == str else self.bm_signs self.bm_sign = self.bm_signs[0] self.lxr2cmnt = {NO_LXR_SIGN: self.unlxr_cmnt} self.ext2lxr = {} for lxr in apx.get_enabled_lexers(): cmnt = app.lexer_proc(app.LEXER_GET_PROP, lxr)['c_line'] # cmnt = app.lexer_proc(app.LEXER_GET_COMMENT, lxr) if not cmnt: continue #for lxr self.lxr2cmnt[lxr] = cmnt for ext in app.lexer_proc(app.LEXER_GET_PROP, lxr)['typ']: self.ext2lxr[ext] = lxr
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 _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_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 dlg_config(self): save_bd_col = apx.get_opt('comment_save_column' , False) at_min_bd = apx.get_opt('comment_equal_column' , False) bUseFLn = apx.get_opt('comment_full_line_if_no_sel' , True) bSkip = apx.get_opt('comment_move_down' , True) save_s = _('(Line commands) Try to keep text position after (un)commenting') save_h = _('Try to replace only blank(s) to keep text positions:' '\rUncommented lines:' '\r····foo1' '\r····foo2' '\rCommented lines:' '\r#···foo1' '\r···#foo2' ) vert_s = _('(Line "at non-space") If selected few lines, insert comment at maximal common indent') vert_h = _('Use max same column to comment:' '\rUncommented lines:' '\r··foo1' '\r····foo2' '\r······foo3' '\rCommented lines:' '\r·#foo1' '\r·#··foo2' '\r·#····foo3' ) full_s = _('(Stream) Comment full line if no selection') down_s = _('(All) Move caret to next line') aid,vals,chds = dlg_wrapper(_('Config commenting commands'), 610, 135, #NOTE: dlg-cmnt [dict(cid='save',tp='ch' ,t=5 ,l=5 ,w=600 ,cap=save_s ,hint=save_h) # ,dict(cid='vert',tp='ch' ,t=5+25 ,l=5 ,w=600 ,cap=vert_s ,hint=vert_h) # ,dict(cid='full',tp='ch' ,t=5+50 ,l=5 ,w=600 ,cap=full_s ) # ,dict(cid='down',tp='ch' ,t=5+75 ,l=5 ,w=600 ,cap=down_s ) # ,dict(cid='!' ,tp='bt' ,t=105 ,l=610-165-5,w=80 ,cap=_('OK'),props='1' ) # default ,dict(cid='-' ,tp='bt' ,t=105 ,l=610 -80-5,w=80 ,cap=_('Cancel') ) ], dict(save=save_bd_col ,vert=at_min_bd ,full=bUseFLn ,down=bSkip ), focus_cid='save') if aid is None or aid=='-': return if vals['save'] != save_bd_col: apx.set_opt('comment_save_column' , vals['save']) if vals['vert'] != at_min_bd: apx.set_opt('comment_equal_column' , vals['vert']) if vals['full'] != bUseFLn: apx.set_opt('comment_full_line_if_no_sel',vals['full']) if vals['down'] != bSkip: apx.set_opt('comment_move_down' , vals['down'])
def is_word(s, lexer): bads = NONWORD.get(lexer) if bads is None: bads = appx.get_opt('nonword_chars', NONWORD_DEF, appx.CONFIG_LEV_ALL, lexer=lexer) NONWORD[lexer] = bads for ch in s: if ch in ' \t'+bads: return False return True
def on_complete(self, ed_self): carets = ed_self.get_carets() if len(carets)!=1: return x0, y0, x1, y1 = carets[0] if y1>=0: return #don't allow selection lex = ed_self.get_prop(PROP_LEXER_FILE, '') if lex is None: return if not is_lexer_allowed(lex): return global nonwords nonwords = appx.get_opt( 'nonword_chars', '''-+*=/\()[]{}<>"'.,:;~?!@#$%^&|`…''', appx.CONFIG_LEV_ALL, ed_self, lex) word = get_word(x0, y0) if not word: return word1, word2 = word if not word1: return # to fix https://github.com/Alexey-T/CudaText/issues/3175 words = [] regex = get_regex(nonwords) #find word list from needed editors for e in get_editors(ed_self, lex): words += get_words_list(e, regex) #exclude numbers words = [w for w in words if not w.isdigit()] if words: words = sorted(list(set(words))) acp_words,acp_set = get_acp_words(word1, word2) if option_use_acp else ([],set()) if not words and not acp_words: return words = [prefix+'|'+w for w in words if is_text_with_begin(w, word1) and w not in acp_set # do not repeat words from acp and w!=word1 and w!=(word1+word2) ] #print('word:', word) #print('list:', words) ed_self.complete('\n'.join(words+acp_words), len(word1), len(word2)) return True
def _choose_icons(self, icon_dir, icon_option, icon_def): import cudax_lib as appx dir = os.path.join(app_path(APP_DIR_DATA), icon_dir) dirs = sorted(os.listdir(dir)) if not dirs: return s = appx.get_opt(icon_option, icon_def, appx.CONFIG_LEV_USER) try: index = dirs.index(s) except: index = -1 res = dlg_menu(DMENU_LIST, dirs, focused=index) if res is None: return s = dirs[res] appx.set_opt(icon_option, s, appx.CONFIG_LEV_USER) s_now = appx.get_opt(icon_option) if s != s_now: msg_box(_('Error writing option to user.json\nGot value "{}"').format(s_now), MB_OK+MB_ICONERROR) else: msg_box(_('Changed option in user.json, restart app to see effect'), MB_OK+MB_ICONINFO)
def top_sess(self, ssPath): ''' Set the session on the top of recent. Params: ssPath Full path to session file ''' ssPath = os.path.normpath(ssPath) sess = self._loadSess() rcnt = sess['recent'] if ssPath in rcnt: pos = rcnt.index(ssPath) if 0==pos: return # Already at top del rcnt[pos] rcnt.insert(0, ssPath) max_len = apx.get_opt('ui_max_history_menu', 10) del rcnt[max_len:] self._saveSess(sess)
def top_sess(self, ssPath): ''' Set the session on the top of recent. Params: ssPath Full path to session file ''' ssPath = os.path.normpath(ssPath) sess = self._loadSess() rcnt = sess['recent'] if ssPath in rcnt: pos = rcnt.index(ssPath) if 0 == pos: return # Already at top del rcnt[pos] rcnt.insert(0, ssPath) max_len = apx.get_opt('ui_max_history_menu', 10) del rcnt[max_len:] self._saveSess(sess)
def __init__(self):#NOTE: init if app.app_api_version()<FROM_API_VERSION: return app.msg_status(_('Need update application')) self.wrap = apx.get_opt('intextbookmk_wrap' , apx.get_opt('ibm_wrap' , True)) self.show_wo_alt= apx.get_opt('intextbookmk_compact_show' , apx.get_opt('ibm_compact_show' , True)) # self.show_wo_alt= apx.get_opt('intextbookmk_compact_show' , apx.get_opt('ibm_compact_show' , False)) self.unlxr_cmnt = apx.get_opt('intextbookmk_no_lexer_comment', apx.get_opt('ibm_no_lexer_comment', '//')) self.bm_signs = apx.get_opt('intextbookmk_signs' , apx.get_opt('ibm_signs' , ['NOTE:', 'NB!', 'TODO:', 'todo:', 'todo.', 'FIX:'])) self.bm_signs = [self.bm_signs] if type(self.bm_signs)==str else self.bm_signs self.bm_sign = self.bm_signs[0] self.lxr2cmnt = {NO_LXR_SIGN:self.unlxr_cmnt} self.ext2lxr = {} for lxr in apx.get_enabled_lexers(): cmnt = app.lexer_proc(app.LEXER_GET_PROP, lxr)['c_line'] # cmnt = app.lexer_proc(app.LEXER_GET_COMMENT, lxr) if not cmnt: continue#for lxr self.lxr2cmnt[lxr] = cmnt for ext in app.lexer_proc(app.LEXER_GET_PROP, lxr)['typ']: self.ext2lxr[ext] = lxr
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 fit_top_by_env(what_tp, base_tp='label'): """ Get "fitting" to add to top of first control to vertical align inside text with text into second control. The fittings rely to platform: win, unix(kde,gnome,...), mac """ if what_tp==base_tp: return 0 if (what_tp, base_tp) in fit_top_by_env__cash: pass; #log('cashed what_tp, base_tp={}',(what_tp, base_tp)) return fit_top_by_env__cash[(what_tp, base_tp)] env = get_desktop_environment() pass; #env = 'mac' fit4lb = ENV2FITS.get(env, ENV2FITS.get('win')) fit = 0 if base_tp=='label': fit = apx.get_opt('dlg_wrapper_fit_va_for_'+what_tp, fit4lb.get(what_tp, 0)) else: fit = fit_top_by_env(what_tp) - fit_top_by_env(base_tp) pass; #log('what_tp, base_tp, fit={}',(what_tp, base_tp, fit)) return fit_top_by_env__cash.setdefault((what_tp, base_tp), fit)
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)) 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 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 go_back_dlg(): pass log4fun = 0 # Order log in the function if app.app_api_version() < '1.0.253': return app.msg_status(NEED_UPDATE) pass log__("", (), __=(log4fun, _log4mod)) # scam = app.app_proc(app.PROC_GET_KEYSTATE, '') if 'c' not in app.app_proc(app.PROC_GET_KEYSTATE, ''): # User already is released Ctrl return go_back_tab() cfg_keys = get_plugcmd_hotkeys('go_back_dlg') pass #log('ok scam,cfg_keys={}',(scam,cfg_keys)) act_clr = rgb_to_int(232, 232, 232) pss_clr = rgb_to_int(216, 216, 216) side_pns = app.app_proc(app.PROC_SIDEPANEL_ENUM, '').split('\n') botm_pns = app.app_proc(app.PROC_BOTTOMPANEL_ENUM, '').split('\n') panels = [((app.PROC_SIDEPANEL_ACTIVATE, (pn,True)), pn) for pn in side_pns] \ + [( None , '') ] \ + [((app.PROC_BOTTOMPANEL_ACTIVATE,(pn,True)), pn) for pn in botm_pns] panels = [(act, pn) for (act, pn) in panels if pn != 'Menu'] eds = [app.Editor(h) for h in app.ed_handles()] # Native order ed_tats = [(ed_, ed_.get_prop(app.PROP_ACTIVATION_TIME, '')) for ed_ in eds] ed_tats = [(at, ed_) for (ed_, at) in ed_tats if at] # Only activated ed_tats.sort(reverse=True, key=lambda ae: ae[0]) eds = [ed_ for (at, ed_) in ed_tats] # Sorted by activation time eds = eds[:apx.get_opt('ui_max_history_edits', 20)] # Cut olds eds = eds if eds else [ed] eds_hist = [(ed_, ed_.get_prop(app.PROP_TAB_ID, ''), ed_.get_prop(app.PROP_TAB_TITLE), ed_.get_filename()) for ed_ in eds] pass #log('eds_hist={}',(eds_hist)) start_sel = min(1, len(eds_hist) - 1) pass #log('start_sel,len(eds_hist)={}',(start_sel,len(eds_hist))) ed_back = eds_hist[start_sel][0] panel_to = None start_pnls = get_hist('switcher.start_panel', 'Code tree') def do_show(ag, key, data=None): pass log__("", (), __=(log4fun, _log4mod)) if 'c' not in app.app_proc(app.PROC_GET_KEYSTATE, ''): ag.hide() app.timer_proc( app.TIMER_START_ONE, lambda tag: ag.hide() if 'c' not in app.app_proc(app.PROC_GET_KEYSTATE, '') else 0, 200) return [] #def do_show def do_key_up(ag, key, data=None): scam = data if data is not None else app.app_proc( app.PROC_GET_KEYSTATE, '') return None if 'c' not in scam else [] #def do_key_up def do_key_down(ag, key, data=None): nonlocal ed_back, panel_to scam = data if data is not None else app.app_proc( app.PROC_GET_KEYSTATE, '') pass #log('scam={}',(scam)) k2K = dict(s='Shift+', c='Ctrl+', a='Alt+') hotkey = ''.join(k2K[k] for k in scam) + chr(key) pass #log('key,hotkey,cfg_keys={}',(key,hotkey,cfg_keys)) to_othr = False sel_to = '' if 0: pass elif key == VK_ENTER: ag.hide() elif key == VK_ESCAPE: panel_to = ed_back = None ag.hide() elif key in (VK_LEFT, VK_RIGHT): to_othr = True elif key == VK_DOWN: sel_to = 'next' elif key == VK_UP: sel_to = 'prev' elif key == VK_TAB and scam == 'c': sel_to = 'next' elif key == VK_TAB and scam == 'sc': sel_to = 'prev' elif hotkey in cfg_keys: sel_to = 'next' else: return [] pass #log('sel_to,to_othr={}',(sel_to,to_othr)) fid = ag.focused() if to_othr: fid = 'pnls' if fid == 'tabs' else 'tabs' ag.update( dict(fid=fid, ctrls=[ ('tabs', dict(color=act_clr if fid == 'tabs' else pss_clr)), ('pnls', dict(color=act_clr if fid == 'pnls' else pss_clr)) ])) ed_back = None if fid == 'pnls' else eds_hist[ag.val('tabs')][0] panel_to = None if fid == 'tabs' else panels[ag.val('pnls')] pass #log('sel_to={}',(sel_to)) if sel_to: ed_back = None panel_to = None shft = 1 if sel_to == 'next' else -1 if fid == 'tabs': sel = (ag.val('tabs') + shft) % len(eds_hist) pass #log("shft,tabs.val,sel={}",(shft,ag.val('tabs'),sel)) ed_back = eds_hist[sel][0] pass #log('sel={}',(ag.val('tabs'), sel)) ag.update({'vals': {'tabs': sel}}) if fid == 'pnls': sel = (ag.val('pnls') + shft) % len(panels) panel_to = panels[sel] if not panel_to[0]: sel = (sel + shft) % len(panels) panel_to = panels[sel] pass #log('sel={}',(ag.val('pnls'), sel)) ag.update({'vals': {'pnls': sel}}) return False # Stop event #def do_key_down def do_select(ag, aid, data=''): nonlocal ed_back, panel_to sel = ag.val(aid) pass #log('sel={}',(sel)) if aid == 'tabs': ed_back = eds_hist[sel][0] panel_to = None if aid == 'pnls': ed_back = None panel_to = panels[sel] return [] def do_dclk(ag, aid, data=''): do_select(ag, aid) if aid == 'pnls' and not panel_to[0]: return [] # Ignore return None # Close dlg #def do_dclk panls = [(pn if pn else '—' * 100) for act, pn in panels] items = [ed_tit for (ed_, ed_tid, ed_tit, ed_fn) in eds_hist] if 'c' not in app.app_proc(app.PROC_GET_KEYSTATE, ''): # User already is released Ctrl return go_back_tab() ag_swch = DlgAg( form=dict(cap=_('Switcher'), w=350, h=300, frame='resize', on_show=do_show, on_key_down=do_key_down, on_key_up=do_key_up), ctrls=[ 0, ('tabs', dict(tp='libx', items=items, ali=ALI_CL, color=act_clr, on=do_select, on_click_dbl=do_dclk, on_click=do_dclk)), ('pnls', dict(tp='libx', items=panls, ali=ALI_RT, w=110, color=pss_clr, on=do_select, on_click_dbl=do_dclk, on_click=do_dclk)) ][1:], fid='tabs', vals=dict(tabs=start_sel, pnls=panls.index(start_pnls) if start_pnls in panls else 0)) # ag_swch.gen_repro_code('repro_dlg_switcher.py') pass #log("app.app_proc(app.PROC_GET_KEYSTATE, '')={}",(app.app_proc(app.PROC_GET_KEYSTATE, ''))) if 'c' not in app.app_proc(app.PROC_GET_KEYSTATE, ''): # User already is released Ctrl return go_back_tab() ag_swch.show() pass #log("",()) if ed_back: ed_back.focus() elif panel_to and panel_to[0]: set_hist('switcher.start_panel', panel_to[1]) app.app_proc(*(panel_to[0]))
def __init__(self): self.filename = os.path.join(ct.app_path(ct.APP_DIR_SETTINGS), 'cuda_differ_history.ini') self.max_size = appx.get_opt('ui_max_history_files', 25)
def _prep_const(self): brckts = apx.get_opt('intextcomp_brackets' , apx.get_opt('itc_brackets' , DEF_BRCKTS)) self.min_len= apx.get_opt('intextcomp_min_len' , apx.get_opt('itc_min_len' , DEF_MIN_LEN)) self.kill = apx.get_opt('intextcomp_kill' , apx.get_opt('itc_kill' , DEF_KILL)) self.sngl = apx.get_opt('intextcomp_sngl' , apx.get_opt('itc_sngl' , DEF_SNGL)) self.near = apx.get_opt('intextcomp_near' , apx.get_opt('itc_near' , DEF_NEAR)) self.wdsgns = apx.get_opt('intextcomp_word_signs' , apx.get_opt('itc_word_signs' , DEF_WDSGNS)) self.exsgns = apx.get_opt('intextcomp_expr_signs' , apx.get_opt('itc_expr_signs' , DEF_EXSGNS)) self.exall = apx.get_opt('intextcomp_expr_all' , apx.get_opt('itc_expr_all' , DEF_EXALL)) self.expair = apx.get_opt('intextcomp_expr_pair' , apx.get_opt('itc_expr_pair' , DEF_EXPAIR)) self.quotes = apx.get_opt('intextcomp_quotes' , apx.get_opt('itc_quotes' , DEF_QUOTES)) self.opn2cls= {brckts[i ]:brckts[i+1] for i in range(0,len(brckts),2)} self.cls2opn= {brckts[i+1]:brckts[i ] for i in range(0,len(brckts),2)} self.wdcmpl = r'[\w'+re.escape(self.wdsgns)+']+' self.excmpl = r'\S+' \ if self.exall else \ r'[\w'+re.escape(self.exsgns)+']+' self.base_re= re.compile(self.wdcmpl)
from itertools import * from pathlib import PurePath as PPath from pathlib import Path as Path def first_true(iterable, default=False, pred=None):return next(filter(pred, iterable), default) # 10.1.2. Itertools Recipes import cudatext as app import cudatext_cmd as cmds import cudax_lib as apx from cudatext import ed #from .cd_plug_lib import * d = dict odict = collections.OrderedDict OptFetchResult = collections.namedtuple('OptFetchResult', 'opts filter sort') pass; LOG = (-1== 1) or apx.get_opt('_opts_dlg_log',False) # Do or dont logging. pass; from pprint import pformat pass; pf=lambda d:pformat(d,width=150) pass; pf80=lambda d:pformat(d,width=80) pass; pf60=lambda d:pformat(d,width=60) pass; ##!! waits correction _ = apx.get_translation(__file__) # I18N VERSION = re.split('Version:', __doc__)[1].split("'")[1] VERSION_V, \ VERSION_D = VERSION.split(' ') MAX_HIST = apx.get_opt('ui_max_history_edits', 20) CFG_JSON = app.app_path(app.APP_DIR_SETTINGS)+os.sep+'cuda_options_editor.json' HTM_RPT_FILE= str(Path(tempfile.gettempdir()) / 'CudaText_option_report.html') FONT_LST = ['default'] \
def get_cnts(self, what=''): m,M = self,self.__class__ open_src = apx.get_opt('config_keys_with_open', False) sndt_b = bool(sndt) def is_cond4snps(cond, sns_l): if not cond: return True if not sns_l: return False return any(map(lambda sn:fnmatch(sn, cond), sns_l)) def test_cond(cnd_s, text, text2='', what='cmds'): if not cnd_s: return True if not text+text2: return False text = text + ' ' + text2 text = text.upper() if '_' in cnd_s: text = '·' + M.reND.sub('·', text) + '·' cnd_s = ' ' + cnd_s + ' ' cnd_s = cnd_s.replace(' _', ' ·').replace('_ ', '· ') pass; #LOG and log('cnd_s, text={}',(cnd_s, text)) return all(map(lambda c:c in text, cnd_s.split())) def bmix(val1, bor12, val2, bor23, val3): val12 = val1 or val2 if bor12 else val1 and val2 return val12 or val3 if bor23 else val12 and val3 # def bmix(bor12, bor23, val1, val2, val3): # val12 = val1 or val2 if bor12 else val1 and val2 # return val12 or val3 if bor23 else val12 and val3 ccnd_u = m.ccnd.upper() kcnd_u = m.kcnd.upper() pass; #LOG and log('ccnd_u, kcnd_u, scnd={}',(ccnd_u, kcnd_u, m.scnd)) nkkis_l = [ (nm, k1, k2, id, sndt.get_snips(id) if sndt else []) for (nm, k1, k2, id) in m.nkki_l] pass; #LOG and log('nkkis_l={}',(pf(nkkis_l))) fl_NKKISs=[ (nm, k1, k2, id, sns) for (nm, k1, k2, id, sns) in nkkis_l if bmix( (not ccnd_u or test_cond(ccnd_u, nm)) ,m.orcn and (ccnd_u and kcnd_u) ,(not kcnd_u or test_cond(kcnd_u, k1, k2, 'keys')) ,m.orsn and (m.scnd) ,(not m.scnd or not sndt or is_cond4snps(m.scnd, sns)) ) ] # if bmix(m.orcn, m.orsn # ,(not ccnd_u or test_cond(ccnd_u, nm)) # ,(not kcnd_u or test_cond(kcnd_u, k1, k2, 'keys')) # ,(not m.scnd or not sndt or is_cond4snps(m.scnd, sns)) )] sort_n = apx.icase(m.sort[0]=='nm',0, m.sort[0]=='k1',1, m.sort[0]=='k2',2, m.sort[0]=='sn',4, 0) # index in item of fl_NKKISs sort_c = '' if not m.sort[0] else ' ▲' if m.sort[1] else ' ▼' if m.sort[0]: fl_NKKISs = sorted(fl_NKKISs, key=lambda mkkis:('_' if not mkkis[sort_n] and not m.sort[1] else mkkis[sort_n]), reverse=m.sort[1]) # fl_NKKISs = sorted(fl_NKKISs, key=lambda mkkis:mkkis[sort_n], reverse=m.sort[1]) stat_c = f(' ({}/{})',len(fl_NKKISs), len(nkkis_l)) + (sort_c if m.sort[0]=='nm' else '') stat_k1 = f(' ({}/{})',sum(1 if k1 else 0 for (nm, k1, k2, id, sns) in fl_NKKISs) ,sum(1 if k1 else 0 for (nm, k1, k2, id, sns) in nkkis_l)) + (sort_c if m.sort[0]=='k1' else '') stat_k2 = f(' ({}/{})',sum(1 if k2 else 0 for (nm, k1, k2, id, sns) in fl_NKKISs) ,sum(1 if k2 else 0 for (nm, k1, k2, id, sns) in nkkis_l)) + (sort_c if m.sort[0]=='k2' else '') stat_s = f(' ({}/{})',sum(1 if sns else 0 for (nm, k1, k2, id, sns) in fl_NKKISs) ,sum(1 if sns else 0 for (nm, k1, k2, id, sns) in nkkis_l)) + (sort_c if m.sort[0]=='sn' else '') m.fl_Is = [id for (nm, k1, k2, id, sn) in fl_NKKISs ] ##!! itms = (list(zip([_('Command')+stat_c, _('Hotkey-1')+stat_k1, _('Hotkey-2')+stat_k2, _('Snips')+stat_s], map(str, M.COL_WS))) , [ (nm, k1, k2, ', '.join(sns)) for (nm, k1, k2, id, sns) in fl_NKKISs ] ) if what=='lwks': return [('lwks',dict(items=itms))] cnts =[ ('fltr',dict(tp='bt' ,t=5+40+10 ,l=M.lrpt ,w=100 ,cap=_('&Filter') ,ex0='1' ,call=m.do_fltr )) # &f default ,('drop',dict(tp='bt' ,t=5+70+10 ,l=M.lrpt ,w=100 ,cap=_('&All') ,call=m.do_fltr )) # &a ,('orcn',dict(tp='ch' ,t=5 ,l=M.lfk1-60,w=40 ,cap=_('&OR') ,call=m.do_fltr )) # &o ,('orsn',dict(tp='ch' ,t=5 ,l=M.lfsn-60,w=40 ,cap=_('O&R') ,vis=sndt_b ,call=m.do_fltr )) # &r ,('ccn_',dict(tp='lb' ,tid='orcn' ,l=5+5 ,w=90 ,cap=_('In &Command:') ,hint=M.ccnd_h )) # &c ,('ccnd',dict(tp='ed' ,t=5+20 ,l=5+5 ,w=150 )) # ,('kcn_',dict(tp='lb' ,tid='orcn' ,l=M.lfk1 ,w=50 ,cap=_('In &Hotkeys:') ,hint=M.kcnd_h )) # &h ,('kcnd',dict(tp='ed' ,t=5+20 ,l=M.lfk1 ,w=120 )) # ,('scn_',dict(tp='lb' ,tid='orsn' ,l=M.lfsn ,w=50 ,cap=_('In &Snip(s):') ,hint=M.scnd_h ,vis=sndt_b )) # &s ,('shlp',dict(tp='bt' ,tid='orsn' ,l=M.lfsn+80,w=20 ,cap=_('&?') ,vis=sndt_b ,call=m.do_shlp )) # &? ,('scnd',dict(tp='ed' ,t=5+20 ,l=M.lfsn ,w=100 ,vis=sndt_b )) # #,('srt0',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&1') ,sto=F ,call=m.do_sort ))# &1 #,('srt1',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&2') ,sto=F ,call=m.do_sort ))# &2 #,('srt2',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&3') ,sto=F ,call=m.do_sort ))# &3 #,('srt3',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&4') ,sto=F ,vis=sndt_b ,call=m.do_sort ))# &4 ,('lwks',dict(tp='lvw' ,t=5+50 ,l=5 ,w=M.LST_W,h=M.LST_H ,items=itms ,ex0='1' ,a='tB' ,on_click_header=lambda idd, idc, data:m.wn_sort(data) )) # grid ,('cpnm',dict(tp='bt' ,t=M.DLG_H-60 ,l=5+5 ,w=110 ,cap=_('Copy &name') ,hint=M.cpnm_h ,a='TB' ,call=m.do_code )) # &n ,('open',dict(tp='bt' ,t=M.DLG_H-30 ,l=5+5 ,w=110 ,cap=_('Open code &#') ,hint=M.open_h ,a='TB' ,call=m.do_code )) # &# ,('hrpt',dict(tp='bt' ,t=M.DLG_H-60 ,l=130 ,w=150 ,cap=_('Report to HT&ML') ,hint=M.hrpt_h ,a='TB' ,call=m.do_rprt )) # &m ,('trpt',dict(tp='bt' ,t=M.DLG_H-30 ,l=130 ,w=150 ,cap=_('Report to new &Tab'),hint=M.trpt_h ,a='TB' ,call=m.do_rprt )) # &t ,('add1',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lfk1 ,w=150 ,cap=_('Set/Add Hotkey-&1') ,hint=M.addk_h ,a='TB' ,call=m.do_work )) # &1 ,('del1',dict(tp='bt' ,t=M.DLG_H-30 ,l=M.lfk1 ,w=150 ,cap=_('Remove Hotkey-1 &!') ,a='TB' ,call=m.do_work )) # &! ,('add2',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lfk2 ,w=150 ,cap=_('Set/Add Hotkey-&2') ,hint=M.addk_h ,a='TB' ,call=m.do_work )) # &2 ,('del2',dict(tp='bt' ,t=M.DLG_H-30 ,l=M.lfk2 ,w=150 ,cap=_('Remove Hotkey-2 &@') ,a='TB' ,call=m.do_work )) # &@ ,('asnp',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lfsn ,w=150 ,cap=_('Set/A&dd Snip') ,vis=sndt_b ,a='TB' ,call=m.do_work )) # &d ,('rsnp',dict(tp='bt' ,t=M.DLG_H-30 ,l=M.lfsn ,w=150 ,cap=_('R&emove Snip(s)') ,vis=sndt_b ,a='TB' ,call=m.do_work )) # &e ,('help',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lrpt ,w=100 ,cap=_('Hel&p') ,a='TB' ,call=m.do_shlp )) # &p ] return cnts
def find_tree_node(): pass; log4fun=-1==-1 # Order log in the function HELP_C = _(''' Search starts on Enter. • A found node after current one will be selected. • All found nodes are remembered and dialog can jump over them by [Shift+]Enter or by menu commands. • If option "O" (wrapped search) is tuned on: - Search continues from the start, when end of the tree is reached - Jumps to previous/next nodes are looped too • Option ".*" (regular expression) allows to use Python reg.ex. See "docs.python.org/3/library/re.html". • Option "w" (whole words) is ignored if entered string contains not a word. • If option "Close on success" (in menu) is tuned on, dialog will close after successful search. • Option "Show full tree path" (in menu) shows in the statusbar the path of the found node (names of all parents). • Command "Restore initial selection" (in menu) restores only first of initial carets. ''').strip() ed_crts = ed.get_carets() # Carets at start opts = d(reex=False,case=False,word=False,wrap=False,hist=[],clos=False,fpth=False) opts.update(get_hist('tree.find_node', opts)) # Scan Tree ID_TREE = app.app_proc(app.PROC_SIDEPANEL_GET_CONTROL, 'Code tree') if not ID_TREE: return app.msg_status(_('No CodeTree')) if not app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, 0): # 0 is root ed.cmd(cmds.cmd_TreeUpdate) # Try to build tree tree_t = [] # [{nid:ID, sub:[{nid:ID, sub:{}, cap:'smth', path:['rt','smth']},], cap:'rt', path:[]},] tree_p = [] # [,(ID, 'smth',['rt','smth']),] def scan_tree(id_prnt, tree_nds, path_prnt): nonlocal tree_p kids = app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, id_prnt) if kids is None: return None for nid, cap in kids: path = path_prnt + [cap] tree_p += [(nid, cap, path)] sub = scan_tree(nid, [], path) return tree_nds #def scan_tree scan_tree(0, tree_t, []) # 0 is root pass; #log('tree_t={}',pfrm100(tree_t)) if iflog(log4fun,_log4mod) else 0 pass; #log('tree_p={}',pfrm100(tree_p)) if iflog(log4fun,_log4mod) else 0 # How to select node def select_node(nid): app.tree_proc(ID_TREE, app.TREE_ITEM_SELECT, nid) c_min, r_min, \ c_max, r_max = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_RANGE, nid) ed.set_caret(c_min, r_min) #def select_node # Ask MAX_HIST= apx.get_opt('ui_max_history_edits', 20) stbr = None status = lambda msg: app.statusbar_proc(stbr, app.STATUSBAR_SET_CELL_TEXT, tag=1, value=msg) def add_to_hist(val, lst): """ Add/Move val to list head. """ if val in lst: if 0 == lst.index(val): return lst lst.remove(val) lst.insert(0, val) if len(lst)>MAX_HIST: del lst[MAX_HIST:] return lst #def add_to_hist compile_pttn= lambda pttn_s, reex, case, word: re.compile( pttn_s if reex else r'\b'+pttn_s+r'\b' if word and re.match('^\w+$', pttn_s) else re.escape(pttn_s) , 0 if case else re.I) prev_wt = None # Prev what ready_l = [] # [(nid,cap|path,ndn)] ready_p = -1 # pos in ready_l nfnd_st = lambda: status(_('No suitable nodes')) ready_st= lambda: status(f('{pos}/{all}: {cap}', pos=1+ready_p, all=len(ready_l), cap=ready_l[ready_p][1])) ready_er= lambda: status(_('Error')) def do_attr(ag, aid, data=''): nonlocal prev_wt prev_wt = '' return d(fid='what') def do_menu(ag, aid, data=''): def wnen_menu(ag, tag): nonlocal opts, prev_wt if tag in ('prev','next'): return do_next(ag, tag) if tag in ('fpth','clos'): prev_wt = ''; opts[tag] = not opts[tag] elif tag=='help': app.msg_box(HELP_C, app.MB_OK) elif tag=='rest': ed.set_caret(*ed_crts[0]); return None return [] #def wnen_menu ag.show_menu( [ d( tag='help' ,cap=_('&Help...') ),d( cap='-' ),d( tag='prev' ,cap=_('Find &previous') ,key='Shift+Enter' ),d( tag='next' ,cap=_('F&ind next') ,key='Enter' ),d( cap='-' ),d( cap=_('&Options') ,sub= [ d(tag='fpth' ,cap=_('Show full tree path') ,ch=opts['fpth'] ),d(tag='clos' ,cap=_('Close on success') ,ch=opts['clos'] )]),d( cap='-' ),d( tag='rest' ,cap=_('Restore initial selection and close dialog &=') ,key='Shift+Esc' )] , aid , cmd4all=wnen_menu # Set cmd=wnen_menu for all nodes ) return d(fid='what') #def do_menu def do_next(ag, aid, data=''): if not ready_l: return d(fid='what') nonlocal ready_p ready_n = ready_p + (-1 if aid=='prev' else 1) ready_n = ready_n % len(ready_l) if opts['wrap'] else max(0, min(len(ready_l)-1, ready_n), 0) pass; #log('ready_n,ready_p={}',(ready_n,ready_p)) if iflog(log4fun,_log4mod) else 0 if ready_p == ready_n: return d(fid='what') ready_p = ready_n ready_st() select_node(ready_l[ready_p][0]) return d(fid='what') #def do_next def do_find(ag, aid, data=''): nonlocal opts, tree_p, prev_wt, ready_l, ready_p # What/how/where will search what = ag.val('what') if prev_wt==what and ready_l: return do_next(ag, 'next') prev_wt = what pass; #log('what={}',(what)) if iflog(log4fun,_log4mod) else 0 if not what: ready_l, ready_p = [], -1 return d(fid='what') opts['hist']= add_to_hist(what, opts['hist']) opts.update(ag.vals(['reex','case','word','wrap'])) pass; #log('opts={}',(opts)) if iflog(log4fun,_log4mod) else 0 tree_sid = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_SELECTED) # cur nodes = tree_p # To find from top if tree_sid and opts['clos']: # To find from cur # Trick: [..,i,sid]+[j,..] switch to [j,..] or [j,..]+[..,i] to search first after cur nids = [nid for nid, cap, path in tree_p] pos = nids.index(tree_sid) nodes = tree_p[pos+1:] + (tree_p[:pos] if opts['wrap'] else []) # Search ready_l = [] tree_ndn= -1 try: pttn_r = compile_pttn(what, opts['reex'], opts['case'], opts['word']) except: ready_er() return d(ctrls=[('what',d(items=opts['hist']))] ,fid='what') for ndn, (nid, cap, path) in enumerate(nodes): if not pttn_r.search(cap): continue if opts['clos']: select_node(nid) return None # Close dlg ready_l+= [(nid, ' / '.join(path) if opts['fpth'] else cap, ndn)] tree_ndn= ndn if ndn==tree_sid else tree_ndn pass; #log('ready_l={}',(ready_l)) if iflog(log4fun,_log4mod) else 0 ready_p = -1 if not ready_l else \ 0 if not tree_sid else \ first_true(enumerate(ready_l), 0, (lambda n_nid_cap_ndn: n_nid_cap_ndn[1][2]>tree_ndn))[0] pass; #log('ready_p={}',(ready_p)) if iflog(log4fun,_log4mod) else 0 # Show results if ready_p!=-1: select_node(ready_l[ready_p][0]) if opts['clos']: return None # Close dlg ready_st() else: nfnd_st() return d(ctrls=[('what',d(items=opts['hist']))] ,fid='what') #def do_find def do_key_down(ag, key, data=''): scam = data if data else app.app_proc(app.PROC_GET_KEYSTATE, '') pass; #log('key,data,scam={}',(key,data,scam)) if iflog(log4fun,_log4mod) else 0 if 0:pass elif (scam,key)==('s',VK_ENTER): # Shift+Enter ag.update(do_next(ag, 'prev')) elif (scam,key)==('s',VK_ESCAPE): # Shift+Esc ed.set_caret(*ed_crts[0]) return None else: return [] # Nothing return False # Stop event #def do_key_down ag = DlgAg( form =dict(cap=_('Find tree node'), w=365, h=58, h_max=58 ,on_key_down=do_key_down ,border=app.DBORDER_TOOLSIZE # ,resize=True ) , ctrls =[0 ,('find',d(tp='bttn',y=0 ,x=-99 ,w=44 ,cap='' ,sto=False ,def_bt=T ,on=do_find )) # Enter ,('reex',d(tp='chbt',tid='what' ,x=5+38*0 ,w=39 ,cap='.&*' ,hint=_('Regular expression') ,on=do_attr )) # &* ,('case',d(tp='chbt',tid='what' ,x=5+38*1 ,w=39 ,cap='&aA' ,hint=_('Case sensitive') ,on=do_attr )) # &a ,('word',d(tp='chbt',tid='what' ,x=5+38*2 ,w=39 ,cap='"&w"' ,hint=_('Whole words') ,on=do_attr )) # &w ,('wrap',d(tp='chbt',tid='what' ,x=5+38*3 ,w=39 ,cap='&O' ,hint=_('Wrapped search') ,on=do_attr )) # &/ ,('what',d(tp='cmbx',y =5 ,x=5+38*4+5 ,w=155 ,items=opts['hist'] ,a='r>' )) # ,('menu',d(tp='bttn',tid='what' ,x=320 ,w=40 ,cap='&=' ,on=do_menu ,a='>>' )) # &= ,('stbr',d(tp='stbr' ,x=0 ,r=365 ,ali=ALI_BT ,a='r>' )) # ][1:] , fid ='what' , vals = {k:opts[k] for k in ('reex','case','word','wrap')} #,options={'gen_repro_to_file':'repro_dlg_find_tree_node.py'} ) stbr = ag.chandle('stbr') app.statusbar_proc(stbr, app.STATUSBAR_ADD_CELL , tag=1) app.statusbar_proc(stbr, app.STATUSBAR_SET_CELL_AUTOSTRETCH , tag=1, value=True) ag.show(lambda ag: set_hist('tree.find_node', upd_dict(opts, ag.vals(['reex','case','word','wrap']))))
def init_form(self): h = dlg_proc(0, DLG_CREATE) _colors = app_proc(PROC_THEME_UI_DICT_GET, '') color_form_bg = _colors['TabBg']['color'] ###### FORM ####################### dlg_proc(h, DLG_PROP_SET, prop={ 'cap': _('JSON option editor: {}').format(self.opt['opt']), 'w': 600, 'h': 400, 'border': DBORDER_SIZE, 'color': color_form_bg, 'topmost': True, }) # option description ######### n = dlg_proc(h, DLG_CTL_ADD, 'editor') dlg_proc(h, DLG_CTL_PROP_SET, index=n, prop={ 'name': 'editor', 'align': ALIGN_CLIENT, 'sp_l': PAD * 2, 'sp_t': PAD * 2, 'sp_r': PAD * 2, 'sp_b': PAD * 2, }) h_ed = dlg_proc(h, DLG_CTL_HANDLE, index=n) self.edt = Editor(h_ed) # option description ######### n = dlg_proc(h, DLG_CTL_ADD, 'editor') dlg_proc(h, DLG_CTL_PROP_SET, index=n, prop={ 'name': 'memo', 'align': ALIGN_BOTTOM, 'h': 200, 'max_h': 200, 'sp_l': PAD * 2, 'sp_r': PAD * 2, 'sp_b': PAD + BTN_H + PAD * 2, }) h_ed = dlg_proc(h, DLG_CTL_HANDLE, index=n) self.memo = Editor(h_ed) ### Bottom Btns ################### # OK ####### self.n_ok = dlg_proc(h, DLG_CTL_ADD, 'button_ex') dlg_proc(h, DLG_CTL_PROP_SET, index=self.n_ok, prop={ 'name': 'btn_ok', 'h': BTN_H, 'max_h': BTN_H, 'w': BTN_W, 'a_l': None, 'a_t': None, 'a_r': ('', ']'), 'a_b': ('', ']'), 'sp_r': PAD * 2, 'sp_b': PAD * 2, 'cap': _('OK'), 'on_change': self._on_btn_click, }) # Cancel ####### self.n_cancel = dlg_proc(h, DLG_CTL_ADD, 'button_ex') dlg_proc(h, DLG_CTL_PROP_SET, index=self.n_cancel, prop={ 'name': 'btn_cancel', 'h': BTN_H, 'max_h': BTN_H, 'w': BTN_W, 'a_l': None, 'a_t': None, 'a_r': ('btn_ok', '['), 'a_b': ('', ']'), 'sp_r': PAD * 2, 'sp_b': PAD * 2, 'cap': _('Close'), 'on_change': self._on_btn_click, }) # Check ####### self.n_check = dlg_proc(h, DLG_CTL_ADD, 'button_ex') dlg_proc(h, DLG_CTL_PROP_SET, index=self.n_check, prop={ 'h': BTN_H, 'max_h': BTN_H, 'w': BTN_W, 'a_l': None, 'a_t': None, 'a_r': ('btn_cancel', '['), 'a_b': ('', ']'), 'sp_r': PAD * 2, 'sp_b': PAD * 2, 'cap': _('Check'), 'on_change': self._on_btn_click, }) self.h_btn_check = dlg_proc(h, DLG_CTL_HANDLE, index=self.n_check) # Copy default ####### self.n_load_def = dlg_proc(h, DLG_CTL_ADD, 'button_ex') dlg_proc(h, DLG_CTL_PROP_SET, index=self.n_load_def, prop={ 'name': 'btn_defaults', 'h': BTN_H, 'max_h': BTN_H, 'w': BTN_W_BIG, 'a_l': ('', '['), 'a_t': None, 'a_b': ('', ']'), 'sp_l': PAD * 2, 'sp_b': PAD * 2, 'cap': _('Load default'), 'on_change': self._on_btn_click, }) # Undo changes ####### self.n_undo = dlg_proc(h, DLG_CTL_ADD, 'button_ex') dlg_proc(h, DLG_CTL_PROP_SET, index=self.n_undo, prop={ 'h': BTN_H, 'max_h': BTN_H, 'w': BTN_W_BIG, 'a_l': ('btn_defaults', ']'), 'a_t': None, 'a_b': ('', ']'), 'sp_l': PAD * 2, 'sp_b': PAD * 2, 'cap': _('Undo changes'), 'on_change': self._on_btn_click, }) self.edt.set_prop(PROP_LEXER_FILE, 'JSON') _os_suffix = app_proc(PROC_GET_OS_SUFFIX, '') font = get_opt('font_name' + _os_suffix), get_opt('font_size' + _os_suffix) for _edt in [self.edt, self.memo]: _edt.set_prop(PROP_GUTTER_ALL, False) _edt.set_prop(PROP_MINIMAP, False) _edt.set_prop(PROP_MICROMAP, False) _edt.set_prop(PROP_LAST_LINE_ON_TOP, False) _edt.set_prop(PROP_HILITE_CUR_LINE, False) self.edt.set_prop(PROP_GUTTER_ALL, True) # show line numbers on top editor self.edt.set_prop(PROP_GUTTER_NUM, True) self.edt.set_prop(PROP_GUTTER_BM, False) self.edt.set_prop(PROP_GUTTER_FOLD, False) self.edt.set_prop(PROP_GUTTER_STATES, False) self.undo_changes() dlg_proc(h, DLG_SCALE) return h
def toggle(self): global FIND_REGEX global CASE_SENSITIVE global STYLES_DEFAULT global STYLES_NO_DEFAULT global STYLES global STYLES_NO if len(ed.get_carets()) != 1: msg_status('Sync Editing: Need single caret') return original = ed.get_text_sel() # Check if we have selection of text if not original and self.saved_sel is None: msg_status('Sync Editing: Make selection first') return self.set_progress(3) if self.saved_sel is not None: self.start_l, self.end_l = self.saved_sel self.selected = True else: # Save cords self.start_l, self.end_l = ed.get_sel_lines() self.selected = True # Save text selection self.saved_sel = ed.get_sel_lines() # Break text selection ed.set_sel_rect(0, 0, 0, 0) # Mark text that was selected self.set_progress(5) ed.set_prop(PROP_MARKED_RANGE, (self.start_l, self.end_l)) ed.set_prop(PROP_TAG, 'sync_edit:1') # Go naive way if lexer id none or other text file cur_lexer = ed.get_prop(PROP_LEXER_FILE) if cur_lexer in NON_STANDART_LEXERS: # If it if non-standart lexer, change it's behaviour STYLES_DEFAULT = NON_STANDART_LEXERS[cur_lexer] elif cur_lexer == '': # If lexer is none, go very naive way self.naive_mode = True if cur_lexer in NAIVE_LEXERS or get_opt( 'syncedit_naive_mode', False, lev=CONFIG_LEV_LEX): self.naive_mode = True # Load lexer config CASE_SENSITIVE = get_opt('case_sens', True, lev=CONFIG_LEV_LEX) FIND_REGEX = get_opt('id_regex', FIND_REGEX_DEFAULT, lev=CONFIG_LEV_LEX) STYLES = get_opt('id_styles', STYLES_DEFAULT, lev=CONFIG_LEV_LEX) STYLES_NO = get_opt('id_styles_no', STYLES_NO_DEFAULT, lev=CONFIG_LEV_LEX) # Compile regex self.pattern = re.compile(FIND_REGEX) self.pattern_styles = re.compile(STYLES) self.pattern_styles_no = re.compile(STYLES_NO) # Run lexer scan form start self.set_progress(10) ed.action(EDACTION_LEXER_SCAN, self.start_l) #API 1.0.289 self.set_progress(40) # Find all occurences of regex tokenlist = ed.get_token(TOKEN_LIST_SUB, self.start_l, self.end_l) #print(tokenlist) if not tokenlist and not self.naive_mode: self.reset() self.saved_sel = None msg_status('Sync Editing: Cannot find IDs in selection') self.set_progress(-1) return elif self.naive_mode: # Naive filling for y in range(self.start_l, self.end_l + 1): cur_line = ed.get_text_line(y) for match in self.pattern.finditer(cur_line): token = ((match.start(), y), (match.end(), y), match.group(), 'id') if match.group() in self.dictionary: self.dictionary[match.group()].append(token) else: self.dictionary[match.group()] = [(token)] else: for token in tokenlist: if not self.token_style_ok(token['style']): continue idd = token['str'].strip() if not CASE_SENSITIVE: idd = idd.lower() old_style_token = ((token['x1'], token['y1']), (token['x2'], token['y2']), token['str'], token['style']) if idd in self.dictionary: if old_style_token not in self.dictionary[idd]: self.dictionary[idd].append(old_style_token) else: self.dictionary[idd] = [(old_style_token)] # Fix tokens self.set_progress(60) self.fix_tokens() # Exit if no id's (eg: comments and etc) if len(self.dictionary) == 0: self.reset() self.saved_sel = None msg_status('Sync Editing: Cannot find IDs in selection') self.set_progress(-1) return # Exit if 1 occurence found (issue #44) elif len(self.dictionary) == 1 and len(self.dictionary[list( self.dictionary.keys())[0]]) == 1: self.reset() self.saved_sel = None msg_status('Sync Editing: Need several IDs in selection') self.set_progress(-1) return self.set_progress(90) # Mark all words that we can modify with pretty light color if MARK_COLORS: rand_color = randomcolor.RandomColor() for key in self.dictionary: color = html_color_to_int( rand_color.generate(luminosity='light')[0]) for key_tuple in self.dictionary[key]: ed.attr(MARKERS_ADD, tag = MARKER_CODE, \ x = key_tuple[0][0], y = key_tuple[0][1], \ len = key_tuple[1][0] - key_tuple[0][0], \ color_font=0xb000000, color_bg=color, color_border=0xb000000, border_down=1) self.set_progress(-1) if self.want_exit: msg_status( 'Sync Editing: Cancel? Click somewhere else to cancel, or on ID to continue.' ) else: msg_status( 'Sync Editing: Click on ID to edit it, or somewhere else to cancel' )
def _cmt_toggle_line(self, cmt_act, cmt_type='', ed_=ed): ''' Add/Remove full line comment Params cmt_act 'del' uncomment all lines 'add' comment all lines 'bgn' (un)comment all as toggled first line cmt_type '1st' at begin of line 'bod' at first not blank ''' # if not apx._check_API('1.0.108'): return lex = ed_.get_prop(app.PROP_LEXER_CARET) if not lex: return prop = app.lexer_proc(app.LEXER_GET_PROP, lex) if not prop: return cmt_sgn = prop['c_line'] pass #log('cmt_type, lex, cmt_sgn={}', (cmt_type, lex, cmt_sgn)) if not cmt_sgn: return app.msg_status( f(_('Lexer "{}" don\'t support "line comments"'), lex)) # Analize empty_sel = False rWrks = [] use_rep_lines = True # use API replace_lines() y1, y2, lines = (-1, -1, []) if use_rep_lines else (None, None, None) pass #LOG and log('ed_.get_sel_mode(),app.SEL_NORMAL,app.SEL_COLUMN={}', (ed_.get_sel_mode(),app.SEL_NORMAL,app.SEL_COLUMN)) crts = ed_.get_carets() if False: pass elif ed_.get_sel_mode() == app.SEL_NORMAL: empty_sel = 1 == len(crts) and -1 == crts[0][3] for (cCrt, rCrt, cEnd, rEnd) in crts: (rCrtMin, rCrtMax) = apx.minmax(rCrt, rEnd if -1 != rEnd else rCrt) if -1 != rEnd and rCrt > rEnd and 0 == cCrt: rCrtMax = rCrtMax - 1 # For direct section along left bound rWrks += list(range(rCrtMin, rCrtMax + 1)) use_rep_lines = use_rep_lines and 1 == len(crts) elif ed_.get_sel_mode() == app.SEL_COLUMN: (cBgn, rSelBgn, cEnd, rSelEnd) = ed_.get_sel_rect() rWrks = list(range(rSelBgn, rSelEnd + 1)) if not rWrks: rWrks = [crts[0][1]] pass #log('rWrks={}', (rWrks)) y1, y2 = (rWrks[0], rWrks[-1]) if use_rep_lines else (y1, y2) pass #LOG and log('y1,y2,lines={}', (y1,y2,lines)) do_uncmt = ed_.get_text_line(rWrks[0]).lstrip().startswith(cmt_sgn) \ if cmt_act=='bgn' else \ True \ if cmt_act=='del' else \ False # Work save_bd_col = apx.get_opt('comment_save_column', False) at_min_bd = apx.get_opt('comment_equal_column', False) col_min_bd = 1000 # infinity col_kept = False # plugin applied the "Try to keep text position" if at_min_bd: for rWrk in rWrks: line = ed_.get_text_line(rWrk) pos_body = line.index(line.lstrip()) pos_body = len(line) if 0 == len(line.lstrip()) else pos_body col_min_bd = min(pos_body, col_min_bd) if 0 == col_min_bd: break # for rWrk blnks4cmt = ' ' * len(cmt_sgn) # '\t'.expandtabs(len(cmt_sgn)) pass #log('rWrks,do_uncmt, save_cols, at_min_bd, col_min_bd={}', (rWrks,do_uncmt,save_bd_col,at_min_bd,col_min_bd)) for rWrk in rWrks: line = ed_.get_text_line(rWrk) pos_body = line.index(line.lstrip()) pos_body = len(line) if 0 == len(line.lstrip()) else pos_body pass #LOG and log('rWrk,pos_body,line={}', (rWrk,pos_body,line)) if do_uncmt: # Uncomment! if not line[pos_body:].startswith(cmt_sgn): # Already no comment if use_rep_lines: lines += [line] continue #for rWrk if False: pass elif len(line) == len(cmt_sgn): # and line.startswith(cmt_sgn) line = '' elif save_bd_col and (' ' == line[0] or ' ' == line[pos_body + len(cmt_sgn)]): # Before or after cmt_sgn must be blank line = line.replace(cmt_sgn, blnks4cmt, 1) col_kept = True 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 if use_rep_lines: lines += [line] continue #for rWrk if False: pass elif cmt_type == '1st' and save_bd_col and line.startswith( blnks4cmt): line = line.replace(blnks4cmt, cmt_sgn, 1) col_kept = True #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): col_kept = True pos_cmnt = col_min_bd if at_min_bd else pos_body pass #LOG and log('pos_cmnt={}', (pos_cmnt)) if pos_cmnt >= len(cmt_sgn): line = line[:pos_cmnt - len(cmt_sgn)] + cmt_sgn + line[pos_cmnt:] else: line = line[:pos_cmnt] + cmt_sgn + line[pos_cmnt + len(cmt_sgn):] #line = line[:pos_cmnt-len(cmt_sgn)]+cmt_sgn+line[pos_cmnt:] #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 pos_cmnt = col_min_bd if at_min_bd else pos_body pass #LOG and log('pos_cmnt={}', (pos_cmnt)) line = line[:pos_cmnt] + cmt_sgn + line[pos_cmnt:] #line = line[:pos_body] +cmt_sgn+line[pos_body:] pass #LOG and log('new line={}', (line)) if use_rep_lines: lines += [line] else: pass log('line={}', (line)) ed_.set_text_line(rWrk, line) #for rWrk if use_rep_lines: pass #log('y1, y2, len(lines), lines={}',(y1, y2, len(lines), lines)) if y1 == y2: ed_.set_text_line(y1, lines[0]) else: ed_.replace_lines(y1, y2, lines) # move caret down (cCrt, rCrt, cEnd, rEnd) = crts[0] move_down = apx.get_opt('comment_move_down', True) and (rCrt + 1 < ed_.get_line_count()) if empty_sel and move_down: apx._move_caret_down(cCrt, rCrt) # shift caret horizontally if it's on the same line if not move_down and empty_sel and not col_kept: dx = len(cmt_sgn) if do_uncmt: dx = -dx cCrt = max(0, cCrt + dx) ed_.set_caret(cCrt, rCrt)
def get_cnts(self, what=''): m,M = self,CfgKeysDlg open_src = apx.get_opt('config_keys_with_open', False) sndt_b = bool(sndt) def is_cond4snps(cond, sns_l): if not cond: return True if not sns_l: return False return any(map(lambda sn:fnmatch(sn, cond), sns_l)) def test_cond(cnd_s, text, text2='', what='cmds'): if not cnd_s: return True if not text+text2: return False text = text + ' ' + text2 text = text.upper() if '_' in cnd_s: text = '·' + M.reND.sub('·', text) + '·' cnd_s = ' ' + cnd_s + ' ' cnd_s = cnd_s.replace(' _', ' ·').replace('_ ', '· ') pass; #LOG and log('cnd_s, text={}',(cnd_s, text)) return all(map(lambda c:c in text, cnd_s.split())) def bmix(val1, bor12, val2, bor23, val3): val12 = val1 or val2 if bor12 else val1 and val2 return val12 or val3 if bor23 else val12 and val3 # def bmix(bor12, bor23, val1, val2, val3): # val12 = val1 or val2 if bor12 else val1 and val2 # return val12 or val3 if bor23 else val12 and val3 ccnd_u = m.ccnd.upper() kcnd_u = m.kcnd.upper() pass; #LOG and log('ccnd_u, kcnd_u, scnd={}',(ccnd_u, kcnd_u, m.scnd)) nkkis_l = [ (nm, k1, k2, id, sndt.get_snips(id) if sndt else []) for (nm, k1, k2, id) in m.nkki_l] pass; #LOG and log('nkkis_l={}',(pf(nkkis_l))) fl_NKKISs=[ (nm, k1, k2, id, sns) for (nm, k1, k2, id, sns) in nkkis_l if bmix( (not ccnd_u or test_cond(ccnd_u, nm)) ,m.orcn and (ccnd_u and kcnd_u) ,(not kcnd_u or test_cond(kcnd_u, k1, k2, 'keys')) ,m.orsn and (m.scnd) ,(not m.scnd or not sndt or is_cond4snps(m.scnd, sns)) ) ] # if bmix(m.orcn, m.orsn # ,(not ccnd_u or test_cond(ccnd_u, nm)) # ,(not kcnd_u or test_cond(kcnd_u, k1, k2, 'keys')) # ,(not m.scnd or not sndt or is_cond4snps(m.scnd, sns)) )] sort_n = apx.icase(m.sort[0]=='nm',0, m.sort[0]=='k1',1, m.sort[0]=='k2',2, m.sort[0]=='sn',4, 0) # index in item of fl_NKKISs sort_c = '' if not m.sort[0] else ' ▲' if m.sort[1] else ' ▼' if m.sort[0]: fl_NKKISs = sorted(fl_NKKISs, key=lambda mkkis:('_' if not mkkis[sort_n] and not m.sort[1] else mkkis[sort_n]), reverse=m.sort[1]) # fl_NKKISs = sorted(fl_NKKISs, key=lambda mkkis:mkkis[sort_n], reverse=m.sort[1]) stat_c = f(' ({}/{})',len(fl_NKKISs), len(nkkis_l)) + (sort_c if m.sort[0]=='nm' else '') stat_k1 = f(' ({}/{})',sum(1 if k1 else 0 for (nm, k1, k2, id, sns) in fl_NKKISs) ,sum(1 if k1 else 0 for (nm, k1, k2, id, sns) in nkkis_l)) + (sort_c if m.sort[0]=='k1' else '') stat_k2 = f(' ({}/{})',sum(1 if k2 else 0 for (nm, k1, k2, id, sns) in fl_NKKISs) ,sum(1 if k2 else 0 for (nm, k1, k2, id, sns) in nkkis_l)) + (sort_c if m.sort[0]=='k2' else '') stat_s = f(' ({}/{})',sum(1 if sns else 0 for (nm, k1, k2, id, sns) in fl_NKKISs) ,sum(1 if sns else 0 for (nm, k1, k2, id, sns) in nkkis_l)) + (sort_c if m.sort[0]=='sn' else '') m.fl_Is = [id for (nm, k1, k2, id, sn) in fl_NKKISs ] ##!! itms = (list(zip([_('Command')+stat_c, _('Hotkey-1')+stat_k1, _('Hotkey-2')+stat_k2, _('Snips')+stat_s], map(str, M.COL_WS))) , [ (nm, k1, k2, ', '.join(sns)) for (nm, k1, k2, id, sns) in fl_NKKISs ] ) if what=='lwks': return [('lwks',dict(items=itms))] cnts =[ ('fltr',dict(tp='bt' ,t=5+40+10 ,l=M.lrpt ,w=100 ,cap=_('&Filter') ,props='1' ,call=m.do_fltr )) # &f default ,('drop',dict(tp='bt' ,t=5+70+10 ,l=M.lrpt ,w=100 ,cap=_('&All') ,call=m.do_fltr )) # &a ,('orcn',dict(tp='ch' ,t=5 ,l=M.lfk1-50,w=40 ,cap=_('&OR') ,call=m.do_fltr )) # &o ,('orsn',dict(tp='ch' ,t=5 ,l=M.lfsn-50,w=40 ,cap=_('O&R') ,vis=sndt_b ,call=m.do_fltr )) # &r ,('ccn_',dict(tp='lb' ,tid='orcn' ,l=5+5 ,w=90 ,cap=_('In &Command:') ,hint=M.ccnd_h )) # &c ,('ccnd',dict(tp='ed' ,t=5+20 ,l=5+5 ,w=150 )) # ,('kcn_',dict(tp='lb' ,tid='orcn' ,l=M.lfk1 ,w=50 ,cap=_('In &Hotkeys:') ,hint=M.kcnd_h )) # &h ,('kcnd',dict(tp='ed' ,t=5+20 ,l=M.lfk1 ,w=120 )) # ,('scn_',dict(tp='lb' ,tid='orsn' ,l=M.lfsn ,w=50 ,cap=_('In &Snips:') ,hint=M.scnd_h ,vis=sndt_b )) # &s ,('shlp',dict(tp='bt' ,tid='orsn' ,l=M.lfsn+80,w=20 ,cap=_('&?') ,vis=sndt_b ,call=m.do_shlp )) # &? ,('scnd',dict(tp='ed' ,t=5+20 ,l=M.lfsn ,w=100 ,vis=sndt_b )) # #,('srt0',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&1') ,sto=F ,call=m.do_sort ))# &1 #,('srt1',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&2') ,sto=F ,call=m.do_sort ))# &2 #,('srt2',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&3') ,sto=F ,call=m.do_sort ))# &3 #,('srt3',dict(tp='bt' ,t =0 ,l=1000 ,w=0 ,cap=_('&4') ,sto=F ,vis=sndt_b ,call=m.do_sort ))# &4 ,('lwks',dict(tp='lvw' ,t=5+50 ,l=5 ,w=M.LST_W,h=M.LST_H ,items=itms ,props='1' ,a='tB' ,on_click_header=lambda idd, idc, data:m.wn_sort(data) )) # grid ,('cpnm',dict(tp='bt' ,t=M.DLG_H-60 ,l=5+5 ,w=110 ,cap=_('Copy &name') ,hint=M.cpnm_h ,a='TB' ,call=m.do_code )) # &n ,('open',dict(tp='bt' ,t=M.DLG_H-30 ,l=5+5 ,w=110 ,cap=_('Open code &#') ,hint=M.open_h ,a='TB' ,call=m.do_code )) # &# ,('hrpt',dict(tp='bt' ,t=M.DLG_H-60 ,l=130 ,w=150 ,cap=_('Report to HT&ML') ,hint=M.hrpt_h ,a='TB' ,call=m.do_rprt )) # &m ,('trpt',dict(tp='bt' ,t=M.DLG_H-30 ,l=130 ,w=150 ,cap=_('Report to new &Tab'),hint=M.trpt_h ,a='TB' ,call=m.do_rprt )) # &t ,('add1',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lfk1 ,w=150 ,cap=_('Set/Add Hotkey-&1') ,hint=M.addk_h ,a='TB' ,call=m.do_work )) # &1 ,('del1',dict(tp='bt' ,t=M.DLG_H-30 ,l=M.lfk1 ,w=150 ,cap=_('Remove Hotkey-1 &!') ,a='TB' ,call=m.do_work )) # &! ,('add2',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lfk2 ,w=150 ,cap=_('Set/Add Hotkey-&2') ,hint=M.addk_h ,a='TB' ,call=m.do_work )) # &2 ,('del2',dict(tp='bt' ,t=M.DLG_H-30 ,l=M.lfk2 ,w=150 ,cap=_('Remove Hotkey-2 &@') ,a='TB' ,call=m.do_work )) # &@ ,('asnp',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lfsn ,w=150 ,cap=_('Set/A&dd Snip') ,vis=sndt_b ,a='TB' ,call=m.do_work )) # &d ,('rsnp',dict(tp='bt' ,t=M.DLG_H-30 ,l=M.lfsn ,w=150 ,cap=_('R&emove Snip(s)') ,vis=sndt_b ,a='TB' ,call=m.do_work )) # &e ,('help',dict(tp='bt' ,t=M.DLG_H-60 ,l=M.lrpt ,w=100 ,cap=_('Hel&p') ,a='TB' ,call=m.do_shlp )) # &p ] return cnts
def toggle(self): global FIND_REGEX global CASE_SENSITIVE if len(ed.get_carets())!=1: msg_status('Sync Editing: Need single caret') return original = ed.get_text_sel() # Check if we have selection of text if not original and self.saved_sel == (0,0): msg_status('Sync Editing: Make selection first') return self.set_progress(3) if self.saved_sel != (0,0): self.start_l, self.end_l = self.saved_sel self.selected = True else: # Save cords self.start_l, self.end_l = ed.get_sel_lines() self.selected = True # Save text selection self.saved_sel = ed.get_sel_lines() # Break text selection ed.set_sel_rect(0,0,0,0) # Mark text that was selected self.set_progress(5) ed.set_prop(PROP_MARKED_RANGE, (self.start_l, self.end_l)) ed.set_prop(PROP_TAG, 'sync_edit:1') # Load lexer config CASE_SENSITIVE = get_opt('case_sens', True, lev=CONFIG_LEV_LEX) FIND_REGEX = get_opt('id_regex', FIND_REGEX_DEFAULT, lev=CONFIG_LEV_LEX) # Compile regex self.pattern = re.compile(FIND_REGEX) # Run lexer scan form start self.set_progress(10) ed.lexer_scan(self.start_l) self.set_progress(40) # Find all occurences of regex tokenlist = ed.get_token(TOKEN_LIST_SUB, self.start_l, self.end_l) if not tokenlist: self.reset() self.saved_sel = (0,0) msg_status('Sync Editing: Cannot find IDs in selection') self.set_progress(-1) return for token in tokenlist: if not token_style_ok(token['style']): continue idd = token['str'].strip() if not CASE_SENSITIVE: idd = idd.lower() old_style_token = ((token['x1'], token['y1']), (token['x2'], token['y2']), token['str'], token['style']) if idd in self.dictionary: if old_style_token not in self.dictionary[idd]: self.dictionary[idd].append(old_style_token) else: self.dictionary[idd] = [(old_style_token)] # Fix tokens self.set_progress(60) self.fix_tokens() # Exit if no id's (eg: comments and etc) if len(self.dictionary) == 0: self.reset() self.saved_sel = (0,0) msg_status('Sync Editing: Cannot find IDs in selection') self.set_progress(-1) return # Exit if 1 occurence found (issue #44) elif len(self.dictionary) == 1 and len(self.dictionary[list(self.dictionary.keys())[0]]) == 1: self.reset() self.saved_sel = (0,0) msg_status('Sync Editing: Need several IDs in selection') self.set_progress(-1) return self.set_progress(90) # Mark all words that we can modify with pretty light color if MARK_COLORS: rand_color = randomcolor.RandomColor() for key in self.dictionary: color = html_color_to_int(rand_color.generate(luminosity='light')[0]) for key_tuple in self.dictionary[key]: ed.attr(MARKERS_ADD, tag = MARKER_CODE, \ x = key_tuple[0][0], y = key_tuple[0][1], \ len = key_tuple[1][0] - key_tuple[0][0], \ color_font=0xb000000, color_bg=color, color_border=0xb000000, border_down=1) self.set_progress(-1) if self.want_exit: msg_status('Sync Editing: Cancel? Click somewhere else to cancel, or on ID to continue.') else: msg_status('Sync Editing: Click on ID to edit it, or somewhere else to cancel')
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)) 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))) empty_sel = -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 empty_sel: # Use full line line = ed.get_text_line(rCrt) (cTx1, rTx1), (cTx2, rTx2) = (0, rCrt), (len(line), rCrt) elif bOnlyLn: # and not empty_sel # 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 empty_sel: # 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 move_down = apx.get_opt('comment_move_down', True) if False: pass elif 1 == len(crts) and empty_sel and move_down: 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 _cmt_toggle_line(self, cmt_act, cmt_type='', ed_=ed): ''' Add/Remove full line comment Params cmt_act 'del' uncomment all lines 'add' comment all lines 'bgn' (un)comment all as toggled first line cmt_type '1st' at begin of line 'bod' at first not blank ''' # if not apx._check_API('1.0.108'): return lex = ed_.get_prop(app.PROP_LEXER_CARET) prop = app.lexer_proc(app.LEXER_GET_PROP, lex) cmt_sgn = prop['c_line'] if prop else None pass; #LOG and log('cmt_type, lex, cmt_sgn={}', (cmt_type, lex, cmt_sgn)) if not cmt_sgn: return app.msg_status(f(_('No line comment for lexer "{}"'), lex)) # Analize bEmpSel = False rWrks = [] bUseRepLns = app.app_api_version()>='1.0.177' y1,y2,lines = (-1, -1, []) if bUseRepLns else (None, None, None) # To use API replace_lines pass; #LOG and log('ed_.get_sel_mode(),app.SEL_NORMAL,app.SEL_COLUMN={}', (ed_.get_sel_mode(),app.SEL_NORMAL,app.SEL_COLUMN)) crts = ed_.get_carets() if False:pass elif ed_.get_sel_mode() == app.SEL_NORMAL: bEmpSel = 1==len(crts) and -1==crts[0][3] for (cCrt, rCrt ,cEnd, rEnd) in crts: (rCrtMin ,rCrtMax) = apx.minmax(rCrt, rEnd if -1!=rEnd else rCrt) if -1!=rEnd and rCrt>rEnd and 0==cCrt: rCrtMax = rCrtMax-1 # For direct section along left bound rWrks += list(range(rCrtMin, rCrtMax+1)) bUseRepLns = bUseRepLns and 1==len(crts) elif ed_.get_sel_mode() == app.SEL_COLUMN: (cBgn ,rSelBgn ,cEnd ,rSelEnd) = ed_.get_sel_rect() rWrks = list(range(rSelBgn, rSelEnd+1)) if not rWrks: rWrks = [crts[0][1]] pass; #LOG and log('rWrks={}', (rWrks)) y1,y2 = (rWrks[0],rWrks[-1]) if bUseRepLns else (y1,y2) pass; #LOG and log('y1,y2,lines={}', (y1,y2,lines)) do_uncmt = ed_.get_text_line(rWrks[0]).lstrip().startswith(cmt_sgn) \ if cmt_act=='bgn' else \ True \ if cmt_act=='del' else \ False # Work save_bd_col = apx.get_opt('comment_save_column' , False) at_min_bd = apx.get_opt('comment_equal_column', False) col_min_bd = 1000 # infinity if at_min_bd: for rWrk in rWrks: line = ed_.get_text_line(rWrk) pos_body = line.index(line.lstrip()) pos_body = len(line) if 0==len(line.lstrip()) else pos_body col_min_bd = min(pos_body, col_min_bd) if 0==col_min_bd: break # for rWrk blnks4cmt = ' '*len(cmt_sgn) # '\t'.expandtabs(len(cmt_sgn)) pass; #LOG and log('rWrks,do_uncmt, save_cols, at_min_bd, col_min_bd={}', (rWrks,do_uncmt,save_bd_col,at_min_bd,col_min_bd)) for rWrk in rWrks: line = ed_.get_text_line(rWrk) pos_body= line.index(line.lstrip()) pos_body= len(line) if 0==len(line.lstrip()) else pos_body pass; #LOG and log('rWrk,pos_body,line={}', (rWrk,pos_body,line)) if do_uncmt: # Uncomment! if not line[pos_body:].startswith(cmt_sgn): # Already no comment if bUseRepLns: lines += [line] continue #for rWrk if False:pass elif len(line)==len(cmt_sgn): # and line.startswith(cmt_sgn) line = '' elif save_bd_col and (' '==line[0] or ' '==line[pos_body+len(cmt_sgn)]): # Before or after cmt_sgn must be blank 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 if bUseRepLns: lines += [line] continue #for rWrk 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): pos_cmnt = col_min_bd if at_min_bd else pos_body pass; #LOG and log('pos_cmnt={}', (pos_cmnt)) if pos_cmnt>=len(cmt_sgn): line = line[:pos_cmnt-len(cmt_sgn)]+cmt_sgn+line[pos_cmnt: ] else: line = line[:pos_cmnt ]+cmt_sgn+line[pos_cmnt+len(cmt_sgn):] #line = line[:pos_cmnt-len(cmt_sgn)]+cmt_sgn+line[pos_cmnt:] #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 pos_cmnt = col_min_bd if at_min_bd else pos_body pass; #LOG and log('pos_cmnt={}', (pos_cmnt)) line = line[:pos_cmnt] +cmt_sgn+line[pos_cmnt:] #line = line[:pos_body] +cmt_sgn+line[pos_body:] pass; #LOG and log('new line={}', (line)) if bUseRepLns: lines += [line] else: ed_.set_text_line(rWrk, line) #for rWrk if bUseRepLns: ed_.replace_lines(y1, y2, lines) bSkip = apx.get_opt('comment_move_down', True) if bEmpSel and bSkip: (cCrt, rCrt, cEnd, rEnd) = crts[0] apx._move_caret_down(cCrt, rCrt)
def get_opt(path, val): return appx.get_opt(path, val, user_json=fn_config)
Version: '1.0.03 2017-09-13' ToDo: (see end of file) ''' import os, sys, json from collections import namedtuple, OrderedDict as odict import cudatext as app from cudatext import ed import cudax_lib as apx pass; LOG = (-1== 1) # Do or dont logging. pass; from cudax_lib import log GAP_SIZE = apx.get_opt('carethistory_gap_size' , apx.get_opt('curshist_gap_size' , 10)) # Минимальное отличие по строкам (y) от предыдущего значения для сохранения HIST_MAX = apx.get_opt('carethistory_max_history', apx.get_opt('curshist_max_history', 5)) # Максимальный размер истории для каждого таба #SAVE_HIST = apx.get_opt('carethistory_save_history', False) #CFG_JSON = app.app_path(app.APP_DIR_SETTINGS)+os.sep+'cuda_carethistory.json' HistItem = namedtuple('HistItem', ['x', 'y', 'x_', 'y_']) # x/y - caret, x_/y_ - end of selection (-1/-1 if no sel) class Command: history = {} # {tab_id:([HistItem])} poses = {} # {tab_id:pos} skip_rec= False # Antiloop def __init__(self): pass # if SAVE_HIST:
def get_opt(key, def_val: tp.Any = ''): return ctx.get_opt('differ.' + key, def_val, user_json=JSONFILE) \ if ctx.version(0) >= '0.6.8' \ else ctx.get_opt('differ.' + key, def_val)
def _dlg_opt(self): defs_json = apx.get_opt('dlg_cuda_options.defs_json', 'default.json') defs_json = defs_json if os.sep in defs_json else apx.get_def_setting_dir()+os.sep+defs_json opted = OptEdD(path_keys_info=defs_json, subset='df.') opted.show(_('Options Editor Lite'))
,' * '.join(cmd_keys.get('s2', [])) ]).strip('/') return desc #def get_hotkeys_desc @lru_cache(maxsize=32) def get_plugcmd_hotkeys(plugcmd): lcmds = app.app_proc(app.PROC_GET_COMMANDS, '') cfg_keys= [(cmd['key1'], cmd['key2']) for cmd in lcmds if cmd['type']=='plugin' and cmd['p_method']==plugcmd][0] return cfg_keys #def get_plugcmd_hotkeys MAX_HIST= apx.get_opt('ui_max_history_edits', 20) def add_to_history(val:str, lst:list, max_len=MAX_HIST, unicase=True)->list: """ Add/Move val to list head. """ pass; #log('val, lst={}',(val, lst)) lst_u = [ s.upper() for s in lst] if unicase else lst val_u = val.upper() if unicase else val if val_u in lst_u: if 0 == lst_u.index(val_u): return lst del lst[lst_u.index(val_u)] lst.insert(0, val) pass; #log('lst={}',lst) if len(lst)>max_len: del lst[max_len:] pass; #log('lst={}',lst) return lst
def _prep_const(self): brckts = apx.get_opt('intextcomp_brackets', apx.get_opt('itc_brackets', DEF_BRCKTS)) self.min_len = apx.get_opt('intextcomp_min_len', apx.get_opt('itc_min_len', DEF_MIN_LEN)) self.kill = apx.get_opt('intextcomp_kill', apx.get_opt('itc_kill', DEF_KILL)) self.sngl = apx.get_opt('intextcomp_sngl', apx.get_opt('itc_sngl', DEF_SNGL)) self.near = apx.get_opt('intextcomp_near', apx.get_opt('itc_near', DEF_NEAR)) self.wdsgns = apx.get_opt('intextcomp_word_signs', apx.get_opt('itc_word_signs', DEF_WDSGNS)) self.exsgns = apx.get_opt('intextcomp_expr_signs', apx.get_opt('itc_expr_signs', DEF_EXSGNS)) self.exall = apx.get_opt('intextcomp_expr_all', apx.get_opt('itc_expr_all', DEF_EXALL)) self.expair = apx.get_opt('intextcomp_expr_pair', apx.get_opt('itc_expr_pair', DEF_EXPAIR)) self.quotes = apx.get_opt('intextcomp_quotes', apx.get_opt('itc_quotes', DEF_QUOTES)) self.opn2cls = { brckts[i]: brckts[i + 1] for i in range(0, len(brckts), 2) } self.cls2opn = { brckts[i + 1]: brckts[i] for i in range(0, len(brckts), 2) } self.wdcmpl = r'[\w' + re.escape(self.wdsgns) + ']+' self.excmpl = r'\S+' \ if self.exall else \ r'[\w'+re.escape(self.exsgns)+']+' self.base_re = re.compile(self.wdcmpl)
def dlg_config(self): save_bd_col = apx.get_opt('comment_save_column', False) at_min_bd = apx.get_opt('comment_equal_column', False) move_down = apx.get_opt('comment_move_down', True) skip_blank = apx.get_opt('comment_skip_blank', False) by_1st = apx.get_opt('comment_toggle_by_nonempty', False) save_s = _( '(Line commands) Try to keep text position after (un)commenting') save_h = _('Try to replace only blank(s) to keep text positions:' '\rUncommented lines:' '\r····foo1' '\r····foo2' '\rCommented lines:' '\r#···foo1' '\r···#foo2') vert_s = _( '(Line "at non-space") If selected few lines, insert comment at maximal common indent' ) vert_h = _('Use maximal common column of first non-blank char:' '\rUncommented lines:' '\r··foo1' '\r····foo2' '\r······foo3' '\rCommented lines:' '\r··#foo1' '\r··#··foo2' '\r··#····foo3') down_s = _('(All) Move caret to next line') skip_s = _('(Line commands) Skip blank lines') by1st_s = _( '"Toggle line comment" detects action by first non-blank line') aid, vals, chds = dlg_wrapper( _('Configure commenting commands'), 610, 160, [ dict(cid='save', tp='ch', t=5, l=5, w=600, cap=save_s, hint=save_h) # , dict(cid='vert', tp='ch', t=5 + 25, l=5, w=600, cap=vert_s, hint=vert_h) # , dict(cid='down', tp='ch', t=5 + 50, l=5, w=600, cap=down_s) # , dict(cid='skip', tp='ch', t=5 + 75, l=5, w=600, cap=skip_s) # , dict(cid='by1st', tp='ch', t=5 + 100, l=5, w=600, cap=by1st_s) # , dict(cid='!', tp='bt', t=130, l=610 - 165 - 5, w=80, cap=_('OK'), ex0='1') # default , dict(cid='-', tp='bt', t=130, l=610 - 80 - 5, w=80, cap=_('Cancel')) ], dict(save=save_bd_col, vert=at_min_bd, down=move_down, skip=skip_blank, by1st=by_1st), focus_cid='save') if aid is None or aid == '-': return if vals['save'] != save_bd_col: apx.set_opt('comment_save_column', vals['save']) if vals['vert'] != at_min_bd: apx.set_opt('comment_equal_column', vals['vert']) if vals['down'] != move_down: apx.set_opt('comment_move_down', vals['down']) if vals['skip'] != skip_blank: apx.set_opt('comment_skip_blank', vals['skip']) if vals['by1st'] != by_1st: apx.set_opt('comment_toggle_by_nonempty', vals['by1st'])