Display or highlight invisible zero width characters in (neo)vim - vim

How can I display zero width characters in (neo)vim? For example take this line:
This is ㅤsome textㅤ
... which actually has a zero width character before some:
This is \u3164some textㅤ
When I copy and paste the first line into my vim editor it is not displayed:
(It actually messes up the cursor, too: character count seems to be wrong and color column is offset.)
How can I make such zero width characters visible in (neo)vim? Is this possible?
It think it would be enough to display it as a question mark or maybe as ☒ or something, so it should actually not be zero width but be single width.
Update 11.11.2021:
I'm using NVIM v0.5.1 on MacOS 12.0.1 and iTerm2 as a terminal emulator.

Related

How to fix problem with tabstop configuration in ~/. vimrc

I set tab configuration in ~/.vimrc as below:
set ts=4 sts=4 sw=4
I notice that if the word is 4 characters long or above, the cursor shift into right 4 spaces as in configuration for tabstop.
But if the word is less than 4 characters long, it didn't shift into 4 spaces.
Example:
'name' + <Tab>: tab produced correct number of spaces (i.e 4 spaces)
'age' + <Tab>: tab produced wrong number of spaces (i.e 1 space only)
Why is it ?
Does the word length effect tab?
What can I do if I want to shift the cursor to 4 spaces as configured regardless of the word length?
Thanks a lot
You’re probably inserting regular tabs, which display variable-width according to what’s before and after. I find having set list on is really handy for this (though you probably won’t like the default listchars settings).
If you really want spaces (which I find better anyway, set expandtab.
Also, most long-time users recommend leaving tabstop at 8, since you can’t control how wide every one’s tabs are.
The way that the tabstop, shiftwidth, and softtabstop options work is that they control indentation to certain points that are commonly referred to as "tab stops". In other words, they're designed to always indent to a column that's a multiple of the setting.
So if your tab stops are at multiples of 4, then hitting the Tab key will cause the cursor to indent to a column that is the next multiple of 4. This is the behavior of inserting a literal tab (U+0009, CHARACTER TABULATION) into a document and then rendering it on a normal terminal (except that the width is usually 8 there). This results in text that is aligned at fixed columns, which is the desired style for most programming languages and text markup formats.
As you've noted, this does result in different amounts of indent if the words are different lengths. Typically in code, we would just cause the second column to be at the next tab stop and not care that the indents are of different lengths. That is, in your example, we'd hit Tab once on the first line and twice on the second, and start the next column at column 8.
I'm not aware of any way to force Vim to insert a specific number of spaces other than the standard editing commands. Normally users who are in this situation just hit Space four times if they really want four spaces and not an indentation to the next tab stop. You can of course create a mapping if you need to do that a lot.

Vim hides lines that are too long to be displayed completely

Editing a document where I didn't bother to make line breaks, I noticed that Vim (MacVim 8.0 to be precise), instead of just showing that part of the line that fits, completely hides lines of text that are too long to fit on the current screen. The space that would be occupied by the part of the line that does fit is simply left blank, as if the characters had become invisible.
Is there a way to change that behaviour?
If I understand your problem correctly, setting :set display=lastline will help.
Change the way text is displayed. This is comma separated list of
flags:
lastline When included, as much as possible of the last line
in a window will be displayed. "###" is put in the
last columns of the last screen line to indicate the
rest of the line is not displayed.
truncate Like "lastline", but "###" is displayed in the first
column of the last screen line. Overrules "lastline".
uhex Show unprintable characters hexadecimal as <xx>
instead of using ^C and ~C.
When neither "lastline" nor "truncate" is included, a last line that
doesn't fit is replaced with "#" lines.
You can also try :set nowrap.

How can a paragraph be changed to wrap at a column greater than that at which it currently wraps?

I've got many paragraphs of the following form (shown in the Geany text editor):
The text wraps at column 48 currently. I want it to wrap at column 80. On the right is shown a vertical line indicating column 80.
How can this text (which is actually a small selection of a great deal of text) be selected and reformatted such that it wraps at column 80 (preferably preserving the leading whitespace of 8 spaces — though this is not particularly important). I am happy to see solutions in Geany, Vim or Emacs.
vim file.txt
type :set textwidth=72
type V to start highlighting
type G to go to the bottom of the file
type gq to break the line at 72 character
type g to go back to the top
type V to start highlighting
type G to go the bottom
type > to indent the text
repeat 5-8 until indented properly

Highlight multiple positions in VIM independant of the content of the buffer

I would like to highlight certain positions in VIM. The solution should work for empty files.
Ideally, the command should work like this (The form is just to get the idea across):
set colorposition=((12,12),(14,12)), ((1,1),(1,1))
This command would, in this case, highlight (line 12, column 12) to (line 14, column 12), as well as the first position at (line 1, column 1).
One possible solution I found is using the command match.
It works like this:
let us say we would like to color the position in (column 3, line 4). We can use a certain highlight group and the command match:
highlight highlightgroup ctermbg=darkred
match highlightgroup /\%3c\%4l/
Multiple positions can be chained together using the operator \|. Highlighting position 3,4 and 1,1 would be:
match highlightgroup /\%3c\%4l\|\%1c\%1l/
The caveat is that one can only highlight positions inside the existing buffer. If one wants to highlight something at a specific position, where no text exists, the command match will not work.
A related option is available since Vim 7.3. To set the color for a whole column, e.g. 80, one can use colorcolumn.
The command colorcolumn is indifferent to the text in the buffer and works even for empty files, but it only colorizes whole columns, e.g.
set colorcolumn=80
Edit
To clarify what my goals are and to address what has been mentioned by Ingo in the answer section:
I work a lot with Fortran 77. Sometimes fixed form source code can become difficult to handle, if a certain number of IF THEN, ELSE, DO, END DO sections are used. I would like to introduce markings for every level, let's say beginning in the 81st column.
SUBROUTINE SUB(I,J)
C THE COLORCOLUMN IS VISIBLE AT C C
C=0
IF(I .GT. 0) THEN VISUAL_MARK1
IF(J. LT. 1) THEN VISUAL_MARK2
C=2
END IF VISUAL_MARK2
END IF VISUAL_MARK1
WRITE(*,*) I,J,C
END SUBROUTINE
Why would you highlight cells where no text exists?
Because Vim is a text editor, that's not supported. As you've found out, :match only highlights matching, i.e. existing text. The 'colorcolumn' is an aid for not exceeding a certain width, and as such is visible in all lines. :set virtualedit=all allows to you address non-existing positions with the cursor, but that doesn't highlight anything. The only ugly workaround I can think of is adding actual whitespace to the buffer to match those positions (and then removing them on :write).

Limiting text width does not work as expected if not inserting at the end of a line

I know we can use :set tw=80 to limit the text width. However, if we insert text before the end, this function doesn't work at all.
For example, let's say we type "Would you like to have responses to your questions sent to you via email?"
If we continue to input after "?", tw works fine. But if we insert before say "have", it doesn't break off the line even if it exceeds the specified text width.
Is there any way to make this work in the latter case?
You may try
:set fo+=a
which reformats your paragraph as you type.
See :h fo-table.
This might be configurable using formatoptions or formatexpr, but I'm not sure how.
Another solution is to manually format using gq on a visual line selection i.e. add a breakline if the text width is >= tw.
Type in whatever text you like inside another block of text, thus making it 80 chars or more in width
Select the text you think is misformatted using V (Shiftv)
gq
From :h gq:
Format the lines that {motion} moves over.
Formatting is done with one of three methods:
1. If 'formatexpr' is not empty the expression is
evaluated. This can differ for each buffer.
2. If 'formatprg' is not empty an external program
is used.
3. Otherwise formatting is done internally.
In the third case the 'textwidth' option controls the
length of each formatted line (see below).
If the 'textwidth' option is 0, the formatted line
length is the screen width (with a maximum width of
79).
The 'formatoptions' option controls the type of
formatting fo-table.
[..]
For more information on how Vim's textwidth works, take a look at
How to use Vim’s textwidth like a pro

Resources