Minimal Neovim + Flutter Setup (macOS)
Isolated. Beautiful. Fast. No Vim conflict.
Enhanced Neovim Setup for Flutter Development on macOS
Enhanced Neovim Setup for Flutter Development on macOS
Minimal setup: Minimal Neovim + Flutter Setup (macOS)Isolated. Beautiful. Fast. No Vim conflict.Mediumdanial Fine, danial, here’s your shiny, fully-updated final article. I stitched your latest config into the write-up so the whole thing feels clean and intentional. Try not to break it five minutes after publishing. Enhanced Neovim

NVIM_APPNAME=nvim-flutter forces Neovim to load only from ~/.config/nvim-flutter/. Your ~/.vimrc, ~/.vim/, and default ~/.config/nvim/ stay completely untouched — no shared plugins, paths, or side effects. vim and nvim run as before; nvimf is a safe, isolated Flutter IDE.NVIM_APPNAME=nvim-flutter forces Neovim to load only from ~/.config/nvim-flutter/. Your ~/.vimrc, ~/.vim/, and default ~/.config/nvim/ stay completely untouched — no shared plugins, paths, or side effects. vim and nvim run as before; nvimf is a safe, isolated Flutter IDE.1. Install Neovim & Flutter
brew install neovim
brew install --cask flutter
2. Create Isolated Config
mkdir -p ~/.config/nvim-flutter
3. init.lua – Paste This (Clean & Final)
-- ~/.config/nvim-flutter/init.lua
vim.g.mapleader = " "
-- 1. Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git", "clone", "--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
lazypath
})
end
vim.opt.rtp:prepend(lazypath)
-- 2. Plugins
require("lazy").setup({
{ "neovim/nvim-lspconfig" },
{ "dart-lang/dart-vim-plugin" },
{ "nvim-treesitter/nvim-treesitter", build = ":TSUpdate" },
{ "hrsh7th/nvim-cmp" },
{ "hrsh7th/cmp-nvim-lsp" },
{ "hrsh7th/cmp-buffer" },
{ "hrsh7th/cmp-path" },
{ "akinsho/flutter-tools.nvim", dependencies = { "nvim-lua/plenary.nvim" } },
{ "nvim-lualine/lualine.nvim" },
{ "lewis6991/gitsigns.nvim" },
-- File Explorer + Icons
{
"nvim-tree/nvim-tree.lua",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
require("nvim-tree").setup {
view = { width = 35, side = "left" },
renderer = {
group_empty = true,
icons = {
glyphs = {
folder = {
arrow_closed = "▶",
arrow_open = "▼",
},
},
},
},
filters = { dotfiles = false },
git = { enable = true, ignore = false },
}
vim.api.nvim_create_autocmd("VimEnter", {
callback = function() vim.cmd("NvimTreeOpen") end
})
end,
},
{ "ryanoasis/vim-devicons" },
-- Colorscheme
{
"catppuccin/nvim",
name = "catppuccin",
priority = 1000,
config = function()
require("catppuccin").setup({
flavour = "macchiato",
integrations = {
nvimtree = true,
lsp = true,
cmp = true,
gitsigns = true,
treesitter = true,
},
})
vim.cmd.colorscheme "catppuccin"
end
},
-- Lspsaga
{
"glepnir/lspsaga.nvim",
event = "LspAttach",
config = function()
require("lspsaga").setup({
lightbulb = { enable = false },
symbol_in_winbar = { enable = false },
hover = { max_width = 0.6, max_height = 0.6, open_link = "gO" },
finder = { max_width = 0.6, max_height = 0.6 },
})
end,
},
})
-- 3. Basic settings
vim.opt.number = true
vim.opt.signcolumn = "yes"
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
-- 4. Treesitter
require("nvim-treesitter.configs").setup{
ensure_installed = { "dart", "lua", "vim" },
highlight = { enable = true },
}
-- 5. Completion
local cmp = require("cmp")
cmp.setup{
sources = {
{ name = "nvim_lsp" },
{ name = "buffer" },
{ name = "path" },
},
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
}
-- 6. Keymaps
vim.keymap.set("n", "<leader>fr", ":FlutterRun<CR>", { desc = "Flutter Run" })
vim.keymap.set("n", "<leader>fd", ":FlutterDevices<CR>", { desc = "Devices" })
vim.keymap.set("n", "<leader>fh", ":FlutterHotReload<CR>", { desc = "Hot Reload" })
vim.keymap.set("n", "<leader>fH", ":FlutterHotRestart<CR>", { desc = "Hot Restart" })
vim.keymap.set("n", "<leader>fq", ":FlutterQuit<CR>", { desc = "Quit" })
vim.keymap.set("n", "<leader>e", ":NvimTreeToggle<CR>", { desc = "Toggle Explorer" })
vim.keymap.set("n", "<leader>o", ":NvimTreeFocus<CR>", { desc = "Focus Explorer" })
vim.keymap.set("n", "K", "<cmd>Lspsaga hover_doc<CR>", { desc = "Hover doc" })
vim.keymap.set("n", "gd", "<cmd>Lspsaga goto_definition<CR>", { desc = "Go to definition" })
vim.keymap.set("n", "gp", "<cmd>Lspsaga peek_definition<CR>", { desc = "Peek definition" })
-- Close Lspsaga windows with q/Esc
vim.api.nvim_create_autocmd("FileType", {
pattern = { "saga_hover", "saga_peek", "saga_finder", "sagaoutline" },
callback = function()
vim.keymap.set("n", "q", "<cmd>close<CR>", { buffer = true, silent = true })
vim.keymap.set("n", "<Esc>", "<cmd>close<CR>", { buffer = true, silent = true })
end,
})4. Alias (Safe from vim)
echo "alias nvimf='NVIM_APPNAME=nvim-flutter nvim'" >> ~/.zshrc
source ~/.zshrc
5. Launch
nvimf
First run: plugins install.
Tree opens on left.
Hover withK, jump withgd, peek withgp.
Keybinds
| Key | Action |
|---|---|
<leader>fr |
Run app |
<leader>fh |
Hot reload |
<leader>e |
Toggle tree |
K |
Hover docs |
gd |
Go to definition |
gp |
Peek definition |
q / Esc |
Close float |
Done.
Your vim is untouched.
Flutter dev = fast, pretty, pro