Skip to content

Instantly share code, notes, and snippets.

@Antoniozinchenko
Last active February 3, 2025 09:10
Show Gist options
  • Save Antoniozinchenko/b7e1d3679a88ec4f1b3a3bd6e5b44961 to your computer and use it in GitHub Desktop.
Save Antoniozinchenko/b7e1d3679a88ec4f1b3a3bd6e5b44961 to your computer and use it in GitHub Desktop.
Lunarvim configuration with flutter support
-- Read the docs: https://www.lunarvim.org/docs/configuration
-- Video Tutorials: https://www.youtube.com/watch?v=sFA9kX-Ud_c&list=PLhoH5vyxr6QqGu0i7tt_XoVK9v-KvZ3m6
-- Forum: https://www.reddit.com/r/lunarvim/
-- Discord: https://discord.com/invite/Xb9B4Ny
--
lvim.format_on_save.enabled = false
lvim.log.level = "warn"
lvim.colorscheme = "tokyonight-night"
vim.opt.relativenumber = true
-- escape insert mode by "jk"
lvim.keys.insert_mode["jk"] = "<ESC>"
-- delete single character without copying into register
lvim.keys.normal_mode["x"] = '"_x'
-- spit windows verticall and horizontally
lvim.keys.normal_mode["<leader>sv"] = ":vsplit<CR>"
lvim.keys.normal_mode["<leader>sh"] = ":split<CR>"
lvim.keys.normal_mode["<leader>|"] = ":vsplit<CR>"
lvim.keys.normal_mode["<leader>-"] = ":split<CR>"
-- aligh cursor on screen center during scroll
lvim.keys.normal_mode["<C-d>"] = "<C-d>zz"
lvim.keys.normal_mode["<C-u>"] = "<C-u>zz"
lvim.keys.normal_mode["<leader>Lt"] = ":15 split<CR>:terminal<CR>"
-- Change Telescope navigation to use j and k for navigation and n and p for history in both input and normal mode.
-- we use protected-mode (pcall) just in case the plugin wasn't loaded yet.
local _, actions = pcall(require, "telescope.actions")
lvim.builtin.telescope.defaults.mappings = {
-- for input mode
i = {
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
["<C-n>"] = actions.cycle_history_next,
["<C-p>"] = actions.cycle_history_prev,
},
-- for normal mode
n = {
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
},
}
lvim.builtin.telescope.on_config_done = function(telescope)
telescope.load_extension("flutter")
end
-- if you don't want all the parsers change this to a table of the ones you want
lvim.builtin.treesitter.ensure_installed = {
"bash",
"c",
"javascript",
"json",
"lua",
"typescript",
"tsx",
"css",
"yaml",
"dart",
"ruby",
"markdown",
"python",
"markdown_inline",
}
lvim.builtin.treesitter.ignore_install = { "haskell" }
lvim.builtin.treesitter.highlight.enable = true
-- generic LSP settings
---@usage disable automatic installation of servers
lvim.lsp.installer.setup.automatic_installation = false
-- -- make sure server will always be installed even if the server is in skipped_servers list
lvim.lsp.installer.setup.ensure_installed = {
"lua_ls",
"jsonls",
"dartls",
}
local lspconfig = require("lspconfig")
-- Configure tsserver for JavaScript and TypeScript
lspconfig.tsserver.setup({
filetypes = { "javascript", "javascriptreact", "typescript", "typescriptreact" },
on_attach = function(client, bufnr)
-- Optionally disable formatting if you use another tool like Prettier
client.resolved_capabilities.document_formatting = false
end,
})
-- Flutter snippets enable
local luasnip = require("luasnip")
luasnip.filetype_extend("dart", { "flutter" })
lvim.builtin.which_key.mappings["F"] = {
name = "+Flutter",
c = { "<cmd>Telescope flutter commands<cr>", "Open Flutter Commans" },
d = { "<cmd>FlutterDevices<cr>", "Flutter Devices" },
e = { "<cmd>FlutterEmulators<cr>", "Flutter Emulators" },
r = { "<cmd>FlutterReload<cr>", "Hot Reload App" },
R = { "<cmd>FlutterRestart<cr>", "Hot Restart app" },
q = { "<cmd>FlutterQuit<cr>", "Quit running application" },
L = { "<cmd>FlutterIntlGenerate<cr>", "Flutter Intl: generate classes" },
l = { "<cmd>FlutterIntlDownload<cr>", "Flutter Intl: download .arb" },
v = { "<cmd>Telescope flutter fvm<cr>", "Flutter version" },
}
lvim.builtin.which_key.mappings["T"] = {
name = "+Tests",
t = { "<cmd>lua require('neotest').run.run()<CR>", "Run nearest test" },
-- T = { "<cmd>lua require('neotest').run.run({strategy = 'dap'})<CR>", "Debug nearest test" },
f = { '<cmd>lua require("neotest").run.run(vim.fn.expand("%"))<cr>', "Run test for entire file" },
o = { "<cmd>lua require('neotest').summary.toggle()<cr>", "Output summary panel" },
g = {
'<cmd>lua require("neotest").run.run({extra_args="--update-goldens"})<CR>',
"Update goldens for current test",
},
}
lvim.builtin.which_key.mappings["t"] = {
name = "+Trouble",
r = { "<cmd>Trouble lsp_references<cr>", "References" },
f = { "<cmd>Trouble lsp_definitions<cr>", "Definitions" },
d = { "<cmd>Trouble document_diagnostics<cr>", "Diagnostics" },
q = { "<cmd>Trouble quickfix<cr>", "QuickFix" },
l = { "<cmd>Trouble loclist<cr>", "LocationList" },
w = { "<cmd>Trouble workspace_diagnostics<cr>", "Workspace Diagnostics" },
t = { "<cmd>TodoTelescope<cr>", "TODO List" },
}
lvim.builtin.alpha.active = true
lvim.builtin.alpha.mode = "dashboard"
lvim.builtin.terminal.active = true
lvim.builtin.nvimtree.setup.view.side = "left"
lvim.builtin.nvimtree.setup.renderer.icons.show.git = true
lvim.plugins = {
{ "stevearc/dressing.nvim" },
{ "folke/tokyonight.nvim" },
-- Drow diagrams
{ "jbyuki/venn.nvim" },
-- Flutter plugin
{
"akinsho/flutter-tools.nvim",
dependencies = { "nvim-lua/plenary.nvim", "stevearc/dressing.nvim" },
config = function()
require("flutter-tools").setup({
-- flutter_path = "~/development/flutter",
fvm = true, -- takes priority over path, uses <workspace>/.fvm/flutter_sdk if enabled
ui = {
-- the border type to use for all floating windows, the same options/formats
-- used for ":h nvim_open_win" e.g. "single" | "shadow" | {<table-of-eight-chars>}
border = "rounded",
-- This determines whether notifications are show with `vim.notify` or with the plugin's custom UI
-- please note that this option is eventually going to be deprecated and users will need to
-- depend on plugins like `nvim-notify` instead.
notification_style = "plugin",
},
decorations = {
statusline = {
-- set to true to be able use the 'flutter_tools_decorations.app_version' in your statusline
-- this will show the current version of the flutter app from the pubspec.yaml file
app_version = true,
-- set to true to be able use the 'flutter_tools_decorations.device' in your statusline
-- this will show the currently running device if an application was started with a specific
-- device
device = true,
},
},
outline = {
open_cmd = "30vnew", -- command to use to open the outline buffer
auto_open = false, -- if true this will open the outline automatically when it is first populated
},
debugger = {
enabled = true,
run_via_dap = true,
register_configurations = function(_)
local dap = require("dap")
-- dap.adapters.dart = {
-- type = "executable",
-- command = "node",
-- args = { debugger_path, "flutter" },
-- }
dap.set_log_level("TRACE")
dap.configurations.dart = {}
require("dap.ext.vscode").load_launchjs()
end,
},
dev_log = {
enabled = false,
-- open_cmd = "tabedit", -- command to use to open the log buffer
},
lsp = {
color = {
-- show the derived colours for dart variables
enabled = true, -- whether or not to highlight color variables at all, only supported on flutter >= 2.10
background = false, -- highlight the background
foreground = false, -- highlight the foreground
virtual_text = true, -- show the highlight using virtual text
virtual_text_str = "■", -- the virtual text character to highlight
},
settings = {
showTodos = true,
completeFunctionCalls = true,
renameFilesWithClasses = "prompt", -- "always"
enableSnippets = true,
enableSdkFormatter = true,
},
},
})
end,
},
{
"nvimdev/lspsaga.nvim",
event = "LspAttach",
config = function()
local saga = require("lspsaga")
saga.setup({
-- -- keybinds for navigation in lspsaga window
move_in_saga = { prev = "<C-k>", next = "<C-j>" },
-- -- use enter to open file with finder
--
finder = {
silent = true,
default = "def+ref+imp",
layout = "float",
keys = {
shuttle = "[]",
toggle_or_open = "<CR>",
jump_to = "e",
vsplit = "v",
split = "s",
tabe = "t",
tabnew = "n",
quit = "q",
close = "<Esc>",
},
},
-- -- use enter to open file with definition preview
definition = {
edit = "<CR>",
},
})
local keymap = vim.keymap.set
-- Lsp finder find the symbol definition implement reference
-- if there is no implement it will hide
-- when you use action in finder like open vsplit then you can
-- use <C-t> to jump back
keymap("n", "gh", "<cmd>Lspsaga finder<CR>", { silent = true })
-- -- Rename
-- keymap("n", "gr", "<cmd>Lspsaga rename<CR>", { silent = true })
-- Peek Definition
-- you can edit the definition file in this flaotwindow
-- also support open/vsplit/etc operation check definition_action_keys
-- support tagstack C-t jump back
keymap("n", "gd", "<cmd>Lspsaga goto_definition<CR>", { silent = true })
keymap("n", "gD", "<cmd>Lspsaga peek_definition<CR>", { silent = true })
-- Hover Doc
keymap("n", "K", "<cmd>Lspsaga hover_doc<CR>", { silent = true })
-- Float terminal
keymap("n", "<A-d>", "<cmd>Lspsaga term_toggle<CR>", { silent = true })
keymap("n", "∂", "<cmd>Lspsaga term_toggle<CR>", { silent = true }) -- macos ALT+d(Option+d) binding
end,
dependencies = {
{ "nvim-tree/nvim-web-devicons" },
{ "nvim-treesitter/nvim-treesitter" },
},
},
-- Syntax highlight for mdx files: used by Storybook
{ "jxnblk/vim-mdx-js" },
{
"folke/todo-comments.nvim",
dependencies = "nvim-lua/plenary.nvim",
config = function()
require("todo-comments").setup({
-- your configuration comes here
-- or leave it empty to use the default settings
-- refer to the configuration section below
})
end,
},
{ "Antoniozinchenko/neotest-dart" },
{
"nvim-neotest/neotest",
dependencies = {
"nvim-neotest/nvim-nio",
"nvim-lua/plenary.nvim",
"antoinemadec/FixCursorHold.nvim",
"nvim-treesitter/nvim-treesitter",
"haydenmeade/neotest-jest",
"Antoniozinchenko/neotest-dart",
},
config = function()
require("neotest").setup({
adapters = {
require("neotest-dart")({
command = "fvm flutter", -- or "fvm flutter"
-- command = 'flutter', -- or "fvm flutter"
use_lsp = true,
custom_test_method_names = {
"testGoldens",
},
}),
require("neotest-jest")({
jestCommand = "yarn test --",
}),
},
})
end,
},
{
"folke/trouble.nvim",
opts = {},
cmd = "TroubleToggle",
},
{ "github/copilot.vim" },
{
"Antoniozinchenko/flutter-intl",
-- dir = "~/work/flutter-intl",
commit = "c482c157783da18623b99fe61114eed3d46ad86b",
config = function()
require("flutter-intl").setup()
end,
},
{
"adelarsq/image_preview.nvim",
event = "VeryLazy",
config = function()
require("image_preview").setup()
end,
},
}
-- Autocommands (https://neovim.io/doc/user/autocmd.html)
-- vim.api.nvim_exec([[
-- augroup HighlightHexInStrings
-- autocmd!
-- autocmd FileType typescript,typescriptreact lua highlightHex()
-- augroup END
-- ]], false)
vim.api.nvim_create_autocmd("BufEnter", {
pattern = { "*.json", "*.jsonc", "*.arb" },
-- enable wrap mode for json files only
command = "setlocal wrap",
})
-- Flutter .arb files should be concidered as json files
vim.filetype.add({
extension = {
arb = "json",
},
})
-- set additional linters
local linters = require("lvim.lsp.null-ls.linters")
linters.setup({
{
command = "eslint",
filetypes = {
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
},
},
})
-- set a formatter, this will override the language server formatting capabilities (if it exists)
local formatters = require("lvim.lsp.null-ls.formatters")
formatters.setup({
{
command = "stylua",
},
{
-- each formatter accepts a list of options identical to https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md#Configuration
command = "prettier",
---@usage arguments to pass to the formatter
-- these cannot contain whitespaces, options such as `--line-width 80` become either `{'--line-width', '80'}` or `{'--line-width=80'}`
extra_args = { "--print-with", "100" },
---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
filetypes = { "typescript", "typescriptreact", "javascript", "javascriptreact" },
},
-- {
-- command = "eslint_d",
-- filetypes = {
-- "javascript", "javascriptreact",
-- "typescript", "typescriptreact"
-- }
-- }
})
-- disable tab navigation in cmp (needed for copilot plugin to work properly)
local cmp_mapping = require("cmp.config.mapping")
local cmp = require("lvim.utils.modules").require_on_index("cmp")
lvim.builtin.cmp.mapping["<Tab>"] = cmp_mapping({
i = function(fallback)
if cmp.visible() then
cmp.close()
end
fallback()
end,
})
-- Venn
lvim.builtin.lualine.sections.lualine_c = {
{
function()
local venn_enabled = vim.inspect(vim.b.venn_enabled)
if venn_enabled == "true" then
vim.opt.virtualedit = "all"
return "Diagram mode"
end
vim.opt.virtualedit = ""
return ""
end,
},
}
function _G.Toggle_venn()
local venn_enabled = vim.inspect(vim.b.venn_enabled)
if venn_enabled == "nil" then
vim.b.venn_enabled = true
vim.cmd([[setlocal ve=all]])
-- draw a line on HJKL keystokes
vim.api.nvim_buf_set_keymap(0, "n", "J", "<C-v>j:VBox<CR>", { noremap = true })
vim.api.nvim_buf_set_keymap(0, "n", "K", "<C-v>k:VBox<CR>", { noremap = true })
vim.api.nvim_buf_set_keymap(0, "n", "L", "<C-v>l:VBox<CR>", { noremap = true })
vim.api.nvim_buf_set_keymap(0, "n", "H", "<C-v>h:VBox<CR>", { noremap = true })
-- draw a box by pressing "f" with visual selection
vim.api.nvim_buf_set_keymap(0, "v", "f", ":VBox<CR>", { noremap = true })
else
vim.cmd([[setlocal ve=]])
vim.cmd([[mapclear <buffer>]])
vim.b.venn_enabled = nil
end
end
lvim.keys.normal_mode["<leader>v"] = ":lua Toggle_venn()<CR>"
function _G.switch_case()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
local word = vim.fn.expand("<cword>")
local word_start = vim.fn.matchstrpos(vim.fn.getline("."), "\\k*\\%" .. (col + 1) .. "c\\k*")[2]
-- Detect camelCase
if word:find("[a-z][A-Z]") then
-- Convert camelCase to snake_case
local snake_case_word = word:gsub("([a-z])([A-Z])", "%1_%2"):lower()
vim.api.nvim_buf_set_text(0, line - 1, word_start, line - 1, word_start + #word, { snake_case_word })
-- Detect snake_case
elseif word:find("_[a-z]") then
-- Convert snake_case to camelCase
local camel_case_word = word:gsub("(_)([a-z])", function(_, l)
return l:upper()
end)
vim.api.nvim_buf_set_text(0, line - 1, word_start, line - 1, word_start + #word, { camel_case_word })
else
print("Not a snake_case or camelCase word")
end
end
lvim.keys.normal_mode["<leader>S"] = ":lua switch_case()<CR>"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment