Temporarily disable vim plugin without relaunching - vim

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.

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.

Disable vim E211: File no longer available

After switching git branches, any files that existed on my previous branch raise an E211: File "path/to/file.txt" no longer available warning. I already know that and I find it very annoying that I'm warned about it every time I change the tab or pane that I'm focused on. Especially if I need to close 8 panes of files that no longer exist.
Is there any way to disable this warning or make it something that does not require any input to continue?
You can tweak Vim's default behavior via the :help FileChangedShell event.
This autocommand is triggered for each changed file. [...] If a FileChangedShell autocommand is present the warning message and prompt is not given.
Unfortunately, by defining an :autocmd (e.g. invoking a no-op like an empty :execute), you'll lose all the default functionality, and would have to re-implement parts of it (without the message on deletion) by inspecing v:fcs_reason. If the sledgehammer approach is fine for you, this will do:
:autocmd FileChangedShell * execute
Instead of *, you could enumerate all of your Git working copies, to make this a bit more targeted.

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.

Stop vim from dynamically updating folds

Is there any way to stop vim from automatically updating folds on the fly? I really love vim's folding, and I prefer having it in syntax mode so that folds are created as I type. But for instance when I code C++ and I write a bracket { it automatically closes all subsequent folds, and when I then close the bracket again with a }, vim automatically expands all subsequent folds, meaning that I have to refold everything.
Another related problem, if I have the same document open in a different buffer, say I have run ":split", then writing an open bracket { will nest all folds in the buffer under the fold in which I opened the bracket, and closing it will un-nest the folds but also close all of them. If I use either "." or "->" to access a member function/variable, it resets all folds in the buffer to be whatever the current foldlevel is, regardless of which folds I have opened/closed myself.
This is somewhat frustrating when I have the same document open in two buffers so I can read the contents of one function when writing another, as I constantly have to switch buffers and reopen my folds.
In my .vimrc I have
set foldmethod=syntax
and that is about it. For autocompletion I use clang-complete and supertab with:
let g:SuperTabDefaultCompletionType = "<c-x><c-u><c-p>"
I think that is everything which migh affect this.
Edit:
Added some pictures to help illustrate the problem
Both problems can be solved with the following two autocmds:
autocmd InsertLeave,WinEnter * setlocal foldmethod=syntax
autocmd InsertEnter,WinLeave * setlocal foldmethod=manual
This sets the buffer local 'foldmethod' to manual when insert mode is entered or its window (a buffer display) is left, and sets it to syntax when insert mode is left or its window is entered.
This works because setting 'foldmethod' to manual will keep the folds automatically created by syntax as if you set them yourself (manually), and manual folds are not updated based on the syntax of the file.
I've found two bugs with this solution:
When switching windows while in insert mode, the autocmd will set the 'foldmethod' to syntax for the new window, even though it's in insert mode and should be set to manual.
This isn't really a problem for me because I use Vim like a civilized person and operate in normal mode by default.
When
a new buffer is created (e.g. by reading a file)
and 'foldlevel' is 0
and a particular syntax is used (I'm able to duplicate the issue with a C file)
and the o or O command is used to enter insert mode for the first time in that buffer (doing i<esc>o does not duplicate the bug),
then all folds below the cursor will be opened.
I accidentally discovered this when testing the above solution, and now looking back I'm surprised I found it; it's almost not even worth mentioning. I don't intend on trying to write a test file that has the exact syntax necessary to duplicate the bug, so this may go unnoticed for another eon.
I actually discovered this question several months ago and used the solution Ben linked to for a while, before eventually being annoyed enough with the multiple window for one buffer issue (your second problem) to fix it.
So thanks to Ben for his solution, and you for asking this question!
I made a bit of a modification to user4830797's answer which helps deal with situations where the file you're editing doesn't use foldmethod=syntax (for example, a .vimrc file which might use foldmethod=marker):
autocmd InsertLeave,WinEnter * let &l:foldmethod=g:oldfoldmethod
autocmd InsertEnter,WinLeave * let g:oldfoldmethod=&l:foldmethod | setlocal foldmethod=manual
I think you need to check :h 'foldlevel. You should also perhaps use :mkview, probably in autocmd which restores manually open and closed folds.
Other then that you should perhaps set folding method differently on different file types (for instance on C you could set it to manual or marker)
If you temporarily set the foldmethod to manual, then Vim will keep all the folds currently defined by syntax, and keep them in the exact open/closed state you have them in now. This can be done automatically with an InsertEnter autocmd and restored on InsertLeave to protect your fold states in a single window. Unfortunately I have not yet spent time trying to get it working in split windows, but using window-local variables it is easy enough to even account for the user switching windows or something without leaving insert mode. See http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text for details and discussion.

Coda Clips for Vim

I'm currently trying to switch from Coda (a Mac IDE) to Vim. One thing I loved about Coda and my knowledge of Vim cannot replace were the so-called "clips". Basically, you type, say, "new", press TAB, and the text is replaced with a basic XHTML page. And you can add as many keyword/clips combinations as you want.
The most I could get with Vim so far was to create a new file containing my clip, and then use :r FILE in Vim in order to get it inserted, but this is not a very elegant solution, as I'd have to carry these clips around in every directory I have a file I want to use my clips with.
So assuming I've explained things properly, what would be my choices?
For various editors, there's a functionality called '''snippets''' which tab expands the beginnings of common text (like a HTML div, or C function definition) into a skeleton for that code.
There's a couple vim plugins that present this functionality. Two off the top of my bookmark list:
snippetsEmu
snipMate
I heard of another plugin for quick HTML editing that uses snippets recently:
zencoding
Check those out and see if they're near what you're looking for.
Also, you can define a default BufNewFile action in vim - which lets you read in a skeleton for a file if it doesn't already exist automatically.
*skeleton* *template*
To read a skeleton (template) file when opening a new file: >
:autocmd BufNewFile *.c 0r ~/vim/skeleton.c
:autocmd BufNewFile *.h 0r ~/vim/skeleton.h
:autocmd BufNewFile *.java 0r ~/vim/skeleton.java
Put those (or the equivalent) in your .vimrc (w/o the leading colon) to have them set up automatically every time you run vim.
Very late to the party, but:
I would recommend something like Dash for this, because the snippets are then available across all your apps.
This can be a significant bonus as your muscle-memory starts to rely on particular snippets, and can also ease the transition from one editor to the other, because your snippets are independent.
Sometimes I find myself using snippets in something like Mail to send to someone else, or in a Vim terminal on a remote machine I haven't configured, and it's great to have them all there at the ready.
Now all we need is a cross-platform solution which moves with you to a colleague's machine!
As well as the various snippet plugins, Vim also has an abbreviation feature built in, using the :ab[breviate] command.
For example you can define this:
:ab <h <head>^M</head>^M<body>^M<\body>
Then when you type <h<SPACE> it will expand into the full text. The ^M in the example above are actually carriage returns inserted in the string definition with <ctrl-V><RETURN>.

Resources