当前位置: 首页 > 工具软件 > Open Perl IDE > 使用案例 >

用Vim打造Perl的IDE

齐昊苍
2023-12-01

使用Eclipse EPIC插件写perl程序有一段时间了,觉得它的自动完成和跳转功能比较弱(可能是因为我不太会使用的原因),决定试试vim,先在Windows 7上安装个vim (我安装的是7.4版本的)学习一下。

本文的配置都是在gVim下实验过的,没有试过terminal下的Vim。

Vim相关的文档和帖子中经常提到的一些东西的解释:

1. $HOME 及 ~ ,这两个基本上是一样的,是你的home目录。$VIM是Vim程序的安装目录, $VIMRUNTIME 一般是Vim程序(比如Windows上是vim.exe,gvim.exe)所在的目录,比如在我的Windows 7上上查到的$VIMRUNTIME是C:\Program Files (x86)\Vim\vim74。 runtimepath和$VIMRUNTIME不是相同的东西,可以在Vim的命令行模式下通过 set rtp查看runtimepath里面含了那些路径。

2.Vim的模式。Vim有多种模式,包括Normal Mode, Insert Mode, Visual Mode,Command-line mode等

3. 在Vim命令行模式下可以通过用echo命令显示一个变量的值,比如 echo $HOME

4. Vim命令行模式下键入命令时,可以用tab键进行自动补全

5. Vim配置文件,Windows上一般是指 $HOME/_vimrc,linux/unix/Max OS一般是 $HOME/.vimrc

6.Vim的个人文件目录,Windows上一般是 $HOME/vimfiles,linux/unix/Max OS一般是 $HOME/.vim

7. 很多plugin的说明中提到了 ,这个默认情况下值得是 \

8. 如果你看到像<C-v>字样的指示,指的是CTRL和v键同时按下。

9. 有时侯字母的大小写代表的是不同的意思,比如F是指Shift+f,和小写的f是不一样的

10. Vim配置文件文件中的注释符号是单个双引号

注意事项:

Vim默认的 Keycodes and maps 超时时间似乎比较短,导致我多次误认为安装上的插件没有正常工作,在配置文件中做了如下设置,好了许多

" Keycodes and maps timeout in 1/2 sec...

set timeout timeoutlen=500 ttimeoutlen=500

VIM配置文件

Windows上配置文件一般是 _vimrc,linux/unix/Mac OS一般是 .vimrc 。

Linux/Unix/Mac OS上将按以下顺序在不同位置寻找配置文件

1)$VIM/.vimrc

2)$HOME/.vimrc

Windows上,VIM将按以下顺序在不同位置寻找配置文件

1)$VIM/_vimrc

2)$HOME/_vimrc

Note: $HOME目录下有配置文件的话,$VIM目录中的配置文件不起作用。

我的配置过程:

在Windows的cmd命令行下没有查到$HOME和$VIM这两个环境变量,但是在powershell下可以看到$HOME变量是有值的。

虽然在cmd或powershell下查不到$VIM变量,但是打开vim,键入echo $VIM命令,可以看到$VIM是C:\Program Files (x86)\Vim,键入echo $HOME命令,可以看到$HOME是C:\Users\xxx (此处xxx是用户名)。

刚安装好Vim后,到$HOME目录查看,没有_vimrc文件,没有vimfiles目录, 到$VIM目录下查看,有_vimrc配置文件,这个配置文件里面又通过source命令引用了$VIMRUNTIME/mswin.vim 和$VIMRUNTIME/vimrc_example.vim。

  • 创建自己的配置文件及个人目录

在$HOME目录中新建一个_vimrc文件用来做自己的自定义配置文件,然后在$HOME目录中新建一个vimfiles目录用来存放Vim 各种plugin的文件。

Pathogen这个Vim插件是用来管理Vim的runtimepath的,这也使在个人目录中安装插件变得非常容易,因为Vim启动的时候会扫描runtimepath下的plugin,syntax等目录加载runtime文件。

如前所述,可以在Vim的命令行模式下通过 set rtp 这个命令查看runtimepath里面含了那些路径。

安装配置步骤:

从github上,点那个”Donwload Zip“按钮,下载 pathogen.vim

在$HOME\vimfiles目录下新建下面两个文件夹

autoload

bundle

把pathogen.vim放到autoload目录中,然后把下面一行添加到$HOME\_vimrc文件中的第一行

execute pathogen#infect()

搞定,随后要安装的plugin只用解压到$HOME\vimfiles\bundle目录下即可

下载snipMate并解压到$HOME\bundle目录下,然后在Vim的命令行模式下运行helptags $HOME\vimfiles\bundle\snipMate\doc,这样就可以在Vim的命令行模式下运行help snipMate来查看它的帮助文件了。

本文接下来提到的Vim插件的安装如没有特殊说明,则安装方法和这个一样。

snipMate简介

snipMate.vim aims to be an unobtrusive, concise vim script that implements some of TextMate's snippets features in Vim. A snippet is a piece of often-typed text that you can insert into your document using a trigger word followed by a . For instance, in a C file using the default installation of snipMate.vim, if you type "for" in insert mode, it will expand a typical for loop in C: for (i = 0; i < count; i++) { }

用法举例:

打开一个.pl文件,输入for然后按tab键,就会自动生成下面的代码

for (my $var = 0; $var < count; $var++) {
    # body...
}

不知道这个具体能起到什么作用,但是还是从github上下载下来按照上面的方法安装了一下。

perl-help插件的一个好处是它可以让你在在Vim中打开perl文档并在Vim中进行查看,比通过在Vim命令行下用!perldoc打开一个Windows的命令行窗口查看perl文档方便

这个插件的说明文档最好看Github上的。

这个插件的简单描述:

extended % matching for HTML, LaTeX, and many other languages 

which extends the shift + F5 (%) parenthesis matching in Vim to match HTML tags and if/then/else statements and other constructs.

这个插件的简单描述:

Surround.vim is all about "surroundings": parentheses, brackets, quotes, XML tags, and more. The plugin provides mappings to easily delete, change and add such surroundings in pairs.

具体用法可以看它自带的文档或者下面这篇博文

http://www.catonmat.net/blog/vim-plugins-surround-vim

这个插件的简单描述:

provides insert mode auto-completion for quotes, parens, brackets, etc

接下来要安装的taglist依赖这个,Vim自身的自动完成(auto completion)功能也会用到用它或其他工具生成的Tags文件。

简单描述:

Ctags generates an index (or tag) file of language objects found in source files that allows these items to be quickly and easily located by a text editor or other utility. A tag signifies a language object for which an index entry is available (or, alternatively, the index entry created for that object).

The “Exuberant ctags” program is a ctags clone that is considerably more capable than Unix ctags. It produces an extended tags file format that makes the tag searching and matching process more flexible and powerful.

安装:

下载ctags58.zip (Source and binary for Windows 98/NT/2000/XP),打开这个文件,把其中的ctags.exe 解压出来,在C:\Program Files (x86)下新建一个ctags目录,把ctags.exe拷贝到这个目录下,然后把C:\Program Files (x86)\ctags加入到windows的PATH环境变量中


对Perl程序的变量没有生成tags,通过下面的命令确认了ctags的确不支持生成Perl变量的tags,

 ctags --list-kinds=perl


 c constants

 f formats

 l labels

 p packages

 s subroutines

 d subroutine declarations [off]


不过 C:\Program Files (x86)\Vim\vim74\tools下有个pltags.pl工具,可以用来对perl的程序文件生成tags,包括perl程序文件中的变量。

CPAN上有一个 Vim::Tag 可以用来生成 perl tags for vim,不过我没有使用过。

Github上还有一个 https://github.com/kberov/ctags, Extended Rules to support Modern Perl in Exuberant Ctags,我没有试过。

配置Ctags:

编辑vim配置文件

添加两行: 

set tags=tags;

set autochdir

这里第一个命令里的分号是必不可少的。这个命令让Vim先在当前目录里寻找tags文件,如果没有找到tags文件,或者没有找到对应的目标,就到父目录中查找,一直向上递归。因为tags文件中记录的路径总是相对于tags文件所在的路径,所以要使用第二个设置项来改变vim的当前目录。如果你想直接使用绝对路径,这样也是可以的:

set tags=/absolute/path/to/tags (把/absolute/path/to/tags换成你要设置的绝对路径)

在使用过程中我用Ctags生成的tags文件似乎不能正常跳转,而使用pltags.pl工具生成的tags文件可以正常使用,不知道哪里弄错了。


用法举例:

光标移动到一个function名字上,按CTRL+],跳到该function定义的地方,接这按CTRL+t 就会跳回来。


简单描述:

The "Tag List" plugin is a source code browser plugin for Vim and provides an overview of the structure of source code files and allows 

you to efficiently browse through source code files for different programming languages.  

因为taglist需要调用ctags工具来生成tag文件,所以我们之前安装Ctags的时候要把Ctags的安装路径放到Windows的PATH变量中去,如果没有,也可以通过在Vim中设置Tlist_Ctags_Cmd这个变量的值来指定Ctags程序的位置


taglist默认情况下不会显示Perl程序里面的变量,不过如果有需要,可以通过修改taglist.vim来实现。

下面是在网上看到的一段关于对C++设置的话,供参考

--------------------------------

There is a variable s:tlist_def_cpp_settings in Taglist plugin (.vim/plugin/taglist.vim) that defines which elements are shown by default.

I extended it to:

let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' . \ 'c:class;g:enum;s:struct;u:union;f:function;m:member;' . \ 'p:prototype'

According to taglist manual you can also define tlist_cpp_settings in your .vimrc with similar value. For other languages different variables exist.

--------------------------------


taglist常用的几项_vimrc设置:


“禁止自动改变当前Vim窗口的大小

let Tlist_Inc_Winwidth=0

“把列表放在屏幕的右侧

let Tlist_Use_Right_Window=1

“让当前不被编辑的文件的列表自动折叠起来, 这样可以节约一些屏幕空间

let Tlist_File_Fold_Auto_Close=1


启用taglist

在Vim的命令行模式下如果Tlist命令即可


Vim的 Auto Complete

Vim的自动完成的方法:

Command        Type of Completion
<C-n>               Generic keywords
<C-x><C-n>    Current buffer keywords
<C-x><C-i>     Included file keywords
<C-x><C-]>     tags file keywords
<C-x><C-k>    Dictionary lookup
<C-x><C-l>    Whole line completion
<C-x><C-f>    Filename completion
<C-x><C-o>  Omni-completion
In insert mode, type the first couple of characters of a word, then press:
Ctrl-N to insert the next matching word; or Ctrl-P to insert the previous matching word.
This is particularly useful when entering the names of variables in a program.

The 'complete' option controls where the keywords are searched (include files, tag files, buffers, and more).
The 'completeopt' option controls how the completion occurs (for example, whether a menu is shown).

Vim Omni completion

Omni completion using a tags file will complete the names of defined constants, functions, classes and other names from included and other external files.

When generating a tags file, Exuberant Ctags should be used
Omni completion is not usually enabled by default. To turn on omni completion, add the following to your vimrc:
filetype plugin on
set omnifunc=MyCompleteFunction

Now you would just have to create a function called MyCompleteFunction that gives you the completions. This setting is only available to the currently active buffer, and you will have to set it for all buffers where you want to use it. Setting omnifunc is normally done in a file type plugin such that it is bound to a single file type.

看了一下perl的 type plugin,没有找到类似syntaxcomplete#Complete样子的语句,感觉是不支持Omni-completion. Github上有一个perlomni插件,不过我没有试

https://github.com/c9s/perlomni.vim

在网上看了很多文章,最终选择了neocomplcache

  • 安装neocomplcache:

neocomplcache的简单描述:

neocomplcache : Ultimate auto completion system for Vim

neocomplcache is the abbreviation of "neo-completion with cache". It provides keyword completion system by maintaining a cache of keywords in the current buffer. 

具有使用缓存,自动补全时效率高、生成的关键词列表准确等优点。


设置:

安装后,在_vimrc文件中添加下面的配置

let g:neocomplcache_enable_at_startup = 1


使用:

输入两个字母后会自动弹出补全的菜单,它似乎是不会去搜索tag文件的,

Ctrl-N to insert the next matching word; or Ctrl-P to insert the previous matching word.

注意:

打开文件第一次进入insert mode,第一次编辑时,会有停顿,可能是neocomplcache在生成关键词列表的缘故。


文件浏览器

netrw.vim是Vim自带的文件浏览器, 如果希望在vim中查看到文件的目录结构,

:Ex 开启目录浏览器netrw

:Sex 水平分割当前窗口,并在一个窗口中开启目录浏览器

:Vex 垂直分割当前窗口,并在一个窗口中开启目录浏览器
或者

:e some/directory 编辑一个目录,这样就打开了该目录结构

不过,我比较喜欢NERD tree这个插件的显示方式,就在vim配置文件中添加下面一行禁用netrw
let loaded_netrwPlugin = 1

简单描述:

The NERD tree : A tree explorer plugin for navigating the filesystem 

用法:

打开Gvim, 用命令 :NERDTree path/to/your/desired/directory  这会在左侧垂直分割出来一个窗口显示目录结构

Nerd Tree plugin can be activated by the :NERDTree vim command.

Here are the basics of how to use the plugin:

Use the natural vim navigation keys hjkl to navigate the files.

Press o to open the file in a new buffer or open/close directory.

Press t to open the file in a new tab.

Press i to open the file in a new horizontal split.

Press s to open the file in a new vertical split.

Press p to go to parent directory.

Press r to refresh the current directory.

All other keyboard shortcuts can be found by pressing ?. It will open a special help screen with the shortcut listings. Press ? again to get back to file tree.

To close the plugin execute the :NERDTreeClose command.



Mojolicious Wiki上提到的, Mojolicious templates syntax。

到Github上下载,解压到pathogen管理的bundle目录,之后把mojo.vim目录下的的snippets目录中的epl.snippets拷贝到snipMate插件目录下的snippets目录中,之后把mojo.vim目录下的的snippets目录删除,不然会导致snipMate不能正常工作。



The NERD Commenter : A plugin that allows for easy commenting of code for many filetypes. 

可以从github下载最新版

使用说明:

n\cc : 为光标以下 n 行添加注释

n\cu : 为光标以下 n 行取消注释

n\cm : 为光标以下 n 行添加块注释

注:

其中 \ 是Vim 默认的 <leader> 值,可通过在 .vimrc 文件中添加  nmap ,cc <leader>cc  =  修改映射为 , 键。就可在Normal Mode中使用   n,cc   n,cu  n,cm 快捷键设置注释了。



简单描述:

True Sublime Text style multiple selections for Vim

用这个插件可以实现多行同时编辑

可在正常、插入和可视化三种模式下工作。


使用举例:

按下<C-n>选中光标下的单词

继续按下<C-n>两次选中另外两个相同的单词

按下c进行修改

键入修改内容

按下 <Esc> 退出


我没有安装Supertab,因为不知道如何让它和snipMate和谐相处。

学习资源:

http://slideshare.net 搜索Vim

Youtube

参考文章:

Perl最佳实践附录中下面关于vim设置的部分

http://www.catonmat.net/series/vim-plugins-you-should-know-about

https://perltricks.com/article/133/2014/11/10/Boost-your-Perl-productivity-with-auto-compile-checking

https://github.com/thoughtstream/Damian-Conway-s-Vim-Setup

Vim相关的书籍

Learning vim script the hardway  这个书对于理解vim的配置文件及一些插件的配置有帮助

Hacking Vim

Learning the Vi and Vim Editors (7th Edition) 这个有中文版的

practical vim

vim 101 hacks

我的配置文件设置:

禁用了Normal Mode中使用上下左右方向键,强制自己熟悉hjkl这四个键

用分号来代替冒号,这样从Normal模式进入Command-line模式少按一下SHIFT键

参考了$VIMRUNTIME/mswin.vim 和$VIMRUNTIME/vimrc_example.vim,设置了Windows风格的拷贝粘帖快捷键(CTRL-C,CTRL-V),这样即可以在Vim内用这两个快捷键做复制(到系统粘帖板)粘贴(待粘帖的内容是从系统粘帖板取的),暂考虑到用系统粘帖板进行复制剪切的时候不多,就没有设置剪切(CTRL-X)快捷键。

把CTRL+S设置成insert mode下的Save快捷键。

通过下面的设置,不让自动完成功能搜索C:\Perl\lib目录,不然的话,会很慢。
set complete-=i

设置colorscheme为desert,似乎这个是多数人的选择。可以到$VIMRUNTIME\colors下查看VIM自带的各种colorscheme的名称,网上也可以下载到很多其他的colorscheme,blackboard.vim这个colorscheme似乎不错。


execute pathogen#infect()
filetype plugin indent on

" CTRL-C is Copy, to system clipboard
vnoremap <C-C> "+y
" CTRL-V is Paste, from system clipboard
vnoremap <C-V> "+gP
cmap <C-V>		<C-R>+
" Pasting blockwise and linewise selections is not possible in Insert and
" Visual mode without the +virtualedit feature.  They are pasted as if they
" were characterwise instead.
" Uses the paste.vim autoload script.
" Use CTRL-G u to have CTRL-Z only undo the paste.

exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i']
exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v']
" Use CTRL-Q to do what CTRL-V used to do, Henry: tested, CTRL-V still enter
" into block visual mode
noremap <C-Q>		<C-V>
" For CTRL-V to work autoselect must be off.
" On Unix we have two selections, autoselect can be used.
if !has("unix")
  set guioptions-=a
endif

colorscheme desert
" In many terminal emulators the mouse works just fine, thus enable it.
if has('mouse')
  set mouse=a
endif

" Switch syntax highlighting on, when the terminal has colors
" Also switch on highlighting the last used search pattern.
if &t_Co > 2 || has("gui_running")
  syntax on
  set hlsearch
endif

set incsearch "highligh search while typing search pattern

" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
" Only define it when not defined already.
if !exists(":DiffOrig")
  command DiffOrig vert new | set bt=nofile | r ++edit # | 0d_ | diffthis
		  \ | wincmd p | diffthis
endif

"always open vertical split window in the right side
set splitright
"always open horizontal split window below
set splitbelow
"STOP using the arrow keys
map <up> <nop>
map <down> <nop>
map <left> <nop>
map <right> <nop>
"replace 'SHIFT+:' with ';'
noremap ; :
" Use Ctrl+hjkl to switch between Window in normal mode
nmap <C-j> <C-w>j
nmap <C-k> <C-w>k
nmap <C-h> <C-w>h
nmap <C-l> <C-w>l
"ctrl+s to save the file in insert mode
imap <C-s> <C-O>:w<cr>
set showmatch
set cursorline
"set cursorcolumn
set number
set ruler
let g:neocomplcache_enable_at_startup=1
let loaded_netrwPlugin=1
"Below is to set the path where to search the tag file
set tags=tags;
set autochdir
"For auto completion, do not scan the included files, otherwise, it is very slow
set complete-=i

" Keycodes and maps timeout in 1/2 sec...
set timeout timeoutlen=500 ttimeoutlen=500

set smarttab "use shiftwidth when inserting 
set autoindent "Preserve current ident on new lines
set textwidth=78 "Wrap at this column
" allow backspacing over everything in insert mode
set backspace=indent,eol,start

set tabstop=4 "Indentation levels every four columns
set expandtab "Convert all tabs typed to spaces
set shiftwidth=4 "Indent/outdent by four columns
set shiftround "Indent/outdent to nearest tabstop
"when filetype is perl, use autocmd to set external program to use for = command
autocmd Filetype perl :set equalprg=perltidy  
"every time a file ending in .pm, .t, or.pl is saved, 
"vim will run the check syntax command on the file, 
"echoing the results to the current windowi
"%:p will pass the full path name of the file to the Unix command 
autocmd BufWritePost *.pm,*.t,*.pl echom system("perl -Ilib -c " . '"' . expand("%:p"). '"' )


下面是我的vimfiles目录结构

|~vimfiles/
| |~autoload/
| | `-pathogen.vim
| `~bundle/
|   |~delimitMate-2.7/
|   | |+autoload/
|   | |+doc/
|   | `+plugin/
|   |~matchit/
|   | |+doc/
|   | `+plugin/
|   |~mojo.vim/
|   | |+after/
|   | |+ftdetect/
|   | |+syntax/
|   | |+t/
|   | |-Changes
|   | |-LICENSE
|   | |-Makefile
|   | `-README
|   |~neocomplcache-8.0/
|   | |+autoload/
|   | |+doc/
|   | |+plugin/
|   | |+vest/
|   | `-README.md
|   |~nerdcommenter/
|   | |+doc/
|   | `+plugin/
|   |~nerdtree/
|   | |+doc/
|   | |+nerdtree_plugin/
|   | |+plugin/
|   | `+syntax/
|   |~perlhelp/
|   | |+doc/
|   | `+plugin/
|   |~snipMate/
|   | |+after/
|   | |+autoload/
|   | |+doc/
|   | |+ftplugin/
|   | |+plugin/
|   | |+snippets/
|   | `+syntax/
|   |~surround/
|   | |+doc/
|   | `+plugin/
|   |~taglist_46/
|   | |+doc/
|   | `+plugin/
|   |~vim-multiple-cursors/
|   | |+assets/
|   | |+autoload/
|   | |+doc/
|   | |+plugin/
|   | |+spec/
|   | |-CHANGELOG.md
|   | |-Gemfile
|   | |-Gemfile.lock
|   | |-MIT-LICENSE.txt
|   | |-Rakefile
|   | `-README.md
|   `~vim-perl/
|     |+contrib/
|     |+ftdetect/
|     |+ftplugin/
|     |+indent/
|     |+syntax/
|     |+t/
|     |+t_source/
|     |+tools/
|     |-build-corpus.pl
|     |-Changes
|     |-CONTRIBUTING.md
|     |-funcs-from-perlfunc.pl
|     |-Makefile
|     |-README.md
|     `-verify-corpus.pl


 类似资料: