Readit News logoReadit News
aequitas · 8 years ago
If you forgot to sudo vi, you've already edited the file, saving the file as root without first saving it as your own and then having to move it:

<ESC>:w !sudo tee %

Pipes the content of the file to a tee process as root and lets tee save it under the current file name. Vim will tell you the file has changed on disk and ask if it should reload it afterwards.

dllthomas · 8 years ago
> If you forgot to sudo vi

IMO, it's better not to do that in the first place (which, of course, only makes your tip all the more useful!)

mugurel_chirica · 8 years ago
Make sure you are 100% confident that you know the proper syntax for this when you use it. I once blanked by mistake an important file, lucky for me I had a backup.
thedjinn · 8 years ago
Not really a trick of Vim itself, but when using Vim from the terminal I find ctrl-z very useful to background Vim, type in a few shell commands for git or whatever and then use "fg" to hop back into Vim.
hiyer · 8 years ago
vim 8 and neovim have pretty functional in-built terminals (:term). You can try that if you're using one of these.
thedjinn · 8 years ago
That's more keystrokes. ;)
vram22 · 8 years ago
Only a few more keystrokes is:

:sh ENTER

or for more control over which shell, or to run a shell with any arguments, or even to run any command w/ or w/o args:

:!bash

:!bash -o vi

:!bash some_script.sh

:!some_command some args

and after any of those, just press Ctrl-D or type exit ENTER to return to the vim session.

Very fast and easy to do. I use it all the time.

Xophmeister · 8 years ago
Many of the things here, as of writing, are quite elementary Vim tips. A lesser known trick that I learnt quite recently and have found very useful is `gn`, which visually selects the next search hit (similarly `gN` for the previous hit). That's not so useful in itself, but it can be combined with an operation, such as `c` or `y`, etc., which can then be repeated using the `.`.
k4ch0w · 8 years ago
Macros, Macros, Macros. These are a game changer when editing large files. Use the `q` key and followed by any letter you like, I default to `a`. Perform some action, like deleting a line, appending to the start of a line, or searching for a word then deleting it. Press `esc`, then type in the number of times you want to repeat the action, followed by `@` and the letter you chose. I.E `10@a` and it will perform that action 10 times.
Pete_D · 8 years ago
Also fun: macros can call themselves. So if you want to repeat something across a whole file, it's sometimes easiest to write an infinitely recursive macro and let it error when it bumps up against the bottom of the file.
MaxBarraclough · 8 years ago
Vim can be great for quickly doing tedious text transformations. Far easier to get right than doing it the 'proper way' with a script in Python/Perl/whatever.

To do something like scan through a JSON or XML document and split a 'name' field/tag into 'firstName'/'lastName', Vim is the tool I'd reach for.

I think of it as 'cursor-oriented programming', but what I do with it isn't really programming, it's generally of the pattern of 1. Find start of pattern 2. Transform pattern 3. GOTO 1

Or at worst, the decorate/sort/undecorate pattern.

But it boils down to repeatedly applying a macro.

Xophmeister · 8 years ago
A useful thing to know when using macros is that the letter you press after `q` is just the register in which Vim stores the macro. Registers are also used when copying and pasting. As such, if you want to edit a macro, you can just paste it into a new buffer (e.g., `"ap` for register `a`), edit it as you wish, then copy it back into that register (`:%y a`). You can even use this method to write macros from scratch, rather than recording them first.
robotvert · 8 years ago
`Ctrl + v` to visually select one character at a time (instead of say `Shift + v` that selects a whole line) and then use the movement keys to select a block of characters horizontally as well as vertically. Imagine several well indented HTML <li class="something"> elements, you could for instance delete/modify all the class attributes on all lines visually in one go (to insert text use `Shift + i`, type, then Esc).
wawhal · 8 years ago
I think I don’t quite get you. Doesn’t “v” do the same thing?
majewsky · 8 years ago
What robotvert means is rectangular selection across multiple lines. For example, suppose you have the following text:

  <li class="wrong">first</li>
  <li class="wrong">second</li>
  <li class="wrong">third</li>
You want to change all the instances of "wrong" to "right". So you put the cursor on the first "w", then `Ctrl-V` to enter blockwise visual mode, then `e2j` to select the "wrong" words, then `c` to remove all of them and enter insert mode to type a replacement. The replacement text is then applied to each line separately. Full series of keystrokes (starting with the cursor on the "w" in the first line) if you want to follow along:

  <Ctrl-V>e2jcright<ESC>

vikin9 · 8 years ago
:norm(al) command Allows you to do some of the vim magic also on remote systems where you don't have all your plugins.

Example:

(1) Select block with `C-v`

(2) Hit colon `:`

(3) Write norm and enter any sequence as you would be in normal mode: `norm I# ` (prepend selection with a comment sign)

(4) Admire the result.

Brometheus · 8 years ago
yes, awesome!!!
valbaca · 8 years ago
Quick renaming of variables: what to type"explanation

    gd" go to definition of variable
    :%s/" beginning of a replace...
    Ctrl-r /" inserts the last word searched into the command, so what "gd" found
    /newname/gc" finish the replace command, g=global replace, c=confirm each replace
Save a character going to a line: instead of using :42<enter> to go to line 42, can use 42G

Auto-indent: =

Go to last file: Ctrl-^

Abbreviations: put this in your ~/.vimrc

    iab cmain int main() {
    \<CR>    return 0;
    \<CR>}
Insert the contents of a file: :r <filename>

I like to have a ~/gitmessage.txt which has a template I like, then when I do git commit all I have to do is:

    :r ~/gitmessage.txt
Vim + Ctags:

Ctags link usages and definitions so you can navigate through code like in an IDE without the bloat of an IDE. Works best with C, but works pretty well with any language with C-like syntax (and more).

Goto tag (definition) of what's under cursor: Ctrl-]

Go back: Ctrl-t

Open tag in a preview: Ctrl-w

:tag <tag> " go to tag, like:

    :tag someFunction
    :tag SOME_CONSTANT

wyoung2 · 8 years ago
> Insert the contents of a file: :r <filename>

The file name can be a pipe instead.

Let’s say you have a Makefile based project and the dependencies aren’t as complete as they ought to be. With your cursor on this line in the Makefile:

    SOURCES = \
You can say

    :r !ls src/*.c
That will put the complete list of extant C source files into the file at that position, complete with the “src/“ path prefix. Then to format the list properly for “make” syntax, use Shift-V to select the list, hit the right angle bracket (“>”) once to indent it a level, then say:

     :s/$/ \/
This trick of replacing the start (“^”) or end (“$”) of a line is very often helpful. Here I’ve used it to ask Vim to put a space and backslash after every line to allow the SOURCES variable definition to continue from one line to the next.

(This will look like “:’<,’>s...” in your editor, with the bit between the colon and s being inserted by Vim; it means “front the start of the selection to the end.”)

Remove the final backslash and it’s done.

The advantage of working this way is that you aren’t manually transcribing things the computer already knows and can report on command.

The possibilities here are vast. For instance, if your C source files are buried under subdirectories of `src`, say this instead:

    :r !find src -name \*.c

lgeorget · 8 years ago
`Shift+v` to select a block of text and do a single operation to the same portion of text on several lines (regexp, aligning, etc.)

There's also `vt` + some character to select text from the cursor to the next occurrence of that character.

_31 · 8 years ago
I've been looking for something like `Shift+v`! Thanks for that. +1 for `vt` as well.
amaterasu · 8 years ago
Also ctrl-v allows you to manipulate a block of text, or insert text on multiple lines at once using I or A for before or after the block.