Why does MacVim show `#` and blank space for long strings? - vim

This drives me really insane...
Say I have a short line of text on line 32, and a very long string on line 33, say 10,000 characters long... if I have word-wrap on, it ONLY shows line 32 and stops there, and instead of displaying 33+ it just displays # in the first column and all the rest is whitespace.
I have to move the cursor all the way to the very bottom and then the entire string appears at once.
This is extremely jarring because if you 'overshoot' when scrolling, it immediately disappears again.
I want it to behave sanely... where nothing jumps in or out of the screen all at once. It should just flow along like normal with all the other line numbers, and always be visible.

The answer was I needed to add this:
" show as much of long lines as possible
:set display+=lastline

Related

Python '\r' print on the same line but won't erase the previous text

I am trying to print the report for each iteration. Since each iteration takes a really long time to run, therefore, I use print together with end="\r" to show the current item being processed.
Here's the dummy code:
import time
y = list(range(50))
print("epoch\ttrain loss\ttest loss\ttrain avg\ttest avg\ttime\tutime")
for e in range(10):
for i in range(50):
print("training {}/{} batches".format(i,50), end = '\r')
time.sleep(0.05)
print('{}\t{:2f}\t{:2f}\t{:2f}\t{:2f}\t{:2.1f}\t{:2.1f}'.format(y[0]+e,y[1]+e,y[2]+e,y[3]+e,y[4]+e,y[5]+e,y[6]+e))
Expected Result
This is my expected result, where the progress information is completely erased after each iteration. (I am running it in Jupyter notebook, and it looks fine)
The Result that I am getting
However, when I run it on linux terminal, the progress information is not completely erased, and the result is overlaying on top of the progress.
Why is it so? How to solve it?
\r simply moves the cursor back to the beginning of the current line. Anything printed after the \r is printed "on top of" the content previously there. On a real printer/teletype this would be literally true, with two characters getting printed in the same position ("overstruck"). On a terminal, the new characters replace the old ones (but only in positions that you actually write to).
You can take advantage of this behavior of terminals by printing spaces. You need at least as many spaces as the content you want to erase, but not enough to make the terminal wrap to the next line (this may be impossible if the line was printed all the way to the last character).
In your case, you know that the line won't be more than 22 characters long, so you could use end='\r \r' (go back to the beginning of the line, print 22 blanks, then go back to the beginning of the line again).
\r option will set (move) the cursor to start. It will not clear the text.
You have to make sure your printed data has enough space to overwrite the previous printed data or be of the same length since just moving to the same line would not automatically clear the previous contents.

What exactly does IDWriteTextFormat1::SetLastLineWrapping do?

Documentation for IDWriteTextFormat1::SetLastLineWrapping() is insufficient:
Sets the wrapping mode of the last line. If [the single BOOL parameter is] set to FALSE, the last line is not wrapped. If set to TRUE, the last line is wrapped.
For IDWriteTextLayout2::SetLastLineWrapping() it is equally terse:
Set whether or not the last word on the last line is wrapped.
Some details lacking that I want to know:
Which one is the last line? In my tests, sometimes it is the last visible line that gets the extra word, but sometimes it is the next one, and then more lines follow. (Is it a bug in DirectWrite? In my code?) Here "visible" means (for horizontal lines, in the vertical direction) completely inside the layout rectangle.
How does it interact with IDWriteTextFormat::SetTrimming()? Some tests suggest that behaviour is different when trimming is set. (With SetTrimming(&DWRITE_TRIMMING{DWRITE_TRIMMING_GRANULARITY_CHARACTER,0,0}, nullptr);.)
It was intended for rectangular tiles where the last word of the application name would otherwise be hidden because it got wrapped to the next line. By default, this would yield:
"here is an example of a long application name" ->
<----------->.
here is an /|\
example of a |
long \|/
application
name
So if the tile height was short (say only 3 lines), then only none of the word "application" would be visible, but it's more useful to also show at least part of the next word.
<----------->.
here is an /|\
example of a |
long applica\|/
name
In conjunction with ellipsis character trimming, it looks like:
It always means the last visible line whether trimming is enabled or not, but when trimming is enabled, any partial lines are trimmed out, making the last "visible" the last untrimmed line. So that's the difference you're seeing.

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.

How to know in VI which line the cursor is on?

I want to copy paste some lines in vi.
I have a text like
python class1 def:
code code code
...
code code code
last line class1
python class2 def:
code code code
...
code code code
I want to copy the whole class1. I was trying to do it with yNy, so I needed to get N, that is, to count the number of lines the class has.
Then I thought it would be good to get the line number of python class1 def: (let's say X) and the last line class1 (Y), calculate N=Y-X, go to the first line of the class and do the yNy. However, I could not figure out how I can get the line numbers.
So, is there any way to know which line I am in? And in general, is there any other way to copy paste a whole block like the one I indicated?
This is my vi version:
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:44:45)
Included patches: 1-547
The current line number can be obtained by :.=. Ctrl-g gives more details including filename, column information, ...
In order to copy a block, go to the start of the line to be copied 0. Hitting v would start the visual mode. Navigate to the last line to be copied. Yank y. (Visual selection is now in buffer.)
Using only normal mode commands:
You can do y} to yank everything from the current line to and including the next empty line, delimiting what Vim considers to be a "paragraph". This may or may not work depending on your coding style.
Still using the notion of "paragraph", you can do yip or yap from anywhere in a "paragraph".
You can set the number option which allows you to see absolute line numbers and therefore be able to do y10G, "yank everything from here to line 10".
You can set the relativenumber option which allows you to see relative line numbers and therefore be able to do y5j, "yank everything from here to 5 lines below".
You can do V/foo<CR>y to yank everything from here to foo linewise.
More generally, you can simply use visual mode to select what you want and yank it.
You can also set a mark on the first line of the class with ma, move the cursor to its last line and do y'a (which sounds like the name of a Lovecraftian deity).
Using Ex commands:
Because the aforementioned number option shows absolute line numbers, you can see that the class ends at line 10 and do :.,10y.
Because the aforementioned relativenumber option shows relative line numbers, you can see that the class ends 5 line below and do :,+5y (dropping the implied .).
Using your statusline (or not):
You can :set ruler to have the current line number displayed on the right side of your statusbar if you have one or on the right side of your command line if you don't have a statusline.
Using Vimscript:
You can use line('.') to retrieve the number of the current line.
Using custom text-objects:
There are a number of custom text-objects available on vim.org for indented blocks, function arguments and many other things. Maybe there is one for Python classes.
More generally, I'd advise you to set either ruler, number or relativenumber permanently in your ~/.vimrc and get used to it.
ruler is the least invasive of the bunch but it's also the most limited: you know where you are but it doesn't help at all when you want to define a target.
number is the most classical and can be used to easily target a specific line.
relativenumber is a bit weird at first and, like number, can be used easily to target a specific line.
Choosing number or relativenumber is, as far as I'm concerned, a matter of taste. I find relativenumber very intuitive, YMMV.
Try the following in command mode
:.= returns line number of current line at bottom of screen
yNy or Nyy copies the next N lines, including the current line
p pastes the copied text after the current line
Additionally,
:set nu! in command mode will turn on/off the line number at the beginning of each line.
let the vim registers do this task. why bother calculating lines
for example if you want to copy line X to line y
1) move your cursor to 1st character of line X.
2) type "ma" . this will save current cursor position in register "a".
3) move cursor to last char of line Y.
4) type "y`a". copy is done
5) p pastes the copied text
This method can work not only lines but block ,words even on characters.

gvim What do the # symbols mean at the bottom left of the screen?

I've been getting used to using vim for the last two weeks and am really starting to like it. There's one thing I've been wondering about - sometimes when I'm typing something, these rows with nothing but the # symbol appear at the bottom of the screen:
This has happened a couple of times but I've never paid much attention to it, but I'm curious - like in that situation, pressing enter gets rid of one of them, and pressing enter again gets rid of the other. Then another two enters after that, another # row appears. Does anyone know what they mean?
this usually happens when you open a very big file (or very long lines).
You can set display option to show all lines. (without showing those #).
lastline When included, as much as possible of the last line
in a window will be displayed. When not included, a
last line that doesn't fit is replaced with "#" lines.
e.g. in my vimrc, I have set display=lastline
if you want to know detail about it, check :h 'display'
This means you have a line larger than your terminal's height and width.

Resources