Vim 如何为vi中生成的文件自动生成Shebang行?

Vim 如何为vi中生成的文件自动生成Shebang行?,vim,Vim,我尝试了一些Vim函数,比如vimleeve和vimleevepre,以执行一个脚本,一旦退出Vi,该脚本就会自动将Shebang行添加到所有文件中。 但是,当我们不保存文件而只是退出时,问题就出现了。 vi功能不应该被改变,这意味着当我们给vi文件名时,它会打开该文件,当我们不写就关闭时,该文件将不会被创建。在这种情况下,不应执行脚本。 还有一个特性是,这个脚本应该只在第一次写入时执行。 有可能编写这样的代码吗?如果需要操作缓冲区内容,则应改为trapBufWrite。当然,脚本可以执行很多次

我尝试了一些Vim函数,比如vimleeve和vimleevepre,以执行一个脚本,一旦退出Vi,该脚本就会自动将Shebang行添加到所有文件中。 但是,当我们不保存文件而只是退出时,问题就出现了。 vi功能不应该被改变,这意味着当我们给vi文件名时,它会打开该文件,当我们不写就关闭时,该文件将不会被创建。在这种情况下,不应执行脚本。 还有一个特性是,这个脚本应该只在第一次写入时执行。
有可能编写这样的代码吗?

如果需要操作缓冲区内容,则应改为trap
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

我建议您阅读这篇文章。除了这篇文章,他还有一个

这种方法的最大优点是,您可以得到一个动态的Shebang,而不是静态的Shebang,因为我们大多数人已经安装了某种代码片段插件,并且使用静态文件骨架与这种解决方案并不一致

注意:这篇文章有点长,但我保证它值得一读

为了我个人使用,我采用了诺亚的解决方案,如下所示:

"             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
在我的vimrc上,我有一些预定义的变量,可以在代码片段或_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'
让g:snips_author='Sergio Araujo'
让g:剪断https://dev.to/voyeg3r'
让g:snips_email=''
让g:剪断https://github.com/voyeg3r'
让g:snips_twitter='@voyeg3r'

保存/退出时,由文本编辑器将内容添加到文件中似乎是一个非常糟糕的主意。至少,在加载文件时让Vim添加该行会更明智,这样您就可以看到该行,并在不合适的情况下将其删除。
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'