Setting up Vim for PHP and laravel in 2024

Setting up Vim for PHP and laravel in 2024

I am going to mostly document my own journy of setting up Vim (Not Neovim!) for PHP and laravel. Feel free to follow along.

We’re going to use Vim+VimPlug+CoC.nvim, so we need to have nodejs and npm installed. It goes without saying that you should have Vim8+ as well. The current version of Vim as of this writing is Vim-9.1

So let’s start from a clean ~/.vimrc

Lets place this block, that automatically installs VimPlug, on top of our ~/.vimrc.

function! VimplugInstaller()
let data_dir = has(‘nvim’) ? stdpath(‘data’) . ‘/site’ : ‘~/.vim’
if empty(glob(data_dir . ‘/autoload/plug.vim’))
silent execute ‘!curl -fLo ‘.data_dir.‘/autoload/plug.vim –create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim’
autocmd VimEnter * PlugInstall sync | source $MYVIMRC
endif
endfunction

call VimplugInstaller()

Followed by several essential plugins:

call plug#begin()

Plug ‘neoclide/coc.nvim’, {‘branch’: ‘release’}
Plug ‘https://github.com/preservim/tagbar.git’
Plug ‘vim-php/phpctags’, {‘for’:‘php’}
Plug ‘honza/vim-snippets’
Plug ‘SirVer/ultisnips’
Plug ‘tpope/vim-commentary’
Plug ‘sheerun/vim-polyglot’
Plug ‘jwalton512/vim-blade’

call plug#end()

The most important one, is coc.nvim. The rest are for various enhancements, that we’ll go over soon, but before we do, let’s define some extensions for coc.nvim and configure the other plugins.

“===[Coc.nvim]===”
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#_select_confirm() : “<C-g>u<CR>”
” use <tab> to trigger completion and navigate to the next complete item
function! CheckBackspace() abort
let col = col(‘.’) 1
return !col || getline(‘.’)[col 1] =~# ‘s’
endfunction

inoremap <silent><expr> <Tab>
coc#pum#visible() ? coc#pum#next(1) :
CheckBackspace() ? “<Tab>” :
coc#refresh()
inoremap <expr><stab> coc#pum#visible() ? coc#pum#prev(1) : “<c-h>”

” Enhanced <CR> for pairs
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
: “<C-g>u<CR><c-r>=coc#on_enter()<CR>”

” Disable < expansion for pairs
autocmd FileType * let b:coc_pairs_disabled = [“<“]

“===[ Coc-Explorer ]===”
” set up coc-explorer to open in the current directory
let g:coc_explorer_global_mirror = 0
let g:coc_explorer_disable_default_keybindings = 1
let g:coc_explorer_global_root = ‘current’
nnoremap <space>e <Cmd>CocCommand explorer<CR>

“===[ Coc Global Extensions ]===”
let g:coc_global_extensions = [
‘coc-html’,
‘coc-css’,
‘coc-pairs’,
‘coc-emmet’,
‘coc-explorer’,
‘coc-phpactor’,
‘coc-laravel’,
‘coc-blade’
]

” GoTo code navigation
nmap <silent> gd <Plug>(cocdefinition)
nmap <silent> gy <Plug>(coctypedefinition)
nmap <silent> gi <Plug>(cocimplementation)
nmap <silent> gr <Plug>(cocreferences)

” Use `[g` and `]g` to navigate diagnostics
” Use `:CocDiagnostics` to get all diagnostics of current buffer in location list
nmap <silent> [g <Plug>(cocdiagnosticprev)
nmap <silent> ]g <Plug>(cocdiagnosticnext)

” List code actions available for the current buffer
nmap <leader>ca <Plug>(coccodeaction)

nnoremap <silent> K :call ShowDocumentation()<CR>
function! ShowDocumentation()
if CocAction(‘hasProvider’, ‘hover’)
call CocActionAsync(‘doHover’)
else
call feedkeys(‘K’, ‘in’)
endif
endfunction

” Add `:Format` command to format current buffer
command! nargs=0 Format :call CocActionAsync(‘format’)
” Formatting selected code
vmap <leader>f <Plug>(cocformatselected)

” coc-pairs
” disable characters for a specified filetypes
autocmd FileType markdown let b:coc_pairs_disabled = [‘txt’]

The above code, configures tab completion, auto pairs, coc-explorer file explorer and other keybinding to get the most out of coc.nvim.
In the coc global extension section, we define extensions to be installed automatically. I have decided to use phpactor, you may change it for coc-intelephense.

Lets also configure the snippets:

We can manage our snippets with coc.nvim too, but I choose to use UltiSnips for that.

“===[ SNIPPETS ]===”
“Use Ctrl j key to trigger the snippets, default was TAB but that conflicts with
“The Completion trigger see :h keycodes to change this to sth else
“Use Ctrl j and k to move visually within the snippet that was just triggered
“Ctrl l lists the available snippets
let g:UltiSnipsExpandTrigger=‘<C-j>’
let g:UltiSnipsListSnippets=‘<C-l>’
let g:UltiSnipsJumpForwardTrigger=‘<C-j>’
let g:UltiSnipsJumpBackwardTrigger=‘<C-k>’
let g:copypath_copy_to_unnamed_register = 1

Save and quit Vim and open it again and wait for the plugins and extensions to install.

If you get prompted by an error msg, just press enter and wait for the plugins and the extensions to install.

Now lets configure the coc extensions.

Issue the :CocConfig command from Vim’s command mode and paste the following, inside the file.

{
“suggest.noselect”: true,
“explorer.icon.enableNerdfont”: true,
“explorer.file.reveal.auto”: true
“languageserver”: {
“phpactor”: {
“command”: “phpactor”,
“args”: [“language-server”],
“trace.server”: “verbose”,
“filetypes”: [“php”]
}
}
}

If you choose to use a local installation of phpactor, you can just remove coc-phpactor with :CocUninstall coc-phpactor and modify the ~/.vim/coc-settings.json to include a path to the phpactor executable and remove the languageserver block entirely.

{
“phpactor.enable”: true,
“phpactor.path”: “/usr/bin/phpactor”,
}

The keybindings:

The only keybindings that you should know, besides the usual Vim keybindings, are:

Key
Action

Tab
completion

gd
definition

gy
type definition

gi
implementation

gr
references

[g
diagnostics prev

]g
diagnostics next

ca
code actions

K
hover docs

f (in visual mode)
format code

Ctrl-j
Expand Snippet & Move to Next Placeholder

Ctrl+k
Move to Prev Placeholder

Ctrl-l
List Snippets

Space-e
Open Explorer

Now we should have an efficient and comfortable setup for working with PHP and laravel.

Lets setup several other things for convenience

Theme:

Add these plugins to the plugins list and install them with :PlugInstall after sourcing the ~/.vimrc.

Plug ‘ryanoasis/vim-devicons’
Plug ‘catppuccin/vim’, { ‘as’: ‘catppuccin’ }

Setup Vim to use the popular catppuccin theme.

“===[ Theme ]===”
set background=dark
” Inspect $TERM instead of t_Co
if &term =~ ‘256color’
” Enable true (24-bit) colors instead of (8-bit) 256 colors.
if has(‘termguicolors’)
let &t_8f = “<Esc>[38;2;%lu;%lu;%lum”
let &t_8b = “<Esc>[48;2;%lu;%lu;%lum”
let &t_TI = “”
let &t_TE = “”
set termguicolors
set mouse=a
colorscheme catppuccin_mocha
endif
else
colorscheme catppuccin_mocha
let &t_TI = “”
let &t_TE = “”
endif

if has(‘gui_running’)
set mouse=a
set guicursor+=a:blinkon0
set guifont=FiraCodeNerdFont 12
colorscheme catppuccin_mocha
endif

“===[ Curosr Shape ]===”
let &t_SI = “<Esc>[6 q”
let &t_SR = “<Esc>[4 q”
let &t_EI = “<Esc>[2 q”

The above block, will make vim use termgui colors (in a termgui capable terminal) and use different cursor shapes for different modes.
Make sure your $TERM variable reports xterm-256color.

In the screenshot below, you can see phpactor, coc-explorer and tagbar at work.
I’ve left an error in the syntax to show you what the inline diagnostics look like.

It would do you well to familiarize yourself with the coc.nvim documentation and commands.

For example, running :CocDiagnostics will open a drawer with all the errors found by coc.nvim.

Pressing enter on each item will jump you to the line containing the error.

I could not find a decent phpdoc plugin for Vim, but besides that, this setup is very effective. The only things that you can add to it are your prefered plugins for dealing with git and fuzzy finding.

You can find my full config on github, (probably in the Devel branch) Woland’s Vim

If you have any notes or questions, please leave a comment.

Possible Q&A

Can I use this with Nvim?
Yes, you just have to paste all the code into ~/.config/nvim/init.vim

Why not use Nvim with lspconfig and cmp etc … ?
Because it takes way longer to configure and the results aren’t better than what coc provides with so much ease.

Please follow and like us:
Pin Share