Autocommands
- Autocommands are a way to tell Vim to run certain commands whenever certain event happen
:autocmd BufNewFile * :write
- With this command, vim will automatically create thefile
Autocommand Structure
:autocmd BufNewFile * :write
^ ^ ^
| | |
| | The command to run.
| |
| A "pattern" to filter the event.
|
The "event" to watch for.
- Event
Vim offers many events like
- Starting to edit a file that doens't exist
- Reading a file
- Switching a buffer's
filetype
setting - Not pressing a key for a certain amount of time
- Entering insert mode
- Exiting insert mode
- Pattern
:autocmd BufNewFile *.txt :write
- Vim writes only
bar.txt
automatically, but doesn't writebar
Another Example
:autocmd BufWritePre *.html :normal gg=G
- Then create a new file called
foo.html
and enter following text exactly including whitespace
<html>
<body>
<p>Hello!</p>
</body>
</html>
- When save this file with
:w
, Vim seems to have reindented the file before saving it! BufWritePre
means the event will be checked just before you write any file
Multiple Events
example
:autocmd BufWritePre,BufRead *.html :normal gg=G
- A common idiom in Vim scripting is
BufRead
andBufNewFile
.
:autocmd BufNeewFile,BufRead *.html setlocal nowrap
FileType Events
- One of the most useful events:
FileType
event. - This event is fierd whenever Vim set a buffer`s
FileType
:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc>
:autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
Exercises
- Skim
:help autocmd-events
Buffer-Local Abbreviations
- Open
foo
andbar
files, switch tofoo
and run following commands
:iabbrev <buffer> --- —
Then write following texts
Hello --- world.
- Vim will replace
---
only infoo
file.
Autocommands and Abbreviations
:autocmd FileType python :iabbrev <buffer> iff if:<left>
Autocommand Group
:autocmd BufWrite * :echom "Writing Buffer!"
Now write the buffer (
:w
) and run:message
, you can see theWriting Buffer!
messageAnd run the exact same autocommand again:
:autocmd BufWrite * :echom "Writing Buffer!"
After
:message
again, you can seeWriting Buffer!
twice increased.Vim has no way to know if you want it to replace or create.
The problem
- Sourcing your
~/.vimrc
file rereads the entire file: every time source your~/.vimrc
you'll be duplicating autocommand - Will make vim run slower
Grouping Autocommands
- Vim has a solution to the problem: group related autocommands
:augroup testgroup
: autocmd BufWrite * :echom "Foo"
: autocmd BufWrite * :echom "Bar"
:augroup END
The indentation is insignificant
- after
:w
and see:message
, you can see"Foo"
and"Bar"
.
:augroup testgroup
: autocmd BufWrite * :echom "Baz"
:augroup END
Clearing Groups
- If you want to clear a group, you can use
autocmd!
inside the group
:augroup testgroup
: autocmd!
: autocmd BufWrite * :echom "Cats"
:augroup END
Using Autocommands in your Vimrc
- Can use this to add autocmd to
~/.vimrc
that don't add a duplicate every time we source it.
augroup filetype_html
autocmd!
autocmd FileType html nnoremap <buffer> <localleader>f Vatzf
augroup END
Excersize
- Try to figure out what the mapping in the last example does. (
Vatzf
)V
: visual mode for the lineat
: a<tag></tag>
blockzf
: fold
Operator-Pending Mappings
- An operator is a command that waits for you to enter a movement command like
d
,c
,y
below.
Keys Operator Movement
---- -------- -------------
dw Delete to next word
ci( Change inside parens
yt, Yank until comma
Movement mapping
You can create new movements.
- Example
Let's make a example movement for inner parentheses (()
)
:onoremap p i(
And with the line below, and put the cursor in cat
and type dp
.
return person.get_pets(type="cat", fluffy_only=True)
The whole text inside the parentheses are deleted.
You can use p
with other operators as well like cp
or yp
.
- Other example
:onoremap b /return<cr>
And write text below
def count(i):
i += 1
print i
return foo
Move the cursor to i
in the second line, and type db
. Vim automatically remove all the body until the return
.
Changing the start
For the last example with dp
, you have to move the cursor to inside the parentheses. Let's make for the operator that can used in whole line.
:onoremap in( :<c-u>normal! f(vi(<cr>
Also, write or copy the text that we used before.
return person.get_pets(type="cat", fluffy_only=True)
Move the cursor whereever you want in the line - like p
in person. When type cin(
, you can see whole text inside parentheses was deleted.
You can think of this mapping as meaning "inside next parentheses", and it will perform the operator on the text inside the next set of parentheses on the current line.
Let's make inside last parentheses
too.
:onoremap il( :<c-u>normal! F)vi(<cr>
Now, you can use the motion il(
for find the last parentheses backwards.
Exercises
- Create operator-pending mappings for "around next parentheses" and "around last parentheses".
:onoremap an( :<c-u>normal! f(va)<cr>
:onoremap al( :<c-u>normal! F)va(<cr>
- Create similar mappings for in/around next/last for curly brackets.
# in next curly brackets
:onoremap in{ :<c-u>normal! f{vi}<cr>
# around next curly brackets
:onoremap an{ :<c-u>normal! f{va}<cr>
# in last curly brackets
:onoremap il{ :<c-u>normal! F}vi{<cr>
# around last curly brackets
:onoremap al{ :<c-u>normal! F}va{<cr>
- Read :help omap-info and see if you can puzzle out what the
in the examples is for.
The CTRL-U (
) is used to remove the range that Vim may insert
# example for find the next function name in the current line
:onoremap <silent> F :<c-u>normal! 0f(hviw<c-r>