get the current statusline from buffer - vim

I have a plugin that has some functionality that adds some string to the statusline. I have a series of functional tests that verify that certain actions produce some output, and would like to verify that, if set, the statusline will change after some trigger.
I haven't been able to find something that will allow me to capture (dump?) the rendered contents of the statusline. Both the :help statusline and :help status-line didn't hint to anything that might allow this.
Is there a way to actually do this?

You're looking for :help screenchar(). With it, you can capture any visible screen cell controlled by Vim (including status lines), and it's main purpose is testing. Its use is a bit clumsy, because you have to query each position individually, and have to explicitly convert back to characters / strings. For example, if the statusline is the second-to-last line, this will get it's first character:
:echo nr2char(screenchar(&lines-1, 1))
And this will obtain the entire statusline (assuming you don't have any vertical window splits):
:echo join(map(range(1, &columns), 'nr2char(screenchar(&lines-1, v:val))'), '')

Related

how to autocomplete options in vim command mode

my setting for command mode completion is:
set wildmenu
set wildmode=longest,list,full
currently when i type
:set fdm=
in command mode, then press tab, manual appended, if i Press tab again , character ^I appended, what i want is manual changed to another foldmethod options such as syntax, indent and so on.
does anyone know is that possible or if there is any plugin could do that ?
thanks !
As you say, when you press <Tab> after :set fdm=, you get manualinserted.
That could seem the usual autocomplete behaviour we are used to in many places, manual being just the first of all possible values. So, you expect that repeating <Tab> will give you more possibilites.
But that's not indeed the case. What you get when pressing <Tab> in such a situation is not the first autocompletion alternative, but the current option value. So, you're getting manual because that's in fact the default value for that option. Successive <Tab>s get inserted literally, as this behaviour is only fired right after =.
From Vim's help:
The old value of an option can be obtained by hitting 'wildchar' just after
the '='. For example, typing 'wildchar' after ":set dir=" will insert the
current value of 'dir'. This overrules file name completion for the options
that take a file name.
So, what you described is expected behaviour. See :help cmdline-completion for the whole story.
I don't know about any plugin capable of changing this to what you want.

Display some special character as a linebreak in Vim

I would like to display some (arbitrary) special character as linebreak <CR> in vim.
So far I tried misusing (certainly extreme misuse:) the non-breakable space typing
:set list listchars=nbsp:<CR>
which does not work, seemingly because the command does not accept the <CR>.
Is there anything which I can use here for <CR>? \r didn't work either.
Note that I don't want to edit the text file. The goal is to have blocks of lines (some related code) treated as a single line with respect to vim actions but displayed as multiple lines. The special character (to be defined) would be used only to save this block structure in the file replacing the linebreak \r in these cases.
Given the wider context of the problem that you have provided in a
later comment, I would suggest the following solution. Group dependent
lines of code in folds by indentation, language’s syntax, or markers.
All of these three methods are automatic and do not require manual
creation of folds. Which one to choose depends on the language you
use. See :help foldmethod, and feel free to comment this answer if
you need any help with folding.
Unless the syntax of the language you use has extensive support in
Vim, the most convenient methods would be using fold markers or
defining a custom expression to calculate fold level of each line.
The former method implies surrounding every group of lines to fold
with special text markers (which could be enclosed in a comment not
to break the syntax rules of the language). By default, those markers
are {{{ and }}}; see :help fold-marker and :help foldmarker
to find out how to change them. Use
:set foldmethod=marker
to enable this mode of folding.
Defining an expression to calculate fold level for every line is an
even more flexible method. It allows to use any logic (that can be
expressed in Vimscript) to determine the fold level. For example, to
fold groups of lines that start with a single space use the following
settings:
:set foldmethod=expr
:set foldexpr=getline(v:lnum)[0]=='\ '
See :help fold-expr for further details on customizing the fold
expression.
When the lines that depend on each other are grouped into folds, you
can easily pass the contents of any particular fold to a filter
program. Move the cursor to a line inside a target fold, then type
[zV]z to select the entire fold, followed by !, and enter the
command to run. To save typing, you can define the mapping
:nnoremap <leader>z [zV]z!
If the command is always the same, you can include it in the mapping:
:nnoremap <leader>z [zV]z!cat -n<cr>
Substitute the cat -n portion above—my example command—with the
appropriate command in your case.
I think you might want check out this vimcasts episode. May not be exactly what you want, but could get you there. Good luck!
My solution, in the end, was to insert non-breaking spaces and linebreaks in the respective places in the file. :set list listchars=nbsp:$ can then be used to display these 'special linebreaks'. Their presence allows interpreting code to identify the blocks of lines separated by this combination as related lines.
Of course this doesn't answer the question. The answer, according to my best knowledge now, is that neither :set list nor :wrap can be used to achieve this.

Is it possible to display page feed symbols differently in Vim?

One of the nice things about Vim is that one can insert a page feed symbol (Ctrl-L in Insert mode), which delegates the printer to start printing the following on a new page. It shows as ^L in text.
Is it possible to make this symbol show as something else, for example as
----------------- new page here -----------------
so it is somewhat more visible while scrolling through pages of text?
That is, without rebuilding Vim from source.
If you do not use folding extensively when editing those files
containing page feed symbols, you can use one-line folds to mark
them out.
Using the foldexpr option, it is possible to increase the fold level
of the lines that contain page feed symbol. (Herein, for the sake of
efficiency of evaluating foldexpr, I assume that page feed symbols
are always the first characters on their lines.) To achieve the
desired effect of a screen-wide separator, these folds can be made
auto-closable.
The following function configures folding according to the idea
described above. Call it (manually or by means of an autocommand)
to enable page feed symbol folding in the current buffer.
function! FoldPageFeed()
setl foldmethod=expr
setl foldexpr=getline(v:lnum)[0]==\"\\<c-l>\"
setl foldminlines=0
setl foldtext='---\ new\ page\ '
setl foldlevel=0
set foldclose=all
endfunction
Resulting separators appear as the text --- new page followed by
a continuing string of filling characters to the right of the window
(see :help fillchars, under the fold: item).
I don't think you can. There is a non-text highlight group which could help.
Another way (a bit ugly) would be to write some autocommand to expand ^L to ---- new page ---- and vice versa when on InsertLeave, BufRead and BufSave.
Anyway, the answer of your question is no, if you just want to change the display, and probably yes with a nasty plugin.
If it could, I would be uncomfortable knowing that Vim, my heavily trusted tool and friend, could misrepresent a text file.
Of course, you could always execute this command (perhaps as a macro) to do the same thing:
:%s/^L/----------------- new page here -----------------/
If you defined your own highlight group in Vim to be just the ^L symbol, then you could have a custom highlighted background for all lines that contain that character.
It’s not quite a ---- new page here ----, but it would make page breaks easily visible when scrolling through large amounts of text.
I don’t know enough Vim to actually tell you how to set the highlight group though…

Is it possible to not display a ~ for blank lines in Vim/Neovim?

Is it possible to not display a ~ for blank lines in Vim?
This confuses Mac Vim's scrollbar, and I quite don't like these tildes.
:hi NonText guifg=bg
That command should set the color of non text characters to be the same as the background color.
Vim 8.x:
You can now change the color just for the end of the buffer ~:
highlight EndOfBuffer ctermfg=black ctermbg=black
See changelog for Vim 8.x.
As jamessan said, you can’t disable them. The scrolling behavior isn’t specific to MacVim, either — it works the same way in the terminal and in gvim:
Instead of seeing this as a problem, what you should do is learn to see this as part of Vim’s flexibility. For example, you can use the zt command to scroll the current line to the top of the screen, regardless of where in the file it is. This can make it easier to write macros that do some work and then scroll back to where you were. The commands <C-E> and <C-Y> are made simpler because of this, as is the 'scrolloffset' option.
If you must, retrain your brain to think of Vim’s scrollbar as mapping to which line is on top, instead of which screenful is visible.
For NeoVim, you can set the fillchars value for eob to a space character and that will effectively hide it. (This might not work for plain Vim).
In Lua (Nvim 0.5+):
vim.wo.fillchars='eob: '
In VimScript:
set fillchars=eob:\
Note: Calling the above will override your fillchars value for other items as well (if set), so use this as a reference to set multiple values together:
set fillchars=eob:\ ,fold:\ ,vert:\│
Or use set fillchars+=... to append it your existing values.
You can't disable them, but you can change your colorscheme such that the NonText highlight group is colored the same as the Normal highlight group. However, this affects more than just the end of document tildes.
I doubt that it's actually "confusing" MacVim's scrollbar and if it is, then that's a bug in the patching that MacVim does.
The tilde ~ characters are meant to remind the user that those lines are not part of buffer content.
The above highlight trick will hide the ~ character, but it is still there. For some terminals, this may not even work. If you happen to be a Neovim user, you can use fillchars option to change the end of buffer symbol like this:
set fillchars=fold:\ ,vert:\│,eob:\ ,msgsep:‾
This will use space instead of ~ for end of buffer, effectively hiding the annoying ~.
You may also be interested in discussions here.

How do I make vim syntax highlight a whole line?

I'd like to have vim highlight entire lines that match certain patterns. I can get all the text in a line to highlight (by doing syn match MyMatch "^.*text-to-match.*$"), but it always stops at the end of the text. I'd like to to continue to the end of the term, like highlighting CursorLine.
I've tried replacing $ with a \n^, hoping that would wrap it around. No change. (I didn't actually expect this would work, but there's no harm in trying.) I also tried adjusting the syn-pattern-offset (which I read about here: http://vimdoc.sourceforge.net/htmldoc/syntax.html#:syn-pattern). Long story short, adding he=he-5 will highlight 5 fewer characters, but he=he+5 doesn't show any extra characters because there aren't characters to highlight.
This is my first attempt at making a vim syntax and I'm relatively new to vim. Please be gentle and include explanations.
Thanks!
(edit: Forgot to include, this is a multiline highlight. That probably increases the complexity a bit.)
It's not very adaptive as the filename (buffer) and line to full row highlight needs to be explicitly identified, but apparently the sign command can be used:
It is possible to highlight an entire
line using the :sign mechanism.
An example can be found at :help
sign-commands
In a nutshell:
:sign define wholeline linehl=ErrorMsg
:sign place 1 name=wholeline line=123 file=thisfile.txt
Obviously, you should pick a higlight
group that changes the color of the
background for the linehl argument.
source: Erik Falor, vim mailing list
From the documentation on syn-pattern:
The highlighted area will never be
outside of the matched text.
I'd count myself surprised if you got this to work, but then again, Vim is always full of surprises.
could also try
:set cursorline
:set cursorcolumn
change colors like this:
:hi cursorline
:hi cursorcolumn
using the usual term=, ctermfg=, ctermbg= etc
see this answer
VIM Highlight the whole current line

Resources