Display the current status of `expandtab` in statusline in macvim - vim

I am currently using vim-airline in my macvim and I want to display the status of expandtab whether it is set or not in the statusline.
I can find out the status of expandtab by running the following command :set expandtab?. From the vim-airline documentation I found that I can use something like this
let g:airline_section_b = '%{getcwd()}'
I modified it to
let g:airline_section_b = '%{expandtab?}'
but I am getting the error undefined variable: expandtab.
Can someone kindly tell how I can retrieve the status of expandtab and then show it in the status line. Thanks.

:set does not access variables, so you cannot use the question mark to query variables.
You are trying to access the variable expandtab variable, which doesn't exists. You actually want to access an option setting and those are accessed using the & prefix.
Sou you should add:
let g:airline_section_b = '%{&expandtab}'
Note, the quesion mark is not necessary and has no special meaning for VimL.
See :h expr-option for the details.
Update
This will only display 1 (expandtab set) or 0 (expandtab not set). What should work however is something like this:
let g:airline_section_b = '%{&expandtab?"et":"noet"}'
Which will display 'et' when expandtab is set or 'noet' when expandtab is not set. This uses the <cond>?<true>:<false> expression to display a certain string depening on the value of the <cond> condition. This is explained in the help below :h expr1

Vim options can be accessed live variables if prefixed with &. Example:
let g:airline_section_b = '%{&expandtab}'
See :h :let-& for more

Related

How to hide Foldcolumn in Vim?

I tried to hide a foldcolumn in VIM via .vimrc :
set foldcolumn=0
but it doesn't work. It always appears as an extra column.
Commenting "set foldcolumn=0" didn't work too.
As a buffer-local option, 'foldcolumn' is probably set by a filetype plugin, especially because its global default value is 0.
When the fold column appears, find out where it got set via :verbose setlocal foldcolumn?. Then, e.g. when it was set by ftplugin/cpp.vim, you can put the following into ~/.vim/after/ftplugin/cpp.vim:
:setlocal foldcolumn=0
The after directory allows to override filetype-specific settings without modifying the original script.
For me some automatic folding options were done by the vim-pandoc plugin. Ingo's tip tip worked good when I created the file ~/.vim/after/ftplugin/pandoc.vim with his recommendations; however, the plugin reloaded at times and its folding settings returned. With the vim-pandoc plugin its own settings have to be used. I set the column width to 0 and opted to do folding on my own:
: let g:pandoc#folding#mode = ['manual']
: let g:pandoc#folding#fdc = 0

Vim Statusline - Virtualenv Function

I have just add virtualenv to vim. I want to have the active virtualenv show in the statusline so I know which environment I am in.
From Virtualenv help
g:virtualenv_stl_format
Format string for the statusline
Example:
let g:virtualenv_stl_format = '[%n]'
To sue the statusline flag, this must appear in your 'statusline' setting
%{virtualenv#statusline()}
So I went searching for the statusline and found
writing a valid statusline
They are going way beyond what I am trying to do and I really don't understand. I just want to simply add %{virtualenv#statusline()} to whatever line it is I have now, how do I do that?
The plugin I am referencing is this one https://github.com/jmcantrell/vim-virtualenv#readme
In its simplest form, your statusline could be reduced to this line in your ~/.vimrc (note the =):
set statusline=%{virtualenv#statusline()}
If you want that information to be displayed at the end of your current statusline, paste the following line in your ~/.vimrc (note the +=):
set statusline+=%{virtualenv#statusline()}
Or to place it at the beginning (note the ^=):
set statusline^=%{virtualenv#statusline()}
If you want to place this information at some arbitrary position in your custom statusline, you'll simply need to edit the corresponding line(s) in your ~/.vimrc. But you already know how to do that since you already have a custom statusline, do you?
If you use the default statusline, you'll need to replicate it as per the example given in :help statusline:
set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
and place the virtualenv snippet at the desired location, say after the status flags:
set statusline=%<%f\ %h%m%r%{virtualenv#statusline()}%=%-14.(%l,%c%V%)\ %P
But all that is clearly explained in :help statusline.

Vim: What's the difference between let and set?

What's the difference between let and set in the vim editor?
I've always wondered why both of them exist?
Also, I'd be interested to hear its historical background.
:set is for setting options, :let for assigning a value to a variable.
It happens that the value for an option is linked to the name of the option prepended by a & (the &option-name construct then behaves very similar to "ordinary" variables). So, the following are equivalent:
:set tw=40
:let &tw=40
But, for example, assigning 50 to the global variable foo (:let g:foo=50) cannot be achieved with a :set command (because g:foo is a variable and not an option).
Some options are boolean like. When setting these, no value is needed (as in :set noic and the opposite :set ic).
Set is a more user-friendly interface specialized for options
E.g.
:verbose set
to display all options in effect.
:set tw=40
Will work as a shorthand for set textwidth=40
:set wrap&
Will set the default value for option wrap
:set nowrap
Will unset the option
:set wrap!
Will toggle the option
Most importantly,
:setTab # to get tab completion!
Few of the above can (easily) be achieved with let.
:set only works with options, and sehe's answer showcases some good usage examples.
:let on the other hand can do almost everything that :set can do, plus more. It can assign a value to
a variable, e.g. let vi = 'vim'
an option, e.g. let &tw = 40
a register, e.g. let #a = $HOME . '/vimfiles'
an environment variable, e.g. let $NOTHING = 'NOTHING'
Another major difference is that the right hand side of :let is an expression, meaning you can do things like string concatenation (as seen in my register example above) and arithmetic operations (e.g. let &tw = 40 + 60). This also means that you have to quote the value if it's a string. :set on the other hand reads the value verbatim.
It's easier to use :set with options even though :let can also do most of it, Here are some comparison using sehe's examples ("n/a" means no way to do it with :let)
:verbose set vs n/a (don't think there's another way to list all options)
:set tw=40 vs :let &tw = 40 (yes, you can use the same shorthand in let too)
:set wrap& vs n/a
:set nowrap vs :let &wrap = 0 (for boolean options, 0 is false and 1 is true)
:set wrap! vs :let &wrap = !&wrap
A few more examples
print the value of an option: :set formatoptions? vs :echo &formatoptions (let doesn't print values, unlike set)
assigning to multiple options at the same time:
:set et sw=4 sts=4
vs
:let [&et, &sw, &sts] = [0, 4, 4]
set global option: setglobal et vs let &g:et = 1
set local option: setlocal et vs let &l:et = 1
See :h :set and :h :let for more details
tl;dr
:set only works with options but the syntax is much simpler. :let works with not just options but also variables, registers, and environment variables. Unlike :set, the right hand side of :let is an expression.
Expanding on what people have written about :let, I've noticed that it can be used to assign a value in a variable to an option, something :set can't do. For example, this function uses let to assign the value in the global variable orig_tw to the textwidthoption:
" Toggle Autowrap
" Default of 72 but can be overridden by tw settings in other vimrc files
let g:orig_tw = 72
function Toggle_autowrap_mode()
if &textwidth == 0
" Must use let instead of set here in order for g:orig_tw to be
" evaluated properly
let &textwidth = g:orig_tw
echo "Autowrap mode on tw=" . &textwidth
else
let g:orig_tw = &textwidth
set textwidth=0
echo "Autowrap mode off tw=" . &textwidth
endif
endfunction
noremap _A :call Toggle_autowrap_mode()<CR>
It's very simple.
As people have said set is for options and works better because of the limitation. Also set is the historical command that all versions of vi use to set their options. Most (all?) other versions of vi don't have let.
But possibly most important is that set works on all versions of vim, the let command can be omitted when you compile vim. The standard tiny and small builds do this.
If it's missing let gives you the error:
E319: Sorry, the command is not available in this version
Note: if and endif are not implemented either in vim.tiny but in this case the commands do not give an error, instead everything between the two commands is skipped INCLUDING else.

How to impose hard wrap against my soft wrap wishes?

Well, I'm a newb at Vim, so I'm guessing there's a 99% chance it's a user error!
Vim was soft wrapping long lines very nicely thank you, then a couple of days ago it started to insert hard wraps but only when I had saved the file.
I have been through wrap, nolinebreak, textwidth, nolist, and all combinations thereof to try to get softwrap back but to no avail. Heck, I even read the help pages. All of 'em.
Here's the relevant bits from my .vimrc (as you can tell, I'm getting desperate):
" Editing
set aw ai
set et ts=8 sts=2 sw=2 nu
set fo+=tcrqw fo-=o
set showmatch matchtime=5
set whichwrap=<,>,h,l,[,]
set cursorline
set nofoldenable
set wrap
set linebreak
let mapleader = ","
I picked up this .vimrc from using Vundle.
I found the culprit, Tim Pope's Vim Markdown plugin. Lovely plugin but personally prefer soft wraps, will have to find how to change it!
but only when I had saved the file.
This should hint to you that some plugin is touching the buffer Pre-Write.
Find out which it is by doing
:au BufWrite,BufWritePre,BufWriteCmd
:au FileWriteCmd,FileWritePre
To see where the trigger was installed from:
:verbose au BufWrite,BufWritePre,BufWriteCmd
:verbose au FileWriteCmd,FileWritePre
I have a suspicion this is probably caused by your fo line. Having "t" in the formatoptions option means that if a textwidth is set for the current buffer then vim will break lines at this width. You may notice that this only happens for certain filetypes because different ftplugins may be setting textwidth without you knowing.
The next time you see this happening, I'd suggest running :verbose set textwidth? (with the question mark) and seeing if the value is set. This command will also point you to where it was last set.
Another test would be to just remove "t" from your fo line and see if the problem goes away.
Janus is another Vim plugin that fiddles with linewrap/linebreak and textwidth.
:verbose set tw?
told me:
textwidth=72
Last set from ~/.vim/janus/vim/core/before/plugin/filetypes.vim
Now I just need to figure out the right incantation to disable that... for now, I just added set textwidth=99 to my ~/.vimrc.after file, but there may be a better way...

Can you query what a variable/setting in vim is set to?

For example, in vim, if I want to know if autoread is set or not, is there a command I can run to tell me? Or to know what my tabstop is set to?
In your case, :set autoread? will give you the current value of autoread. Generally, set foo? will give you the value of option foo.
:set will display all options that are different from default.
:verbose set autoread? will tell you what set autoread and its value.
You can also do, for example,
echo &ft
The & refers to the contents of the variable. I find this useful in scripts.
You can view settings in vim with this command
:set all

Resources