Scripting common tasks in Vim
Asked Answered
D

4

11

While using Vim (at home and at work), I often find myself doing similar things repeatedly. For example, I may turn a bunch of CSV text into a series of SQL inserts. I've been using Vim for years, but only recently have I tried to seriously think about how I could improve my productivity while using it.

My question is.. Is there a good way (or right way) to store commonly used commands or command sequences? And how is the best way to execute them? It would be nice to be able to use the same script on a live session and also over the command line against some file.

I'm hoping that I can store them in a .vim file so that I can hand them to coworkers (who are not as proficient with vim) for them to use.

Desired answered 1/11, 2008 at 7:44 Comment(0)
M
14

You can store your common task macros in .vim files, like this for example, and then you can load them with the command :so file.vim

Here you can find a bunch of useful macros, also I recommend you to learn well the useful q macro recording command, it's very very powerful...

The macros created with the q command are stored in a register, qq stores the macro in the q register, so when you end the recording you can simply paste the macro, with "qp and save it, later you can load it by simply yanking the macro into a register i.e.: "qY, the macros are only text and remember you can use any register instead of q. There is a Vim Script for storing q macros:

marvim : Macro Persistent Storage and Shareable Repository for VIM

Also take a look to the Vim Scripting Language.

Mateo answered 1/11, 2008 at 7:57 Comment(2)
This may be answered in one of your links, but can qq macros be stored once recorded? I've always used them, but I didn't know if they could be persisted across sessions.Desired
The macros created with the q command are stored in a register, qq stores the macro in the q register, so when you end the recording you can simply paste the macro, with "qp and save it, later you can load it by simply yanking the macro text, by "qY remember you can use any register instead of q...Mielke
G
3

I use q/@ to record/replay a macro quite frequently.

The next step up is trying to write in something like 3 or fewer ex commands.

If something so complex that neither a macro nor a short ex sequence won’t suffice, I tend to write it as a Perl script instead. The vim script language is a bit too limited to try to do grand things in, for my taste. (Although vim 7 has made great strides in that respect, by borrowing a bunch of things from Python.)

Note that @ does something very simple: it takes the contents of a register and replays them as if you had typed them in normal mode. Likewise q simply records the sequence you are typing into the register you name. These are the self-same registers you use for yanking/putting – which means you can directly paste a recorded sequence into a file (.vimrc anyone?) or yank a sequence of commands from a file and replay it (so you could keep a bunch of them in ~/my-vim-macros.txt or something).

Grumpy answered 2/11, 2008 at 3:59 Comment(0)
S
2

You can store command sequences in your .vimrc and assign them a key binding with the :map command. For instance:

echo >>~/.vimrc ":map ,c :%s/,/','/g<CR>:%s/^/('/g<CR>:%s/$/'),/g<CR>"

When pressing ",c" in a live session this will convert your CSV file into a portion of an INSERT statement.

On the command line that very same piece of editing can be applied to a file via (this will overwrite, be sure to backup first):

vim file.txt -c ':normal ,c | :x'

There might be a better way but this works.

Scolopendrid answered 1/11, 2008 at 8:28 Comment(0)
E
1

Personally, and maybe in part because I was using Unix long before vim existed (heck, the first version of Unix I used didn't have "vi" either - but that's another story), I would normally use a 'shell script' (or, more likely, a Perl script) to do the transform. For converting CSV data to INSERT, dealing with quotes/non-quotes and embedded commas in full generality is messy -- I'd probably aim to use a Perl script with Text::CSV_XS to guarantee correct parsing. I'd then run that script on the range of text that needed converting.

One advantage of this is the focussed tool approach - one tool does one job right. My private bin directory has 300 or more scripts and programs in it; the RCS directory has over 500 scripts in it.

This is not to say that scripting in vim is bad. I use (more or less) complex map commands to write complex manipulations, often when I'm about to have to do the same change across a suite of files, and when I don't think it will be worth creating a script for the job. However, if I think I might need the changes more than once, then I'll script it. For example, GCC started to get uppity (circa 2005) about not embedding unused static strings in object files - which meant my version control information wasn't visible. So, over a period of years, as I edit the source files, I've converted from a static (fixed) name to a public name - reluctantly, but necessarily AFAIAC. I have a script that does that edit for me, so when I need to make the change in a file, I run that script to do so. I have another script that updates the copyright information; I need that each time I first modify a file in a given year. Yeah, I could probably stash it away as something in vim -- I grew up thinking that the separate script is better, not least because if I switch to any other editor, I can still use the script.

Eppes answered 1/11, 2008 at 16:18 Comment(1)
For the most part, I agree. I have tons of bash, zsh, and python scripts for the same reason. My aim with this question, on the other hand, is to find the right technique to fill this particular gap in my productivity, which is smallish tasks that I do repeatedly within Vim.Desired

© 2022 - 2024 — McMap. All rights reserved.