I stumbled upon something in Vim that I'm not quite sure how I can replicate.
Basically I have this
var first_set = input[0].split(',');
var second_set = input[1];
I had my cursor somewhere between the ] and ; on the second line, accidentally fat-fingered a key near i on my keyboard, and it instantly popped out what I was going to type.
var second_set = input[1].split(',');
I had previously inserted .split(',') to the first line.
Is there a Vim shortcut that automatically takes your last edit and spits it back out? I really can't figure out what Vim did that would know I wanted the exact same method. Even my autocomplete <C-n> doesn't go that far to even put in the same arguments.
Hopefully this isn't too obvious but you can use the . command to repeat the last command you did, also if you had deleted some piece of text then p would paste it. If this is an action that you do often you can create a macro that would automaticly transform something like input[1] into iniput[1].split(','). Also you can use a snippets plugin to expand things like spl into what you want.
There's many options :).
Related
So, I just realized I could use marks with capital letters to go to different files. That's great! However, I'm trying to find a way to close the buffer and return to the previous one. Say I go to my header file to change or add the declaration of the function I'm writing, and then I'd like to save the file, but only if there's changes to it, to go back to working on the contents of the function. How can I do this?
There's :x, but it also quits VIM
There's :bd!, but it doesnt save the changes
There's :bw, but that's even worse (unfortunately that's w[ipeout], not w[rite]...)
There's ctrl+O, but it doesnt seem to work when I edit the file (also, it doesnt actually close the buffer)
There's :up followed by :bd, but that's two commands and VIM's about efficiency, so I'd prefer a single command if it exists
There's a few other options and variants, but none that do what I wanted, afaik
It feels like this should be simple enough to do with one command, preferably without macros/plugins/functions/snippets/etc; as close to vanilla as possible. I get the feeling I'm missing something obvious.
You could concatenate commands like so:
:w|bd
I'd like to save the file, but only if there's changes to it
:up[date]
to go back to working on the contents of the function
Press Ctrl^, or enter the command :e[dit] #
I'd prefer a single command if it exists
Set an option :set autowrite and then Vim will save the current buffer on pressing Ctrl^ automatically.
I am using vim for quite some time now, but several times per day I accidentally encounter an inconvenience by hitting ESC too early.
Assume I am editing the following file:
I want to change 'house' in this line.
'house' should stay like this.
This 'house' should become 'home'
The other 'house' should also change.
I want to change house to home in all lines except the second one. (In this simple example it would easy to write a :s command and perform the task, but usually the task is more specific and manual replacements are quicker and less error prone.) I navigate to the first occurrence of house, press cw, type hone, and hit ESC. After hitting ESC I realize that by accident I typed the letter n instead of m.
I could navigate to the next occurrence of house and hit . to repeat the faulty replacement. In this case I have to fix all hones and replace the n by m afterwards.
I could fix the mistake immediately, but then I can not repeat the same house->home replacement, since . would repeat the n->m replacement.
All of this would be no problem, if I had spotted the mistake before hitting ESC. My question is, if there is a way to undo leaving the insert mode, such that . will repeat both actions? Or similarly, is there a way to tell . to repeat the last to operations?
(Of course this sounds like recording a macro, but since I end up in this situation by mistake, I have not started a macro recording.)
As far as I am concerned, there's no command history of vim in that you could repeat the last two operations.
However, there's a plugin that could help you accomplish that. It's called the RepeatLast.vim plugin to address this exact requirement. It provides a 2\. key binding. The cost for using that plugin and how the plugin actually works is that... it actually enables macro recording all the time. But if you could live with that, it should deal with this sort of situation pretty fine.
I am not trying to play golf with my editor. I am just trying to improve my editing skills with vim.
Let's consider this piece of assembly that I would like to convert to C. In order to do it methodically, I want to make small changes iteratively line after line.
dm(__abcd_bar_id + axis) = f4;
f1 = dm(_abcd_foo_id + axis);
f5 = f4 - f1;
The job with this example is:
Simplify the first line with abcd_bar_id[axis] = f4
Simplify the second line with f1 = abcd_foo_id[axis]
Replace f1 in the third line with the second line
Remove the second line
These steps are not negotiable. I know I can easily get rid of all my dm(__variable + index) with a regex like the one below but this is off topic.
:%s/dm\s*(\s*_\+\(\w\+\)\s\++\s\+\(\w\+\)\s*)/\1[\2]/g
So, to achieve these changes I traditionally do this:
▶▶▶▶DelDelDelDelDel▶▶▶▶▶▶▶▶▶▶▶▶[DelDelDel▶▶▶▶Right]
▼DeleteDelDel[▶▶▶▶]Del
Home▶▶▶▶RightDelDelDelDel
Shift+End Shift+◀ Ctrl+c
▼End◀◀BackspaceBackspace Ctrl+v
And the result should be this:
abcd_bar_id[axis] = f4;
f5 = f4 - abcd_foo_id[axis];
What saves me is I am quite fast hitting the same key multiple times. However I am sure I can be more productive if I use vi features
vfahd
wh3lxi[wr]
j:%s/dm(_//Enter
f+hv2lxi[Escwr]
$hvF2ay
jf1hhplxxx
Well, this seems to me much more complicated for my brain because a pre-processing bain-time is needed before each keystrokes.
For instance if I want to move to f1 I need to parse with my eyes if there is no other 1 on the way to f1.
I really feel I need years of training to be 'fluent' with vim.
So the questions are:
How a vim guru will treat this example?
Does a vim guru exist?
I definitely don't consider myself vim guru, although I use it on the daily basis. Answering your second question first, probably there's somebody who can be treated as a guru, there are simply so many options and possibilities in vim, that everybody can have their own way of doing things. Moreover, because you can tailor vim to your needs, it's easy to simplify regular tasks, and those configurations may differ a lot. Also people who are considered gurus by me (like, for instance, Derek Wyatt) claim that have still much to learn about vim, so it can definitely take years to become one.
But don't be discouraged, it takes only some practise to start thinking vim-way, and your editing tasks will become much easier :)
Back to your example. First of all, I'd edit the first line with slightly less keystrokes:
dta
f)r]
bdTd
i[
The difference isn't huge in terms of number of keystrokes, but it illustrates different approach. It allows, in my opinion, much less pre-processing, which is the problem you highlighted. I divided those keystrokes into sections to show you my thought process:
delete till a
find ) and replace it with ]
back one word and delete Till (backwards) d
insert [
I don't have to think much, when I apply those changes. You might think that this is counter-intuitive, that I jumped to ) character first, but it was much easier for me to spot closing bracket than count words or
hit h or l multiple times. Of course you might know the keystrokes but when you edit something you don't always remember all of them. This comes with practise and forcing yourself to use some of them (like t/T)
to put them firmly under your fingers. Also, print a cheat-sheet trying to make use of every key, until you'll learn it by heart. It won't take long ;)
As William already suggested in the comment, I'd also think about macro here. It's a powerful and easy-to-use tool, which can really automate your changes.
I already know how to edit first line. In your example, I know that in the second step I'll be doing the same thing, but in slightly different location, so instead of editing first line, I instantly record a macro, but I have to make it universal
for easier application. So I think about putting my cursor in proper location first, before making any changes. My macro would look like this:
qq
0fd dta f)r] bdTd i[
q
Notice, that I added 3 keystrokes at the beginning (not counting qq, which starts recording macro to q register). That might look redundant in the first line, but it ensures proper location of the cursor before making any changes.
That way I can easily apply this macro in the second line with #q
Now, you have to replace this f1 in the third line. You're still in the second line with your cursor, so you just yank with:
0fay$
and then paste it to the third line:
j$bPlD
Using macros mith look like a redundant thing when you edit just 3 lines, but when you get used to making changes in a vim way, you'll really feel you're taking advantage of it's power.
When it comes to remembering recorded macros it's not that hard, you have to have the proper attitude. First of all, you record your macros to registers, so typing :registers will show you also your macros. Secondly, you can edit them,
by pasting specific register, altering it and then saving to the same register. And then you can play it with #[register_letter]. And finally, don't get attached to specific macros. Save one or two, use them to make multiple changes at
once and forget about them. And then record another one under the same letter. For example, if you realize that you have to make some repetitive change across the file, use qq, because it's fast and intuitive. After making changes you rarely
need to play the same macro over again, because whole buffer is already in the right state. But if you know, that you'll need it, record next macro under another letter. If you'll get comfortable making changes intuitively vim way, so that
they can easily be repeted, you'll find that's much easier to record another macro than trying to remember under which letter you recorded previous one.
I hope that this answer will convince you, that you don't need years of training to get fluent, but of course it won't happen overnight ;)
When I want to see where my continue; jumps I have to delete ; and type it again (so something, let's call it Intellisense, will highlight continue and for or while line).
Same goes when I want to reformat something enclosed between { and } (in case formatting was not possible, because i wrote to example double a = inside and only after editing the rest could finish), I have to delete } (preferably the last one in the currently opened file) and type it again.
Question is:
are there keybindings to simplify this? Like pressing Ctrl+K and then something?
what are you guys doing, same as I deleting and retyping stuff to make things working?
P.S.: I know about Ctrl+Space (and one with the Shift) and I read this and also did some Googling, no luck.
Something that I want to do from time to time is paste the output of a vim command into the buffer. E.g. when I'm editing my vimrc, it'd be nice to be able to fiddle with statusline and then be able to just do something akin to
"=set statusline?<Enter>p
Problem is, that yields
E121: Undefined variable: set
E15: Invalid expression: set statusline?
Press ENTER or type command to continue
I figure that this is possible, and that I just don't know enough about the builtin functions and how to use them (I see expand used here and there, but have never successfully made it work for me in any context), even though I (think that I) have a pretty solid understanding of normal mode.
Note that this specific example is a little contrived, but I can't think of a better one right now. For the specific use case above, I could just ":p to get the whole set command that I used during experimentation and then edit to suit, but fairly regularly I run into other cases where I want vim to tell me something and then I want to paste that output somewhere so that I can continue to look at it while continuing with my work.
You can paste an option setting:
"=&statusline<Enter>p
I don't know of any way to put the output of an arbitrary command in the buffer, however.
The values of settings are stored in variables that are prepended with an & symbol. So the value that statusline is set to can be accessed by referencing &statusline. To insert into a document one way is to use the "expression" register, <ctrl-R>=. To use it enter insert mode and press <ctrl-R> and then =. You will see an equals sign in the command line, where you can enter: &statusline and then press enter. This will insert the value into the buffer.