DEV Community

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

Discussion (19)

pic
Editor guide
Collapse
bradenbest profile image
Braden Best • Edited

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.

Collapse
tux0r profile image
tux0r

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?

Collapse
jovica profile image
jovica Author

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!

Collapse
michaelmior profile image
Michael Mior

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.

Collapse
supahambition profile image
Supahambition

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?

Collapse
jdnewman85 profile image
jdnewman85

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...

Collapse
italovieira profile image
Ítalo Vieira • Edited

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

Collapse
vinneycavallo profile image
vinney cavallo

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.

Collapse
samyi profile image
Sam Yi

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

Collapse
jovica profile image
jovica Author

Haha, thanks :)

Collapse
gerardbm profile image
Gerard • Edited

I use this map:

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

However, I prefer to edit files with this alias:

alias svim='sudoedit'
Collapse
atomicwrites profile image
David Castro

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.

Collapse
ploppy1337 profile image
ploppy

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

Collapse
gcorrel profile image
gcorrel

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

Collapse
kevcui profile image
Kevin Cui

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

Collapse
necauqua profile image
Anton Bulakh

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

Collapse
cebtenzzre profile image
Cebtenzzre

Will this work for paths with spaces?

Collapse
jerpint profile image
jerpint

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

Collapse
vinneycavallo profile image
vinney cavallo

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