Beispiel #1
0
 def open_selected(self):
     pass;                  #LOG and log('ok',)
     bs_dir  = os.path.dirname(ed.get_filename())
     crts    = ed.get_carets()
     for (cCrt, rCrt, cEnd, rEnd) in crts:
         if -1==cEnd: continue
         if rCrt!=rEnd: continue
         (rTx1, cTx1), (rTx2, cTx2) = apx.minmax((rCrt, cCrt), (rEnd, cEnd))
         selTx   = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
         op_file = os.path.join(bs_dir, selTx)
         if not os.path.exists(op_file):
             app.msg_status(NO_FILE_FOR_OPEN.format(op_file))
             continue
         op_ed   = _file_open(op_file)
         op_ed.focus()
Beispiel #2
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)
Beispiel #3
0
    def cmt_toggle_stream(self):
        ''' '''
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(f(_('{} works only with normal selection'), _('Commenting')))
        lex     = ed.get_prop(app.PROP_LEXER_CARET)
        ((bgn_sgn
        ,end_sgn)
        ,bOnlyLn)=self._get_cmt_pair(lex)
        if not bgn_sgn:
            return app.msg_status(f(_('No stream comment for lexer "{}"'), lex))
        bUseFLn = apx.get_opt('comment_full_line_if_no_sel', True)
        crts    = ed.get_carets()
        pass;                  #LOG and log('lex, get_carets()={}', (lex, crts))
        pass;                  #LOG and log('(bgn_sgn,end_sgn),bOnlyLn,bUseFLn={}', ((bgn_sgn,end_sgn),bOnlyLn,bUseFLn))
        for icrt, (cCrt, rCrt, cEnd, rEnd) in enumerate(crts):
            pass;              #LOG and log('(cCrt, rCrt), (cEnd, rEnd)={}', ((cCrt, rCrt), (cEnd, rEnd)))
            bEmpSel     = -1==rEnd
            bDrtSel     = -1==rEnd or (rCrt, cCrt)>(rEnd, cEnd)
            if False:pass
            elif bEmpSel and (bUseFLn or bOnlyLn):
                # Use full line
                line        = ed.get_text_line(rCrt)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rCrt), (len(line), rCrt)
            elif bOnlyLn: # and not bEmpSel
                # Only full lines
                rTx1, rTx2  = apx.minmax(rCrt, rEnd)
                line    = ed.get_text_line(rTx2)
                (cTx1, rTx1), (cTx2, rTx2) = (0, rTx1), (len(line), rTx2)
            elif bEmpSel: # and not bUseFLn and not bOnlyLn
                continue
            else:
                (rTx1, cTx1), (rTx2, cTx2) = apx.minmax((rCrt, cCrt), (rEnd, cEnd))
            selTx   = ed.get_text_substr(cTx1, rTx1, cTx2, rTx2)
            pass;              #LOG and log('(rTx1, cTx1), (rTx2, cTx2), selTx={}', ((rTx1, cTx1), (rTx2, cTx2), repr(selTx)))
            do_uncmt= selTx.startswith(bgn_sgn) and selTx.endswith(end_sgn)
            pass;              #LOG and log('do_uncmt={}', (do_uncmt))

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

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

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

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

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

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

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

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

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

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

        self.sess.bids = list(bids_d.keys())
        self.sess.bids_c = list(bids_d.values())
        self.sess.bids_i= min([(abs(bid_r-self.sess.row), bid_i)
                                for (bid_i,bid_r) in enumerate(self.sess.bids_c)
                              ])[1] \
                            if len(self.sess.bids)>1 and self.near else \
                          0
        self.incr_bfr = False  # Dont increment before use
        pass
        #LOG and log('bids={}',(list(zip(self.sess.bids, self.sess.bids_c))))
        pass
        #LOG and log('sess={}',(self.sess))
        pass
        #return False
        return True
    def _prep_sess(self, wdex='word'):
        """ Params
                wdex    Type of sess:   'word' / 'expr'
        """
        crts    = ed.get_carets()
        if len(crts)>1: 
            return app.msg_status(_("Command doesnt work with multi-carets"))
        (cCrt, rCrt
        ,cEnd, rEnd)= crts[0]
        if -1!=rEnd and rCrt!=rEnd:
            return app.msg_status(_("Command doesnt work with multi-line selection"))

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

        what        = ''                    # Str to find
        what_b      = -1                    # Pos what begin
        what_e      = -1                    # Pos what end
        kill_b      = -1                    # Pos kill begin
        kill_e      = -1                    # Pos kill end
        wbnd        = True                  # Need left word bound
        sel         = ''
        if stayed   and   wdex!=self.sess.wdex:
            # Change sess type
            what    = self.sess.src_what
            what_b  = self.sess.src_what_b
            what_e  = self.sess.src_what_e
            kill_b  = self.sess.src_kill_b
            kill_e  = self.sess.src_kill_e
            wbnd    = self.sess.src_wbnd
        if not stayed:
            # New sess
            line    = ed.get_text_line(rCrt)
            sel     = ed.get_text_sel()
            if sel:
                # Use selection to find
                what    = sel
                what_b  = cSelB
                what_e  = cSelE
                wbnd    = 0==cSelB or line[cSelB-1].isspace()
            else:
                # Use "chars around caret" to find what
                tx_bfr  = line[:cCrt ]
                ch_bfr  = tx_bfr[-1] if tx_bfr else ' '
                tx_aft  = line[ cCrt:]
                ch_aft  = tx_aft[ 0] if tx_aft else ' '
                pass;          #LOG and log('ch_bfr,ch_aft,tx_bfr,tx_aft={}',(ch_bfr,ch_aft,tx_bfr,tx_aft))
                shf_l   = 0
                shf_r   = 0
                if ch_bfr.isalnum() or ch_bfr in self.wdsgns:
                    tx_bfr_r= ''.join(reversed(tx_bfr))
                    shf_l   = len(self.base_re.match(tx_bfr_r).group())
                if ch_aft.isalnum() or ch_aft in self.wdsgns:
                    shf_r   = len(self.base_re.match(tx_aft).group())
                what_b  = cCrt-shf_l
                if self.kill:
                    what_e  = cCrt
                    kill_b  = cCrt
                    kill_e  = cCrt+shf_r
                else:
                    what_e  = cCrt+shf_r
                what    = line[what_b:what_e]
                pass;          #LOG and log('(shf_l,shf_r), (what_b,what_e), what={}',((shf_l,shf_r), (what_b,what_e), what))
        
        if not  what \
        or not  what.strip():
            return app.msg_status(_('No data for search'))
        if len(what) < self.min_len:
            return app.msg_status(f(_('Need |base|>={}, but |"{}"|=={}'), self.min_len, what, len(what)))
        pass;                  #LOG and log('what,wbnd={}',(what,wbnd))
        
        asword              = wdex=='word'
        asexpr              = wdex=='expr'
        # Make new Sess
        if not stayed:
            pass;              #LOG and log('new sess',())
            self.sess           = Command.Sess()
            self.sess.row       = rCrt
            self.sess.sel_sub   = sel_be_eb
            self.sess.src_crt   = cCrt
            self.sess.src_what  = what
            self.sess.src_what_b= what_b
            self.sess.src_what_e= what_e
            self.sess.src_kill_b= kill_b
            self.sess.src_kill_e= kill_e
            self.sess.src_wbnd  = wbnd
        self.sess.wdex          = wdex
        what_re = re.compile(''
                            + (r'\b' if wbnd else '')
                            + re.escape(what)
                            + (self.wdcmpl if asword else self.excmpl)
                            )
#               +  r'[\w'+re.escape(self.wdsgns)+']+')
        pass;                  #LOG and log('what_re={}',(what_re.pattern))
        bids_d  = OrdDict()
        for line_n in range(ed.get_line_count()):
            if line_n == self.sess.row: continue#for line_n
            line    = ed.get_text_line(line_n)
            if asexpr and self.expair:
                # Find+expand upto close brackets/quotes
                lbids_l = []
                for m in what_re.finditer(line):
                    lbid    = m.group(0)
                    
                    ok      = False
                    for op, cl in self.opn2cls.items():
                        if  op in lbid and  lbid.count(op)      > lbid.count(cl):   # Try expand to good cl
                            ext_bgn = m.end()
                            ext_end = line.find(cl, ext_bgn)
                            while -1!=ext_end:
                                lbid_ext    = lbid + line[ext_bgn:ext_end+1]
                                if          lbid_ext.count(op) == lbid_ext.count(cl):
                                    lbid,ok = lbid_ext, True
                                    break#while
                                ext_end = line.find(cl, ext_end+1)
                        if ok: break#for op
                       #for op
                    ok      = False
                    for qu in self.quotes:
                        if  qu in lbid and  1 == lbid.count(qu)     % 2:            # Try expand to good qu
                            ext_bgn = m.end()
                            ext_end = line.find(qu, ext_bgn)
                            while -1!=ext_end:
                                lbid_ext    = lbid + line[ext_bgn:ext_end+1]
                                if          0 == lbid_ext.count(qu) % 2:
                                    lbid,ok = lbid_ext, True
                                    break#while
                                ext_end = line.find(cl, ext_end+1)
                        if ok: break#for qu
                       #for qu
                    
                    lbids_l.append(lbid)
                   #for m
            else:
                # Find only
                lbids_l = what_re.findall(line)
            if lbids_l:
                bids_d.update({bid:line_n 
                                for bid in lbids_l 
                                if  bid not in bids_d
                                or  abs(line_n-self.sess.row)<abs(bids_d[bid]-self.sess.row)
                              })  # closest
        if not bids_d:
            return app.msg_status(_('No in-text completions'))
            
        self.sess.bids  = list(bids_d.keys())
        self.sess.bids_c= list(bids_d.values())
        self.sess.bids_i= min([(abs(bid_r-self.sess.row), bid_i) 
                                for (bid_i,bid_r) in enumerate(self.sess.bids_c)
                              ])[1] \
                            if len(self.sess.bids)>1 and self.near else \
                          0
        self.incr_bfr   = False  # Dont increment before use
        pass;                  #LOG and log('bids={}',(list(zip(self.sess.bids, self.sess.bids_c))))
        pass;                  #LOG and log('sess={}',(self.sess))
        pass;                  #return False
        return True
Beispiel #6
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])
Beispiel #7
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)