Ejemplo n.º 1
0
    def duplicate(self):
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(DUPLICATION))

        crts    = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format(DUPLICATION))

        (cCrt, rCrt, cEnd, rEnd)    = crts[0]
        bEmpSel = -1==rEnd
        bUseFLn = get_opt('duplicate_full_line_if_no_sel', True)
        bSkip   = get_opt('duplicate_move_down', True)
        if bEmpSel:
            if not bUseFLn:
                return
            # Dup whole row
            row_txt    = ed.get_text_line(rCrt)
            ed.insert(0, rCrt, row_txt+'\n')

            # Move crt to next row
            if bSkip and (rCrt+1)<ed.get_line_count():
                _move_caret_down(cCrt, rCrt)
            return

        (rFr, cFr), (rTo, cTo)  = minmax((rCrt, cCrt), (rEnd, cEnd))
        pass;                  #LOG and log('(cFr , rFr , cTo , rTo) ={}',(cFr , rFr , cTo , rTo))
        sel_txt = ed.get_text_substr(cFr, rFr, cTo, rTo)
        pass;                  #LOG and log('sel_txt={}',repr(sel_txt))
        ed.insert(cFr, rFr, sel_txt)
Ejemplo n.º 2
0
    def duplicate(self):
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(DUPLICATION))

        crts = ed.get_carets()
        if len(crts) > 1:
            return app.msg_status(ONLY_SINGLE_CRT.format(DUPLICATION))

        (cCrt, rCrt, cEnd, rEnd) = crts[0]
        bEmpSel = -1 == rEnd
        bUseFLn = get_opt('duplicate_full_line_if_no_sel', True)
        bSkip = get_opt('duplicate_move_down', True)
        if bEmpSel:
            if not bUseFLn:
                return
            # Dup whole row
            row_txt = ed.get_text_line(rCrt)
            ed.insert(0, rCrt, row_txt + '\n')

            # Move crt to next row
            if bSkip and (rCrt + 1) < ed.get_line_count():
                _move_caret_down(cCrt, rCrt)
            return

        (rFr, cFr), (rTo, cTo) = minmax((rCrt, cCrt), (rEnd, cEnd))
        pass
        #LOG and log('(cFr , rFr , cTo , rTo) ={}',(cFr , rFr , cTo , rTo))
        sel_txt = ed.get_text_substr(cFr, rFr, cTo, rTo)
        pass
        #LOG and log('sel_txt={}',repr(sel_txt))
        ed.insert(cFr, rFr, sel_txt)
Ejemplo n.º 3
0
    def duplicate(self):
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(DUPLICATION))

        crts    = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format(DUPLICATION))

        (cCrt, rCrt, cEnd, rEnd)    = crts[0]
        if -1==cEnd:
            # Empty sel -- dup whole row
            row_txt    = ed.get_text_line(rCrt)
            ed.insert(0, rCrt, row_txt+'\n')

            # Move crt to next row
            if (rCrt+1)<ed.get_line_count():
                colCrt  = pos2pos(cCrt  , rCrt,   'smb2col')
                smbCrt1 = pos2pos(colCrt, rCrt+1, 'col2smb')
                ed.set_caret(smbCrt1, rCrt+1)
            return

        (rFr, cFr), (rTo, cTo)  = minmax((rCrt, cCrt), (rEnd, cEnd))
        #pass;                   LOG and log('(cCrt, rCrt, cEnd, rEnd)={}',(cCrt, rCrt, cEnd, rEnd))
        pass;                   LOG and log('(cFr , rFr , cTo , rTo) ={}',(cFr , rFr , cTo , rTo))
        sel_txt = ed.get_text_substr(cFr, rFr, cTo, rTo)
        pass;                   LOG and log('sel_txt={}',repr(sel_txt))
        ed.insert(cFr, rFr, sel_txt)
        if -1==rEnd: # or rCrt==rEnd:
            # Move crt to next row
            colCrt  = pos2pos(cCrt  , rCrt,   'smb2col')
            smbCrt1 = pos2pos(colCrt, rCrt+1, 'col2smb')
            ed.set_caret(smbCrt1, rCrt+1)
Ejemplo n.º 4
0
    def run(self, mcr_id, times=1, waits=0, while_chngs=False, till_endln=False):
        ''' Main (and single) way to run any macro
        '''
        pass;                   LOG and log('mcr_id, times, waits, while_chngs, till_endln={}',(mcr_id, times, waits, while_chngs, till_endln))
        mcr     = self.mcr4id.get(str(mcr_id))
        if mcr is None:
            pass;               LOG and log('no id',)
            return app.msg_status(_('No macros: {}').format(mcr_id))
        cmds4eval   = ';'.join(mcr['evl'])
        pass;                   LOG and log('nm, cmds4eval={}',(mcr['nm'], cmds4eval))
        how_t       = 'wait'
        rp_ctrl     = self.tm_ctrl.get('rp_ctrl', 1000)                     # testing one of 1000 execution
        tm_wait     = waits if waits>0 else self.tm_ctrl.get('tm_wait', 10) # sec
        start_t     = datetime.datetime.now()
        pre_body    = '' if not while_chngs else ed.get_text_all()
        for rp in range(times if times>0 else 0xffffffff):
            exec(cmds4eval)
            if till_endln and ed.get_carets()[0][1] == ed.get_line_count()-1:
                pass;           LOG and log('break endln',)
                break   #for rp
            if while_chngs:
                new_body    = ed.get_text_all()
                if pre_body == new_body:    
                    pass;       LOG and log('break no change',)
                    break   #for rp
                pre_body    = new_body
            if  (how_t=='wait'
            and (rp_ctrl-1) == rp % rp_ctrl
            and tm_wait < (datetime.datetime.now()-start_t).seconds):
                cnts    = ([
  dict(              tp='lb'    ,t=GAP          ,l=GAP  ,w=400   ,cap=_('Macro "{}" playback time is too long'.format(mcr['nm'])))
 ,dict(cid='wait'   ,tp='bt'    ,t=GAP*2+25*1   ,l=GAP  ,w=400   ,cap=_('Wait &another {} sec').format(tm_wait)  ,props='1'      )   # default
 ,dict(cid='cont'   ,tp='bt'    ,t=GAP*3+25*2   ,l=GAP  ,w=400   ,cap=_('Continue &without control')                             )
 ,dict(cid='stop'   ,tp='bt'    ,t=GAP*6+25*3   ,l=GAP  ,w=300   ,cap=_('&Cancel playback [ESC]')                                )
                        ])
                btn,vals,chds= dlg_wrapper(_('Playback macro'), GAP*2+400, GAP*7+4*25, cnts, {})
                if btn is None or btn=='stop':
                    pass;       LOG and log('break by user',)
                    app.msg_status(_('Cancel playback macro: {}'.format(mcr['nm'])))
                    break   #for rp
                if btn=='cont': #ans=='cont':
                    how_t   = 'work'
                if btn=='wait': #ans=='wait':
                    start_t = datetime.datetime.now()
           #for rp
        self.last_mcr_id = mcr_id
Ejemplo n.º 5
0
    def _cmt_toggle_line(self, cmt_type):
        ''' Add/Remove line comment
            Params
                cmt_type    '1st'    at begin of line
                            'bod'    at first not blank
        '''
        if not _check_API('1.0.107'):    return
        if ed.get_sel_mode() != app.SEL_NORMAL:
            return app.msg_status(ONLY_NORM_SEL_MODE.format(COMMENTING))

        lex         = ed.get_prop(app.PROP_LEXER_CARET)
        cmt_sgn     = app.lexer_proc(app.LEXER_GET_COMMENT, lex)
        pass;                   LOG and log('lex, cmt_sgn={}', (lex, cmt_sgn))
        if not cmt_sgn:
            return app.msg_status(CMT_NO_LINE_4LEX.format(lex))
        crts        = ed.get_carets()
        if len(crts)>1:
            return app.msg_status(ONLY_SINGLE_CRT.format(COMMENTING))

        no_tab      = ed.get_prop(app.PROP_TAB_SPACES)    # only blanks
        opts        = self._get_opts('cmt')
        save_bd_col = no_tab and opts.get('save_body_col', False)
        blnks4cmt   = '\t'.expandtabs(len(cmt_sgn))
        (cCrt, rCrt
        ,cEnd, rEnd)= crts[0]
        (rCmtBgn
        ,rCmtEnd)   = minmax(rCrt, rEnd if -1!=rEnd else rCrt)
        uncmtAll    = ed.get_text_line(rCmtBgn).lstrip().startswith(cmt_sgn)
        pass;                   LOG and log('rCmtBgn,rCmtEnd,uncmtAll={}', (rCmtBgn,rCmtEnd,uncmtAll))
        for rCmt in range(rCmtBgn, rCmtEnd+1):
            line    = ed.get_text_line(rCmt)
            pos_body= line.index(line.lstrip())
            pass;               LOG and log('rCmtBgn,rCmtEnd,uncmtAll={}', (rCmtBgn,rCmtEnd,uncmtAll))
            if uncmtAll:
                # Uncomment!
                if not line[pos_body:].startswith(cmt_sgn):
                    # Already no comment
                    continue
                if save_bd_col:
                    line = line.replace(cmt_sgn, blnks4cmt, 1)
                else:
                    line = line.replace(cmt_sgn, ''       , 1)
            else:
                # Comment!
                if cmt_type=='bod' and line[pos_body:].startswith(cmt_sgn):
                    # Body comment already sets - willnot double it
                    continue
                if False:pass
                elif cmt_type=='1st' and save_bd_col and line.startswith(blnks4cmt) :
                    line = line.replace(blnks4cmt, cmt_sgn, 1)
#               elif cmt_type=='1st' and save_bd_col #  !line.startswith(blnks4cmt) :
                elif cmt_type=='1st':#  !save_bd_col
                    line = cmt_sgn+line
                elif cmt_type=='bod' and save_bd_col and line.startswith(blnks4cmt) :
                    line = line.replace(blnks4cmt, cmt_sgn, 1)
                    line = line[:pos_body-len(cmt_sgn)]+cmt_sgn+line[pos_body:]
#               elif cmt_type=='bod' and save_bd_col #  !line.startswith(blnks4cmt) :
                elif cmt_type=='bod':#  !save_bd_col
                    line = line[:pos_body]             +cmt_sgn+line[pos_body:]

            ed.set_text_line(rCmt, line)
            #for rCmt
        if -1==rEnd and opts.get('skip-line-after', True) and (rCrt+1)<ed.get_line_count():
            colCrt  = pos2pos(cCrt  , rCrt,   'smb2col')
            smbCrt1 = pos2pos(colCrt, rCrt+1, 'col2smb')
            ed.set_caret(smbCrt1, rCrt+1)
def _get_occurrences(ignore_min_len=False):
    """
    Gets a tuple (items, text, is_selection, x1, y1) containing all the
    occurrences for the selected word or for the word under current caret.
    param: ignore_min_len works only with selections.
    """
    global occurrences

    lex = ed.get_prop(app.PROP_LEXER_FILE)

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

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

    current_text = _get_current_text()
    if not current_text: return

    text, caret_pos, is_selection = current_text

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

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

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

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

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

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

    items = find_all_occurrences(text, case_sensitive, whole_words)

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

    return items, text, is_selection, x1, y1
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
 def find_cb_string(self, updn, bgn_crt_fin='crt'):
     ''' Find clipboard value in text.
         Params
             updn            'up'|'dn' - direction
             bgn_crt_fin     'bgn'|'crt'|'fin' - start point
     '''
     clip    = app.app_proc(app.PROC_GET_CLIP, '')
     if ''==clip:    return
     clip    = clip.replace('\r\n', '\n').replace('\r', '\n')
     pass;                  #LOG and log('clip={}',repr(clip))
     crts    = ed.get_carets()
     if len(crts)>1:
         return app.msg_status(ONLY_SINGLE_CRT.format('Command'))
     # Prepare bgn-, crt-, fin-point
     (cBgn, rBgn)    = (0, 0)
     (cCrt, rCrt
     ,cEnd, rEnd)    = crts[0]
     lst_line_ind    = ed.get_line_count()-1
     lst_line        = ed.get_text_line(lst_line_ind)
     (cFin, rFin)    = (max(0, len(lst_line)-1), lst_line_ind)
     if bgn_crt_fin=='crt':
         # Some cases for natural (not wrap) find
         if updn=='dn' and (cFin, rFin) == (cCrt, rCrt):
             # Caret at finish - immediately find from start
             return self.find_cb_string(updn, bgn_crt_fin='bgn')
         if updn=='up' and (cBgn, rBgn) == (cCrt, rCrt):
             # Caret at start - immediately find from finish
             return self.find_cb_string(updn, bgn_crt_fin='fin')
         if updn=='dn' and (cBgn, rBgn) == (cCrt, rCrt):
             # Caret already at start - switch wrap off
             bgn_crt_fin = 'bgn'
         if updn=='up' and (cFin, rFin) == (cCrt, rCrt):
             # Caret already at finish - switch wrap off
             bgn_crt_fin = 'fin'
     (cPnt, rPnt
     ,cEnd, rEnd)    = apx.icase(False,0
                         ,bgn_crt_fin=='bgn', (cBgn, rBgn, cBgn, rBgn)
                         ,bgn_crt_fin=='crt', (cCrt, rCrt, cEnd, rEnd)
                         ,bgn_crt_fin=='fin', (cFin, rFin, cFin, rFin)
                         )
     # Main part
     if '\n' not in clip:
         # 1) Find inside each line
         row     = rPnt
         line    = ed.get_text_line(row)
         pos     = line.find(clip, cPnt) if updn=='dn' else line.rfind(clip, 0, cPnt)
         while -1==pos:
             row     = apx.icase(updn=='dn', row+1,   updn=='up', row-1,   -1)
             if row<0 or row==ed.get_line_count():
                 break #while
             line    = ed.get_text_line(row)
             pos     = line.find(clip) if updn=='dn' else line.rfind(clip)
         if False:pass
         elif -1==pos  and bgn_crt_fin!='crt':
             return app.msg_status(FIND_FAIL_FOR_STR.format(clip))
         elif -1==pos:#and bgn_crt_fin=='crt'
             # Wrap!
             return self.find_cb_string(updn, bgn_crt_fin=apx.icase(updn=='dn', 'bgn', 'fin'))
         elif updn=='dn':
             ed.set_caret(pos+len(clip), row, pos, row)
         elif updn=='up':
             ed.set_caret(pos, row, pos+len(clip), row)
         return
     # 2) Find m-line
     pass;                  #LOG and log('')
     clpls   = clip.split('\n')
     pass;                  #LOG and log('clpls={}',(clpls))
     clip    = repr(clip)
     if False:pass
     elif updn=='dn':
         found   = False
         row     = max(rPnt, rEnd if rEnd!=-1 else rPnt)
         if row+len(clpls) < ed.get_line_count():
             txtls   = [ed.get_text_line(r) for r in range(row, row+len(clpls))]
             pass;          #LOG and log('txtls={}',(txtls))
             while True:
                 if self._find_cb_string_included_mlines(txtls, clpls):
                     # Found!
                     found   = True
                     break #while
                 row     = row+1
                 pass;          #LOG and log('row={}',(row))
                 if row+len(clpls) >= ed.get_line_count():
                     pass;  #LOG and log('nfnd12',)
                     break #while
                 txtls   = txtls[1:]+[ed.get_text_line(row+len(clpls)-1)]
                 pass;      #LOG and log('txtls={}',(txtls))
                #while
         if False:pass
         elif not found  and bgn_crt_fin!='crt':
             return app.msg_status(FIND_FAIL_FOR_STR.format(clip))
         elif not found:#and bgn_crt_fin=='crt'
             # Wrap!
             return self.find_cb_string(updn, bgn_crt_fin=apx.icase(updn=='dn', 'bgn', 'fin'))
         ed.set_caret(len(clpls[-1]), row+len(clpls)-1, len(txtls[0])-len(clpls[0]), row)
     elif updn=='up':
         found   = False
         row     = min(rPnt, rEnd if rEnd!=-1 else rPnt)
         if row-len(clpls)+1 >= 0:
             txtls   = [ed.get_text_line(r) for r in range(row-len(clpls)+1, row+1)]
             pass;          #LOG and log('txtls={}',(txtls))
             while True:
                 if self._find_cb_string_included_mlines(txtls, clpls):
                     # Found!
                     found   = True
                     break #while
                 row     = row-1
                 pass;          #LOG and log('row={}',(row))
                 if row-len(clpls)+1 < 0:
                     break #while
                 txtls   = [ed.get_text_line(row-len(clpls)+1)]+txtls[:-1]
                 pass;          #LOG and log('txtls={}',(txtls))
                #while
         if False:pass
         elif not found  and bgn_crt_fin!='crt':
             return app.msg_status(FIND_FAIL_FOR_STR.format(clip))
         elif not found:#and bgn_crt_fin=='crt'
             # Wrap!
             return self.find_cb_string(updn, bgn_crt_fin=apx.icase(updn=='dn', 'bgn', 'fin'))
         ed.set_caret(len(clpls[-1]), row, len(txtls[0])-len(clpls[0]), row-len(clpls)+1)
Ejemplo n.º 9
0
 def run(self, mcr_id, times=1, waits=0, while_chngs=False, till_endln=False):
     ''' Main (and single) way to run any macro
     '''
     pass;                   LOG and log('mcr_id, times, waits, while_chngs, till_endln={}',(mcr_id, times, waits, while_chngs, till_endln))
     mcr     = self.mcr4id.get(str(mcr_id))
     if mcr is None:
         pass;               LOG and log('no id',)
         return app.msg_status('No macros: {}'.format(mcr_id))
     cmds4eval   = ';'.join(mcr['evl'])
     pass;                   LOG and log('nm, cmds4eval={}',(mcr['nm'], cmds4eval))
     how_t       = 'wait'
     rp_ctrl     = self.tm_ctrl.get('rp_ctrl', 1000)                     # testing one of 1000 execution
     tm_wait     = waits if waits>0 else self.tm_ctrl.get('tm_wait', 10) # sec
     start_t     = datetime.datetime.now()
     pre_body    = '' if not while_chngs else ed.get_text_all()
     for rp in range(times if times>0 else 0xffffffff):
         exec(cmds4eval)
         if till_endln and ed.get_carets()[0][1] == ed.get_line_count()-1:
             pass;           LOG and log('break endln',)
             break   #for rp
         if while_chngs:
             new_body    = ed.get_text_all()
             if pre_body == new_body:    
                 pass;       LOG and log('break no change',)
                 break   #for rp
             pre_body    = new_body
         if  (how_t=='wait'
         and (rp_ctrl-1) == rp % rp_ctrl
         and tm_wait < (datetime.datetime.now()-start_t).seconds):
             WD_BTN  = 220
             ans = app.dlg_custom(  'Playback macro', GAP*2+WD_BTN, GAP*7+4*25,  '\n'.join([]
                 +[C1.join(['type=label'     ,POS_FMT(l=GAP,  t=GAP*1+25*0+3,   r=GAP+WD_BTN, b=0)
                           ,'cap=Macro playback time is too long'
                           ] # i=0
                  )]
                 +[C1.join(['type=button'    ,POS_FMT(l=GAP,  t=GAP*2+25*1,    r=GAP+WD_BTN, b=0)
                           ,'cap=Wait &another {} sec'.format(tm_wait)
                           ] # i=1
                  )]
                 +[C1.join(['type=button'    ,POS_FMT(l=GAP,  t=GAP*3+25*2,    r=GAP+WD_BTN, b=0)
                           ,'cap=Continue &without control'
                           ] # i=2
                  )]
                 +[C1.join(['type=button'    ,POS_FMT(l=GAP,  t=GAP*6+25*3,    r=GAP+WD_BTN, b=0)
                           ,'cap=&Cancel playback [ESC]'
                           ] # i=3
                  )]
                 ), 1)    # start focus
             pass;          #LOG and log('ans={}',ans)
             ans     =('break'   if ans is None  else
                       'break'   if ans[0]==3    else
                       'wait'    if ans[0]==1    else
                       'cont'    if ans[0]==2    else 'break')
             if ans=='cont':
                 how_t   = 'work'
             if ans=='wait':
                 start_t = datetime.datetime.now()
             if ans=='break':
                 pass;       LOG and log('break by user',)
                 break   #for rp
        #for rp
     self.last_mcr_id = mcr_id
Ejemplo n.º 10
0
 def run(self,
         mcr_id,
         times=1,
         waits=0,
         while_chngs=False,
         till_endln=False):
     ''' Main (and single) way to run any macro
     '''
     pass
     LOG and log('mcr_id, times, waits, while_chngs, till_endln={}',
                 (mcr_id, times, waits, while_chngs, till_endln))
     mcr = self.mcr4id.get(str(mcr_id))
     if mcr is None:
         pass
         LOG and log('no id', )
         return app.msg_status('No macros: {}'.format(mcr_id))
     cmds4eval = ';'.join(mcr['evl'])
     pass
     LOG and log('nm, cmds4eval={}', (mcr['nm'], cmds4eval))
     how_t = 'wait'
     rp_ctrl = self.tm_ctrl.get('rp_ctrl',
                                1000)  # testing one of 1000 execution
     tm_wait = waits if waits > 0 else self.tm_ctrl.get('tm_wait',
                                                        10)  # sec
     start_t = datetime.datetime.now()
     pre_body = '' if not while_chngs else ed.get_text_all()
     for rp in range(times if times > 0 else 0xffffffff):
         exec(cmds4eval)
         if till_endln and ed.get_carets()[0][1] == ed.get_line_count() - 1:
             pass
             LOG and log('break endln', )
             break  #for rp
         if while_chngs:
             new_body = ed.get_text_all()
             if pre_body == new_body:
                 pass
                 LOG and log('break no change', )
                 break  #for rp
             pre_body = new_body
         if (how_t == 'wait' and (rp_ctrl - 1) == rp % rp_ctrl and tm_wait <
             (datetime.datetime.now() - start_t).seconds):
             WD_BTN = 220
             ans = app.dlg_custom(
                 'Playback macro',
                 GAP * 2 + WD_BTN,
                 GAP * 7 + 4 * 25,
                 '\n'.join([] + [
                     C1.join([
                         'type=label',
                         POS_FMT(l=GAP,
                                 t=GAP * 1 + 25 * 0 + 3,
                                 r=GAP + WD_BTN,
                                 b=0), 'cap=Macro playback time is too long'
                     ]  # i=0
                             )
                 ] + [
                     C1.join([
                         'type=button',
                         POS_FMT(
                             l=GAP, t=GAP * 2 + 25 * 1, r=GAP + WD_BTN, b=0
                         ), 'cap=Wait &another {} sec'.format(tm_wait)
                     ]  # i=1
                             )
                 ] + [
                     C1.join([
                         'type=button',
                         POS_FMT(
                             l=GAP, t=GAP * 3 + 25 * 2, r=GAP +
                             WD_BTN, b=0), 'cap=Continue &without control'
                     ]  # i=2
                             )
                 ] + [
                     C1.join([
                         'type=button',
                         POS_FMT(
                             l=GAP, t=GAP * 6 + 25 * 3, r=GAP +
                             WD_BTN, b=0), 'cap=&Cancel playback [ESC]'
                     ]  # i=3
                             )
                 ]),
                 1)  # start focus
             pass
             #LOG and log('ans={}',ans)
             ans = ('break'
                    if ans is None else 'break' if ans[0] == 3 else 'wait'
                    if ans[0] == 1 else 'cont' if ans[0] == 2 else 'break')
             if ans == 'cont':
                 how_t = 'work'
             if ans == 'wait':
                 start_t = datetime.datetime.now()
             if ans == 'break':
                 pass
                 LOG and log('break by user', )
                 break  #for rp
     #for rp
     self.last_mcr_id = mcr_id
Ejemplo n.º 11
0
    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