<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>commandliners</title>
	
	<link>http://commandliners.com</link>
	<description># killall -9 X</description>
	<pubDate>Thu, 18 Mar 2010 22:08:47 +0000</pubDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/commandliners" /><feedburner:info uri="commandliners" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Shell scripting for Nautilus</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/-WsIiIp_Ztw/</link>
		<comments>http://commandliners.com/2010/03/shell-scripting-for-nautilus/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 22:08:47 +0000</pubDate>
		<dc:creator>n0str0m0</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[bash]]></category>

		<category><![CDATA[gtk]]></category>

		<category><![CDATA[nautilus]]></category>

		<category><![CDATA[scripts]]></category>

		<category><![CDATA[zenity]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1825</guid>
		<description><![CDATA[It has been a while since I wrote my last post. Sorry for the delay, but I was a bit busy lately. In this post, I shall explain how to get the most of your nautilus file manager by using shell scripts.
Nautilus provides some facilities available from shell scripts. Combining them with a small utility [...]]]></description>
			<content:encoded><![CDATA[<p>It has been a while since I wrote my last post. Sorry for the delay, but I was a bit busy lately. In this post, I shall explain how to get the most of your nautilus file manager by using shell scripts.</p>
<p>Nautilus provides some facilities available from shell scripts. Combining them with a small utility called zenity can improve your daily tasks.</p>
<p>Nautilus has the ability of executing shell scripts applying them to the selected files. The executable scripts are those present in the following directory:</p>
<pre><code>~/.gnome2/nautilus-scripts</code></pre>
<p>Every script present in that directory will be shown in the &#8220;Scripts&#8221; entry of the contextual menu that shows up by right-clicking on a file. If that entry is not shown, navigate into the directory mentioned above in Nautilus and you will see a message indicating that all the scripts in the folder will be available from now on.<br />
Nautilus sets up four environment variables for the process executing the script which are:</p>
<pre><code>NAUTILUS_SCRIPT_SELECTED_FILE_PATHS: selected file paths.

NAUTILUS_SCRIPT_SELECTED_URIS: URIs delimited by \n

NAUTILUS_SCRIPT_CURRENT_URI: Current URI

NAUTILUS_SCRIPT_WINDOW_GEOMETRY: size and location of the current window
</code></pre>
<p>In addition, the names (without the full path) of all the selected items are passed to the script as input parameters.</p>
<p>These scripts will be executed silently (not in a terminal window) so it seems reasonable to be able to communicate with the user. Enter zenity.</p>
<p><strong><u>Introducing zenity</u></strong><br />
zenity is a program for displaying GTK+ dialogs. It reads data from stdin and returns user input through stdou. It is an easy way of gathering and showing information from a shell script on a desktop environment. Here are some examples on how to use zenity:</p>
<p>Show an information window:</p>
<pre><code>$ zenity --info --title=InfoWindow --text="This is an information text"

<img class="alignnone size-full wp-image-1829" src="http://commandliners.com/wp-content/uploads/2010/03/zenity-info-window.png" alt="zenity-info-window" width="254" height="149" />
</code></pre>
<p>Get some user input:</p>
<pre><code>$zenity --entry --title=EntryWindow --text="Type a text, please"

<img class="alignnone size-full wp-image-1828" src="http://commandliners.com/wp-content/uploads/2010/03/zenity-entry-window.png" alt="zenity-entry-window" width="208" height="137" />

Hello World!
$
</code></pre>
<p>As you can see, zenity provides an easy way to interact with the user in a graphical environment.</p>
<p>With this little information, it is possible to write a small debugging script. I called it <code>test.sh</code></p>
<pre><code>#! /bin/bash
# Use /usr/local/bin/bash on FreeBSD

ZENITY=$(which zenity)

$ZENITY --info --text="$*"

$ZENITY --info --text="NAUTILUS_SCRIPT_SELECTED_FILE_PATHS = $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
$ZENITY --info --text="NAUTILUS_SCRIPT_SELECTED_URIS = $NAUTILUS_SCRIPT_SELECTED_URIS"
$ZENITY --info --text="NAUTILUS_SCRIPT_CURRENT_URI  = $NAUTILUS_SCRIPT_CURRENT_URI"
$ZENITY --info --text="NAUTILUS_SCRIPT_WINDOW_GEOMETRY = $NAUTILUS_SCRIPT_WINDOW_GEOMETRY"
</code></pre>
<p>This script shows the contents of the parameters and the Nautilus variables.</p>
<p>zenity is really easy to use, and with a little effort and some bash scripting knowledge (that I will not explain, because it is out of the scope of this post) you can write a convenience script like the one below (I named it <code>packit.sh</code>):</p>
<pre><code>#! /bin/bash
# Use /usr/local/bin/bash on FreeBSD
#
# Small script intended to be used from Nautilus.
# It compresses the selected files and/or directories
# in several formats
# Requires: zenity, tar, gzip, bzip2, zip, mkisofs

FORMATS="tar tgz tbz2 zip iso9660"
ZENITY=$(which zenity)

# Check if we have selected any files...
if [ -z "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" ]; then
        $ZENITY --error --text="No files selected"
        exit 0;
fi

# Ask for output file name
output_filename=packit-$(date +%s)
output_filename=$($ZENITY --entry --title="Output file name" --text="Type file name" --entry-text="$output_filename")

# Ask the user to select a compressing format
selected_format=$($ZENITY --title="Select format" --list --column=Format $FORMATS)

if [ -z "$selected_format" ]; then
        $ZENITY --error --text="No format selected"
        exit 0;
fi

# Select the compressing utility to use
case $selected_format in
        "tar")
                COMP_COMMAND="tar cvf"
        ;;
        "tgz")
                COMP_COMMAND="tar czvf"
        ;;
        "tbz2")
                COMP_COMMAND="tar cjvf"
        ;;
        "zip")
                COMP_COMMAND="zip -9"
        ;;
        "iso9660")
                COMP_COMMAND="mkisofs -R -o"
        ;;
esac

# Execute the command while showing a progress bar.
(echo "0" ;
 $COMP_COMMAND "$output_filename" $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
 echo "100") | $ZENITY --progress --pulsate --title=Working...
</code></pre>
<p>The script above works for me, but it assumes the existence of several commands. If you want to use it you might need modify some lines.</p>
<p>Enjoy!</p>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/-WsIiIp_Ztw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2010/03/shell-scripting-for-nautilus/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2010/03/shell-scripting-for-nautilus/</feedburner:origLink></item>
		<item>
		<title>Running e2fsck on a mounted filesystem</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/IFzn2H8pHP0/</link>
		<comments>http://commandliners.com/2010/02/running-e2fsck-on-a-mounted-filesystem/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 12:43:15 +0000</pubDate>
		<dc:creator>rafacas</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[e2fsck]]></category>

		<category><![CDATA[filesystem]]></category>

		<category><![CDATA[fsck]]></category>

		<category><![CDATA[mounted]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1791</guid>
		<description><![CDATA[I know, running fsck on a mounted filesystem is utterly unrecommended. The command warns you (it actually frightens you) with the following message:
# fsck /dev/VolGroup00/LogVol00
fsck 1.41.4 (27-Jan-2009)
e2fsck 1.41.4 (27-Jan-2009)
/dev/VolGroup00/LogVol00 is mounted.  

WARNING!!!  Running e2fsck on a mounted filesystem may cause
SEVERE filesystem damage.

Do you really want to continue (y/n)? no

check aborted.

But sometimes I need [...]]]></description>
			<content:encoded><![CDATA[<p>I know, running <code>fsck</code> on a mounted filesystem is utterly unrecommended. The command warns you (it actually <i>frightens</i> you) with the following message:</p>
<pre><code># fsck /dev/VolGroup00/LogVol00
fsck 1.41.4 (27-Jan-2009)
e2fsck 1.41.4 (27-Jan-2009)
/dev/VolGroup00/LogVol00 is mounted.  

WARNING!!!  Running e2fsck on a mounted filesystem may cause
SEVERE filesystem damage.

Do you really want to continue (y/n)? no

check aborted.
</code></pre>
<p>But sometimes I need to check a filesystem in a remote host, so I cannot boot from a liveCD to run <code>fsck</code> in the unmounted device. Looking for an option allowing me to overcome this nuisance I found the following in e2fsck&#8217;s man page:</p>
<pre><code>Note  that  in general it is not safe to run e2fsck on mounted filesys-
tems.  The only exception is if the -n option is specified, and -c, -l,
or  -L  options  are not specified.
</code></pre>
<p>Using <code>e2fsck</code> instead of <code>fsck</code> is not a problem because it checks ext2 and ext3 filesystems and mine are ext3 (<code>fsck</code> checks and optionally repairs a lot of filesystem types).</p>
<p>Let us see what the man page says about the <code>-n</code> option:</p>
<pre><code>-n     Open the filesystem read-only, and assume an answer of  `no'  to
       all  questions.   Allows  e2fsck  to  be used non-interactively.
       (Note: if the -c, -l, or -L options are specified in addition to
       the -n option, then the filesystem will be opened read-write, to
       permit the bad-blocks list to be  updated.   However,  no  other
       changes will be made to the filesystem.)  This option may not be
       specified at the same time as the -p or -y options.
</code></pre>
<p>So it seems to be safe running it with that option. But the <code>e2fsck</code> man page also states (dealing with the safe check):</p>
<pre><code>However, even if it is safe to do
so, the results printed by e2fsck are not valid if  the  filesystem  is
mounted.    If e2fsck asks whether or not you should check a filesystem
which is mounted, the only correct answer is ``no''.  Only experts  who
really know what they are doing should consider answering this question
in any other way.
</code></pre>
<p>So, I use it only when I want to know if there is something wrong with the filesystem. I run it with the <code>-f</code> option too which forces checking even if the file system seems clean.</p>
<pre><code># e2fsck -fn /dev/VolGroup00/LogVol00
e2fsck 1.41.4 (27-Jan-2009)
Warning!  /dev/VolGroup00/LogVol00 is mounted.
Warning: skipping journal recovery because doing a read-only filesystem check.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
F10-i686-Live: 123335/475136 files (3.8% non-contiguous), 876070/1900544 blocks
</code></pre>
<p>If the output is like above all is OK, but if the device has errors, then you will need to run <code>fsck</code> with the filesystem unmounted.</p>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/IFzn2H8pHP0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2010/02/running-e2fsck-on-a-mounted-filesystem/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2010/02/running-e2fsck-on-a-mounted-filesystem/</feedburner:origLink></item>
		<item>
		<title>Force fsck at next boot</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/Txgd26e5BlA/</link>
		<comments>http://commandliners.com/2010/02/force-fsck-at-next-boot/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 09:31:51 +0000</pubDate>
		<dc:creator>rafacas</dc:creator>
		
		<category><![CDATA[cmd]]></category>

		<category><![CDATA[boot]]></category>

		<category><![CDATA[fsck]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1812</guid>
		<description><![CDATA[# touch /forcefsck
Creating an empty forcefsck file in the root directoy will force fsck to run at the next boot.
]]></description>
			<content:encoded><![CDATA[<pre><code># touch /forcefsck</code></pre>
<p>Creating an empty <code>forcefsck</code> file in the root directoy will force <code>fsck</code> to run at the next boot.</p>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/Txgd26e5BlA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2010/02/force-fsck-at-next-boot/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2010/02/force-fsck-at-next-boot/</feedburner:origLink></item>
		<item>
		<title>Vim for programmers (III)</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/DMjmsNwklV0/</link>
		<comments>http://commandliners.com/2010/01/vim-for-programmers-iii/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 16:00:59 +0000</pubDate>
		<dc:creator>n0str0m0</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[branch]]></category>

		<category><![CDATA[fold]]></category>

		<category><![CDATA[man]]></category>

		<category><![CDATA[manual]]></category>

		<category><![CDATA[mark]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[undo]]></category>

		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1632</guid>
		<description><![CDATA[Welcome to the last &#8220;Vim for programmers&#8221; issue.  Ironically, in this issue I will show you some nice characteristics despite they are not specific of programming. However they make much more sense when they are applied to programming.
Getting C help
This first feature is oriented directly to C programming. In most UNIX systems, there is [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to the last &#8220;Vim for programmers&#8221; issue.  Ironically, in this issue I will show you some nice characteristics despite they are not specific of programming. However they make much more sense when they are applied to programming.</p>
<p><u>Getting C help</u><br />
This first feature is oriented directly to C programming. In most UNIX systems, there is a collection of system manual pages available with the command &#8220;man&#8221;. Although I will not explain <b>man</b> in detail (you can read more <a href="http://www.manpages.info/linux/man.1.html">here</a> (or type <code>man man</code>) it is worth saying it shows information about the command, system call, file, etc passed as parameter. In the simplest case it works this way:</p>
<pre><code>$ man scanf</code></pre>
<p>How is this related to Vim? Vim allows contextual access to the system manual using the <i>K</i> command. For example, given the code below:</p>
<pre><code>#include
int main(int argc, char **argv)
{
  printf("Hello world);
}
</code></pre>
<p>We can place the cursor at the &#8220;printf&#8221; function call and press <i>K</i>.<br />
However, the information showed by <i>man</i> relates to the <i>printf</i> user command. At this point, it is necessary to explain that the system manual is split into several sections (man man for more information). To query the manual about a specific section, we need to pass the section number as first parameter, e.g:</p>
<pre><code>$ man read   # Section 1, shows read /bin/sh built-in command.
$ man 2 read   # Section 2, shows read system call.
</code></pre>
<p>Going back to our example, if we want to see the manual page on the printf  C function (Section 3 &#8220;System library calls&#8221;) we need to type <i>3K</i>. Once you are done with the manual, type ENTER to return to Vim.<br />
This is an extremely useful feature (unless you have memorized all the functions / system calls present in your system)</p>
<p><u>Folding</u><br />
Folding is just great. It is a feature that lets you &#8220;compress&#8221; several lines into a single one which is useful to compress function bodies for instance. The fold can be opened and closed at will. To create a fold,  type &#8220;zf&#8221;. But first, you have to instruct Vim which lines to include. You can do this<br />
in several ways (repetition, selecting the lines in visual mode, etc):</p>
<pre><code>void simple_function(void)
{
 int i;
 int j;
 float f;

return;
}
</code></pre>
<p>If we want to fold the variable declaration section and the cursor is placed at the first variable declaration line, we can do the following: &#8220;zf2j&#8221;.<br />
This tells Vim to create a fold and include the current line and the next two. The same thing can be done with &#8220;Vjjzf&#8221;. In this case, we go to visual mode, move two lines downwards and create the fold. In both cases, we end up with the following:</p>
<pre><code>void simple_function(void)
{
+--  3 lines: int i;-------------------------------------------------------------------------------------------
       return;
}
</code></pre>
<p>Vim replaces the selected lines with a single one. This line has a leading &#8216;+&#8217; character and shows the first folded line as a reminder for the user. Placing the cursor at that line we can operate with the fold. We can either open it (<i>zo</i>) or close it (<i>zc</i>). These two operations can be applied at every line inside the fold.</p>
<p>Folds behave as other text objects in most aspects. You can cut a fold and paste it elsewhere, however, when you paste it, the fold is destroyed (hold your horses, I said the fold, but your text is still there). If you undo (<i>u</i>) the copy-paste operation, the fold does not come back. If you make a copy, the fold persists, and the new text (wherever you paste it) is pasted unfolded.</p>
<p>Folds can be nested, as in the example below:</p>
<pre><code>int main(int argc, char **argv)
{
       int var1;
       int var2;
       float var3;

       struct person {
               unsigned int salary;
               unsigned char siblings;
               char *name;
       };

       struct person john;

       return 0;
}
</code></pre>
<p>First, we collapse the struct person</p>
<pre><code>int main(int argc, char **argv)
{
       int var1;
       int var2;
       float var3;

+---  5 lines: struct person {---------------------------------------------------------------------------------
       struct person john;

       return 0;
}
</code></pre>
<p>And then, we compress everything but the return statement.</p>
<pre><code>int main(int argc, char **argv)
{
+-- 11 lines: int
var1;----------------------------------------------------------------------
       return 0;
}
</code></pre>
<p>If we unfold the top level fold, the inner one is shown collapsed. The states of nested folds are independent. <i>zd</i> and <i>zD</i> are used to deleted folds (the latter recursively), and <i>zE</i> deletes all the folds in the current window. As a general rule, the capitalized version of all the commands (<i>zC</i>, <i>zO</i>) applies the action recursively.</p>
<p><u>Marks</u><br />
The name speaks by itself. Marks allow you to refer to a location in a file, using a name. I make an intensive use of marks, because often, I need to jump from one place to another in the code. Let us see how to use them playing with a small text:</p>
<pre><code>This is the fi<b>r</b>st line
This is a second line
And finally, this is the last line
</code></pre>
<p>The cursor is placed at the &#8220;r&#8221; in boldface in the first line. We use the <b>m</b> command followed by the letter (the identifier) of the mark to create a new mark. For instance <i>ma</i> creates a mark called <i>a</i>. Marks are not shown in Vim in any way, they just exist :)<br />
Once the mark is set, you can jump to it using either <b>&#8216;</b> or <b>`</b> followed by the mark identifier. The single quote jumps to the beginning of the line (the <b>T</b> letter) and the backtick jumps to the specific location of the mark (the <b>r</b> letter). The <i>:delmarks</i> command deletes the specified mark and <i>:marks</i> shows all the marks.<br />
There are two kind of mark identifiers:</p>
<ul>
<li>a - z. Valid within a file as long as it is loaded in a buffer
<li>A - Z. Valid between files.
</ul>
<p>When using upper case letters as identifiers, Vim loads the required file if necessary.
<p>
<b>Note:</b> There is another kind of mark identifiers (0 - 9) but they are out of the scope of this post.
<p>
Marks are specially useful for jumping between two or more functions or locations in your code.</p>
<p><u>Undo branches</u><br />
This is a complex topic and I will just introduce it. For more information, see <i>:help new-undo-branches</i> on a Vim 7 editor.<br />
Vim supports undo branches. This means Vim can keep track of the different changes you made to your text (or your code). In its simplest form, you can use two commands, <i>:earlier</i> and <i>:later</i> to bring your code to a previous state. E.g:</p>
<pre><code>:earlier 20s
:later 5m
:earlier 2h
</code></pre>
<p>The commands above bring the code to the state it was 20 seconds earlier, 5 minutes later and 2 hours later.<br />
This is useful when making changes to code under no source control systems. Undo branches is a new feature present in Vim since version 7. I recommend you to play with it and learn how to get the maximum out of it.</p>
<p><u>Vim Sheet (VI)</u></p>
<ul>
<li> <b>[number]K</b>. Show manual page for the word under the cursor.
<li> <b>zf</b>. Create a fold.
<li> <b>zo / zc</b> Open / close a fold.
<li> <b>zd</b> Delete a fold.
<li> <b>zE</b> Delete all the folds in a file.
<li> <b>m[identifier]</b> Creates a mark
<li> <b>&#8216;[identifier]</b> Goes to the first non-blank character of the line where the mark is located
<li> <b>`[identifier]</b> The same as above but move to the precise location of the mark.
<li> <b>:marks</b> Show all the marks
<li> <b>:delmarks</b> Delete a mark.
<li> <b>:earlier [s/m/h]</b> Brings the text to an earlier state
<li> <b>:later [s/m/h]</b> Brings the text to a later state from a past point in the undo branch.
</ul>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/DMjmsNwklV0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2010/01/vim-for-programmers-iii/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2010/01/vim-for-programmers-iii/</feedburner:origLink></item>
		<item>
		<title>RPM: Listing dependencies of an rpm file</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/N6cYIIxof4g/</link>
		<comments>http://commandliners.com/2010/01/rpm-listing-dependencies-of-an-rpm-file/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 17:46:05 +0000</pubDate>
		<dc:creator>rafacas</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[dependencies]]></category>

		<category><![CDATA[manager]]></category>

		<category><![CDATA[package]]></category>

		<category><![CDATA[red hat]]></category>

		<category><![CDATA[rpm]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1673</guid>
		<description><![CDATA[rpm is a powerful Package Manager, which can be used to build, install, query, verify, update and erase individual software packages. It is the default package manager for several popular distributions such as Red Hat, Fedora, Suse and many others.
The list of dependencies an rpm package has, that is, the packages that must be installed [...]]]></description>
			<content:encoded><![CDATA[<p><code><a href="http://commandliners.com/tag/rpm/">rpm</a></code> is a powerful Package Manager, which can be used to build, install, query, verify, update and erase individual software packages. It is the default package manager for several popular distributions such as Red Hat, Fedora, Suse and many others.</p>
<p>The list of dependencies an <code>rpm</code> package has, that is, the packages that must be installed in the system for it to work properly, can be shown with the following command if the argument is the rpm file:</p>
<pre><code># rpm -qpR rsync-3.0.6-0.fc10.i386.rpm
config(rsync) = 3.0.6-0.fc10
libacl.so.1
libacl.so.1(ACL_1.0)
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1)
libc.so.6(GLIBC_2.2)
libc.so.6(GLIBC_2.3)
libc.so.6(GLIBC_2.3.4)
libc.so.6(GLIBC_2.4)
libc.so.6(GLIBC_2.8)
libpopt.so.0
libpopt.so.0(LIBPOPT_0)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rtld(GNU_HASH)
</code></pre>
<p>and this command if querying on the package name:</p>
<pre><code># rpm -qR rsync
config(rsync) = 3.0.6-0.fc10
libacl.so.1
libacl.so.1(ACL_1.0)
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1)
libc.so.6(GLIBC_2.2)
libc.so.6(GLIBC_2.3)
libc.so.6(GLIBC_2.3.4)
libc.so.6(GLIBC_2.4)
libc.so.6(GLIBC_2.8)
libpopt.so.0
libpopt.so.0(LIBPOPT_0)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rtld(GNU_HASH)
</code></pre>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/N6cYIIxof4g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2010/01/rpm-listing-dependencies-of-an-rpm-file/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2010/01/rpm-listing-dependencies-of-an-rpm-file/</feedburner:origLink></item>
		<item>
		<title>Vim for programmers (II)</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/6AYjSUVhnV4/</link>
		<comments>http://commandliners.com/2010/01/vim-for-programmers-ii/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 09:52:18 +0000</pubDate>
		<dc:creator>n0str0m0</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[completion]]></category>

		<category><![CDATA[make]]></category>

		<category><![CDATA[omni]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1635</guid>
		<description><![CDATA[In the first part of this series, we visited some Vim features that help us in programming. In this second issue, I will show you some other important things you should know to really appreciate the power of Vim.
Completion
Completion is not a programming specific feature in Vim, however it is in programming where I find [...]]]></description>
			<content:encoded><![CDATA[<p>In the first part of this series, we visited some Vim features that help us in programming. In this second issue, I will show you some other important things you should know to really appreciate the power of Vim.</p>
<p><u>Completion</u><br />
Completion is not a programming specific feature in Vim, however it is in programming where I find it to be more useful. There are several completion options, but I will explain the ones I find more interesting. Completion is a sub mode of insert mode. This means the commands are applied while being in insert mode.</p>
<ul>
<li>Line completion: Ctrl-x Ctrl-l completes the whole line. This is very useful as in programming, yo usually need to write exactly the same line you wrote before or a line very similar to that one.
<li>Word completion: Ctrl-p completes a word
<li>File completion: Ctrl-x Ctrl-f Extremely useful in #include like sentences as it completes file names.
</ul>
<p><u>Tags</u><br />
Tags are a used to rapidly navigate source code. Having the cursor placed at a function invocation, it lets you jump to the function definition. Vim has support for tags based on the <a href="http://ctags.sourceforge.net/">ctags</a> utility. Ctags scans your source files and creates an index file with information about the structures and objects found in the code. Vim uses this file to know about your source code (functions, variables, etc.)<br />
The first step is to run ctags. Change to the top level source directory of your project and run the following command:</p>
<pre><code>$ ctags -R</code></pre>
<p>This runs ctags recursively in all directories. Note that the BSD ctags version does not provide this flag, so it could be convenient to install the GNU version from ports (/usr/ports/devel/ctags) that gets named <i>exctags</i> upon installation.<br />
Ctags just creates a &#8220;tags&#8221; file we can inspect (it is a text file):</p>
<pre><code>$ less tags

!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Darren Hiebert  /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME      Exuberant Ctags //
!_TAG_PROGRAM_URL       http://ctags.sourceforge.net    /official site/
!_TAG_PROGRAM_VERSION   5.5.4   //
__UTILS_H__     utils.h 2;"     d
main    main.c  /^int main(int argc, char **argv)$/;"   f
multiply        utils.c /^int multiply(const int a, const int b)$/;"    f
</code></pre>
<p>Vim uses a tags file in the current directory if present, but it can be instructed to load an alternative one using the -t flag:</p>
<pre><code>$ vim -t /path/to/tags_file</code></pre>
<p>Let us create a project with three files:</p>
<pre><code>$ cat main.c

#include "utils.h"

int main(int argc, char **argv)
{
        int result;

        resultxx = multiply(3, 4);  /* resultxx is not defined */

        printf("Result = %d\n", result)   /* ; missing */

        retrun 0;   /* this should be 'return' */
}

$ cat utils.c
int multiply(const int a, const int b)
{
        return a * b;
}

$ cat utils.h
#ifndef __UTILS_H__
#define __UTILS_H__

int multiply(const int a, const int b);

#endif /* __UTILS_H__ */
</code></pre>
<p>After running ctags * (we do not need the -R flag in this example) if we place the cursor at the &#8216;multiply&#8217; invocation and press Ctrl-], we jump to the function&#8217;s code. Once there, we can go back using Ctrl-t. Vim stacks the jumps so you can move forward / backwards using these commands no matter how deep you go into your code. At any time, you can check the state of the stack with:</p>
<pre><code>:tags
 # TO tag         FROM line  in file/text
  1  1 multiply            8  main.c
&gt;
</code></pre>
<p><u>Finding the declaration</u><br />
The embedded <b>gD</b> command applied on a variable or function name moves the cursor to the declaration of that variable / function. If the prototype of the function does not exist, then it takes the cursor to the definition of the function.</p>
<p><u>Omni completion</u><br />
This is known by Microsoft as &#8220;Intellisense&#8221;. It basically autocompletes in an intelligent way. For instance, if you have something like this:</p>
<pre><code>struct person {
      char* name;
      unsigned char children
      unsigned char age;
};

struct person john;
</code></pre>
<p>Now, if you type <b>john.</b> and then Ctrl-X Ctrl-O, Vim will autocomplete with one of the fields of the struct. This would be in a perfect world, however this is not as easy. First off, omni completion is based on a ctags file. If you want a &#8220;full&#8221; C language completion, you need to first create a tags file scanning /usr/include, /usr/local/include and so on. In my laptop (AMD 64 900 MHz), executing this:</p>
<pre><code>exctags -R -f ~/.vim/systags /usr/include /usr/local/include</code></pre>
<p>takes almost 6 minutes and the generated file is as big as 791M. In addition if you install a new development library, you will need to scan the .h files to add them to you tags file. Personally I do not use omni completion as I do not think it is mature enough yet.</p>
<p><u>Compiling from inside Vim</u><br />
Let us assume you are editing main.c from the project above. Usually, you would leave the editor and compile the sources by hand, typing commands in the shell. From inside Vim, you can do the same with:</p>
<pre><code>$ :!gcc -Wall -o program main.c utils.c</code></pre>
<p>But there is a more efficient mechanism to compile a project. This method implies the creation of a Makefile. Probably you should have a Makefile for all your projects as it improves compilation times and helps managing other tasks as installation. How to write a Makefile is out of the scope of this post, you can find more information <a href="http://www.seul.org/docs/autotut/">here</a>. Assuming you have created your Makefile, you can compile your project with:</p>
<pre><code>:make

f00993z4@cipres:~/prueba/dummy&gt; vim main.c

gcc -o program main.c utils.c
main.c: In function 'main':
main.c:8: error: 'resultxx' undeclared (first use in this function)
main.c:8: error: (Each undeclared identifier is reported only once
main.c:8: error: for each function it appears in.)
main.c:12: error: expected ';' before 'retrun'
make: *** [all] Error 1

Press ENTER or type command to continue
</code></pre>
<p>So far, the behavior is similar to the shell way. However, Vim parsed the output of the make command so you can see a list of errors directly from Vim:</p>
<pre><code>:clist
 3 main.c:8: error: 'resultxx' undeclared (first use in this function)
 4 main.c:8: error: (Each undeclared identifier is reported only once
 5 main.c:8: error: for each function it appears in.)
 6 main.c:12: error: expected ';' before 'retrun'
Pulse INTRO o escriba una orden para continuar
</code></pre>
<p>The example above shows the output of make with the lines in which the errors occurred. In addition the messages are pretty nice formatted and colored ;)</p>
<p>After typing ENTER, Vim places the cursor at the line in which the first error occurred (line 8).<br />
We fix the error (the name of the variable is wrong)  and move on:</p>
<pre><code>:cn
</code></pre>
<p>We have to do this several times because Vim shows you all of make&#8217;s output, so you have the whole description instead of just the first line of the error message (in this case, the error was pretty obvious, but in cases in which C++ and STL are involved, I really appreciate the complete message).<br />
Finally, Vim places the cursor at other line:</p>
<pre><code>(6 de 7): error: expected ';' before 'retrun'
</code></pre>
<p>We missed the &#8216;;&#8217; at the previous line. We fix the error and move on:</p>
<pre><code>:cn
</code></pre>
<p>There are no more errors. How is this possible if we did not fix the &#8216;retrun&#8217; issue? It is because the compiler did not reach that point. It realized the &#8216;;&#8217; was missing and after that it could not tell what the &#8216;retrun&#8217; thing was about. This is how compilers work, we can not blame Vim for it :)<br />
Let us compile again:</p>
<pre><code>:make

gcc -o program main.c utils.c
main.c: In function 'main':
main.c:12: error: 'retrun' undeclared (first use in this function)
main.c:12: error: (Each undeclared identifier is reported only once
main.c:12: error: for each function it appears in.)
main.c:12: error: expected ';' before numeric constant
make: *** [all] Error 1
</code></pre>
<p>We fix the error, and compile for the last time:</p>
<pre><code>:make

Press ENTER or type command to continue
gcc -o program main.c utils.c

Press ENTER or type command to continue
</code></pre>
<p>Here you are!, your project successfully compiled!.</p>
<p>I moved forward fixing a bug at a time, but you can use the <i>:cp</i> (cprevious) command to move to a previous error line.</p>
<p>Note that the :make command does not actually execute the &#8216;make&#8217; program. It executes the program the variable <i>makeprg</i> is pointing to. In my BSD box, I usually do this:</p>
<pre><code>:set makeprg=gmake
</code></pre>
<p>in order to use the GNU make version instead of the BSD licensed one.</p>
<p><u>Conclusion</u><br />
Vim provides many features useful for programming. Completion is specially useful as Vim learns as you type. The other very useful thing is the possibility of executing Makefiles from inside the editor. The parsing of the output makes the edit-compile-debug cycle more efficient.
<p>
<u>Vim Sheet (VI)</u></p>
<ul>
<li>Ctrl-x Ctrl-l / Ctrl-p / Ctrl-f Autocomplete the whole line / word / file name
<li> vim -t file_name Open Vim with the file_name tags file loaded.
<li>Ctrl-] / Ctrl-t Jump to the definition of that object / Jump back. (The objects must be scanned and present in the tags file)
<li>gD Go to the declaration / definition of the variable / function name
<li>:make Execute make in the current directory
<li>:clist Show the error and warning list
<li>:cn / :cp Move to the next / previous error line.
</ul>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/6AYjSUVhnV4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2010/01/vim-for-programmers-ii/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2010/01/vim-for-programmers-ii/</feedburner:origLink></item>
		<item>
		<title>Make Love</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/mVD7oKCkotU/</link>
		<comments>http://commandliners.com/2009/12/make-love/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 12:55:59 +0000</pubDate>
		<dc:creator>n0str0m0</dc:creator>
		
		<category><![CDATA[cmd]]></category>

		<category><![CDATA[cd]]></category>

		<category><![CDATA[FreeBSD]]></category>

		<category><![CDATA[make]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1702</guid>
		<description><![CDATA[In FreeBSD:
$ cd /usr/src
$ make love

Enjoy the output. Merry Christmas!
Source: psybermonkey
]]></description>
			<content:encoded><![CDATA[<p>In FreeBSD:</p>
<pre><code>$ cd /usr/src
$ make love
</code></pre>
<p>Enjoy the output. Merry Christmas!</p>
<p>Source: <a href="http://scratching.psybermonkey.net/2009/09/30/freebsd-for-the-love-of-all/">psybermonkey</a></p>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/mVD7oKCkotU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2009/12/make-love/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2009/12/make-love/</feedburner:origLink></item>
		<item>
		<title>Mounting and unmounting a disk image (dmg) in OS X</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/VdEBa3PuVBg/</link>
		<comments>http://commandliners.com/2009/12/mounting-and-unmounting-a-disk-image-dmg-in-os-x/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 07:00:34 +0000</pubDate>
		<dc:creator>rafacas</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[hdiutil]]></category>

		<category><![CDATA[mount]]></category>

		<category><![CDATA[osx]]></category>

		<category><![CDATA[unmount]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1655</guid>
		<description><![CDATA[A file with the extension .dmg uses a proprietary disk image format commonly found on Mac OS X (well, usually: you can use any extension anywhere, obviously) .
The command used for manipulating disk images is hdiutil
$ hdiutil attach nmap-5.00.dmg
esperado   CRC32 $C955C266
/dev/disk2             [...]]]></description>
			<content:encoded><![CDATA[<p>A file with the extension <code>.dmg</code> uses a proprietary disk image format commonly found on Mac OS X (well, usually: you can use any extension anywhere, obviously) .</p>
<p>The command used for manipulating disk images is <code>hdiutil</code></p>
<pre><code>$ hdiutil attach nmap-5.00.dmg
esperado   CRC32 $C955C266
/dev/disk2              Apple_partition_scheme
/dev/disk2s1            Apple_partition_map
/dev/disk2s2            Apple_HFS                       /Volumes/nmap-5.00
</code></pre>
<p>This command will attach a disk image to the system as a device. <code>attach</code> will return information about an already-attached image if it had already attached it. <code>mount</code> is a synonym for <code>attach</code>.</p>
<pre><code>$ hdiutil detach /Volumes/nmap-5.00/
"disk2" unmounted.
"disk2" ejected.
</code></pre>
<p>The above command will detach a disk image and terminate any associated hdid process. <code>eject</code> is a synonym for detach.</p>
<p>There are useful encryption options which we shall speak of in a forthcoming post.</p>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/VdEBa3PuVBg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2009/12/mounting-and-unmounting-a-disk-image-dmg-in-os-x/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2009/12/mounting-and-unmounting-a-disk-image-dmg-in-os-x/</feedburner:origLink></item>
		<item>
		<title>Are your DNS Servers failing?</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/s1EYiLKTxWU/</link>
		<comments>http://commandliners.com/2009/12/are-your-dns-servers-failing/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 07:45:16 +0000</pubDate>
		<dc:creator>rafacas</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1649</guid>
		<description><![CDATA[Some days ago Google launched its public DNS service. Another older, public DNS service is OpenDNS. Both let you use their DNS servers insted of your ISP&#8217;s.
I have been using OpenDNS for a year because I had problems with my ISP&#8217;s DNS servers. They were down frequently, so I searched for a reliable alternative. There [...]]]></description>
			<content:encoded><![CDATA[<p>Some days ago Google launched its <a href="http://code.google.com/speed/public-dns/">public DNS service</a>. Another older, public DNS service is <a href="http://www.opendns.com/">OpenDNS</a>. Both let you use their DNS servers insted of your ISP&#8217;s.</p>
<p>I have been using OpenDNS for a year because I had problems with my ISP&#8217;s DNS servers. They were down frequently, so I searched for a reliable alternative. There are some ways to know if your service provider&#8217;s DNS servers are working properly.</p>
<p>You can use <code>nslookup</code>, which is a program to query Internet domain name servers.</p>
<pre><code>$ nslookup google.com
Server:         208.67.222.222
Address:        208.67.222.222#53

Non-authoritative answer:
Name:   google.com
Address: 66.102.9.103
Name:   google.com
Address: 66.102.9.105
Name:   google.com
Address: 66.102.9.99
Name:   google.com
Address: 66.102.9.104
Name:   google.com
Address: 66.102.9.147
</code></pre>
<p>The <code>host</code> command is a simple utility for performing DNS lookups. It is normally used to convert names to IP addresses and vice versa.</p>
<pre><code>$ host google.com
google.com has address 66.102.9.105
google.com has address 66.102.9.147
google.com has address 66.102.9.104
google.com has address 66.102.9.103
google.com has address 66.102.9.99
google.com mail is handled by 10 google.com.s9b2.psmtp.com.
google.com mail is handled by 10 google.com.s9a2.psmtp.com.
google.com mail is handled by 10 google.com.s9b1.psmtp.com.
google.com mail is handled by 10 google.com.s9a1.psmtp.com.
</code></pre>
<p>And finally, the <code>dig</code> command (domain information groper) is a flexible tool for querying DNS name servers. It  performs DNS lookups and displays the answers returned from the queried name server(s). Most DNS administrators use <code>dig</code> to troubleshoot DNS problems because of its flexibility, ease of use and clarity of output.</p>
<pre><code>$ dig google.com

; <<>> DiG 9.4.3-P3 <<>> google.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62217
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             141     IN      A       66.102.9.103
google.com.             141     IN      A       66.102.9.104
google.com.             141     IN      A       66.102.9.105
google.com.             141     IN      A       66.102.9.147
google.com.             141     IN      A       66.102.9.99

;; Query time: 223 msec
;; SERVER: 208.67.222.222#53(208.67.222.222)
;; WHEN: Mon Dec 14 18:49:21 2009
;; MSG SIZE  rcvd: 108
</code></pre>
<p>if one of these command does not return an IP address as a result, then the DNS servers are not working. <i>Usually</i> this can be tested with <code>$?==0</code>: if true, the command returned a valid IP address, otherwise there was a problem.</p>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/s1EYiLKTxWU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2009/12/are-your-dns-servers-failing/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2009/12/are-your-dns-servers-failing/</feedburner:origLink></item>
		<item>
		<title>Vim for programmers (I)</title>
		<link>http://feedproxy.google.com/~r/commandliners/~3/rl_ZYzURrcQ/</link>
		<comments>http://commandliners.com/2009/12/vim-for-programmers-i/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 07:00:19 +0000</pubDate>
		<dc:creator>n0str0m0</dc:creator>
		
		<category><![CDATA[shell]]></category>

		<category><![CDATA[C]]></category>

		<category><![CDATA[comment]]></category>

		<category><![CDATA[indent]]></category>

		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://commandliners.com/?p=1523</guid>
		<description><![CDATA[Vim is suitable for a myriad of applications. However, it is in programming where it specially shines. Vim offers facilities that make the programming workflow especially easy and efficient. Some people use newer editors (or IDEs) just because they think Vim lacks some new cool features. That is not the case as I will show [...]]]></description>
			<content:encoded><![CDATA[<p>Vim is suitable for a myriad of applications. However, it is in programming where it specially shines. Vim offers facilities that make the programming workflow especially easy and efficient. Some people use newer editors (or IDEs) just because they think Vim lacks some new cool features. That is not the case as I will show you in this issue.</p>
<p>(I will use C source files in the examples, but most of the information in this post is applicable regardless of the language programming you use)</p>
<p><span style="text-decoration: underline;">Syntax highlighting</span><br />
Vim supports syntax highlighting for hundreds of file types. Having a look at /usr/share/vim/vim64/syntax (this is for my linux system, it may vary on your system) reveals 420 different syntax files (one file per file type). Among these, it supports all of the most popular languages (c, c++, basic, yacc, lex, java, html, xml, eiffel, perl&#8230;). In addition, Vim also recognizes some other file formats as alsaconf, xf86conf, etc. If Vim has been properly set up after installation, it should detect the file type and color the content accordingly. If that is not the case, you can enable/disable syntax highlighting with :syntax on/off. The picture below depicts three different files  (C,  bashrc and xorg.conf) with syntax highlighting activated:</p>
<p><img class="alignnone size-medium wp-image-1535" src="http://commandliners.com/wp-content/uploads/2009/11/vim_syntax_example-300x207.png" alt="vim_syntax_example" width="300" height="207" /></p>
<p><span style="text-decoration: underline;">Line numbers</span><br />
Sometimes it is convenient to see line numbers at the left of the window. It helps to quickly locate the line you are interested in. You can do this with :set number or :set nu. To dissable it, use :set nonu[mber]</p>
<p><img class="alignnone size-medium wp-image-1534" src="http://commandliners.com/wp-content/uploads/2009/11/vim_lines_numbers-300x207.png" alt="vim_lines_numbers" width="300" height="207" /></p>
<p><span style="text-decoration: underline;">Parenthesis matching</span><br />
Vim matches parenthesis and square brackets as you type if the <em>showmatch</em> option is enabled (:set showmatch). If you want to check if your parenthesis are properly balanced, you can place the cursor at one of the parenthesis and type % in command mode. This will move the cursor to the matching parenthesis (if it exists). This works with square and curly brackets too.</p>
<p><span style="text-decoration: underline;">Vim counts for you</span><br />
This is specially cool in my opinion. Ctrl-a and Ctrl-x increments/decrements the number the cursor is placed on. This is especially good because Vim understands different bases. So, typing Ctrl-a in the following scenario:</p>
<pre><code>0x09
</code></pre>
<pre><code>0xa
</code></pre>
<p>The same works for octal numbers (those that have a leading zero) and, of course, decimal numbers. While this can seem just incidental, it turns out to be really useful if combined with repetition. What is the hexadecimal representation of 1564 (decimal)? Just do the following:</p>
<pre><code>0x0
</code></pre>
<p>And now 1564 Ctrl-a ESC (this tells Vim to do Ctrl-a 1564 times). This is what you get:</p>
<pre><code>0x61c
</code></pre>
<p><span style="text-decoration: underline;">Indentation</span><br />
Indentation is obviously an important aspect of writing software: it makes the code readable. Vim helps you in this task adding support for indentation. We need to set some global options. You can use these three:</p>
<ul>
<li> :set autoindent</li>
<li> :set smartindent</li>
<li> :set cindent</li>
</ul>
<p>The first one sets up a basic indentation. The second one provides an improved one, suitable for C and other programming languages. The third one establishes the specific indentation for C files. I use these three but you should try them and keep only those you feel comfortable with.</p>
<p>Another command to use for indentation is = (equal). It &#8220;filters&#8221; the text with an external program (if specified) or with the internal C indentation routine. To specify an external filter, you have to set the <em>equalprg</em> variable:</p>
<pre><code>:set equalprog=indent
</code></pre>
<p>Note that the definition for filter is &#8220;program that accepts text at stantard input, changes it in some way, and sends it to the standard output&#8221;. Not all programs match this criteria. Regardless of the rutine used to filter the text, = indents the line where the cursor is placed or the selected text if any.</p>
<p>Tip: <i>G=gg</i> indents the whole file. This is very useful when copy-pasting from another window, remote session, etc, messes  the indentation up. In the picture below, the left window shows a code copied from the Internet and the right one, the same text after doing <em>G=gg</em></p>
<p><em><img class="alignnone size-medium wp-image-1546" src="http://commandliners.com/wp-content/uploads/2009/11/vim_indentation-300x207.png" alt="vim_indentation" width="300" height="207" /><br />
</em></p>
<p>You can always indent text blocks freely if the automatic indentation rules do not fit your taste. In order to do this, use the &lt;&gt; commands. Applied twice on a text object they indent that text to the left or to the right.</p>
<p><span style="text-decoration: underline;">Commenting out blocks of code</span><br />
Some times, you need to comment out several lines. There is a quick way to do this and it involves using the free selection command (Ctrl-v). With it you can select portions of text freely. The trick is that after selecting the text, if you type I (capital i), write something at the beginning of the line and press ESCESC, what you just wrote will be inserted at the beginning of all the rest of the selected lines. So if we select the beginning of the line, type I, write <i>//</i> and then ESCESC, those characteres (used as comment markers in C++) will be inserted in each of the selected lines.</p>
<p><u>Conclusion</u><br />
This is the first part of &#8220;Vim for programmers&#8221;. It just shows some of the features that can be used for programming (though most of them are just useful at any time). In the next issue I will cover more of the aspects that make Vim a great editor for programmers.</p>
<p><u>Vim Sheet (V)</u></p>
<ul>
<li>:syntax on/off Enable/disable syntax highlighting
<li>:set nu/nonu Enable/disable line numbers
<li> % matches parenthesis, square brackets and curly braces
<li> Ctrl-a, Ctrl-x Increment/decrement numbers in different bases.
<li> =, &lt;&lt;, &gt;&gt; Indent text.
</ul>
<img src="http://feeds.feedburner.com/~r/commandliners/~4/rl_ZYzURrcQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://commandliners.com/2009/12/vim-for-programmers-i/feed/</wfw:commentRss>
		<feedburner:origLink>http://commandliners.com/2009/12/vim-for-programmers-i/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 0.742 seconds -->
