How to document all commands that I used in Vim editor in a special file? - linux

I need to document all commands that I used to modify text using Vim editor. When I am in the terminal and need to save all my input in a file I usually write:
history > ~/some_file.txt
However, I am not sure how to do it while using vim. Can you tell me?

Any output can be redirected with :redir. So
redir >~/vim.history|silent history|redir END
Will redirect the output of :history to the file ~/vim.history. Here silent is used to prevent a -- More -- prompt.
You could also put the history into the current buffer with
:put =execute(':history')
Note that Vims history is limited to 50 entries by default (see :help 'history).

Use startup option -w. From the docs:
All the characters that you type are recorded in the file "scriptout", until you exit Vim. This is useful if you want to create a script file to be used with "vim -s" or ":source!".

Press qx, which causes Vim to start recording your keystrokes.
Press q to finish recording.
Move your cursor to wherever you would like Vim to paste the record it has just made.
Press "xp to paste the record.
The x identifies a buffer. Buffers y, z and so on also exist, so you can use a different letter than x if you wish.
Nothing requires you to paste the record into the file you were editing when the record was made, incidentally. To paste into a different file, give the command :tabedit name-of-different-file, press [Enter], and then press "xp to paste. (Since :tabedit opens the second files in another tab, you can then press gt to toggle between the two if you wish.)

Related

Redo after reopening a file in Vim

I am using vim editor. I was writing a program and did some of the changes in the file after which I "undo" all the changes and by mistake closed the file. Later I realized that the approach that I was doing in the code is right, So I again opened the file and tried to do "redo" operation,but as I have closed the session I think I have lost all the history. Can somebody please tell me if I can do redo by some means as retyping the whole thing again is quite tedious.
Is there some way in which I can redo changes after opening a new session of Vim file
For that you need to have :help persistent-undo enabled:
When unloading a buffer Vim normally destroys the tree of undos created for
that buffer. By setting the 'undofile' option, Vim will automatically save
your undo history when you write a file and restore undo history when you edit
the file again.
Unfortunately, 'undofile' is off by default, so unless you've configured it (and if you've tried redo and failed, that looks like it's off), it's of no use for your current problem.
If the swap-file is still lying around (unlikely as there was a clean exit of Vim), you might be able to grab small incoherent bits of your edits from it.
soap box
To preempt the typical comments: You probably have to accept the loss right now, but take this as an opportunity to rethink your approach. Persistent undo is a really nice feature. With a modern revision control systems (like Git or Mercurial), you can commit often and only locally, and revising your edits is easy to do. Even if that's not an option, there are plugins for Vim (like my writebackup plugin) that make it very easy to frequently save "snapshots" of important editing states. Any of these could save you from the data loss next time!
Another approach, in case you have executed some commands, is recovering your command history by redirecting it into a register.
:redir #h
:history
:redir END
:set paste
"hp
:redir #h ............. start redirecting output to register "h"
:history .............. outputs all commands history
:redir END ............ stops redirecting
:set paste ............ to avoid wrong indentation
"hp ................... puts the "h" register in the current position
you can control where to put it by doing...
0put h .............. pastes the `h` register at the line zero
Once you have a series of commands into a file or register it makes easier to build a function like:
function! Helo()
echo "hello world"
endfunction
If by any change you have used a macro, let's say q, you can retrive it or even edite it, because macros are regular registers that you can reassign as you want. For example, on insert mode you can type:
Ctrl-r q .................... pastes register q
:let #q= ................... starts reassingning macro q
:let #q= ctrl-r q .......... pastes the q register on its reassignment
setting register q to "hello vim"
:let #q = "ihello\<Return>vim\<Esc>"
OBS: Using double quotes you can use control keys as seen above
Any complex command can be saved into the clipboard
:let #+ = #: .............. places last command on the clipboard
:#+ ......................... uses clipboard as command

How to copy all the text from vim editor using vim command line?

I want to select all the text from the vim editor, I tried the command :%y+ but getting error E850: Invalid register name. I get this command from this link. Please help me how to copy all the text from file which is open in vim. They are using yank, what is meaning of it..
I had a similar problem. Don't know why you got so many down votes.
The problem is that you haven't installed vim-gnome which takes about 24 MB and adds a feature to the inbuilt vim.
sudo apt-get install vim-gnome
then your command will work. :%y+ This command will copy all the text in system's clipboard.
TLDR: If you want to copy text in Vim to the system clipboard type ggVG"*y. Explanation below...
Vim runs in the terminal and, depending upon how you are using it and which type of Vim you are running, it's not really designed for you to select text with a mouse and copy and paste in the traditional way.
If you want to select all of the text using Vim then use ggVGy (note the uppercase VG in the middle). This command moves the cursor to the top of the file, enters visual mode, moves to the bottom of the file (thus, selecting all of the text) and then yanks (copies) it. You can then use p to put (paste) this code but only inside of Vim.
If you want to copy to the clipboard to use somewhere outside of Vim then try this:
First, select everything using the commands outlined above but without the final y: (ggVG). Then press "*y. This should now copy it to your operating system's clipboard and you can just paste (Ctrl/Cmd+v) anywhere you want outside of Vim. This can vary depending on what settings you have for Vim but it should work.
A brief explanation of the commands used. gg goes to the top of the file. V enters visual mode by lines. G goes to the end of the file. y yanks (copies) the text but not to the clipboard. p puts (pastes) the text.
The more advanced (i.e. cool) stuff:
" allows you to access registers. For example "a provides access to register a.
The * is the system clipboard so "* provides access to the system keyboard. Therefore, "*y yanks into the system clipboard.
While there's a great explanation of how to exploit the system clipboard in vim, it sounds like you're just having trouble getting your vim to access the clipboard in the first place. Try installing vim-gnome, it gives you the packages you need to get to the system clipboard.
For some reason, "* didn't work for me, but the exact same command with the "+ register did.
To select the whole file you can jump to the beginning, start visual mode, jump to the end:
ggVG
This question is a few years old now, but I had this same problem on Linux Mint 18. I found using xclip worked for me. You can map the command vmap <F7> :!xclip -sel c<CR><CR> in your .vimrc to have your current selection in visual mode copied to the system clipboard.
Here is a thread containing the above (and other) solutions.
You can use
Vggy/vggy or,
VGy/VGy
To visually select any number of text and then copy it, in your case it is gg / G as you want all text on the file,
gg is to copy while your cursor is at bottom of the file, gg for go to top
G is to copy while your cursor is at top of the file
Or even you can always use
Vk(as number of time)y to copy the selected lines of text.

Duplicating line in Vim and appending few letters

I am editing a dictionary in a text file, containing Russian words - one word per line.
Some nouns are missing their derivatives, which are usually the same word appended by few more letters - in 6-7 variations as shown in this screenshot:
In Vim I would like to put the cursor in the first column and scroll down line by line. And when I recognize a noun, I'd like to press some (as few as possible!) keystrokes to take that word, copy it in separate lines and append the letters.
I can get rid of the duplicates by issuing %sort u later.
If I could run that command on the whole file it would be something like:
%s/\(.\+\)$/\1^M\1а^M\1ам^M\1ами^M\1ах^M\1е^M\1ном^M/
Do you please have an idea, how to create such a "macro" in Vim?
There are a couple of ways that you can handle this. You can create a macro or you can create a map. Either can be done while running VIM. Either can be placed in another file (your .vimrc, for example, or a file with bindings specific to this project) and sourced when needed.
I will also give you a bit more advice with regular expressions: if you are writing something particularly complex, you can greatly decrease the number of \s needed by starting the regular expression with \v (i.e., :s/\v([0-9a-f]+\s)/0x\1/g).
Creating a Macro in VIM
You can start a macro in VIM by pressing q in Normal mode, followed by the key that you wish to use for the macro. You can then invoke the macro by pressing # followed by the macro's letter. Press q again in Normal mode to stop recording.
You can therefore enter this macro as follows (using the q register):
qq:s/\(.\+\)$/\1\r\1а\r\1ам\r\1ами\r\1ах\r\1е\r\1ном\r/Enterq
Then, when you are on a line and you want to run this command, enter #q from Normal mode.
Storing a macro in a file and sourcing it
When you created a macro in the last step, what you were actually doing was setting the q register. You can check this by entering the registers in command mode. You can instead set this macro in your .vimrc file as follows and it will be available every time you start VIM.
Create the file you want to store this macro in (:new).
Add the following line to the file:
let #q=":s/\\(.\\+\\)$/\\1\\r\\1a\\r\\1b\\r\\1ам\\r\\1ами\\r\\1ах\\r\\1е\\r\\1ном\\r/^M"
(If you yank the line and paste it in VIM with Ctrl+R", there will be a proper ^M character at the end of the line. You'll need to do some manual editing to make sure that it's inside the quotes. Alternatively, you can enter Ctrl+VCtrl+M to enter the ^M character.)
Save the file (:w testmacro.vim).
Source it (:so % or :source %).
Test your macro by typing #q on one of the lines you'd like to do this to.
Later, you will be able to load this macro by running :so testmacro.vim.
Create a Mapping
You can instead create a mapping. The following mapping copies the last word in a given line, pastes it onto the following six lines, and then appends to each of the given lines.
nnoremap <c-j> yy6pAа<esc>jAам<esc>jAами<esc>jAах<esc>jAе<esc>jAном<esc>j
n at the beginning of "nnoremap" indicates that it only functions in Normal mode.
noremap means that this command won't engage in any recursive remapping (whereas with nmap, this could happen).
<c-j> maps to Ctrl+J
yy6p yanks the line and pastes it 6 times.
Aa<esc>j appends to the end of the current line, enters the text (in this case a), exits Insert mode, and moves down a line.
You can enter this command in VIM's command mode or you can store it in a file and load it with the :source command.
Combining Registers with Mappings
You can access a register in your mappings. This means that if you know that entering a given replacement regex will do what you want, you can save that in a register and then enter your command on the current line.
To do this, enter the following commands in a file and then source it:
nnoremap <c-i> :<c-r>f<cr>
let #f="s/\\(.\\+\\)$/\\1\\r\\1a\\r\\1b\\r\\1ам\\r\\1ами\\r\\1ах\\r\\1е\\r\\1ном\\r/^M"
Now you can enter Ctrl+I to run the replacement regex in register f on the current line.
Alternatively, dedicate a few registers to the purpose - let's say a-f.
nnoremap <c-l> yy6p$"apj"bpj"cpj"dpj"epj"fpj
let #a="a"
let #b="ам"
let #c="ами"
let #d="ax"
let #e="e"
let #f="ном
In this case, we're using the ability to press " and the name of a register before hitting a command that uses it, such as paste.
You can record macros by pressing q in the escape mode. For example,
position your cursor on the noun you want to edit.
press qa to start recording macro and store it in register a (other alphabet and digits may also be used for registers) .
do whatever general actions you want to do (copy line, paste, append letters, etc. as in you have tried to show in your search string).
once you are done with the changes, in escape mode press q again.
Your macro is now created in register a. Whenever, you want to repeat your key sequences, just press #a.
Note that you can do anything in recording mode, including any kinds of commands, insertions, cursor movements, and so on. For more information on macros and related options, check out Vim help :h complex-repeat.
Vim registers are shared as place holders for both macros and yanked test; this feature allows you to even save and edit your macros in a file. See this question for details.
Here is a map solution - which copies the line into a buffer and then pastes using p.
The A appends at the end of the line
map <F2> 0dwpo<esc>pAa<enter><esc>pAam<enter><esc>pAax ...etc
If your goal is, when your cursor on a special word, and press something, vim will append different "suffixes" (I hope I used the right word, but you knew what I mean). You could go macro (q). However since you have already written the :s command, you could create a mapping using that command do the same, and it would be shorter.
in command line, you can get the word under cursor by pressing <c-r><c-w>. so you could try:
nnoremap <leader>z :s/<c-r><c-w>/& & &..../<cr>
I didn't write the & & &... part, since I don't know (never tried, I don't have vim under windows. I don't even have windows) if the line break \n could be used here under windows. & means the whole matched part, which in this case is the word under your cursor.
So you just move your cursor to the word, type <leader>z, vim will do the job for you. (if the replacement part is correct :) ).

How to clear the line number in Vim when copying?

I copy some code from one part of one file to another part in vim, I find that, there are line numbers in each line and the format is gone, how to set correct format as origin ?
like this:
40 root /opt/release/current/public;
67 41 passenger_enabled on;
68 42
If you have line numbers, I'm quite sure you are not using Vim's yank/put operations (these will never copy the linenumbers, foldcolumn, icons etc) because in terms of the edit buffer, they don't exist.
My guess is you are working in a terminal emulator and using the mouse to copy stuff to the clipboard, which possibly selects the 'extraneous' room of the screen (including virtual spaces at the end, line numbers, fold markers etc)
You might have luck setting
:se mouse+=a
in order to get the behaviour of the mouse like you expect it. Otherwise, do the selection with V<movement>...y (y for yank, which corresponds to 'copy')
Then on the destination use p (put at cursor), or P (put before cursor)
Let me know if that helped or you need more info
In case anyone wants a quicker way (on Linux anyways), I have noticed in vim you can hold down ctrl and drag over the region you want to copy and you'll avoid the line numbers and select the part you want.
Steps:
ctrl and drag over area
release ctrl
copy (either keyboard shortcut or right click)
In normal mode, type :se nonu
This is the easiest way to remove the line numbers and you will be able to copy the text without the line numbers.
A permanent solution for this is to add the below code at the end of your .vimrc file located in your home directory.
se mouse+=a
By adding this you will be able to select only text and not the line numbers as shown in below image:
If you are not getting your .vimrc file in your home directory (i faced this problem), type the command :scriptnames in vi editor, it will display the location of your .vimrc file. Reference
On Mac: I found out that you can select the desired area with Option+Command and copy paste it to another editor.
All the previously entered solution are very good one. However, sometimes your are using vim on a remote server (so you cant copy to your clipboard using "+y). Often terminals support copy paste operation.
I use vim to output visual selection to a new shell where I can copy text using terminal feature:
:'<,'>w ! bash -c cat
Then I can easily copy the output.
Same pattern for pasting in vim:
:r ! bash -c cat
Then I paste and send EOF to cat using Ctrl+d. This method also avoid reindenting the text you paste (Note: you can disable automatic indentation using :set pi!).
Have a look at the pastetoggle option sometimes set to F11.
As an alternative you could always write the section you want to copy into a temporary file
(ma, goto end line then use :'a,.w tempfile) then read it into the second file.
For further investigation you might want to look at the autoindent option.
On Windows VIM GUI: :set nu and then hold down Ctrl-Shift while
highlighting the desired text with the mouse. This yanks the line numbers
into the buffer.
On Windows using Putty, I have noticed in vim you can hold down ALT and drag over the region you want to copy and you'll avoid the line numbers and select the part you want.
Steps:
Press and Hold ALT
Drag over area
Release ALT
Copy using CTRL+Shift+C (or right click if that is turned on)
Variations:
The specific key may be different based on your specific set up.
If ALT does not work, try the following keys instead:
CTRL
CTRL+Shift
ALT+Shift
Note:
If anyone knows of any other key combinations that have worked for them let me know and I will update this answer with them.
I mapped the below command to a key.
It strips the whitespace around the copied line numbers.
It ignores the line text and any blank lines behind.
:1,$s/^\s*[0-9]\+\s//\|1,$s/^\s*[0-9]\+\n/\r/<cr>
You can also consider using sed and pbcopy to copy the lines to a clipboard, where you can paste to another terminal or apps outside of vim.
sed -n <line start #>,<line end #>p <file name> | pbcopy
simplest way just: $ cat "your file"
and then just copy it from your terminal without numbers

Saving vim macros

Does anyone know how to properly save/reuse macros recorded inside of a vim editor?
Use q followed by a letter (for example 'x') to record a macro, then press q to end the macro definition. The pattern surrounded by the starting and ending 'q' during this definition just goes into one of the copy/paste registers (in this case, register 'x') so you can paste it with the"xp or "xP commands in normal mode, where x is the register to paste. Typing "xp in normal mode inserts the contents in register x and exits back to normal mode.
To save it, you open up .vimrc and paste the contents while defining the macro using let #x, then the register will be around the next time you start vim.
The format is something like:
let #q = 'macro contents'
Be careful of quotes, though. They would have to be escaped properly.
So to save a macro 'x', you can do:
From normal mode: qx
enter whatever commands
From normal mode: q
open .vimrc
insert a line let #x = '...' (see the following)
For the above ... pattern, you can use "xp just at the place where the pattern should be placed. But this is not essential, you can just type in the macro definition.
For a more robust solution you can checkout Marvim.
It lets you save a macro in a specific namespace (or use the filetype as a default namespace) and you can later search for your saved macros and load them in a register ready for use.
If you reuse a lot of macros, this is pretty helpful.
Write your macros inside your ~/.vimrc, to define a macro launched by CTRL+O by example, add the following line to your ~/.vimrc :
map <C-O> MACROTEXT
when you record a macro by typing qa you can retrieve your macro text by typing "ap
You can do like this on your ~/.vimrc
:let #a="iHello World!\<CR>bye\<Esc>"
NOTE: You must use double quotes to be able to use special keys like in \<this silly example>.
The :mkexrc (or :mkvimrc) command can be used to save all the current :map and :set settings to a file. See :help mkexrc for details.
Vim 8.0 on MacOS Mojave (10.14.6) actually persists macros and named buffers automatically (by default, although I haven't looked for a way of turning this behavior off). Closing a Vim session will update the ~/.viminfo file with any named buffers / macros.

Resources