Esempio n. 1
0
 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')))))
Esempio n. 6
0
    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
Esempio n. 8
0
    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)
Esempio n. 12
0
    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
Esempio n. 13
0
 def dlg_ibms_in_tabs(self):
     ibms = []
     for h_tab in app.ed_handles():
         ted = app.Editor(h_tab)
         t_ibms, \
         msg     = self._ibms_in_tab(ted, self.bm_signs)
         ibms += t_ibms
     #for h_tab
     if not ibms: return app.msg_status(_('No in-text bookmarks in tabs'))
     line_max = max(
         [line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms])
     ln_wd = len(str(line_max))
     ibms = [(tab_id, line_n, bm_msg,
              f('{} {}',
                str(1 + line_n).rjust(ln_wd, ' '), line_s), tab_info)
             for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     tid = ed.get_prop(app.PROP_TAB_ID)
     rCrt = ed.get_carets()[0][1]
     near = min([(abs(line_n - rCrt) if tid == tab_id else 0xFFFFFF, ind)
                 for ind, (tab_id, line_n, bm_msg, line_s,
                           tab_info) in enumerate(ibms)])[1]
     ans = dlg_menu(
         (app.DMENU_LIST if self.show_wo_alt else app.DMENU_LIST_ALT) +
         app.DMENU_EDITORFONT + app.DMENU_CENTERED,
         w=900,
         h=800,
         cap=f(_('In-text bookmarks (all tabs): {}'), len(ibms)),
         its=[
             f('({}) {}', tab_info, bm_msg)
             for tab_id, line_n, bm_msg, line_s, tab_info in ibms
         ] if self.show_wo_alt else [
             f('({}) {}\t{}', tab_info, bm_msg, line_s)
             for tab_id, line_n, bm_msg, line_s, tab_info in ibms
         ],
         sel=near)
     if ans is None: return
     tab_id, line_n, bm_msg, line_s, tab_info = ibms[ans]
     ted = apx.get_tab_by_id(tab_id)
     ted.focus()
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(
             app.PROP_LINE_BOTTOM)):
         ed.set_prop(
             app.PROP_LINE_TOP,
             str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Esempio n. 14
0
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)
Esempio n. 15
0
 def _jump_to_ibm(self, what):
     ibms,   \
     msg     = self._ibms_in_tab(ed, self.bm_signs)
     if not ibms and msg:    return app.msg_status(msg)
     if not ibms:            return app.msg_status(_('No in-text bookmarks'))
     rCrt    = ed.get_carets()[0][1]
     if  1==len(ibms) \
     and rCrt==ibms[0][1]:   return app.msg_status(_('No more bookmarks'))
     line_ns = [line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     if self.wrap:
         line_ns = [-line_ns[-1]] + line_ns + [line_ns[0]+0xFFFFFFFF]
     line_cns= [line_n for line_n in line_ns 
                 if (line_n>rCrt if what=='next' else line_n<rCrt)]
     if not line_cns:        return app.msg_status(_('No bookmark for jump'))
     line_n  = min(line_cns)         if what=='next'         else max(line_cns)
     line_n  = -line_n               if line_n<0             else line_n
     line_n  =  line_n-0xFFFFFFFF    if line_n>=0xFFFFFFFF   else line_n
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(app.PROP_LINE_BOTTOM)):
         ed.set_prop(app.PROP_LINE_TOP, str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Esempio n. 16
0
 def dlg_ibms_in_tab(self):
     ibms,   \
     msg     = self._ibms_in_tab(ed, self.bm_signs)
     if not ibms and msg: return app.msg_status(msg)
     if not ibms: return app.msg_status(_('No in-text bookmarks'))
     line_max = max(
         [line_n for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms])
     ln_wd = len(str(line_max))
     pass
     #LOG and log('ln_wd={}',(ln_wd))
     pass
     #LOG and log('self.show_wo_alt={}',(self.show_wo_alt))
     ibms = [(bm_msg, line_n,
              f('{} {}',
                str(1 + line_n).rjust(ln_wd, ' '), line_s))
             for (tab_id, line_n, bm_msg, line_s, tab_info) in ibms]
     pass
     #LOG and log('ibms=¶{}',pf(ibms))
     rCrt = ed.get_carets()[0][1]
     near = min([(abs(line_n - rCrt), ind)
                 for ind, (bm_msg, line_n, line_s) in enumerate(ibms)])[1]
     ans = dlg_menu(
         (app.DMENU_LIST if self.show_wo_alt else app.DMENU_LIST_ALT) +
         app.DMENU_EDITORFONT,
         w=900,
         cap=f(_('Tab in-text bookmarks: {}'), len(ibms)),
         its=[
             f('{}\t{}', line_nd, bm_msg)
             for bm_msg, line_n, line_nd in ibms
         ] if self.show_wo_alt else
         [f('{}\t{}', bm_msg, line_nd) for bm_msg, line_n, line_nd in ibms],
         sel=near)
     if ans is None: return
     bm_msg, line_n, line_nd = ibms[ans]
     ed.set_caret(0, line_n)
     if not (ed.get_prop(app.PROP_LINE_TOP) <= line_n <= ed.get_prop(
             app.PROP_LINE_BOTTOM)):
         ed.set_prop(
             app.PROP_LINE_TOP,
             str(max(0, line_n - max(5, apx.get_opt('find_indent_vert')))))
Esempio n. 17
0
    def cmt_toggle_stream(self):
        ''' '''
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(f(_('{} works only with normal selection'), _('Commenting')))
        lex     = ed.get_prop(app.PROP_LEXER_CARET)
        ((bgn_sgn
        ,end_sgn)
        ,bOnlyLn)=self._get_cmt_pair(lex)
        if not bgn_sgn:
            return app.msg_status(f(_('No stream comment for lexer "{}"'), lex))
        bUseFLn = apx.get_opt('comment_full_line_if_no_sel', True)
        crts    = ed.get_carets()
        pass;                  #LOG and log('lex, get_carets()={}', (lex, crts))
        pass;                  #LOG and log('(bgn_sgn,end_sgn),bOnlyLn,bUseFLn={}', ((bgn_sgn,end_sgn),bOnlyLn,bUseFLn))
        for icrt, (cCrt, rCrt, cEnd, rEnd) in enumerate(crts):
            pass;              #LOG and log('(cCrt, rCrt), (cEnd, rEnd)={}', ((cCrt, rCrt), (cEnd, rEnd)))
            bEmpSel     = -1==rEnd
            bDrtSel     = -1==rEnd or (rCrt, cCrt)>(rEnd, cEnd)
            if False:pass
            elif bEmpSel and (bUseFLn or bOnlyLn):
                # Use full line
                line        = ed.get_text_line(rCrt)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rCrt), (len(line), rCrt)
            elif bOnlyLn: # and not bEmpSel
                # Only full lines
                rTx1, rTx2  = apx.minmax(rCrt, rEnd)
                line    = ed.get_text_line(rTx2)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rTx1), (len(line), rTx2)
            elif bEmpSel: # and not bUseFLn and not bOnlyLn
                continue
            else:
                (rTx1, cTx1), (rTx2, cTx2) = apx.minmax((rCrt, cCrt), (rEnd, cEnd))
            selTx   = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
            pass;              #LOG and log('(rTx1, cTx1), (rTx2, cTx2), selTx={}', ((rTx1, cTx1), (rTx2, cTx2), repr(selTx)))
            do_uncmt= selTx.startswith(bgn_sgn) and selTx.endswith(end_sgn)
            pass;              #LOG and log('do_uncmt={}', (do_uncmt))

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

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

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