Remember my article on The Busy Beaver Problem? Well, someone built a real Turing Machine and decided to run the busy beaver with 4 states on it. Here is the video.

The Turing Machine in this video runs for 107 steps and halts with the total of 13 ones, as expected.

In my article on The Busy Beaver Problem, I also wrote a program that visualizes the tape changes. If you follow the video closely, you'll see that they match the visualization (black square stands for 1, white for 0).

Tape changes for 4 state busy beaver.

See A Turing Machine website for more videos and information about how this machine was actually built. Also see my article on Busy Beaver for a Turing Machine implementation in Python and C++.

This article is part of the article series "CommandLineFu One-Liners Explained."
<- previous article next article ->

CommandLineFu ExplainedHere are the next ten top one-liners from the commandlinefu website. The first post about the topic became massively popular and received over 100,000 views in the first two days.

Before I dive into the next ten one-liners, I want to take the chance and promote the other three article series on one-liners that I have written:

Update: Russian translation now available.

Alright, so here are today's one-liners:

#11. Edit the command you typed in your favorite editor

$ command <CTRL-x CTRL-e>

This one-liner opens the so-far typed command in your favorite text editor for further editing. This is handy if you are typing a lengthier shell command. After you have done editing the command, quit from your editor successfully to execute it. To cancel execution, just erase it. If you quit unsuccessfully, the command you had typed before diving into the editor will be executed.

Actually, I have to educate you, it's not a feature of the shell per se but a feature of the readline library that most shells use for command line processing. This particular binding CTRL-x CTRL-e only works in readline emacs editing mode. The other mode is readline vi editing mode, in which the same can be accomplished by pressing ESC and then v.

The emacs editing mode is the default in all the shells that use the readline library. The usual command to change between the modes is set -o vi to change to vi editing mode and set -o emacs to change back to emacs editing mode.

To change the editor, export the $EDITOR shell variable to your preference. For example, to set the default editor to pico, type export EDITOR=pico.

Another way to edit commands in a text editor is to use fc shell builtin (at least bash has this builtin). The fc command opens the previous edited command in your favorite text editor. It's easy to remember the fc command because it stands for "fix command."

Remember the ^foo^bar^ command from the first top ten one-liners? You can emulate this behavior by typing fc -s foo=bar. It will replace foo with bar in the previous command and execute it.

#12. Empty a file or create a new file

$ > file.txt

This one-liner either wipes the file called file.txt empty or creates a new file called file.txt.

The shell first checks if the file file.txt exists. If it does, the shell opens it and wipes it clean. If it doesn't exist, the shell creates the file and opens it. Next the shell proceeds to redirecting standard output to the opened file descriptor. Since there is nothing on the standard output, the command succeeds, closes the file descriptor, leaving the file empty.

Creating a new empty file is also called touching and can be done by $ touch file.txt command. The touch command can also be used for changing timestamps of the commands. Touch, however, won't wipe the file clean, it will only change the access and modification timestamps to the current time.

#13. Create a tunnel from localhost:2001 to somemachine:80

$ ssh -N -L2001:localhost:80 somemachine

This one-liner creates a tunnel from your computer's port 2001 to somemachine's port 80. Each time you connect to port 2001 on your machine, your connection gets tunneled to somemachine:80.

The -L option can be summarized as -L port:host:hostport. Whenever a connection is made to localhost:port, the connection is forwarded over the secure channel, and a connection is made to host:hostport from the remote machine.

The -N option makes sure you don't run shell as you connect to somemachine.

To make things more concrete, here is another example:

$ ssh -f -N somemachine

This one-liner creates a tunnel from your computer's port 2001 to via somemachine. Each time you connect to localhost:2001, ssh tunnels your request via somemachine, where it tries to open a connection to

Notice the additional -f flag - it makes ssh daemonize (go into background) so it didn't consume a terminal.

#14. Reset terminal

$ reset

This command resets the terminal. You know, when you have accidentally output binary data to the console, it becomes messed up. The reset command usually cleans it up. It does that by sending a bunch of special byte sequences to the terminal. The terminal interprets them as special commands and executes them.

Here is what BusyBox's reset command does:


It sends a bunch of escape codes and a bunch of CSI commands. Here is what they mean:

  • \033c: "ESC c" - sends reset to the terminal.
  • \033(K: "ESC ( K" - reloads the screen output mapping table.
  • \033[J: "ESC [ J" - erases display.
  • \033[0m: "ESC [ 0 m" - resets all display attributes to their defaults.
  • \033[?25h: "ESC [ ? 25 h" - makes cursor visible.

#15. Tweet from the shell

$ curl -u user:pass -d status='Tweeting from the shell'

This one-liner tweets your message from the terminal. It uses the curl program to HTTP POST your tweet via Twitter's API.

The -u user:pass argument sets the login and password to use for authentication. If you don't wish your password to be saved in the shell history, omit the :pass part and curl will prompt you for the password as it tries to authenticate. Oh, and while we are at shell history, another way to omit password from being saved in the history is to start the command with a space! For example, <space>curl ... won't save the curl command to the shell history.

The -d status='...' instructs curl to use the HTTP POST method for the request and send status=... as POST data.

Finally, is the API URL to POST the data to.

Talking about Twitter, I'd love if you followed me on Twitter! :)

#16. Execute a command at midnight

$ echo cmd | at midnight

This one-liner sends the shell command cmd to the at-daemon (atd) for execution at midnight.

The at command is light on the execution-time argument, you may write things like 4pm tomorrow to execute it at 4pm tomorrow, 9pm next year to run it on the same date at 9pm the next year, 6pm + 10 days to run it at 6pm after 10 days, or now +1minute to run it after a minute.

Use atq command to list all the jobs that are scheduled for execution and atrm to remove a job from the queue.

Compared to the universally known cron, at is suitable for one-time jobs. For example, you'd use cron to execute a job every day at midnight but you would use at to execute a job only today at midnight.

Also be aware that if the load is greater than some number (for one processor systems the default is 0.8), then atd will not execute the command! That can be fixed by specifying a greater max load to atd via -l argument.

#17. Output your microphone to other computer's speaker

$ dd if=/dev/dsp | ssh username@host dd of=/dev/dsp

The default sound device on Linux is /dev/dsp. It can be both written to and read from. If it's read from then the audio subsystem will read the data from the microphone. If it's written to, it will send audio to your speaker.

This one-liner reads audio from your microphone via the dd if=/dev/dsp command (if stands for input file) and pipes it as standard input to ssh. Ssh, in turn, opens a connection to a computer at host and runs the dd of=/dev/dsp (of stands for output file) on it. Dd of=/dev/dsp receives the standard input that ssh received from dd if=/dev/dsp. The result is that your microphone gets output on host computer's speaker.

Want to scare your colleague? Dump /dev/urandom to his speaker by dd if=/dev/urandom.

#18. Create and mount a temporary RAM partition

# mount -t tmpfs -o size=1024m tmpfs /mnt 

This command creates a temporary RAM filesystem of 1GB (1024m) and mounts it at /mnt. The -t flag to mount specifies the filesystem type and the -o size=1024m passes the size sets the filesystem size.

If it doesn't work, make sure your kernel was compiled to support the tmpfs. If tmpfs was compiled as a module, make sure to load it via modprobe tmpfs. If it still doesn't work, you'll have to recompile your kernel.

To unmount the ram disk, use the umount /mnt command (as root). But remember that mounting at /mnt is not the best practice. Better mount your drive to /mnt/tmpfs or a similar path.

If you wish your filesystem to grow dynamically, use ramfs filesystem type instead of tmpfs. Another note: tmpfs may use swap, while ramfs won't.

#19. Compare a remote file with a local file

$ ssh user@host cat /path/to/remotefile | diff /path/to/localfile -

This one-liner diffs the file /path/to/localfile on local machine with a file /path/to/remotefile on host machine.

It first opens a connection via ssh to host and executes the cat /path/to/remotefile command there. The shell then takes the output and pipes it to diff /path/to/localfile - command. The second argument - to diff tells it to diff the file /path/to/localfile against standard input. That's it.

#20. Find out which programs listen on which TCP ports

# netstat -tlnp

This is an easy one. Netstat is the standard utility for listing information about Linux networking subsystem. In this particular one-liner it's called with -tlnp arguments:

  • -t causes netstat to only list information about TCP sockets.
  • -l causes netstat to only list information about listening sockets.
  • -n causes netstat not to do reverse lookups on the IPs.
  • -p causes netstat to print the PID and name of the program to which the socket belongs (requires root).

To find more detailed info about open sockets on your computer, use the lsof utility. See my article "A Unix Utility You Should Know About: lsof" for more information.

That's it for today.

Tune in the next time for "Another Ten One-Liners from CommandLineFu Explained". There are many more nifty commands to write about. But for now, have fun and see ya!

PS. Follow me on twitter for updates!

This article is part of the article series "CommandLineFu One-Liners Explained."
<- previous article next article ->

CommandLineFu ExplainedI love working in the shell. Mastery of shell lets you get things done in seconds, rather than minutes or hours, if you chose to write a program instead.

In this article I'd like to explain the top one-liners from the It's a user-driven website where people get to choose the best and most useful shell one-liners.

But before I do that, I want to take the opportunity and link to a few of my articles that I wrote some time ago on working efficiently in the command line:

Update: Russian translation now available.

And now the explanation of top one-liners from commandlinefu.

#1. Run the last command as root

$ sudo !!

We all know what the sudo command does - it runs the command as another user, in this case, it runs the command as superuser because no other user was specified. But what's really interesting is the bang-bang !! part of the command. It's called the event designator. An event designator references a command in shell's history. In this case the event designator references the previous command. Writing !! is the same as writing !-1. The -1 refers to the last command. You can generalize it, and write !-n to refer to the n-th previous command. To view all your previous commands, type history.

This one-liner is actually really bash-specific, as event designators are a feature of bash.

I wrote about event designators in much more detail in my article "The Definitive Guide to Bash Command Line History." The article also comes with a printable cheat sheet for working with the history.

#2. Serve the current directory at http://localhost:8000/

$ python -m SimpleHTTPServer

This one-liner starts a web server on port 8000 with the contents of current directory on all the interfaces (address, not just localhost. If you have "index.html" or "index.htm" files, it will serve those, otherwise it will list the contents of the currently working directory.

It works because python comes with a standard module called SimpleHTTPServer. The -m argument makes python to search for a module named in all the possible system locations (listed in sys.path and $PYTHONPATH shell variable). Once found, it executes it as a script. If you look at the source code of this module, you'll find that this module tests if it's run as a script if __name__ == '__main__', and if it is, it runs the test() method that makes it run a web server in the current directory.

To use a different port, specify it as the next argument:

$ python -m SimpleHTTPServer 8080

This command runs a HTTP server on all local interfaces on port 8080.

#3. Save a file you edited in vim without the needed permissions

:w !sudo tee %

This happens to me way too often. I open a system config file in vim and edit it just to find out that I don't have permissions to save it. This one-liner saves the day. Instead of writing the while to a temporary file :w /tmp/foobar and then moving the temporary file to the right destination mv /tmp/foobar /etc/service.conf, you now just type the one-liner above in vim and it will save the file.

Here is how it works, if you look at the vim documentation (by typing :he :w in vim), you'll find the reference to the command :w !{cmd} that says that vim runs {cmd} and passes it the contents of the file as standard input. In this one-liner the {cmd} part is the sudo tee % command. It runs tee % as superuser. But wait, what is %? Well, it's a read-only register in vim that contains the filename of the current file! Therefore the command that vim executes becomes tee current_filename, with the current directory being whatever the current_file is in. Now what does tee do? The tee command takes standard input and write it to a file! Rephrasing, it takes the contents of the file edited in vim, and writes it to the file (while being root)! All done!

#4. Change to the previous working directory

$ cd -

Everyone knows this, right? The dash "-" is short for "previous working directory." The previous working directory is defined by $OLDPWD shell variable. After you use the cd command, it sets the $OLDPWD environment variable, and then, if you type the short version cd -, it effectively becomes cd $OLDPWD and changes to the previous directory.

To change to a directory named "-", you have to either cd to the parent directory and then do cd ./- or do cd /full/path/to/-.

#5. Run the previous shell command but replace string "foo" with "bar"

$ ^foo^bar^

This is another event designator. This one is for quick substitution. It replaces foo with bar and repeats the last command. It's actually a shortcut for !!:s/foo/bar/. This one-liner applies the s modifier to the !! event designator. As we learned from one-liner #1, the !! event designator stands for the previous command. Now the s modifier stands for substitute (greetings to sed) and it substitutes the first word with the second word.

Note that this one-liner replaces just the first word in the previous command. To replace all words, add the g modifer (g for global):

$ !!:gs/foo/bar

This one-liner is also bash-specific, as event designators are a feature of bash.

Again, see my article "The Definitive Guide to Bash Command Line History." I explain all this stuff in great detail.

#6. Quickly backup or copy a file

$ cp filename{,.bak}

This one-liner copies the file named filename to a file named filename.bak. Here is how it works. It uses brace expansion to construct a list of arguments for the cp command. Brace expansion is a mechanism by which arbitrary strings may be generated. In this one-liner filename{,.bak} gets brace expanded to filename filename.bak and puts in place of the brace expression. The command becomes cp filename filename.bak and file gets copied.

Talking more about brace expansion, you can do all kinds of combinatorics with it. Here is a fun application:

$ echo {a,b,c}{a,b,c}{a,b,c}

It generates all the possible strings 3-letter from the set {a, b, c}:

aaa aab aac aba abb abc aca acb acc
baa bab bac bba bbb bbc bca bcb bcc
caa cab cac cba cbb cbc cca ccb ccc

And here is how to generate all the possible 2-letter strings from the set of {a, b, c}:

$ echo {a,b,c}{a,b,c}

It produces:

aa ab ac ba bb bc ca cb cc

If you liked this, you may also like my article where I defined a bunch of set operations (such as intersection, union, symmetry, powerset, etc) by using just shell commands. The article is called "Set Operations in the Unix Shell." (And since I have sets in the shell, I will soon write articles on on "Combinatorics in the Shell" and "Algebra in the Shell". Fun topics to explore. Perhaps even "Topology in the Shell" :))

#7. mtr - traceroute and ping combined

$ mtr

MTR, bettern known as "Matt's Traceroute" combines both traceroute and ping command. After each successful hop, it sends a ping request to the found machine, this way it produces output of both traceroute and ping to better understand the quality of link. If it finds out a packet took an alternative route, it displays it, and by default it keeps updating the statistics so you knew what was going on in real time.

#8. Find the last command that begins with "whatever," but avoid running it

$ !whatever:p

Another use of event designators. The !whatever designator searches the shell history for the most recently executed command that starts with whatever. But instead of executing it, it prints it. The :p modifier makes it print instead of executing.

This one-liner is bash-specific, as event designators are a feature of bash.

Once again, see my article "The Definitive Guide to Bash Command Line History." I explain all this stuff in great detail.

#9. Copy your public-key to remote-machine for public-key authentication

$ ssh-copy-id remote-machine

This one-liner copies your public-key, that you generated with ssh-keygen (either SSHv1 file or SSHv2 file to the remote-machine and places it in ~/.ssh/authorized_keys file. This ensures that the next time you try to log into that machine, public-key authentication (commonly referred to as "passwordless authentication.") will be used instead of the regular password authentication.

If you wished to do it yourself, you'd have to take the following steps:

your-machine$ scp ~/.ssh/ remote-machine:
your-machine$ ssh remote-machine
remote-machine$ cat >> ~/.ssh/authorized_keys

This one-liner saves a great deal of typing. Actually I just found out that there was a shorter way to do it:

your-machine$ ssh remote-machine 'cat >> .ssh/authorized_keys' < .ssh/

#10. Capture video of a linux desktop

$ ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq /tmp/out.mpg

A pure coincidence, I have done so much video processing with ffmpeg that I know what most of this command does without looking much in the manual.

The ffmpeg generally can be descibed as a command that takes a bunch of options and the last option is the output file. In this case the options are -f x11grab -s wxga -r 25 -i :0.0 -sameq and the output file is /tmp/out.mpg.

Here is what the options mean:

  • -f x11grab makes ffmpeg to set the input video format as x11grab. The X11 framebuffer has a specific format it presents data in and it makes ffmpeg to decode it correctly.
  • -s wxga makes ffmpeg to set the size of the video to wxga which is shortcut for 1366x768. This is a strange resolution to use, I'd just write -s 800x600.
  • -r 25 sets the framerate of the video to 25fps.
  • -i :0.0 sets the video input file to X11 display 0.0 at localhost.
  • -sameq preserves the quality of input stream. It's best to preserve the quality and post-process it later.

You can also specify ffmpeg to grab display from another x-server by changing the -i :0.0 to -i host:0.0.

If you're interested in ffmpeg, here are my other articles on ffmpeg that I wrote while ago:

PS. This article was so fun to write, that I decided to write several more parts. Tune in the next time for "The Next Top Ten One-Liners from CommandLineFu Explained" :)

Have fun. See ya!

PSS. Follow me on twitter for updates.

Sponsor this series!

Contact me, if you wish to sponsor any other of my existing posts or future posts!

This article is part of the article series "Visual Math Friday."
<- previous article next article ->

Visual Math FridayHey everyone, I'm starting a new article series here on catonmat that will be published on Fridays. It's called "Visual Math Friday." The goal of this article series is to assemble all the wonderful mathematical proofs and identities that can be proven in a single picture or drawing. I have been collecting them for years from various books, math journals, websites and video lectures and have collected several hundred of them.

If you have been following my blog, you'll have noticed that I love to explain things. I'll use the same writing style in this series as well. I'll post the visual proof together with my explanation. In the explanations I'll walk you through the proof, suggesting how to think about the visual image. But it's best if you try to understand the proof without reading my explanation and only then read it.

The proofs come from algebra, number theory, geometry, calculus, complex analysis, topology and various other fields of mathematics. I'll do one proof a week and will try to alternate between really easy, moderate and difficult proofs every week so that readers with various mathematical backgrounds can enjoy the series.

I'll start with a really easy integer sum proof this week. Without further ado, here it is.

1 + 3 + 5 + 7 + 9 + 11 + 13 + … = n²

Now try to figure what it proves without reading further! The colors play an important role in the visual proofs, as do the shape of the visual drawing, the shapes on it and their arrangement!

The Proof

This picture proves that the sum of first n odd numbers is equal to n². In other words:

1 + 3 + 5 + 7 + 9 + 11 + ... + (2n-1) = n².


Imagine that the blue and green dots are marbles. Now let's look at the lower left corner. One blue marble is located there. Next if we follow the diagonal to the upper right corner, we see that the 1 blue marble is kind-of wrapped in 3 green marbles, then they in turn are wrapped in 5 blue marbles again, then those are wrapped in 7 green ones, which in turn are wrapped in 9 blue ones, then 11 green ones, and finally 13 ones.

This suggests that we could look at the sum 1 + 3 + 5 + 7 + 9 + 11 + 13. Well what is it? It's 49. Also what does this sum involve? It involves only odd numbers. Interesting.

Now let's count how many marbles we have on each side. 7 on one side and 7 on the other. And what is 7x7? It's 49! And how many numbers did we sum together? Well, seven - 1, 3, 5, 7, 9, 11, 13. Interesting.

Could it be that the sum of the first n odd numbers is equal to n²? Or in other words, is 1 + 3 + 5 + 7 + ... + (2n-1) equal to n²?

Let's try to prove this hypothesis by going one number further and adding 15 green marbles - 13 filled marbles and 2 semi-filled marbles:

Visual Math Proof - sum of odd numbers is n squared

Adding 15 marbles created a square of marbles again - now we have 64 marbles, 8 on each side.

The 2 semi-filled marbles are very important here. Each time we go further from n odd marbles to n+1 odd marbles, the difference changes by 2. This difference of two marbles can always be put where the semi-filled ones are in this picture.

This actually concludes the proof. We showed that the proof worked for several marbles, and showed how it still works if we went one step further. Therefore it works for all future steps. This method of proof is called mathematical induction and it's a very powerful and important tool in mathematics for proving sums like these.

Before we go

Can you figure out the two proofs hidden in the logo of this post?

Visual Math Friday

Let me know in the comments if you can!

Get ahead of me

By the way, if you wish to get ahead of me in this series, you can get these three amazing books on visual proofs:

Here are these books on

This article is part of the article series "Vim Plugins You Should Know About."
<- previous article next article ->

Vim Plugins, surround.vimThis is the seventh post in the article series "Vim Plugins You Should Know About". This time I am going to introduce you to a plugin called "ragtag.vim". A month ago it was still known as "allml.vim" but now it has been renamed to ragtag.vim.

The best parts of RagTag are mappings for editing HTML tags. It has a mapping for quickly closing open HTML tags, a mapping for quickly turning the typed word into a pair of open/close HTML tags, several mappings for inserting HTML doctype, linking to CSS stylesheets, loading JavaScript <script src="...">...</script> and it includes mappings for wrapping the typed text in a pair of <?php ... ?> tags for PHP, or <% ... %> for ASP or eRuby, and {% .. %} for Django.

RagTag is written by Tim Pope. He's the master of Vim plugin programming. I have already written about two of his plugins - surround.vim and repeat.vim and more articles about his plugins are coming!

Previous articles in the series.

Here are examples of using the RagTag plugin.

Quickly closing an open HTML tag.

Suppose you have typed <div> and you want to close it without typing the whole closing tag </div> yourself.

The quick way to do it with RagTag is to press CTRL+X /. This mapping automatically closes the last open HTML tag.

Extra tip: If you didn't have this plugin you could quickly close the tag by typing </ and pressing CTRL+X CTRL+O. The default Vim mapping CTRL+X CTRL+O guesses the item that may come after the cursor. In case of an open HTML tag it's the close tag.

Creating a pair of open/close HTML tags from a word.

Suppose you want to quickly create a pair of <div></div> and place the cursor between the two tags.

The quick way to do it with RagTag is to type div and press CTRL+X SPACE. This mapping takes the typed word and creates a pair of HTML tags, one closing tag and one open tag on the same line.

However, if you wish to create open/close tag pair separated by a newline, type CTRL+X ENTER.

Here is an example, if you just typed div and then press CTRL+X ENTER it will produce the following output:


| indicates the position of cursor.

Insert HTML doctype.

If you type CTRL+X ! RagTag will display a list of HTML doctypes to choose from. Defaults to HTML 4.01 Strict.

This mapping is not that useful, given that I already introduced snipmate.vim plugin for creating snippets. Using snipmate.vim you can create a snippet "h" that would insert the whole HTML structure, including doctype, html, body, title, meta tags, etc.

Link to a CSS stylesheet.

Typing CTRL+X @ inserts the snippet for linking to a CSS stylesheet.

<link rel="stylesheet" type="text/css" href="/stylesheets/|.css">

This is again not that useful, given that we have snipmate.vim.

The mapping is easy to remember because @ is used for importing in CSS.

Insert meta content-type tag.

Typing CTRL+X # inserts the HTML meta tag for document's content type and encoding.

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

The charset depends on document's charset. If it's utf-8, the mapping will set the charset to utf-8 in the meta tag.

Load JavaScript document.

Typing CTRL+X $ links to a JavaScript file.

<script type="text/javascript" src="/javascripts/|.js">

The mapping is easy to remember because $ is a valid char in identifiers in many languages.

Wrap the typed text in PHP, Django, eRuby template tags.

There are several different mappings for wrapping text in template tags. It's best to summarize them in the following table. The table assumes you had just typed "foo" and you are editing an eRuby document:

Mapping    Result
---------  -----------
CTRL+X =   foo<%= | %>
CTRL+X +   <%= foo| %>
CTRL+X -   foo<% | %>
CTRL+X _   <% foo| %>
CTRL+X '   foo<%# | %>
CTRL+X "   <%# foo| %>

What this table shows us is, for example, that if you have typed "foo" and press CTRL+X _, the plugin will wrap "foo" in <% %> tags and place the cursor after "foo".

Summary of all the RagTag mappings.

CTRL+X /       Close the last open HTML tag
CTRL+X SPACE   Create open/close HTML tags from the typed word
CTRL+X CR      The same as CTRL+X SPACE but puts a newspace in between
CTRL+X !       Insert HTML doctype
CTRL+X @       Insert CSS stylesheet
CTRL+X #       Insert meta content-type meta tag
CTRL+X $       Load JavaScript document

For the following mappings, suppose that
you have typed "foo".

Mapping        Result
---------      -----------
CTRL+X =       foo<%= | %>
CTRL+X +       <%= foo| %>
CTRL+X -       foo<% | %>
CTRL+X _       <% foo| %>
CTRL+X '       foo<%# | %>
CTRL+X "       <%# foo| %>

How to install ragtag.vim?

To get the latest version:

  • 1. Download
  • 2. Extract to ~/.vim (on Unix/Linux) or ~\vimfiles (on Windows).
  • 3. Run :helptags ~/.vim/doc (on Unix/Linux) or :helptags ~\vimfiles\doc (on Windows) to rebuild the tags file (so that you can read help :help ragtag.)
  • 4. Restart Vim or source ragtag.vim by typing :so ~/.vim/plugin/ragtag.vim (on Unix/Linux) or :so ~\vimfiles\plugin\ragtag.vim

Have Fun!

Have fun closing those HTML tags and until next time!