My previous posts about using Vim ( 1 , 2 ) were well received by readers, and it's time to update. Vim 8 has a lot of really needed functionality, and new community sites like VimAwesome made it easier to find and select plugins. Recently, I have been working a lot with Vim and have organized a workflow based on maximum efficiency, here is a snapshot of my current work.
In short:
ag
- to search for files.
Recent vim session
As usual, everyone can download my dot-files and vimrc . I also prepared a separate installation script for updating and installing Vim plug-ins.
TextMate and Sublime Text showed us that the fastest way to search for files is fuzzy finding, when you enter parts of a file name, path, tag, or something else. Sometimes it works, even if the characters are not located next to each other or when you are mistaken in writing. Fuzzy search is so useful that in modern text editors has become a standard feature.
For years, the lord of fuzzy search was Ctrl-P , but the new FZF tool turned out to be faster and unpretentious when searching for one file or tag among thousands of others. Ctrl-P worked fine in my codebase of 30,000 files on the 2013 MacBook Pro, but began to slow down when searching through a huge tagged file, and so much so that they simply could not be used. And the speed of FZF does not change at all - it searches for files and tags equally quickly.
Getting started with FZF is easy. Just follow the installation instructions ( brew install FZF
on macOS using Homebrew ) and install the additional plugin FZF.vim to get hellishly fast functionality.
FZF is accompanied by a basic Vim plugin, but its functionality is minimal, so FZF.vim is designed to provide all the features you need. The most useful commands are :Buffers
:Files
and :Tags
, I tied them to ;
,t
and ,r
respectively:
nmap ; :Buffers<CR> nmap <Leader>t :Files<CR> nmap <Leader>r :Tags<CR>
The binding is important to me ;
because I live buffers. I practically do not use tabs - we'll talk about this below - that's why it is important for me that I can switch to what I think about with minimal effort.
Make sure FZF applies ag
, a grep/ack
replacement called Silver Searcher . ag will respect your .gitignore
and .agignore
, so there is no longer any need to store the huge wildignore
string in your vimrc
.
FZF can also work in a shell, it comes with bindings for Zsh, Bash and Fish. In Zsh, I can press Ctrl-t
to instantly start a fuzzy search for any file in the current directory. And since I configured FZF to use ag, it ignores everything that is excluded in .gitignore
. It is wonderful.
Here is a piece of code from my .zshrc . When FZF is called from Vim, FZF environment variables are also used:
# FZF via Homebrew if [ -e /usr/local/opt/FZF/shell/completion.zsh ]; then source /usr/local/opt/FZF/shell/key-bindings.zsh source /usr/local/opt/FZF/shell/completion.zsh fi # FZF via local installation if [ -e ~/.FZF ]; then _append_to_path ~/.FZF/bin source ~/.FZF/shell/key-bindings.zsh source ~/.FZF/shell/completion.zsh fi # FZF + ag configuration if _has FZF && _has ag; then export FZF_DEFAULT_COMMAND='ag --nocolor -g ""' export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" export FZF_ALT_C_COMMAND="$FZF_DEFAULT_COMMAND" export FZF_DEFAULT_OPTS=' --color fg:242,bg:236,hl:65,fg+:15,bg+:239,hl+:108 --color info:108,prompt:109,spinner:108,pointer:168,marker:168 ' fi
I was going to write about one big flaw in FZF: this is an external command that does not work with MacVim. But now everything has changed! Support was added recently with the help of new native terminals in Vim 8 . It works well, but much slower than the terminal in a large code base (~ 1 million files).
Although FZF, Ctrl-P and other editors support fuzzy searches in paths and file names, I hope that someone will create a search for first characters for Vim. For example, in IntelliJ, if you want to open the class FooFactoryGeneratorBean
, then press Cmd-o
and write FFGBEnter
(the first characters of each part of the class name). This is very convenient for finding tags, because class names are often written in the Camel register, regardless of programming language. You can, for example, treat characters before the underscore as first characters, so that fbbq
will match a file like foo_bar_baz_quux.js
.
Ag
is the new ack
, which was a new grep
. At first glance, the best way to use ag
from Vim is ack.vim , but this is a misconception because ag.vim is outdated , but ack.vim supports both ack
and ag
.
ack.vim provides the command :Ack
, which takes arguments in the same way as ag is executed from the command line, except that it opens the QuickFix window with a list of search results:
Note that :Ack
defaults to the first result in the QuickFix list. If you don't like it, use :Ack!
, or swap the functionality of two commands in a particular document .
(You may be confused by the fact that FZF.vim
adds the command :Ag
, which interactively uses FZF to search using ag. I tied it to the sample for ,a
. I didn’t notice any special sense, but it’s cool.)
When the results appear in the QuickFix window, the easiest way to use them is to move the cursor and press Enter to open the result. Also to navigate through the list there are commands :cnext
and :cprev
, and I tried to find suitable cross-platform shortcut keys, but did not find it. Then I discovered vim-unimpaired , adding useful binding like [q
and ]q
for :cprev
and :cnext
. In fact, vim-unimpaired has much more bindings for forward / backward pairs — navigating through compiler / linter errors and including popular options like line numbers, which I think should be built into Vim.
Using the QuickFix window for search results is so convenient that I wrote a few bindings to search for the current word under the cursor. As exhuberant-ctags
tries to search for tags in Ruby and CoffeeScript, sometimes you just need to search for the word you are looking at:
nmap <Mk> :Ack! "\b<cword>\b" <CR> nmap <Esc>k :Ack! "\b<cword>\b" <CR> nmap <MSk> :Ggrep! "\b<cword>\b" <CR> nmap <Esc>K :Ggrep! "\b<cword>\b" <CR>
Finally, after searching and navigating, I usually press \x
(tied to :cclose
) to close the QuickFix window. Probably, I will need to return to the file that I looked at before starting the search, so I usually repeat Ctrl-o
several times, thereby jumping back through the list of transitions , as if pressing the Back button in the browser. At other times I use; to raise the list from the buffer and search for the original file there. But now, when I thought about it, maybe I’ll change the global mark in my Meta-k
binding to 'O
, so 'O
will always take me back to where I started.
I once mentioned that I rarely use gvim / MacVim. I prefer the terminal, but there are a number of good reasons for choosing a separate Vim application:
Besides being close to the command line, another important reason to use Vim in a terminal is tmux . It is popular for remote development, but is also convenient for local development. Today tmux is present in my daily full-screen working environment, and Vim usually occupies one of the tmux panels. This allows me to use Vim while keeping several shells open — usually a server and one or two utility panels. Sometimes I temporarily open Vim full screen with a keyboard shortcut .
Killer feature tmux - the ability to send keystrokes in the panels from anywhere. I use tmux and Vim as an IDE: I can edit in one panel, execute commands in another, while keeping the server log in front of my eyes in case of errors. For example, if I work with a REST endpoint, I can retest it with curl
and view the output with jq by pressing just a few keys:
I usually make changes to Vim, to save, press :wEnter
, then use <prefix>h
go to the left panel (where <prefix>
is the prefix-combination of tmux keys, usually Ctrl-a
), then UpEnter
to repeat the command, and finally <prefix>l
to return to Vim. But it will be much faster to build a Binding for this in Vim:
nmap \r :!tmux send-keys -t 0:0.1 Cp Cj <CR><CR>
The tmux send-keys
command is launched, which orders you to send keystrokes of the session, window, and panel 0:0.1
, where I had previously run curl
. Then Ctrl-p
sent there, which is similar to pressing Up
, as a result of which the last command is extracted from the history, and after Enter
for execution. I tied it to \r
like run or repeat. Learn more about send-keys
here and here .
This approach helped me six months and greatly increased my productivity. But I must say that now Vim 8 supports native terminals inside the editor , and after some use, they seemed to me very sensible. Prior to this, various plugins tried to integrate terminals into Vim with mediocre results. New native terminals work fast, are Unicode sensitive, support 256 colors, and use the new term_sendkeys()
function, which allows you to send keystrokes using tmux for example. It appeared in Vim just a few months ago, so I still need to experiment. Who knows, maybe, instead of tmux, I will choose split MacVim in combination with :terminal
.
How many can remember, instead of the standard Terminal.app MacOC terminal, I chose iTerm2 . And recently I noticed that when typing in Vim inside iTerm2, I feel slowness, especially inside tmux. For comparison, I tried to use urxvt
inside XQuartz, and everything worked with lightning speed. Something added a noticeable delay, but I was not going to make urxvt
my main terminal on macOS due to buffer problems, switching and the lack of support for high DPI values ​​in XQuartz.
A few days later, I read an article that said there was a delay in input between terminals on macOS and claimed that Terminal.app is now much faster than iTerm2. I tried it myself and found that the delay after pressing the keys was somewhere between urxvt and iTerm2, so I completely switched to Terminal.app. I turned on a fancy color scheme and was happy to find a project that converted all the themes under Terminal.app.
I miss only vertical splits in iTerm2 and the simplicity of using fonts of different sizes in different panels. In iTerm2 (more precisely, in any editor in which the editing zone is not a single grid with a fixed-size cell) this is easier to do. But I can live without it.
The ability to write without distracting is important. There are some nice looking native and browser applications for this, but I wanted to work with Vim, so I came up with a solution.
Beautiful goyo.vim plugin adds a lot of functions to the buffer and hides all unnecessary. He recognizes the status bar of Airline / Powerline / Lightline and also hides them, well, for the most part . This is plus a few other tricks in the setting I call the prose mode :
function! ProseMode() call goyo#execute(0, []) set spell noci nosi noai nolist noshowmode noshowcmd set complete+=s set bg=light if !has('gui_running') let g:solarized_termcolors=256 endif colors solarized endfunction command! ProseMode call ProseMode() nmap \p :ProseMode<CR>
I tied this command to \p
. It includes Goyo and gets rid of all sorts of funny things useful when writing code, such as indents when entering brackets. Also, the plugin changes the color scheme from my usual dark to a light version of Solarized. This is important because it visually reminds me that I am in the "writing mode" and that it is impossible to be distracted: you need to create text.
The command also forces the auto-complete function to pull words out of the dictionary when I press Tab in the hope that I can write faster. This feature is still in development, but it can be useful from time to time.
One of the best and most essential additions to Vim has become the management of asynchronous processes . Now, when Vim can execute processes in the background, a good new ALE plugin intrudes into the possession of Syntastic , asynchronously executing linters. No more waiting for your linter to do the work each time the file is written. I wrote a lot of Ruby-code in Jruby, and there it was necessary to wait for a long time while the linter did everything, so I turned off Syntastic. But thanks to ALE, I can now include lint when writing code.
I worked with Powerline for the last few years and eventually transformed it into a more lightweight Airline . But the information and widgets in the status lines are more distracting than useful. I do not need to know the current file encoding or syntax type. In addition, I am not pleased with his fonts . I switched to Lightline and put some effort into minimizing it and adding linter status icons:
I do not see the need to display the name of the current Git branch in the status bar, especially in the terminal to which you can switch at the touch of a button. Also, I don’t like the idea of ​​putting a Git branch in shell status, because it looks messy if you switch branches from another shell. But here I’m definitely in the minority, maybe I’m missing something.
If you are using Git, several plugins will be important to you.
vim-gitgutter shows markers for any lines that have been added, deleted, or changed, as most other editors do today. For changes, I made the display of a color dot (•)
instead of the symbols -
and +
by default, so it’s more understandable.
vim-fugitive is the most popular Git plugin for Vim, it has plenty of features. I have a lot of shell aliases for Git , so in Vim I rarely use anything other than :Gblame
and :Gbrowse
, but there are many other nice things you expect from the Git-tools built into the editor (if your repository is hosted on GitHub, you will need vim-rhubarb to make it work :Gbrowse
).
:Gbrowse
is a miracle - it opens the current file in the browser with an optional row selection, assuming that your repository is mirrored on GitHub, GitLab or elsewhere. Now, when used to solve problems and requests to include code, it has become even more useful to display in GitHub links to specific commits and line numbers as code fragments. It is enough to select a few lines using Shift-v
, execute :Gbrowse
, copy the opened URL and insert a comment into GitHub:
I planned to talk about RootIgnore and how it automatically configures wildignore
based on your .gitignore
. But this was not the best idea, because on the Vim command line, the auto-completion of paths by pressing Tab does not work if the path is in wildignore
. Moreover, the expand()
built-in function returns null if the path that you ask it to expand is on the ignored list. I did not immediately figure out that because of this, my prescribed .gitignore
and host- .vimlocal
file .vimlocal
not be provided to my registered .vimrc
.
I am a strong believer in the use of buffers. I tried to work with tabs, but did not find any use in them. Tabs are an additional way to hide information, and in order to navigate to them, you need to memorize additional keyboard shortcuts or commands. If you have tmux, it is easier to open it in another Vim panel. And if you are good at using buffers, you can easily get the file you need in a few button presses - with the help of FZF, as described above.
Buffers are easy to understand: after running Vim, any open or created file turns into a named buffer. You can view them with the command :buffers
and navigate to one of them with :buf <name>
, where <name>
is any part of the name of the buffer file. Or using the numbers that appear on the command :buffers
.
If you run Vim from the command line with several files as arguments, then each file will already be opened in a buffer. If you have installed vim-unimpaired , then for simple navigation between the buffers you can use [b
and ]b
.
I significantly accelerated this process by clicking the key ;
FZF-command :Buffers
, so that one click of the button I get a list of buffers with a fuzzy search function. For example, if I opened three vim foo.txt bar.txt quux.txt
files on the command line, then to go to quux.txt
just type ;qEnter
. (Yes, it looks like usage :buf
, but FZF shows a live preview when you have a lot of files open with similar names.)
Sometimes I accidentally create buffers, for example, when I try to open a file, I enter :e
and press Enter too quickly. The command :bd
can be used to erase the buffer and remove it from the list, but then the Vim or split window in which this buffer is open will also close. A good solution is bufkill.vim , which provides :BD
to erase the current buffer and keep the current window open. I often use it, so I tied it to Meta-w
.
If you need to rename, make chmod or delete the file, you can go to the terminal and make a change, but then the Vim buffer will no longer be synchronized and will show an annoying warning “File is no longer available”. It is better to take NERDTree and highlight the current file with :NERDTreeFind
, press m
to change and select an action like move or rename. I prefer vim-eunuch , which adds a series of commands:: :Chmod
applies chmod to the current file :Chmod
:Rename
renames the file in its parent directory :Chmod
:Move
can move the file to another location, and :Delete
deletes the file and the buffer. There are a few more commands, but I resort to these most often.
I was prompted by the vim-polyglot plugin, in which more than 100 syntax plugins are assembled into a single package. It loads them only on demand. All versions are fresh, the author chose the best plug-ins, so that indentation and highlighting work well for most popular languages.
Commenting code is an everyday task, so it makes sense to choose a plugin smart enough to comment on lines or blocks of code in different languages. You can take :s/^/#
if you write code that uses hashes to comment on lines, but I prefer the vim-commentary plugin. It allows you to comment out or uncomment the code in any language using the gc
command.
The vim-surround plugin is so useful that it can be embedded in Vim. , . , . , .
, repeat.vim . , cS'"
, .
.
Ruby , end
. endwise . HTML XML, closetag.vim , </
.
, , . sleuth.vim , . 90 % .
Vim VimL, ( indispensable types ). VimAwesome .
Vim . : , , . WordPress. , , Mac OS Classic. .
Vim . Y «vim X with Y», . , (binary-search) , . , , .
— Vim. Vim, , , , , . , EasyMotion vim-sneak , , Vim. Vim , , Vim, . .
, Vim Ruby, Python, - , , . Vim 7 , VimL . vim-pathogen , runtime- Vim ~/.vim/bundle/
, , git clone
.
: , Vim, . , , Vim . , .
. Atom Microsoft Visual Studio Code , . Sublime Text . IntelliJ IDEA Community Edition. Vim , .
- , . Sublime Text. , , macOS, Windows Linux. , . - Vim .
Java, , IntelliJ IDEA. Community Edition , , , Java- Kotlin-. Maven-, Git, , , , , ctags, . Ruby, - puts
, IntelliJ . Vim, IdeaVIM .
Visual Studio Code, , TypeScript, Microsoft . . . , Vim- YouCompleteMe , C C++, TypeScript.
NeoVim , . , Vim.
, . Vim , . VimAwesome.com - . - « ».
Source: https://habr.com/ru/post/340740/
All Articles