Is there a way to have vim start line numbering at 0? - vim

I have added the set nu to my vimrc file, and I like it, but I would like to have vim start with line number 0 (it's to match the samples from a book I am using to learn C++).
I saw a suggestion to change set nu to set rnu, and at first it looked good, until I moved downward, and the 0 moved with my cursor. I understand what's going on here - it's displaying a 0 for my current position, and the lines above and below are renumbered relative to where 0 is. While cool, this is not what I want.
Thanks in advance!
Shane

This is not possible without patching the source.
Note that, in Vim, line numbers can be used in many more ways than in "regular" editors so changing how the line numbers are displayed will have a non-negligible impact in other areas. This doesn't seem like a very good idea.

Related

Any way to add additional space after line number in Vim?

I am looking for a way to move text further from the line number in Vim. Default settings are to add one space after the line number when using set number. I would like to add a bit more. Using set numberwidth=n doesn't help, because additional space goes before the line number, not in between the line number and the text itself.
No native Vim option seems to alter this, but there is an old plugin which could accomplish what you want to achieve called vimroom. It is not actively being maintained and I don't know if it still works with current Vim versions. But this screenshot makes it look like it is possible to have the line numbers way on the left.
Hopefully this pointer helps you out!

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.

Long-line handling from Nano in 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 :-)

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

Dynamic vim font size based on file length

I want vim (MacVim) to default to a large font for new/short files and dynamically scale down to a smaller font (to a set minimum) as the number of lines grows. Is this possible to do with a plugin? What vim concepts will I need to know to write that plugin?
My reason for wanting this is that I love writing code in a large font, but after files get longer I'd rather squint a little than scroll.
That's an interesting idea. Not sure if I'd use it :-) — but it's certainly an interesting idea.
You don't need to write a complete plugin, as all it needs to do is to perform some math. More specifically, a rough formula would be:
Where the desired size (S) depends on the current document number of lines (n), a constant determining what is considered a big file (k, in lines), the desired amplitude (a) — meaning how much will the size vary — and a minimum font size (m).
Now that we know that, it's just a matter of implementing it. Quick notes:
To get n we can call the line() function passing "$" as argument
To set the font size, after we have the number we can build a string and execute it with exec
With that in mind, a quick function quite descriptive could be written as:
function! DetermineFontSize()
let bigFile = 200
let nLines = line("$")
let rate = (nLines > bigFile) ? 0 : (1-nLines/(bigFile*1.0))
exec "set guifont=Menlo:h".float2nr(ceil((rate*5)+11))
endfunction
I'm sure that other Vim masters can improve this a lot. Anyway, a quick explanation:
Set up what we call big file. I've chossen 200 lines for debugging purposes, you probably want a bigger number.
Get the number of lines in the current file.
Do the parenthesis in the previous formula. Note that there is a conditional involved (if you noticed I missed that in the formula, congratulations!). If we have more lines than the maximum constant, 0 is returned. Otherwise, we'd have a negative number — plus calculating something that's obvious.
In the fourth line we build the string to be executed while completing the formula. I choose to hardcode the values for a and m here, since they are used only once and it's easy to modify them. Here a is 5 and m is 11, meaning the font will vary between 11 and 16. The syntax I used here to set the font is valid for Mac. If another reader uses another system you may want to change it accordingly.
Put that in your .vimrc or source it from other file and you'll be ready to test it. On a file with one line, the font is set to 16. If there are 39 lines, also size 16 but size 15 if there are 40. Size goes to 14 when there are 80 lines and so on.
You probably want to call this automatically, so create an auto command as well.
autocmd BufEnter * call DetermineFontSize()
This will work only when you enter a buffer, as the name says. You could change that to include InsertLeave or something like, but keep in mind this will generate more calls to the function. Should not be a performance problem though.
Check :h autocommand-events and build the autocmd as you like.
Update
As ZyX pointed out in the comments, the last line from the function could be written as:
let &guifont='Menlo:h'.float2nr(ceil((rate*5)+11))
vim executes in a terminal. Font size is terminal dependant, so what you ask may be impossible unless your vim ask directly the terminal to change font size... which may be difficult to do.

Resources