Enclosing curly braces in parenthesis with Vim? - vim

How to enclose curly braces in parenthesis in vim?
Initial string:
{a: b}
Final string:
({a: b})
The string possibly span multilines:
{
a: b
}

Assuming you are in normal mode and on any curly bracket character (opening or closing).
The manual/vanilla version (without any bracketing plugin) would be
c%(^R")
With:
^R meaning CTRL+R
the default register (") being filled with the content of the dictionary.
ca{ that should be used instead of c% if you're anywhere within the dictionary.
With my lh-brackets plugin, I would use v%( or vi{( -- unlike the vanilla version, will leave the default register unmodified.
With the popular surround plugin, I guess (I may be wrong as I've been using my plugin for decades) it would be something like ys%( or ysa{(.
PS: the fact your dictionary spans on several lines doesn't make any difference here.

With the vim-surround plugin you can visually select the text first e.g. va{, then surround with parentheses using S). I find it easier to remember this visual surround sequence v{motion}S<char> than the other options

Related

Disable matching single quote in Atom Text Editor

How to selectively disable atom from creating a matching single quote and and backtick? This helps in programming in Scheme.
I tried Settings>Package>Bracket Matcher, if I disable Autocomplete bracket then it also disables matching brackets and matching double quotes. I want matching brackets and matching double quotes but not matching single quotes.
EDIT: This feature is now available in Atom.
The feature that you want is now available. Just delete the quotes from the Autocomplete Characters in Bracket Matcher package settings.
Edit -> preferences
from left choose packages
there is a search bar at the top search for Bracket-Matcher
then press setting from right side
look foo settings section and in that section look for something called auto Brackets. Uncheck it.
Unfortunately, it's an all or nothing deal (as of version 0.82.0).
Unchecking the "Autocomplete Brackets" box means no autocompleted closing single/double quotes, brackets, backticks, or parentheses.
You could always log an issue (search first and make sure one doesn't already exist) and request that this feature be extended.

How to delete enclosing braces in Vim?

I have the following text:
Monkeys eat {bananas}.
My cursor is in the middle of the word banana:
Monkeys eat {bana|nas}.
Here the | symbol denotes the cursor's position.
How can I delete the braces from there?
I can change bananas to apples with a simple ci}apples, so perhaps I could use a similar trick just to get rid of the { and } characters?
Also, can I do this even in this case, which is actually what I really need to do?
networks {
local
is|p
}
(The simplified example above was just to introduce the concept.)
Using Tim Pope's excellent surround.vim plugin (which I highly recommend), you would do ds{ for delete surrounding {
I understand that adding another plugin isn't always the ideal solution when you could find a native key sequence instead, but surround.vim is supremely useful, as it can also handle XML/HTML tags and perform enclosures on complex text objects. I regard it as one of those "stuck on a desert island, must have under any circumstance" plugins.
The task can be accomplished by means of Vim built-in text motions.
Delete the text inside the braces, select the braces, and paste the
previously deleted text over them:
di{v%p
What about this:
yiBvaBp
No plugin and simple.
Delete the braces and leave everything else?
mz[{x]}x`z
Expanded
:help m - set a mark. In this case marking the initial cursor position so I can go back there at the end. :help [{ - moves the cursor to the opening brace of the smallest block enclosing the cursor. :help x - delete the brace which is now under the cursor. ]} and x - doing the same to the closing brace. And finally
help `
returning to marked position, the one called z created at the start.
"Plugins" aren't my style...

How to substitute for matching delimiters in vi?

I have some text which has matched delimiters (in this case, curly braces, and the text happens to be LaTeX, which is only incidental):
\nb{\vec{n},\vec{y}} \in \vec{z}
What I'd like to do is globally replace \nb{...} with (...), while respecting the nesting of delimiters. I.e., the result should be
(\vec{n},\vec{y}) \in \vec{z}
and not
(\vec{n},\vec{y}} \in \vec{z)
which is what would be produced by :%s/\\nb{\(.*\)}/(\1)/g. Standard regular expressions can't handle matched delimiters, so I wasn't expecting this way to work. Is there some vi-specific trick I can use to do this?
If you have surround.vim installed then the following should do the trick
:set nowrapscan
:let #q="/\\m\\\\nb{/e+1\<cr>cs{)dF\\#q"
gg#q
If you do not:
:set nowrapscan
let #q="/\\m\\\\nb{<cr>dt{yi{\"_ca{()\<esc>\"0P#q"
gg#q
Overview
Create a recursive macro that searches for \nb{, positions the cursor just inside the {, replace the }{'s with ()'s.
Glory of Details
:set nowrapscan this prevents searches from looping back around the file.
:let #q="..." store our macro inside the q register
/\m\nb{/e+1 searches for \nb{ and positions the cursor after the {
cs{) the surround version will just change the surrounding { with )
#q run the macro again
Used " so must escape a few things so they work correctly.
gg#q go to the top of the file and execute the macro in register q
The non surround version varies a bit here
yi{ copy the text inside {'s
"_ca{()<esc> change the text inside and including the {'s and replace with ()
"0P paste what we just copied inside the ()
I would use the following :global command.
:g/\\nb{/norm!/^M%r)[{r(dF\\
Type ^M as Ctrl+V, Enter.

In vim, is there a plugin to use % to match the corresponding double quote (")?

The % key is one of the best features of vim: it lets you jump from { to }, [ to ], and so on.
However, it does not work by default with quotes: Either " or ', probably because the opening and closing quote are the same character, making implementation more difficult.
Thinking a bit more about the problem, I'm convinced that it should be implemented, by counting if the number of preceding quotes is odd or even and jumping to the previous or next quote, accordingly.
Before I try to implement it myself, I'd just like to know if someone already has?
Depending on your reason for needing this, there may be a better way to accomplish what you're looking for. For example, if you have the following code:
foo(bar, "baz quux")
^
and your cursor happens to be at the ^, and you want to replace everything inside the quotes with something else, use ci". This uses the Vim "text objects" to change (c) everything inside (i) the quotes (") and puts you in insert mode like this:
foo(bar, "")
^
Then you can start typing the replacement text. There are many other text objects that are really useful for this kind of shortcut. Learn (and use) one new Vim command per week, and you'll be an expert in no time!
Greg's answer was very useful but i also like the 'f' and 'F' commands that move the cursor forward and backward to the character you press after the command.
So press f" to move to the next " character and F" to move to the previous one.
I have found this technique very useful for going to the start/end of a very long quoted string.
when cursor is inside the string, visually select the whole string using vi" or vi'
go to start/end of the string by pressing o
press escape to exit visual select mode
this actually takes the cursor next to the start/end quote character, but still feels pretty helpful.
Edit
Adding Stefan's excellent comment here which is a better option for anyone who may miss the comment.
If you use va" (and va') then it will actually visually select the quotes itself as well.
– Stefan van den Akker
I'd like to expand on Greg's answer, and introduce the surround.vim plugin.
Suppose that rather than editing the contents of your quotes, you want to modify the " characters themselves. Lets say you want to change from double-quotes to single-quotes.
foo(bar, "baz quux")
^
The surround plugin allows you to change this to
foo(bar, 'baz quux')
^
just by executing the following: cs"' (which reads: "change the surrounding double-quotes to single-quotes").
You could also delete the quote marks simply by running: ds" (which reads: "delete the surrounding double-quotes).
There is a good introduction to the surround plugin here.
I know this question is old but here is a plugin to use % to match the corresponding double quote:
https://github.com/airblade/vim-matchquote

How to select between brackets (or quotes or ...) in Vim?

I'm sure there used to be a plugin for this kinda stuff, but now that I need it, I can't seem to find it (naturally), so I'll just ask nice and simple.
What is the easiest way to select between brackets, or quotes, or generally a list of matching characters?
write ( *, '(a)' ) 'Computed solution coefficients:'
For example, here I'd like to select (a), or Computed solution coefficients:.
I'm not interested in multiline, just cases which occur on one line.
To select between the single quotes I usually do a vi' ("select inner single quotes").
Inside a parenthesis block, I use vib ("select inner block")
Inside a curly braces block you can use viB ("capital B")
To make the selections "inclusive" (select also the quotes, parenthesis or braces) you can use a instead of i.
You can read more about the Text object selections on the manual, or :help text-objects within vim.
Use whatever navigation key you want to get inside the parentheses, then you can use either yi( or yi) to copy everything within the matching parens. This also works with square brackets (e.g. yi]) and curly braces. In addition to y, you can also delete or change text (e.g. ci), di]).
I tried this with double and single-quotes and it appears to work there as well. For your data, I do:
write (*, '(a)') 'Computed solution coefficients:'
Move cursor to the C, then type yi'. Move the cursor to a blank line, hit p, and get
Computed solution coefficients:
As CMS noted, this works for visual mode selection as well - just use vi), vi}, vi', etc.
This method of selection is built-in and well covered in the Vim help. It covers XML tags and more.
See :help text-objects.
For selecting within single quotes use vi'.
For selecting within parenthesis use vi(.
Use arrows or hjkl to get to one of the bracketing expressions, then v to select visual (i.e. selecting) mode, then % to jump to the other bracket.
I wanted to add to the already good answers. I came here looking for a way to change the text inside of html brackets, so I want to provide an answer for anyone else that is also looking for that.
You might think ci< would work, but actually that only works if you are inside one of the tags themselves:
<would work inside here> But not here </would work inside here>
What I wanted was to change the text between the html tags themselves:
<div>change me</div>
What I wanted was "change inner tag": cit
Thank you to the other answer that mentioned the documentation (:help text-objects) which is how I found what I was looking for.
Write a Vim function in .vimrc using the searchpair built-in function:
searchpair({start}, {middle}, {end} [, {flags} [, {skip}
[, {stopline} [, {timeout}]]]])
Search for the match of a nested start-end pair. This can be
used to find the "endif" that matches an "if", while other
if/endif pairs in between are ignored.
[...]
(http://vimdoc.sourceforge.net/htmldoc/eval.html)
I would add a detail to the most voted answer:
If you're using gvim and want to copy to the clipboard, use
"+<command>
To copy all the content between brackets (or parens or curly brackets)
For example: "+yi} will copy to the clipboard all the content between the curly brackets your cursor is.
Stop at the beginning of brackets, and to select all and print
vi'
vi(
vi[
vi{
vi<
vi"
if you want to delete replace vi with di
I've made a plugin vim-textobj-quotes: https://github.com/beloglazov/vim-textobj-quotes
It provides text objects for the closest pairs of quotes of any type. Using only iq or aq it allows you to operate on the content of single ('), double ("), or back (`) quotes that currently surround the cursor, are in front of the cursor, or behind (in that order of preference). In other words, it jumps forward or backwards when needed to reach the quotes.
It's easier to understand by looking at examples (the cursor is shown with |):
Before: foo '1, |2, 3' bar; after pressing diq: foo '|' bar
Before: foo| '1, 2, 3' bar; after pressing diq: foo '|' bar
Before: foo '1, 2, 3' |bar; after pressing diq: foo '|' bar
Before: foo '1, |2, 3' bar; after pressing daq: foo | bar
Before: foo| '1, 2, 3' bar; after pressing daq: foo | bar
Before: foo '1, 2, 3' |bar; after pressing daq: foo | bar
The examples above are given for single quotes, the plugin works exactly the same way for double (") and back (`) quotes.
You can also use any other operators: ciq, diq, yiq, viq, etc.
Please have a look at the github page linked above for more details.
A simple keymap in vim would solve this issue.
map viq F”lvf”hh
This above command maps viq to the keys to search between quotes. Replace " with any character and create your keymaps.
Stick this in vimrc during startup and you should be able to use it everytime.

Resources