gvim: passing the visually-selected text to the command line - command-line

I use gvim to store recipes of commands that I will execute, depending on output. Currently, I select the text in gvim and paste the commands into a terminal console, but I bet there's a way I can pass the visually selected range into a command-line for execution.

Assuming you mean the Vim command line:
(if you mean the OS command line, see below).
For parts of lines (i.e. no end of line character), you could do something like this:
" Visually select lines, then:
y:<C-R>"<ENTER>
where <C-R> means press Ctrl+R. The y 'yanks' the selected text, the : enters command mode, <C-R>" pulls the contents of the " (last yanked text) register onto the command line and <ENTER> (obviously) runs the command.
If you want to do line-wise stuff, it's a bit more complicated (as the command line doesn't like ^Ms in the command). I'd recommend something like this in your vimrc:
function! RunCommands()
exe getline('.')
endfunction
command -range RunCommands <line1>,<line2>call RunCommands()
vmap ,r :RunCommands<CR>
Select the lines (after restarting vim) and press ,r.
Another way that you may find useful is to copy the lines you want, hit q: to open the command line window and paste the lines you want into there and then move the cursor over the line you want and press ENTER. This has the advantage that you can edit the command before pressing ENTER. It'll only run one command at a time.
If you mean an (e.g.) Windows or Linux command line:
Use the function I listed above, but instead of:
exe getline('.')
use
call system(getline('.'))
or, if you want to see the result:
echo system(getline('.'))
or
echomsg system(getline('.'))
For more information:
:help :echo
:help :echomsg
:help :messages
:help :vmap
:help :command-range
:help :command
:help :function
:help c_CTRL-R
:help :exe
:help getline()
:help system()

If you are using the vim GUI, you can do set guioptions+=a. This way, any highlighted text inside gvim in visual mode gets pasted to a clipboard.

Related

How to open a file and select/highlight several lines on Sublime from the command line?

I know subl myfile.txt:5 would open “myfile.txt” on line 5. I however want to be able to, from the command line, open a file with say lines 5,9,15 highlighted or selected. I know adding –command should enable me to do that, but how? What would the command be?
There's no built-in command that I know of that can do this, but one can easily create one.
(Technically, it could be done using the bookmarks functionality from the Default package, and the built-in "Expand Selection to Line" functionality. However, experience shows that it would be better and more reliable to write a command in ST specifically for this purpose.)
In ST:
from the Tools menu -> Developer -> New Plugin...
select all and replace with the following
import sublime
import sublime_plugin
class SelectSpecificLinesCommand(sublime_plugin.TextCommand):
def run(self, edit, lines):
self.view.sel().clear()
for line in lines:
position = self.view.text_point(int(line) - 1, 0) # internally, line numbers start from 0
self.view.sel().add(self.view.line(position))
save it, in the folder ST recommends (Packages/User/) as something like select_lines.py (file extension is important).
subl myfile.txt
subl --command "select_specific_lines { \"lines\": [5, 9, 15] }" (this style of escaping the quotes for JSON strings works from the Windows Command Prompt and Linux's Bash)
Why did I specify the command on a separate line / call to subl? Because of these 2 caveats:
ST must already be running, otherwise commands specified on the command line may not get executed, because the plugins haven't loaded yet.
the command could get executed before the file is loaded.
Arguably, point 2 could still happen with multiple invocations of subl, but hopefully it is less likely. There is an open issue on the ST bug tracker for better command line command handling: https://github.com/SublimeTextIssues/Core/issues/1457.

When using magic %paste in ipython, how can i get it to just paste the copied code, rather than paste and execute, so that it can be edited

When using magic %paste in ipython, it executes pasted code, rather than just pasting. How can i get it to just paste the copied code so that it can be edited?
You have two options:
To edit it by hand, run %cpaste. Then you can paste it in with standard terminal options (try Ctrl-Shift-V), and edit it. Enter -- on a line to finish.
To change it as text in your code, run %paste foo. It will store the clipboard contents in foo.
Adding to Thomas K's answer (quoted below), if you have stored statements to a string variable foo by using %paste foo, you can later run that string (or any python statements in string form) using the exec(foo [, globals, locals]).
You have two options:
To edit it by hand, run %cpaste. Then you can paste it in with standard terminal options (try Ctrl-Shift-V), and edit it. Enter --
on a line to finish.
To change it as text in your code, run %paste foo. It will store the clipboard contents in foo.
There is a solution for this issue in ipython, if you are not concerned with indentation,
Just run %autoindent to Automatic indentation OFF.

set commandline shortcut in tcsh for moving cursor by word

from How to move the cursor by word in command line of tcsh I know how to move cursor by word in tcsh, but they not easy to use, so can I set a shortcut on command line for example, when I use Ctrl+leftarrow, it actually works as Esc f?
To see a list of pre-defined key-bindings, visit:
http://www.csc.fi/english/pages/data-services/linux_basics/tcsh
To see a list of all commands which can be used to configure key-bindings, visit:
http://www.rohidekar.com/sridharsarnobat/mediawiki/index.php?title=TCSH_Key_bindings
Example: (Write this in your ~/.tcshrc)
bindkey '^[^[[C' forward-word
bindkey '^[^[[D' backward-word
This will bind the alt-right with forward-word and alt-left with backword-word.
To map to a different keyset, just run cat and hit enter. Hit the key-combination (in the above example, right-arrow and left-arrow), record the strings that are echoed back, and use these as the key combinations to bind.

Display Vim intermediate commands

In vimtutor Lesson 2.1: DELETION COMMANDS, there is a note after the #4 item:
The letter d will appear on the last line of the screen as you type it. Vim is waiting for you to type w. If you see another character than d you typed something wrong; press <ESC> and start over.
However, I do not see intermediate commands in the last line as the note says. How do I enable this? What option should I set in my .vimrc?
You can use
:set showcmd
That will display the commands as you type it in Vim.
The same can also be put into .vimrc
This 'last line' is the line at bottom of screen.
If you don't see this you may have trouble with (Linux?) terminal setting.
If you use terminal on Linux system, try to invoke command export TERM=Linux before running Vim.

How can I script vim to run perltidy on a buffer?

At my current job, we have coding-style standards that are different from the ones I normally follow. Fortunately, we have a canned RC file for perltidy that I can apply to reformat files before I submit them to our review process.
I have code for emacs that I use to run a command over a buffer and replace the buffer with the output, which I have adapted for this. But I sometimes alternate between emacs and vim, and would like to have the same capabilities there. I'm sure that this or something similar is simple and had been done and re-done many times over. But I've not had much luck finding any examples of vim-script that seem to do what I need. Which is, in essence, to be able to hit a key combo (like Ctrl-F6, what I use in emacs) and have the buffer be reformatted in-place by perltidy. While I'm a comfortable vim-user, I'm completely clueless at writing this sort of thing for vim.
After trying #hobbs answer I noticed that when filtering the entire buffer through perltidy the cursor returned to byte 1, and I had to make a mental note of the original line number so I could go back after :Tidy completed.
So building on #hobbs' and #Ignacio's answers, I added the following to my .vimrc:
"define :Tidy command to run perltidy on visual selection || entire buffer"
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy
"run :Tidy on entire buffer and return cursor to (approximate) original position"
fun DoTidy()
let l = line(".")
let c = col(".")
:Tidy
call cursor(l, c)
endfun
"shortcut for normal mode to run on entire buffer then return to current line"
au Filetype perl nmap <F2> :call DoTidy()<CR>
"shortcut for visual mode to run on the current visual selection"
au Filetype perl vmap <F2> :Tidy<CR>
(closing " added to comments for SO syntax highlighting purposes (not required, but valid vim syntax))
DoTidy() will return the cursor to its original position plus or minus at most X bytes, where X is the number of bytes added/removed by perltidy relative to the original cursor position. But this is fairly trivial as long as you keep things tidy :).
[Vim version: 7.2]
EDIT: Updated DoTidy() to incorporate #mikew's comment for readability and for compatibility with Vim 7.0
My tidy command:
command -range=% -nargs=* Tidy <line1>,<line2>!
\perltidy (your default options go here) <args>
If you use a visual selection or provide a range then it will tidy the selected range, otherwise it will use the whole file. You can put a set of default options (if you have any) at the point where I wrote (your default options go here), but any arguments that you provide to :Tidy will be appended to the perltidy commandline, overriding your defaults. (If you use a .perltidyrc you might not have default args -- that's fine -- but then again you might want to have a default like --profile=vim that sets up defaults only for when you're working in vim. Whatever works.)
The command to filter the entire buffer through an external program is:
:%!command
Put the following in ~/.vimrc to bind it to Ctrl-F6 in normal mode:
:nmap <C-F6> :%!command<CR>
For added fun:
:au Filetype perl nmap <C-F6> :%!command<CR>
This will only map the filter if editing a Perl file.
Taking hobbs' answer a step further, you can map that command to a shortcut key:
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
noremap <C-F6> :Tidy<CR>
And another step further: Only map the command when you're in a Perl buffer (since you probably wouldn't want to run perltidy on any other language):
autocmd BufRead,BufNewFile *.pl,*.plx,*.pm command! -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
autocmd BufRead,BufNewFile *.pl,*.plx,*.pm noremap <C-F6> :Tidy<CR>
Now you can press Ctrl-F6 without an active selection to format the whole file, or with an active selection to format just that section.
Instead of creating a new keyboard shortcut, how about replacing the meaning of the = command which is already in people's finger memory for indenting stuff? Yes, perlcritic does more than just indent but when you use perlcritic anyways, then you probably don't want to go back to the inferior "just indent" = command. So lets overwrite it!
filetype plugin indent on
autocmd FileType perl setlocal equalprg=perltidy
And now we can use = just like before but with the added functionality of perlcritic that goes beyond just indenting lines:
== run perlcritic on the current line
5== run perlcritic on five lines
=i{ Re-indent the 'inner block', i.e. the contents of the block
=a{ Re-indent 'a block', i.e. block and containing braces
=2a{ Re-indent '2 blocks', i.e. this block and containing block
gg=G run perlcritic on the entire buffer
And the best part is, that you don't have to learn any new shortcuts but can continue using the ones you already used with more power. :)
I'm used to select text using line oriented visual Shift+V and then I press : an I have !perltidy -pbp -et4 somewhere in history so I hit once or more up arrow ⇧.