## brace matching in vim, regardless of how it is formatted?

August 31, 2016 C/C++ development and debugging. No comments ,

DB2 functions were usually formatted with the brace on the leading line like so:

size_t table_count( T * table )
{
size_t count = 0 ;
....
}


For such code, typing [[ in vim anywhere from somewhere in the function text would take you to the beginning of the function. It has always annoyed me that this key sequence didn’t work for functions formatted without the leading { in the first column, such as

size_t table_count( T * table ) {
size_t count = 0 ;
....
}


Having my handy [[ command sequence take me to the first line of the file is pretty annoying, enough that I looked up the way to do what I want. A key sequence that does part of this job is:

[{

This takes you to the outermost ending position of the current scope, and you can use % to get to the beginning of that scope. You can repeat this as many times as necessary, until you get the outermost scope.

Is there a better way to go directly to the outermost scope directly, regardless of how the function happens to be formatted?

## Some notes on copying and moving text in vim

April 13, 2015 perl and general scripting hackery No comments , ,

Emad just asked me a vim question (how to use a search expression instead of a line number), and I ended up learning a new vim commmand from him as a side effect.

I’d done stuff like the following before to move text to a new file

:,/Done/-1 !cat > /tmp/newfile.txt


This assumes you’d like to delete everything from the current position to the line just before the /Done/ search expression, and write it into /tmp/newfile.txt.

The mechanism here, is that the selection is filtered through a script, where the output of the script is empty, so the lines are deleted. This particular script has the side effect of creating a file with the selected range of lines. The end effect is that the text is moved.

If you’d like to keep it and copy it to the new file, you can tee instead of cat it:

:,/Done/-1 !tee /tmp/newfile.txt


This is faster than selecting a range, switching buffers copying into the buffer, saving, and switching buffers back.

Emad taught me that this can also be done with the w command, like so:

:,/Done/-1 w /tmp/newfile.txt


It doesn’t surprise me that there’s a faster way to copy text from one file to another than using tee, but since I knew one way, I never went looking for it.

## Some Unix command line one liners

Here’s a couple one-liner shell commands collected over the last couple months when it occurred to me to record them.  Each of these I thought were somewhat notable at the time I did so.

## Nested “backquotes”

I often have to run commands where it is convenient to have the parameters of the commands in a file.  A simple example is to edit all the files in a list of files, say:

vim cat c
# or:
vim $(cat c)  A useful variation of this is to do the same using the output of a command that also takes its input from a file. Here’s one to edit all the “ancestor” files in the version control system, assuming a command vcsancestor that produces such filenames vim vcsancestor$(cat c)
# or
vim $(vcsancestor$(cat c))


Observe how two different methods of embedding shell commands can be combined into one command. In the past I often used for loops for something like this, say:

for i in cat c ; do vcsancestor $i ; done > f vim cat f  (because backquotes can’t be nested). It only recently occurred to me that this isn’t a limitation if$() style subshells are used.

## Batching commands with xargs

When working in a version control system, it’s often useful to do a batch checkout of all the files that have compilation errors.  Suppose that you made changes that produced the following compilation error output:

## Unix to Windows path separator switching

Suppose we have some unix filenames

</pre>
$head -5 f /vbs/bin/AEDefines.pm /vbs/bin/AEMacro.pm /vbs/bin/bld_shared_lib_Darwin /vbs/bin/chglibpaths /vbs/bin/chglibpaths_Darwin  and want the Windows paths for the same </pre>$ head -5 f | tr / '\\'
bin\AEDefines.pm
bin\AEMacro.pm
bin\bld_shared_lib_Darwin
bin\chglibpaths
bin\chglibpaths_Darwin
<pre>

The tr command above looks a bit like ascii barf, and will translate forward slashes to backward slashes (perhaps for input that’s a list of files).

I didn’t understand the requirement to both single quote the backslash as well as escaping it, but Darin explained it for me:

Quotes allow the backslashes to go through the shell to tr.  And tr has its own backslash escape mechanism (so you can do things like transform \n into \r or something – where you’d then specify ‘\n’ or just \\n and ‘\r’ or \\r).

## Vim: replace search results with contents from a file

Probably related to merging conflicting changes, I wanted to completely replace the implementation of a particular function:

void foo() {
...
}


This was an easy way one liner method to do that replacement, deleting the implementation of foo, and replacing it with the one that was found in the file ‘foo’

:,/^}/ !cat foo


## file:line: delimited output for a single file

The grep -n command is very handy for producing file:line:content delimited output.  In particular, you can iterate over such output with vim -q.  When you want to do this for a single file, grep -n doesn’t include the filename, defeating a subsequent vim -q (since vim then doesn’t know what file to open).  Here’s an example

$cat my_file_to_search blah patternOfInterest hi foo goo patternOfInterest bye blah patternOfInterest hi blah patternOfInterest hi foo goo patternOfInterest bye foo goo patternOfInterest bye$ grep -n patternOfInterest my_file_to_search | tee v
1:blah patternOfInterest hi
3:patternOfInterest bye
4:blah patternOfInterest hi
5:blah patternOfInterest hi
7:patternOfInterest bye
9:patternOfInterest bye



To get vim -q’able output, just include a second non-existent dummy file in the search

grep -n patternOfInterest my_file_to_search a_file_that_doesnt_exist | tee v
vim -q v


I usually use a very-short filename for the “does not exist file”, say, .u (which presumes I also don’t create little hidden files .u in my day-to-day work).

## Sum of digits of small powers of nine.

In a previous post I wondered how to prove that for integer $$d \in [1,N]$$

\label{eqn:numberGame:20}
((N-1) d) \text{mod} N + ((N-1) d) \text{div} N = N-1.

Here’s a proof in two steps. First for $$N = 10$$, and then by search and replace for arbitrary $$N$$.

## $$N = 10$$

Let

\label{eqn:numberGame:40}
x = 9 d = 10 a + b,

where $$1 \le a, b < 9$$, and let $$\label{eqn:numberGame:180} y = a + b,$$ the sum of the digits in a base $$10$$ numeral system. We wish to solve the following integer system of equations \label{eqn:numberGame:60} \begin{aligned} 9 d &= 10 a + b \\ y &= a + b \\ \end{aligned}. Scaling and subtracting we have $$\label{eqn:numberGame:80} 10 y - 9 d = 9 b,$$ or $$\label{eqn:numberGame:100} y = \frac{9}{10} \lr{ b + d }.$$ Because $$y$$ is an integer, we have to conclude that $$b + d$$ is a power of $$10$$, and $$b + d \ge 10$$. Because we have a constraint on the maximum value of this sum $$\label{eqn:numberGame:120} b + d \le 2 ( 9 ),$$ we can only conclude that $$\label{eqn:numberGame:140} b + d = 10.$$ or $$\label{eqn:numberGame:160} \boxed{ b = 10 - d. }$$ Back substitution into \ref{eqn:numberGame:40} we have \label{eqn:numberGame:200} \begin{aligned} 10 a &= 9 d - b \\ &= 9 d - 10 + d \\ &= 10 d - 10 \\ &= 10 \lr{ d - 1 }, \end{aligned} or $$\label{eqn:numberGame:220} \boxed{ a = d - 1. }$$ Summing \ref{eqn:numberGame:220} and \ref{eqn:numberGame:160}, the sum of digits is $$\label{eqn:numberGame:240} a + b = d - 1 + 10 - d = 9.$$

## For arbitrary $$N$$

There was really nothing special about $$9, 10$$ in the above proof, so generalizing requires nothing more than some search and replace. I used the following vim commands for this “proof generalization”

:,/For arb/-1 y
:+/For arb/+1
:p
:,$s/\<9\>/(N-1)/cg :,$ s/\<10\>/N/cg
:,s/numberGame:/&2:/g  Let \label{eqn:numberGame:2:40} x = (N-1) d = N a + b, where $$1 \le a, b < N-1$$, and let $$\label{eqn:numberGame:2:180} y = a + b,$$ the sum of the digits in a base $$N$$ numeral system. We wish to solve the following integer system of equations \label{eqn:numberGame:2:60} \begin{aligned} (N-1) d &= N a + b \\ y &= a + b \\ \end{aligned}. Scaling and subtracting we have $$\label{eqn:numberGame:2:80} N y - (N-1) d = (N-1) b,$$ or $$\label{eqn:numberGame:2:100} y = \frac{N-1}{N} \lr{ b + d }.$$ Because $$y$$ is an integer, we have to conclude that $$b + d$$ is a power of $$N$$, and $$b + d \ge N$$. Because we have a constraint on the maximum value of this sum $$\label{eqn:numberGame:2:120} b + d \le 2 ( N-1 ),$$ we can only conclude that $$\label{eqn:numberGame:2:140} b + d = N.$$ or $$\label{eqn:numberGame:2:160} \boxed{ b = N - d. }$$ Back substitution into \ref{eqn:numberGame:2:40} we have \label{eqn:numberGame:2:200} \begin{aligned} N a &= (N-1) d - b \\ &= (N-1) d - N + d \\ &= N d - N \\ &= N \lr{ d - 1 }, \end{aligned} or $$\label{eqn:numberGame:2:220} \boxed{ a = d - 1. }$$ Summing \ref{eqn:numberGame:2:220} and \ref{eqn:numberGame:2:160}, the sum of digits is $$\label{eqn:numberGame:2:260} a + b = d - 1 + N - d = N-1.$$ This completes the proof of \ref{eqn:numberGame:20}. ## vim hacking: move set of lines into new file without buffer switching Yesterday I was faced with a task where I wanted to repeatedly edit the first N lines of a file, then when they were in the form I wanted insert them into another file to be consumed by another script. A braindead way to do this would be something like: :0, d :w :e t :
:p
:0, d
:w
:e#

This is:

• delete the lines from the beginning of the file to the current line.
• save my file with these lines deleted
• switch to my destination file to be overwritten and go to the end
• paste in the new content
• delete the old content
• save this new destination file