Как запустить скрипт vim, который изменяет текущий буфер? - PullRequest
3 голосов
/ 28 февраля 2011

Я пытаюсь написать сценарий beautify.vim, который заставляет C-подобный код придерживаться стандарта, который я могу легко прочитать.

Мой файл содержит только команды замещения, которые начинаются с %s/...

Однако, когда я пытаюсь запустить скрипт с открытым файлом, в порядке :source beautify.vim или :runtime beautify.vim, он запускается, но все замещающие команды указывают, что их шаблон не был найден (шаблоны были проверены путем они вручную и должны работать).

Есть ли какой-нибудь способ заставить vim запускать команды в контексте текущего буфера?

beautify.vim:

" add spaces before open braces
sil! :%s/\%>1c\s\@<!{/ {/g
" beautify for
sil! :%s/for *( *\([^;]*\) *; *\([^;]*\) *; *\([^;]*\) *)/for (\1; \2; \3)/
" add spaces after commas
sil! :%s/,\s\@!/, /g

В моих тестах команда first: s должна совпадать (она применяется при ручном применении).

1 Ответ

3 голосов
/ 05 мая 2011

Я только недавно написал похожий скрипт beautifier, но я реализовал его более гибким способом; Кроме того, я попытался придумать механизм, позволяющий избежать подстановки содержимого в строках.

" {{{ regex silly beautifier (avoids strings, works with ranges)
function! Foo_SillyRegexBeautifier(start, end)

    let i = a:start
    while i <= a:end
        let line = getline(i)

        " ignore preprocessor directives
        if match(line, '^\s*#') == 0
            let i += 1
            continue
        endif

        " ignore content of strings, splitting at double quotes characters not 
        " preceded by escape characters
        let chunks = split(line, '\(\([^\\]\|^\)\\\(\\\\\)*\)\@<!"', 1)

        let c = 0
        for c in range(0, len(chunks), 2)

            let chunk = chunks[c]
            " add whitespace in couples
            let chunk = substitute(chunk, '[?({\[,]', '\0 ', 'g')
            let chunk = substitute(chunk, '[?)}\]]', ' \0', 'g')

            " continue like this by calling substitute() on chunk and 
            " reassigning it
            " ...

            let chunks[c] = chunk
        endfor

        let line = join(chunks, '"')

        " remove spaces at the end of the line
        let line = substitute(line, '\s\+$', '', '')

        call setline(i, line)

        let i += 1
    endw
endfunction
" }}}

Затем я определяю отображение, которое влияет на весь файл в обычном режиме и только на выделенные строки в визуальном режиме. Это хорошо, когда у вас есть некоторые тщательно отформатированные части файла, к которым вы не хотите прикасаться.

nnoremap ,bf :call Foo_SillyRegexBeautifier(0, line('$'))<CR>
vnoremap ,bf :call Foo_SillyRegexBeautifier(line("'<"), line("'>"))<CR>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...