1

I'm writing myself a function that allow users to align the column by a given character

The script is working well so far, I haven't seen any bugs yet, but I found the part that deletes the old lines and replaces them by the new aligned ones is quite messy.

Is there any better way to delete the lines than the one I'm using?

The part that replaces old text by new text:

    " + Part 3: Replace the old text by the new one
    "----------------------------------------------
    let i=a:nline-1
    while (i>-1)
        put! =list_stringsubs[i]
        let i-=1
    endwhile

    let i=0
    while (i<a:nline)
        norm j
        let i+=1
    endwhile

    let i=0
    while (i<a:nline)
        norm dd
        let i+=1
    endwhile

    let i=0
    while (i<a:nline)
        norm k
        let i+=1
    endwhile

My full script is here:

function! Align_Column (nline, charsearch, ...)
    " Print the arguments
    "echo "nline["a:nline"], charsearch["a:charsearch"], ocurrence["a:1"]"
    " Declare the argument variable
    let charorder = (a:1<=0) + (a:1>0)*a:1

    " + Part 1: Find the longest distance to the selected character
    "--------------------------------------------------------------
    " Return list
    let list_charcount = []

    " Vars for line loop
    let iln     = 0
    let linecur = line('.')
    let maxlen  = -1

    while (iln<a:nline)
        " Vars for char loop
        let nchar  = strchars (getline (linecur+iln))
        let ich    = 0
        let nmatch = 0

        while (ich<nchar)
            let charcur  = strpart (getline (linecur+iln), ich, 1)
            let charnext = strpart (getline (linecur+iln), ich+1, 1)

            if (a:charsearch != ' ')
                if (charcur == a:charsearch)
                    let nmatch += 1
                endif
            else
                if (charnext!=' ' && charcur==a:charsearch)
                    let nmatch += 1
                endif
            endif

            if (nmatch == charorder)
                break
            endif

            let ich += 1
        endwhile

        let ncharcount      = (nmatch==charorder)*(ich)
        let list_charcount += [ncharcount]
        let maxlen          = (ncharcount>maxlen)*ncharcount + (ncharcount<=maxlen)*maxlen

        let iln += 1
    endwhile

    " + Part 2: Add spaces to the shorter distances
    "----------------------------------------------
    let list_stringsubs = []

    let iln = 0

    while (iln<a:nline)
        " Vars for char loop
        let nchar   = strchars (getline (linecur+iln))
        let ich     = 0
        let strline = ""
        let nmatch  = 0
        let doadd   = 1

        while (ich<nchar)
            let charcur   = strpart (getline (linecur+iln), ich, 1)
            let charnext  = strpart (getline (linecur+iln), ich+1, 1)

            if (a:charsearch != ' ')
                if (charcur == a:charsearch)
                    let nmatch += 1
                endif
            else
                if (charnext!=' ' && charcur==a:charsearch)
                    let nmatch += 1
                endif
            endif

            if (nmatch==charorder && doadd)
                let iadd = 0
                let nadd = maxlen - ich

                while (iadd<nadd)
                    let strline .= " "
                    let iadd += 1
                endwhile

                let doadd = 0
            endif

            let strline  .= charcur
            let ich += 1
        endwhile

        let list_stringsubs += [strline]

        let iln += 1
    endwhile

    " + Part 3: Replace the old text by the new one
    "----------------------------------------------
    let i=a:nline-1
    while (i>-1)
        put! =list_stringsubs[i]
        let i-=1
    endwhile

    let i=0
    while (i<a:nline)
        norm j
        let i+=1
    endwhile

    let i=0
    while (i<a:nline)
        norm dd
        let i+=1
    endwhile

    let i=0
    while (i<a:nline)
        norm k
        let i+=1
    endwhile
endfunction
5
  • 1
    :h setline(), :h getline(), :h :d
    – Maxim Kim
    Feb 21, 2022 at 8:25
  • @MaximKim thank you VERY MUCH!!!!!!!!!!!!!
    – Rekkhan
    Feb 21, 2022 at 8:48
  • I only read your question title, but it seems this plugin might be relevant to you
    – mattb
    Feb 21, 2022 at 12:30
  • @mattb Thanks, the plugin you post do exactly what I want to do. But I prefer to write one by myself. I just want to learn vimscript through practicing.
    – Rekkhan
    Feb 21, 2022 at 13:24
  • @Rekkhan if Maxim's comment allowed you to find a solution don't hesitate to answer your own question with what you ended up using, it could be useful for other users.
    – statox
    Feb 22, 2022 at 11:28

1 Answer 1

1

Thanks to Maxim's comment on my question, I use setline() to do the replacement

The text replacement part becomes:

let iln = 0

while (iln < a:nline)
    let lncur = linecur + iln
    call setline (linecur + iln, list_stringsubs[iln])
    let iln += 1
endwhile

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.