为什么Vim如此缓慢?

6
我是一位刚开始使用vim用户,有些困惑。看起来Vim比Geany慢很多,这是非常明显的区别。在Geany中按任何键时,它都可以立即打印出来(例如llllllll)。而在Vim中则会感觉到速度变慢和跳动。与Geany相比,vim中的自动完成功能很糟糕。我曾以为Vim像光一样快,但事实并非如此。有没有什么建议可以改善,使Vim更快呢?
以下是我的_vimrc文件:
" This must be first, because it changes other options as side effect
set nocompatible

" Use pathogen to easily modify the runtime path to include all
" plugins under the ~/.vim/bundle directory
call pathogen#helptags()
call pathogen#infect()

" change the mapleader from \ to ,
let mapleader=","

" Quickly edit/reload the vimrc file
nmap <silent> <leader>ev :e $MYVIMRC<CR>
nmap <silent> <leader>sv :so $MYVIMRC<CR>

set hidden
set nowrap        " don't wrap lines
set tabstop=4     " a tab is four spaces
set backspace=indent,eol,start
                " allow backspacing over everything in insert mode
set autoindent    " always set autoindenting on
set copyindent    " copy the previous indentation on autoindenting
set number        " always show line numbers
set shiftwidth=4  " number of spaces to use for autoindenting
set shiftround    " use multiple of shiftwidth when indenting with '<' and '>'
set showmatch     " set show matching parenthesis
set ignorecase    " ignore case when searching
set smartcase     " ignore case if search pattern is all lowercase,
                "    case-sensitive otherwise
set smarttab      " insert tabs on the start of a line according to
                "    shiftwidth, not tabstop
set hlsearch      " highlight search terms
set incsearch     " show search matches as you type

set history=1000         " remember more commands and search history
set undolevels=1000      " use many muchos levels of undo
set wildignore=*.swp,*.bak,*.pyc,*.class
set title                " change the terminal's title
set visualbell           " don't beep
set noerrorbells         " don't beep

set nobackup
set noswapfile

filetype plugin indent on

autocmd filetype python set expandtab

if &t_Co >= 256 || has("gui_running")
    colorscheme badwolf
endif

if &t_Co > 2 || has("gui_running")
    " switch syntax highlighting on, when the terminal has colors
    syntax on
endif

" Vim can highlight whitespaces for you in a convenient way:
set list
set listchars=tab:>.,trail:.,extends:#,nbsp:.

set pastetoggle=<F2>

set mouse=a " Enable mouse

set encoding=utf-8
set langmenu=en_US
let $LANG = 'en_US'
source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim

set autochdir " working directory is always the same as the file you are       editing 
noremap <F5> :w !python %<CR>
inoremap <F5> <ESC>:w !python %<CR>

nmap <leader>t :NERDTree<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") &&     b:NERDTreeType == "primary") | q | endif

set guifont=Hack:h10:cDEFAULT
let g:Powerline_symbols = 'fancy'
set laststatus=2

python from powerline.vim import setup as powerline_setup
python powerline_setup()
python del powerline_setup

filetype plugin on
set omnifunc=syntaxcomplete#Complete
au CompleteDone * pclose
set completeopt=longest,menuone,preview

set guioptions-=T
set nofoldenable    " disable folding

nmap <silent> ,/ :nohlsearch<CR>

4
可能是您的vimrc文件有问题。首先尝试不使用该文件来运行vim,看看是否有区别:vim -u NONE - Andreas Louv
4
是的,你错了。 - romainl
1
你没有错 - 关于自定义,我建议的是你的vimrc文件中有一些无用的代码导致了卡顿。 - Andreas Louv
3
请参考这个问题的答案:https://dev59.com/u2ct5IYBdhLWcg3wQ7bP 。内置性能分析工具总是帮助我找到 Vim 缓慢的原因所在。 - dNitro
1
首先让我注意到的是:为什么每次启动 Vim 时都要运行 pathogen#helptags()?你只需要在安装或升级插件后运行一次即可。至于其他导致 Vim 缓慢的原因,你可能有太多的插件,这些插件会逐渐消耗它的性能。禁用你实际上没有使用的插件,然后像上面建议的那样运行分析。 - Sato Katsura
显示剩余2条评论
4个回答

15

可能有很多因素导致缓慢,不一定是Vim的问题。实际上,这很可能不是Vim的问题。

  1. 首先,了解一下Vim的运行速度:使用 vim -u NONE 运行并注释掉 .vimrc 文件中的所有内容-然后执行那个看起来很慢的操作。

  2. 不带 -u NONE 运行并进行比较。它应该与之前一样快,否则某些插件自动加载且存在问题。如果是这样,请尝试将文件暂时移出 ~/.vim/bundle 目录。

  3. 接下来,取消 .vimrc 文件的一半内容的注释并检查是否会导致缓慢。继续注释或取消注释直到找到具体行。

  4. 搜索导致缓慢的行,并查找是否有替代选项。

我猜想您可能正在进行每次滚动都要耗费大量时间的操作,例如检查文件语法。

最好逐步查找缓慢的原因。

另一个问题可能是终端和/或驱动程序速度缓慢(因此请将Vim与GVim进行比较)。如果您的终端速度很慢,有花哨的字体、透明度、小字体和大屏幕大小,则终端可能非常非常缓慢。


我正在尝试找到“坏”的插件,但我注意到了一些奇怪的事情。当我在我的导入语句后长时间按下任何键(llllllllllllllll)时,vim可以毫无问题地打印出来。但是当我在程序中间这样做时,vim会变慢并开始“跳动”。我找不到问题所在。 - jundymek
1
看起来像是语法高亮。尝试使用“:syntax off”。你的源文件很大吗?是什么操作系统?Vim的哪个版本?你使用python.vim吗?如果是,那么是哪个版本?内置的?从GitHub上获取的?你使用Tmux或Screen吗?你编译了Python支持吗?你正在使用哪些插件(如果可能,请列出~/.vim/bundle中的文件/目录)?您提供的答案越多,您将获得更快的好建议。 - Cezary Baginski
关闭语法高亮并不能解决问题。我的测试文件非常小,只有大约350行。我正在使用Windows 10,VIM 7.4。我在Vim\vim74\syntax、Vim\vim74\ftplugin和Vim\vim74\indent目录中都有python.vim文件。我没有使用Tmux或screen。我在我的.vim/bundle目录中安装了这些插件:command-t、indentpython.vim、vim-flake8。我删除了powerline,因为我注意到它会稍微减慢我的VIM速度。我安装了https://github.com/amix/vimrc来尝试,效果很好。我认为我的vimrc配置中的自动完成功能是问题所在(当输入“点”时,我必须等待一两秒钟)。 - jundymek
1
@Luk 你提到在 import 语句之后这样做是可以的(假设使用Python),但是然后开始变慢。最有可能的嫌疑人是你的 indentpython 脚本(它可能正在尝试自动缩进)或者 flake8(它运行了三个语法检查器来检查代码)。两者中的任何一个都可能通过尝试实时执行某些操作来减慢速度。我建议禁用它们。如果速度再次变快,那么逐个重新启用它们,并查看是否只有一个在减慢速度 - 然后你就找到了罪魁祸首。 - Dan Lowe
1
@Luk,再看一下你的vimrc文件,我建议你也要关注底部的自动完成设置(从omnifunccompleteopt...)。在这种情况下,自动完成将解析你的所有代码和导入的库以匹配类和符号名称,并且根据情况,这可能会相当缓慢。 - Dan Lowe
最终我卸载了Vim,删除了所有文件并重新开始。现在速度很快,但没有一些我想要的插件。我会明智地尝试添加扩展。 - jundymek

6
如果你像我一样在终端中使用vim (而不是GVim),我刚发现了一个很好的方法:尝试并且它看起来非常好:
在你的~/.vimrc中添加以下内容:
set timeoutlen=1000 set ttimeoutlen=0
在你的~/.screenrc中添加以下内容(更重要):
maptimeout 0
自从我这样做了,一切都变得更好了。

3
你能提供有关这个配置的更多信息吗? - Gordon Freeman
2
你在这里有一个相当好的解释:https://vi.stackexchange.com/questions/10249/what-is-the-difference-between-mapped-key-sequences-and-key-codes-timeoutl#answer-10284。长话短说,这些超时时间是常量(以毫秒为单位),用于停止vim等待,如果您处于按键序列中。从技术上讲(这就是我理解的),maptimeout与您的GNU屏幕直接设置的内容相同。对我来说,0毫秒很好,但我可以理解10毫秒应该更好,以便继续一些序列。 - Zero Xan
这句话是不是应该写成~/screenrc?文件名中有3个e,只是想确认一下这是否是一个打字错误:P - jenkizenki
谢谢!太棒了。现在如何消除Chrome的延迟问题呢... :-) - zeusstl

0

我曾经遇到过类似的问题,粘贴大段文字或者以正常速度输入时vim会卡顿。

你可以尝试排除你的.vimrc文件,如果你已经这么做了,可以参考这个问题查看哪些插件拖慢了速度。或者,你也可以跳过排除故障的步骤,直接使用neovim,它完全兼容vim并且异步运行。

使用neovim后,我的输入延迟问题消失了。它使用了异步库libuv,与node使用的同一库。我仍然使用与vim相同的.vimrc(复制到了~/.config/nvim/init.vim中),所以不是因为使用了不同的插件。我在Ubuntu 20.04和Macos 10.14上都看到了这种响应性改善。

我发布这个答案是因为当我最近读到这个问题时,希望有人能给出类似的答案。


0

在我的vimrc中添加了以下配置后,我的vim开始飞起来了。当您整天/整周保持vim运行并经常打开和关闭许多不同的文件进行编辑时,这非常有用。

function! CloseHiddenBuffers()
    " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    " close any buffers hidden
    " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    let open_buffers = []

    for i in range(tabpagenr('$'))
        call extend(open_buffers, tabpagebuflist(i + 1))
    endfor

    for num in range(1, bufnr("$") + 1)
        if buflisted(num) && index(open_buffers, num) == -1
            exec "bdelete ".num
        endif
    endfor
endfunction

au BufEnter * call CloseHiddenBuffers()

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