Why does ci` jump into the backticks but ci( does not jump into braces? [duplicate] - vim

This question already has answers here:
Why ci" and ci(, ci{.... behave differently?
(2 answers)
Closed 6 years ago.
Suppose I have a textfile like this:
this is some test `more test`
this is some test (more test)
If I am at the beginning of the first line and type ci` the cursor will jump into the backticks, replaces the content inside and let's me edit.
However, if I am at the beginning of the second line and I type ci( nothing will happen.
What's the reason for this behavior? Is there a setting that might change it?

Concerning the internal behavior of vim 7.4:
For blocks (),{},[],<>:
Vim searches backwards and then forwards starting from current position to match the opening and closing character.
For quotes "", '', `` :
Vim spans the whole line, where the cursor is, till it finds the quotes.
Here is the last case where there is no quotechar under the cursor:
/* Search backward for a starting quote. */
col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe);
if (line[col_start] != quotechar)
{
/* No quote before the cursor, look after the cursor. */
col_start = find_next_quote(line, col_start, quotechar, NULL);
if (col_start < 0)
return FALSE;
}
/* Find close quote character. */
col_end = find_next_quote(line, col_start + 1, quotechar,curbuf->b_p_qe);

Related

How to take curly brace to end of previous line

I see many codes like following on the net:
public static void read()
{
using (StreamReader m_StreamReader = new StreamReader("C:\\myCsv.Csv"))
{
while (m_StreamReader.Peek >= 0)
{
string m_Str = m_StreamReader.ReadLine;
string[] m_Splitted = m_Str.Split(new char[] { "," });
Console.WriteLine(string.Format("{0}={1}", m_Splitted[0], m_Splitted[1]));
}
}
}
However, I want to convert above to following:
public static void read() {
using (StreamReader m_StreamReader = new StreamReader("C:\\myCsv.Csv")) {
while (m_StreamReader.Peek >= 0) {
string m_Str = m_StreamReader.ReadLine;
string[] m_Splitted = m_Str.Split(new char[] { "," });
Console.WriteLine(string.Format("{0}={1}", m_Splitted[0], m_Splitted[1]));
}
}
}
Hence starting curly brace is taken to the end of previous line. How can this be done programmatically in Vim? It tried but though I can pick up starting curly brace but could not manage to take it to end of previous line.
Note: above code is from here.
Joining the next line to the current line is done with :help J in normal mode or :help :join in command-line mode.
Joining the current line to the previous line is done in normal mode by moving the cursor to the previous line with - and then joining with J. In command-line mode, you would use -, short for .-1 ("current line number minus one"), as :h address for :join: :-j, which mirrors the normal mode method quite well.
To do this on the whole buffer, you need a way to execute a given command on every isolated opening brace. This is done with :help :g:
:g/^\s*{\s*$/-j
Breakdown:
:g/<pattern>/<command> executes <command> on every line matching <pattern>,
^\s*{\s*$ matches lines with a single opening braces and optional leading and trailing whitespace,
-j joins the current line with the line above.
But the result is not correctly indented anymore so you will need something like the following command to fix the mess:
gg=G
Breakdown:
gg moves the cursor to line 1,
=G re-indents every line from the cursor to the last line, see :help =.
That said, switching from one coding style to another seems like something that should be done with a dedicated tool rather than with general text editing.
The desired output looks strikingly similar to the ratliff style. If that's correct, astyle is one formatter that supports this particular style and this solution will be more robust than making changes manually.
You can wrap it in your own command as follows:
command! -buffer Fmt let winsaved = winsaveview() | execute '%! astyle --style=ratliff' | if v:shell_error > 0 | silent undo | endif | call winrestview(winsaved)

Vim - change up to and including searched string

Assuming I have the following code:
bool myCopiedFunc() {
Some code that I've written;
The cursor is on this line; <<<<<<<<<<<<<<
if (something) {
bool aValue;
some of this is inside braces;
return aValue;
}
if (somethingElse) {
this is also inside braces;
bool anotherValue;
{
more braces;
}
return anotherValue;
}
return false;
}
I decide I want to rewrite the remainder of the function, from the line with the cursor on it.
To replace up to a char on the same line, I can use ct<char> e.g. ct;
To replace up to and including a char on the same line I can use cf<char> e.g. cf;
To replace up to a string across multiple lines, I can use c/<string> e.g. c/return false
To replace up to and including a string across multiple lines, I can use... ?? e.g. ??
I can't just search for a semicolon, as there are an unknown number of them between the cursor and the end of the function, and counting them would be slow.
I can't just search for a closing brace, as there are several blocks between the cursor and the end of the function, and counting all closing braces would be slow.
With the help of code highlighting, I can easily see that the unique string I can search for is return false.
Is there an elegant solution to delete or change up to and including a string pattern?
I've already looked at a couple of related questions.
Make Vim treat forward search as "up to and including" has an accepted answer which doesn't answer my question.
In my case, I settled for deleting up to the search string, then separately deleting up to the semicolon, but it felt inefficient, and like it would have been quicker to just reach for the mouse. #firstworldproblems
To replace up to and including a string across multiple lines, I can
use... ?? e.g. ??
The / supports offsets.
In your case, you are gonna need the e offset, that is, c/foo/e.
You may want to know more details about "search offset":
:h offset
If you'll replace up to the closing brace associated to your current scope, you have c]}.
If you're looking for the end of the function, even if it means crossing to the upper scope, you'll need a plugin if the function may not be 0-indented as it's the case in C++, Java... See the related Q/A on vi.SE

How to replace a `\norm{ some string }` by `\| some string\|` quickly? [duplicate]

This question already has answers here:
Find and replace strings in vim on multiple lines
(11 answers)
Vim - Capture strings on Search and use on Replace
(4 answers)
Closed 3 years ago.
I am editing a markdown file with vim. This file exist many string \norm{ some string }. I want to replace them by \| some string \|. Does there exist any quick way? Thanks very much.
The answer in Find and replace strings in vim on multiple lines can not answer my question. It just talk about general replacing for one line and multi line. Here I want to replace a surrounding and keep the string in the surrounding.
What you're looking for are so-called capture groups and backreferences. Provided there are no nested forms (curly braces inside do not mean a problem in themselves) and forms spanning multiple lines, a quick solution could be: %s/\\norm {\(.*\)}/\\|\1\\|/g.
The \1 in the substitution part refers to the group captured by \(.*\), i.e. the original content inside the outermost pair of curly braces. See e.g. http://www.vimregex.com/#backreferences for more.
You could also use a macro to accomplish what you want.
Place your cursor on the first line that have the pattern you want to substitute. Then start recording the macro:
qq0ldwr|$xi\|ESCjq
Meaning:
qq = start recording a macro (q) in register q
0 = move to the beginning of the line
l = move one char to the right
dw = delete the word
r| = substitute what is under the cursor with a "|"
$ = move to the end of line
x = delete last char of the line
i = insert mode
\| = insert chars "\|"
ESC = exit insert mode
j = move to next line
q = stop recording
Execute the macro with:
#q
Execute the macro once again:
##
Keep doing it for as many lines as needed, or use:
<number>##
ex. 100##
To execute the macro number times.

Vim keyboard shortcut: Deleting code without deleting the if statement

This is probably a basic vim questions to all those vim gurus out there.
If I want to delete a particular if statement and its closing bracket, but without deleting the code inside the expression, how can I achieve this through some keyboard shortcuts?
eg:
if (a == 2) {
// do not delete this part.
for (int i = 1; i < 10; i++) {
// code
}
}
The result will be:
// do not delete this part.
for (int i = 1; i < 10; i++) {
// code
}
Thanks for any help.
Alternatively to Zachs solution, you could use this:
di{Vk]p
Explanation:
You start inside the { } block, and with di{ you delete inside the { } block.
Then, you select the the if statement, which you want to remove, which now is two lines. Vk selects both, and you paste the block you just deleted over it with p. The ] makes the pasted block be correctly indented (thanks, Kache)
There could be a more elegant solution to the pasting part, buth this was the first one that came to mind.
The anvantage over Zachs answer is that you don't have to move the cursor to the line with the if, you just need to be inside it (although you may run into trouble with nested {} blocks, which there usually are). In addition, you don't need to fix indentation.
Move your cursor anywhere on the line with the if statement. Here is the sequence of commands (will be explained after)
$%dd''.
Explanation:
$ goes to the end of the line (cursor is now on {).
% goes to the matching curly brace (or parentheses etc...). Cursor is now on } of the if statement
dd deletes the line the cursor is on (} is now deleted)
'' goes to the line of the last jump. The last jump was when we used %. (cursor is back on if statement line)
. Repeats the last command (dd). This deletes the line (if statement line is now deleted)
Result:
// do not delete this part.
for (int i = 1; i < 10; i++) {
// code
}
The indentation will be off so you can use gg=G (which correctly indents the file) to fix it.
If you do this alot you can make map it to a key in your .vimrc or you can make it into a macro
Making it into a mapping:
Example of a mapping in your .vimrc:
nnoremap <C-d> $%dd''.gg=G
Whenever you press control-d (you can choose any key, just replace <C-d>) Vim will run those commands, doing what I explained before followed by an entire file indentation this time. Make sure your cursor is on the if statement line when using this command otherwise there could be unintended results.

How can I indent a block of C code in Vim? [duplicate]

This question already has answers here:
Closed 13 years ago.
Duplicate:
How to indent code in vim editor in Windows?
Tabbing selected section in VIM
Sometimes I want to indent a block of C code in Vim. I usually ended up tabbing it line by line.
What is a better/faster way?
I'm surprised no one came up with =% yet.
Make sure you have :set cindent,
Place yourself on one of the {} of your block, and just hit:
=%
All code within this block will be correctly indented.
Use '>' to tab a block
Enter visual mode, select to the next matching bracket, indent:
V
%
>
While insert: C-d, C-t
While visual: >, <
While normal: >>, <<
In any of this modes use '.' to indent further.
Try
:set cindent
This will turn on C indenting magic in vim. So as soon as you open a brace, it will automatically tab until you close the brace.
If you have unindented code that looks like this...
if (foo)
{
/* line 1 */
/* line 2 */
/* line 3 */
}
...place your cursor on "line 1" in command mode and type 3==, where 3 is the number of lines to indent.
I think this will do it without any indent switches being set.
:startRange,stopRange s/^/^\t/g
should add a tab space at beginning of line between the line number range you provide
unindent with:
:startRange,stopRange s/^\t/^/g
In addition to what skinp said, if you have:
int foo()
{
/* line 1 */
/* line 2 */
/* line 3 */
/* line 4 */
}
and for whatever reason wish it to look like this (i.e. you want everything indented 4 spaces* from where they were previously, rather than indenting 'correctly' according to the cindent rules):
int foo()
{
/* line 1 */
/* line 2 */
/* line 3 */
/* line 4 */
}
anywhere within the block, do viB> (visualselection innerBlock indent)**
* or whatever your shiftwidth is set at
** vi} is the same as viB, and may be easier to remember since vi} selects within {}, vi) selects within (), vi] selects within [], and vi> selects within <>.
Also, va}, va), etc. select the {}, (), etc in addition to what's contained within the block.

Resources