Vim - how to start inserting at the end of the file in one step - vim

Is there a single shortcut to start inserting in the new line at end of the file?
I'm aware of G + o combo.

There's also the command line option "+":
vim + myfile.txt
Will open myfile.txt and do an automatic G for you.

Not that I know of - G+o is what I would have suggested too, but that is 2 steps :)
You could always create a macro which does G+o, and then you can invoke the macro which will be 1 step.

Adding the following into ~/.vimrc will create one for you:
:nmap ^A Go
To type the "^A" first press Ctrl-V, then press Ctrl-A. You can then use Ctrl-A to append at the end of the file when not in insert or visual mode.

echo >> myfile.txt && vim -c 'startinsert' + myfile.txt
You can also save the above command in a script and then use $1 instead of myfile.txt, name your script myvim ( or whatever you like ) and always open your files and start writing away instantly.
myvim myfile.txt

You could stick the map definition in your .vimrc and then invoke it when the you open the file.
Or, if you only want to do this for a particular file, you could create an autocmd for that file type that does it automatically. See autocommand in the vim doc's.

Related

how to remove new lines in vi editor linux?

I am using Linux (centos flavor) and created a file with the following text:
" hello
world
"
Question:
Now, I opened the file in vi editor mode and am able to remove all non blank characters(backspace or delete keys do nothing).
But newline characters persist and I get error saying "no previous regular expression".
What should I do to remove all the new lines so that my file is just empty?? I have tried backspace key many times but no effect and I do not want to use cat > filename to just overwrite the file to make it empty!
You can use dd to delete any lines in vi editor.
Example:
You have a file having 6 lines and you want to delete all 6 lines:
Open the file using 'vi` editor
Go to first line
use 6dd
:g (for global) could help you here.
:g/^$/d basically says that "globally find any pattern matching ^$ and delete those".
If you think that you might have blanks in those lines, you could say ^\ *$
open txt with vi
:1 << move cursor to first of file
d << enter delete mode
G << move cursor to end of file
It will remove all from cursor( in this case, at first of file ) to end of file
or
open txt with vi
d
N (Number, As many as you want to delete lines)
Enter

Vim --- Read from an External Command, Inserting Right Where the Cursor Is

:r !program opens a new line, inserts my program's output and then inserts a line after it.
I simply want to insert the output right where the cursor is without that additional mess.
I figured I can:
Run a before macro
mai^M^[`a
"Mark where I'm at, insert a line and go back
Run my command
:r !echo -ne "line1\nline2\nline3"
Run an after macro (cleanup the lines)
$mb:j!^M`a:j!^M`b
"Go to the end of inserted outpu
"Mark it b
"Join with the next line
"Go to the first mark
"Delete the inserted newline with :j!
"Go to the second mark
How can I combine this into a single command?
I'd like to be able to do:
:Readhere !echo -ne "line1\nline2\nline3"
where :Readhere would be my custom command.
This might do what you want. (You don't need the !)
command! -nargs=1 ReadHere exec 'normal! i' . system(<q-args>)
This creates a command called ReadHere that takes everything as a quoted argument and passes it directly to the system command. Then we use exec to insert everything in normal mode. (This might not be robust enough)
Example: Starting buffer is
one two three
Running :ReadHere echo -ne "line1\nline2\nline3" where the cursor is on the w produces
one tline1
line2
line3wo three

Can I call multiple function on Vim startup?

I frequently send files to Vim from Visual Studio. I have it set up as an external tool with the following parameter:
"+call cursor($(CurLine), $(CurCol))"
However, I also want to be able to call my own function as well. When I'm editing a file from VS I want the window to be large, so I expected to be able to do something like this:
"+call cursor($(CurLine), $(CurCol)); +call Embiggen()"
However, that doesn't work. I've tried a few variations (e.g. , call Embiggen(), etc).
Obviously I could write my own PlaceCursorAndEmbiggen function, but I don't really want to do that. Is there any way to call multiple functions on Vim startup?
Eureka!
Simply pass two strings:
"+call cursor($(CurLine), $(CurCol));" "+call Embiggen()"
Maybe the solution would have been easier to find had you used the alternative, more commonplace syntax: -c "cmd" instead of "+cmd". According to :help -c, you can pass up to 10 of these.
These exact commands can be combined into one using pipe symbol:
"+call cursor($(CurLine), $(CurCol)|call Embiggen()"
. There are much more that can be combined this way, but some like :normal can’t, use #Ingo Karkat’s or your own answer for them. If you are short* on +commands and still don’t want to create a .vim file you can use either :execute
vim -c "execute 'normal! 1' | execute 'normal! 2'"
or (bash/zsh) -S with process substitution:
vim -S <(echo '
normal! 1
normal! 2
')
. Though most of time it is better to just create a .vim file.
* You can pass up to 10 + or -c (they are equivalent and they are not counted separately) and 10 other --cmd, though letter is less useful.

vim - process the output from the "read" command as a range in Ex mode

BACKGROUND:
In vim (Ex mode) it is possible to run an external command and have the output from that command automatically inserted into the current buffer.
In Example 001, we see how to cd to the current directory, get a listing of the files there and auto insert that into the current buffer
EXAMPLE 001:
:cd . | :r ! dir /w/s/b
QUESTIONS:
1) Is it possible to automatically specify or capture the Vim {range} to reflect the lines that were recently inserted into the file ?
2) Using the range obtained in question 1) is it possible to chain Ex mode commands to automatically process the lines that were inserted into the file ?
3) If it is not possible to do 1) or 2) above, is there an alternate way for Vim to recognize lines recently inserted into the buffer and run arbitrary commands on them ?
4) What is a relevant :help cross reference that can be used for this purpose ?
GOAL:
The goal is to be able to chain multiple Ex mode commands together to easily run process recently added lines to a file, without having to expressly identify the line number or manually select them using Visual mode or something similar.
The goal is do something similar to the (psuedo-code) in Example 002
Example 002:
:cd . | :r ! dir /w/s/b | :{auto-range}s/^/ /
Vim sets the change marks '[ and '] to the inserted range; you can use these to define a range for subsequent Ex commands:
:cd . | execute 'r ! dir /w/s/b' | '[,']s/^/ /
You need :execute because otherwise the | is interpreted to belong to the :r command.
What about processing those lines before inserting them in Vim?
:r!dir /w/s/b | sed -e "s/^/ /"

Efficient way to refactor a class/method/string within a directory using vim

So far, I have been manually refactoring code by using the find-and-replace operation
%s:/stringiwanttoreplace/newstring/g
in vim.
But this is a slow and laborious process if I have stringiwanttoreplace in many files inside a specific directory.
My current/typical slow and laborious process involves a grep:-
grep -rn "stringiwanttoreplace" .
in my terminal to reveal all the locations/filenames where stringiwanttoreplace are; and now that I know which files contain stringiwanttoreplace, I will open each file one-by-one to perform the find-and-replace operation in each file.
Is there a more efficient workflow (in vim) to get this done?
CLARIFICATION: I would prefer a vim-based solution instead of a bash script/one-liner.
Here's the full sequence of commands that I would use:
/stringiwanttoreplace
:vimgrep /<c-r>// **
:Qargs
:argdo %s//newstring/g
:argdo update
In the first line, we search for the target pattern. That populates the last search pattern register (:help quote/), which means that we won't have to type it out in full again.
The :vimgrep command searches the entire project for the specified pattern. Type <c-r>/ as ctlr+r followed by / - this inserts the contents of the last search pattern register onto the command line. The first and last / symbols are delimiters for the search field. The trailing ** tells Vim to look inside every file and directory below the current directory.
At this point, the quickfix list will be populated with search matches from all matching files. :Qargs is a custom command, which populates the argument list with all of the files listed in the quickfix list. Here's the implementation:
command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames()
function! QuickfixFilenames()
" Building a hash ensures we get each buffer only once
let buffer_numbers = {}
for quickfix_item in getqflist()
let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
endfor
return join(values(buffer_numbers))
endfunction
Add that to your vimrc file.
Having run :Qargs, our argument list should now contain all of the files that include our target string. So we can run the substitution command with :argdo, to execute the command in each file. We can leave the search field of the substitution command blank, and it will automatically use the most recent search pattern. If you want, you could include the c flag when you run the substitution command, then you'll be prompted for confirmation.
Finally, the :argdo update command saves each file that was changed.
As #Peter Rincker pointed out, you should ensure that Vim's 'hidden' option is enabled, otherwise it will raise an error when you try to switch to another buffer before writing any changes to the active buffer.
Also, note that the last 3 commands can be executed in a single command line, by separating them with a pipe character.
:Qargs | argdo %s//replacement/gc | update
The :Qargs command is pinched from this answer (by me), which in turn was inspired by this answer by DrAl. A very similar solution was posted by #ib, which suggests to me that Vim should really implement something like :quickfixdo natively.
If you really want to do it in Vim you can follow the suggestions here.
You can call this from within Vim (:!find ...) but you don't need to:
find . -type f | xargs sed -i 's/stringiwanttoreplace/newstring/g'
Fine-tune the file selection with the dozens of parameters described in
man find
(e.g., replace only in HTML files: -name \*.html)
This solution will try to attempt the replacement in all files. You can filter that through grep before, but that is just doing twice the work for no gain.
By the way: sed uses almost the same syntax for regular expressions as Vim (stemming from the same history).
You could open all the files and type
:bufdo :s/stringiwanttoreplace/newstring/g
It performs the search/replace in all your buffers.
You don't need vim to do this, you can use command line tools. Using sed in a loop on the list of files to do this for you automatically. Something like this:
for each in `grep -l "stringiwanttoreplace" *` ;
do
cat $each | sed -e "s/stringiwanttoreplace/newstring/g" > $each
; done
vim7 has recursive grep built-in
:vimgrep /pattern/[j][g] file file1 file2 ... fileN
the result will be shown in a quickfix-window (:help quickfix)
to do the search recursively use the **-wildcard like
**/*.c to search through the current folder and recursively through all subdirectories.

Resources