Tuesday, February 15, 2011

An Intro to Phing

What is Phing

Phing is a build system for php projects, like Ant is for java. Moreover phing is based on Apache Ant. Like any traditional build systems you can do a lot of things with Phing. Phing uses XML build files similar to ant build files. Phing is useful in cases where you have to write custom scripts for testing, packaging and deploying your application code. Phing provides a number of built in tasks or operational modules, and it also allows you to add custom tasks as per your need.

In short Phing provides the following features:
  • Simple XML buildfiles
  • Rich set of provided tasks
  • Easily extendable via PHP classes
  • Platform-independent: works on UNIX, Windows, MacOSX
  • No required external dependencies

How Phing Works

Phing uses XML buildfiles, these buildfiles contain a description of the things to do. A buildfile contains one or more targets. These targets contain the actual commands to execute or perform (e.g. create a directory, delete a directory, copy a file from one directory to another, create a archive file etc.). In order to use Phing, you need to write a buildfile first and then you need to run phing, specifying the target in your buildfile that you want to execute.

$ phing [-f buildfile.xml] [target]

If name of a buildfile is not given, then Phing will search for a file name build.xml in the directory from where the Phing command is run. You can also define default target in your buildfile. In that case you can skip the target also while executing the phing command.

Installation

Phing requires PHP version 5.2 or above compiled with --with-libxml2 at minimum. For advanced usage of Phing you may need other libararies and softwares. For a detailed list of dependencies you can visit this page.

The easiest way to install phing is by using the PEAR installer. Just run the following commands from the command line:
$ pear channel-discover pear.phing.info
$ pear install phing/phing

A sample Phing build file:

Given below is a small simple build file that I used for one of my projects. I have added comments before each line or section to explain what is that doing.

<?xml version="1.0"  encoding="UTF-8" ?>

<!-- project is the root element, a buildfile shoud start with project tag after the document prolog  -->
<!-- name : name of the project -->
<!-- basedir : the base project directory -->
<!-- default : the default target to build if phing is executed without specifying any target -->

<project name="applyservice" basedir="." default="main">

    <!-- define some project properties like package name, build directory and source directory -->
    <property name="package"  value="${phing.project.name}" override="true" />
    <property name="builddir" value="./build/" override="true" />
    <property name="srcdir"   value="${project.basedir}" override="true" />

    <!-- You can define set of all files to include/exclude in the build, give fileset an id for later reference -->
    <fileset dir="${srcdir}" id="allfiles">
        <include name="**/*.php" />
        <include name="**/*.yml" />
        <exclude name="**/*.log" >
    </fileset>

    <!-- Target: prepare, this will create a build directory if not already there -->
    <target name="prepare" description="initial setup">
        <echo msg="Creating build directory....." />
        <mkdir dir="./build" />
    </target>

    <!-- Target: main, Its our default target as defined in project tag -->
    <!-- A target can depend on other targets. You can define dependencies using depends attribute -->
    <!-- Our main target is dependent on prepare target to complete first -->
    <!-- You can define multiple targets in depends attribute using a comma separated list like A, B, C -->

    <target name="main" description="main target" depends="prepare">
        <echo msg="Copying files to build directory..." />
        <!-- copy all source files from the fileset defined above to the build directory -->
        <copy todir="${builddir}">
            <fileset refid="allfiles" />
        </copy>
       
        <!-- create a archive file of all the files in build directory using gzip compression -->
        <echo msg="Creating archive from build..." />
        <tar destfile="./build/build.tar.gz" compression="gzip">
            <fileset dir="./build">
                <include name="**" />
            </fileset>
        </tar>

        <echo msg="Build completed successfully........" />
    </target>

    <!-- Traget: rebuild, this target is for rebuilding, its first deletes previously build files and creates a new one by calling main target. -->
    <target name="rebuild" description="rebuilds this package">
    <echo msg="Deleting old build directory........" />
        <delete dir="${builddir}" />
        <phingcall target="main" />
    </target>
</project>

For a detailed list of all available options. Please go through the Phing User Guide.

Wednesday, February 9, 2011

Exploring timeout variables in Mysql

Few days back I was checking one of my mysql server's settings. I found that there are a number of timeout settings. Since I am using mysql for last few years, I am well aware of wait_timeout and connect_timeout variables. As if you are using mysql in production then in most of the cases you have to tune these two variables. But Mysql provides a number of other timeout variables also. 
 
If you run show variables like '%timeout' query then you will get a number of different timeout variables, in my case I got 9 such variables.

mysql> show variables like '%timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| delayed_insert_timeout     | 300   |
| innodb_lock_wait_timeout   | 50    |
| interactive_timeout            | 28800 |
| net_read_timeout               | 30    |
| net_write_timeout          | 60    |
| slave_net_timeout          | 3600  |
| table_lock_wait_timeout    | 50    |
| wait_timeout               | 5     |
+----------------------------+-------+
9 rows in set (0.00 sec)

Why are there so many timeout variables, and what are their purpose?

MySQL uses different timeout variables at different stages. When a connection is just being established connect_timeout is used. When server waits for another query to be sent to it wait_timeout (or interactive_timeout for applications which specified they are interactive during connection). If query is being read or result set is being sent back, net_read_timeout and net_write_timeout are used. innodb_lock_wait_timeout is used with Innodb tables in case getting locks on table rows. delayed_insert_timeout is used in case you are using delayed insert queries. slave_net_timeout is used in case of replication when a slave is reading data from the master.

Lets look into some more details about these variables:

connect_timeout:
The number of seconds the mysqld server waits for a connect packet before responding with Bad handshake. As of MySQL 5.1.23 the default value is 10 seconds and before that it was 5 seconds. Increasing the connect_timeout value might help if clients frequently encounter errors of the form Lost connection to MySQL server.

delayed_insert_timeout:
You can delay insert queries from happening until the table is free by using the delayed hint in your SQL statement. For example:
INSERT DELAYED INTO table (id) VALUES (123);

The above SQL statement will return quickly, and mysql server will store the insert statement in a memory queue until the table you are inserting into is free from reads. The downside to this is that you don't really know how long its going to take for your INSERT to happen. INSERT DELAYED handler thread in Mysql server will wait for delayed_insert_timeout seconds before terminating.

innodb_lock_wait_timeout:
The timeout in seconds an InnoDB transaction may wait for a row lock before giving up. innodb_lock_wait_timeout applies to InnoDB row locks only. A MySQL table lock does not happen inside InnoDB and this timeout does not apply to waits for table locks. InnoDB does detect transaction deadlocks in its own lock table immediately and rolls back one transaction. The default value is 50 seconds. A transaction that tries to access a row that is locked by another InnoDB transaction will hang for at most this many seconds before issuing the following error:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

interactive_timeout:
The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to mysql_real_connect(). interactive_timeout is the amount of seconds during inactivity that MySQL will wait before it will close a connection for a interactive connection.

net_read_timeout:
The number of seconds to wait for more data from a connection before aborting the read. Before MySQL 5.1.41, this timeout applies only to TCP/IP connections, not to connections made through Unix socket files, named pipes, or shared memory. When the server is reading from the client, net_read_timeout is the timeout value controlling when to abort. net_read_timeout rarely becomes the problem unless you have extremely poor network, because in most cases query is generated and sent as single packet to the server and application can’t switch doing something else and leaving server with partial query received.

net_write_timeout:
When the server is writing to the client, net_write_timeout is the timeout value controlling when to abort. It defines the number of seconds to wait for a block to be written to a connection before aborting the write. Before MySQL 5.1.41, this timeout applies only to TCP/IP connections, not to connections made using Unix socket files, named pipes, or shared memory. If you do not fetch data for long enough MySQL Server may think client is dead and close connection. This well may happen if you need long processing for each row or have long periodic data flushes. Also, result set comes back in multiple pieces and if you're using mysql_use_result you can do any work between fetches, which potentially could take a lot of time.

slave_net_timeout:
The number of seconds to wait for more data from the master before the slave considers the connection broken, aborts the read, and tries to reconnect. The first retry occurs immediately after the timeout. The interval between retries is controlled by the MASTER_CONNECT_RETRY option for the CHANGE MASTER TO statement or --master-connect-retry option, and the number of reconnection attempts is limited by the --master-retry-count option. The default is 3600 seconds.

table_lock_wait_timeout:
As per the mysql manual this variable is not used.

wait_timeout:
The number of seconds the server waits for activity on a noninteractive connection before closing it. This timeout applies only to TCP/IP and Unix socket file connections, not to connections made using named pipes, or shared memory. On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()). Setting a value too low may cause connections to drop unexpectedly. Setting a value too high may cause stale connections to remain open, preventing new access to the database. For wait_timeout, this value should be set as low as possible without affecting availability and performance.


Monday, February 7, 2011

Understanding MySQL Persistent Connections with mysql_pconnect()

What is mysql_pconnect():

The main purpose of using mysql_pconnect() function is to maintain a persistent connection to the mysql server. A persistent connection is a connection that do not get closed even after the excecution of the script is over which opened the connection. Even function mysql_close() can't close a persisitent connection. In contrast a normal connection opened using mysql_connect() gets closed either by mysql_close() or at the end of the scripts execution.

Why mysql_pconnect():

In one word the answer is "Efficiency". Persistent connections are good if the overhead to create a link to your db server is high. This overhead may be high due to various reasons. Persistent connections can help you considerably if the connection overhead is high.

How mysql_pconnect() works:

The most popular method to run PHP is to run it as a module in a multiprocess web server like Apache. A multiprocess server typically has one parent process which coordinates with a set of child processes. These child processes actually do the work of serving up web pages. When a request comes in from a client, it is handed over to one of the children that is free. This means that when the same client makes a second request to the server, it may be served by a different child process than the first time.

When opening a persistent connection, the function would first try to find a persistent link that is already open with the same host, username and password combination. If one is found, instead of opening a new connection an identifier for it will be returned. It causes the child process to simply connect only once for its entire lifespan, instead of every time it processes a page that requires connecting to the same db server. Every child that opened a persistent connection will have its own open persistent connection to the db server. For example, if you had 20 different child processes that ran a script that made a persistent connection to your db server, you would have 20 different connections to the db server, one from each child.

Issues with mysql_pconnect():
  • Persistent database connections don't necessarily reflect subsequent privilege changes.
  • Be very careful when using persistent connections and temporary tables on MySQL. With normal connections temporary tables are visible only to the current connection, but if you have a persistent connection the temporary tables will be visible to everybody sharing the same persistent connection. This can lead to major trouble.
  • Don't use mysql_pconnect() in situations where multiple MySQL servers are running on multiple ports of the same host. The connection pooling algo in php apparently only checks for the host, username and password combination but not the port. Therefore, if you use the same host, username and password but a different port, you might get a connection that is connected to a different port than the one you asked for.
  • Do not use transactions with persistent connections.  If your script stops or exits for any reason, your transaction will be left open and your locks will be left on.  You have to reset MySQL to release them. They won't rollback automatically on error, like they ought to. When you restart the script, you'll get a new connection, so you can't rollback or commit for the previous script.
  • You should be very careful when using LOCK TABLES with persistent connections. If the script terminates before the UNLOCK TABLES is executed, the the table(s) will stay locked, and very likely hang future scripts.

Things to remember:
  • Persistent connections were designed to have one-to-one mapping to regular connections. That means that you should always be able to replace persistent connections with non-persistent connections, and it won't change the way your script behaves. It may change the efficiency of the script, but not its behavior.
  • Any script with a start transaction, rollback, or commit SQL statement should use regular, not persistent connections.
  • Use totally random temporary table names when using persistent connections to avoid major problems.
  • Make damn sure that max connections limit in your my.cnf has a limit with a few more connections than your httpd.conf has for number of apache children. Less MySQL connections than apache children means some apache children will be starved for db.
  • Leave a few extra mysql connections, so that in case of a problem it can leave you with the ability to log in from shell to diagnose/fix it. Otherwise, you will have to bring down all of apache to get into your database.
  • You can also use register_shutdown_function() to register a simple cleanup function to unlock your tables or roll back your transactions. But it's better to avoid the problem entirely by not using persistent connections in scripts which use table locks or transactions.
  • Instead of use wait_timeout, you can set interactive_timeout to short period of time (for ex. 20 sec.) this is a lot better solution in apache + mysql environment than wait_timeout.

Sunday, February 6, 2011

ऊँचाई

ऊँचे पहाड़ पर,
पेड़ नहीं लगते,
पौधे नहीं उगते,
न घास ही जमती है।

जमती है सिर्फ बर्फ,
जो, कफ़न की तरह सफ़ेद और,
मौत की तरह ठंडी होती है।
खेलती, खिलखिलाती नदी,
जिसका रूप धारण कर,
अपने भाग्य पर बूंद-बूंद रोती है।

ऐसी ऊँचाई,
जिसका परस
पानी को पत्थर कर दे,
ऐसी ऊँचाई
जिसका दरस हीन भाव भर दे,
अभिनंदन की अधिकारी है,
आरोहियों के लिये आमंत्रण है,
उस पर झंडे गाड़े जा सकते हैं,

किन्तु कोई गौरैया,
वहाँ नीड़ नहीं बना सकती,
ना कोई थका-मांदा बटोही,
उसकी छाँव में पलभर पलक ही झपका सकता है।

सच्चाई यह है कि
केवल ऊँचाई ही काफ़ी नहीं होती,
सबसे अलग-थलग,
परिवेश से पृथक,
अपनों से कटा-बँटा,
शून्य में अकेला खड़ा होना,
पहाड़ की महानता नहीं,
मजबूरी है।
ऊँचाई और गहराई में
आकाश-पाताल की दूरी है।

जो जितना ऊँचा,
उतना एकाकी होता है,
हर भार को स्वयं ढोता है,
चेहरे पर मुस्कानें चिपका,
मन ही मन रोता है।

ज़रूरी यह है कि
ऊँचाई के साथ विस्तार भी हो,
जिससे मनुष्य,
ठूँठ सा खड़ा न रहे,
औरों से घुले-मिले,
किसी को साथ ले,
किसी के संग चले।

भीड़ में खो जाना,
यादों में डूब जाना,
स्वयं को भूल जाना,
अस्तित्व को अर्थ,
जीवन को सुगंध देता है।

धरती को बौनों की नहीं,
ऊँचे कद के इंसानों की जरूरत है।
इतने ऊँचे कि आसमान छू लें,
नये नक्षत्रों में प्रतिभा की बीज बो लें,

किन्तु इतने ऊँचे भी नहीं,
कि पाँव तले दूब ही न जमे,
कोई काँटा न चुभे,
कोई कली न खिले।

न वसंत हो, न पतझड़,
हो सिर्फ ऊँचाई का अंधड़,
मात्र अकेलेपन का सन्नाटा।

मेरे प्रभु!
मुझे इतनी ऊँचाई कभी मत देना,
ग़ैरों को गले न लगा सकूँ,
इतनी रुखाई कभी मत देना।

-अटल बिहारी वाजपेयी

Thursday, February 3, 2011

Interesting GTalk status messages

If electricity comes from electrons, does morality come from morons?

Save earth, this is the only planet where you get girls :)

The problem doesn't lie with me.... the problem lies with your expectations.

Be nice to nerds, chances are you'll end up working with one.

SEX is not the answer. SEX is the question and YES is the answer!!

Heaven won't take me and hell's afraid I'll take over.

A man in love is incomplete until he has married. Then he’s finished.

I can only please one person per day. Today isn't your day...and tomorrow don't look good either.

I believe in looking reality straight in the eye and denying it.

I was the best man at the wedding. If I'm the best man, why is she marrying him?

Great People like us work on the principle of rockets, Not that we aim for the skies but we dont start performing unless ur ass is on fire

Why do couples hold hands during their wedding? It's a formality just like two boxers shaking hands before the fight begins!

REASONS behind the REASONS are the REASONS due to REASONS.

Chuck Norris can parse HTML with regex.

Linux: the operating system with a CLUE... Command Line User Environment.

Reducing the number of atheists in India since 1989 - Sachin Tendulkar!

People who don't like their beliefs being laughed at shouldn't have such funny beliefs in the first place!

I am not HANDSOME guy, but i can give my HAND to SOME guy who needs my help - ABDUL KALAM.

Prediction is very difficult, especially about the future.

To kiss a miss is strategy and miss a kiss is tragedy.

Surely it’s no coincidence that the word "listen" is an anagram of the word "silent".

I was depressed last night so I called Lifeline. Got a call centre in Pakistan. Told them I felt suicidal. They got all excited and asked if I could drive a truck.

There are two types of people , those who divide people into two types, and those who don’t.

This thing, is thing, a thing, good thing, way thing, to thing, keep thing, an thing, idiot thing, busy thing, for thing, 20 thing, seconds thing! … Now read without
the word thing.

Both pessimist and optimist contributed to world. Optimist invented aero plane and pessimist , the parachute.

People are made to be Loved & Things are made to be Used. The confusion in the World is, People are being Used & Things are being Loved.

I want to change the world but God won't give me the Source Code ... :(

If you are not living life on the edge.. You are taking too much space.


You can also view some interesting quotes here.

Some useful settings and plugins for VI Editor : Part 5 - Comment a code block

In the part 5 of this series, I am going to explain how to Comment/Uncomment a code block in VIM editor.

Method 1

Add folowing lines in your ~/.vimrc file

func! PhpUnComment() range
    let l:paste = &g:paste
    let &g:paste = 0

    let l:line        = a:firstline
    let l:endline     = a:lastline

    while l:line <= l:endline
        if getline (l:line) =~ '^\s*\/\/.*$'
            let l:newline = substitute (getline (l:line), '^\(\s*\)\/\/ \(.*\).*$', '\1\2', '')
        else
            let l:newline = substitute (getline (l:line), '^\(\s*\)\(.*\)$', '\1// \2', '')
        endif
        call setline (l:line, l:newline)
        let l:line = l:line + 1
    endwhile

    let &g:paste = l:paste
endfunc

vnoremap <buffer> <C-c> :call PhpUnComment()<CR>

Now In visual mode select the lines to comment/uncomment and press <CTRL-c>. This will comment all the uncommented lines, and uncomment all the commented lines.


Method 2

Using blockwise visual mode (CTRL-V) select the block to be commented.
Press I (capital i) and write the text you want to prepend to each line of the selected block (e.g. // or #). Then press ESC and the text will be inserted to the left of each line of the selected block.


For other posts related to VIM settings and plugins you can also visit

Some useful settings and plugins for VI Editor : Part 1 - General settings
Some useful settings and plugins for VI Editor : Part 2 - Autocompletion
Some useful settings and plugins for VI Editor : Part 3 - PHP documentor
Some useful settings and plugins for VI Editor : Part 4 - CodeSniffer Integration

Wednesday, February 2, 2011

Some good Quotes

Here are some of my favourite quotes, I collected them over a period of time, not in any particular order.

Not all chemicals are bad. Without chemicals such as hydrogen and oxygen, for example, there would be no way to make water, a vital ingredient in beer. -Dave Barry

Imagination was given to man to compensate him for what he is not; a sense of humor to console him for what he is. -Francis Bacon

It takes a lot of experience for a girl to kiss like a beginner. -Ladies Home Journal

Seven days without laughter make one weak. - Joel Goodman

Give a man a fish and he will eat for a day. Teach a man to fish and he will sit in a boat all day drinking beer.

If raising children was going to be easy, it never would have started with something called labour!

Women will never be equal to men until they can walk down the street with a bald head and a beer gut, and still think they are sexy.

10 Terrorists came by Boat, 539 terrorists will come by your vote, vote Carefully

You shouldn't say it is not good. You should say, you do not like it; and then, you know, you're perfectly safe.

Always and never are two words you should always remember never to use.

Children: You spend the first 2 years of their life teaching them to walk and talk. Then you spend the next 16 years telling them to sit down and shut-up.

The main purpose of holding children's parties is to remind yourself that there are children more awful than your own.

I learned law so well, the day I graduated I sued the college, won the case, and got my tuition back.  ~Fred Allen

We judge others by their behavior. We judge ourselves by our intentions.

If we were meant to talk more & listen less, we’d have two mouths & one ear.

The problem is never how to get new, innovative thoughts into your mind but how to get the old ones out.

People ask you for criticism but they only want praise.

Brains are like mouths; when empty they blather, when full they digest. - Pete Harrison

If you make people think they're thinking, they'll love you, but if you really make them think, they'll hate you.

Common sense is the most widely shared commodity in the world, for every man is convinced that he is well supplied with it. - Rene Decartes

Learn from the mistakes of others. You can't live long enough to make them all yourself. -

Being successful is like being pregnant , everyone congratulates you but no one knows how much you got screwed to get there.

A clever person solves a problem. A wise person avoids it. ~ Einstein

God gives and forgives. Man get and forgets.

Men are like bank accounts. Without a lot of money they don't generate a lot of interest.

Good judgment comes from bad experience and a lot of that comes from bad judgment.

The severity of the itch is inversely proportional to the ability to reach it.

Time is what keeps everything from happening at once.

Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why.

To err is human. To keep erring is inhuman.

Inside every large program, there is a small program trying to get out.

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

There are two ways to write error-free programs; only the third works.

If debugging is the process of removing bugs, then programming must be the process of putting them in.

If a million monkeys were typing on computers, one of them will eventually write a Java program. The rest of them will write Perl programs.

The key to understanding recursion is to begin by understanding recursion. The rest is easy.

In software, the chain isn't as strong as its weakest link; it's as weak as all the weak links multiplied together.

I'm so poor that I can't afford to pay attention.

There are two rules for success: 1.) Don't tell all you know.

Art is work, to sell it is art.

God made man before woman to give him time to think of an answer for her first question.

A fine is a tax for doing wrong. A tax is a fine for doing well.

All desirable things in life are either-- illegal, banned, expensive or married to someone else!

Bad is never good until worse happens.

It is the woman who chooses the man who will choose her.

Time you enjoy wasting, is not wasted.

I find television very educational. Every time someone switches it on I go into another room and read a good book.

Intelligence is like underwear, everyone has it but you don't have to show it off.

The politicians divide the country by Words, while the terrorists unite it with bullets!!!
       
Radar spelled backwards is radar. They get you coming and going.

When you ASSUME, it makes an ASS out of U and ME.

The closest to perfection a person ever comes is when he fills out a job application.

API design is like sex: make one mistake and support if for the rest of your life.

You can also view some interesting Gtalk status messages here.

Some useful settings and plugins for VI Editor : Part 4 - CodeSniffer Integration

In this part 4 of this series, I am going to discuss CodeSniffer and its integration with VIM editor.

What is CodeSniffer

CodeSniffer is a code analysis tool. This tool allows you to check your php code against a coding standard. It allows you to apply a set of rules (standard) to your source code. These rules can be used to detect common programming errors. It can also be used to define a set of coding standards for your project.

A coding standard in CodeSniffer is a collection of sniff files. Each sniff file checks one part of the coding standard only. CodeSniffer comes with a set of coding standards already defined. These are:

  • MySource
  • PEAR
  • PHPCS
  • Squiz
  • Zend

The default coding standard used by CodeSniffer is the PEAR coding standard. By integrating CodeSniffer into vim you can get the list of violations in a separate error window.

How to install CodeSniffer

You can install CodeSniffer using pear.

$ sudo pear install PHP_CodeSniffer

This will download and install the CodeSniffer from the PEAR repository.

How to run CodeSniffer

To run CodeSniffer execute

$ phpcs --standard=<standard> <path to file or directory>

The output will be a list of errors and warnings in your code as per your coding standard. 

CodeSniffer Integration with VIM editor

Add folowing lines in your ~/.vimrc file

function! RunPhpcs()
    let l:filename=@%
    let l:phpcs_output=system('phpcs --report=full --standard=PEAR '.l:filename)
    let l:phpcs_list=split(l:phpcs_output, "\n")
    unlet l:phpcs_list[0]
    cexpr l:phpcs_list
    cwindow
endfunction

set errorformat+=\"%f\"\\,%l\\,%c\\,%t%*[a-zA-Z]\\,\"%m\"
command! Phpcs execute RunPhpcs()

Now you can run CodeSniffer for the current file using command

:Phpcs

After that run

:cope

This will open a window with a list of all the errors and warnings in your code as per your coding standard. Alternatively you can use quickfix also to navigate through the error window. For that see help quickfix in the vim help.


For other posts related to VIM settings and plugins you can also visit

Some useful settings and plugins for VI Editor : Part 1 - General settings
Some useful settings and plugins for VI Editor : Part 2 - Autocompletion
Some useful settings and plugins for VI Editor : Part 3 - PHP documentor
Some useful settings and plugins for VI Editor : Part 5 - Comment a code block

Tuesday, February 1, 2011

Some useful settings and plugins for VI Editor : Part 3 - PHP documentor

In the part 1 and part 2 I talked about some useful vim settings and how to enable autocompletion in vim. In this part I am going to talk about a very useful plugin written by Tobias Schlitt, for generating comment blocks or docblocks for php scripts.

We do document our code with proper inline comments. To make this task easier, Tobias Schlitt wrote a VIM plugin which automatically lookup some characteristics of the item you want to document and creates a docblock skeleton for it. This plugin provides functions to generate documentation blocks for your PHP code. The script currently documents:

- Classes
- Methods/Functions
- Attributes

This plugin supports PHP 4 and 5 syntax elements. It also allows you to define default values for phpDocumentor tags like @version, @author, @license and so on. For function/method parameters and attributes, the script tries to guess the type as good as possible from PHP5 type hints or default values (array, bool, int, string etc).

Steps to install this plugin

  • Download the plugin file (php-doc.vim) from here.
  • After downloading just place the php-doc.vim file in ~/.vim/plugin/ folder
  • Add folowing lines in your ~/.vimrc file

        source ~/.vim/plugin/php-doc.vim
        inoremap <c-p> <esc>:call PhpDocSingle()<cr>i
        nnoremap <c-p> :call PhpDocSingle()<cr>
        vnoremap <c-p> :call PhpDocRange()<cr>

This includes the script and maps the combination <ctrl> + p to the doc functions.

How to use

Just hit <ctrl>+p on the line where the element to document resides and the doc block will be created directly above that line.

For other posts related to VIM settings and plugins you can also visit

Some useful settings and plugins for VI Editor : Part 1 - General settings
Some useful settings and plugins for VI Editor : Part 2 - Autocompletion
Some useful settings and plugins for VI Editor : Part 4 - CodeSniffer Integration
Some useful settings and plugins for VI Editor : Part 5 - Comment a code block

Some useful settings and plugins for VI Editor : Part 2 - Autocompletion

In the first part I talked about some useful settings, In this part I am going to explain how to use Autocompletion with VI editor.

To set autocompletion on, add the following settings in .vimrc file in your home directory or alternatively you can add them to /etc/vim/vimrc file, that will enable these settings for all users on the system.
   
set ofu=syntaxcomplete

Vim has autocomplete functionality for all common web development contexts. Now, If you are editing a file in vim which ends with .php, .html, .css, .js, .sql, .rb, or .py. Vim's "omnifunc" feature combined with its built-in autocomplete feature will show autocomplete options specific to the corresponding language. You can type a few words/chars and can press (in insert mode) following commands to autocomplete words from different context, vim shows a box below the cursor containing the options, with the first entry highlighted:

CTRL-X_CTRL-O - To search matching words in coding language manual
CTRL-X_CTRL-L - To search matching words in whole lines
CTRL-X_CTRL-N - To search matching words in the current file
CTRL-X_CTRL-K - To search matching words in dictionary
CTRL-X_CTRL-I - To search matching words in the current and included files
CTRL-X_CTRL-F - To search matching words in file names
CTRL-X_CTRL-] - To search matching words in tags
CTRL-N        - To search matching words in all of above

Autocompletion using the TAB key

Using above commands are little difficult. For easy use we can remap them to TAB key. Add the following function to your vimrc file. This function determines, wether we are on the start of the line text (then tab indents) or if we want to try autocompletion

func! InsertTabWrapper()
    let col = col('.') - 1
    if !col || getline('.')[col - 1] !~ '\k'
        return "\<tab>"
    else
        return "\<c-p>"
    endif
endfunction

Remap the TAB key to select action with InsertTabWrapper, add the following line in vimrc file

inoremap <buffer> <tab> <c-r>=InsertTabWrapper()<cr>

Now, when you will press a TAB key, it will check wheather you are on the start of a line, if yes it will indent your code, otherwise it will try to show you autocompletion window.


For other posts related to VIM settings and plugins you can also visit

Some useful settings and plugins for VI Editor : Part 1 - General settings
Some useful settings and plugins for VI Editor : Part 3 - PHP documentor
Some useful settings and plugins for VI Editor : Part 4 - CodeSniffer Integration
Some useful settings and plugins for VI Editor : Part 5 - Comment a code block