Last active
February 3, 2025 09:10
-
-
Save Antoniozinchenko/b7e1d3679a88ec4f1b3a3bd6e5b44961 to your computer and use it in GitHub Desktop.
Lunarvim configuration with flutter support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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