фильтры vim и стандартный вывод / стандартный поток ошибок - PullRequest
9 голосов
/ 04 апреля 2010

Когда я использую:%!чтобы пропустить содержимое файла через фильтр, и фильтр не работает (он возвращает код, отличный от 0), и выводит сообщение об ошибке в stderr. Мой файл заменяется этим сообщением об ошибке.Есть ли способ сказать vim пропустить фильтрацию, если фильтр возвращает код состояния, который указывает на ошибку и / или игнорировать вывод, который программа фильтра записывает в stderr?

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

Также у меня есть похожая проблема при написании пользовательского сценария vim для выполнения фильтрации.У меня есть скрипт, который вызывает программу-фильтр с помощью system () и заменяет файл в буфере выводом, но, похоже, нет способа определить, были ли строки, возвращенные system (), записаны в stdout или stderr,Есть ли способ отличить их в скрипте vim?

Ответы [ 4 ]

5 голосов
/ 06 апреля 2010

:!{cmd} Выполняет {cmd} с оболочкой и устанавливает v:shell_error.

Если вы настроили сопоставления для вызова ваших фильтров, вы можете сделать что-то вроде следующего:

function! UndoIfShellError()
    if v:shell_error
        undo
    endif
endfuntion

nmap <leader>filter :%!/path/to/filter<CR>:call UndoIfShellError()<CR>
3 голосов
/ 05 апреля 2010

Вы можете использовать Python для различия между stdout и stderr:

python import vim, subprocess
python b=vim.current.buffer
python line=vim.current.range.start
python p=subprocess.Popen(["command", "argument", ...], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
python returncode=p.poll()
python if not returncode: b.append(("STDOUT:\n"+p.stdout.read()+"\nSTDERR:\n"+p.stderr.read()).split("\n"), line)
1 голос
/ 11 августа 2010

Альтернативой может быть запуск команды фильтра, такой как изменение файла на диске.

Например, для gofmt (www.golang.org) у меня есть следующие сопоставления:

map <f9> :w<CR>:silent !gofmt -w=true %<CR>:e<CR>
imap <f9> <ESC>:w<CR>:silent !gofmt -w=true %<CR>:e<CR>

Пояснение: : w - сохранить файл : silent - избегать нажатия Enter в конце % - передает файл в gofmt -w = true - говорит gofmt записать обратно в файл : e - сообщает vim перезагрузить измененный файл

0 голосов
/ 06 января 2018

Вот что я в итоге сделал:

function MakeItAFunction(line1, line2, args)
  let l:results=system() " call filter via system or systemlist
  if v:shell_error
    "no changes were ever actually made!
    echom "Error with etc etc"
    echom results
  endif
  "process results if anything needed?

  " delete lines but don't put in register:
  execute a:line1.",".a:line2." normal \"_dd"
  call append(a:line1-1, l:result)  " add lines
  call cursor(a:line1, 1)  " back to starting place
  " echom any messages
endfunction
command -range <command keys> MakeItAFunction(<line1>,<line2>,<q-args>) 
"                                         or <f-args>, etc.

Вы можете увидеть мой полный код на http://vim.wikia.com/wiki/Perl_compatible_regular_expressions

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...