我如何 运行 对 select 模板中的新创建文件的一些命令 vim?
how can I run some commands to select template for new created file in vim?
我是 vim 的新手,想了解有关模板的一些有趣功能。现在我有一个 c 模板,在我的 vimrc:
if has("autocmd")
augroup templates
autocmd BufNewFile *.c 0r ~/.vim/templates/skeleton.c
augroup END
endif
但是,我不想用这个模板打开每个 c 文件(也许我有很多不同 c 文件的模板),并且想要在不同模板之间使用一些命令 select。如何实现这个目标?非常感谢!
让我们从需求列表开始:
- 每次我们编辑一个新的 C 文件时,我们想要...
- 插入模板…
- 从列表中选择...
- 根据特定目录的内容构建。
让我们从下往上做。
目录布局
~/.vim/templates/skeleton.<extension>
允许我们为给定的扩展设置多个“骨架”。我倾向于更喜欢基于文件类型做事,但在这种情况下扩展名更有意义,所以我们将保留您的布局。
列出给定目录中的文件
每当我们需要内置函数时,我们的第一站应该是 :help function-list
,它按主题对每个内置函数进行分组,或者如果我们熟悉该分组,则直接 :help <topic>-functions
.在这种情况下,我们在 :help file-function
下找到以下行:
readdir() get a List of file names in a directory
的确,:help readdir()
正是我们所需要的,但不幸的是(而且未记录)它不会自行扩展环境变量或波浪号,因此我们必须 :help expand()
我们的目录路径.
我们可以做到:
:let templates = readdir(expand('~/.vim/templates/'))
:echo templates
得到类似的东西:
['foo.c', 'bar.c', 'baz.h']
或者我们只能 return 扩展名为 .c
的文件:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.c$'})
:echo templates
['foo.c', 'bar.c']
或者我们可以使用与当前缓冲区关联的文件的扩展名:
:let templates readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:echo templates
['foo.c', 'bar.c']
完成。
Select 来自列表
我们再次转向 Vim 寻找线索。在 :help interactive-functions
下,我们发现以下有前途的函数:
inputlist() let the user pick an entry from a list
首先,让我们认识一下:help inputlist()
。
:echo inputlist(['Choose:', '1. foo', '2. bar', '3. baz'])
看起来像:
Choose:
1. foo
2. bar
3. baz
Type number and <Enter> or click with the mouse (q or empty cancels):
并打印所选数字。
让我们使用之前的文件列表命令让它更有用:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:echo inputlist(['Choose a template:'] + templates)
看起来像:
Choose a template:
bar.c
foo.c
Type number and <Enter> or click with the mouse (q or empty cancels):
并且仍然打印所选的数字,但我们在每次输入之前没有数字。这可以用 :help mapnew()
:
来解决
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:echo inputlist(['Choose a template:'] + templates_for_display)
看起来像:
Choose a template:
1. bar.c
2. foo.c
Type number and <Enter> or click with the mouse (q or empty cancels):
并且仍然打印所选的数字。这个阶段剩下的就是打印 templates
中的实际项目。由于列表是从零开始的,我们必须偏移一个以获得直观的显示,我们只需要将 return 由 inputlist()
:
编辑的数字减去 1
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:echo templates[choice - 1]
正确打印 bar.c
或 foo.c
.
我们正在取得巨大进步!
插入模板
:help :read
是一种从外部源插入文本的粗略方法。在这里,我们更喜欢使用 :help setline()
和 :help readfile()
.
的更简洁的方式
但首先,让我们根据所选模板名称构建完整路径:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:echo chosen_template
应该打印如下内容:
~/.vim/templates/foo.c
我们现在可以读取文件了:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:let template_content = readfile(chosen_template)
:echo template_content
最后,将其插入缓冲区:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:let template_content = readfile(chosen_template)
:call setline(1, template_content)
让我们将它们放在我们 vimrc
:
中的一个函数中
function SelectTemplate()
let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
let choice = inputlist(['Choose a template:'] + templates_for_display)
let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
let template_content = readfile(chosen_template)
call setline(1, template_content)
endfunction
并从 c
文件中测试它:
:call SelectTemplate()
太棒了!我们快完成了!
自动化
对于最后一步,我们可以简单地使用您的代码段并进行一些小改动:
if has("autocmd")
augroup templates
autocmd!
autocmd BufNewFile *.c call SelectTemplate()
augroup END
endif
呸!多么美妙的旅程!
什么,现在?
- 可以通过删除重复项并在各处添加检查来稍微改进该函数。
- 这应该可以在自动命令中使用
*
以便它适用于任何文件扩展名。
我是 vim 的新手,想了解有关模板的一些有趣功能。现在我有一个 c 模板,在我的 vimrc:
if has("autocmd")
augroup templates
autocmd BufNewFile *.c 0r ~/.vim/templates/skeleton.c
augroup END
endif
但是,我不想用这个模板打开每个 c 文件(也许我有很多不同 c 文件的模板),并且想要在不同模板之间使用一些命令 select。如何实现这个目标?非常感谢!
让我们从需求列表开始:
- 每次我们编辑一个新的 C 文件时,我们想要...
- 插入模板…
- 从列表中选择...
- 根据特定目录的内容构建。
让我们从下往上做。
目录布局
~/.vim/templates/skeleton.<extension>
允许我们为给定的扩展设置多个“骨架”。我倾向于更喜欢基于文件类型做事,但在这种情况下扩展名更有意义,所以我们将保留您的布局。
列出给定目录中的文件
每当我们需要内置函数时,我们的第一站应该是 :help function-list
,它按主题对每个内置函数进行分组,或者如果我们熟悉该分组,则直接 :help <topic>-functions
.在这种情况下,我们在 :help file-function
下找到以下行:
readdir() get a List of file names in a directory
的确,:help readdir()
正是我们所需要的,但不幸的是(而且未记录)它不会自行扩展环境变量或波浪号,因此我们必须 :help expand()
我们的目录路径.
我们可以做到:
:let templates = readdir(expand('~/.vim/templates/'))
:echo templates
得到类似的东西:
['foo.c', 'bar.c', 'baz.h']
或者我们只能 return 扩展名为 .c
的文件:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.c$'})
:echo templates
['foo.c', 'bar.c']
或者我们可以使用与当前缓冲区关联的文件的扩展名:
:let templates readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:echo templates
['foo.c', 'bar.c']
完成。
Select 来自列表
我们再次转向 Vim 寻找线索。在 :help interactive-functions
下,我们发现以下有前途的函数:
inputlist() let the user pick an entry from a list
首先,让我们认识一下:help inputlist()
。
:echo inputlist(['Choose:', '1. foo', '2. bar', '3. baz'])
看起来像:
Choose:
1. foo
2. bar
3. baz
Type number and <Enter> or click with the mouse (q or empty cancels):
并打印所选数字。
让我们使用之前的文件列表命令让它更有用:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:echo inputlist(['Choose a template:'] + templates)
看起来像:
Choose a template:
bar.c
foo.c
Type number and <Enter> or click with the mouse (q or empty cancels):
并且仍然打印所选的数字,但我们在每次输入之前没有数字。这可以用 :help mapnew()
:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:echo inputlist(['Choose a template:'] + templates_for_display)
看起来像:
Choose a template:
1. bar.c
2. foo.c
Type number and <Enter> or click with the mouse (q or empty cancels):
并且仍然打印所选的数字。这个阶段剩下的就是打印 templates
中的实际项目。由于列表是从零开始的,我们必须偏移一个以获得直观的显示,我们只需要将 return 由 inputlist()
:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:echo templates[choice - 1]
正确打印 bar.c
或 foo.c
.
我们正在取得巨大进步!
插入模板
:help :read
是一种从外部源插入文本的粗略方法。在这里,我们更喜欢使用 :help setline()
和 :help readfile()
.
但首先,让我们根据所选模板名称构建完整路径:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:echo chosen_template
应该打印如下内容:
~/.vim/templates/foo.c
我们现在可以读取文件了:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:let template_content = readfile(chosen_template)
:echo template_content
最后,将其插入缓冲区:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:let template_content = readfile(chosen_template)
:call setline(1, template_content)
让我们将它们放在我们 vimrc
:
function SelectTemplate()
let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
let choice = inputlist(['Choose a template:'] + templates_for_display)
let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
let template_content = readfile(chosen_template)
call setline(1, template_content)
endfunction
并从 c
文件中测试它:
:call SelectTemplate()
太棒了!我们快完成了!
自动化
对于最后一步,我们可以简单地使用您的代码段并进行一些小改动:
if has("autocmd")
augroup templates
autocmd!
autocmd BufNewFile *.c call SelectTemplate()
augroup END
endif
呸!多么美妙的旅程!
什么,现在?
- 可以通过删除重复项并在各处添加检查来稍微改进该函数。
- 这应该可以在自动命令中使用
*
以便它适用于任何文件扩展名。