如何编写 Vim 函数以将模板文本粘贴到当前文件中?

3
最近我在学习go语言。 我发现在很多情况下,我需要输入以下文本:
package main

import "fmt"

func main () {
}

我在想,也许我可以在我的 .vimrc 文件中编写一些 vim 函数,当使用 vim 时,它们可以将模板文本写入当前文件。这可以节省我大量的工作。

我知道经过几个小时的学习 vim 脚本语言,我可以弄清楚它。但我认为这对于许多不熟练的 vim 用户来说可能是一个普遍的需求,并且我没有在 Stackoverflow 上找到类似的问题。因此,我提出了这个问题。


有一些通用的代码片段引擎。例如,可以看看 https://github.com/SirVer/ultisnips。 - Doktor OSwaldo
请参考:help skeleton,了解如何自动为新文件执行此操作的示例。 - Randy Morris
1
可能是如何在vim中使用模板的重复问题。 - phd
https://stackoverflow.com/search?q=%5Bvim%5D+insert+template - phd
我很喜欢 Golang,所以我想尽可能轻松地启动一个新的 Golang 程序 :) - Sridhar Sarnobat
4个回答

6
您可以按以下步骤创建模板:
首先,创建一个文件(例如base.go),这将成为您的模板,在其中输入您在问题中键入的代码段(我将我的模板存储在$HOME/.vim/templates/<language>/中,因此在您的情况下,它应该是$HOME/.vim/templates/go/base.go,但位置完全取决于您)。
然后,在您的.vimrc中,添加以下映射:
nnoremap <space>t :-1read $HOME/.vim/templates/go/base.go<CR>/{<CR>o

当你在普通模式下按下space-t时,此映射将执行以下操作:

  • 文件$HOME/.vim/templates/go/base.go的内容将被插入到光标所在的位置,
  • 光标将移动到起始{处,
  • 您将进入括号内的插入模式。

因此,当您打开一个新的go文件时,请按space-t,它将插入您的模板并放置您需要开始编码的位置。

编辑:-1指示要插入文件内容的位置(:.read file在当前(.)行后面插入。 -1在当前行-1后面插入。因此,实际上是在光标所在的位置插入它,并向下移动包括您所在的行在内的所有行。有关更多信息,请阅读:help range

跳转是通过/{<CR>o部分完成的,该部分查找{/{),转到它(<CR>)并在其后立即进入插入模式(o)。


如果您能解释一下 :-1read 到底代表什么,以及读取内容如何与跳转光标动作结合,那就更好了。我的意思是,我得到了一些很好的效果,但我并没有真正理解 :-1read $HOME/.vim/templates/go/base.go<CR>/{<CR>o 的机制。 - Zen

2
其他答案和评论都很好,这只是一个额外的选项。这与padawin的答案非常相似,但将骨架嵌入到vimrc文件中,这可能对您有利也可能不利。
我将其设置为插入模式扩展(通过此处的最后一行),因此我只需键入copy#并按回车键,就会出现这个文本。(您会注意到文本不包括随后行的注释星号,这是因为它们在Vim“为我键入”时自动添加。可能有一种方法可以关闭该行为,但对我来说还好。)
function! InsertCopyright()
    let l:year = strftime("%Y")
    return
        \  "/**\n"
        \. "Copyright My Great Company, " . l:year . ". All rights reserved.\n"
        \. "/"
endfunction

iabbrev <expr> copy# InsertCopyright()

我建议使用"\r"而不是"\n":https://dev59.com/eHVD5IYBdhLWcg3wJIEK - Jose

1

:help templates 显示如何在打开新文件时读取骨架模板。

几个模板扩展插件基于这种原始机制构建,并支持自动评估(例如当前日期,环境变量,内联Vimscript表达式)等功能。

有些人更喜欢按需加载这些模板(而不是自动加载),因此他们对片段插件非常满意。一些插件同时实现了片段按需和新文件模板的功能。


紧密相关(有很大的重叠部分):片段就像内置的:abbreviate,通常带有参数插入、镜像和多个停止点。其中一个最早、非常著名(并且仍然广泛使用)的Vim插件是snipMate(受编辑器启发);不幸的是,它已经不再维护了;尽管有一个分支。一种现代的替代方案(需要Python)是UltiSnips。还有更多,请参见Vim Tips Wiki上的此列表Mark Weber的这个比较

需要评估三个方面:首先是片段引擎本身的特点,其次是作者或其他人提供的片段的质量和广度;第三,添加新片段的难易程度。


0

我基于ultisnips插件和Noah Frederick的工作创建了自己的解决方案。一个名为"ultisnips_custom.vim"的文件应该放在after/plugin/ultisnips_custom.vim

然后,对于每个你想要触发标题的文件类型,都应该创建一个名为_skel的snipt。

另一个提示:在下面链接的代码中,ultisnips触发器被更改为<c-j>,所以你可以根据自己的需要进行更改。

这是我的代码:

"             File: ultisnips_custom.vim - Custom UltiSnips settings
"       Maintainer: Sergio Araújo
" Oririnal Creator: Noah Frederick
"      Last Change: abr 02 2019 17:40
"      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-j>")'
endfunction

augroup ultisnips_custom
  autocmd!
  au Bufnewfile *.sh,*.zsh,*.html,*.css,*.py,*.tex,*.md :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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接