概述
多文件类型也可以叫混合文件类型(multiple filetype), 比如 HTML 里面写 CSS, JS 代码,虽然不提倡,但偶尔也有这个需求。
根据常识,我们知道,往往针对不同的文本类型,vim 或其插件,会出发不同的事件,例如特定的语法高亮、特定的语法检测、特定的自动补全方案等。
几乎每个 vim user 的 vimrc 中都会有如下配置:
1
| filetype plugin indent on
|
其中的 filetype on 表示:
每次一个新的或者已经存在的文件被编辑时,Vim 会试图识别文件的类型,并设置’filetype’ 选项。同时,也触发 FileType 事件。该事件可以设置语法高亮,特定选项,等等。———— 出自 《vim 参考手册》,译者: Willis、tocer
那么是否能直接通过修改文件的 filetype 值实现多文件类型的自动补全呢? 答案是否定的,因为这将引起语法检测,语法高亮等一系列的变化,这是我们所不能接受的。
github 上已经有人大致实现了这个功能,主要通过 deoplete.nvim
和 context_filetype.vim
两个插件。都是一个作者写的,前者提供一个可扩展的 vim 自动补全框架,后者支持前者实现多文件类型自动补全。
实际操作
修改 .vimrc
文件如下:
(下面提供的插件安装方式都是基于 vim-plug
的。不要再用 vundle
了,因为它目前不支持多线程,下载插件很慢。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| if has('nvim') Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' } else Plug 'Shougo/deoplete.nvim' Plug 'roxma/nvim-yarp' Plug 'roxma/vim-hug-neovim-rpc' endif
Plug 'Shougo/context_filetype.vim'
if !exists('g:context_filetype#same_filetypes') let g:context_filetype#filetypes = {} endif let g:context_filetype#filetypes.svelte = [ \ {'filetype' :'javascript', 'start': '<script>', 'end': '</script>'}, \ {'filetype' :'css', 'start': '<style>', 'end': '</style>'}, \ ]
let g:deoplete#enable_at_startup = 1 autocmd InsertLeave,CompleteDone * if pumvisible() == 0 | pclose | endif
call deoplete#custom#var('omni', 'functions', { \ 'css': ['csscomplete#CompleteCSS'], \ 'javascript': ['javascriptcomplete#CompleteJS'], \ 'html': ['htmlcomplete#CompleteTags'], \}) call deoplete#custom#var('omni', 'input_patterns', { \ 'javascript': '[^. *\t]\.\w*', \ })
inoremap <silent><expr> <TAB> pumvisible() ? "\<C-n>" : \ <SID>check_back_space() ? "\<TAB>" : \ deoplete#mappings#manual_complete() function! s:check_back_space() abort "{{{ let col = col('.') - 1 return !col || getline('.')[col - 1] =~ '\s' endfunction
|
执行 :PlugInstall
代码分析
作为一个 vimscript
还没入门的新手,看了大半天代码,了解如下:
context_filetype.vim
插件,通过 context_filetype#get()
入口函数在光标处于<style> </style>
范围内时,返回如下格式的字典:
1
| {'range': [[9, 1], [12, 4]], 'filetype': 'css'}
|
该字典含义为 {范围:[ 标签起始位置,标签结束位置 ],文件类型 }
但是我没有明白 deoplete.nvim
是如何使用这个接口的。
作者让我看 context.py 这段代码,我只能弱弱的回复一个”Thanks”。