Delete till end of current parenthesis block in vim - linux

Say I am editing this json
{
"a": {"language": "python"},
"b": {},
"c": {"language": "java"},
"d": {"encoding": "utf-16"}
}
My cursor is at b of "b": {}. I want to delete till the end of current {} block. So it'll look like,
{
"a": {"language": "python"},
"
}
Looks little odd. But explains what I want.
How can I do that in Vim?

You can use d]}.
From :help ]}:
*]}*
]} go to [count] next unmatched '}'.
|exclusive| motion.
The help also says that this is one of the motion's use case:
The above four commands can be used to go to the start or end of the current
code block. It is like doing "%" on the '(', ')', '{' or '}' at the other
end of the code block, but you can do this from anywhere in the code block.

for your example, d]] works too. It is easier to press.
However, ]} is better, since it works no matter which column the { or } sits on.

Related

Sublime Text 3 Replace with regular expression

How to add string pieces to existing strings in Sublime Text 3?
Example: I have a text with strings like (23aa67) or (ret457) and I would like to transform them into \as{(23aa67)} or \as{(ret457)}.
Is it possible?
This solution will work if you have at least build number 4107 - you can tell by selecting Help → About Sublime Text.
Open your key bindings by selecting Preferences → Key Bindings. The pane on the right is your user key bindings file, and may simply look like this:
[
]
Position your cursor between the brackets and paste in the following:
{
"keys": ["ctrl+alt+super+a"],
"command": "chain",
"args":
{
"commands":
[
{
"command": "expand_selection",
"args": {"to": "smart"}
},
{
"command": "insert_snippet",
"args": {"contents": "\\as{${0:$SELECTION}}"},
}
]
},
"context":
[
{
"key": "selector",
"operator": "equal",
"operand": "text.tex",
"match_all": true
}
]
}
Here's how it works: The key combo CtrlAltSuperA (where Super is the Windows key) initiates two commands - expand_selection and insert_snippet.
You place your cursor between the two parentheses of your original text, and expand_selection expands the selection to include all of the text plus the opening and closing parens.
The second command wraps the selection - ${0:$SELECTION} - with \as{ at the beginning and } at the end. The "context" at the end only allows the command to run in TeX/LaTeX files. This can be removed if you'd like access to it everywhere.
If you want to change the key binding from CtrlAltSuperA to something else, just be sure that you're not overriding another keybinding. The FindKeyConflicts plugin is great for figuring that out.
Make sure you save the key bindings file when you're done. This shortcut will even work with multiple selections, so you can put multiple cursors in multiple places throughout your text, hit the key combo once, and they'll all be wrapped.
Using regular expression, you can do:
Ctrl+H
Find: (\(.+?\))
Replace: \\as{$1}
Replace all
Explanation:
( # start group 1
\( # opening parens, have to be escaped as it has special meaning in regex
.+? # 1 or more any character, not greedy
\) # closing parens
) # end group 1
Replacement:
\\ # backslash, have to be escaped
as{ # literally
$1 # content of group 1
} # literally
Screenshot (before):
Screenshot (after):

Move Cursor Immediately Before a Character on a Line in Vim

Say I have the following:
text function(contents) text
and I wanted it to be
text function() text
Placing the cursor right after the opening parenthesis, I thought the following command would work df); however, what I ended up with was the following
text function( text
So I would need someway to specify that I want the character just before the closing parenthesis, but I'm not sure how to do that. There may also be a better way to do this.
What would be the best way to go about this?
You were close! You need dt) as in delete till )
The f motion places the cursor on the ) (remember it like find)
As for the 'best' way to do it, there is at least a more general way: if the
cursor were somewhere in the middle of the ( and ) (or on one of them), you
can do di) (or equivalently di() to delete inside )
If you do da) (or equivalently da() to delete around ), you would
delete the stuff in between and including the brackets.
The same goes for di[, di{, di<, di', di" etc. Using these so-called
text objects, as opposed to the d{motion} way, has the advantage that you can
repeat the edit on other pairs of brackets/quotes without the cursor needing to
be in precisely the same place - it just needs to be on or in between them.
In the following you could position the cursor on e.g. the 'i' of 'initial' in
the first line, do di) to delete the words 'some initial text', then move the
cursor to the 'e' in 'more' in the second line and just do . to also delete
the words 'some more text'):
(some initial text)
(some more text)
This way also works when the brackets (or quotes) are on different lines. For
example, with the cursor somewhere between the {}, doing di} will change
this:
function( args ) {
body of function
}
to this:
function( args ) {
}

The vscode vim extension does not write real characters?

I have customized the vim-extension in vscode, and for most modes, it executes commands correctly. However If I try to write actuall characters (which are thus no longer commands), it won't. Why is that?
Example:
"vim.insertModeKeyBindingsNonRecursive": [
{
"before": [
"<leader>",
"o"
],
"after": [
"<Esc>",
"i",
"Abcd"
]
},
]
This should only write Abcd, because before that sequence is i, switching into insert mode. (So the <Esc> -> i, is redundant, it is here just as example). The vscode vim extension executes the <Esc> and also the i (becuase I know after that command I am back in insert mode), but will not print the Abcd. Why? Is the extension configured just to execute commands and not to actually print something? How to enable that?
It looks like you just need to split each character of the "Abcd" on to a separate line:
"vim.insertModeKeyBindingsNonRecursive": [
{
"before": [
"<leader>",
"o"
],
"after": [
"<Esc>",
"i",
"A",
"b",
"c",
"d"
]
},
]
As mentioned in the documentation of the project, you are supposed to pass a single key character (single character for normal key and multiple characters for special keys such as arrow keys or escape keys).
Updating after value will solve the issue:
"after": [
"<Esc>",
"i",
"A", "b", "c", "d"
]
You can take a look at the internals of the plugin to understand why it is not working with multiple characters passes in here, specifically NormalizeKey function, which would wrap any string with multiple characters with <>.

Vim, practical usage example

While I mostly use Sublime Text (with the Vintageous plugin) I'm trying to adopt Vim-style practices into my workflow. As you might expect, I'd like to learn how to more quickly jump around a document to edit its content.
For example, let's say I want to jump around and edit the ID values in a JSON file or perhaps jump from the first line of the document down to edit the first name of Gale Gomez.
I understand some of the basic commands like 'change inside quotes' (ci") or 'change word' (cw), I'm hoping to get better at page navigation.
Thoughts or suggestions?
{
"id": 5,
"firstName": "Jayne",
"lasttName": "Norris",
"email": "jaynenorris#talae.com"
},
{
"id": 6,
"firstName": "Gale",
"lasttName": "Gomez",
"email": "galegomez#talae.com"
},
{
"id": 7,
"firstName": "Garner",
"lasttName": "Crane",
"email": "garnercrane#talae.com"
},
{
"id": 7,
"firstName": "Gill",
"lasttName": "Carter",
"email": "gillcarter#talae.com"
},
{
"id": 8,
"firstName": "Evans",
"lasttName": "Douglas",
"email": "evansdouglas#talae.com"
}
To jump to the next ID and edit it:
/"id<return>3wcw
(searches for string "id, goes forward 3 words, then edits the next word, which is the ID's value)
To edit another ID:
n3wcw
(repeats the last search with “n”, then same as before)
Go to the first line of the document:
gg
Change first name of Gale Gomez:
/Gale<return>cw
(searches for “Gale”, then edits it)
And don't forget * to search the word under the cursor (for example id in your case), then n for next occurrence, N for previous occurrence.
# is the same as *, only it searches backward. Actually, I never use that.
If you press / and then <UP> and <DOWN>, then <CR>, you can select and repeat one of your previous searches.
And sometimes when a search hits the last line of the window you may wish to type zz to scroll the window so that the current line will be in the middle of it and you will see some lines below.
Also, you can press % while over an opening/closing parenthesis to jump to the corresponding closing/opening parenthesis.

Linewise inclusive delete up to a pattern

Suppose you want to delete a C function from its name up to and including the line with the closing curly:
int main (void) /* Cursor on this line. */
{
while (...) {
...
}
}
I have tried d/^}<CR> but this does not delete the line with the closing curly. How can I have an inclusive find pattern delete? I must be missing something simple.
Edit You can assume the function's closing curly is at the start of a line and other curlies are never.
I just did a quick search and found the offset syntax of the / operator here.
d/^}/0
did the trick for me. It means "find the matching pattern, then select to the end of the 0th line after it" (i.e. the end of the line it is found on)
Use V][d.
It means:
V: Enter in Visual Mode.
][: Move until next }
d: Delete all visual selection.
Your command won't work on functions that have nested braces. I would delete to the first '{' with 0d]], followed by daB to delete the block.
Details for new vimmers: The '0' in the first command makes sure you're at the start of the line before editing the d command. ']]' is a motion that gets you to the next block, and 'aB' is a selecting motion that selects the whole block, including nested blocks. So 0d]]daB means delete from the start of the line to the next block, then delete the block.
You could do jVaBokd
j - move down a line
VaB - visual line select on outer block
o - move to the opposite end of the visual selection
k - move up a line
d - delete selection

Resources