vim代码片段插件ultisnips使用教程(代码片段)

author author     2022-12-27     382

关键词:

博客原文

安装

Ultisnips 插件安装分两部分,一个是 ultisnips 插件本身,另外一个是代码片段仓库。一般来说把默认的代码片段仓库下载下来按需修改后上传到自己的 github 即可。如果你和我一样也使用 vim-plug 来管理插件的话,添加下面的代码到你的 vimrc 中保存刷新即可

Plug ‘SirVer/ultisnips‘
" 你自己的代码仓库 git 地址
Plug ‘keelii/vim-snippets‘

上面的示例中所有的代码片段都存放在插件安装目录下面的 vim-snippets/UltiSnips 中,文件命名格式为 ft.snippets, ft 就是 vim 中的 filetype,其中有个 all.snippets 是唯一一个所有文件都适用的代码片段

配置

快捷键设置,我一般使用 tab 来触发代码片段补全,且不使用 YCM (官方文档表示使用YCM的话就不能使用tab补全)

let g:UltiSnipsExpandTrigger="<tab>"
" 使用 tab 切换下一个触发点,shit+tab 上一个触发点
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<S-tab>"
" 使用 UltiSnipsEdit 命令时垂直分割屏幕
let g:UltiSnipsEditSplit="vertical"

依赖

ultisnips 插件需要你的 vim 支持 python,可以在 vim 命令模式下使用下面的检测你的 vim 版本是否支持 python,返回 1 表示支持

:echo has("python")
:echo has("python3")

定义一个代码片段

定义格式

snippet 触发字符 ["代码片段说明" [参数]]
代码片段内容
endsnippet

最小化的一个代码片段

snippet if "if (condition)  ... "
if ($1:true) 
    $0

endsnippet

这时当你在 vim 中输入 if 敲 tab 就会展开一条 if 语句,第一个触发点是 if 条件表达式,最后一个是 if 语句体

$1:true 表示这是第一个触发点,占位符为 true,如果占位符没有默认值可直接使用 $1, $2, $3...

可视选择区的内容为占位符

snippet if "if (...)"
if ($1:true) 
    $VISUAL

endsnippet

$VISUAL 表示在 vim 中使用可视模式下选择的文本,这个在重构代码的时候非常有用(后面会有高级用法),上个图感受一下

技术分享图片

代码片段的参数

  • b 表示触发字符应该在一行的开始
  • i 表示触发字符可以在单词内(连续展示会使用这个选项)
  • w 表示触发字符的前后必须是一个字母分界点
  • r 表示触发字符可以是一个正则表达式
  • t 表示展开的代码片段中如果有制表符,原样输出,即使你的 vimrc 里面设置了 expandtab
  • m 表示删除代码片段右边的所有空白字符
  • e 表示自定义上下文
  • A 表示自动触发,不需要按 tab,类似于 VIM 中的 abbr

内容解释器

Ultisnips 定义的代码片段中支持三种不同的语言注入:shell, vimscript, python,在代码片段中用反引号表示

shell 代码

就是在你的命令行 shell 能执行的代码片段,比如输出当前时间

? date
2018年 8月27日 星期一 18时19分38秒 CST

在代码片段中用反引号「`」引用即可

snippet today
Today is the `date`.
endsnippet

输入 today 按 tab 展开后(格式和上面shell中的不一样,估计是因为 vim 语言设置的问题):

Today is the Mon Aug 27 18:24:51 CST 2018.

vimscript 代码

使用 indent 来输出当前缩进值,使用前缀 !v 表示是 vimscript

snippet indent
Indent is: `!v indent(".")`.
endsnippet

技术分享图片

python 代码

在代码片段中解释执行 python 代码是 ultisnips 最强大的功能,以前缀 !p 开始。系统会向 python 中注入一些变量,可以使用 python 代码直接对其进行操作

  • fn - 表示当前文件名
  • path - 当前文件名的路径
  • t - 占位符的字典,可以使用 t[1], t[2], t.v 来取占位符内容
  • snip - UltiSnips.TextObjects.SnippetUtil 对象的一个实例
  • match - 正则代码片段时返回的匹配元素(非常强大)

其中最常用的 snip 对象提供了下面一些变量:

  • snip.rv 表示 return value,python 代码执行后处理过的字符串赋给 rv 即可
  • snip.fn 表示当前文件名
  • snip.ft 表示当前文件类型
  • snip.v 表示 VISUAL 模式变量,其中 snip.v.mode 表示模式类型,snip.v.text 表示 VISUAL 模式中选择的字符

技术分享图片

占位符选择

UltiSnips 支持使用快捷键切换占位符,我使用 &lt;tab&gt;&lt;shift-tab&gt; 来切换 下一个上一个 占位符,占位符切换的作用域为当前代码片段内部(即使占位符已被修改过),当光标移动出去以后就不起作用了

技术分享图片

自定义上下文

自定义上下文可以通过正则匹配来决定代码片断是否可用,比如判断在指定的 if 语句里面才起作用的代码片断,定义格式如下:

snippet 触发字符 "描述" "表达式" 参数

比如我们定义一个 只有 在上一行以 if (DEVELOPMENT) 开头才可以展开的代码片段

snippet dbg "if (DEVELOPMENT) dbg" "re.match(‘^if (DEVELOPMENT) ‘, snip.buffer[snip.line-1])" be
debugger;
endsnippet

常见用法

行内连续展开

这个常见于需要连续展开代码片段的情况,比如,有两个片段,一个打印变量,一个处理 JSON 序列化。这时需要使用参数选项 in-word

技术分享图片

使用正则代码片段

通常写代码的时候需要使用 log, print 等来打印上下文中的变量。使用普通片段按 cl 展示 console.log() 然后把变量字符复制进括号,这样操作会比较复杂。使用正则来动态匹配前面的字符可以很好的解决这个问题

snippet "([^s]w+).log" "console.log(postfix)" r
console.log(`!p snip.rv = match.group(1)`)$0
endsnippet
snippet "([^s].*).upper" "Uppercase(postfix)" r
`!p snip.rv = match.group(1).upper()`$0
endsnippet
snippet "([^s]w+).lower" "Lowercase(postfix)" r
`!p snip.rv = match.group(1).lower()`$0
endsnippet

动图演示

技术分享图片

注意:正则代码片段只适用于单行文本处理,如果是多行转换还是得用到下面的 python + VISUAL 代码片段来处理

使用 python 解释器 + VISUAL 模式实现代码注释功能

通常我们需要使用一大堆插件来实现各种代码的注释功能。不过 Ultisnips 提供了 VISUAL 模式可以提取 vim 可视模式中选择的内容到代码片段里面,于是我们就可以结合起来制作一个具有注释功能的代码片段

流程大概是这样的:

  1. 进入 vim 可视模式,选择要注释的内容
  2. 按 tab,清除选择内容
  3. 输入代码片段触发字符,按 tab 完成

由于实现的 python 代码相对复杂一些,主要分成两个方法。单行注释和多行注释,注意 Ultisnips 中可以直接写 python 但是大段的方法建议放在插件目录下面的 pythonx 目录下面,使用的时候在对应的代码片段中的全局 python 代码 global !p 引入即可

单行注释(pythonx/javascript_snippets.py):

def comment(snip, START="", END=""):
    lines = snip.v.text.split(‘
‘)[:-1]
    first_line = lines[0]
    spaces = ‘‘
    initial_indent = snip._initial_indent

    # Get the first non-empty line
    for idx, l in enumerate(lines):
        if l.strip() != ‘‘:
            first_line = lines[idx]
            sp = re.findall(r‘^s+‘, first_line)
            if len(sp):
                spaces = sp[0]
            break

    # Uncomment
    if first_line.strip().startswith(START):
        result = [line.replace(START, "", 1).replace(END, "", 1) if line.strip() else line for line in lines]
    else:
        result = [f‘spacesSTARTline[len(spaces):]END‘ if line.strip() else line for line in lines ]

    # Remove initial indent
    if result[0] and initial_indent:
        result[0] = result[0].replace(initial_indent, ‘‘, 1)

    if result:
        return ‘
‘.join(result)
    else:
        return ‘‘

多行注释:

def comment_inline(snip, START="/* ", END=" */"):
    text = snip.v.text
    lines = text.split(‘
‘)[:-1]
    first_line = lines[0]
    initial_indent = snip._initial_indent
    spaces = ‘‘

    # Get the first non-empty line
    for idx, l in enumerate(lines):
        if l.strip() != ‘‘:
            first_line = lines[idx]
            sp = re.findall(r‘^s+‘, first_line)
            if len(sp):
                spaces = sp[0]
            break

    if text.strip().startswith(START):
        result = text.replace(START, ‘‘, 1).replace(END, ‘‘, 1)
    else:
        result = text.replace(spaces, spaces + START, 1).rstrip(‘
‘) + END + ‘
‘

    if initial_indent:
        result = result.replace(initial_indent, ‘‘, 1)

    return result

代码片段定义:

global !p
from javascript_snippets import (
    comment, comment_inline
)
endglobal

# ...

snippet c "Toggle comment every single line"
`!p
snip.rv = comment(snip, START=‘// ‘, END=‘‘)
`$0
endsnippet

snippet ci "Toggle comment inline."
`!p
snip.rv = comment_inline(snip, START="/* ", END=" */")
`$0
endsnippet

动图演示

技术分享图片

不同的语言可以在对应的片段文件中定义并传入注释符号参数即可,有了这个功能就可以愉快的删除其它的 vim 注释插件了

vim插件-ultisnips(代码片段)

文章目录参考文章安装配置默认参考文章https://blog.csdn.net/keeliizhou/article/details/82260498https://ruby-china.org/topics/25023安装Plug'SirVer/ultisnips'"你自己的代码仓库git地址Plug'honza/vim-snippets'配置letg:U 查看详情

vim下使用ultisnips(代码片段)

vim下使用UltiSnips最近在学习Linux编程,相应的也在学vim。vim中的UltiSnips插件可以实现比一般的代码补全更为强大的效果。这里就记录一下吧。UltiSnips安装、基础及进阶:https://vimzijun.net/2016/10/30/ultisnip/C++中常用的一些、已经内置... 查看详情

text用于vim和ultisnip的reactnative代码段(代码片段)

查看详情

vim自定义补全利器snippet(代码片段)

...pet是一种支持用户自定义补全的需求,在vim中,可以使用UltiSnips和Vim-Snippets两个插件进行补全。UltiSnips类似于一个替换引擎,本身是没有任何补全规则的,而Vim-Snippets则提供了各种各样的snippets。具体效果如下安装方法很简单,... 查看详情

vim8安装教程和vim中文帮助文档vimcdoc安装方法-vim使用技巧(代码片段)

Vim8.0是近十年来的一次大更新,支持任务、异步I/O、Channels和JSON以及异步计时器、Lambdas和Closures等,还包括对GTK+3的支持。由于ubuntu默认安装的Vim版本一般都是7.4.52,该版本不满足许多vim插件的需求(如YouCompleteMe),因此需要升级V... 查看详情

vim树状目录插件nerdtree安装和使用(代码片段)

安装过程:cd~mkdirnerdtreecdnerdtreewgethttp://www.vim.org/scripts/download_script.php?src_id=17123-Onerdtree.zipunzipnerdtree.zipmkdir-p~/.vim/plugin,doccpplugin/NERD_tree.vim~/.vim/plugin/cpdoc/NERD_tr 查看详情

vim-plug插件管理器安装使用(代码片段)

当没有插件管理器时,Vim用户必须手动下载tarball包形式的插件,并将它们解压到 ~/.vim 目录中。在少量插件的时候可以。但当他们安装更多的插件时,就会变得一团糟。所有插件文件分散在单个目录中,用户无法找到哪... 查看详情

Vim Ultisnips - 我如何移动到下一个占位符或制表位?

】VimUltisnips-我如何移动到下一个占位符或制表位?【英文标题】:VimUltisnips-HowdoImovetothenextplaceholderortabstop?【发布时间】:2013-10-0301:59:27【问题描述】:我刚刚安装了Macvim和UltiSnips的全新副本,但我不知道如何使用制表符和占位... 查看详情

从零开始配置vim(13)——标签页插件(代码片段)

...我们来安装它,在使用packer的前提下,你可以使用如下代码--usingpacker.nvimuse'akinsho/bufferline.nvim',tag="v2.*",r 查看详情

从零开始配置vim(13)——标签页插件(代码片段)

...我们来安装它,在使用packer的前提下,你可以使用如下代码--usingpacker.nvimuse'akinsho/bufferline.nvim',tag="v2.*",r 查看详情

vim脚本插件化(代码片段)

日积月累,自己写的vim脚本越来越多,大大的方便了日常编写任务,但是这些脚本没有做成插件的形式,导致换一台新机器时,不方便下载使用,下面就介绍一下如何把自己写的脚本做成一个插件,可以在vimrc中使用Plugxxx安装。... 查看详情

vim使用vundle管理插件(转)(代码片段)

转自:http://os.51cto.com/art/201507/484174.htmVim是Linux上一款用途广泛的轻量级文本编辑工具。虽然对普通的Linux用户来说开始学用起来难度相当大,但鉴于它具有的种种好处,完全值得一学。至于功能方面,Vim可以通过插件实现全面定... 查看详情

vim配置修改教程(代码片段)

一、动态修改vim配置反操作基本在原操作前加上no即可。#显示行号setnu#关闭行号setnonu#开启粘贴模式setpaste#关闭粘贴模式setnopaste  二、静态修改vim配置2.1查看vim使用的配置文件我们可能有时记不清vim使用哪些配置文件,可... 查看详情

linuxdebian安装vim和vim使用教程(代码片段)

Vim是一个开源免费工具,具有命令行界面和图形用户界面。它对于编辑用shell、python、Perl、c/c++等编写的配置文件和程序特别有用。最新版本的Vim包括一些新功能、错误修复和文档更新。Vim安装步骤步骤一、首先使用下... 查看详情

vim使用教程(代码片段)

Vim三种工作模式Vim有三种模式:命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等工作。输入模式:正常的文本录入。末行模式:保存或退出文档,以及设置编辑环境。  在每次运行Vim... 查看详情

从零开始配置vim(27)——代码片段

...可以自动帮我们将缩写的单词展开成一段完整的话。但是代码本身是结构话的,仅仅使用缩写来配置是无法完成自动生成代码这个步骤的。好在我们大量的插件来进行配置。本篇我们将要来讨论如何使用相关插件来完成代码片段... 查看详情

从零开始配置vim(27)——代码片段(代码片段)

...可以自动帮我们将缩写的单词展开成一段完整的话。但是代码本身是结构话的,仅仅使用缩写来配置是无法完成自动生成代码这个步骤的。好在我们大量的插件来进行配置。本篇我们将要来讨论如何使用相关插件来完成代码... 查看详情

常用的vim良好插件(代码片段)

记录在vim使用中,认为较好的插件。备注:安装插件的命令放在vundle#begin和vundle#end之间settabstop=4setsofttabstop=4setshiftwidth=4setnusyntaxon"代码高亮setnocompatible"去除VI一致性,必须要添加filetypeoff"必须要添加 查看详情