Reference selection in Vim command mode to pass on to terminal - vim

Is there something like % (that represents the whole buffer in Vim command line) for the current selection, so that I can do something like: :# sort (Imagine # represents the selection).
EDIT:
Sorry, I missed to mention that I am requesting for a way to operate on block selections not on ordinary selections that can be operated using ranges '<,'>.

Yes. Example:
:'<,'>!sort
The range :'<,'> represents the visually selected lines.
:* is shorthand for :'<,'>
If you hit : while in visual mode it will start the command with '<,'>
For more help see:
:h '<
:h v_:
:h range

You are probably looking for the marks '< and '>:
:'<,'>sort
If you just select a few lines and hit : to enter the command line these marks should appear automatically.

As others have already remarked, the visual selection is represented by the '<,'> range (there's also the :* short form). However, as all ranges, this always covers entire lines, even if the selection is only characters or a block.
Most Ex commands (like :sort) only operate on full lines, for :substitute, you can limit the effects to the visual selection by including the special \%V atom in the search pattern, cp. :help /\%V.
The idea to make Ex commands handle blockwise selections is old, but unlikely to be tackled any time soon.

Related

How to execute specific regex substitution on selected lines in visual mode in vim

I want to replicate the VS code feature of 'highlight and comment out code' (usually bound to keys SHIFT + /) in vim.
I can run :g//s/^/\/\/ / in normal mode to prepend // at the start of every line. I just want to put a constraint on this so it only applies the substitution to lines highlighted in visual mode.
Visually select all the lines (using V), then hit :.
This will give you :'<,'> which is the range of your visual selection.
Then you can add your vim command to it.
I would recommend the following method if you wish to not use plugins.
:'<,'>normal I//
Which is not a substitution.
If you want a really nice vim plugin that does this task in a vim manner, check out tpope's vim-commentary which is an essential in my opinion.
I can run :g//s/^/\/\/ / in normal mode to prepend // at the start of every line.
Well, that would be an unnecessarily complicated way to do it and your command wouldn't really work anyway.
:g// either matches nothing or it matches the previous search. What you want, here, is probably something like :g/^/ or :g/$/.
A simple substitution on the whole buffer would be much simpler and much faster:
:%s/^/\/\/ /
Using :help :global in this context provides no value (you want to operate on every line anyway) and is considerably slower (we are talking thousands of times slower)
You can use alternative separators to avoid all that backslashing:
:%s#^#// #
The last separator is not even needed:
:%s#^#// <-- there is a space, here
And the kicker: you can enter command-line mode from visual mode like you would do from normal mode, by pressing :. So you can simply make your visual selection, press :, and run your substitution:
v " enter visual mode
<motion> " expand the selection
: " press :
:'<,'> " Vim inserts the range covering the visual selection for you
:'<,'>s#^#// <CR> " perform your substitution

Vim: colon appends .,.+3

Sometimes when entering :, vim appends .,.+3 to it, preventing me from executing a command. I couldn't find anything about this behaviour online, is there a way to get do away with it? At the moment, I use vim 8.0 (in iTerm2) but it also used to occur in earlier versions.
This happens when you typed a number before the colon. Vim interprets it as the number of lines on which you want your ex command to operate.
If you press 4: you get :.,.+3 which is a range that covers the current line (.) and the three lines below the current line (.+3).
That behavior is old and documented in :help N: (:help :range is an interesting read, too).
If you want to get rid of that range, see :help <C-u>.

All occurrences of text between quotes (like * but for the whole text, not a single word)

When I edit XML-files I sometimes want to jump to the next occurrence of text between quotes. For example, when my cursor is on my.attr in attr="my.attr" I want to jump to the next occurence of my.attr. I want to do it via some key combination (like Shift + * which is for words occurrences). Is is possible?
You can create a visual selection of the attribute value inside double quotes with vi". Then, there are several plugins that implement the * command for visual mode (usually by overloading the * command), i.e. they search for the next occurrence of the selected text. One such plugin is my SearchHighlighting plugin. (The plugin page has links to alternative plugins.)
Related plugins
If you want to change all attribute values (without constructing a :%s/ substitution), my ChangeGlobally plugin provides a gc{motion} and {Visual}gc command that does that.
I would yank the text inside the quotes with yi" (only works if the opening and closing quotes are on the same line) and then /<C-R>". (The <C-R> means CTRL-R, not 5 characters.)
This gives you a chance to modify the pattern before submitting it; as #Kalanidhi pointed out, you may have to escape some special characters. It uses the same i" text object as in #Ingo Karkat's answer.
If your text is short, then you can edit the command line with the arrow keys, but if it is long you may want to edit it in a command-line window with <C-F>. (Alternatively, if you are thinking ahead, use q/ instead of /.)
:help y
:help text-objects
:help c_CTRL-R
:help cmdline-editing
:help cmdline-window
You can use in command mode type /<exact pattern> if any special character then escape the special character like \
For example In command mode /"my\.attr"
So only search the exact pattern. N or n to move forward and backward .

Vim: yank and paste line and maintain column postition

Background: I am editing a reStructuredText table in vim. I would like to yank a line and paste it. The line only contains cell vertical delimiters (|) so this operation corresponds to giving an existing row one more line of space in the source, but doesn't alone affect the output. A simple yyP or yyp, puts the cursor to column 1 after the operation.
Q: Is there an easy way to "yank and paste a line" and keep the cursor in the same column after the operation as before it?
After I wrote the question, it dawned on me to use a mark, and indeed that works: I can do mayyP and then `a to jump back to the desired column. That's a bit long though. So the question is, can I do this with less keystrokes?
Edit: As Shahbaz rightly points out, I can just write an alias, now I know how to do what I want. I am still interested in any shorter way that uses standard commands, in case I am missing some functionality that I should know about.
As #romainl says, you should :set nostartofline (or :set nosol for short). Then, instead of yyp, use the :copy command:
:copy .
:copy -
If :copy is too long, you can use :co or :t. If you do not use any ex commands in between, then you can repeat the command with #: and then with ##.
:help :copy
:help #:
:help #
:set nostartofline
See :help startofline.
You could record a simple macro like
qamayyP`aq
This writes your command to the register a and lets you replay it with the command #a.

Configure Macvim's text selection to not include character under cursor

Using macvim, when I copy a text selection, it always includes the character under the cursor.
For example, if the cursor is at the far left and I press shift-down arrow, it selects the entire line plus the first character of the next line (since the cursor is sitting over the next line's first character).
Is there a way to configure macvim to not include the cursor character in text selections?
Take a look at the selection option. By default it's set to inclusive, but you can change it to exclusive to make text selections act the way you want:
:set selection=exclusive
You can also set it to exclusive with the behave command:
:behave mswin
This also sets several other options, however, which may or may not be what you want. See the Vim help for the specifics.
:help :behave
:help 'selection'
I am guessing that shift-down arrow activates visual character mode, and moves the cursor down a line. If you are trying to select entire lines, you would be better off using visual line mode, which is activated from normal mode by pressing V (shift-v). This will select the current line in its entirety. You can then extend your selection to include the lines above and below using the k (or up arrow) and j (or down arrow) keys.
When using Vim, I think it is better to go with the grain rather than to fight against it. Don't expect it to work the same way as other text editors. Accept that the Vim way is different.

Resources