Monday, August 1, 2011
Support QComicBook - buy an ad!
QComicBook is a free software that doesn't bring me any profits (well, except for fun of course) - actually it costs me money on web hosting. Here is a new way for you to support QComicBook website & development: if you want to promote your business or a website on QComicBook website, buy a banner for as little as 5-10€ per month (non exclusive banner) or 50-100€/month (exclusive banner - always visible). Get your website advertised, and support opensource at the same time! Please contact me directly for more details.
Friday, July 29, 2011
My dotfiles are on GitHub
Since I wanted to have consistent configuration across all the PCs I work on, I've created a git repo with most crucial dotfiles (such as vim config or openbox files). My dotfiles can be found here.
Wednesday, July 27, 2011
Finding your way in vim
Vim is quite powerful programmer's editor, but has a very steep learning curve and it takes time to configure it properly. In this tutorial I'd like to share my experiences with configuring vim for efficient symbol, buffer and file navigation. In other words, I'm going to focus on finding these things easily in vim and ignore all other configuration aspects. Getting these things right seems to be the most confusing part for a lot of people who can otherwise use vim already. It's also the part that gives a big efficiency boost when programming or just browsing code, especially when it comes to finding symbol definitions quickly.
Preface
This is by no means a definitive guide on the subject. It' just a bunch of things I learned over years when using vim. Vim evolves, new plugins get developed, so the methods I list here may not neccessarily be the best solutions. But they should work and they do the job for me. These methods should work for pretty much every popular programming language, such as C, C++, Java, Python, Ruby etc.
Looking for symbols
A word of caution first: there is no perfect symbol-based navigation for programming languages such as C++ or Java in vim, as vim doesn't perform any syntax analysis of the code. So, for example, it's not possible to go to the right definition of foo->bar() in C++ code if there are multiple definitions of bar() method, because vim has no notion of foo's type.
Tags
![]() |
| Jumping to tag with g CTRL-] |
Vim has a built-in feature for looking for symbols based on so-called tags file. Tags file needs to be created first with ctags utility, e.g:
$ ctags -R /your/source/code
This will create tags file in your current directory. Add the following line to your .vimrc file to load tags automatically from current working directory as well as from specific path automatically:
:set tags=./tags,/home/user/your/source/code
From now on, you can jump to the first matching symbol definition by pressing CTRL-] over a symbol. CTRL-T will bring you back to where your search started. If there are several matching tags for a symbol (e.g. overloaded methods), you can use :tselect to choose the right one. Even better, if you know in advance there will be multiple matches, press "g CTRL-]" instead of CTRL-] over a keyword to bring the selection list right away. See :help tags for more information on how to use tags effectively.
![]() |
| Tagbar plugin window |
Tags list
A very useful feature of most IDEs is the list of all classes/methods/symbols for all open files. This can easily be achieved in vim by installing a plugin such as Tagbar or Taglist. Both have similar capabilites, but I tend to like Tagbar more, as it displays tags ordered by their scope and displays method signatures (unlike Taglist, which displays only names).
Cscope-based navigation
Cscope is similiar to ctags, only a bit more powerful since it's capable of searching for functions calling given function etc. To use this capabilities in vim you have to scan you source files with cscope first (e.g. 'cscope -R -b' in your source code directory). Cscope creates a cscope.out file that needs to be loaded in vim by :cscope add /path/to/cscope.out. A common idiom for doing this automatically on vim startup (taken from vim help - see :help cscope) is:
if filereadable("cscope.out")
cs add cscope.out
" else add database pointed to by environment
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
Once loaded, cscope symbol database may be queried by issuing :cscope find with a query type and symbol name, e.g. to search for functions calling given function, type:
:cs find c foobar
This is not very convient to type, so you can define mappings for all cscope queries like this:
nmap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
... and so on.
If you use tags and cscope at the same time, they are independent of each other, use different keyboard shortcuts and need to be queried separately. This can be solved by using :cstag for symbol defintion lookups: cstag searches both databases (by default cscope is searched first). And if you set cscopetag option, i.e.
:set cscopetag
then all tags queries (like CTRL-]) will use :cstag instead, so both databases will be searched.
![]() |
| Grep search results |
Grep-based searching
Searching for symbols with grep doesn't sound too attractive, but it's actually quite powerful once combined with a handly shortcut key and as long as the symbol you're searching for is not too common.
First off, I highly recommended installing ack-grep, which is a grep-like utility designed specifically for grepping source code files. Then configure vim to use it instead of regular grep - e.g. put this in your .vimrc:
set grepprg=ack-grep\ --cpp\ --cc\ --perl\ --python\ --make
Then define a shortcut key for grep, e.g.
:nmap _g :grep <C-R>=expand("<cword>")<CR><CR>
Pressing _g will grep source code files recursively, starting from the vim's current working directory, for the word under the cursor. Vim places grep results in so called 'quickfix' window, which you can bring up by calling :cwindow. You can navigate through quickfix entries by calling :cnext and :cprev. It's very usefull to map keys for them as well:
:map <F7> :botright cwindow<CR>
:map <F5> :cprev<CR>
:map <F6> :cnext<CR>
If grepping in the current directory is not what you want, then you may want to play with 'expand' macro to grep starting from current file's directory, or from a predefined directory and add new shortcuts for them -- here is how to create a Gvim menu entry for them:
:amenu Devel.Grep\ file\ dir :grep <C-R>=expand(expand("<cword>") . " " . expand("%:h"))<CR><CR>
:amenu Devel.Grep\ source\ dir :grep <C-R>=expand(expand("<cword>") . " " . expand("~/src"))<CR><CR>
Buffer navigation
Standard vim capabilities for navigating to opened files (buffers) are a bit limited when working with large number of files, so installing external plugin(s) is highly recommended. Just for the record, the standard commands for buffer navigation in vim are:
:ls -- shows buffer list
:buffers -- same as above
:bnext -- go to next buffer
:bprev -- go to previous buffer
:[N]b -- edit Nth buffer
There are several plugins that simplify buffer navigation, but I recommend the following: bufexplorer, buffergator and buftabs. Bufexplorer provides a sorted list of all the buffers, which can easily be navigated with cursor keys; pressing ENTER over buffer name makes it active. By default buffers are sorted in MRU (most recently used first) order, but this can easily be changed by pressing 's' in the bufexplorer window. Bufexplorer can be activated by \be, \bv and \bs keyboard shortcuts, but since I use it a lot I prefer a simpler shortcut, e.g. F3 key alone:
:imap <F3> <ESC>:BufExplorer<CR>
:map <F3> :BufExplorer<CR>
Buffergator is similiar, but makes it easy to preview buffers without leaving list of buffers. Upon invocation with \b (or :BuffergatorToggle), a new vertical window with buffers list is opened. CTRL-N, CTRL-P and SPACE keys can be used to navigate the list and preview buffers. ENTER key over buffer name opens it for editing and closes buffer list. One problem buffergator has is its slow response time on invocation: for some reason it takes 1-2 seconds to bring the list of buffers up, whereas it's instantaneous with bufexplorer.
Buftabs is a littler helper addon that is worth installing alongside bufexplorer and/or buffergator. It provides a tabs-like list of buffers displayed in the bottom of the window which is very handy for switch buffers in a circular way, in particular if you map :bprev and :bnext to keys such as CTRL-Left and CTRL-Right:
:noremap <C-left> :bprev<CR>
:noremap <C-right> :bnext<CR>
File navigation
The standard way for finding files is via :Explore [DIR] (or :edit [DIR] and :edit [FILE]). They both support filename completion with TAB key. Explore may be used to find files recursively, if you know only part of a file name, e.g:
:Explore **/*foo*
If you know complete file name, but not its path, you can use vim's built-in find command, e.g:
:find foobar.cpp
This will search for the file in all paths listed in vim's 'path' variable, which is current directory and /usr/include by default. You may want to set to also include subdirectories of your sources directory, for example:
:set path=.,~/src/**,/usr/include,,
Vim's path variable has one more use: it allows for opening files whose name is under or after the cursor. A typical use case is opening an included file in C/C++ source code, by moving over file name in the #include directive, and pressing 'gf' (goto file). Quite handy.
There are plugins which make finding files easier. One of the most useful is NERDTree, which implements a nice filesystem explorer in the form of a tree structure. It's very fast (uses caching), configurable (screen position, list of file patterns to be ignored etc. can be adjusted) and smart (e.g. remembers last cursor position when toggling off and on). It's so useful that its worth having a dedicated keyboard shortut for it, e.g.
:imap <F4> <ESC>:NERDTreeToggle<CR>
:map <F4> :NERDTreeToggle<CR>
Conclusion
The above tips should improve your day-to-day productivity a lot when programming. Go use it, learn it and improve. And let me know in the comments about your ideas and improvements!
Sunday, July 3, 2011
QComicBook 0.8.0 released, brings PDF support
![]() | |
| QComicBook - reading PDF document |
By the way, if you like QComicBook, you can show your appreciation by making small donation (e.g. a beer worth ;)) - it's really easy with Flattr!
Thursday, June 16, 2011
Debian 6.0: encrypting /home partition after installation
Debian installer provides an easy way of creating encrypted disk volumes during installation, including encrypted root partition. However, if you skip this step and decide to encrypt a disk partition later, you need to perform manual setup. Fortunately, it's not too difficult. The following steps cover creating an encrypted /home, so you need to have a separate disk partition for it. Encrypting root filesystem is more sophisticated and it's not covered by this tutorial.
- Install cryptsetup: apt-get install cryptsetup
- Backup current /home contents and unmount the partition.
- Create encrypted LUKS partition: cryptsetup luksFormat /dev/sda2 (replace sda2 with your partion name).
- Open LUKS partition and map it to 'crhome' (this name can be arbitrary): cryptsetup luksOpen /dev/sda2 crhome
- Format encrypted partition, e.g.: mkfs.ext4 /dev/mapper/crhome
- Mount it: mount /dev/mapper/crhome /home
- Restore /home contents from the backup.
- Recreate initrd: update-initramfs -u
- Create /etc/crypttab entry for encrypted volume:
#
crhome /dev/sda2 none luks - Change /etc/fstab entry for /home, .e.g:
/dev/mapper/crhome /home ext4 defaults 0 2 - Reboot!
During system startup you will be prompted for password to access LUKS volume. If you have Plymouth installed, you'll see a nice graphical password prompt - see the screenshot. For more documentation, including Debian-specific docs, got to /usr/share/doc/cryptsetup and cryptsetup/crypttab man pages.
Sunday, May 29, 2011
GNOME 3.0 = big letdown
The GNOME project has just released GNOME 3 - a major overhaul of this popular desktop environment - which promises a new, beautiful and improved interface and a shift in the way users access their desktop. I've been using GNOME 2.x for a few years already and had really high hopes about the upcoming release. Unfortunately, all I got is a big letdown.
The key features I loved about GNOME 2 were its simplicity, configurability, extensibility and stability. This is no longer the case with new GNOME. GNOME developers did what KDE developers did a few years ago, by replacing KDE 3.5 with KDE 4.0: they have rewritten their desktop and dropped tons of features to provide "new desktop experience". I don't mind GNOME Shell - in fact I find some of its aspects quite appealing - I just miss the freedom and flexibility of GNOME 2. In GNOME 3 configurable panels are gone, existing panel applets are gone (well, most of them - all the bonobo-based), apperance settings are gone, gdm settings are not configurable (GDM setup tool had been removed a long time ago, around gnome 2.28 and it is still not available). Not to mention that GNOME 3.0 in its current shape is not really stable and I found some irritating bugs in Gnome Shell after using it just for around one hour.
The key features I loved about GNOME 2 were its simplicity, configurability, extensibility and stability. This is no longer the case with new GNOME. GNOME developers did what KDE developers did a few years ago, by replacing KDE 3.5 with KDE 4.0: they have rewritten their desktop and dropped tons of features to provide "new desktop experience". I don't mind GNOME Shell - in fact I find some of its aspects quite appealing - I just miss the freedom and flexibility of GNOME 2. In GNOME 3 configurable panels are gone, existing panel applets are gone (well, most of them - all the bonobo-based), apperance settings are gone, gdm settings are not configurable (GDM setup tool had been removed a long time ago, around gnome 2.28 and it is still not available). Not to mention that GNOME 3.0 in its current shape is not really stable and I found some irritating bugs in Gnome Shell after using it just for around one hour.
Some of the missing features will probably be provided by 3rd party tools that I'm sure will fill the vacuum sooner or later, but I'm afraid that reaching the functionality and stability offered by GNOME 2 may need a few development cycles. This makes me a little bit concerned about the state of Linux desktop in the next 1-2 years: with immature GNOME 3 and Ubuntu/Unity abandoning GNOME, the only viable option is to stick with a distribution that still supports GNOME 2, or move to XFCE. The current state of affairs may be a big chance for the latter, by the way.u
After testing GNOME 3 & XFCE 4.8 in Arch Linux for a few days, I've sadly decided to abandon Arch Linux... The disadvantage of running a rolling distro is that updates such as GNOME 3 are just rolled out and you either accept it or refuse them (and stop getting security updates at the same time)... And for all these reasons I decided to move to Debian 6.0 (Squeeze) and stick with it for a while... Let's see how GNOME 3 and Unity develop. Maybe by the time of next Debian stable GNOME 3 becomes really usable?
After testing GNOME 3 & XFCE 4.8 in Arch Linux for a few days, I've sadly decided to abandon Arch Linux... The disadvantage of running a rolling distro is that updates such as GNOME 3 are just rolled out and you either accept it or refuse them (and stop getting security updates at the same time)... And for all these reasons I decided to move to Debian 6.0 (Squeeze) and stick with it for a while... Let's see how GNOME 3 and Unity develop. Maybe by the time of next Debian stable GNOME 3 becomes really usable?
Fixing usb drives automount issue in Debian 6.0
If you happened to experience issues with auto-mounting of USB hard disks in Debian 6.0, like the one on the attached screenshot, then read on as this is very easy to fix. The problem is caused by an improper entry in /etc/fstab created by Debian installer: if you've installed Debian from a USB disk, then a "cdrom" entry pointing to that drive could have been created in fstab, e.g.
/dev/sdb1 /media/cdrom0 udf,iso9660 user,noauto 0 0
Just remove such entry and you're done! Note: I experienced this issue when installing Debian 6.0 iso. Chances are this issue was corrected by Debian 6.0.1a (or later) iso, but I haven't verified this.
/dev/sdb1 /media/cdrom0 udf,iso9660 user,noauto 0 0
Just remove such entry and you're done! Note: I experienced this issue when installing Debian 6.0 iso. Chances are this issue was corrected by Debian 6.0.1a (or later) iso, but I haven't verified this.
Subscribe to:
Posts (Atom)





