Define persistent abbreviations in Vim - 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.

Related

Vim :Explore, don't edit file when pressing <Enter>

in Vim, I type :Explore to open the vim browser.
When I press on a directory, I enter the directory as desired.
When I press on a file, I start editing that file. I would like to do something else.
So basically I would like to map to 'enter directory' for directories, and something custom for files.
The netrw plugin allows opening of file in the current window, (vertical) splits, and a remote Vim instance. The closest built-in functionality to what you want is customized browsing with a special handler, which is triggered with the plugin's x mapping; cp. :help netrw-x.
You can customize via an external command, or a Vimscript function that you define (:help netrw_filehandler). In this, you can do "something else", with all the power of Vim to implement it.
As for the distinction between directories and files, this mostly falls flat due to the different keys used. If you need to distinguish in your custom function, the isdirectory() function is there to help.
alternative
The NERD tree plugin offers an alternative to netrw, and also offers a similar extension, either via custom mappings, or a menu. As it's mostly a drop-in replacement for netrw (but with additional functionality), it might be worth to check it out before investing too much in customizing netrw.

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

vim syntax highlighting weirdness

I have some specific settings for my latex highlighting and am using the indentLine plugin, which requires let g:indentLine_fileTypeExclude = ['tex', 'bib'] to avoid the conceal feature annoyance. Anyway, when I start vim with vim filename.tex my vimrc gets loaded properly, but when I simply call vim and then open a given tex file, it'll ignore the vimrc.
Any idea what's causing it? Also, let me know what information you need, as I am far from certain on what would be needed.
EDIT:
Okay so I've found that for both cases i'm in a [tex] environment, but if I'm in a [plaintex] environment then the weirdness doesn't happen. If that helps anyone.
2nd EDIT:
New development, it is only the first file that's opened that seems to ignore the exclusion for indentLine, the remainder are shown exactly as they ought to.
The plaintex is a separate filetype in Vim (cp. :help ft-plaintex), so you need to add it to the IndentLine config:
let g:indentLine_fileTypeExclude = ['tex', 'plaintex', 'bib']
Edit This now looks like a command ordering issue. It's hard to remotely troubleshoot this, as the exact plugins and their initialization order may be important. Please capture a full log of a Vim session with vim -V20vimlog. After quitting Vim, examine the vimlog log file for the ordering of commands (but it might be difficult to see what's happening in a potentially vast list of commands).
It might be sufficient to just reload the first file that has those problems, with :e!.

Apply changes to .vimrc to source file

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?.

Temporarily disable vim plugin without relaunching

I'm using c-support in Vim. One of it's features is the automatic comment expansion.
When I'm pasting code into Vim from an external editor, the comments are expanded (which gives me double-comments and messes up the paste - see below for example). I'd like to be able to disable the plugin, paste, then re-enable it, without relaunching Vim. I'm not sure if this is possible.
The SO questions here, here and here all describe methods to disable plugins, but they all require me to close Vim, mess with my .vimrc or similar, and relaunch; if I have to close Vim, I might as well cat file1 >> myfile; vim myfile, then shift the lines internally, which will be just as quick.
Is it possible to disable a plugin while running vim without relaunching, preferably in a way which allows me to map a hot-key toggle-plugin (so re-sourcing ~/.vimrc is alright; that's mappable to a hotkey [I imagine, haven't tried it yet])?
Messed up comments:
/*
* * Authors:
* * A Name
* *
* * Copyright:
* * A Name, 2012
* */
EDIT: It turns out you can :set paste, :set nopaste (which, to quote :help paste, will "avoid unexpected effects [while pasting]". (See the comments).
However, I'm still curious whether you can disable/enable a plugin as per the original question, so I shall leave the question open.
Insert ":set paste" then paste your code. After that insert :set unpaste
There is no general way of doing this without modifying plugin source. Some plugins (like all of mine) can add this feature (I have “unload” feature in my framework, but use it mainly for updating without restarting vim, not for temporary disabling something). What you can definitely do is to add a function call to each sourced plugin file that will save current vim state and also something that will do this after plugin was loaded (due to existance of finish, throw, try | <code with some error> you can’t just add this function at the end of the plugin), likely on VimEnter, FileType and Syntax events. Then you need to have a function that will revert changes done to the plugin and an s:Execute function definition in each plugin, like this:
function s:Execute_I_do_not_expect_function_with_this_suffix_to_be_defined_by_the_plugin_so_I_add_it_to_avoid_name_collisions(s)
execute a:s
endfunction
. This is needed to execute a line of code in the context of sourced script. By “state” that needs to be saved I mean
Mappings
Commands
Signs
Functions
Menus
Events (autocommands)
Syntax (likely to be empty before plugin run)
Options
Some vim, all global, buffer, tab and window variables
// Script-local variables. Though it is simple here: at the start of the script script-local scope is empty and all you need is to empty it when disabling.
For each item it is possible to revert changes done by plugin, but it is not that easy to code. And presence of <script> argument to mappings is not distinguishable with presence of nore, though they have different behavior.
If you want to write it, do not forget about the fact that if script is resourced, your code will be relaunched.
Also, note the SourcePre event. It will help with automatic addition of your lines to all plugins.
Do not forget that there are more places that can be modified and can’t be saved and restored easily or at all: filesystem, interpreters state, opened plugin buffers, etc.

Resources