Prevent arrow keys from breaking down dot command - vim

I am trying to find replacement for multi cursors plugin and found out cgn command pretty useful. However, there is undesirable behavior using arrow keys during insert mode. Sometimes there is no need to change the whole search entry (e.g. fix typo) so the arrow keys are necessary in that case. To reproduce the "bug" you can type tabe and then 3ifoobar<Enter><Esc>/foo<Enter>cgn<End>bar<Esc>.
No matter what movement you will use: arrow keys or key like <End> - powerful dot command stops working. I mean it just inserts text written after movement at the same position instead of changing the next search entry.

The only way to support redo, consists in using <C-G>U before <right> and <left>. This requires has('patch-7.4.849')
If you need to move to the end of the line, you'll need to count. If you need to move to the next line, you'll loose redo.

Related

How do I map Vim colon search and replace command to work just with visual selection?

Sometimes I want to replace some text in multiple lines but not in the whole line, so I toggle visual mode on and highlight the text I want to replace. But then, I need to add this annoying \%V that I always forget for it to replace the text just in the selection and not in the whole line
:'<, '>s/\%Vold/new/g
Is there a way to map the normal replace command
:'<, '>s/old/new/g
To the one shown above so that I don't need to remember that V every time?
Thank you
I tried using cmap command in the vimrc file in the following way:
cmap '<, '>s/* '<, '>s/\%V*
But this of course doesn't work, because instead of the asterisk I should input the text I want to search and replace to end the search and replace command.
There are three basic parts to a mapping:
the mapping command,
the "left-hand side" (LHS),
and the "right-hand side" (RHS).
The LHS is the key sequence/combination that you want to press and the RHS is a different key sequence that you want Vim to "press" instead of those in the LHS. You "map" one key sequence to another.
The RHS is, fundamentally, a macro: a sequence of keystrokes, "just" like if you pressed them yourself but without any delay between them. So, the RHS is really just a bunch of keystrokes you are tired of making over and over again.
The main use of mappings is to reduce repetitiveness. You figure that you often press the imaginary sequence sdlusdrosydtsodsd and you map it all to <F5> to be more efficient.
In this case…
The current mode is visual mode so the mapping has to be a visual mode mapping.
This makes :xmap or :xnoremap the proper mapping command. Let's make it :xnoremap.
The repetitive key sequence you want to abstract away is:
:s/\%V
That's your RHS.
(Note that the range '<,'> is automatically inserted for you so it can be ignored.)
The key sequence you want to press instead is, let's say… <F5>.
That's your LHS.
Now that you have your mapping command, your LHS, and your RHS, building the mapping is extremely easy:
:xnoremap <F5> :s/\%V

Insert a specific string instead of tabs or spaces in gVim

Since I'm working with LaTeX documents in vim, I want to be able to insert \quad instead of a tab space whenever I press tab (instead of having to replace/insert them manually). Is there any setting that could do this? If not, are there any plugins that work like this?
While you can use inoremap to change Tab to \quad in insert mode, that means
that you lose the original Tab functionality...
This might be worth it if you're sure that you'll never want to use Tab, but
what will you do when you face a similar problem of wanting some
latex-specific text? You could try and find a second key to map... but each
addition will take up a new key that already had some function.
The way I would handle this would be to use iabbrev to map some unlikely
sequence of keys like ;q to \quad:
iabbrev ;q \quad
This has the advantage that you can build up a whole set of insert mode
abbreviations, all consistently starting with ; followed by a letter or two
that you can choose to be easily remembered. And you get to keep all the
original functionality.

How to efficiently add parentheses or a string in vim?

In traditional text editors, whenever I needed to open a string or parentheses and type something between it I used to do:
Type () or ""
Press left
Type in what I need
Press right
But in vim (that is if I followed the vim way) the process becomes quite tedious as I have to enter the normal mode to move a whole bunch of times:
Type () or ""
Press <ESC>
Press i
Type what I need
Press <ESC>
Press l
Press a
If it is not a good practice to use the arrow keys at any time, is there a more efficient way of doing this kind of task in vim?
It is actually quite easy to automatically append those closing characters in a mapping, and put your cursor where you want it. The trick is to do that, without also messing up the undo/redo/repeat actions. The problem is that cursor movement commands in insert mode will break the "undo sequence" so that any change you make after moving the cursor is undone separately from changes made before moving the cursor.
Warning: the following information may become dated
There are plenty of plugins available to automatically append these characters (see the partial list at the Vim wiki page for appending closing characters), and prior to Vim 7.4, some of them even had complicated workarounds for keeping the undo sequence intact. Unfortunately, they all relied on a bug in Vim that got fixed in version 7.4 for this.
A patch is available to add a cursor movement that does not break undo, so if you want to compile Vim yourself, you can grab that patch and use mappings like the following (no plugin required!) to do what you want:
inoremap ( ()<C-G>U<Left>
inoremap <expr> ) strpart(getline('.'), col('.')-1, 1) == ")" ? "\<C-G>U\<Right>" : ")"
These mappings will insert "()" when you type an opening (, placing the cursor in between the parentheses. When you type ')' and there is already a closing ')' after the cursor, Vim will skip over the parenthesis instead of inserting a new one. Cursor movement is preceded by <C-G>U which is the feature the aforementioned patch adds, allowing the following cursor movement to not break the undo sequence (as long as the movement is all in a single line).
As of Vim 7.4.663, this patch has still not been officially included.
No. Doing it in Vim is exactly the same as in your "traditional" editor:
Type () or ""
Press left
Type in what you need
Press right
But… why don't you type the opening character, what you want inside the pair and then the closing character?
Type ( or "
Type what you need
Type ) or "
Too simple?
I think using arrow keys to move around is bad practice in normal mode but in your case; moving one space while in insert mode, I would hazard to say using the arrow keys is probably best practice.
That being said if you are dead set on avoiding them you could use <i_ctrl-o>.
:help i_ctrl_o
CTRL-O execute one command, return to Insert mode *i_CTRL-O*
So, while in insert mode, you could type: ()<ctrl-o>h<xxx><ctrl-o>l, where <xxx> is whatever you want in the brackets.
Unfortunately that doesn't work if you cursor is on the last character of the line, which if you are typing it most likely is.
To solve that problem do :set virtualedit+=onemore or add it to your ~/.vimrc file.
Note that this solution is more keystrokes than simply using the arrow keys but you don't need to move your hands away from the home row so it may be faster anyway.

How to skip over auto-inserted matching chars in vim insert mode?

When I'm in VIM insert mode, it wonderfully adds matching end characters. E.g. if I type " it will add another " immediately after the cursor. Similarly for parenthesis, braces etc. when programming.
How can I quickly skip over the inserted character, while staying in insert mode? The best I've found is to use the forward arrow key, but that's not conveniently located.
Accordingly, I either type the closing character, or I <esc>li (exit insert mode, move right one character, re-enter insert mode). This reduces the convenience of the auto-insertion quite dramatically, so I figure I'm missing something obvious.
(Note, for convenience I'm using the handy SPF13 curated collection of plugins and running MacVIM. Edit: This is the autoclose script providing the matching.)
There's basically no way to get out of an autoclosed pair that doesn't involve pressing at least one key.
The standard mechanism provided by all the autoclosing plugins is simple: type the closing character. You can also press <Right> or, if you are at the end of the line, <End>.
Maybe your plugin gives you another mechanism but you'll have to find out for yourself.
Whatever key you press, you'll still do at the very least exactly the same amount of typing as you'd do without autoclosing.
Autoclosing is not about saving typing, the only practical use of that feature is to prevent unmatched pairs. That's all and, I think, the "obvious" thing you are missing.
As you are using a SPF13 and don't know which plugins brought the mapping. There are two things that we can do
1) I usually esc followed by A. This will kept you in insert mode after the closed character if it is the last character. I usually prefer this over the second one.
2) You can circumvent the automatic closing by ctrl - v before the character, for instance ". This will not autoclose the corresponding character and you are responsible for the closing.

Vim: transitioning from mouse to movement

I use MacVim (and gvim) a lot. I'm familiar with and use a lot of the basic movement commands (b, w, $, 0, G). However, for a lot of things—such as selecting particular lines on the screen or jumping to a particular column in a different line—I use the mouse (sometimes in concert with my left hand on the keyboard). It also helps that my mouse has a scroll wheel and buttons for changing tabs.
I also need to admit... I use the arrow keys on my keyboard rather than hjkl.
I think that my speed (and posture at the computer) will be improved by not having to escape from insert mode, and from keeping both hands on the main part of the keyboard.
What convinced you to abandon the mouse? What are the most helpful shortcuts for moving quickly between lines and columns, scrolling, etc.?
This question is inspired by this recent post
I think that my speed (and posture at
the computer) will be improved by not
having to escape from insert mode
No, you must escape from insert mode right after you typed what you want. It quickly becomes a reflex, so you don't really lose time (I sometimes even press escape after completing a web form...). Normal mode isn't just for moving around, it's used to perform most operations (save from typing): for instance deleting or moving sections of text. You also benefit from entering insert mode with the appropriate key: o to start a line, S to replace a line (while keeping indentation), A to move to the end of the line, c+motion to replace a few words or until a given character... All of these save keystrokes.
The mouse seems fast, but in reality it isn't precise, so you lose time (in addition to the constant back and forth with the keyboard). ViM has a long list of moving commands (see :help usr_03) which, when mastered, are faster than the mouse in most situations.
Use search the most you can (/, ?, *, #, f, t...). I personally use Ctrl+(d,u,f,b) a lot. Also, Ctrl+(o, i) and `` are really useful to go back where you were before a search or something else.
h, j, k, l are there to place your right hand near to useful commands (i, u, o...): I always have my fingers on them. The arrows force you to move your hand a lot.
Try to look at a few commands in :help, then use them a lot, and you'll get habits about what you should use to move according to the situation. Nobody uses ViM the same way.
The more I used the keyboard movement in vim, the less I wanted to use the mouse. It doesn't help that extended periods of time where I'm constantly moving from keyboard to mouse can take a toll on my wrist.
If you want to force doing things the vim way, unplug your mouse for a while! The more you use the keyboard, the more you will love it. This worked for me.
For moving between lines, I usually just use jk but I often skip to lines using :line_num. Getting to a specific column in a line, I typically use wbe^0$ and put modifiers in front of w, b, or e if I'm skipping through several words. And there is also the shifted versions, WBE which also come in handy often.
I have to admit that I often use the arrow keys for specific movement in vim.
I rarely use hjkl. However, I find that most of my navigation is done with other commands such as w (skip a word forward), b (skip a word backwards). Combine this with modifiers such as 3w (3 words forward). : skip to a specific line.
I've never really had to abandon the mouse since I never really started with it. All I can say is that attempting to use editors without all the keyboard shortcuts that vim has can feel quite painful.
I'd run vimtutor from the command line (Terminal.app in OS X). It runs vim with a tutorial document. That document was what really made me realize the power of some of the commands. You'll pick up some that are most useful to you and gain more over time. Eventually you'll find yourself using the mouse less and less.
One command that will really improve your movement speeds is f. f plus a character will jump to the first occurrence of that character on the current line. Pressing ; will jump to the next occurrence. Of course this can be used in combination with other commands. So, for example, removing all characters up to and including the first closing parenthesis is achieved by pressing d+f+).
You can seriously revolve your life around jk in hjkl.
nnoremap <c-k> ddkP "move current line up one
nnoremap <c-j> ddp "move current line down one
vnoremap <c-j> dp'[V'] "move visual block down one
vnoremap <c-k> dkP'[V'] "move visual block up one
"These may be a bit more esoteric to me"
inoremap jj <esc>o "Insert mode can move to next line (works mid line)
inoremap kk <esc>O "Insert mode new line on previous line
also for the desktop gui (ion3 and gnome)
winj - next window
wink - prev window
(This beats alttab if your editing in vim all day)
also read :he motion.txt in its entirety using j and k to scroll up and down as you do.
I learned vi so for me the mouse has never been something to use with a text editor.
I don't use hjkl except when the machine/network/keyboard/whatever-in-between is not comfortably configured.
Use the mouse where it makes sense. It often does (copy/paste to and from other gui applications).
To answer your question, though: Once you start using vim as a tool for transforming text bits with macros, the movements will all start to fall into place ;)
I think you're wondering if there's a quick way to move around while in insert mode (without using the mouse or arrow keys) but unfortunately there isn't; you have to escape out of insert mode. However I know that jumping all the way to your Esc key can be really annoying, which is why I've gotten into the habit of escaping with Ctrl+c, it's much faster.
I almost never use hjkl because it's too tedious. I usually try to jump right to where I want to go. There's a great cheat sheet out there (a Dvorak version is a available also (although it's in PDF)) that you can stare at and imagine the possibilities.
Mostly I use f, F, t, and T, and sometimes they're enhanced by typing a number up front like d2t) will delete up to the second close paren. Sometimes I use search. A lot of the time I use w, W, b, B, e, and E. They're all fantastic.
When I see vim users arrowing all over the place in visual mode just to delete text it makes me shudder, because there are so much easier ways (and hjkl only make you move your arm less, they don't change the number of button presses).
Something I did that I don't know if it's common or not is remapped my arrow keys to be <Esc><Up> and so on. For whatever reason I started out always arrowing around and assuming I'd be back in normal mode, so I just made it do that...
The biggest bummer about Vim is that now when I edit anything anywhere else I hit escape all of the time and type :w after every change...

Resources