Názor k článku Vim ve funkci textového editoru pro tvůrčí psaní od Noris - Kdyby nekdo vedel jak na to lepe, tak...

  • Článek je starý, nové názory již nelze přidávat.
  • 16. 4. 2020 20:03

    Noris

    Kdyby nekdo vedel jak na to lepe, tak sem s tim.
    Jedna se o funkci, ktera po stisku tab doplni mezery podle vzoru predchoziho radku.

    function FillChar2(...) "{{{
    python << EOF
    import vim
    try:
        def fillChar2():
            mode      = 'up'
            char      = ' '
    
            args      = vim.eval('a:0')
            mode      = vim.eval('a:1') if args > 0 else mode
            char      = vim.eval('a:2') if args > 1 else char
    
            buff      = vim.current.buffer
    
            nRowEdit  = int(vim.eval("""line("'f")""")) - 1
            nColMark  = int(vim.eval("""col("'f")""")) - 1
            nColCurs  = int(vim.eval("""col(".")""")) - 1
            nColEnd   = int(vim.eval("""col("$")""")) - 1
    
            # Po ukonceni insert rezimu kurzor skoci o 1 pozici zpet
            # Vyjimkou je prvni sloupec, kdy kurzor zustava na miste
            # Nejde pak rozeznat, zda byl kurzor na prvnim nebo druhem sloupci
            # Proto mam pozici pred ukoncenim insert rezimu v f mark
            # Ta y mela byt vzdy o jedna vetsi, nez akt. pozice kurzoru
            # s vyjimkou kurzoru na prvnim sloupci.
            # Naopak f mark nefunguje na konci radku, takze musim pozici
            # kurzoru v insert modu vypocitat z akt. pozice s osetrenim
            # vyjimky na prvnim sloupci.
    
            if  nColMark == 0:
                nCol  = 0
            else:
                nCol  = nColCurs + 1
    
            # pozice kursoru v insert rezimu
            nCol = 0 if nColMark == 0 else nColCurs + 1
    
            # detekce kursoru na konci radku
            cEol = 1 if nColMark+1 == nColEnd else 0
    
            # musim najit vzorovy radek podle modu, preskakuji vsechny nevyhovujici
    
            delta = -1 if mode == 'up' else 1
    
            nr  = nRowEdit
            nrs = 0
            while True:
                nrs += 1
                nr  += delta
                if  nr < 0 or nr >= len(buff) or nrs > 5: # hledat do 5 radku
                    print 'FillChar2(): model line is not found.'
                    return 'end'
    
                sRowModel = buff[nr]
                if  len(sRowModel) <= nCol:
                    continue # moc kratka
    
                nColSpace = sRowModel[nCol:].find(' ')
                if  nColSpace == -1:
                    continue # nema mezeru
    
                sRemain  = sRowModel[nCol+nColSpace:]
                lFRemain = len(sRemain)
                lSRemain = len(sRemain.lstrip())
                if lSRemain == 0:
                    continue # nema znak za mezerou
    
                nIndent = lFRemain - lSRemain + nColSpace
                indent  = char * nIndent
    
                # ok, indent je vytvoren
                break
    
            # ted musim  vlozit indent do  radku
            reg_f = vim.eval('@f')
            vim.command('let @f="%s"' % indent)
    
            if  nCol == 0:
                vim.command('normal "fP')
            else:
                vim.command('normal "fp')
    
            vim.command('let @f="%s"' % reg_f)
    
            print 'indent by %d row, len=%d' % (nr+1, nIndent)
    
            if  cEol:
                # kdyz je kurzor na konci radku, skoci kurzor sam doleva
                vim.command('exe "normal \<Right>x"')
            else:
                vim.command('exe "normal \<Right>x\<Left>"')
            return 'done'
    
        fillChar2()
    
    except vim.error, e:
        print 'Vim FillChar2() ERROR:', e
        raise
    except Exception, e:
        print 'Python FillChar2() ERROR:', e
        raise
    EOF
    return ''
    endfunction
    " vkladam mezeru pro usnadneni zjisteni pozice kursoru, bude odstranena
    inoremap <Tab> <Space><Left><C-O>mf<Esc>:call FillChar2('up', ' ')<CR>a
    "}}}