Boost your productivity with Symfony and Vim

Published on

Nov 29, 2011

knp

Nov 30, 2011 − In this article, we will walk through a series of vim tips we've been using here at KNP when hacking with Symfony. Please note that we will not show you how to setup vim for php or symfony, we assume you already know the vim's basics.

In this article, we will walk through a series of vim tips we've been using here at KNP when hacking with Symfony. Please note that we will not show you how to setup vim for php or symfony, we assume you already know the vim's basics.

We love Vim because it can be easily extended, and we are always eager to discover new tricks, so don't hesitate to share yours :)

Intelligent namespace and use statements insertion

Working on a Symfony project, you will find yourself creating a lot of new classes, each in a new file, of course. For each new class, you have to type the name of the file first, then write the namespace, and finally fill in the class. This is boring, right? Actually, this can be a lot easier if you let vim guess the namespace and class name from the filename. Obviously, there is more that one way to do this: here we will use a snippet, powered by the SnipMate plugin.

snippet class
<?php

namespace ${1:`substitute(substitute(expand("%:h"), 'v^w+/(u)', '1', ''), '/', '\', 'g')`};

class ${2:`Filename('', 'myClass')`}
{
    ${3}
}

With that snippet code, now you only type class at the beginning of your file, and you're done! Now, if you have a file like this:

%project_root%/src/Acme/Bundle/AcmeBundle/Controller/AcmeController.php

the namespace will be automatically generated as AcmeBundleAcmeBundleController;. Looking at the regex, you can see this works because src is not capitalized, and there is only one directory before the namespace.

This is cool and saves us some annoying typing. But what if we could automatically insert some use statements too? Well, this is possible thanks to the php namespace plugin! (you need ctags to use this plugin)

Autocompletion of routes and service names

Given Symfony's architecture, you can easily being to have a lot of routes and services that are located in many different places (bundles, app/config, DI extensions, ...).

Hopefully, some CLI tools like container:debug and router:debug help you to get a global view of all theses definitions.

The vim-symfony plugin uses this output to autocomplete route names and services ids,
thanks to a simple user-defined autocompletion.

Just use <C-x><C-u> keys to get an autocomplete list of current typed word. The result is pretty useful.

In a view (like a twig file), or anywhere else, you can use this to autocomplete a route name:

routing

The services id completion:

services

Jump from controller to template file

In Symfony you often write something like this in a controller:

return $this->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));

Why don't use vim's integrated file searching capability, and the awesome gf command to jump to the view file automatically? If you are used to starting vim from the root folder of your project you can benefit from the recursive downward search in all subdirectories by typing this: :set path+=**. And file searching is remarkably fast!

We can go a step further, and try to automate the series of commands you will have to type to really jump to that view (basically put the cursor above file name, and type 'gf'). This simple function in our .vimrc will do the job:

" first set path
set path+=**

" jump to a twig view in symfony
function! s:SfJumpToView()
    mark C
    normal! ]M
    let end = line(".")
    normal! [m
    try
        call search('v[^.:]+.html.twig', '', end)
        normal! gf
    catch
        normal! g`C
        echohl WarningMsg | echomsg "Template file not found" | echohl None
    endtry
endfunction
com! SfJumpToView call s:SfJumpToView()

" create a mapping only in a Controller file
autocmd BufEnter *Controller.php nmap <buffer><leader>v :SfJumpToView<CR>

Alternatively, you could use ctags with some extra configuration, typically by creating a tag entry for each file:

--extra=+f
--langdef=file
--langmap=file:.html.twig.xml.yml

Build your ctags and jump to any file using tag related commands. This is useful when several files have the same name in your project, because you can choose between them.

How to integrate phpcs with Syntastic

syntastic recently introduced phpcs integration in php checks.
It will now display every coding standard warning or error if phpcs is installed.

To make this work, you should have:

  • a vim with syntastic installed (obvioulsy)
  • a working phpcs
  • a default phpcs sniffers package (or not)

Typical steps are:

  • get a useful phpcs sniffs package like Symfony2
  • enable it by default using phpcs --config-set default_standard Symfony2
  • work

Now, each time you save a php file, vim will notify you about coding standard problems encoutered in the current file.

Launching unit tests and navigate into failures

Install the PHPUnit plugin.

Add a shortcut in your vimrc that will facilitate your life:

" phpunit compilation
com! -nargs=* Phpunit make -c app <q-args> | cw

You can now use :Phpunit % to test your current test file or :Phpunit <whatever path> to test whatever path. :Phpunit will launch all tests.

The cool thing with this is that it will put all failed assertions in your quickfix list:

phpunit

Written by

KNP Labs
KNP Labs

Comments