loading...

The Vim Trick Which Will Save Your Time and Nerves

jovica profile image jovica ・2 min read

Whether you're beginner or advanced Vim user, I'm sure you've seen this at least once:

E45: 'readonly' option is set (add ! to override)

It usually goes like this:

You open a file with Vim and make some changes. When you try to save the file and see the message above.

Then you realize that you didn’t run Vim with sudo?! Argh, so annoying isn't it?

Today, you're gonna learn how to solve this easily, and once for all.

It's very simple, all you need to do is to add this line to your .vimrc:

cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!

When you get to the same situation again and you can't save your file, simply run :w!! command, and your changes will be saved!

Now, how this works:

  • cnoremap - tells Vim that the following mappings that is used when in command-line mode
  • w!! - the mapping (shortcut) itself.
  • execute '<command>' - executes a command between the quotes
  • silent! - run it silently
  • write !sudo tee % >/dev/null - the magic trick which would take another post to explain
  • <bar> edit! - this calls the edit command to reload the buffer and then avoid messages such as "the buffer has changed".

Hint: you need to type :w!! fast, so it expands into the full command. Typing these four strings slowly and hitting Enter won't work.


I share tips like this at Mastering Vim Quickly Newsletter.

I also wrote a book Mastering Vim Quickly: From WTF to OMG in no time

You can also get the best Vim tips by following @MasteringVim

Posted on by:

jovica profile

jovica

@jovica

#infosec #sysadmin #gentoo #vim

Discussion

markdown guide
 

I just use :w !sudo tee % when that happens. I don't come across that situation enough to justify a mapping, and the command is easy to reinvent when needed.

w <file> writes to a file, and can be redirected to an external program's stdin if file is !<command>

sudo tee <file> takes its input and writes it to both stdout and file.

% is vim shorthand for the file open in this buffer.

Btw: sudo -e some_file. Try it.

 

the magic trick which would take another post to explain

Here's a comment to save you another post:

  • ! executes a command and returns its result. This was adopted from Vim's predecessors, it already exists in ed (which begat em which begat en which begat ex which begat vi which was cloned as stevie which begat Vim, eventually).
  • tee splits the input (here: the contents of the buffer which is % in Vim's language) into an output file (redirected into the void, >/dev/null) and an output stream (returned).
  • write is the equivalent to :w.

Wouldn't /dev/zero be faster, by the way?

 

hah - thanks :) It's just hardly understandable for beginners in this kind of short form - that's what I had in mind when I mentioned another post.

I didn't test the difference between the /dev/zero and /dev/null, but it shouldn't make a really big difference in this case. Cheers!

 

At least on my machine, /dev/zero and /dev/null are the same speed. Even if they were different, I doubt it would be enough to matter unless you were writing a really massive file.

 

Or use the chmod command to change the permissions of the file right?
Idk about you guys but I'm not particularly comfortable with running vim through Super User all the time. But maybe that's just being paranoid?

 

This 'trick' alleviates the need to run vim itself as root. Changing permissions is not always preferable. How do you edit system configs? Full blown root user?

Your paranoia has caused you to be less safe...

 

sudoedit (or sudo -e) is the right way to do when you have not yet open the file with Vim.

 

Sometimes you want the permissions staying the same, but you need the file changed regardless. Maybe this is bad practice, I dunno. Would be curious to hear it discussed by folks who know more than I do.

 

Man though crowd. I like this shortcut. Thanks for posting.

 
 

I use this map:

cnoremap WW w !sudo tee > /dev/null %

However, I prefer to edit files with this alias:

alias svim='sudoedit'
 

Just a warning for anyone that uses this, sudoedit or sudo -e makes a temporary copy of the file and then moves it on top of the real file when the editor exits. Which means that writing your changes doesn't actually modify the file, which caused me much head banging because no matter what I did I'd get the same error since I was making changes that were buffered in sudoedit until I closed my editor, but I was retrying after just writing the change.

 

Oh wow that‘s stupid... not very usefull.

 

Well, I decided to follow you here just so, I can learn more from you. I'm a Software Developer by the way.

 

Nice trick! Unfortunately, at this moment it's not working in Neovim. I have to use a plugin instead github.com/lambdalisue/suda.vim

 

I've maid a :W command, instead of this ugly expansion with cnoremap
And a :WQ too)

 

Will this work for paths with spaces?

 

How does it work practically? When am I prompted for a password?

 

If you’re attempting to edit a file for which your user on the system doesn’t have write access, say.