Vim Comments Format Options Repeat Not Working - vim

I set the comments option for a filetype to b:*. If I open such file I can verify this with set comments?. Now further I explicit set the formatoptions to use r for repeating the comment on a new line. After all calling set formatoptions? return in sum j1tcqln.
If open a new line o and write something like * This is a comment hit <CR I expect to get a * on the new line es well, cause the r option, but is doesn't.
The check if the +comments feature is available with :echo has('comments') is positive and returns 1.
Whats the problem here?
Edit:
This is my ftplugin/markdown.vim:
setlocal comments=b:*,b:-,b:+,b:>
setlocal formatoptions+=r
setlocal formatoptions-=c
echom 'Format: ' . &formatoptions
The last line leave a correct message when open a file with this type. But calling :echo &formatoptions manually afterwards, its again the false output.
It seems like no matter what I do in this ftplugin afterwards its not there anymore, even though it has been executed.
Edit:
It looks like my ftplugin gets overwritten by the default one in /usr/share/nvim/runtime/ftplguin/. Does this make sense and how can I mix them up?

Filetype plugins are sourced in this order, each potentially overriding the preceding one:
$HOME/.vim/ftplugin/markdown.vim
$VIMRUNTIME/ftplugin/markdown.vim
$HOME/.vim/after/ftplugin/markdown.vim
--- edit ---
The first location is suitable for two scenarii:
you are creating support scripts for a language not natively supported by Vim,
you want to prevent Vim from sourcing the default support script for a specific filetype (the solution in your answer).
The second location is off-limits. Four main reasons for this:
your changes can and will be overridden during future updates,
your changes may make Vim unstable,
having to sudo your way to your config will get annoying pretty quickly,
put your stuff in your $HOME.
The third location is sourced last so it allows you to selectively override default settings and add your own. This is the safest place for your own filetype-specific settings.

The solution is to add this at the header of the ftplugin file:
if exists('b:did_ftplugin') | finish | endif
let b:did_ftplugin = 1
Then is necessary cause the ftplugin in /usr/share/nvim gets loaded after and does not been executed if this variable is set.

Related

How to set a VimScript to be executed last?

Problem
A setting in my vimrc (set noshowmode) is being overridden by a plugin later in the loading process.
Goal
Have a VimScript file be executed last (or at least after plugins).
What I Know
Plugin VimScripts are executed after the vimrc (Source).
The after-directory is run close to last and holds user overrides
(Source: :h after-directory).
Vim's runtimepath determines the order of what is run.
Failed Attempts
I tried appending a VimScript file (containing set noshowmode) to the
end of $VIMRUNTIME with
set runtimepath=$VIMRUNTIME,~/.vim/nosmd.vim, but this method ended up
messing up other plugins (namely vim-airline, which did not load).
I also tried creating the ~/.vim/after directory and putting my
VimScript in there, but this had no effect.
Your attempts
set runtimepath=$VIMRUNTIME,~/.vim/nosmd.vim
That cannot work. 'runtimepath' contains a list of root configuration directories; you cannot directly place script files in there. Instead, point to a directory that contains plugin/yours.vim.
I also tried creating the ~/.vim/after directory and putting my VimScript in there, but this had no effect.
You can check with :scriptnames to see whether your script was executed (and at the end of the plugin load sequence!)
Solutions
An ounce of prevention is better than any workaround. I would first try to locate the culprit who changes the 'showmode' option; a plugin shouldn't do this (or at least have a configurable option to disable it).
:verbose set showmode?
might already tell you who changed this setting.
As #romainl already commented, ~/.vim/after/plugin/myplugin.vim should work for undoing this. If it doesn't try the following autocmd (in your ~/.vimrc) as a last resort:
autocmd VimEnter * set noshowmode

Buffer-local value of global variable?

Many Vim's plugin's settings are specified by let g:something = value. I have a need for setting buffer-local values of some variables (actually with vim-localvimrc)
I know there's a way to outwit by using a condition (Setting buffer specific variables in Vim). But not all these autocmds are under my control, since some are set by other plugins. Is there anything like setlocal for global variable?
There are many ways to do to what you actually want (strip trailing whitespace for some projects) but I don't think there is anyway to shadow a global variable with a buffer local one (which is what you asked).
One way to do this is to add
autocmd BufWritePre /path/to/project/* call StripTrailingWhitespace()
the following to your vimrc. Which will call the function StripTrailingWhitespace for any file under /path/to/project (including subdirectories). StripTailingWhitespace is defined in spf13.
You can probably generate the path to the project dynamically by looking at the path to the local vimrc file.
Another way would be to change the condition spf13 uses to call StripTrailingWhitespace
The StripTrailingWhitespace autocmd in spf13 is defined as the following. (I added newlines so I'm not sure if this will work.)
autocmd FileType c,cpp,java,go,php,javascript,python,twig,xml,yml,perl
\ autocmd BufWritePre <buffer>
\ if !exists('g:spf13_keep_trailing_whitespace') |
\ call StripTrailingWhitespace() |
\ endif
So you would change it to !exists('g:spf13_keep_trailing_whitespace') to some other condition like checking if in whitelisted projects or check a buffer local variable.
General recommendation would be to get rid of any vim distribution. It is very hard to understand what is in them when you are first starting out. It then becomes very hard to modify them. It is generally better to start from scratch and add plugins and mappings when you find something lacking. It will take longer but you will understand everything in your vim configuration.
In your case, the plugin you are using shall accept overriding global variables with buffer local variables. Indeed it can be done by changing the condition -- in lh-vim-lib there is a lh#option#get() function that'll be easy to adapt to spf13. If you think it makes sense, contact spf13 maintainers or open an issue in the project bug tracker.
Another solution would rely on defining a local_vimrc script for each project you are working on. In some projects you'll have a :let g:spf13_keep_trailing_whitespace = 1, in other you'll have a :silent! unlet g:spf13_keep_trailing_whitespace -- usually it is accomplished with a :let g:var=0, but the current condition ignores the variable value.

.vimrc overridden by sys admins settings

I have a mapping in my .vimrc file to map F2 to save a file. Have done this for years. However now the system administrator has decided to override my setting with one of their mappings. If I run :scriptnames I see the order and I know which one is the offending script.
Is there a way to just ignore one startup script? I also tried creating a .vim/after/fixit.vim file which re-did the mapping but that file does not get read.
I know I could ignore all files and just load my .vimrc but I do want some of the administrator's defaults, just not all.
You can only avoid sourcing of a script if it uses the canonical inclusion guard:
:if exists('g:loaded_pluginname') | finish | endif
But it probably doesn't.
Your idea with .vim/after/fixit.vim is a good one (you haven't posted your :scriptnames output, so I can't tell for sure), but you need to include the plugin subdirectory there, too:
.vim/after/plugin/fixit.vim
Finally, as a last resort, you can define an :autocmd VimEnter (in your ~/.vimrc). That autocmd will fire after all other initializations, so you can definitely change the offending mapping in there.

Quickest Way to Revert Spaces to TABs in VIM

I have always been one to replace TABs in VIM with x amount of spaces (usually 4).
Four lines I almost always use in my .vimrc config file are:
set tabstop=4
set shiftwidth=4
set expandtab
syntax on
Basically, there are moments when I NEED to use a single TAB (such as Makefiles), and I don't know how else to work around that other than leaving the file, editing my .vimrc, and then reloading the file of interest.
That said, what is the quickest way (from within VIM) to revert it back to using TABS, and then reverting back to my original settings? I'm looking for the least-hassle, least-keystrokes solution.
VIM will automatically enable the TAB for a makefile, assuming you name it "makefile," as opposed to "Makefile." Not sure why VIM still doesn't detect the type with a lower-uppercase difference, but such is life. (#Sedrik)
That aside, other alternative solutions are:
Filetype Binding (#ThorstenS #tungd):
autocmd FileType make setlocal noexpandtab
RealTime Switch (#ThorstenS):
Assuming the .vimrc configuration mentioned in the question, do:
:set noet (to switch from spaces to TAB)
and :set et (to switch back)
Just use the magical escape key available in insert mode.
On the *NIX's it is ^V by default when you are in insert mode. On Windows, you need to find out what the magical escape character is - ^V is taken for something else; I think it may be ^Q or ^S?
So! In your makefile:
this: this.c
<C-V><Tab>cc this.c
where the usual meanings apply:
means hit ctrl-V (you should see a ^ hiding away under the cursor)
- hit the tab key. Bingo.
Works for me.
Note: if you use vim settings or startup code which smashes tabs as you read a file, this obviously is a short-term fix. I prefer to learn how to use the retab command to ensure a file is tab-clean, because I don't like a file to be touched unless I consciously choose to do so.
Just type set noexpandtab . Perhaps you bind this to a function key.
Only this configuration helped me solve this problem.
filetype plugin indent on
filetype detect
autocmd FileType make set noexpandtab
Vim defaults to tabstop=8 and noexpandtab, so the defaults are well suited to working with Makefiles. If your .vimrc uses custom options for tabstop, expandtab, etc., one simple solution is to bypass your .vimrc while working with Makefiles.
From the manpage (emphasis mine):
-u {vimrc} Use the commands in the file {vimrc} for initializations. All the other initializations are skipped. Use this to edit a special kind of files. It can also be used to skip all initializations by giving the name "NONE". See ":help initialization" within vim for more details.
Since I can never remember the necessary flag/value/formatting, I've created a Bash alias which remembers for me: alias vimnone='vim -u NONE'
You can create a custom configuration per file type.
mkdir -p ~/.vim/after/indent
echo 'set noexpandtab' >> ~/.vim/after/indent/make.vim
Basically, here we created a new indent configuration for makefiles that will be loaded after other scripts.
source

VIM cpoptions+=n in an XML file

In my vimrc I set cpoptions+=n. Usually this option stays enabled, but as soon as I open an XML file it gets disabled. I've looked through the vim folder for things that modify cpo but can't see anything interesting (other than some saving and restoring of the options so that -=C can be used, but commenting those out changes nothing).
Any idea what's causing this or some pointers as to what to look for?
Open a XML file and run :verbose set cpoptions?. This will show you the current value of the setting and what file set that value. This setting is likely being overridden by the syntax file for xml (it is in my case).
Edit: Although this normally helps, it seems in this case there are many files loaded for the XML filetype that simply save cpo off, change it for their script, then restore the original value. It doesn't look like this is going to help you much.
You may have better luck opening up an XML file and running :scriptnames, then grepping through those scripts listed for cpo to see if you can find the culprit.
If you use GVIM, set it in your .gvimrc, because this is the last loaded configuration file. See :help initialization
other way, as #Randy Morris said, a plugin might set it to the default value. In my configuration, Tabularize set it last time in .vim/bundle/after/plugin/TabularMaps.vim.
EDIT: I found it !
In autoclose plugin, in plugin/autoclose.vim the saved cpoption is not writed back at the end. Simply add
" restore cpoptions
let &cpo = s:global_cpo
to the end of the file.
If you dont use the autoclose plugin, you can search for plugin files that reset the state of cpotions by :vimgrep "set cpo&vim" ~/.vim/**
then in the list you can search after the files that don't restore the original state (usually at the end of script a line starting with let &cpo = is missing).

Resources