Vim "show my last command" command? - vim

Is there a command which shows what was the last command in normal mode?
Suppose I accidently hit random key and got some unexpected result.
Sure I can undo it, but could I reveal what key was pressed and how it was interpreted?

Hit the colon (:) and then use the up arrow to start going back through previous commands. You can use the up/down arrows too to move around the list.

q: will show you command history in Vim.
q/ will show you history of searches.
And must importantly, :q will quit the mode.

The text from the last command is stored in the . register. You can see all registers by :display. Unfortunately it doesn't say what the started the normal command.
To see commands from : (command mode) you can use :hist or q: which is limited to the last 20 (by default).
Another ability is to save the undo buffer :wundo undo.bin -- but the undo buffer is binary.
But none of these actually answer your question. I'm curious if it can be done.

Entering colon : then ctrl+p shows your previous command, i.e., moving backward through your vim command history. ctrl+n moves forward.
This is very convenient if you're used to using the command line and prefer not to change your keyboard hand positioning to use arrow keys.

It is difficult to know it. You can play with the variables:
v:operator
v:count (and v:prevcount)
v:register
But you cannot fully get the last normal mode command issued.
However if you want to systematically record everything you type while in Vim, you can launch vim -W ~/.vim-last-scriptout (a Windows version: vim -W "%HOMEPATH%\Vim\.last-scriptout) You can alias it in your shell on a UNIX machine. Every single key, or control-key, will be recorded into that file. Note that if you happen to use gvim or vim -g (the GUI) you might encounter this bug.
If you want to replay this file you can use :source! (with the exclamation mark) or the -s option from the command line.
On Windows I have set gvimportable.exe -W gvim_directory\last_scriptout as my default editor in my Commander program (FreeCommander). This way I can always remember what I have typed to do something and repeat a sequence of commands on another file. Of course I have another shortcut for opening Vim and playing the scriptout.
Note that the file might be written only when Vim exits, so you have to lose your session to know what you've done.

Related

Is it possible to improve this vim mapping that repeats a command on the command line?

So here is my mapping:
nnoremap <cr> :nnoremap <lt>cr> :w!<lt>cr>:!tmux send-keys -t :1.1 "py.test --cov=." C-m <lt>cr><lt>cr><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left>
It's pretty awesome. What it does is when I first start my vim session (or after reloading a vimrc), and hit enter, I can immediately type the name of the tmux session that I'm in and hit enter again. Assuming that I'm editing my files in the zeroth pane of window 1 and I have a tmux split (horizontal, in my typical case). Subsequent times hitting enter in normal mode will save my active file and launch my py.test tests in another window. That means that I can technically continue coding before my tests have finished passing. I forget who I first got the idea from, but h/t that guy.
Anyhow, you've no doubt noticed that there are a lot of <left>'s in that mapping, because I'd like to start the command out being able to set the session name. But there also might be cases where I'm editing my code in a different window or something, or I need to change my pytest command or something, so I still want the ability to make those modifications.
Is there a way that I can improve this mapping? Maybe by approaching it in a different way altogether?
Your initial mapping builds another mapping command, and uses <Left> to insert the cursor on the right position to complete and then execute it.
An alternative to that would be defining a custom command (e.g. :TestInSession) that takes the variable parts as argument(s). Then, your initial mapping could just build the other mapping, leaving the cursor at the end of :TestInSession, and you would have less clutter in the command-line, and easier editing at the end.
If you need the ability to re-configure your other mapping, you could define an alternative initial mapping that isn't overwritten, e.g.:
:nnoremap <Leader><cr> :nnoremap <lt>cr> ...

Keep vim always in command line mode with a ":"

Is there a way to make vim stuck in command mode with a : already typed in?
In that way, for instance:
I would type /fooEnter and the cursor would go to the beginning of the next line containing foo.
Next, I would be still on command line mode with a : already typed in for the next command.
Yes, start it in Ex mode, by invoking it either as ex or as vi -e.
You can also enter Ex mode from the normal visual mode by typing Q (must be upper case).
You can return from Ex mode to normal visual mode by using the vi command.
EDIT : This doesn't actually do what the OP is looking for. He wants to keep the visual display while keeping the cursor on the bottom command line. That may not be possible.
No, but you can map ; to : to put yourself "closer" to command mode.
I'll link to the Vim wiki instead of reposting identical information here.
http://vim.wikia.com/wiki/Map_semicolon_to_colon
You can build your own REPL, like this:
:while 1 | execute input(':') | redraw | endwhile
This is just a conceptual demo; you probably want to add a condition to quit this special mode. Also, commands like :append would need special handling to work properly.
As a last try, I could just initialize vim with -servername=FOO and then code a little script that would read from stdin and send remote-send to FOO whenever it detects(by parsing) a whole command was typed on stdin.
Then I would just use Vim and this other script side by side on different xterms/gnu screens.
EDIT
OK, I will use this one. This way I can even make :a command to enter vim's Insert mode and switch back to command mode when entering a line with a single .. This way I would also have syntax highlight on the fly when inserting text (you know, vim has a very pretty visual display of the text, I'm just too used with ed's interface). When I have so time I'll write this script and link it here.

vim completion deletes typed letters

I've come to a vim completion behavior that is very annoying for me and I cannot figure out how to configure vim to behave differently.Maybe it is not possible at all.
Suppose I'm editing file with following content:
MyCompany2
MyCompanies
MyCompany3
Now I want to add another entry (say MyCompanyABC) so I type My and hit Ctrl-N, so now I have
MyCompany2
Now I hit backspace, then A so I'm at
MyCompanyA
No I decide to try completion again so I hit Ctrl-N and vim takes me back to
My
So is there a way to make it so that the last step keeps what I already have?
UPDATE:
I gave the completion sequence wrong. The problem I describe appears if one first hits Ctrl-P. Then in the above scenario you get and the rest as above.
MyCompany3
This doesn't behave like this on my machine (Ubuntu 10.10, vim 7.2.330 here). If I do this:
Open vim by typing vi
Type the text you gave above
MyCompany2
MyCompanies
MyCompany3
Open a new line below
Type "My"
Press Ctrl-N
Choose MyCompany2
Backspace (get "MyCompany" after that)
Type A (get "MyCompanyA")
Ctrl-N does nothing - as expected, status bar says: -- Keyword completition (^N^P) Pattern not found.
Is it possible you have some plugin that is changing the default behavior? You can also try vi -u NONE to check whether you have something in your .vimrc that is changing this behavior. Best if you have some other system to check it out.
Are you sure that you want to use Ctrl-N directly without hitting Ctrl-X beforehand? Ctrl-N will also search in all opened buffers.
Maybe hitting CTRL-X CTRL-N or CTRL-X CTRL-P will result in a more stable completion.

handling special characters when executing named buffers in vim

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. :-)

Readline's vi-mode in vim ex mode

Let's see if I can explain myself.
I use vi-mode in bash, which is really great since I'm used to Vi.
When I'm inside vim and type : (to go to ex mode), since I'm used to the vi-mode from bash, I feel the slowliness of having to use this mode like the "regular" way of using bash.
Question is: is there a way of using vim's ex-mode like bash's (or readline) vi-mode?
Not sure if I understand what you're trying to do, but it might be something like hitting q: in normal mode?
For users that use Vim or vi bindings almost everywhere, including on their shell command line, it really hurts when you leave that environment. If you're used to the vi bindings hyperdrive, going back to chords for skipping words and other manoeuvres is painful and slow. Operating systems also differ on their default bindings so Mac, for instance, supports option-arrow instead of control-arrow, adding to the pain.
But there is one place where this also happens where it's really upsetting: in Vim itself. When working in Vim and entering command mode using : the default readline editing returns. Chords all over again. How to fix this?
Simple: When in "normal" mode, that is, when navigating around, type q:
Vim will drop you at the bottom of a full Vim full screen editing experience, go for your life
Additionally the command history is available on previous lines in the buffer
You can yank and paste lines and edit the commands as much as you wish
To execute a command in "command" or "ex" mode just hit ENTER on the line you want to execute
Hitting enter on an empty line closes the buffer and does nothing
But this is just another buffer so you can quit it as usual with :q as well
Although ESC leaves the "ex" command line, ESC in the buffer will not leave the buffer, because it's an actual buffer
The q prefix is used to introduce macro recording, so the q: variant is perfectly mnemonic for entering recording of an "ex" command line.
Note that q: to enter the buffer editing mode is very similar to :q ! You may have hit that by accident sometimes ;-) Now you know how to get out of it!
Zigdon had this answer a long time ago, of course, but it's pretty darn sparse, but then again, so is the question. If Zigdon adds this extra detail to his answer I'll be happy to delete this answer so that there can be one good answer.

Resources