Thursday, February 26, 2015

First Step In Z Shell (AKA “Give Me a Prompt or Give Me bash”)

published by Suby

Ironic, isn’t it, that for the prompt being maybe the coolest and flashiest thing that you always hear about Z shell (zsh), when you first switch from bash you get this:


So it’s giving us the computer name (or hostname), and then uses a % as delimiter before our input begins (where bash uses a $). This, by itself and with nothing else to recommend it to our collective impressionability, is not exactly what we in the geosciences* call “earth-shattering stuff.”

This is more like what I normally saw as the prompt (on OS X) when I was on bash:

Scrooge-and-Marley:bookshelf ebenezer$

Let’s start simple and just try to replicate that on zsh for now.

Ye Olde prompt string

The relevant setting (or “parameter”), in both bash and zsh, is PS1 (zsh also allows PROMPT). Both shells have a nice array of special characters which we can use, escaped, to represent various bits of info which we want in our command prompt (the prompt string). My old OS X bash prompt used three, which are listed under PROMPTING in the man page for bash:

h    the hostname up to the first `.'
W    the basename of the current working directory,
     with $HOME abbreviated with a tilde
u    the username of the current user

In bash, these are escaped with a \, so this would have been the value of PS1 there:

\h:\W \u\$

Or, quoted as we could set it with export:

export PS1='\h:\W \u\$ '

So now to make that, but in zsh.

The new prompt string (New Look, Same Different Taste)

zsh has a huge manual, which (as it explains in man zsh—that acts as a sort of index) is broken out into different sections. The relevant one here is:

man zshparam

…except that it turns out it’s not. Well, it sort of is. Here’s what it says for PS1:

       PS1 <S>
              The primary prompt string, printed before a command is read.  It undergoes a special form of expansion before being displayed; see EXPANSION OF PROMPT SEQUENCES in  zsh-misc(1).  The default is `%m%# '.

So, to man zshmisc!

Under SIMPLE PROMPT ESCAPES, we have a list: the special characters which stand for informational bits in our prompt string. These are the three which correspond to our bash special characters:

       %m     The hostname up to the first `.'.  An integer may follow the `%' to specify how many components of the hostname are desired.  With a negative  integer,  trailing  components of the hostname are shown.

       /      Current working directory.  If an integer follows the `%', it specifies a number of trailing components of the current working directory to show; zero  means  the  whole path.  A negative integer specifies leading components, i.e. %-1d specifies the first component.

       %n     $USERNAME.

If you do not yet have a .zshrc, create one. This can be its first line:

PS1='%m:%1d %n$ '

We can see the % for escaping rather than \ (as bash uses), of course. Other than that, we have the hostname (%m), a literal colon (:), the first item in our current working directory path (%1d), a space, and then our username (%n) and a literal dollar sign ($).

The %d confused me for a bit (I am not a Nobel-winning rocket scientist). Using the example in the man page, I tried something like

PS1='%m:%-1d %n$ '

which gives us something like:

Scrooge-and-Marley:/Users ebenezer$

Yes, the first item is indeed the first. (Who would have thought? A Nobel-winning rocket scientist would have, for one.)

So there you have a familiar (if you’re a fellow switcher from bash) prompt. Obviously we’ve not really taken over the world here—this is just about (if you’re also on OS X) getting back to what you were used to—but we now know how to modify prompt strings, or at least one of them, in zsh. Stay tuned for more exciting updates in this space…

(I stole the title of this post from that of the excellent book by James Ward and Bruce Eckel, First Steps in Flex.)

* I am not in the geosciences.

Tuesday, February 24, 2015

A More Betterer Autosave In Vim

Run :version in your local Vim. What do you see?

Here are the first two lines I get:

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Feb 24 2015 14:04:47)

That 7.4 is the key thing.

I actually wrote in old time (December 2013, as I recall; this was on an older site) about a cool new(-ish) autocommand event, or rather a pair of events, which someone sent a patch to the vim_dev list about—they were not mentioned in the help file. I don’t know when the events were added, but in Vim 7.4, the help file situation was remedied, and now we have this as the help for TextChanged and TextChangedI:

TextChanged            After a change was made to the text in the
                       current buffer in Normal mode.  That is when
                       b:changedtick has changed.
                       Not triggered when there is typeahead or when
                       an operator is pending.
                       Careful: This is triggered very often, don't
                       do anything that the user does not expect or
                       that is slow.
TextChangedI           After a change was made to the text in the
                       current buffer in Insert mode.
                       Not triggered when the popup menu is visible.
                       Otherwise the same as TextChanged.

I’ve (since writing that) upgraded to OS X Yosemite, and was back on its system Vim until today, in fact. (Its system Vim is a 7.3.) So I’d forgotten about these events, and was not even using an auto-saving trick for some time (until my last post, as it turns out). Then “Unknown” reminded me of the events (albeit indirectly) with a comment on that last post, “Save time in Vim NOW with these five weird tricks”, which mentioned an auto-saving autocommand as a bonus (sixth) trick:

Sadly auto-save a file when you leave insert mode doesn't do anything for edits made in normal mode (dd to delete a line etc)

(And yes, as you can see, I just upgraded to 7.4 again today. Yay Homebrew!)

I hereby, therefore, give you a new and improved (or at least improved) autocommand, Unknown! Here it is:

autocmd InsertLeave,TextChanged * if expand('%') != '' | update | endif

As the help text says, TextChanged watches for changes to the text (hmm—what a surprise!) when we’re in normal mode, which is where we do things such as dd, p, c, etc.; InsertLeave only notices that we’ve left insert mode (and thus lets us save all of the changes we made there, which is very nice of it). So the combined effect of the two events in this improved autocommand should be to take care of All Your Autosaving Needs (TM).

The one thing to keep in mind with this version is that, well, it saves after basically every change to the buffer. This means that after every accidental command or mis-pasted text, Vim will write the file. You can always undo it right afterwards, of course, if you notice it, but still. (Plus, as the help implies, this will cause our file to be saved quite often—normally we would consider this a Win, but if you’re the kind of Vimmist that’s doing 382,000,000,000 editing operations a second, who knows.)

So, I’m going to go with something like at the end of a recipe when they say “Salt to taste.” Try it out, and maybe it’ll prove massively helpful. (I’m trying it out again now myself.) Or, your taste might run more toward the old InsertLeave one (or even to not using an autosave at all—I would not understand that point of view myself, but to own his each).

Thursday, February 19, 2015

Save time in Vim NOW with these five weird tricks

[Yo. If you like these, check for additional tricks in the series: see posts labeled “Vim tips”.—Ed.]
It’s not just, as Alex, Mathias, and Andrew point out, that you can refactor your .vimrc (though, to be sure, you can—and probably should!). You can also niftily rework Vim, as it were, using this full-blown programming language to redirect its interface (your keyboard) in ways that save you time.

Here are five excellent ways to do that, which I’ve gradually come across in that unending fountain of Vim wisdom, the World-Wide Web. (Where I can recall a source, I’ve linked to it; also, I’ve sometimes tweaked such snippets for my own I’ll-have-you-to-know completely well-intentioned purposes.) Add the code from each to your .vimrc to try it out.

1. Exit insert mode without using Esc

inoremap jk <Esc>

This is for the “how can you possibly use Vim you’re always at the body shop for new pinky fingers you spend all day hitting Esc” crowd. Your right index finger is on the j key by default, right? And k is right next to that. So this is a brilliantly fast way to get back to normal mode, no Esc required.

Credit: This tactic is crazy-common among Vim masters, of course. I think I first came across the idea in Steve Losh’s epic “Coming Home To Vim”.

2. Allow mispelings when :wq-ing

cabbrev ew :wq
cabbrev qw :wq

:cabbrev is one of the abbreviation commands. It’s specific to commands, so that in the first word of each of these lines, when we type it, will be taken as the second word (the command—in this case, :wq).

3. Switch windows with two keystrokes

noremap <c-j> <c-w>j
noremap <c-k> <c-w>k
noremap <c-l> <c-w>l
noremap <c-h> <c-w>h

I use these all the time. Normally, to switch windows (split windows) in Vim, you have to do Ctrl+W and then a direction key (j, k, h, or l). This changes that to just Ctrl and then the direction.

Credit: Chris McKinnel’s Coderwall protip, “Speed up your already speedy Vim development”.

4. Enter command mode with one keystroke

nnoremap ; :
nnoremap : ;

Likewise this—now, instead of Shift+; to run a command, you can just hit the ; key. YOU’RE SAVING A KEYSTROKE!

(No, seriously—if you use the Vim command line as much throughout the day as I do, you’ll find that every such keystroke adds up. Use this. You’re quite welcome.)

Credit: Also Chris McKinnel.

5. Start an external command with a single bang

nnoremap ! :! 

To run an external command from within Vim, we just have to prepend ! at the Vim command line (as in :!date or :!ls). So that makes at least three keystrokes: (Shift+); and Shift+1—unless you use this mapping, in which case you can just hit Shift+1 in normal mode.



6. Auto-save a file when you leave insert mode

autocmd InsertLeave * if expand('%') != '' | update | endif

There are other ways to do this—I used to use something like this variation on #1 above:

inoremap jk <Esc>:w<cr>

Then I saw Romain Lafourcade recommending this autocommand on Stack Overflow, and switched to it right away. (A huge benefit of this approach: it catches, for example, when you leave insert mode via Ctrl+C—the InsertLeave event is triggered, as you might expect, whenever we leave insert mode.)

After the event (InsertLeave) and file pattern (*, or “any file”), we have an if statement which checks for something in the % special character.* If we’re editing a file, this will give us its filename; if not, it will return '' (an empty string). So we check for a non-empty string, and if we get one, we run :update (which saves the file only if it’s been modified—basically like a smarter :w). Then we end the if.

(Worth noting also is the | line separator. In VimL, this functions like the semicolon ; does in many other programming languages, denoting the end of a line and allowing us to continue our code all on the same line of the file, if we wish. We use it here to write all three lines of our autocommand’s code on the one autocommand line.)

UPDATE: See my newer post on this particular trick: “A More Betterer Autosave In Vim.”

And yourself?

What weird tricks do you have in your .vimrc?

* See :help cmdline-special for the whole list of those characters.

Wednesday, February 18, 2015

Required reading for the predated-by-Vim folks in the audience

For those of us newer than Vim to the business of text editing, it’s important to remember that vi was the editor which got the “most efficient manipulator of text possible” reputation. Vim is, after all, only “Vi IMproved.”

Watching an experienced VI user inspires awe. The cursor seems to follow their eyes. Unfortunately, it takes about two years of daily VI usage to get to that point because the learning curve is so daunting. If you’ve used it every day for 1 year and 364 days, you’ll still struggle.
— Neal Ford, The Productive Programmer

We hear from one such experienced user (Jim Dennis) in what I’d guess is one of the most-voted-for answers on Stack Overflow, in reply to the question “What is your most productive shortcut with Vim?”

The answer’s title, to the extent to which answers can have titles on Stack Overflow, is “Your problem with Vim is that you don't grok vi.” Go read it. It’s all good and there’s no part that particularly calls for quotation other than this at the end:

I've only scratched to surface of vi's power and none of what I've described here is even part of the "improvements" for which vim is named! All of what I've described here should work on any old copy of vi from 20 or 30 years ago.

Tuesday, February 17, 2015

How to use :helpgrep in Vim

Vim’s quickfix mode, in case you weren’t already familiar with it, is meant to assist error correction in a situation involving compilers and error messages. You can save compiler errors to a file and have Vim list each one, with line numbers, the easier to jump to it. Errors show up in the quickfix window (a horizontal split below whatever you were already working on).

Vim also has :grep (and :vimgrep) commands. These use the OS’s grep or grep equivalent (or Vim’s own “internal grep”) to find patterns (search patterns) in a file. They can make use of the same window:

Related to these commands is a cool one, :helpgrep, which is (as its name might suggest) a grep dedicated to searching Vim’s help. It’s simple to use—unlike other grep commands, it doesn’t require a filename, and instead searches all of the various Vim help files for whatever pattern you give it.

The cpoptions option can be (is) a tad mysterious. It’s one of the option strings (like concealcursor, which we discuss in the book), and each character in the string stands for a bit of vi behavior which Vim will support. To see each time that cpoptions is referred to in a help entry, we could run this:

:helpgrep cpoptions

(It’s important to note that in this example, “cpoptions” is a pattern—a Vim regex pattern—even despite the lack of escaped or special characters here.)

When I run the command, I am taken to line 810 of the help file for TwitVim (since I’ve installed that plugin and its help file has been added to my Vim). This is printed on the command line:

(1 of 17): like 'magic' is set and 'cpoptions' is empty. (Essentially, this is

That’s the line that the cursor was put on (810 of the help file).

From here, we can navigate through results using quickfix commands. (As in the Vim help, the bracketed parts of the commands are optional; you can enter just the non-bracketed part to save time.)

:cfir[st] (needs the ir to distinguish it from :cf, which is for :cfile, an error-related command)
:cla[st] (needs the a to distinguish it from :cl, which is for :clist)

:cl shows all of the results in “list” format (rather like :messages shows messages).

Notice the last one. When we’re running :helpgrep, :cw can open all of the results in a jump-enabling (and search-enabling!) window: the quickfix window.

Each entry (as you can see from the illustration) shows the name of the help file it’s in, the line and column numbers, and then the relevant line.

To jump to an entry, just hit Enter. The usual navigation commands apply in this buffer, too: you can j and k your way around if you wish, but also do not forget / and the power of Search To Navigate™!

Thursday, February 5, 2015

Is it VimL or Vimscript?

This one’s easy:

It’s VimL, because it’s neither!

Allow me, if you will, to explain.

On The Pragmatic Bookshelf’s page for The VimL Primer (click the “Details” tab to see it), there’s a Q&A I did regarding the book’s topic (the language we’re discussing). Here’s one part of it:

2. There’s no such thing as VimL! What is this book about?

This book is about Vim’s built-in scripting language, VimL. This language is also known as Vimscript. Depending on how you look at it, either VimL is an alternate name for Vimscript or Vimscript is an alternate name for VimL.

Actually, there’s no real official name for the language; the closest seems to be the two-word “Vim script.”…

What madness is this? It’s quite true! the official name is “Vim script”. See the manual at :help exception-handling for proof:

The Vim script language comprises an exception handling feature.…

Does that not convince you? Wikipedia—WIKIPEDIA!introduces the language thusly:

Vim script… is the scripting language built into Vim.

(Wikipedia does list “Vimscript” and “VimL” as alternate names.)

So how does that, as I say, mean that the name is VimL? See farther down in the Wikipedia article:

Vim script files are stored in plain text format and the file name extension is .vim.

What files? Script files, in Vim. No, maybe files in Vim’s scripting language. No, what about script files in general, but when Vim’s editing them…

I expect you can see that at which I am getting: this is a confusing name until you join the words or uppercase the “s” in “script.” And at the point at which we’re doing that, we’re already changing the official name. We can change it to whatever we want!

Thus the end of my answer:

The relatively new name “VimL” (“Vim Language”) has been gaining in popularity in rough correlation with the growth of the code-sharing site GitHub. Its use is a matter of preference, but I do find it more easily distinguishable from mentions of Vim scripts or of writing generic scripts using Vim (in search results, for instance). It’s a short, tolerably memorable name, a bit catchy, and what I use throughout this book.

The reality, of course, is that I can’t change the Vim manual (although I could change the Wikipedia page…). I am content with accepting that this is a scripting language, and I suppose it technically works to call it the obvious (“Vimscript”). But as long as we have a cool distinguishable alternate name, my vote (with the vote of the masses) is for VimL.

Tuesday, February 3, 2015

Vim ranges: an introduction

According to a study conducted in 2015 by the National Association of Search Engine Users’ Board Of Suddenly Saying “Hey, Let’s Check The Google Trends for Vim-Related Searches”, Google gets a fair number of Vim-related queries. The first that has to do with everyday Vim use (coming in fourth most-common, after “vim linux”, “vi vim”, and “windows vim”) is “replace vim”.

On the face of it that might look like the lunatic keyboard smashings of a madperson OK with switching from The Other One True Editor to Notepad or TextEdit or perhaps even Emacs. Google it, however, and the top results are all for replacing text in Vim. They’ll typically show you a variation on this command:


Here, the colon (:) starts a Vim command on the Vim command line. The s is the command (a shortened form of :substitute). term is the search term, replacement is the replacement text, and g is a flag (think “global”) which we’re giving the command. What in the blue blazes is %?!

That, dear fellow Vimmist, is a range.

The range as line numbers

A range is a line number or set of line numbers. Given to a Vim command, it limits the command’s effect to the lines in the range.

We’ll go ahead and use :s as an example, since it’s such a common range-accepting command. Let us say that we mistook ourselves for Johnson (William Cowper’s publisher), hadn’t realized that the year was not 1785, and were taking it upon ourselves to, using Vim, edit this bit from The Garden (Book III of The Task):

1  I see that all are wand'rers, gone astray,
2  Each in his own delusions; they are lost
3  In chace of fancied happiness, still woo'd
4  And never won. Dream after dream ensues;
5  And still they dream that they shall still succeed,
6  And still are disappointed. Rings the world
7  With the vain stir. I sum up half mankind,
8  And add two-thirds of the remaining half,
9  And find the total of their hopes and fears
10 Dreams, empty dreams.

This is basically perfect, so all we can do is make gratuitous modifications which reassure us of our editorial power. For example, we might change “still” to “yet”. To do that on only line 3, where it first shows up, we could run:


But “still” occurs on four lines—from 3 to 6. What if we wanted to get back at the genius for a supposed overuse of the adverb, and replace it on lines 3 to 5?

Well, for one thing, we’d have to put that g flag back on (otherwise, we’d only get the first instance of “still” on line 5, which has two). But most importantly, we’d have to give :s a range with an ending line number. We could do this:


The range as special characters representing line numbers

Did I say that a range is “a line number or set of line numbers” (hint: I did)? It turns out that that’s not all that can make up a range. There are a number of special characters which we can use to stand for line numbers, too. The full list is at :help :range, but I will steal the top three from there because they’re perhaps the most basically useful:

.    The current line

$    The last line

%    The full file

Aaaaaaaaaaand there we are. I never did explain what % meant, did I? I mean until just now. Just now I did. So there: when you see the :%s in a Vim tutorial somewhere, you know not only the order (yes, I used to always confuse the order of the % and s, because in the early days, all I knew was “this jumble of characters that I just Googled tells Vim to replace text”), but also what the % means (in this context—it’s also a motion).

If we were on line 3 and wanted to change those same occurrences of “still”, we could use the . to say “from this line to line 5”:


We could change from line 3 to the end of the file:


Although by that point, we might as well decide to, in a fit of rageful fury, destroy the world (in a manner of speaking) and change all occurrences across the entirety of the file:


So those are some helpful placeholders for actual line numbers in a range. There’s a deal more to ranges than this; we’re going to get into just one more aspect.

The range as a pattern which depends on the content of the file such that it effectively bypasses the concept of line numbers nearly altogether

This has the potential to be really profoundly effective. Vim allows us to substitute search patterns for line numbers within our range.

Back to our example text. The | is our cursor:

1  I see that all are wand'rers, gone astray,
2  Each in his own delusions; they are lost
3  In chace of fancied happiness, still woo'd
4  And never won. Dream after dream ensues;
5  And still they dream that| they shall still succeed,
6  And still are disappointed. Rings the world
7  With the vain stir. I sum up half mankind,
8  And add two-thirds of the remaining half,
9  And find the total of their hopes and fears
10 Dreams, empty dreams.

Let’s go easy on Cowper, shall we? (He’s the genius, after all. We are only editors.) Let’s only change the first two occurrences of “still” to “yet”.

There are other ways to do this, but here’s how we’d do it using a pattern within a range. We’ll tell :s to only replace instances occurring between “chace” on line 3 and “shall” on line 5:


Now that looks a bit more complex. It’s quite simple though in actuality: ?chace? is a backwards search pattern (remember that in Vim, ? searches backwards), /shall/ is a regular search pattern, and then the command (s) follows with its arguments (still and yet).

For further reading

Juicy details are at :help cmdline-ranges. A user-friendly take, as that help section will tell you, is in the user manual at 10.3 (:help 10.3).