Prevent insert mode in vim - vim

I often like to have a copy of the file that I am working on open on a second monitor, usually to assist with writing tests. I sometimes mindlessly attempt to edit it on this monitor, rather than the most up to date one. To prevent this, I have been setting read only mode with :set ro but that doesn't prevent me from making changes, it only prevents me from saving.
I would like a lock that turns off the ability to go into insert mode. I could create a toggle that remaps all the insert mode keys, but I was wondering if there is a better solution?

Yes, it's possible. :set nomodifiable in the buffer you want to mark read-only. This is used by plugins like taglist to create non-modifiable buffers.

You can open with the argument -M. This prevents edits to the buffer.

Related

Vim detect what kind of buffer the current buffer is

I'm making a plugin where the idea is that if the buffer is empty then you'll enter insert mode, otherwise you'll stay in normal mode.
Of course this is all nice and well but you come across some problems, what if you just opened Vim and you're in the default empty buffer and you don't want to do anything in that buffer? You gotta first go to normal mode and then do your :e magic. Which is undesirable as it takes more work.
So my question is, how does one detect if the current buffer is a real file whether it exists in the file system or not.
For example, I'd like to detect if the buffer is a JS file, whether new or pre-existing. Or if the buffer is a NERDTree buffer or a plugin buffer, that kind of stuff.
Thank you. Any help is appreciated. :)
P.S.: For those interested, this is the plugin: https://github.com/Greduan/vim-empty-insert
if expand('%:p') != ''
" do stuff
endif
See :h %:p and :h expand().
BTW, sorry if this sounds rude, but I'd guess many long-time Vim users would automatically press a/i when they enter a buffer, without thinking whether it exists on the drive or not. So you might want to consider keeping the functionality more consistent.

VIM: disallow focusing a window

In VIM, I want to split a window in two parts where first one is the regular editor, and the second one is just read-only window for some auxiliary information.
The user should not be allowed to access (focus) the read-only window. Can I set that somehow?
set nomodifiable is helpful but it is not what I meant - I still can access the window.
Edit
I mean two independent buffers
Usually the preview window is used for auxiliary information, e.g. insert-mode completion can show additional information there. You can :pedit a scratch buffer, and show your information there.
I don't follow your requirement of not allowing to move into that window. That's not very Vim-like. You can disallow (accidental) editing with :setlocal nomodifiable, but why not allow the user to interact with the window?! (Some operations like resizing are way easier or only possible when you're inside the window.)
Alternative
If the amount of information is small and only needs to be displayed for a short time, and you're in GVIM, you can also use tooltip popups via 'balloonexpr'.
Do you mean two (or more) windows using same buffer? In that case I think that modifiable wouldn't be an option because it wouldn't let you change the data from any window.
You could try to use the WimEnter autocommand to come back to the previous window.
autocmd WinEnter * exe "normal \<c-w>\<c-p>"

An alternative to minibufexplorer (vim)?

minibufexplorer is a persistent buffer manager for vim that lives in its own window. It shows all the buffers you have open, with color indicators as to which are currently visible in windows and which have unsaved changes.
It's a great plugin which I've been hooked on forever. And without the persistent buffer display I find that I now feel lost.
The problem is, minibufexpl tends to get in the way of other window controls. As it is a normal vim window, it behaves like one, causing issues if you wanted to say, rotate your other working windows. Minibufexplorer's window would rotate as well, which is obviously less than desirable.
What I really need is a plugin that persistently displays the open buffers, but doesn't behave like a window. I don't need file navigation or anything as I use other means for that. Perhaps even something like an extended status bar that was capable of displaying information on buffers like minibufexpl does?
There's a new fork of minibufexpl.vim on GitHub which aims to solve some of these problems. One of its new features is "Prevents resizing of MBE buffer by window resizing commands" and it is immune to commands such as C-WC-R (rotate windows).
https://github.com/fholgado/minibufexpl.vim
While this is not an exact answer to your question, I think you could find it useful.
FuzzyFinder plugin provides good visual representation of your open buffers,
and also offers great way to jump between them - fuzzy match.
Its list of buffers is not "persistent" meaning it's only shown on
demand, but I consider this an advantage: firstly the buffers list doesn't eat
up precious screen estate, and secondly with fuzzy match I don't feel a
need to see it at all.
Consider the below screenshot: in order to switch to ext_gcd.py I just need to press
,bg : ,b invokes buffers list and g fuzzy-matches the only buffer
whose name contains letter g.
P.S: it works with files too. My mappings are as follows:
map <leader>f :FufFileWithCurrentBufferDir **/<C-M>
map <leader>b :FufBuffer<C-M>
,f in this case recursively fuzzy-matches files starting from a directory where current buffer is placed.
Old thread, but for anyone else searching checkout the vim-airline plugin. It's very popular and has great compatibility with other plugins.
Use the g:airline#extensions#bufferline#enabled option to get what your looking for.
I really enjoy buftabs.vim because it keeps the information about which buffers I have open in the status line, which disappear when I need to type there in a nice clear manner. I find this quite preferable to minibufexplorer because my cursor never accidentally ends up in a read-only scratch buffer which takes up more space than necessary. It also does some magic-mapping of :bnext and :blast to allow hopping between buffers for a rather more "familiar" feeling.
You can use ctrlp, a plugin written in pure Vimscript and highly configurable.
:CtrlPBuffer open a window with the list of open buffers
you can begin to type, it is a fuzzy finder.
There is also Tagma Buffer Manager. I am not using it yet, but someday I will give it a try, for sure.
You can try Powerline's tabline!
I tried many plugins but they tend to take up the command line or the status line, or won't show up the whole tabs when there're too many of them.
Here is a screen shot (the top bar is the tabline!):
You need to add set showtabline=2 in .vimrc after install Powerline.
And if you want to go to the 8th buffer, :b 8 will jump to it!
Hope this helps.

Making Viper state global

EmacsWiki says:
There is a way to make Viper state and Viper insert state global, like in Vim (and probably vi). In Vim (and probably vi), you start in Normal Mode. You can switch buffer, and Vim stays in Normal Mode. Pressing “i” puts Vim in Insert Mode. Then if you switch buffers by clicking on another window, Vim stays in Insert Mode. You don’t have to remember which buffer is in what mode, you only need to remember in which mode Vim is.
But unfortunately, they don't say what this method is, and I couldn't find it quickly. Does anybody know?
I don't know a single setting or package to do what you want. It's not provided by viper itself.
That said, you can write some advice which does the job. The key being that you need to advise all the ways you switch buffers/windows. For example, if you switch windows through the other-window command (C-x o), you'll want this:
(defadvice other-window (around other-window-maintain-viper-state activate
activate)
"when switching windows, pull the viper-current-state along"
(let ((old-window-state viper-current-state))
ad-do-it
(viper-change-state old-window-state)))
But, switching windows using the mouse doesn't go through that function, and to get that to work you need to advise select-window in exactly the same way:
(defadvice select-window (around select-window-maintain-viper-state activate
activate)
"when switching windows, pull the viper-current-state along"
(let ((old-window-state viper-current-state))
ad-do-it
(viper-change-state old-window-state)))
If you find you use another mechanism to switch windows/buffers that doesn't use the above, it just takes a tiny bit of digging (M-x describe-key ) to find out what new thing you should be advising.

Vim: Maintain the history of a file after it has been changed and reloaded

If I'm editing a file in Vim, then some external program changes the file, Vim tells me:
W11: Warning: File "test.erl" has changed since editing started
See ":help W11" for more info.
[O]K, (L)oad File:
If I Load the file, though, all the undo history is lost.
Is there any way to avoid that?
Update: it appears that this is one of the new features in Vim 7.3: https://groups.google.com/group/vim_announce/browse_thread/thread/66c02efd1523554b
I don't believe this is possible.
There is a very useful patch available for the vim source code available here that keeps the undo history after exiting vim and restarting. However, I've just tried it and it seems to fail when the file is edited externally. It might be worth contacting the author or reporting a bug on the patch website to see if this can be overcome.
G'day,
I'm not sure but does setting autoread, i.e. entering :set autoread leave the undo history for the file when it changes?
Hmmmm. I'm thinking probably not because the change history is maintained as line numbers and vim doesn't know if those line numbers are still relevant to the changed file.
BTW WTF are you editing a file that is being changed by external forces anyway? Sounds dangerous to me. (-:
This is a workaround I used before Vim 7.3:
" :e usually clears undo history, so we don't really do :e any more.
" Instead we delete the contents of the buffer, then read the file in, which
" is an operation we can undo. We must delete the top (empty) line also.
:map :e<Enter> :%d<Enter>:r<Enter>:0<Enter>dd
When you see the warning prompt, you would have to hit ok instead of load, and then perform the load yourself: :e<Enter>
There are two disadvantages (although I found the tradeoff acceptable):
You lose the line you were on. Your cursor is left sitting at the top of the file.
Vim still thinks the buffer is out of sync with the file, so when you next save, you may need to do :w! instead of the normal :w, and you will need to hit y to confirm the overwrite.
Edit: There might be a workaround for the second problem.
Edit: The first problem could be addressed with a bit more scripting (see :h line.)
I don't see how vim could keep track of something it didn't do.
So, as to the question, I would suggest - source control ... but that's probably not the answer you're looking for.

Resources