Building Flutter Application with NeoVim
Introduction
You are here to gain productivity and discover a new way to build a Flutter Application, with NeoVim. In this article, we will cover all you need to know about NeoVim for Flutter developers, and start using it daily.
I've been using NeoVim for a couple of months and can already say it was the best decision. It's fun to use, fun to customize, and fast.
I have been using VSCode for 5 years now, before SublimText and before that emacs and vim during my first year at 42 school. I decided to switch to NeoVim because of an injury I had with my hand, and because of that, I could not use a mouse for a very long period. Thanks to a friend who told me about NeoVim, it was really fun to learn every day, and I still use it after my recovery. Anyway, if you have never used Vim in the past, I will explain what's important to know to start coding with it.
Some Vim history (vi -> vim -> neovim)
I talk about Neovim, vim, etc... but why are they different? It's because Vim was a history, back in the day developers had no mouse, so IDE was only usable with keyboards. So Neovim comes from Vim and Vim comes from Vi. NeoVim is a fork of Vim that adds many capabilities to the IDE. But we still get the essence of Vim. We can still use motion, and keybindings at the same, etc... NeoVim comes with LSP, something important when using Flutter for example. If you want to know more about history go on the official website neovim.
In this article, if I use the term NeoVim, understand that is kinda the same as Vim but with more capabilities.
The basic command for Vim
See https://vim.rtorr.com/ for many examples of vim command and motion.
Install NeoVim
Go to the install documentation to install Neovim on your OS:
Then you can use the command nvim
to open Neovim. For example in a flutter folder just use nvim .
it to open all the files in the folder.
How to leave neovim ?!
Don't worry just use the command like vim::q
How to install a plugin, package manager
NeoVim comes with multiple ways to handle packages, you have many package managers available like vim-plug
,dein
, packer.nvim
or lazy.nvim
. In this article, we will use it only lazy.nvim
to install some packages.
For example, later in this article, we will see how to install Flutter, and we will use a package to do that. To start we will install basic "getting started" packages and we will see later in this article each important package to know. Keep in mind you can fork, and modify your config for NeoVim and it's really important to try it yourself. See my config if you want to install everything you need to go for Flutter/Dart development.
Explaining tree with neotree
Before starting coding, we will install some tools to handle tree navigation. In vscode we have a file tree, in NeoVim we can "reproduce" this. A nice package to do so will be neotree. In the documentation, you will find everything to install it. You still can find my config for this package here.
As you can see each package has its key bind. Keybinds are important with Neovim, we will use everything with keys. And we can still customize it. For example in the config of the package you can see:
vim.keymap.set('n', '<leader>tt', '<Cmd>Neotree toggle<CR>', { desc = "Neo[T]ree [T]oggle" })
vim.keymap.set('n', '<leader>tr', '<Cmd>Neotree reveal<CR>', { desc = "Neo[T]ree [R]eveal" })
vim.keymap.set('n', '<leader>ts', '<Cmd>Neotree git_status<CR>', { desc = "Neo[T]ree git [S]tatus" })
With vim.keymap.set
method in Lua we can bind anything we want. Here I bind the "tt" to toggle (open) Neotree. And I made a little description of the bind. It's useful when you start learning the binding. For example now if I press "space". We can see Neovim open a window to indicate what we can do now:
If we press "t" (here a prefix) we see multiple choices.
And we see the documentation we wrote before. The same approach will apply to every binding we make.
Here we use the "OUR COMMAND", to bind a key to a command. "<\Cmd" we enter command mode (see ':h command-line') then the command here it's "Neotree toggle" (see :h :Neotree
). You can bind many commands like that for your purpose.
Telescope
Telescope is a plugin to add more capabilities for NeoVim, for example, searching for a specific file in your current directory (project). Or search a world in all files. For example, take a look at these two examples of keybindings I use every day:
vim.keymap.set('n', '<leader>sf', require('telescope.builtin').find_files, { desc = '[S]earch [F]iles' })
vim.keymap.set('n', '<leader>sg', require('telescope.builtin').live_grep, { desc = '[S]earch by [G]rep' })
The first one will search for all files in your current directory then open it. And the second one is for grep something in all files. For more see :h telescope
.
All the configs for telescope can be found in my custom nvim config.
LSP for Language Server Protocol
LSP for Language Server Protocol is a protocol of communication for IDEs to use some specific features of a language like code completion, refactoring tools, etc... For Flutter we will see it's useful for example when we have to use code actions or other tools. We will see that later in the article. But keep in mind LSP is used for many things we use daily as developers.
Subscribe to Etienne Théodore
lua language
As we see in examples before, lua is a language used to config neovim. It's a powerful language to make interfaces like add-ons in video games or here config for Neovim. Take a look at this documentation to learn more about it::h lua-guide
Or:
flutter-tools.nvim
This is the main package we will use to work with Flutter. When you have installed it via lazy installer here in my config.
Like always you can see all commands via::h flutter-tools-usage
But I have to bind something to open the tools command via:
vim.keymap.set('n', '<leader>r', require('telescope').extensions.flutter.commands, { desc = 'Open command Flutter' })
This will open a buffer like this:
So now you can select Run to run your app, and it will "attach" it to your code, so hot reload will work on saved files.
One keybinding I love is:<space>ca
on a widget tree to open code action as we use to it in vscode
Or:<space>gr
to open telescope to see all references of methods for examples, and you can use <CTRL>q
to open the result in a different buffer and "save" the search.
All useful keybindings will be covered at the end of the article.
Building your init.lua (powerful customization)
Like me, you can create your own init.lua
to config all your neovim experience for you. Fork this repo and make your change! Add more packages, create your custom keybindings, and more:
Keybindings
Every key has its documentation for example f
you can type :h f
to see the documentation associated. Don't hesitate to take your time for each keybinding.
All keybindings I use a lot every day:
Motions (normal mode):<Ctr>d
Scroll down in a file<Ctr>u
Scroll up in a filej
one line downk
one line uph
one character leftl
one character rightzz
center the buffer to the center of the screene
one word right and cursor finish on each last character of the wordb
one word left and cursor finish on the first character of the wordf{char}
example ft
find the next t
occurrence on the current line, really useful to go on the letter you want?{pattern}
Search in the current file pattern, if you want to search for multiple occurrences use this command press enter then tap n
for the next occurrence of N
for the previous one.<space>?
same result but this time using telescope
Insert:i
will change your mode to insert mode in the current cursora
same to i
but insert just after the cursor something I use a lot with e
motion.o
Begin a new line below the cursor and insert the textciw
change the inside word, remove the current word below your cursor, and pass to insert mode.
Bindings I love:K
on a Class of method etc.. in your code to see the documentation.<space>sf
Search for a file<space>sg
grep something in files<space><space>
looking for opened buffers<space>tt
Toggle tree file<space>d
delete current buffer<space>gr
open telescope with all the references of the current cursorkj
something I use the most, I bind the <ESC>
on this, so I can leave insert mode faster with my right hand see the bind:
vim.api.nvim_set_keymap('i', 'kj', '<ESC>', { noremap = true })
.
Useful to copy the previous command.
Flutter:<space>r
open Flutter tools command<space>ca
open code action
For more tips on vim take a look at this book (affiliate link to support my work):
I was reading this book, and keep close to me when I use nvim. Always a tip to progress on motion/insert and comprehension of vim.
If you want more articles on neovim subscribe to my blogs via: