Apply changes to .vimrc to source file - vim

Im currently making a lot of changes in my .vimrc. At the same time Im also coding away on a project. To fix the new indentation and tabstop rules, and so on, I have to go through every line and re-indent them. This seems a little bit tedious.
Is there any way to apply the newest changes in my .vimrc to the whole source file?

Your problem seems to be that existing buffers do not get the updated (global) values of e.g. 'tabstop', because these are buffer-local options. Therefore, a simple :so % after editing the ~/.vimrc isn't sufficient.
There are several possible approaches:
Use sessions
With the current Vim state persisted via :mksession, you can safely :quit Vim, restart it, :so session.vim, and have the identical editing state, but with the new settings applied (this requires that you :set sessionoptions-=options)
Manually apply
You can e.g. :yank the changed :set tabstop=... commands that you've edited and reapply them to all existing buffers, e.g. by moving there and :#", or (if there are many) with the help of :bufdo.
Note that especially the indent settings can also be set from ftplugins, so your global settings may not be effective. You can check that for a buffer with :verbose set tabstop?.

Related

Define persistent abbreviations in Vim

Vim does not seem able to create global abbreviations. So I created an
abbreviations file (called autocorrect.vim) with the following line in
my .vimrc file:
:source ~/autocorrect.vim
I then manually added my abbreviations to this file. If I work in any
document these abbreviations are available to me.
However, if I am working in a new document and try to add new
abbreviations to this list or remove abbreviations, it last only for
the session. Once I quit vim I lose all changes. To make abbreviations
permanent I have to manually edit the autocorrect.vim file directly.
The thing is that if I work in a new document and add abbreviations I
can see that they have been added to my abbreviations list (by calling
:ab). However, when I exit they are lost. How can I make these changes
global and permanent?
I am hoping to find a solution that does not require a plugin.
In order to persist configuration in Vim, it has to be saved in a configuration file, with :help vimrc as the most prominent one. This has both pros (no matter what you do interactively in Vim, any screw-up can be fixed by restarting Vim) and cons (what you want is difficult to do). I see the following options:
Instead of defining abbreviations on the fly with :ab et al, you need to put the command into a separate configuration file, either in your ~/.vimrc, or in a separate config (e.g. ~/.vim/plugin/myabbreviations.vim). This ensures that the abbreviation is persisted for new Vim sessions. You also need to :source the config to import the new abbreviation into your current session. (With the separate config, reloading shouldn't be an issue; it might if your .vimrc is poorly written.) This may sound tedious, but you can define custom :commands to quickly locate, and an :autocmd BufWritePost to automatically :source it. On the other hand, this is a path towards a "plugin solution" that you don't want.
Vim supports sessions (:help session-file) that (with the default 'sessionoptions') store mappings and abbreviations. So if you :mksession after defining a new abbreviation (or just before quitting Vim) and load that session (via :source) in another Vim instance, you'll get to keep your abbreviations, too. Unfortunately, without a plugin, session handling also is a manual process and easy to forget. Also, the granularity of what gets persistent cannot be controlled; it's mostly all-or-nothing.
As already mentioned in the comments, there are plugins that make this straightforward. If this is only about abbreviations for you (and you're happy with the other configuration handling in general), it might be worth a try.
I personally use the first option, with custom commands (:Abbreviate, :SnippetEdit, etc.) that open dedicated scripts.

Vim - ftplugin settings changes not updating for existing file

It seems like there's some odd caching-like behavior going on for files that I have already opened once in Vim. I have a file foo.txt that I opened, and then I change some of the settings in ~/.vim/after/ftplugin/text.vim, but those new settings do not appear in foo.txt. I can quit vim and reopen foo.txt, or reload with :e, or even :so ~/.vim/after/ftplugin/text.vim, but none of these seem to have an effect on foo.txt's settings. If I mv foo.txt bar.txt, the settings show up for bar.txt with no issues.
EDIT
It seems I can force the settings to reload for foo.txt with the following sequence:
:so ~/.vimrc
:so ~/.vim/after/ftplugin/text.vim
Questions:
Why is this necessary / why were the other settings not picked up?
Why was sourcing ~/.vimrc not enough? It applied settings that were directly specified in ~/.vimrc, but shouldn't the ftplugins have been loaded at the line filetype plugin indent on? Why was sourcing text.vim afterwards necessary?
Vim runtime consists of a few hundred files, I'm not sure why you expect Vim to monitor them continuously. It doesn't. These files are loaded at some well-defined (and documented) points, that's all there is to it.
In particular there is no safe way to reload your configuration. You can do things like :so ~/.vimrc, but unless you specifically wrote your vimrc to take that into account, there will be drawbacks (such as autocmds piling up). If you want to be safe you have to quit Vim and start it again. That's how Vim works.
Now, for ftplugins you might get away with something like this:
:setf text
(use the actual filetype instead of text). This works for simple set fubar options. It works because under the hood setf is actually a carefully written autocmd. It still breaks for more complicated constructs (such as autocmds or file-scoped variables), for the same reasons :so ~/.vimrc has drawbacks.
A few more precisions:
.vimrc is loaded once -> for defining global stuff
same thing with .gvimrc, loaded only with gvim after the .vimrc
plugins are loaded once as well, after the vimrc files -> for global stuff as well
autoloaded plugins are loaded on demand, once, whenever a function they define is invoked
ftplugins are loaded once per buffer (and possibly multiple times! as there may be multiple buffers requiring them to be sourced) -> for definitions that shall apply only to the current buffer that triggered its loading
there are also langmap scripts, syntax scripts, indentation scripts, and even the old macros/ scripts (loaded explicitly/manually)
some plugins provides local vimrcs (basically identical to ftplugins, but loaded depending on the current directory of a buffer, instead of its filetype).
As you see, all things are loaded once, only. If you want to load them several times, you'll have to do it manually and explicitly. That's why a few of us have a :Reload command that simplifies reloading any kind of script - mine is hidden in my collection of scripts: lh-misc -> plugin/vim-maintain.vim

One of my files has an incorrect tabstop setting

One of my files, whenever I open it, has a different (incorrect) value for the 'tabstop' option. In my .vimrc, I have the line:
set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab
and 'tab' is not mentioned in any subsequent lines. When I open a specific file I'm working on, the 'tabstop' option is set to 8, while all the other relevant options are correct; and all other files (so far) show their indentation correctly. I don't use modelines or smart tabs (yet). If I source my vimrc in the file, it corrects the indentation, so I'm assuming it isn't anything directly related to vimrc.
What is happening?
Basically there's two ways in which your .vimrc can be superseeded: plugins (including filetype-specific ones) might reset the option, or it might be changed by an autocommand. In any case, your first step is to check when the option was last modified (see :set-verbose):
:verbose set tabstop?
If that's not enough, look through the list of all the scripts and config files that Vim has read since it was started:
:scriptnames
(better do that in a newly started copy of Vim right after loading the offending fileā€”this way, there'll be less output from :scriptnames.)
After these steps, you should have a list of scripts that might be the culprits. There's no easy way to narrow it down: you'll have to grep, to temporarily remove plugins from your ~/.vim and so on.
Finally you'll find a line that changes the setting. If it's in a plugin, look through its documentation to find a way to override the setting. If it's somewhere in the indent file or ftplugin, override its effect by placing a file into ~/.vim/after/indent/ or ~/.vim/after/ftplugin. An autocommand might also work.

vim: disable plugin by default (diffchar)

Recently (vimdiff: force line-by-line comparison (ignore supposedly missing/additional lines) ), I've found the quite useful vim plugin diffchar, which improves vimdiff by showing multiple diffs on the same line separated, instead of highlighting the whole area from the first to the last diff.
The problem is that I frequently encounter files where diffchar doesn't work properly, namely spills out a whole lot of errors when vimdiff is opened, plus I think it slows down vimdiff substantially for large files (which I'm dealing with far too often).
Is there a way to disable this (or any) plugin by default?
The plugin already has the functionality to turn it off (toggle it), mapped to F7. What I'd like is that it's turned off by default, but that I'm still able to turn it on (using F7) when I specifically need it. (I'm also fine with tweaking the source file of the plugin accordingly, BTW.) What I've already tried is simply adding the command F7 is mapped to (ToggleDiffCharAllLines) to .vimrc, but this doesn't work.
Just put this into your ~/.vimrc:
let g:DiffExpr = 0
You then have to explicitly enable the plugin via one of its mappings or commands.

Vim hard or soft tab depending on what's used in the file

Is there a vim command or plugin that will span the source file I'm opening, and adjust my tab setting to whatever is used in the file.
I currently work on a diverse codebase at work, with some source files using hard tabs, other 4 space soft tabs, and other's 2 space soft tabs. My hard tab, if I forgot to changes, can lead to ugly whitespace in different editors if I forget to change it when I'm editting a soft tab file.
I'd like to not have to remember to check whatever's convention is used in a file every time I open a buffer, and adjust my preferences accordingly.
I use yaifa with great success. It's pretty much an "install-and-forget" plugin that does what it says it does without ever getting in the way. Working in the messy environment I work in was horrible until I found that gem.
If most people at work use Vim (and/or Emacs), you can encode the indent settings within the file itself, see :help modeline (at least Emacs has something similar). Of course, agreeing on a common setting and gradually migrating to it would be even better :-)
In case you can't do that or things are just too chaotic, you need a plugin to dynamically adapt the indent settings. My IndentConsistencyCop plugin checks whether the buffer's indentation is consistent and conforms to tab settings, and then offers to adapt the settings to the detected ones. (The plugin page has links to alternative plugins.)
I've used the following function (found it somewhere on the web) with good success. Just put it into your .vimrc:
function Kees_settabs()
if len(filter(getbufline(winbufnr(0), 1, "$"), 'v:val =~ "^\\t"')) > len(filter(getbufline(winbufnr(0), 1, "$"), 'v:val =~ "^ "'))
set noet
else
set et
endif
endfunction
autocmd BufReadPost * call Kees_settabs()
Take a look at sleuth by the prolific Tim Pope:
This plugin automatically adjusts 'shiftwidth' and 'expandtab' heuristically based on the current file, or, in the case the current file is new, blank, or otherwise insufficient, by looking at other files of the same type in the current and parent directories. In lieu of adjusting 'softtabstop', 'smarttab' is enabled.
I wrote this because I wanted something fully automatic. My goal is that by installing this plugin, you can remove all indenting related configuration from your vimrc.
If your file is consistently indented with hard tabs, 'shiftwidth' will be set to your 'tabstop'. Otherwise, a 'tabstop' of 8 is enforced.

Resources