Vim as a PHP IDE - the complete guide

Last update: 2018-02-23 vim-logo

Vim, an IDE?

I can see you spitting your cereals in front of you computer. "What? A PHP IDE with Vim? Are you insane?"

Am I? It's definitely possible to make a very powerful IDE with Vim, thanks to my ex-colleague kushellig who initiated me to this dark knowledge.

The list of plugins I propose here will cover most of your needs: project management, autocompletion, PHPDoc generation, powerful search and replace tools, debugger... all these features will be at your fingertips, for free!

This configuration won't block Vim to work perfectly with other plugins for different languages as well.

Unlike many articles on the net, I tried to list and describe all the plugins which are necessary for a good PHP IDE.
Of course you need to read the documentation of each plugins to configure them as you wish. That's one of the multiple reason Vim is so great: you can make your own IDE which suits perfectly your needs and preferences!

If you need some concrete configuration examples you can have a look at my general vim configuration.
You can as well look at my configurations for some specific plugins.

Finally you can let a comment if you have difficulties configuring these plugins. I would be happy to help you as much as I can.

Disclaimer

I use those plugins with Neovim on Arch Linux, which means that I have no clue if they work on MacOs or Windows. It should, but be aware I never tested it.

Since I use Neovim, you may have some minor issues if you use Vim instead.

Neovim and Vim are almost the same software in practice, that's why I refer to them in this article under the global name Vim.

Plugins

I try here to highlight every strength of every plugin I use. If you just want a plain boring list, you can directly go to the plugin reference list at the end of the article.

Plugin manager

First of all you need a plugin manager. This plugin is the mother-of-all-plugin: it will help you install new plugins, delete or update them via simple command lines.

vim-plug is all you need to manage your Vim's plugins.
You only need to install it and put this configuration on top of your vimrc:

call plug#begin('~/nvim/plugged')  
Plug 'tpope/vim-fugitive'  
call plug#end()  

The line Plug 'tpope/vim-fugitive' is an example of plugin you can install. The keyword Plug need to be followed by any plugin's github repository.

You need to declare your plugins between the lines call plug#begin and call plug#end.

Simple as that!

Generating Ctags

This tag file is an index which can be set for a lot of OOP languages, including PHP.

Creating a tag file for each of your projects is heavily recommended:

  1. You will be able to go to method and class definitions easily (using ctrl + ] by default)
  2. Some plugins in this list need to have a tag file to work

There are two solutions in order to generating this file: Universal ctags or Gutentags. I personally prefer the first one but you can of course test both.

1 - Universal ctags

For this first approach to generate a tag file you need to use git for your PHP projects (and I secretly hope you do!).

First you need to install universal-ctags in order to generate this tag file.

If it's not available in your package manager, you will need to compile it. Execute those command lines and you will download and compile universal-ctags in the current directory. A little suggestion: it's good practice to keep all your compiled software at one place (I personally have them in the folder ~/bin):

git clone git@github.com:universal-ctags/ctags.git  
cd ctags  
./autogen.sh
./configure
make  
sudo make install  

Then you need to add a git hook to automatically generate this tag file. Create a ctags file in the directory .git/hooks/ of your PHP project with the following content:

#!/bin/sh
set -e  
PATH="/usr/local/bin:$PATH"  
dir="`git rev-parse --git-dir`"  
trap 'rm -f "$dir/$$.tags"' EXIT  
ctags --tag-relative=yes -R -f "$dir/$$.tags" --fields=+aimlS --languages=php --PHP-kinds=+cdfint-av --exclude=composer.phar --exclude=*Test.php --exclude=*phpunit* --exclude="\.git"  
mv "$dir/$$.tags" "$dir/tags"  

Now you need to change the permissions of the file:
sudo chmod 777 ctags

Finally you need to add the following line in your vimrc. It will generate the tags each time you save a PHP file.
au BufWritePost *.php silent! !eval '[ -f ".git/hooks/ctags" ] && .git/hooks/ctags' &

You can test if it works by opening any PHP file in your project and save it. Normally a tags file should appear in the .git directory of your project. This is what we need!

2 - Gutentags

This second approach is more straightforward: all you need is to install gutentags plugin, configure it as you wish and you are ready to go!

Essentials plugins

The plugins of this section are simply the-best-and-must-have-plugins-of-the-death. They improve Vim... a lot! They are not specifically for PHP development but they will bring some great functionalities major IDEs have by default.

Vim comes with a very simple file browser which is... not enough.
If you want a more sophisticated file tree in your editor, this one is very powerful.

Yankring.vim is very good to navigate easily into Vim's registers. The keystrokes ctrl p and ctrl n will become your best friends.

This plugin allow you to close a buffer without closing your window. I use it all the time, it's great not to mess up your window layout and keep the possibility to close files.

lightline.vim is a good status bar to have current file and status information you need at all time. You don't remember in what mode you are in? What file you currently modify? What the encoding of the file? This status bar will give you those information.

Tim Pope is a very prolific contributor in the Vim world. All his plugins are worse trying. Vim-commentary will comment every line selected via a simple keystroke. It works perfectly with many languages (PHP, JavaScript, Go...).

One of the Vim's feature I use the most is the substitution. It allows you to simply substitute one string with another in the current file.

This plugin makes the substitution functionality smarter. For example it allows you to keep the plural of the words you substitute or the uppercase letters. It can even replace camelCase by snake_case by dot.case...

A very nice addition to Vim.

Project management plugins

It is so natural nowadays to have disparate code files organized into a project in a lot of IDE / editors. It feels so natural we don't thing how handy it is anymore.

You can achieve the same thing in Vim by combining two plugins.

With vim-project you will be able to overwrite any vim config for one single project! Like many IDE, it allows you to have a totally personalized configuration depending on the project currently open.

This plugin provide as well a startup page to Vim and let you choose the project you want to open. Unfortunately, this startup page seems not to work on Neovim.

That's why I use vim-project with vim-startify.

Do you know Fortune? vim-startify will use it to display random development-related quotes each time you open Neovim. This may sound silly but it's great!

On this very same page startify will display as well every projects you have configured and let you choose the one you want to open.

Since I keep my project configuration files separated from my vimrc, here an example how you can configure a project with vim-project and vim-startify:

let g:startify_bookmarks = [  
            \ {'1': '~/workspace/mySuperProject/README.md'},
            \]

call project#rc("~/workspace")  
Project  'mySuperProject'  
Callback 'mySuperProject', ['Symfony', 'mySuperProject']

function! mySuperProject(...)  
    let g:vdebug_options["path_maps"] = {
    \       "/mySuperProject": "/home/mySuperUser/workspace/mySuperProject"
    \}
    PadawanStartServer
endfunction

function! Symfony(...)  
    let g:ultisnips_php_scalar_types = 1

    " standard phpcs config
    let g:neomake_php_phpcs_args_standard = 'PSR2'

    " php cs fixer 
    let g:php_cs_fixer_php_path = "php"

    autocmd FileType php nnoremap <leader>g :silent :call PhpCsFixerFixFile()<CR>
endfunction

I defined some special configuration in the functions Symfony and mySuperProject I can then attach to the project mySuperProject via the Callback line.

This configuration use plugins I describe below.

Syntax plugins

Those plugins are very specific for PHP development.

A simple plugin which will improve the syntax highlighting for PHP. Like a lot of plugins in this article, it is highly configurable.

This one will automatically format your code whenever you want (via a keystroke or each time you save a PHP file for example). By default it will format your code followingPSR1 / PSR2 rules but you can as well configure your own.

Autocompletion plugins

I was very afraid to quit IntelliJ (PhpStorm's indexation engine which allows a very nice autocompletion) when I began to fully use Vim. At the end I didn't miss it one second... thanks to the following plugins!

This auto-completion engine is mandatory if you want any auto-completion for any languages.
For Vim users, your should take a look at Shougo/neocomplete.vim.

However this alone is not enough: you will need some other plugin for the specific PHP autocompletion:

phpactor is a must have to me. It can do a lot of stuff (see the Refactoring / code styling plugins section). The autocompletion it provides is very good and pretty stable.

The plugin ncm-phpactor is meant to link phpactor to nvim-completion-manager.

This plugin can insert automatically "use" statements. It will use your tag file to get the good namespace.

You need to type the name of one of your class, hit a keystroke on it and voila! If multiple classes have the same name in different namespaces, you can choose the good namespace you want to insert from a list.

Searching / replacing plugins

What about search and replace in a file or even in an entire project? Can Vim do that as well?

Of course it can, and it does it very well. Those plugins are way more faster and powerful than anything I've ever tested.

Simply put: fzf is the best fuzzy searcher you will ever find. Written in Go, it can search everything in any files at light speed. To be honest, my switch from PhpStorm to Vim was in part because of this plugin!
It is that good.

The first plugin of this list will install the fuzzy searcher itself: you can use it in the terminal for searching... whatever you want. Searching through your command line history (for example) is a major feature I couldn't live without.

The second plugin will enable fzf in Vim. Then you can configure some keystroke to search through your file history, your buffer or to search a file in your project...

Ripgrep is not a Vim plugin but can be combined with fzf to search occurrences into multiple files. Very powerful and again incredibly fast.

You need to install ripgrep on your machine (for those who use Arch linux you simply have to type pacman -S ripgrep) and write a bit of configuration in your vimrc.

For example:

nnoremap <leader>a :Rg<space>  
nnoremap <leader>A :exec "Rg ".expand("<cword>")<cr>

autocmd VimEnter * command! -nargs=* Rg  
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --fixed-strings --ignore-case --no-ignore --hidden --follow --glob "!.git/*" --color "always" '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)

When you enter the keystroke <leader> a and type something in the command line prompt, ripgrep will search this something through all the files of your project.

Then you can fine tune your search in the search window thanks to fzf.
You can even have a preview of the file highlighted in the search by typing ?.

Last but not least, here a plugin using Ripgrep in order to search occurrences in multiple files. Exactly like ripgrep combined with fzf (see above) with one difference: you can rename occurrences in multiple files, using the famous vim substitution on the files you selected for one precise occurrence.

Say you need to rename a variable through a bunch of files? This plugin can do that for you very easily. Moreover it gives you full control of what you are modifying.

I had a lot of problems with PhpStorm batch renaming, specially because it has tendency to replace stuff I don't want to replace.
I never had one problem with this plugin.

Quality tools plugins

With those plugins you can output errors and advice to improve your code quality significantly.

Do you make mistakes when you write your code?
If the answer is no, please let's get in touch. I would love to know how you do it...
In short, you need this plugin (or another similar one).

Neomake will populate the gutter on the left (near the line numbers) and the window's location list for anything wrong in your code, thanks to warning makers.

You can install on your system three of those warning makers for PHP which will work with Neomake:

Those three markers can give you precious advice and alerts. With them I can really focus on code quality.

Neomake display as well any PHP syntax errors.

Refactoring / code styling plugins

Having some tools for refactoring and correctly formatting your code will save you a lot of time.

Via simple keystrokes you can (obviously) configure, this plugin can:

  • Rename local variables, methods, class properties
  • Create getters and setters or class properties
  • Extract use statement, constants, class properties

This list is not exhaustive. A very well done plugin easy to configure.

This one can automatically format your code following whatever convention you want, including PSR-1 and PSR-2. Very convenient!

This plugin do some very useful things like:

  • Moving a class in your project tree and update all its references (!)
  • Automatically create properties from constructor arguments
  • Extract method
  • Extract constant
  • ... and much more

A beast.

Git plugins

Who doesn't use git nowadays? If you prefer using SVN, this is a lie. Try git and never look back.

Vim-fugitive is a must have. You can do a lot with it (git blame or displaying a diff on a specific file...). Highly recommended.

Vim signify is very useful as well: it shows you what lines were modified / added / deleted by displaying little signs in the left gutter.

Snippets plugins

What would I do without snippets? It is very convenient in order to speed up your code typing. Do you want to create a private method by only typing pri followed by a keystroke? I'm sure you do.

Ultisnips will provide you a very good and fast snippet engine working with every languages you want.

Vim-snippets is a very good set of snippets for a lot of languages, including PHP or course.

The best part: it is very easy to extend with your own snippets!

Outline plugins

An outline plugin display a list of every methods and properties of a class in a separate window. You can then select them to jump to their definition in the source file itself.

This is the best outline plugin you will find. I personally don't use it often (and I constantly forget about it) but it can be handy in some occasions.

Debugger plugin

If you need a good debugger working with many languages, vdebug is the best you can find. It can be slightly tedious to configure but it is very powerful. For PHP you need to have xdebug properly configured to use it.

For Docker users (or if you use any virtual machine like Vagrant) you need to specify the path of your project as follow:

let g:vdebug_options["path_maps"] = {  
    \       "/mySuperProject": "/home/mySuperUser/workspace/mySuperProject"
    \}

The path on the left is the one on your virtual machine / Docker, the one on the right is your local path.

PHPDoc plugins

It's very convenient to be able to generate PHPDoc via a simple keystroke. It's exactly what do those plugins!

These plugins will create automatically some useful PHPDoc with argument variables (but not returns). You will most of the time need to complete the information but it's a good start.

In a nutshell: Vim better than PhpStorm?

I don't like to go in this kind of comparison: PhpStorm is an IDE which has much more features. To me, it has too many, I hate having one million windows and pop up which disturb my thinking and my flow.

The command line is more versatile and powerful than a bunch of windows.

Vim is maybe not "better" than PhpStorm but I argue that Vim can definitely replace PhpStorm with the plugins listed in this article.

Moreover you have the flexibility of Vim configuration and you can extend it as you wish. PhpStorm doesn't really give you any configuration choices (at least only basic ones).

To me at least, Vim is indeed more interesting to use and more powerful than any other PHP IDE I've ever tried!

If you have any problems or question while setting up your own Vim, please let me know in the comments.


Quick reference