vim find a line that has this but not that

To find lines which have “This” and “NotThat” it is as simple as:

:g/This\&\(.*NotThat\)\@!

Let’s dive into each piece of this in a little more detail…

The :g is a way to list out all matches in a file. For instance to see all lines listed out which match “This” you could use:

:g/This

Furthermore, if you wanted lines that contained both “This” and “That” then you could use:

:g/This\&\(.*That\)

The reason why the .* is needed is that it looks for the conjoined match (the ampersand) from the previous match. You will notice that the highlighting/match will select the range, i.e.

we use brackets to show the match from [This to That] nothing else matches

By adding the \@! we tell vim to negate that term and viola we are search for “This” and not “That” e.g.

:g/This\&\(.*That\)\@!

Would match the second line, but not the first:

we use brackets to show the match from This to That nothing else matches
on this line we only have This and thus it will match

Notice that only the second line will match.

Advertisements

Vim finding and replacing without captures

Normally when doing find and replaces in a file there are some key words that we want to key off, but not replace. This can be a pain because you have to then isolate the part you want to change, capture everything but the changing part, and then reconstruct it in the substitution. Well there is a better way…

If your goal is to prepend all of the name=”bad-.*” with name=”good-.*”, then we would normally have to write something like:

:s/\(name="\)bad\(-.*"\)/\1good\2/g

There is a better way using zoom start ‘\zs’ and zoom end ‘\ze’:

:s/name="\zsbad\ze-/good/g

Happy finding and replacing!

 

Vim Highlighting

I highlight my searches in VIM using the following in my .vimrc:

" Highlight search terms...
set hlsearch
set incsearch " ...dynamically as they are typed.
nmap  n :silent :nohlsearch
" stop highlighting with n

While demoing or in a code review it is nice to highlight more than one item. You can use searching to match multiple words:

/term1\|term2

Note: You can also us CTRL+R followed by a ‘/’ to paste the exact last search term

However, it is also nice to do highlights in different colors – or to keep a highlight persistent while you search for other terms. To do this I use:

:match Search /pattern/

Now this will use the same highlight color as normal search. You can replace Search, the name of the highlight group, with another group to highlight with a different color (tab completion works here).

To disable the highlighting from match use:

:match none

Enjoy highlighting!

How to generate a ctags files and use it with vim

The ctags command allows you to index source – any source. The command generates a single file called a tags file (which [ironically] is the name of the file). Then you can point to this file with editors like VIM/GVIM/EMACS, etc. for auto-complete and for cross-probing.

Let’s see it in action…

First tag the source you want to index using:

ctags -V -R --c++-kinds=+p --fields=+iaS --extra=+q --languages=c++ .

This will recursively index all files from this point down and generate a ‘tags’ file in the current directory. You should open the tags file and look around to see if it’s getting what you expect and that it isn’t getting things that you don’t expect.

From here we can open vim and start auto-completing. This works because VIM will automatically search the current directory for a tags file, which we just generated. If you want to point to a tags file that lives in another directory, then use:

:set ctags=/path/to/file/with/tags

Now you can start typing. Let’s act like we have a class called MyClass, in VIM you must be in insert mode (press ‘i’) then type…

 MyC<CTRL+N>

…and a drop-down menu should show with the option to auto-complete to MyClass (presuming some MyClass.cpp was indexed with the ctags command).

CTRL+N : to go forward through tags

CTRL+P : to go backward through tags

Now the cool part. Once you’ve auto-completed a word or you put your cursor on any keyword and press CTRL+], then you will see a menu that will let you pick the implementation you would like to go to and once selected VIM will open the source file that defines that keyword.

CTRL+] : to push into tags

CTRL+T : to pop out of keywords

 

How do I easily manipulate individual files in a zip archive?

I have seen zip files used as containers for hand off between programs. Java’s JAR files are just zip archives.  Sometimes you just want to modify a file in a zip archive or view a file in a zip archive and this article will give you some quick steps to do that…

To extract a single file from an archive:

unzip MyTest.zip MyJavaFx.css
unzip MyTest.jar MyJavaFx.css

This will extract only the MyJavaFx.css from the MyTest.{zip,jar} file. Normally, one would want to modify this file and then put it back into the archive, and that can be done with:

zip MyTest.zip MyJavaFx.css
zip MyTest.jar MyJavaFx.css

You may also find that you just want to view a file in an archive, but don’t necessarily want to extract it to disk, well you can just stream the data out and then pipe it to another program like cat or vi:

unzip -p MyTest.zip MyJavaFx.css | gvim -
unzip -p MyTest.zip MyJavaFx.css | cat

The unzip -p switch just tells zip to stream. For vi and gvim the – means to read from STDIN.

Debugging DLL using GDB called via JNI (Java Native Interface) being debugged by JetBrains IntelliJ IDEA

This post is about using GDB to debug a DLL built with debug symbols which was called from a Java application being debugged by JetBrains IntelliJ IDEA.

First things first: I am working on a Java application which has calls to C++ methods. The C++ classes and namespaces are compiled into a DLL using Cygwin.

I am not going into the build process of this project, at this time, but check back later. The development process currently looks like:

  • shell: bash
  • source: Java and C++
  • make: GNU make
  • environment: Window 10 64-bit with Cygwin64
    • IDE: JetBrains IntelliJ IDEA
  • environment: Linux (Fedora 21 64-bit)
    • IDE: Linux

Notes:

  • On Windows I had to call JetBrains IntelliJ IDEA from the Cygwin64 shell
  • I added my own JAR Application in the Run/Debug Configurations dialog within IDEA:
  • Your DLL needs to be built with debug symbols. With a Cygwin shell this means adding -g to the g++ command line.
  • You can always use GDB to call Java and set breakpoints in C++ code; However, if there is a crash, then you will get much more useful information if GDB is attached to the process

JetBrains IntelliJ IDEA debugging Java

addHotKey

Using IDEA, put a break-point right before the native call that you want to debug into.

Now select the Java application you want to run (or setup the JAR Application, as I did above in the Notes section) and click on run Debug mode (start Debug is Shift+F9). Your application should run to the break-point that is just before the DLL call.

If you don’t know the Process ID of the Java application that is being debugged, then you can go to the IDEA session where you are still at a break-point just before the DLL call.

In the IDEA Console session under debug click on the “Evaluate Expression” icon:EvaluateExpression

Enter Code Fragment Mode by clicking the button on the bottom of the “Evaluate Expression” dialog (i.e. if you see a button called Expression Mode, then you are already in Code Fragment Mode). Enter this code (copy and paste), IDEA was not letting me paste, but CTRL+Shift+v worked:

String processName =
  java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
long pid = Long.parseLong(processName.split("@")[0]);

EvaluateCodeFragment

The results (pid variable) is the PID of the Java application that is running.

GDB debugging C++

In the Cygwin64 shell call gdb, then attach GDB to the Java process:

attach 7964

Then set the break-point where you want to start debugging, e.g.:

break Java_keypress_KeyPress_registerHotKey
continue

Back in IDEA now click on ‘Step Into (F7)’ and now we should hit our C++ break point. Continue debugging with GDB as normal.

Hopefully you see something like the following:

Program received signal SIGSEGV, Segmentation fault.
0x00000003dc8c1f3d in cygstdc++-6!_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ () from /usr/bin/cygstdc++-6.dll

To get more information you can use the following:

$ echo _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ | c++filt.exe
std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)

If you have a DLL/SO with debug symbols, then you can also try:

addr2line.exe -p -C -e /usr/bin/cygstdc++-6.dll 0x00000003dc8c1f3d