Need help with vi macros on (redhat-linux 7.5)
My ~/.vimrc looks like below:
set nu
let #c='0i#^[j'
let #u='0<80>kDj'
but still when I vi files, #c or #u doesn't work.
Also, when I cat ~/.vimrc, it shows as below, which I believe is due to control chars:
set nu
let #c='0i#'
let #u='0▒kDj'
However, they do work every time when I record them. Just don't load up from vimrc and work persistently.
thanks in advance :)
If you’re already using vim (instead of pure vi), you could do
let #c = 'I#^[' " make sure to insert a literal escape
Or better yet:
" in ~/.vim/after/ftplugin/c.vim
nnoremap <buffer> gcc I#<Esc>j
The second one can be done similarly.
This should work just fine, as long as the original byte sequences are kept (so <80> is a single character and not four < 8 0 >) - your cat output seems to confirm this. The only issue I can think of is that Vim might use a wrong encoding when reading the .vimrc (but somehow detecting the right one when editing it). A scriptencoding utf-8 at the top might help then.
In any case, by using :help key-notation, these issues can be avoided. You'd need to use double quotes to have then interpreted (and then write \<Esc> instead of ^[, \<BS> instead of <80>kb, and so on). While you're at it, why not define proper mappings (with :map, or rather :nnoremap), to free up the registers again.
Speaking of registers, there's always the chance of accidentally overriding them, they're limited in number, and hard to memorize; all things that mappings don't suffer from. If you really want to continue to reserve registers for these shortcuts (and don't have the problem of overriding them), you could just rely on the viminfo-file to persist them; there actually is no need to explicitly initialize them in your ~/.vimrc.
finally I got it working.
Just tried using "vim" instead of "vi" to see if it loads up the ".vimrc" and it did.
I was assuming that vi would too load .vimrc, but it seems I was wrong.
Now, I am able to use the saved macros exactly as expected.
Related
I do my coding in Vim and recently have been getting more annoyed by its pair completion features. I don't really see the need for pair completion in general as I tend to naturally try to close pairs myself (by pair here I mean type the closing ')' of a set of parentheses, for example). What really annoys me is when I have text already written and to surround it by quotes for example I'll be at the beginning of the word, type ' and then two will pop up right over there rather than just 1 and then me pivoting to the end of the word and typing the other exclamation point. Anyways, that's it for my rant, so any help on stopping my vim from doing this would be appreciated. I use spfvim-13 (https://github.com/spf13/spf13-vim) and have only modified the .vimrc slightly. I wasn't able to pinpoint exactly from where this specific issue arises.
This is not a native vim behavior, it's definitely some plugin causing it. I can't pin-point a particular plugin that spf13 might be having for this, I looked for popular ones I know, like simple_pairs, delimitMate etc.
Best way to investigate what's causing is to just see the output of :verbose imap ' and you'll come to know where it's being set and then remove that plugin / setting.
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.
I am using Cygwin 1.7.22 (32-bit) on Windows 8 (64-bit). Within Cygwin, I am using Vim 7.3.1152, which is the default version.
Behavior that seem like bugs:
When I press I to enter insert mode, it does not say -- INSERT -- in the bottom left. In fact, it doesn't say anything. It does behave correctly, though.
When I delete letters using Backspace in insert mode, the letters do not disappear but the cursor does move to the left.
When I use the arrow keys in insert mode, it enters the letters A, B, C, and D, rather than moving the cursor. The arrow keys work normally outside of insert mode.
How do I make Vim behave as I expect?
Create a ~/.vimrc file with the following contents to put vim in nocompatible mode (actually the mere presence of the file is sufficient.)
set nocompatible
The behavior you are seeing is how vi used to behave. These are not bugs.
Take a look at :h nocompatible
In vim compatible mode tries to emulate vi as closely as possible.
--insert-- is not part of vi so it not shown in compatible mode.
I believe vi did a lazy redraw of the screen and didn't update until you exited back to normal mode. Also backspace is only usable also only works on stuff that was entered in the current insert mode. Overall its not very user friendly.
The arrow keys are sent to vim as escape sequences (escape followed by a coupled of letters). Let ^[ be escape. ^[OA is up on my computer its probably something similar on yours. vim sees this as an escape (goes back to normal mode), and O (add a line above the current) and A which is the A you see entered onto your screen. This just means that vim in compatible mode does not interpret the escape characters properly. Most likely because vi did not interpret them (nor was it designed to use them).
set nocompatible fixes problems 1 and 3.
I think set backspace=indent,eol,start should fix problem 2.
This was asked months ago, but I am answering for future reference for anyone else who encounters this problem.
I was just bitten by this issue. All advice listed in this post, and in other posts on this forum (not to mention posts on other forums) does not work, at least for some of us. I finally figured out the real issue.
vim on cygwin, for whatever reason (at least this was the case for me) does not use the .vimrc you put in your directory. Let's say you copy the example one to your working directory, or copy some .vimrc from online. Or maybe you create a new one from scratch, and put all the settings the good people here and elsewhere recommend (set backspace = blahblah, set nocompatible, set this, set that). It doesn't work. Why? Because for whatever reason (at least in my case) vim isn't looking at the .vimrc you just created.
The solution is to FORCE vim to use a particular .vimrc, by passing in -u on the command line like so:
vim -u [/INSERT/PATH/TO/.vimrc]
For the love of all that is holy, DO NOT type square brackets or the words "/INSERT/PATH/TO/.vimrc" verbatim. Use your brain please.
Anyway, this solved my problems and I was able to use the default example .vimrc and get proper delete and backspace behavior while in insert mode, not to mention other goodies.
You might want to alias the vim command in your .bashrc like this:
alias vim='vim -u [/INSERT/PATH/TO/.vimrc]'
Regarding A,B,C,D for arrow keys in Vim, adding:
:set term=cons25
to ~/.vimrc worked like a charm.
source: http://vim.wikia.com/wiki/Fix_arrow_keys_that_display_A_B_C_D_on_remote_shell
Following different answers in this topic I found a simple solution.
$ vi --version | head
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar 30 2020 21:54:08)
Included patches: 1-486
Modified by <cygwin#cygwin.com>
Compiled by <cygwin#cygwin.com>
$ vi --version | grep 'user vimrc'
user vimrc file: "$HOME/.virc"
2nd user vimrc file: "~/.vim/vimrc"
So I just created ~/.virc (not vimrc) and it works! The content of the file:
set nocompatible
Probably, if you already have this file you will add the above string in it. Or, as people say above, if you have an empty ~/.virc, nocompatible mode must be already in use (I didn't check it).
Apart of the question, line numbers (that I find very useful) may be shown in vi by adding:
set number
I've used vi for decades, and am now practicing using vim, expecting
eventually to switch to it entirely.
I have a number of questions, but I'll start with the one that
troubles me most. Something I have long done in vi is to type
a bottom-line command into the file I am editing, yank it to a named buffer
(e.g., using the keystrokes "ayy) and execute that buffer (using
:#a^M). This allows me to edit complicated commands till they
work right, and to keep commands that I will use many times as I
work in a file. (I have
in my .exrc file a mapping that reduces this yank-and-execute to a
single keystroke; but that isn't relevant to my question.)
I find that in vim, I need a lot more ^Vs than in vi. This
means, on the one hand, that when I have some command-line in a file
that I expect to use this way, I now need to keep it in two
versions, one for vi and one for vim. Also, the requirement of the
extra ^Vs seems inelegant: evidently various special characters
that are interpreted once when the named buffer is executed in vi
are interpreted twice when its is executed in vim -- but why?
As an example, a command of the form
map =f :w^V|e foo^M
(mapping the keystroke-sequence =f to write the current file
and go to the file foo) works this way in vi, but has to have the form
map =f :w^V^V|e foo^V^M
in vim. (Here in both commands, ^V is gotten by typing ^V^V,
and ^M is gotten by typing ^V^M; so typing the first version
involves typing three ^Vs, and the second, seven.) To be
exact: the first version does work in vim if one actually
types it into the bottom line (with the indicated extra ^Vs);
but the latter is required in an executed named buffer.
Any explanation? Anything I can set to fix this? ("compatible"
doesn't seem to do it.) Any hope that it will be fixed in a future
release? (The system I am on uses version 7.0.)
(I should confess that I'm not a programmer; just a user who has
become proficient in vi.)
Personally, I'd stop using ^V completely. In Vim (I've no idea about Vi), there are various key notations that get round the problems you're having. For your specific example, I'd recommend:
map =f :w<bar>e foo<CR>
where <bar> means 'insert the vertical bar here' and <CR> means 'insert a carriage return here'. See:
:help key-notation
for more information. I find the <CR> much easier to understand than ^V^M.
That's an interesting way of using :#, which I hadn't thought of before. I generally just use the command line history when I need to edit complicated commands, and I tend to save common or complicated commands as mappings or commands in my .vimrc (of course, I have a mapping that will pop open my .vimrc in a new tab). But there are certainly benefits to using vim's normal mode rather than command line mode for editing a complicated command.
As I understand it, you not only want to avoid so many <C-V> characters, you would also like to be able to use the same commands in vim and vi. Unfortunately, that would preclude you from using the (preferred in vim) key-notation. I think that you should be able to use the cmdline mode's Ctrl-R Ctrl-R register to help you out (:help c_<C-R>_<C-R>). E.g.
map <Leader>e mm^"ay$`m:<C-R><C-R>a<CR>
mm - mark cursor location so we can return later
^"ay$ - yank current line into register a (ignoring whitespace at beginning and newline at end)
``m` - return cursor to start position
: - enter command line mode
<C-R><C-R>a - place the literal contents of register a onto the command line, which seems to be where your problem with vim versus vi was coming to into play. I think that <C-R>a would give you the same behaviour you are seeing now with :#a.
- execute the whole thing
Using that mapping, I then typed your example of map =f :w^V|e foo^M into a file, placed my cursor on that line, ran my <Leader>e mapping, verified that your =f mapping had loaded correctly, and then ran it. Obviously you'll want to customize it to fit your needs, but I think that playing around with <C-R><C-R> will basically get you what you want.
All of that said, if you can, I'd strongly recommend taking the plunge and forgetting about compatibility with vi. Then you can use the much simpler key-notation and a host of other vim features. :-)
I am using several languages, and currently I am obliged to indicate to vim with which of these the spell check must be done. Is there a way to set up vim so that it automatically detects the correct one? I vaguely remember that in a previous version of vim, when the spell check was not integrated, the vimspell script made this possible.
It would be even better if this could apply not only to a file but also to a portion of a file, since I frequently mix several languages in a single file. Of course, I would like to avoid to load several dictionaries simultaneously.
I don't know if there is a way to autodetect it, but if you put vim:spell:spelllang=foo,bar,baz at the bottom of the file, vim will set the spellchecking languages to foo, bar, and baz when the file is opened. Note that you must put at least one space before that text, or vim will think it's part of the file.
Since vim is missing this feature, I found it useful to define shortcuts like these in .vimrc:
command! Nb :set spelllang=nb
command! En :set spelllang=en