Вопрос

I have a type of data file (ENDF, if your interested) for which I'd like to create a custom ViM folding file. The folds would be dependent on (defined by) the contents of columns 66-80 of the file.

Columns 66-80 of the file(s) look something like this:

-columns 1--65                                             -125 0  0    0
-columns 1--65                                             -125 3  1    1
-columns 1--65                                             -125 3  1    2
-columns 1--65                                             -125 3  1    3
                                                            ...
-columns 1--65                                             -125 3  1   35
-columns 1--65                                             -125 3  099999
-columns 1--65                                             -125 3  2    1
                                                            ...
-columns 1--65                                             -125 3  2   35
-columns 1--65                                             -125 3  099999
                                                            ...
-columns 1--65                                             -125 3  099999
-columns 1--65                                             -125 0  0    0
-columns 1--65                                             -125 4  2    1
                                                            ...
-columns 1--65                                             -125 4  2  195

I'd like the first indent level to be where columns 71–72 have the same number. In the example above those numbers are 3,4.

The second fold level are where columns 73–76 have the same number. In the above example those numbers are 1 and 2, but could have any number—up to three digits.

Here is my first attempt at a script.

" ENDF folding functions

setlocal foldmethod=expr
setlocal foldexpr=ENDFFolds(v:lnum)

let MF = '0'
let MT = '0'

" This function is executed 
function! ENDFFolds(lnum)
    " Get the current line
    let line = getline(v:lnum)

    let mf = strpart(line, 71, 72)
    echom mf

    " Check to see if we have moved into a new file (MF)
    if mf == MF

        " Check to see if we have moved into a new section (MT)
        let mt = strpart(line, 73, 75)
        if mt == MT
            return "="
        else
            MT = mt
            return ">2"
        endif

    else
        MF = mf
        return ">1"
    endif
endfunction

I've put this script in ~/.vim/ftplugin/endf/folding.vim. I know the file is being found because I see the result of echo mf.

Unfortunately, this doesn't work. No folds are found. Please advise.

Это было полезно?

Решение

With painstaking trial and error, I came up with this solution:

setlocal foldmethod=expr
setlocal foldexpr=ENDFFolds()
setlocal foldtext=ENDFFoldText()

let g:current_line = ''
let g:current_mf = 0
let g:current_mt = 0

" This function is executed for every line to determine the fold level
function! ENDFFolds()
    " Get the current line
    let line = getline(v:lnum)

    let g:previous_mf = g:current_mf
    let g:current_mf = str2nr(strpart(line, 70, 2))

    let g:previous_mt = g:current_mt
    let g:current_mt = str2nr(strpart(line, 72, 3))

    if g:previous_mf == 0
        let g:current_mt = 0
        return '>1'
    else
        if g:previous_mt == 0
            return ">2"
        else
            return "="
        endif
    endif
endfunction

function! ENDFFoldText()
    let foldsize = (v:foldend-v:foldstart)

    let line = getline(v:foldstart)
    let MAT = strpart(line, 66, 4)
    let MF = strpart(line, 70, 2)
    let MT = strpart(line, 72, 3)

    return 'MAT='.MAT.' MF='.MF.' MT='.MT.' '.' ('.foldsize.' lines)'
endfunction
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top