Как автоматически создать строку Shebang для файлов, созданных в vi? - PullRequest
0 голосов
/ 16 апреля 2020

Я попробовал некоторые функции Vim, такие как VimLeave и VimLeavePre, чтобы выполнить скрипт, который автоматически добавляет строку Shebang ко всем файлам, как только Vi завершается. Но проблема возникает, когда мы не сохраняем файл и просто завершаем работу. Функцию vi не следует изменять, что означает, что когда мы даем имя файла vi, он открывает этот файл, а когда мы закрываем без записи, файл не будет создан. В этом случае скрипт не должен выполняться. Еще одна особенность заключается в том, что этот сценарий должен выполняться только при первой записи. Можно ли написать такой код?

Ответы [ 2 ]

0 голосов
/ 16 апреля 2020

Я бы порекомендовал прочитать эту статью Ноа Фредерика Шаблоны файлов с UltiSnips и Projectionist . Помимо статьи, у него также есть видео

. Большим преимуществом этого метода является то, что вы получаете динамический c Шебанг вместо статического c, потому что большинство из нас уже установлен какой-то плагин snippets, и использование файловых скелетов stati c не будет соответствовать этим решениям.

Примечание: статья немного длинная, но я гарантирую, что ее стоит прочитать.

Для личного пользования я адаптировал решение Ноя примерно так:

"             File: ultisnips_custom.vim - Custom UltiSnips settings
"       Maintainer: Sergio Araújo
" Oririnal Creator: Noah Frederick
"        Reference: https://noahfrederick.com/log/vim-templates-with-ultisnips-and-projectionist
"      Last Change: nov 20 2019 08:53
"      Place it at: after/plugin/ultisnips_custom.vim

" We need python or python3 to run ultisnips
if !has("python") && !has("python3")
  finish
endif

" This function is called by the autocommand at the end of the file
function! TestAndLoadSkel() abort
  let filename = expand('%')
  " Abort on non-empty buffer or extant file
  if !(line('$') == 1 && getline('$') == '') || filereadable('%')
    return
  endif

  " Load UltiSnips in case it was deferred via vim-plug
  if !exists('g:did_plugin_ultisnips') && exists(':PlugStatus')
    call plug#load('ultisnips')
    doautocmd FileType
  endif

  " the function feedkys simulates the insert key sequence in order to call
  " the template (skel)
   execute 'call feedkeys("i_skel\<C-r>=UltiSnips#ExpandSnippet()\<CR>")'
endfunction

augroup ultisnips_custom
  autocmd!
  au Bufnewfile *.sh,*.zsh,*.html,*.css,*.py,*.tex,*.md,*.vim :call TestAndLoadSkel()
  "autocmd BufEnter *.sh,*.zsh,*.html,*.py execute 'call feedkeys("i_skel\<c-j>")'
augroup END

" vim: fdm=marker:sw=2:sts=2:et

Обратите внимание на место, где вы должны поместить этот файл: after/plugin/ultisnips_custom.vim

Примечание: для каждого типа файла, который вы хотите использовать Shebang, вы должны создать фрагмент с именем _skel, или вы можете адаптировать код под свои нужды.

Для моих фрагментов vim у меня есть этот:

snippet _skel "file header" w
"       file: ${1:`!p snip.rv = snip.fn`}
"     author: `!v g:snips_author`
"       site: `!v g:snips_site`
"    Created: `!v strftime("%b %d, %Y - %H:%M")`
"Last Change: `!v strftime("%b %d, %Y")`
${0}
endsnippet

На моем vimr c У меня есть несколько предопределенных переменных, которые я могу использовать в моих фрагментах или файлах _skel:

let g:snips_author='Sergio Araujo'
let g:snips_site='https://dev.to/voyeg3r'
let g:snips_email='<voyeg3r ✉ gmail.com>'
let g:snips_github='https://github.com/voyeg3r'
let g:snips_twitter='@voyeg3r'
0 голосов
/ 16 апреля 2020

Если вам нужно манипулировать содержимым буфера, вы должны вместо этого перехватить BufWrite. Конечно, сценарий может быть выполнен многократно, но это не так уж и важно, поскольку мы можем легко избежать множественных изменений буфера. Например,

augroup AddShebang | au!
    autocmd BufWrite * call s:add_shebang()
augroup end

let s:known_shebang = {
    \ 'awk': '/usr/bin/awk -f',
    \ 'perl': '/usr/bin/perl -w',
    \ 'python': '/usr/bin/env python',
\ }

function s:add_shebang()
    let l:cmd = get(s:known_shebang, &filetype)
    " filetype is known but shebang was not added yet
    if !empty(l:cmd) && getline(1) !~# '^#!'
        call append(0, '#!'..l:cmd)
    endif
endfunction
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...