linu.us Logo
Linus Benkner

NeoVim Setup for PHP and NodeJS Development

NeoVim Setup for PHP and NodeJS Development

How I sped up my development with NeoVim for WordPress, React, SvelteKit, and more

Hi everyone! šŸ‘‹

Itā€™s been a while since my last post, and today I want to show you how I sped up my development in the last weeks.

Until recently, Iā€™ve been a big fan of Visual Studio Code and it was my primary editor for the last years. Over time, I learned more and more key bindings, started to really use the command palette and started to not do everything with the mouse - and guess what, it felt a lot faster than doing everything with the mouse.

Now, I still love VS Code, can really recommend it and I use it for example in the browser on GitHub. But since I tried Vim, Iā€™m now using this as my primary editor.

Please note, Iā€™m by far no (Neo)Vim expert and still learning it. In this article, I want to share my story about how I got into (Neo)Vim and what my setup looks like.

Why Vim?

When I first heard about Vim, I was like ā€œwhy in the world would you use Vim when there is VS Code and all the other modern IDEā€™s?ā€œ. The only thing I knew about Vim at this time was how to exit Vim. But after a deeper look at Vim and some great input from a co-worker, I decided to at least try it for some time.

Here are the main reasons:


Advertisement

How I learned Vim

Quick answer: Learning by doing :)

I started to use only Vim for a few days, which forced me to learn Vim commands and key bindings. No VS Code or any other text editor - only Vim. At the beginning, I was really slow and constantly looking up how to do basic stuff.

But every day I got faster, learned new commands and improved my workflow. And until now, I didnā€™t go back to VS Code.

Thatā€™s my config for Vim:

set encoding=UTF-8
" Set encoding

set number
" Show line numbers by default

syntax on
" Enable syntax highlighting by default

filetype plugin indent on
" show existing tab with 4 spaces width
set tabstop=4
" when indenting with '>', use 4 spaces width
set shiftwidth=4
" On pressing tab, insert 4 spaces
set expandtab

" Tab / Shift Tab to switch between tabs (:tabe <file>)
nnoremap <Tab> :tabnext<CR>
nnoremap <S-Tab> :tabprevious<CR>

NeoVim

After using Vim for a few weeks, I now moved to NeoVim. I really like Vim now, but there are some VS Code features Iā€™d love to have in Vim. Thatā€™s why I decided to use NeoVim.

Thatā€™s how I wanted my NeoVim setup to look like:

You see, a pretty simple setup. So now letā€™s actually set it up:

Installation & Setup

1. Install NeoVim

Follow the instructions on the NeoVim installation page or use the following command:

macOS (with brew): brew install neovim

Windows (with winget): winget install NeoVim.NeoVim

2. Install VimPlug

To manage the plugins / extensions, I decided to use VimPlug as the plugin manager. Read the installation guide here or use the following command:

macOS / Linux:

sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
       https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

Windows (PowerShell):

iwr -useb https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim |`
    ni "$(@($env:XDG_DATA_HOME, $env:LOCALAPPDATA)[$null -eq $env:XDG_DATA_HOME])/nvim-data/site/autoload/plug.vim" -Force

3. NeoVim Config

Create the NeoVim config file ~/.config/nvim/init.vim and paste the following:

set encoding=UTF-8
set number
syntax on

" set tab to 4 spaces
filetype plugin indent on
set tabstop=4
set shiftwidth=4
set expandtab

" Tab / Shift Tab to navigate between tabs
nnoremap <Tab> :tabnext<CR>
nnoremap <S-Tab> :tabprevious<CR>

" CoC settings
set nobackup
set nowritebackup
set cmdheight=2
set updatetime=300
set shortmess+=c
if has("nvim-0.5.0") || has("patch-8.1.1564")
  set signcolumn=number
else
  set signcolumn=yes
endif
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ CheckBackspace() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! CheckBackspace() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
else
  inoremap <silent><expr> <c-@> coc#refresh()
endif
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
nnoremap <silent> K :call ShowDocumentation()<CR>
function! ShowDocumentation()
  if CocAction('hasProvider', 'hover')
    call CocActionAsync('doHover')
  else
    call feedkeys('K', 'in')
  endif
endfunction
autocmd CursorHold * silent call CocActionAsync('highlight')

" VimPlug plugin manager
call plug#begin()
Plug 'https://github.com/vim-airline/vim-airline'
Plug 'https://github.com/tpope/vim-commentary'
Plug 'https://github.com/ap/vim-css-color'
Plug 'https://github.com/rafi/awesome-vim-colorschemes'
Plug 'https://github.com/neoclide/coc.nvim'
Plug 'othree/html5.vim'
Plug 'pangloss/vim-javascript'
Plug 'evanleck/vim-svelte', {'branch': 'main'}
call plug#end()

" set the colorsheme
" list: https://github.com/rafi/awesome-vim-colorschemes
colorscheme minimalist

At the top, you can see some settings like the tab with, encoding and I also want syntax highlighting and line numbers enabled by default.

Next is a big config block for the CoC extension. I canā€™t really explain what all this is doing, I got this from the CoC installation & setup guide. Basically, it enables the autocompletion window and creates some hotkeys like K to show the documentation.

Below that, you can find the VimPlug section. Here are all the plugins registered:

4. Install Plugins

Because we changed the NeoVim config, restart NeoVim first. There may be some errors because the plugins arenā€™t installed yet. Use VimPlug to install the plugins specified in the config file:

:PlugInstall

5. Set Up CoC Extension

Once the plugins are installed, close NeoVim and navigate to the folder of the CoC extension:

macOS / Linux: ~/.local/share/nvim/plugged/coc.nvim/

Windows: ~/vimfiles/plugged/coc.nvim/

Now, install the dependencies and build the source code:

npm ci && npm run build

6. Extensions for the CoC Extension

You can now start NeoVim again and there shouldnā€™t be any errors. To complete the setup, letā€™s install some extensions for CoC, like a JS/TS language server and intelephense for PHP:

:CocInstall coc-tsserver coc-json coc-svelte @yaegassy/coc-intelephense

Hey šŸ‘‹ Don't want to miss new articles?

Drop your mail and I'll notify you if I have something new!

* indicates required

7. Optional: WordPress

Iā€™m working with WordPress themes and plugins, but with the current setup every WordPress function is marked as error because the intelephense extension doesnā€™t know Iā€™m inside a WordPress theme with all the WordPress functions available. We can change that by opening the CoC config (:CocConfig) and adding ā€œwordpressā€ to the list of intelephense.stubs. If you type ā€œintelephense.stubsā€, you can use the autocompletion by CoC to create the whole list and then only append ā€œwordpressā€ to the end of the list.

Full list:

{
    "intelephense.stubs": [
        "apache",
        "bcmath",
        "bz2",
        "calendar",
        "com_dotnet",
        "Core",
        "ctype",
        "curl",
        "date",
        "dba",
        "dom",
        "enchant",
        "exif",
        "FFI",
        "fileinfo",
        "filter",
        "fpm",
        "ftp",
        "gd",
        "gettext",
        "gmp",
        "hash",
        "iconv",
        "imap",
        "intl",
        "json",
        "ldap",
        "libxml",
        "mbstring",
        "meta",
        "mysqli",
        "oci8",
        "odbc",
        "openssl",
        "pcntl",
        "pcre",
        "PDO",
        "pdo_ibm",
        "pdo_mysql",
        "pdo_pgsql",
        "pdo_sqlite",
        "pgsql",
        "Phar",
        "posix",
        "pspell",
        "readline",
        "Reflection",
        "session",
        "shmop",
        "SimpleXML",
        "snmp",
        "soap",
        "sockets",
        "sodium",
        "SPL",
        "sqlite3",
        "standard",
        "superglobals",
        "sysvmsg",
        "sysvsem",
        "sysvshm",
        "tidy",
        "tokenizer",
        "xml",
        "xmlreader",
        "xmlrpc",
        "xmlwriter",
        "xsl",
        "Zend OPcache",
        "zip",
        "zlib",
        "wordpress"
    ]
}

And thatā€™s my current NeoVim setup. Maybe this will help some of you who want to get started with NeoVim.

Whatā€™s your favorite editor or IDE? Are you using Vim / NeoVim too? Let me know in the comments!

Thank you for reading, happy coding and have a great day! šŸ˜ŠšŸš€

More Articles

Create a WordPress Plugin from Scratch - Full Beginners Guide

Create a WordPress Plugin from Scratch - Full Beginners Guide

Linus Benkner
NeoVim Setup for PHP and NodeJS Development

NeoVim Setup for PHP and NodeJS Development

Linus Benkner
Deploy a SvelteKit-App to DigitalOcean

Deploy a SvelteKit-App to DigitalOcean

Linus Benkner
SQL: The basics and beyond

SQL: The basics and beyond

Linus Benkner
Do you find this content helpful?
Buy Me A Coffee