Long-line handling from Nano in Vim? - vim

I'm a hardcore VIM-user. However, I wonder whether it's possible to configure VIM to provide a lone-line handling like Nano. Imagine the following text file:
1 This is a short line
2 This is a much much much much much much much (...) much longer line
When I open it in VIM, and like to get to the end of the second line, it's displayed like this (with ■ being where the cursor is):
1 ort line
2 ch much much much much much much (...) much longer line■
When I open in Nano, and navigate to the end of the second line, only this specific line is displayed "shifted", like so:
1 This is a short line
2 >h much much much much much much (...) much longer line■
Can I do this with VIM too?

Vim is a fixed-width text editor. The problem with your suggested visualization is that when moving to a previous / next line (e.g. via k / j), the cursor would "jump" horizontally on the screen, instead of going straight up.
One could get accustomed to that (the cursor already jumps when the new line is shorter (unless 'virtualedit' is set)), but how would a blockwise visual selection be represented? With jagged edges on both sides?
That's why it's unlikely to be accepted, but don't let this discourage anyone from writing the (non-trivial) patch :-)

Related

VIM: motion without jk and HardMode installed

I am enjoying hardmode and have definitely seen improvement. However the one item I am dealing with is selecting, moving, copying only two lines at the time. Current line +1 or -1.
Before hardmode the way I would select three lines of code in visual mode would be with the motion:
V2j
Since HardMode disables the "j" key what would be a good substitute to such move?
About HardMode:
Hard Mode is a plugin which disables the arrow keys, the hjkl keys,
the page up/down keys, and a handful of other keys which allow one to
rely on character-wise navigation. The philosophy behind Hard Mode is
that you'll never master Vim's advanced motion and search
functionality if you can fall back on the anti-pattern of fumbling
around your code with the arrow keys.
https://github.com/wikitopian/hardmode
For me, HardMode is all about changing your mindset about how you move in vim. Really getting comfortable with text objects, searching etc.
In this case, you can just use 3V (3 <S-v>) to select 3 lines.
I'd urge you to learn some ex commands while you work in HardMode. Like use
:8,15d " To delete lines from line no. 8 through 15
:8,15co . "To copy range of lines 8 through 15 to current cursor position.
You can also use
:.+3 " To move down
:.-3 " To move up 3 lines
but then you'll be totally missing the point. Just use HardMode for what it's meant to be. Which is learn a few things in a constrained situation.
I think I see the point of hardmode now, and you got an answer for how to select multiple lines in visual mode. That answer is correct, but maybe you don't need to select at all? You mentioned copying, or moving, a few lines. For that, try using counts with your yank/delete commands. Example, to copy 5 lines:
5yy
To delete 3 lines:
3dd

Toward Vim moves from conventional moves (<left> <right> <up> <down> <backspace>)

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 ;)

Is there a way to show line numbers at end of the line in Vim

I am using
set relativenumber
set number
which let's me move easily around. However, it is often hard to know the exact the line number of the object where I would like to jump to because I first need to look to the left. I feel it would be easier if I could see the line numbers also on the right hand side right because my eyes have less space to follow (maybe?). I think the ideal setting would be to show the relative/absolute line number where the $ appears when whitespace characters are shown and to the left/right of the buffer. I.e.
1 Random text.$1 1
159 This is the line where the cursor is.$159 159
1 Some random text.$1 1
2 More random text. Another sentence. Maybe a third one? And so on.$2 2
3 Another line which might be quite long and my eyes focus somewhere here.$3 3
4 More random text containing more text and more words and stuff.$4 4
(In this example, I would like to do 3k but I may type 2k or 4k because I did not follow the correct line to the left.)
Is it possible to achieve this somehow?
Any suggestion on how to change my workflow are welcome, too.
Note: Using cursorline does not help as I do not seek the number of the current line.
No, there is no built-in support to your requirement. also I don't think this is easy to be done by plugin.
Maybe you could consider to change your habit/workflow. E.g. enable the cursorline option, to highlight your "current" line, it may let you easier to identify which line are you on right now.
To move cursor, if you don't want to count lines, you may want to try the EasyMotion plugin. It is very handy plugin. However it won't replace the hjkl ... motions.
No, that's not possible, unless you modify Vim's source code in a non-trivial way, or work around with kludges like a vertically split small scratch buffer at the side that is updated via autocmds.
Do you have :set cursorline? That helps (me) a lot to follow the current line, even with large window widths. Reducing those might help, too, though you have to deal with wrapping / scrolling of long lines then.

Reformatting in Vim, the sensible way

I don't often reformat text, apart from the plain gq so this is probably something simple, but just don't seem to have the luck of finding it in the help.
Anyways, I have the text that looks like this
Funnily enough, that was exciting.
"I've just about had enough of this," said a voice beside him.
He looked up. A girl had come down the other path. Her face was red with exertion under the pale make-up, her hair hung over her eyes in ridiculous ringlets, and she wore a dress which, while clearly made for her size, was designed for someone who was ten years younger and keen on lace edging.
She was quite attractive, although this fact was not immediately apparent.
"And you know what they say when you complain?" she demanded. This was not really addressed to Victor. He was just a convenient pair of ears.
And that's a pain to read in Vim. So I tried to reformat it with gq and that gives me this
Funnily enough, that was exciting. "I've just about had enough of this,"
said a voice beside him. He looked up. A girl had come down the other path.
Her face was red with exertion under the pale make-up, her hair hung over
her eyes in ridiculous ringlets, and she wore a dress which, while clearly
made for her size, was designed for someone who was ten years younger and
keen on lace edging. She was quite attractive, although this fact was not
immediately apparent. "And you know what they say when you complain?" she
demanded. This was not really addressed to Victor. He was just a convenient
pair of ears.
which is rather useless, since the original line endings have special meaning in this case. What I'm trying to accomplish is this
Funnily enough, that was exciting.
"I've just about had enough of this," said a voice beside him.
He looked up. A girl had come down the other path. Her face was red with
exertion under the pale make-up, her hair hung over her eyes in ridiculous
ringlets, and she wore a dress which, while clearly made for her size, was
designed for someone who was ten years younger and keen on lace edging.
She was quite attractive, although this fact was not immediately apparent.
"And you know what they say when you complain?" she demanded. This was not
really addressed to Victor. He was just a convenient pair of ears.
i.e. to keep the original line endings, but to "break" every line longer than textwidth into several lines. So it fits the predefined column width limits.
Anyone have any ideas on how to do that? It is a rather large-ish document, and I need some way of handling it in one piece.
Select visually all lines then execute in ex mode:
:norm gqq
gqq reformats a single line. :norm with a range applies a normal code to each in individually in the range. That means you apply gqq on each single line individually. And because your textwidth is set to a certain length (for example 80) that means shorter lines will not be joined/wrapped.
I've tested this on your example text and it just gives what you want.
Btw, you can use vim's :formatprg to modify it with an external prg. That gives more control of what you want modify with an external application. For more info read :h formatprg
Do you just want to do this for reading purposes? If so, you should consider just turning on line wrapping at word breaks. In command mode:
:set wrap
:set linebreak
Assuming this is on Linux, there are a number of utilities to do what you're wanting - fmt, roff/nroff/troff and variants, etc. fmt is one I use often, but it would require that you have a blank line between each paragraph - that's easy to accomplish in vim, though. So you could add blank lines, save the file, then run it by fmt -76 for example to limit each line to 76 characters.
A primitive way, but in general managed to do it with
tw=80
qa (recording a macro)
Vgq
q (stop recording)
nmap <C-p> :execute "normal! #a"<cr>
and by holding <C-p> for quite a while. Not the most elegant of solutions but worked.
You can make gq think that a series of lines belongs to one paragraph if every line of the series except the last one ends with a space:
set formatoptions+=w
. After this setting gq won’t join lines in your example (unless you have trailing spaces there) and you will still be able to join them back using :%s/ \n/ /. Alternative is to add empty lines between each current line.
I also suggest doing
set list listchars+=trail:-
in order not to only make vim see where the paragraph ends, but to be able to see this by yourself (this setting will show you trailing whitespaces).

What are the most-used vim commands/keypresses?

I'm a Ruby programming trying to switch from Textmate to MacVim, and I'm having trouble wading through the gargantuan lists of things you can do in VIM and all of the keypresses for them. I'm tired of hearing "You can use 'I' for inserting text, or 'a' for appending text after the character, or 'A' for appending text at the end of the line, or…" I can't imagine everyone uses all 20 different keypresses to navigate text, 10 or so keys to start adding text, and 18 ways to visually select an inner block. Or do you!?
My ideal cheat sheet would be the 30-40 most-used keypresses or commands that everyone uses for writing code on a daily basis, along with the absolute essential plugins that rubyists use daily and the 10 most-used commands for them. In theory, once I have that and start becoming as proficient in VIM as I am in Textmate, then I can start learning the thousands of other VIM commands that will make me more efficient.
Or, am I learning VIM the wrong way altogether?
Here's a tip sheet I wrote up once, with the commands I actually use regularly:
References
vim documentation online
advanced vim tips
more useful tips and graphical cheat sheet
General
Nearly all commands can be preceded by a number for a repeat count. eg. 5dd delete 5 lines
<Esc> gets you out of any mode and back to command mode
Commands preceded by : are executed on the command line at the bottom of the screen
:help help with any command
Navigation
Cursor movement: ←h ↓j ↑k l→
By words:
w next word (by punctuation); W next word (by spaces)
b back word (by punctuation); B back word (by spaces)
e end word (by punctuation); E end word (by spaces)
By line:
0 start of line; ^ first non-whitespace
$ end of line
By paragraph:
{ previous blank line; } next blank line
By file:
gg start of file; G end of file
123G go to specific line number
By marker:
mx set mark x; 'x go to mark x
'. go to position of last edit
' ' go back to last point before jump
Scrolling:
^F forward full screen; ^B backward full screen
^D down half screen; ^U up half screen
^E scroll one line up; ^Y scroll one line down
zz centre cursor line
Editing
u undo; ^R redo
. repeat last editing command
Inserting
All insertion commands are terminated with <Esc> to return to command mode.
i insert text at cursor; I insert text at start of line
a append text after cursor; A append text after end of line
o open new line below; O open new line above
Changing
r replace single character; R replace multiple characters
s change single character
cw change word; C change to end of line; cc change whole line
c<motion> changes text in the direction of the motion
ci( change inside parentheses (see text object selection for more examples)
Deleting
x delete char
dw delete word; D delete to end of line; dd delete whole line
d<motion> deletes in the direction of the motion
Cut and paste
yy copy line into paste buffer; dd cut line into paste buffer
p paste buffer below cursor line; P paste buffer above cursor line
xp swap two characters (x to delete one character, then p to put it back after the cursor position)
Blocks
v visual block stream; V visual block line; ^V visual block column
most motion commands extend the block to the new cursor position
o moves the cursor to the other end of the block
d or x cut block into paste buffer
y copy block into paste buffer
> indent block; < unindent block
gv reselect last visual block
Global
:%s/foo/bar/g substitute all occurrences of "foo" to "bar"
% is a range that indicates every line in the file
/g is a flag that changes all occurrences on a line instead of just the first one
Searching
/ search forward; ? search backward
* search forward for word under cursor; # search backward for word under cursor
n next match in same direction; N next match in opposite direction
fx forward to next character x; Fx backward to previous character x
; move again to same character in same direction; , move again to same character in opposite direction
Files
:w write file to disk
:w name write file to disk as name
ZZ write file to disk and quit
:n edit a new file; :n! edit a new file without saving current changes
:q quit editing a file; :q! quit editing without saving changes
:e edit same file again (if changed outside vim)
:e . directory explorer
Windows
^Wn new window
^Wj down to next window; ^Wk up to previous window
^W_ maximise current window; ^W= make all windows equal size
^W+ increase window size; ^W- decrease window size
Source Navigation
% jump to matching parenthesis/bracket/brace, or language block if language module loaded
gd go to definition of local symbol under cursor; ^O return to previous position
^] jump to definition of global symbol (requires tags file); ^T return to previous position (arbitrary stack of positions maintained)
^N (in insert mode) automatic word completion
Show local changes
Vim has some features that make it easy to highlight lines that have been changed from a base version in source control. I have created a small vim script that makes this easy: http://github.com/ghewgill/vim-scmdiff
http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html
This is the greatest thing ever for learning VIM.
Here is a great cheat sheet for vim:
Have you run through Vim's built-in tutorial? If not, drop to the command-line and type vimtutor. It's a great way to learn the initial commands.
Vim has an incredible amount of flexibility and power and, if you're like most vim users, you'll learn a lot of new commands and forget old ones, then relearn them. The built-in help is good and worthy of periodic browsing to learn new stuff.
There are several good FAQs and cheatsheets for vim on the internet. I'd recommend searching for vim + faq and vim + cheatsheet. Cheat-Sheets.org#vim is a good source, as is Vim Tips wiki.
What most people do is start out with the bare basics, like maybe i, yw, yy, and p. You can continue to use arrow keys to move around, selecting text with the mouse, using the menus, etc. Then when something is slowing you down, you look up the faster way to do it, and gradually add more and more commands. You might learn one new command per day for a while, then it will trickle to one per week. You'll feel fairly productive in a month. After a year you will have a pretty solid repertoire, and after 2-3 years you won't even consciously think what your fingers are typing, and it will look weird if you have to spell it out for someone. I learned vi in 1993 and still pick up 2 or 3 new commands a year.
#Greg Hewgill's cheatsheet is very good. I started my switch from TextMate a few months ago. Now I'm as productive as I was with TM and constantly amazed by Vim's power.
Here is how I switched. Maybe it can be useful to you.
Grosso modo, I don't think it's a good idea to do a radical switch. Vim is very different and it's best to go progressively.
And to answer your subquestion, yes, I use all of iaIAoO everyday to enter insert mode. It certainly seems weird at first but you don't really think about it after a while.
Some commands incredibly useful for any programming related tasks:
r and R to replace characters
<C-a> and <C-x>to increase and decrease numbers
cit to change the content of an HTML tag, and its variants (cat, dit, dat, ci(, etc.)
<C-x><C-o> (mapped to ,,) for omnicompletion
visual block selection with <C-v>
and so on…
Once you are accustomed to the Vim way it becomes really hard to not hit o or x all the time when editing text in some other editor or textfield.
I can't imagine everyone uses all 20 different keypresses to navigate text, 10 or so keys to start adding text, and 18 ways to visually select an inner block. Or do you!?
I do.
In theory, once I have that and start becoming as proficient in VIM as I am in Textmate, then I can start learning the thousands of other VIM commands that will make me more efficient.
That's the right way to do it. Start with basic commands and then pick up ones that improve your productivity. I like following this blog for tips on how to improve my productivity with vim.
tuxfiles.org holds a pretty good cheat sheet. I think there are a couple of points to learning the commands:
Read the cheat sheet regularly. Don't worry about using all of them, or remembering all the keys, just know that the command exists. Look up the command and use it when you find yourself doing something repetitive.
If you find yourself doing something regularly (like deleting an entire line after a particular character d$), go a quick google search to see if you can find a command for it.
Write down commands you think you'll find useful and keep that list where you can see it while you're writing your code. I would argue against printing something out and instead encourage you to use post it notes for just a few commands at a time.
If possible, watch other programmers use vim, and ask them what commands they are using as you see them do something interesting.
Besides these tips, there are some basic concepts you should understand.
vim will use the same character to represent the same function. For example, to delete a line after a character use d$. To highlight a line after a particular character use v$. So notice that $ indicates you will be doing something to the end of the line from where your cursor currently is.
u is undo, and ctrl+r is redo.
putting a number in front of a command will execute it repeatedly. 3dd will delete the line your cursor is on and the two lines that follow, similarly 3yy will copy the line your cursor is on and the two lines that follow.
understand how to navigate through the buffers use :ls to list the buffers, and :bn, :bp to cycle through them.
read through the tutorial found in :help This is probably the best way to 'learn the ropes', and the rest of the commands you will learn through usage.
Go to Efficient Editing with vim and learn what you need to get started. Not everything on that page is essential starting off, so cherry pick what you want.
From there, use vim for everything. "hjkl", "y", and "p" will get you a long way, even if it's not the most efficient way. When you come up against a task for which you don't know the magic key to do it efficiently (or at all), and you find yourself doing it more than a few times, go look it up. Little by little it will become second nature.
I found vim daunting many moons ago (back when it didn't have the "m" on the end), but it only took about a week of steady use to get efficient. I still find it the quickest editor in which to get stuff done.
Put this in your .bashrc to open vim with last edited file at last edited line
alias vil="vim +\"'\"0"

Resources