There's the ":a" command, but that's multi-line, and argdo asks you for the text again for each file.
The docs mention the global command (g/pat/command) that will use an alternative version of ":a" that is terminated by a newline instead of by "." on a line (you can include newlines by escaping them with "\"). But I couldn't get this to work.
The only way I've seen is to first yank the text-to-be-added into a named register, then use:
:argdo put x " where x is the register
I'm hoping for something like
:argdo append myTextHere
I'm unclear where you're trying to insert the text in the buffer. If you want it after the current line:
:argdo exe 'normal osometext'
Inserting text with linebreaks in it:
:argdo exe "normal osometext\<CR>anewline"
To append text after line nr 10:
:argdo call append(10, "hello world")
To append text to the line 10:
:argdo call setline(10, getline(10)."textappended")
Yanking a text in vim will put it in the default buffer, which is ". You can paste that buffer in insert mode for example by typing <C-R>". So all you need is argdo put "
Related
I'm trying to open a file using a command I set in my .vimrc file. The relevant line in my .vimrc is similar to the following:
command Of so /Users/Dude/Working/open_file.txt
With open_file.txt containing the following:
tabnew /Users/Dude/Working/Project/config.txt
What I'd like to do when executing the 'Of' command is navigate to the end of config.txt. I've tried adding a large line number which is unlikely to exceed the number of lines in the file like so:
tabnew /Users/Dude/Working/Project/config.txt
250000
This takes me to the end of the file but doesn't seem like the right way to do it. Ideally, I'd also like to add a new line after the last line and navigate there too.
A few things:
I would suggest you use full names instead of short names. e.g. so -> source.
source is probably the wrong choice here as you can do everything with the right-hand-side of command
May want to use ! with command so you can resource your vimrc file. e.g. command! Of ...
$ represents the last line of the file. No need to choose a magic number
Create a new line can be done with :normal o or :put _
So with some tweaks we get the following command:
command! Of tabedit /Users/Dude/Working/Project/config.txt | $put_
For more help see:
:h :command
:h :put
:h :range
:h :bar
Have a look at :h :normal in your case just write :norm Go instead of your number there.
:tabnew, like most variants of :edit (and the command-line arguments when launching Vim), takes arbitrary Ex commands via the [+cmd] argument. The $ command will move to the end of the file:
tabnew +$ /Users/Dude/Working/Project/config.txt
I wanted to paste the yanked line in the vim command prompt after typing certain command.
I saw a solution where they asked to enter <Ctrl-R><Shift-"> to paste the yanked lines in the vim command prompt, however I am having the following problems:
When I try like, :tabnew and then type <Ctrl-R><Shift-">, whatever yanked line gets pasted after :tabnew line.
Eg: :tabnew /disk/bin/hello.log
The above solution doesn't work if I map the same above command in the vimrc. I tried adding the following map in my .vimrc:
:map <S-P> :<C-R><S-">
When I try :tabnew and type <S-P>, it is not pasting the yanked line, i.e. the mapped command is not working.
Can anyone help me on the above scenario?
FOLLOW-UP QUERY:
Is it possible to mix normal mode and command line mode operations?
For Eg:
a. I have a line in text file which is a directory path and wanted to open that directory in vim.
b. Instead of doing Yanking [S-Y] the line and then doing mapped command [map <C-T><C-O> :tabnew <C-R><S-"><bs><CR>] to open the directory for vim, is it possible to do something as given below ?
nnoremap <F7> <S-Y>cnoremap:tabnew <C-R><S-"><bs><CR>
Please drop you comments/suggestions?
The : command line prompt is "Command-line-mode" (see :h Command-line-mode, :h cmdline, or :h : [all show the same help]). You can map keys in that mode using :cnoremap. So you seem to be looking for this:
:cnoremap <s-p> <c-r>"<bs>
The backspace at the end removes the trailing end-of-line character that is (probably) at the end of the buffer.
I very strongly suggest you use a different mapping than <s-p>, because that will be triggered every time you try to type a capital "P".
Occasionally I have to work with mixed Unix/DOS files in Vim. That file will show ^M on the end on most of the lines. I can't convert the whole file to just Unix format.
Fix for that is :e ++ff=dos
I have tried to incorporate that in my vimrc at least as a shorcut (if not autocmd) but without success.
ga for ^M will show:
<^M> 13, Hex 0d, Octal 15
This won't work from vimrc:
function! Fix_dos()
execute "normal :e ++ff=dos<cr>"
endfunction
I have tried something with conceal feature, but that won't conceal all ^M chars.
:set conceallevel=2
:syntax match Todo /\r/ conceal
Also, is there a way to detect if file will show ^M chars?
Thanks for your help.
If you do :e +ff=dos, you convert the file to DOS format; i.e. after writing, all line endings will be converted to CR-LF. You've mentioned that you cannot convert to the whole file to Unix format, but if converting to DOS is okay, then this is the solution.
For your function, you don't need to go through :normal, as the :e command is an Ex command, and those can be directly used in a function. You only need :normal for normal-mode commands like dd. Therefore, you can rewrite:
function! Fix_dos()
" This would be the correct syntax, but no need for :normal:
"execute "normal :e ++ff=dos\<cr>"
" Also, no need for execute:
"execute "e ++ff=dos"
edit ++ff=dos
endfunction
In fact, I would define:
:command! FixDos edit ++ff=dos
If you cannot covert the entire file, you'll have to live with the ^M; best you can do is trying to hide them, as you've tried with concealing. This variant might catch more instances of ^M by also appying inside other syntax groups:
:syntax match Todo /\r/ conceal containedin=ALL
Opening a buffer in DOS fileformat does not convert the file to UNIX format. It is only sufficient if you wish to edit the buffer as DOS, and write it as DOS too. Hiding ^M also doesn't convert - your questions gives me the impression you think it does.
If you want to convert to LF-line-endings-only,
Remove all ^M characters: :%s/<C-V><cr>//ge<cr>. You can incorporate that in a function or autocommand.
Mark the buffer to use only LF line endings: :setlocal ff=unix
If you want to avoid having to press a key before your file opens:
"Press ENTER or type command to continue"
Run the command silently, like this:
com! SetFileFormatDos edit ++ff=dos
:silent SetFileFormatDos
Also, note the uppercase "S" from SetFileFormatDos.
I mostly use vim from the terminal by vi command.
I want to create and save a file named something like getting started.txt (there is space between two words). I tried two methods:
Method #1
:sav getting started.txt
but I got an error : E172: Only one file name allowed
Method #2
:sav "getting started.txt"
This time I got : E471: Argument required
How can I achieve what I want?
Escape the space character:
:sav getting\ started.txt
Commenter #ib mentions fnameescape, here's how you can use it:
Enter :save and a space.
Press Ctrl-R then = to enter expression mode.
Enter fnameescape("Your spacey, special character'y file name"). Tab expansion works, so you can probably do fnTabeTab.
Press Enter to insert the escaped file name into your command line.
Poster iler.ml suggests a function to do this easily (I've modified his code slightly). Put this in your .vimrc:
" :W and :Save will escape a file name and write it
command! -bang -nargs=* W :call W(<q-bang>, <q-args>)
command! -bang -nargs=* Save :call Save(<q-bang>, <q-args>)
function! W(bang, filename)
:exe "w".a:bang." ". fnameescape(a:filename)
endfu
function! Save(bang, filename)
:exe "save".a:bang." ". fnameescape(a:filename)
endfu
I want to pipe the selected text to a shell command and receive the one-line output from this shell command on the vim info/command line?
What I'm really trying to do: Pipe the selected text to a pastebin-type shell command and I want to receive the output of the shell cmd (which is the http link to the pastebin). Is this possible?
For multi line version you can do this after selecting the text:
:'<,'>:w !command<CR>
See the official Vim docs at :help :w_c.
You can map it to simple Visual mode shortcut like this:
xnoremap <leader>c <esc>:'<,'>:w !command<CR>
Hit <leader key>+c in visual mode to send the selected text to a stdin of the command. stdout of the command will be printed below vim's statusbar.
Real world example with CoffeeScript:
https://github.com/epeli/vimconfig/commit/4047839c4e1c294ec7e15682f68563a0dbf0ee6d
Simply highlight the lines using visual line select shift-v, the hit :! and type the command you wish to send the commands to. The resulting output will then replace your selected text.
When you type your command it will appear at the bottom as:
:'<,'>!somecmd
the '<,'> is indicating that the range you have visually selected will be passed to the command specified after the !
I would do it like this:
Place this function in your vimrc:
function Test() range
echo system('echo '.shellescape(join(getline(a:firstline, a:lastline), "\n")).'| pbcopy')
endfunction
This will allow you to call this function by doing:
:'<,'>call Test()
Then you can also map that like this (just under the function declaration in your vimrc):
com -range=% -nargs=0 Test :<line1>,<line2>call Test()
So you can call the function doing this:
:'<,'>Test
Note: :<','> are range selectors, in order to produce them just select the pertinent lines in visual mode and then go to command mode (pressing the colon key)
Maybe you should use something like
:echo system('echo '.shellescape(#").' | YourCommand')
Starting from some vim-7.4 version it is better to use
:echo system('YourCommand', getreg('"', 1, 1))
. This is basically the only way to keep NUL bytes untouched should they be present in the file. Passing #" in one or the other way will transform NUL bytes into NL (newline).
#matias 's solution is not work well for me, because it seems shellescape will append \ to each line.
So I use sed to accomplish this, and it works just fine!
"dump selected lines
function! DumpLines() range
echo system('sed -n '.a:firstline.','.a:lastline.'p '.expand('%'))
endfunction
com! -range=% -nargs=0 Dump :<line1>,<line2>call DumpLines()
An imperative way to do it is to:
yank your selection
drop into command mode with :
! + paste the register in the command-line like <Ctrl> r "
So: y : ! <Ctrl> r "
Another answer:
function Pastebin() range
let savedreg=#"
silent execute a:firstline.",".a:lastline."yank"
python import vim, subprocess
python p=subprocess.Popen(["pastebin"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
python p.stdin.write(vim.eval('#"'))
let #"=savedreg
python p.stdin.close()
python retstatus=p.poll()
python print p.stdout.read()
endfunction
Requires python support. Use it just like matias' function.