From 5bc75d0632b1790fa511e9375608a0520fc857fb Mon Sep 17 00:00:00 2001 From: Youwen Wu Date: Thu, 10 Oct 2024 13:23:08 -0700 Subject: [PATCH] improvements to lazy loading and other qol --- flake.nix | 16 +--- lua/keymaps.lua | 41 +------- lua/plugins/blink-cmp.lua | 177 ----------------------------------- lua/plugins/conform.lua | 34 +++++++ lua/plugins/harpoon.lua | 112 ++++++++++++++-------- lua/plugins/lsp-progress.lua | 1 + lua/plugins/lualine.lua | 2 +- lua/plugins/lz-spec.lua | 123 +++++++++++++----------- lua/plugins/telescope.lua | 108 +++++++++++++++------ lua/plugins/toggleterm.lua | 42 +++++++++ lua/plugins/trouble.lua | 49 ++++++++++ 11 files changed, 357 insertions(+), 348 deletions(-) create mode 100644 lua/plugins/toggleterm.lua create mode 100644 lua/plugins/trouble.lua diff --git a/flake.nix b/flake.nix index b172174..3f879c6 100644 --- a/flake.nix +++ b/flake.nix @@ -78,9 +78,11 @@ python312Packages.pylatexenc fd - # lsps / formatters - lua-language-server + # lsps (minimal because should be provided per-project by nix) nixd + tinymist + + # formatters nixfmt-rfc-style nodePackages_latest.prettier taplo @@ -89,7 +91,6 @@ black stylua marksman - tinymist ]; }; @@ -139,7 +140,6 @@ nvim-autopairs nvim-lspconfig intellitab-nvim - sleuth which-key-nvim telescope-nvim markdown-preview-nvim @@ -188,7 +188,6 @@ "vim" "vi" ]; - neovim-unwrapped = pkgs.neovim-unwrapped; }; categories = { general = true; @@ -223,12 +222,7 @@ devShells = { default = pkgs.mkShell { name = defaultPackageName; - packages = [ defaultPackage ]; - inputsFrom = with pkgs; [ - lua-language-server - stylua - ]; - shellHook = ''''; + packages = [ defaultPackage ] ++ (with pkgs; [ lua-language-server ]); }; }; diff --git a/lua/keymaps.lua b/lua/keymaps.lua index 2400b26..3165297 100644 --- a/lua/keymaps.lua +++ b/lua/keymaps.lua @@ -9,13 +9,6 @@ vim.keymap.set("t", "", "") vim.keymap.set("n", "", "zz") vim.keymap.set("n", "", "zz") -vim.keymap.set("n", "mr", function() - vim.cmd.CellularAutomaton("make_it_rain") -end) -vim.keymap.set("n", "bruh", function() - vim.cmd.CellularAutomaton("game_of_life") -end) - -- when searching, also center screen and reopen folds vim.keymap.set("n", "n", "nzzzv") vim.keymap.set("n", "N", "Nzzzv") @@ -29,33 +22,9 @@ vim.keymap.set({ "n", "v" }, "Y", '"+Y', { desc = "yank rest of line to vim.keymap.set({ "n", "v" }, "p", '"+p', { desc = "put after cursor from clipboard" }) vim.keymap.set({ "n", "v" }, "P", '"+P', { desc = "put before cursor from clipboard" }) -vim.keymap.set("n", "gg", function() - vim.cmd.Neogit() -end, { desc = "Open neogit" }) -vim.keymap.set("n", "gc", function() - vim.cmd.Neogit("kind=floating commit") -end, { desc = "Open neogit commit menu" }) - -vim.keymap.set("n", "u", function() - vim.cmd.UndotreeToggle() -end, { desc = "Toggle undotree" }) - -vim.keymap.set({ "n", "v" }, "cf", function() - require("conform").format({ async = true }) -end) -vim.keymap.set({ "n", "v" }, "ctf", function() - if vim.g.disable_autoformat then - vim.g.disable_autoformat = false - else - vim.g.disable_autoformat = true - end -end, { desc = "Disable autoformat on save globally" }) -vim.keymap.set({ "n", "v" }, "cbf", function() - if vim.b[0].disable_autoformat then - vim.b[0].disable_autoformat = false - else - vim.b[0].disable_autoformat = true - end -end, { desc = "Disable autoformat on save buffer" }) - vim.keymap.set("i", "", require("scripts.intellitab").indent) + +vim.keymap.set("v", "", "gv") +vim.keymap.set("v", "", "gv") +vim.keymap.set("v", "g", "ggv") +vim.keymap.set("v", "g", "ggv") diff --git a/lua/plugins/blink-cmp.lua b/lua/plugins/blink-cmp.lua index 1bb919e..0689186 100644 --- a/lua/plugins/blink-cmp.lua +++ b/lua/plugins/blink-cmp.lua @@ -20,179 +20,6 @@ return { snippet_forward = "", snippet_backward = "", }, - - accept = { - create_undo_point = true, - auto_brackets = { - enabled = false, - default_brackets = { "(", ")" }, - override_brackets_for_filetypes = {}, - -- Overrides the default blocked filetypes - force_allow_filetypes = {}, - blocked_filetypes = {}, - -- Synchronously use the kind of the item to determine if brackets should be added - kind_resolution = { - enabled = true, - blocked_filetypes = { "typescript", "typescriptreact", "javascript", "javascriptreact", "vue" }, - }, - -- Asynchronously use semantic token to determine if brackets should be added - semantic_token_resolution = { - enabled = true, - blocked_filetypes = {}, - }, - }, - }, - - trigger = { - completion = { - -- regex used to get the text when fuzzy matching - -- changing this may break some sources, so please report if you run into issues - -- todo: shouldnt this also affect the accept command? should this also be per language? - keyword_regex = "[%w_\\-]", - -- LSPs can indicate when to show the completion window via trigger characters - -- however, some LSPs (*cough* tsserver *cough*) return characters that would essentially - -- always show the window. We block these by default - blocked_trigger_characters = { " ", "\n", "\t" }, - -- when true, will show the completion window when the cursor comes after a trigger character when entering insert mode - show_on_insert_on_trigger_character = true, - }, - - signature_help = { - enabled = false, - blocked_trigger_characters = {}, - blocked_retrigger_characters = {}, - -- when true, will show the signature help window when the cursor comes after a trigger character when entering insert mode - show_on_insert_on_trigger_character = true, - }, - }, - - fuzzy = { - -- frencency tracks the most recently/frequently used items and boosts the score of the item - use_frecency = true, - -- proximity bonus boosts the score of items with a value in the buffer - use_proximity = true, - max_items = 200, - -- controls which sorts to use and in which order, these three are currently the only allowed options - sorts = { "label", "kind", "score" }, - - prebuiltBinaries = { - -- Whether or not to automatically download a prebuilt binary from github. If this is set to `false` - -- you will need to manually build the fuzzy binary dependencies by running `cargo build --release` - download = false, - -- When downloading a prebuilt binary force the downloader to resolve this version. If this is uset - -- then the downloader will attempt to infer the version from the checked out git tag (if any). - -- - -- Beware that if the FFI ABI changes while tracking main then this may result in blink breaking. - forceVersion = nil, - }, - }, - - sources = { - -- similar to nvim-cmp's sources, but we point directly to the source's lua module - -- multiple groups can be provided, where it'll fallback to the next group if the previous - -- returns no completion items - -- WARN: This API will have breaking changes during the beta - providers = { - { - { "blink.cmp.sources.lsp" }, - { "blink.cmp.sources.path" }, - { "blink.cmp.sources.snippets", score_offset = -3 }, - }, - { { "blink.cmp.sources.buffer" } }, - }, - -- FOR REF: full example - providers = { - { - -- all of these properties work on every source - { - "blink.cmp.sources.lsp", - keyword_length = 0, - score_offset = 0, - trigger_characters = { "f", "o", "o" }, - opts = {}, - }, - -- the follow two sources have additional options - { - "blink.cmp.sources.path", - opts = { - trailing_slash = false, - label_trailing_slash = true, - get_cwd = function(context) - return vim.fn.expand(("#%d:p:h"):format(context.bufnr)) - end, - show_hidden_files_by_default = true, - }, - }, - { - "blink.cmp.sources.snippets", - score_offset = -3, - -- similar to https://github.com/garymjr/nvim-snippets - opts = { - friendly_snippets = true, - search_paths = { vim.fn.stdpath("config") .. "/snippets" }, - global_snippets = { "all" }, - extended_filetypes = {}, - ignored_filetypes = {}, - }, - }, - }, - { { "blink.cmp.sources.buffer" } }, - }, - }, - - windows = { - autocomplete = { - min_width = 30, - max_width = 60, - max_height = 10, - border = "none", - winhighlight = "Normal:BlinkCmpMenu,FloatBorder:BlinkCmpMenuBorder,CursorLine:BlinkCmpMenuSelection,Search:None", - -- keep the cursor X lines away from the top/bottom of the window - scrolloff = 2, - -- which directions to show the window, - -- falling back to the next direction when there's not enough space - direction_priority = { "s", "n" }, - -- whether to preselect the first item in the completion list - preselect = true, - -- Controls how the completion items are rendered on the popup window - -- 'simple' will render the item's kind icon the left alongside the label - -- 'reversed' will render the label on the left and the kind icon + name on the right - -- 'function(blink.cmp.CompletionRenderContext): blink.cmp.Component[]' for custom rendering - draw = "simple", - -- Controls the cycling behavior when reaching the beginning or end of the completion list. - cycle = { - -- When `true`, calling `select_next` at the *bottom* of the completion list will select the *first* completion item. - from_bottom = true, - -- When `true`, calling `select_prev` at the *top* of the completion list will select the *last* completion item. - from_top = true, - }, - }, - documentation = { - min_width = 10, - max_width = 60, - max_height = 20, - border = "padded", - winhighlight = "Normal:BlinkCmpDoc,FloatBorder:BlinkCmpDocBorder,CursorLine:BlinkCmpDocCursorLine,Search:None", - -- which directions to show the documentation window, - -- for each of the possible autocomplete window directions, - -- falling back to the next direction when there's not enough space - direction_priority = { - autocomplete_north = { "e", "w", "n", "s" }, - autocomplete_south = { "e", "w", "s", "n" }, - }, - auto_show = true, - auto_show_delay_ms = 500, - update_delay_ms = 100, - }, - signature_help = { - min_width = 1, - max_width = 100, - max_height = 10, - border = "padded", - winhighlight = "Normal:BlinkCmpSignatureHelp,FloatBorder:BlinkCmpSignatureHelpBorder", - }, - }, - highlight = { ns = vim.api.nvim_create_namespace("blink_cmp"), -- sets the fallback highlight groups to nvim-cmp's highlight groups @@ -201,10 +28,6 @@ return { use_nvim_cmp_as_default = false, }, - -- set to 'mono' for 'Nerd Font Mono' or 'normal' for 'Nerd Font' - -- adjusts spacing to ensure icons are aligned - nerd_font_variant = "normal", - kind_icons = { Text = "󰉿", Method = "󰊕", diff --git a/lua/plugins/conform.lua b/lua/plugins/conform.lua index a93f66d..8db2c84 100644 --- a/lua/plugins/conform.lua +++ b/lua/plugins/conform.lua @@ -2,6 +2,40 @@ return { "conform.nvim", event = "BufWritePre", cmd = "ConformInfo", + keys = { + { + "cf", + function() + require("conform").format({ async = true }) + end, + desc = "Format code", + mode = { "n", "v" }, + }, + { + "ctf", + function() + if vim.g.disable_autoformat then + vim.g.disable_autoformat = false + else + vim.g.disable_autoformat = true + end + end, + desc = "Disable autoformat on save globally", + mode = { "n", "v" }, + }, + { + "cbf", + function() + if vim.b[0].disable_autoformat then + vim.b[0].disable_autoformat = false + else + vim.b[0].disable_autoformat = true + end + end, + desc = "Disable autoformat on save buffer", + mode = { "n", "v" }, + }, + }, after = function() require("conform").setup({ format_on_save = function(bufnr) diff --git a/lua/plugins/harpoon.lua b/lua/plugins/harpoon.lua index b2efbd3..dc47381 100644 --- a/lua/plugins/harpoon.lua +++ b/lua/plugins/harpoon.lua @@ -1,45 +1,77 @@ return { "harpoon2", after = function() - local harpoon = require("harpoon") - - vim.keymap.set("n", "a", function() - harpoon:list():add() - end) - vim.keymap.set("n", "", function() - harpoon:list():select(1) - end) - vim.keymap.set("n", "", function() - harpoon:list():select(2) - end) - vim.keymap.set("n", "", function() - harpoon:list():select(3) - end) - vim.keymap.set("n", "", function() - harpoon:list():select(4) - end) - - local conf = require("telescope.config").values - local function toggle_telescope(harpoon_files) - local file_paths = {} - for _, item in ipairs(harpoon_files.items) do - table.insert(file_paths, item.value) - end - - require("telescope.pickers") - .new({}, { - prompt_title = "Harpoon", - finder = require("telescope.finders").new_table({ - results = file_paths, - }), - previewer = conf.file_previewer({}), - sorter = conf.generic_sorter({}), - }) - :find() - end - - vim.keymap.set("n", "", function() - toggle_telescope(harpoon:list()) - end, { desc = "Open harpoon window" }) + require("harpoon"):setup() end, + keys = { + { + "a", + function() + require("harpoon"):list():add() + end, + desc = "Add to harpoon", + mode = "n", + }, + { + "", + function() + require("harpoon"):list():select(1) + end, + desc = "Select harpoon 1", + mode = "n", + }, + { + "", + function() + require("harpoon"):list():select(2) + end, + desc = "Select harpoon 2", + mode = "n", + }, + { + "", + function() + require("harpoon"):list():select(3) + end, + desc = "Select harpoon 3", + mode = "n", + }, + { + "", + function() + require("harpoon"):list():select(4) + end, + desc = "Select harpoon 4", + mode = "n", + }, + { + "", + function() + require("lz.n").trigger_load("telescope.nvim") + + local conf = require("telescope.config").values + local function toggle_telescope(harpoon_files) + local file_paths = {} + for _, item in ipairs(harpoon_files.items) do + table.insert(file_paths, item.value) + end + + require("telescope.pickers") + .new({}, { + prompt_title = "Harpoon", + finder = require("telescope.finders").new_table({ + results = file_paths, + }), + previewer = conf.file_previewer({}), + sorter = conf.generic_sorter({}), + }) + :find() + end + + toggle_telescope(require("harpoon"):list()) + end, + mode = "n", + desc = "toggle harpoon menu", + }, + }, } diff --git a/lua/plugins/lsp-progress.lua b/lua/plugins/lsp-progress.lua index 11d070d..f3d0364 100644 --- a/lua/plugins/lsp-progress.lua +++ b/lua/plugins/lsp-progress.lua @@ -1,5 +1,6 @@ return { "lsp-progress", + event = "LspAttach", after = function() require("lsp-progress").setup({ client_format = function(client_name, spinner, series_messages) diff --git a/lua/plugins/lualine.lua b/lua/plugins/lualine.lua index 80ad1b0..aad94fb 100644 --- a/lua/plugins/lualine.lua +++ b/lua/plugins/lualine.lua @@ -1,6 +1,5 @@ return { "lualine.nvim", - event = "BufEnter", after = function() require("lualine").setup({ options = { @@ -25,6 +24,7 @@ return { lualine_a = { "branch" }, lualine_b = { function() + require("lz.n").trigger_load("lsp-progress") return require("lsp-progress").progress() end, }, diff --git a/lua/plugins/lz-spec.lua b/lua/plugins/lz-spec.lua index eaa25f9..625284a 100644 --- a/lua/plugins/lz-spec.lua +++ b/lua/plugins/lz-spec.lua @@ -8,7 +8,9 @@ return { require("plugins.lsp-progress"), require("plugins.gitsigns"), require("plugins.autopairs"), - { "telescope-ui-select.nvim", priority = 70 }, + require("plugins.trouble"), + require("plugins.toggleterm"), + { "telescope-ui-select.nvim" }, { "nvim-lspconfig", event = "BufEnter", @@ -16,10 +18,6 @@ return { require("lsp") end, }, - { - "sleuth", - event = "BufEnter", - }, { "which-key.nvim", after = function() @@ -29,30 +27,10 @@ return { end, }, { "nvim-web-devicons" }, - { "rose-pine" }, - { "render-markdown.nvim" }, - { "markdown-preview.nvim" }, + { "rose-pine", priority = 100 }, { - "trouble.nvim", - event = "LspAttach", - after = function() - require("trouble").setup() - vim.keymap.set("n", "xx", function() - vim.cmd("Trouble diagnostics toggle") - end, { desc = "Diagnostics" }) - vim.keymap.set("n", "xX", function() - vim.cmd("Trouble diagnostics toggle filter.buf=0") - end, { desc = "Buffer diagnostics" }) - vim.keymap.set("n", "cs", function() - vim.cmd("Trouble symbols toggle") - end, { desc = "Symbols" }) - vim.keymap.set("n", "cl", function() - vim.cmd("Trouble lsp toggle win.position=right") - end, { desc = "LSP definitions / references /..." }) - vim.keymap.set("n", "ql", function() - vim.cmd("Trouble qflist toggle") - end, { desc = "Quickfix list (trouble)" }) - end, + "markdown-preview.nvim", + filetypes = { "markdown" }, }, { "typst-preview", @@ -66,27 +44,6 @@ return { }) end, }, - { - "toggleterm.nvim", - after = function() - require("toggleterm").setup({ - shade_terminals = false, - }) - - vim.keymap.set({ "n", "t", "v" }, "", function() - vim.cmd("ToggleTerm direction=float") - end) - vim.keymap.set("n", "tv", function() - vim.cmd("ToggleTerm direction=vertical") - end) - vim.keymap.set("n", "tt", function() - vim.cmd("ToggleTerm direction=horizontal") - end) - vim.keymap.set("n", "ts", function() - vim.cmd("TermSelect") - end) - end, - }, { "mini.ai", event = "BufEnter", @@ -109,7 +66,6 @@ return { }, { "mini.notify", - event = "BufEnter", after = function() require("mini.notify").setup({ lsp_progress = { enable = false }, @@ -126,6 +82,24 @@ return { { "cellular-automaton.nvim", cmd = "CellularAutomaton", + keys = { + { + "mr", + function() + vim.cmd.CellularAutomaton("make_it_rain") + end, + desc = "A surprise!", + mode = "n", + }, + { + "bruh", + function() + vim.cmd.CellularAutomaton("game_of_life") + end, + desc = "A surprise!", + mode = "n", + }, + }, }, { "indent-blankline.nvim", @@ -150,13 +124,18 @@ return { }, { "mini.bufremove", - event = "BufEnter", + keys = { + { + "bd", + function() + MiniBufremove.delete() + end, + mode = { "n", "v" }, + desc = "Close buffer", + }, + }, after = function() require("mini.bufremove").setup() - - vim.keymap.set({ "n", "v" }, "bd", function() - MiniBufremove.delete() - end) end, }, { @@ -169,6 +148,29 @@ return { { "neogit", cmd = "Neogit", + keys = { + { + "gg", + function() + vim.cmd.Neogit() + end, + desc = "Open neogit", + mode = "n", + }, + { + "gc", + function() + vim.cmd.Neogit("kind=floating commit") + end, + desc = "Open neogit commit menu", + mode = "n", + }, + }, + before = function() + local lz = require("lz.n") + lz.trigger_load("diffview.nvim") + lz.trigger_load("telescope.nvim") + end, after = function() require("neogit").setup({ graph_style = "unicode", @@ -187,7 +189,6 @@ return { "barbecue.nvim", event = "BufEnter", after = function() - require("barbecue").setup() -- triggers CursorHold event faster vim.opt.updatetime = 200 @@ -214,5 +215,15 @@ return { { "undotree", cmd = "UndotreeToggle", + keys = { + { + "u", + function() + vim.cmd.UndotreeToggle() + end, + desc = "Toggle undotree", + mode = "n", + }, + }, }, } diff --git a/lua/plugins/telescope.lua b/lua/plugins/telescope.lua index 89af384..92617bf 100644 --- a/lua/plugins/telescope.lua +++ b/lua/plugins/telescope.lua @@ -10,32 +10,86 @@ return { }) require("telescope").load_extension("ui-select") - - local builtin = require("telescope.builtin") - - vim.keymap.set("n", " ", function() - local is_git = vim.fn.finddir(".git", vim.fn.getcwd() .. ";") - if is_git then - builtin.git_files() - else - builtin.find_files() - end - end, { desc = "Grep through all files tracked by git, or fall back to just cwd" }) - - vim.keymap.set("n", "ff", builtin.find_files, { desc = "Grep through all files in cwd" }) - vim.keymap.set("n", "ca", vim.lsp.buf.code_action) - vim.keymap.set("n", "/", builtin.live_grep) - vim.keymap.set("n", "k", builtin.buffers) - vim.keymap.set("n", "gd", builtin.lsp_definitions, { desc = "Go to LSP definition" }) - vim.keymap.set("n", "gi", builtin.lsp_implementations, { desc = "Go to implementations" }) - vim.keymap.set("n", "j", builtin.lsp_document_symbols, { desc = "Search through document symbols" }) - vim.keymap.set( - "n", - "fs", - builtin.lsp_workspace_symbols, - { desc = "Search through entire workspace symbols" } - ) - vim.keymap.set("n", "fd", builtin.diagnostics, { desc = "Search through LSP diagnostics" }) end, - priority = 60, + keys = { + { + " ", + function() + local builtin = require("telescope.builtin") + local is_git = vim.fn.finddir(".git", vim.fn.getcwd() .. ";") + if is_git then + builtin.git_files() + else + builtin.find_files() + end + end, + desc = "Grep through all files tracked by git, or fall back to just cwd", + mode = "n", + }, + { + "ff", + function() + require("telescope.builtin").find_files() + end, + desc = "Grep through all files in cwd", + mode = "n", + }, + { "ca", vim.lsp.buf.code_action, desc = "LSP Code Action", mode = "n" }, + { + "/", + function() + require("telescope.builtin").live_grep() + end, + desc = "Live grep", + mode = "n", + }, + { + "k", + function() + require("telescope.builtin").buffers() + end, + desc = "List buffers", + mode = "n", + }, + { + "gd", + function() + require("telescope.builtin").lsp_definitions() + end, + desc = "Go to LSP definition", + mode = "n", + }, + { + "gi", + function() + require("telescope.builtin").lsp_implementations() + end, + desc = "Go to implementations", + mode = "n", + }, + { + "j", + function() + require("telescope.builtin").lsp_document_symbols() + end, + desc = "Search through document symbols", + mode = "n", + }, + { + "fs", + function() + require("telescope.builtin").lsp_workspace_symbols() + end, + desc = "Search through entire workspace symbols", + mode = "n", + }, + { + "fd", + function() + require("telescope.builtin").diagnostics() + end, + desc = "Search through LSP diagnostics", + mode = "n", + }, + }, } diff --git a/lua/plugins/toggleterm.lua b/lua/plugins/toggleterm.lua new file mode 100644 index 0000000..bcac9f8 --- /dev/null +++ b/lua/plugins/toggleterm.lua @@ -0,0 +1,42 @@ +return { + "toggleterm.nvim", + keys = { + { + "", + function() + vim.cmd("ToggleTerm direction=float") + end, + mode = { "n", "t", "v" }, + desc = "Toggle terminal" + }, + { + "tv", + function() + vim.cmd("ToggleTerm direction=vertical") + end, + desc = "Vertical terminal", + mode = "n", + }, + { + "tt", + function() + vim.cmd("ToggleTerm direction=horizontal") + end, + desc = "Horizontal terminal", + mode = "n", + }, + { + "ts", + function() + vim.cmd("TermSelect") + end, + desc = "Terminal select", + mode = "n", + }, + }, + after = function() + require("toggleterm").setup({ + shade_terminals = false, + }) + end, +} diff --git a/lua/plugins/trouble.lua b/lua/plugins/trouble.lua new file mode 100644 index 0000000..2f0e4bf --- /dev/null +++ b/lua/plugins/trouble.lua @@ -0,0 +1,49 @@ +return { + "trouble.nvim", + cmd = "Trouble", + after = function() + require("trouble").setup() + end, + keys = { + { + "xx", + function() + vim.cmd("Trouble diagnostics toggle") + end, + desc = "Diagnostics", + mode = "n", + }, + { + "xX", + function() + vim.cmd("Trouble diagnostics toggle filter.buf=0") + end, + desc = "Buffer diagnostics", + mode = "n", + }, + { + "cs", + function() + vim.cmd("Trouble symbols toggle") + end, + desc = "Symbols", + mode = "n", + }, + { + "cl", + function() + vim.cmd("Trouble lsp toggle win.position=right") + end, + desc = "LSP definitions / references /...", + mode = "n", + }, + { + "ql", + function() + vim.cmd("Trouble qflist toggle") + end, + desc = "Quickfix list (trouble)", + mode = "n", + }, + }, +}