├── .gitignore
├── README.md
├── assets
└── images
│ ├── debug.png
│ ├── features.png
│ ├── lsp.png
│ ├── lsp_linux.png
│ ├── preview.png
│ ├── startup_legion.jpeg
│ └── startup_mbp.png
├── init.lua
├── lsp
├── clangd.lua
├── pyright.lua
├── ruff.lua
├── texlab.lua
├── typescript-language-server.lua
└── vscode-eslint-language-server.lua
├── lua
├── colors.lua
├── diagnostics.lua
├── keymaps.lua
├── lsp.lua
├── options.lua
├── plugins
│ ├── autopairs.lua
│ ├── bbye.lua
│ ├── blankline.lua
│ ├── blink.lua
│ ├── gitsigns.lua
│ ├── init.lua
│ ├── molten.lua
│ ├── nvim-dap.lua
│ ├── nvim-tree.lua
│ ├── otter.lua
│ ├── terminal.lua
│ ├── treesitter.lua
│ └── vimtex.lua
└── statusline.lua
├── projects
└── terminal
│ └── lua
│ └── terminal.lua
├── queries
└── python
│ ├── folds.scm
│ └── highlights.scm
└── snippets
├── markdown.json
├── python.json
├── quarto.json
└── tex.json
/.gitignore:
--------------------------------------------------------------------------------
1 | plugin/
2 |
3 | lazy-lock.json
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | The configuration uses as few plugins as possible to improves robustness against breaking changes and makes it easier to maintain.
20 | Although the config uses only 12 plugins, it has all essential IDE features:
21 |
22 |
23 | - Language servers and code diagnostics
24 | - Code completion and custom snippets
25 | - Debugging capability
26 | - Formatting and linting
27 | - Code testing
28 |
29 |
30 | That being said, if you are a Neovim user, I hope you see something interesting to adopt to your own config. If you are still considering Neovim, I hope you become a part of our community soon!
31 |
32 |
33 |
34 |
35 |
Dependencies
36 |
37 | The config requires neovim v.0.11.x or newer.
38 | In addition, users are expected to install the required language servers, e.g., Pyright, and debug adapter protocol implementations, e.g., debugpy, themselves.
39 | Unlike many Neovim configs, this project does not require Nerd Fonts because it does not use any icon.
40 |
41 |
42 |
43 |
44 |
How to Use
45 |
46 | During startup, nvim looks for a configuration file inside the nvim directory, which is typically '~/.config/nvim/'.
47 | To use the project, you can simply clone the repository using Git:
48 |
49 |
git clone https://github.com/rezhaTanuharja/minimalistNVIM.git ~/.config/nvim
52 |
53 | Subsequently, simply start Neovim and Lazy will automatically install all of the plugins.
54 | Keep in mind that if you have not installed the required language servers or debug adapter protocol implementations, you may encounter errors.
55 |
56 |
57 |
58 |
How It Looks
59 |
60 | The colors are mostly (not all!) grayscale.
61 | A typical Lua code with lua-language-server's hover capability looks like the following image.
62 | An autocmd sets cursorline only in the focused window so it is easier to keep track of where the cursor is in a multi-window layout.
63 |
64 |
65 |

66 |
67 |
68 |
69 | The colors are deliberately chosen to look decent and non-distracting in both transparent and opague terminal windows.
70 | The previous image shows Neovim in iTerm2 on MacOS.
71 | The following image shows an identical layout in an opague Alacritty window on EndeavourOS:
72 |
73 |
74 |

75 |
76 |
77 |
78 | The following image shows how Neovim looks like with the nvim-tree window toggled open.
79 | It also shows how a diagnostic error is displayed inside the buffer and in the tree view.
80 | The TODO item is highlighted and the contextual location of the cursor is shown in the statusline thanks to nvim-treesitter.
81 |
82 |
83 |

84 |
85 |
86 |
87 | The following image shows another essential IDE feature: a debugging capability, thanks to nvim-dap.
88 | Slightly different from other configs, this project does not use nvim-dap-ui, nvim-dap-python, etc..
89 | Instead, we rely completely on what nvim-dap offers.
90 |
91 |
92 |

93 |
94 |
95 |
96 | By default, only the normal buffer window is shown, with red dash(es) indicating breakpoint location(s) and a blue arrow indicating the current position in program execution.
97 | All widgets such as the call stack (bottom left), the scopes (top right), and REPL (bottom right) only appear when the user toggles them.
98 | This is deliberate, since not all widgets are used all the time and will simply be a distraction if they are always present.
99 |
100 |
101 |
102 |
Others
103 |
104 | While we do not think startup time matters, some people apparently do care.
105 | Last time we check, our startup time is ~7-15 ms on a maxed-out Lenovo Legion Pro 7i 2024, as shown below by Lazy's profile.
106 |
107 |
108 |

109 |
110 |
111 | The startup time is still very short in older hardwares.
112 | On our 2015 MacBook Pro with Arch, it is around ~28-35ms as shown below
113 |
114 |
115 |

116 |
117 |
118 |
--------------------------------------------------------------------------------
/assets/images/debug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/debug.png
--------------------------------------------------------------------------------
/assets/images/features.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/features.png
--------------------------------------------------------------------------------
/assets/images/lsp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/lsp.png
--------------------------------------------------------------------------------
/assets/images/lsp_linux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/lsp_linux.png
--------------------------------------------------------------------------------
/assets/images/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/preview.png
--------------------------------------------------------------------------------
/assets/images/startup_legion.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/startup_legion.jpeg
--------------------------------------------------------------------------------
/assets/images/startup_mbp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rezhaTanuharja/minimalistNVIM/8e3deaee5bf8d121d0ec62f7360c90a27557a232/assets/images/startup_mbp.png
--------------------------------------------------------------------------------
/init.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file init.lua
3 | --
4 | -- @brief
5 | -- The starting point of the Neovim config
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-10-12
9 | --
10 |
11 |
12 | -- list of all unnecessary providers
13 |
14 | local disabled_providers = {
15 | "node",
16 | "perl",
17 | "ruby",
18 | }
19 |
20 | for _, provider in pairs(disabled_providers) do
21 | vim.g["loaded_" .. provider .. "_provider"] = 0
22 | end
23 |
24 |
25 | -- list of all config files
26 |
27 | local config_files = {
28 | "options",
29 | "keymaps",
30 | "colors",
31 | "diagnostics",
32 | "statusline",
33 | "plugins",
34 | "lsp",
35 | }
36 |
37 | for _, file in pairs(config_files) do
38 |
39 | local success = pcall(require, file)
40 | if not success then
41 | vim.notify("Failed to load a config file " .. file)
42 | break
43 | end
44 |
45 | end
46 |
--------------------------------------------------------------------------------
/lsp/clangd.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lsp/clangd.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the clangd LSP
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2025-03-28
9 | --
10 |
11 |
12 | return {
13 |
14 | filetypes = {"c", "cpp"},
15 |
16 | cmd = {"clangd", "--background-index", "--clang-tidy", "--log=verbose"},
17 |
18 | root_markers = { ".git", "compile_commands.json" },
19 |
20 | init_options = {
21 | fallbackFlag = {"-std=c++17"},
22 | },
23 |
24 | settings = {},
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/lsp/pyright.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lsp/pyright.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the Pyright LSP
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2025-03-28
9 | --
10 |
11 |
12 | return {
13 |
14 | filetypes = { "python" },
15 |
16 | cmd = {"pyright-langserver", "--stdio"},
17 |
18 | root_markers = { ".git", "pyproject.toml" },
19 |
20 | settings = {
21 | pyright = {
22 | disableOrganizeImports = true,
23 | },
24 | python = {
25 | analysis = {
26 | autoImportCompletions= true,
27 | autoSeachPaths = false,
28 | diagnosticMode = "openFilesOnly",
29 | typeCheckingMode = "basic",
30 | diagnosticSeverityOverrides = {
31 | reportPrivateImportUsage = "none",
32 | },
33 | }
34 | },
35 | },
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/lsp/ruff.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lsp/ruff.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the Ruff LSP
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2025-03-28
9 | --
10 |
11 |
12 | return {
13 |
14 | filetypes = { "python" },
15 |
16 | cmd = { "ruff", "server" },
17 |
18 | root_markers = { ".git", "pyproject.toml" },
19 |
20 | init_options = {
21 | settings = {
22 | organizeImports = true,
23 | lint = {
24 | extendSelect = {
25 | "A",
26 | "ARG",
27 | "B",
28 | "COM",
29 | "C4",
30 | "DOC",
31 | "FBT",
32 | "I",
33 | "ICN",
34 | "N",
35 | "PERF",
36 | "PL",
37 | "Q",
38 | "RET",
39 | "RUF",
40 | "SIM",
41 | "SLF",
42 | "TID",
43 | "W",
44 | },
45 | },
46 | },
47 | },
48 |
49 | settings = {},
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/lsp/texlab.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lsp/ruff.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the TexLab LSP
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2025-03-28
9 | --
10 |
11 |
12 | return {
13 |
14 | filetypes = { "tex", "plaintex", "bib" },
15 |
16 | cmd = { "texlab" },
17 |
18 | root_markers = { ".git", "main.tex" },
19 |
20 | settings = {
21 |
22 | texlab = {
23 |
24 | bibtexFormatter = "texlab",
25 |
26 | build = {
27 | onSave = false,
28 | onType = false,
29 | },
30 |
31 | diagnosticDelay = 100,
32 | formatterLineLength = 80,
33 |
34 | forwardSearch = {
35 | args = {},
36 | },
37 |
38 | }
39 |
40 | },
41 |
42 | single_file_support = true,
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/lsp/typescript-language-server.lua:
--------------------------------------------------------------------------------
1 | return {
2 |
3 | filetypes = { "javascript", "javascriptreact", "javascript.jsx", "typescript", "typescriptreact", "typescript.tsx" },
4 |
5 | cmd = {"typescript-language-server", "--stdio"},
6 |
7 | root_markers = { ".git", "package.json" },
8 |
9 | init_options = {
10 | hostInfo = "neovim",
11 | },
12 |
13 | settings = {},
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/lsp/vscode-eslint-language-server.lua:
--------------------------------------------------------------------------------
1 |
2 | return {
3 |
4 | filetypes = { "javascript", "javascriptreact", "javascript.jsx", "typescript", "typescriptreact", "typescript.tsx" },
5 |
6 | cmd = {"vscode-eslint-language-server", "--stdio"},
7 |
8 | root_markers = { ".git", "package.json" },
9 |
10 | on_attach = function(client, bufnr)
11 | vim.api.nvim_create_autocmd("BufWritePost", {
12 | buffer = bufnr,
13 | command = "silent !npx prettier % --write",
14 | })
15 | end,
16 |
17 | settings = {
18 | codeAction = {
19 | disableRuleComment = {
20 | enable = true,
21 | location = "separateLine"
22 | },
23 | showDocumentation = {
24 | enable = true
25 | }
26 | },
27 | codeActionOnSave = {
28 | enable = false,
29 | mode = "all"
30 | },
31 | experimental = {
32 | useFlatConfig = false
33 | },
34 | format = true,
35 | nodePath = "",
36 | onIgnoredFiles = "off",
37 | problems = {
38 | shortenToSingleLine = false
39 | },
40 | quiet = false,
41 | rulesCustomizations = {},
42 | run = "onType",
43 | useESLintClass = false,
44 | validate = "on",
45 | workingDirectory = {
46 | mode = "location"
47 | }
48 | },
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/lua/colors.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/colors.lua @brief
3 | -- Change some of the highlight groups
4 | --
5 | -- @author Tanuharja, R.A.
6 | -- @date 2024-12-20
7 | --
8 |
9 |
10 | local group_styles = {
11 |
12 | ["Normal"] = { fg = "#CCCCCC", bg = "None" },
13 | ["NormalFloat"] = { fg = "#CCCCCC", bg = "None" },
14 |
15 | ["String"] = { fg = "#D6DFD4" },
16 | ["Comment"] = { fg = "#777777" },
17 |
18 | ["Identifier"] = { fg = "#DDDDDD", bold = true },
19 | ["Statement"] = { fg = "#EEEEEE", bold = true },
20 | ["Special"] = { fg = "#999ECF", bold = false },
21 |
22 | ["Function"] = { fg = "#999ECF" },
23 | ["Constant"] = { fg = "#CCCCCC" },
24 |
25 | ["DiffAdd"] = { fg = "NvimLightYellow" },
26 | ["DiffDelete"] = { fg = "#666666" },
27 | ["DiffText"] = { fg = "NvimLightYellow", bg = "None" },
28 | ["DiffChange"] = { fg = "None", bg = "None" },
29 |
30 | ["Changed"] = { fg = "#EEEEEE", bg = "None" },
31 |
32 | ["Error"] = { fg = "#FFFFFF", bg = "None", bold = true },
33 |
34 | ["QuickFixLine"] = { fg = "#CCCCCC", bold = true },
35 |
36 | ["Pmenu"] = { fg = "#DDDDDD", bg = "#222222" },
37 | ["PmenuSel"] = { fg = "#CCCCCC", bg = "#444444" },
38 |
39 | ["Question"] = { fg = "#666666" },
40 | ["Directory"] = { fg = "#777777" },
41 |
42 | ["MsgSeparator"] = { fg = "#EEEEEE", bg = "#444444" },
43 | ["MoreMsg"] = { fg = "#EEEEEE", bg = "#444444" },
44 |
45 | ["StatusLine"] = { fg = "#EEEEEE", bg = "#333333" },
46 |
47 | ["Folded"] = { fg = "#444444" },
48 | ["MatchParen"] = { fg = "#FFFFFF", bold = true },
49 | ["WinSeparator"] = { fg = "#444444" },
50 |
51 | ["Search"] = { fg = "#000000", bg = "#777777" },
52 | ["CurSearch"] = { fg = "#000000", bg = "#AAAAAA" },
53 |
54 | ["DiagnosticUnnecessary"] = { fg = "#888888" },
55 |
56 | ["Todo"] = { fg = "NvimLightYellow", bg = "None", bold = true },
57 |
58 | ["@variable"] = { fg = "#CCCCCC" },
59 | ["@string.documentation"] = { fg = "#777777" },
60 | ["@comment.warning"] = { fg = "#000000", bg = "NvimLightYellow", bold = true },
61 | ["@comment.error"] = { fg = "#000000", bg = "NvimLightRed", bold = true },
62 | ["@comment.note"] = { fg = "#000000", bg = "#D3EDE7", bold = true },
63 |
64 | ["LspSignatureActiveParameter"] = { bg = "None" },
65 |
66 | }
67 |
68 | for group, style in pairs(group_styles) do
69 | vim.api.nvim_set_hl(0, group, style)
70 | end
71 |
--------------------------------------------------------------------------------
/lua/diagnostics.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/diagnostics.lua
3 | --
4 | -- @brief
5 | -- Configure the behaviour of diagnostics
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-12-20
9 | --
10 |
11 |
12 | vim.diagnostic.config {
13 |
14 | virtual_text = false,
15 | severity_sort = true,
16 | update_in_insert = false,
17 |
18 | signs = {
19 |
20 | text = {
21 | [vim.diagnostic.severity.ERROR] = "",
22 | [vim.diagnostic.severity.WARN] = "",
23 | [vim.diagnostic.severity.HINT] = "",
24 | [vim.diagnostic.severity.INFO] = "",
25 | },
26 |
27 | linehl = {
28 | [vim.diagnostic.severity.ERROR] = "ErrorMsg",
29 | [vim.diagnostic.severity.WARN] = "None",
30 | [vim.diagnostic.severity.HINT] = "None",
31 | [vim.diagnostic.severity.INFO] = "None",
32 | },
33 |
34 | numhl = {
35 | [vim.diagnostic.severity.ERROR] = "ErrorMsg",
36 | [vim.diagnostic.severity.WARN] = "WarningMsg",
37 | [vim.diagnostic.severity.HINT] = "DiagnosticHint",
38 | [vim.diagnostic.severity.INFO] = "DiagnosticHint",
39 | },
40 |
41 | },
42 |
43 | float = {
44 | title = " Diagnostic ",
45 | header = "",
46 | border = "single",
47 | scope = "line",
48 | },
49 |
50 | }
51 |
52 | vim.opt["signcolumn"] = "yes"
53 |
54 | vim.keymap.set("n", "gl", vim.diagnostic.open_float)
55 | vim.keymap.set("n", "gq", vim.diagnostic.setqflist)
56 |
57 | -- removes underline
58 | vim.api.nvim_set_hl(0, "DiagnosticUnderlineError", { sp = "None" } )
59 | vim.api.nvim_set_hl(0, "DiagnosticUnderlineWarn", { sp = "None" } )
60 | vim.api.nvim_set_hl(0, "DiagnosticUnderlineHint", { sp = "None" } )
61 | vim.api.nvim_set_hl(0, "DiagnosticUnderlineInfo", { sp = "None" } )
62 |
--------------------------------------------------------------------------------
/lua/keymaps.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/keymaps.lua
3 | --
4 | -- @brief
5 | -- The file to set general keymaps
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-10-12
9 | --
10 |
11 |
12 | vim.g.mapleader = " "
13 | vim.g.maplocalleader = " "
14 |
15 | vim.keymap.set("", "", "", { desc = "space is only a leader key now" })
16 |
17 | local mode_keymaps = {
18 |
19 | normal = {
20 |
21 | ["x"] = { action = '"_x', desc = 'delete a character without storing it in the clipboard' },
22 |
23 | ["qq"] = { action = vim.cmd.quit, desc = "close the current window" },
24 | ["w"] = { action = vim.cmd.write, desc = "save changes in the current buffer" },
25 |
26 | [""] = { action = "h", desc = "move focus to the pane on the left" },
27 | [""] = { action = "j", desc = "move focus to the pane below" },
28 | [""] = { action = "k", desc = "move focus to the pane above" },
29 | [""] = { action = "l", desc = "move focus to the pane on the right" },
30 |
31 | [""] = { action = vim.cmd.bprev, desc = "switch to the prev buffer" },
32 | [""] = { action = vim.cmd.bnext, desc = "switch to the next buffer" },
33 |
34 | ["v"] = { action = vim.cmd.split, desc = "horizontal split" },
35 | ["h"] = { action = vim.cmd.vsplit, desc = "vertical split" },
36 |
37 | [""] = { action = "vertical resize -2", desc = "decrease rows in the current window" },
38 | [""] = { action = "vertical resize +2", desc = "increase rows in the current window" },
39 | [""] = { action = "horizontal resize -2", desc = "decrease columns in the current window" },
40 | [""] = { action = "horizontal resize +2", desc = "increase columns in the current window" },
41 |
42 | ["r"] = { action = "zR", desc = "unfold everything" },
43 | ["m"] = { action = "zM", desc = "fold everything" },
44 |
45 | [""] = { action = vim.cmd.nohlsearch, desc = "remove highlight from search results" },
46 |
47 | ["j"] = { action = vim.cmd.copen, desc = "open the quickfix list" },
48 | ["J"] = { action = vim.cmd.cclose, desc = "close the quickfix list" },
49 |
50 | ["qj"] = {
51 | action = function()
52 | local success = pcall(vim.cmd, "cnext")
53 | if not success then
54 | local _ = pcall(vim.cmd, "cfirst")
55 | end
56 | end,
57 | desc = "navigate to the next quickfix item"
58 | },
59 |
60 | ["qk"] = {
61 | action = function()
62 | local success = pcall(vim.cmd, "cprev")
63 | if not success then
64 | local _ = pcall(vim.cmd, "clast")
65 | end
66 | end,
67 | desc = "navigate to the prev quickfix item"
68 | },
69 |
70 | ["ql"] = {
71 | action = function()
72 | local _ = pcall(vim.cmd, "cnewer")
73 | end,
74 | desc = "navigate to the next quickfix list"
75 | },
76 |
77 | ["qh"] = {
78 | action = function()
79 | local _ = pcall(vim.cmd, "colder")
80 | end,
81 | desc = "navigate to the prev quickfix list"
82 | },
83 |
84 | ["sd"] = { action = 'call setqflist([], " ")', desc = "create an empty quickfix list" },
85 | ["sf"] = {
86 | action = function()
87 | local filename = vim.fn.expand("%")
88 | local line_number = vim.fn.line(".")
89 | local column_number = vim.fn.col(".")
90 | local line_text = vim.fn.getline(".")
91 |
92 | local entry = {
93 | filename = filename,
94 | lnum = line_number,
95 | col = column_number,
96 | text = line_text,
97 | }
98 |
99 | vim.fn.setqflist( {entry}, "a" )
100 | end,
101 | desc = "add a line into the current quickfix list"
102 | },
103 |
104 | },
105 |
106 | visual = {
107 |
108 | ["H"] = { action = "i"] = { action = ":s/\\(\\s*\\)/\\1", desc = "spawn multiple cursors at the start of highlighted lines" },
114 | ["a"] = { action = ":s/$/", desc = "spawn multiple cursors at the end of highlighted lines" },
115 |
116 | ['"'] = { action = 'c""P', desc = "put highlighted text inside pairing chars" },
117 | ["["] = { action = "c[]P", desc = "put highlighted text inside pairing chars" },
118 | ["("] = { action = "c()P", desc = "put highlighted text inside pairing chars" },
119 | ["{"] = { action = "c{}P", desc = "put highlighted text inside pairing chars" },
120 | ["'"] = { action = "c''P", desc = "put highlighted text inside pairing chars" },
121 | ["`"] = { action = "c``P", desc = "put highlighted text inside pairing chars" },
122 |
123 | },
124 |
125 | }
126 |
127 | for mode, keymaps in pairs(mode_keymaps) do
128 |
129 | local mode_initial = mode:sub(1, 1)
130 |
131 | for key, maps in pairs(keymaps) do
132 | vim.keymap.set( mode_initial, key, maps.action, { noremap = true, silent = true, desc = maps.desc } )
133 | end
134 |
135 | end
136 |
--------------------------------------------------------------------------------
/lua/lsp.lua:
--------------------------------------------------------------------------------
1 | servers = {
2 | "clangd",
3 | "pyright",
4 | "ruff",
5 | "texlab",
6 | "typescript-language-server",
7 | "vscode-eslint-language-server",
8 | }
9 |
10 | for _, server in pairs(servers) do
11 | if vim.fn.executable(server) == 1 then
12 | vim.lsp.enable(server)
13 | end
14 | end
15 |
16 | local function refresh()
17 |
18 | vim.lsp.stop_client(vim.lsp.get_clients(), true)
19 |
20 | vim.defer_fn(
21 | function()
22 | local window_buffer_map = {}
23 | for _, window_id in pairs(vim.api.nvim_tabpage_list_wins(0)) do
24 | local buffer_id = vim.api.nvim_win_get_buf(window_id)
25 | table.insert(window_buffer_map, { window_id = window_id, buffer_id = buffer_id})
26 | end
27 |
28 | if #window_buffer_map > 0 then
29 | vim.cmd("bufdo if &modifiable | write | edit | endif")
30 | end
31 |
32 | for _, entry in pairs(window_buffer_map) do
33 | vim.api.nvim_win_set_buf(entry.window_id, entry.buffer_id)
34 | end
35 | end,
36 | 100
37 | )
38 |
39 | end
40 |
41 | vim.keymap.set("n", "gn", refresh)
42 |
43 | vim.lsp.config( "*", {
44 |
45 | on_init = function(client)
46 | client.offset_encoding = "utf-8"
47 | end,
48 |
49 | on_attach = function(client, buffer)
50 |
51 | vim.bo[buffer].formatexpr = "v:lua.vim.lsp.formatexpr"
52 |
53 | if client.name == 'ruff' then
54 | client.server_capabilities.hoverProvider = false
55 | end
56 |
57 | if client:supports_method("textDocument/formatting") then
58 |
59 | vim.api.nvim_create_autocmd("BufWritePre", {
60 | buffer = buffer,
61 | callback = function()
62 | vim.lsp.buf.format({ buffer = buffer, id = client.id })
63 | end,
64 | })
65 |
66 | end
67 |
68 | end,
69 | })
70 |
71 | vim.api.nvim_create_autocmd("FileType", {
72 | pattern = "markdown",
73 | callback = function()
74 |
75 | local query = [[
76 | (backslash_escape) @escape
77 | ]]
78 |
79 | vim.treesitter.query.set("markdown_inline", "conceal_backslash", query)
80 |
81 | local function conceal_backslash()
82 | local bufnr = vim.api.nvim_get_current_buf()
83 | local parser = vim.treesitter.get_parser(bufnr, "markdown_inline")
84 | local tree = parser:parse()[1]
85 | local query_obj = vim.treesitter.query.get("markdown_inline", "conceal_backslash")
86 |
87 | for _, node in query_obj:iter_captures(tree:root(), bufnr, 0, -1) do
88 | local start_row, start_col, end_row, end_col = node:range()
89 | vim.api.nvim_buf_set_extmark(
90 | bufnr, vim.api.nvim_create_namespace("conceal"), start_row, start_col, {
91 | end_col = start_col + 1,
92 | conceal = '',
93 | }
94 | )
95 | end
96 | end
97 |
98 | vim.api.nvim_buf_attach(0, false, {
99 | on_lines = function()
100 | vim.schedule(conceal_backslash)
101 | end,
102 | })
103 | conceal_backslash()
104 | end,
105 | })
106 |
107 | vim.api.nvim_set_hl(0, "@string.escape.markdown_inline", { link = "@spell"})
108 |
--------------------------------------------------------------------------------
/lua/options.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/options.lua
3 | --
4 | -- @brief
5 | -- The file to set general Neovim behaviours
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-10-12
9 | --
10 |
11 |
12 | local options = {
13 |
14 | -- user interface
15 |
16 | termguicolors = true, -- enable 24-bit RGB color
17 | mouse = "", -- disable mouse in neovim
18 | clipboard = "unnamedplus", -- makes neovim use the system clipboard
19 | winborder = "single", -- all floating window has a single border
20 | cursorline = true, -- highlight the row where the cursor is
21 | showtabline = 0, -- hide tabline
22 | inccommand = "split", -- when performing substitution, show preview at the bottom
23 | timeoutlen = 300, -- time for user to finish a key combination
24 | updatetime = 200, -- faster completion
25 | virtualedit = "block", -- enable highlighting empty spaces
26 | splitbelow = true, -- when splitting horizontally, new window goes below
27 | splitright = true, -- when splitting vertically, new window goes to the right
28 | showmode = false, -- mode will be shown by statusline instead
29 | cmdheight = 0, -- hide the command line when not typing command
30 | path = ".,,**", -- find-like operations works recursively
31 |
32 | -- tabs and indentations
33 |
34 | expandtab = true, -- convert tabs into spaces
35 | shiftwidth = 2, -- the number of spaces for each indentation
36 | tabstop = 2, -- the number of spaces for each tab
37 |
38 | -- number columns
39 |
40 | relativenumber = false, -- don't display relative line numbers
41 | number = true, -- display the current line number
42 | numberwidth = 3, -- the column width to display line numbers
43 |
44 | -- text display
45 |
46 | foldlevelstart = 99, -- open files with all folds open
47 | foldtext = "", -- keep the first line of folded section visible
48 | foldmethod = "expr", -- assign fold based on expressions
49 |
50 | foldexpr = "nvim_treesitter#foldexpr()",
51 |
52 | wrap = false, -- do not wrap lines because it looks ugly and inconsistent
53 | smartindent = true, -- automatic indentations
54 | scrolloff = 99, -- keep cursorline in the middle
55 | sidescrolloff = 6, -- minimul number of columns to the left and right of cursor
56 |
57 | fillchars = {
58 | eob = " ", -- removes annoying tilde at the bottom of short files
59 | fold = "-", -- replace dots with horizontal line to indicate folded sections
60 | stl = "-", -- fill empty spaces in the statusline with this
61 | },
62 |
63 | pumheight = 8, -- specify the max height of pop-up menu
64 | pumwidth = 20, -- specify the min width of pop-up menu
65 | pumblend = 15, -- semi transparent pop-up menu
66 |
67 | -- text search
68 |
69 | ignorecase = true, -- make search case-insensitive
70 | smartcase = true, -- but if our search contains uppercase(s), it becomes case-sensitive
71 |
72 | -- miscellaneous
73 |
74 | backup = false, -- do not create a backup file
75 | swapfile = false, -- do not create a swap file
76 | undofile = false, -- undo is limited to the current session
77 | fileencoding = "utf-8", -- the encoding written to a file
78 |
79 | }
80 |
81 | for parameter, value in pairs(options) do
82 | vim.opt[parameter] = value
83 | end
84 |
--------------------------------------------------------------------------------
/lua/plugins/autopairs.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/autopairs.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin autopairs
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | return {
13 |
14 | "windwp/nvim-autopairs",
15 |
16 | event = "InsertEnter",
17 |
18 | opts = {
19 |
20 | check_ts = true,
21 |
22 | ts_config = {
23 | lua = { "string" },
24 | python = { "string" },
25 | },
26 |
27 | disable_filetype = { "TelescopePrompt", "spectre_panel" },
28 |
29 | fast_wrap = {
30 | map = "",
31 | chars = { "{", "[", "(", '"', "'" },
32 | pattern = [=[[%'%"%>%]%)%}%,]]=],
33 | offset = 0,
34 | end_key = "k",
35 | keys = "qwertyuiopzxcvbnmasdfghjkl",
36 | check_comma = true,
37 | highlight = "PmenuSel",
38 | highlight_grey = "LineNr",
39 | },
40 |
41 | },
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/lua/plugins/bbye.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/bbye.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin bbye
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | return {
13 |
14 | "moll/vim-bbye",
15 |
16 | event = "UIEnter",
17 |
18 | config = function()
19 | vim.keymap.set("n", "c", "Bdelete!")
20 | vim.keymap.set("n", "n", "bufdo :Bdelete!")
21 | end
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/lua/plugins/blankline.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/blankline.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin blankline
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | return {
13 |
14 | "lukas-reineke/indent-blankline.nvim",
15 |
16 | ft = { "python", "lua", "typescript", "typescriptreact" },
17 |
18 | config = function()
19 |
20 | local success, blankline = pcall(require, "ibl")
21 | if not success then
22 | vim.notify("Failed to load plugin: blankline")
23 | return
24 | end
25 |
26 | blankline.setup {
27 |
28 | indent = {char = "│"},
29 | exclude = {
30 | filetypes = { "tex", "plaintex", "bib" },
31 | },
32 |
33 | scope = {
34 | enabled = true,
35 | show_start = false,
36 | show_end = true,
37 | },
38 |
39 | }
40 |
41 | end,
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/lua/plugins/blink.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/blink.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin blink
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-11-02
9 | --
10 |
11 |
12 | return {
13 |
14 | "saghen/blink.cmp",
15 |
16 | event = "UIEnter",
17 |
18 | version = "1.*",
19 |
20 | opts = {
21 |
22 | keymap = {
23 |
24 | [""] = { "accept", "fallback" },
25 | [""] = { "show", "show_documentation", "hide_documentation" },
26 |
27 | [""] = { "select_prev", "fallback" },
28 | [""] = { "select_next", "fallback" },
29 |
30 | [""] = { "snippet_forward", "fallback" },
31 | [""] = { "snippet_backward", "fallback" },
32 |
33 | },
34 |
35 | completion = {
36 |
37 | accept = {
38 | auto_brackets = { enabled = false },
39 | },
40 |
41 | documentation = {
42 |
43 | auto_show = false,
44 |
45 | window = {
46 |
47 | min_width = 10,
48 | max_width = 60,
49 | max_height = 20,
50 | border = "single",
51 | scrollbar = false,
52 |
53 | winhighlight = "Normal:NormalFloat,FloatBorder:FloatBorder,Search:None,Pmenu:Normal",
54 |
55 | direction_priority = {
56 | menu_north = { "e", "w", "n", "s" },
57 | menu_south = { "e", "w", "s", "n" },
58 | }
59 |
60 | },
61 |
62 |
63 | },
64 |
65 | ghost_text = {
66 | enabled = false,
67 | },
68 |
69 | keyword = {
70 | range = "full"
71 | },
72 |
73 | list = {
74 | selection = {
75 | preselect = true,
76 | auto_insert = true,
77 | },
78 | },
79 |
80 | menu = {
81 |
82 | auto_show = true,
83 | min_width = 15,
84 | max_height = 10,
85 | border = "single",
86 |
87 | scrollbar = false,
88 |
89 | winhighlight = "Normal:NormalFloat,FloatBorder:FloatBorder,Search:None,Pmenu:Normal",
90 |
91 | direction_priority = { "s", "n" },
92 |
93 | draw = {
94 | columns = {
95 | { "label", "kind", gap = 1 },
96 | },
97 | },
98 |
99 | },
100 |
101 | },
102 |
103 | sources = {
104 |
105 | default = {
106 | "snippets",
107 | "lsp",
108 | "path",
109 | "buffer",
110 | },
111 |
112 | providers = {
113 |
114 | lsp = {
115 |
116 | name = "LSP",
117 | module = "blink.cmp.sources.lsp",
118 |
119 | enabled = true,
120 | transform_items = nil,
121 | should_show_items = true,
122 | max_items = nil,
123 | min_keyword_length = 0,
124 | fallbacks = { "buffer", "path", },
125 | score_offset = 0,
126 | override = nil,
127 |
128 | },
129 |
130 | path = {
131 |
132 | name = "Path",
133 | module = "blink.cmp.sources.path",
134 | min_keyword_length = 2,
135 | score_offset = 0,
136 |
137 | opts = {
138 | trailing_slash = false,
139 | label_trailing_slash = true,
140 | get_cwd = function(context) return vim.fn.expand( ("#%d:p:h"):format(context.bufnr) ) end,
141 | show_hidden_files_by_default = false,
142 | }
143 |
144 | },
145 |
146 | snippets = {
147 |
148 | name = "Snippets",
149 | module = "blink.cmp.sources.snippets",
150 | min_keyword_length = 2,
151 | score_offset = 3,
152 |
153 | opts = {
154 | friendly_snippets = true,
155 | search_paths = { vim.fn.stdpath("config") .. "/snippets" },
156 | global_snippets = { "all" },
157 | extended_filetypes = {},
158 | ignored_filetypes = {},
159 | }
160 |
161 | },
162 |
163 | buffer = {
164 |
165 | name = "Buffer",
166 | module = "blink.cmp.sources.buffer",
167 | min_keyword_length = 5,
168 |
169 | },
170 | },
171 |
172 | },
173 |
174 | fuzzy = {
175 |
176 | implementation = "prefer_rust_with_warning",
177 |
178 | use_frecency = true,
179 | use_proximity = false,
180 |
181 | sorts = {
182 | "exact",
183 | "score",
184 | "sort_text"
185 | },
186 |
187 | prebuilt_binaries = {
188 | download = true,
189 | },
190 |
191 |
192 | },
193 |
194 |
195 | },
196 |
197 | }
198 |
--------------------------------------------------------------------------------
/lua/plugins/gitsigns.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/gitsigns.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin gitsigns
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | return {
13 |
14 | "lewis6991/gitsigns.nvim",
15 |
16 | event = "UIEnter",
17 |
18 | config = function()
19 |
20 | local success, gitsigns = pcall(require, "gitsigns")
21 | if not success then
22 | vim.notify("Error loading plugin: gitsigns")
23 | return
24 | end
25 |
26 | gitsigns.setup {
27 |
28 | signs = {
29 | add = {text = "+"},
30 | change = {text = "*"},
31 | delete = {text = "-"},
32 | topdelete = {text = "-"},
33 | changedelete = {text = "*"},
34 | },
35 |
36 | signcolumn = true,
37 | numhl = false,
38 | linehl = false,
39 | word_diff = false,
40 |
41 | watch_gitdir = {
42 | interval = 1000,
43 | follow_files = true,
44 | },
45 |
46 | attach_to_untracked = true,
47 | current_line_blame = false,
48 |
49 | current_line_blame_opts = {
50 | virt_text = true,
51 | virt_text_pos = "eol",
52 | delay = 1000,
53 | ignore_whitespace = true,
54 | },
55 |
56 | sign_priority = 6,
57 | update_debounce = 100,
58 | status_formatter = nil,
59 | max_file_length = 10000,
60 |
61 | preview_config = {
62 | border = "single",
63 | style = "minimal",
64 | relative = "cursor",
65 | row = 0,
66 | col = 1,
67 | },
68 |
69 | }
70 |
71 | vim.keymap.set("n", "k", gitsigns.preview_hunk)
72 | vim.keymap.set("n", "u", gitsigns.reset_hunk)
73 | vim.keymap.set("n", "x", gitsigns.diffthis)
74 | vim.keymap.set("n", "z", "wincmd p | q")
75 |
76 | vim.keymap.set("n", "", gitsigns.stage_hunk)
77 | vim.keymap.set("n", "", gitsigns.stage_buffer)
78 | vim.keymap.set("n", "", gitsigns.blame_line)
79 |
80 | vim.keymap.set("n", "gnh", function() gitsigns.nav_hunk("next") end)
81 | vim.keymap.set("n", "gph", function() gitsigns.nav_hunk("prev") end)
82 |
83 | vim.api.nvim_set_hl(0, "GitSignsAddInline", { fg = "#EEEEEE", bg = "#444444" })
84 | vim.api.nvim_set_hl(0, "GitSignsDeleteInline", { fg = "#AAAAAA", bg = "#333333" })
85 | vim.api.nvim_set_hl(0, "GitSignsStagedAdd", { fg = "#AAAAAA" })
86 | vim.api.nvim_set_hl(0, "GitSignsStagedChange", { fg = "#AAAAAA" })
87 | vim.api.nvim_set_hl(0, "GitSignsStagedChangeDelete", { fg = "#AAAAAA" })
88 |
89 | end
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/lua/plugins/init.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/init.lua
3 | --
4 | -- @brief
5 | -- The initialization file to load external plugins
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
13 |
14 | -- install lazy from github repository if it is not installed
15 | if not (vim.uv or vim.loop).fs_stat(lazypath) then
16 |
17 | -- github repository for lazy
18 | local lazyrepo = "https://github.com/folke/lazy.nvim.git"
19 |
20 | -- command to clone repository
21 | local out = vim.fn.system({
22 | "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath
23 | })
24 |
25 | if vim.v.shell_error ~= 0 then
26 | vim.api.nvim_echo({
27 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
28 | { out, "WarningMsg" },
29 | { "\nPress any key to exit..." },
30 | }, true, {})
31 | vim.fn.getchar()
32 | os.exit(1)
33 | end
34 |
35 | end
36 |
37 | vim.opt.rtp:prepend(lazypath)
38 |
39 | -- use protected call to load lazy
40 | local success, lazy = pcall(require, "lazy")
41 | if not success then
42 | vim.notify("Failed to load plugin: lazy")
43 | return
44 | end
45 |
46 | -- all plugin settings are in this directory
47 | local location = "plugins."
48 |
49 | -- specify manually the plugins to load
50 | lazy.setup {
51 |
52 | dev = {
53 | path = "~/.config/nvim/projects",
54 | fallback = false,
55 | },
56 |
57 | lockfile = nil,
58 |
59 | rocks = {
60 | enabled = false,
61 | hererocks = false,
62 | },
63 |
64 | ui = {
65 | border = "single",
66 | icons = {
67 | cmd = "",
68 | config = "",
69 | event = "",
70 | favorite = "",
71 | ft = "",
72 | init = "",
73 | import = "",
74 | keys = "",
75 | lazy = "",
76 | loaded = "●",
77 | not_loaded = "○",
78 | plugin = "",
79 | runtime = "",
80 | require = "",
81 | source = "",
82 | start = "",
83 | task = "✔ ",
84 | list = {
85 | "●",
86 | "➜",
87 | "★",
88 | "‒",
89 | },
90 | },
91 | },
92 |
93 | change_detection = {
94 | enabled = false,
95 | notify = false,
96 | },
97 |
98 | performance = {
99 |
100 | cache = {
101 | enabled = true,
102 | },
103 |
104 | reset_packpath = true,
105 |
106 | rtp = {
107 | reset = true,
108 | disabled_plugins = {
109 | "editorconfig",
110 | "gzip",
111 | "man",
112 | "netrwPlugin",
113 | "spellfile",
114 | "tarPlugin",
115 | "tohtml",
116 | "tutor",
117 | "zipPlugin",
118 | },
119 | },
120 |
121 | },
122 |
123 | spec = {
124 |
125 | { import = location .. "blink" },
126 | { import = location .. "gitsigns" },
127 | { import = location .. "autopairs" },
128 | { import = location .. "treesitter" },
129 | { import = location .. "bbye" },
130 | { import = location .. "blankline" },
131 | { import = location .. "nvim-tree" },
132 | { import = location .. "nvim-dap" },
133 | { import = location .. "vimtex" },
134 |
135 | { import = location .. "terminal" },
136 |
137 | { import = location .. "molten" },
138 | { import = location .. "otter" },
139 |
140 | },
141 |
142 | install = { colorscheme = { "default" } },
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/lua/plugins/molten.lua:
--------------------------------------------------------------------------------
1 | return {
2 | "benlubas/molten-nvim",
3 | version = "^1.0.0",
4 |
5 | ft = {"python", "quarto"},
6 |
7 | dependencies = {
8 |
9 | "3rd/image.nvim",
10 |
11 | opts = {
12 | backend = "kitty",
13 | integrations = {},
14 | max_width = 100,
15 | max_height = 40,
16 | max_height_window_percentage = math.huge,
17 | max_width_window_percentage = math.huge,
18 | window_overlap_clear_enabled = false,
19 | window_overlap_clear_ft_ignore = {},
20 | },
21 |
22 | },
23 |
24 | build = ":UpdateRemotePlugins",
25 |
26 | init = function()
27 | vim.g.molten_image_provider = "image.nvim"
28 | vim.g.molten_output_win_max_height = 40
29 | vim.g.molten_use_border = true
30 | vim.g.molten_auto_open_output = false
31 | vim.g.molten_image_location = "float"
32 | vim.g.molten_tick_rate = 200
33 | end,
34 |
35 | config = function()
36 |
37 | vim.keymap.set("n", "ai", "MoltenInit", { noremap = true, silent = true, desc = "initialize molten"})
38 |
39 | local run_block = function()
40 | local node = vim.treesitter.get_node()
41 | local start_row, _, end_row, _ = vim.treesitter.get_node_range(node)
42 | vim.fn.MoltenEvaluateRange(start_row + 1, end_row)
43 | end
44 |
45 | vim.api.nvim_create_autocmd("User", {
46 | pattern = "MoltenInitPost",
47 | callback = function(arg)
48 |
49 | vim.opt_local.colorcolumn="80"
50 |
51 | vim.keymap.set("n", "ar", run_block, { buffer = arg.buf, desc = "reevaluate the current block"})
52 |
53 | vim.keymap.set("n", "am", "MoltenReevaluateCell", { buffer = arg.buf, desc = "rerun cell"})
54 | vim.keymap.set("v", "am", ":MoltenEvaluateVisual", { buffer = arg.buf, desc = "run highlighted code"})
55 |
56 | vim.keymap.set("n", "ao", "MoltenShowOutput", { buffer = arg.buf, desc = "show outputs from the current cell"})
57 | vim.keymap.set("n", "ah", "MoltenHideOutput", { buffer = arg.buf, desc = "hide outputs from the current cell"})
58 | vim.keymap.set("n", "al", "MoltenEvaluateLine", { buffer = arg.buf, desc = "evaluate the current line"})
59 | vim.keymap.set("n", "an", "MoltenNext", { buffer = arg.buf, desc = "move to the next cell"})
60 | vim.keymap.set("n", "ap", "MoltenPrev", { buffer = arg.buf, desc = "move to the prev cell"})
61 | vim.keymap.set("n", "aa", "MoltenReevaluateAll", { buffer = arg.buf, desc = "reevaluate all cells"})
62 | vim.keymap.set("n", "ae", ":noautocmd MoltenEnterOutput", { buffer = arg.buf, desc = "enter the output window"})
63 | vim.keymap.set("n", "af", "MoltenImagePopup", { buffer = arg.buf, desc = "open image in a new window"})
64 | vim.keymap.set("n", "as", "MoltenDeinit", { buffer = arg.buf, desc = "stop molten"})
65 |
66 | vim.keymap.set(
67 | "n",
68 | "ad",
69 | function()
70 | vim.cmd("MoltenEvaluateArgument import debugpy")
71 | vim.cmd("MoltenEvaluateArgument _ = debugpy.listen(('localhost', 5678))")
72 | end,
73 | { buffer = arg.buf, desc = "initialize debugger"}
74 | )
75 |
76 | vim.keymap.set("n", "dd", "MoltenEvaluateArgument debugpy.breakpoint()", { buffer = arg.buf, desc = "enter virtual breakpoint"})
77 |
78 | end,
79 | })
80 |
81 | vim.api.nvim_create_autocmd("User", {
82 | pattern = "MoltenDeinitPost",
83 | callback = function(arg)
84 |
85 | vim.opt_local.colorcolumn=""
86 |
87 | vim.keymap.del("n", "ar", { buffer = arg.buf })
88 |
89 | vim.keymap.del("n", "am", { buffer = arg.buf })
90 | vim.keymap.del("v", "am", { buffer = arg.buf })
91 |
92 | vim.keymap.del("n", "ao", { buffer = arg.buf })
93 | vim.keymap.del("n", "ah", { buffer = arg.buf })
94 | vim.keymap.del("n", "al", { buffer = arg.buf })
95 | vim.keymap.del("n", "an", { buffer = arg.buf })
96 | vim.keymap.del("n", "ap", { buffer = arg.buf })
97 | vim.keymap.del("n", "aa", { buffer = arg.buf })
98 | vim.keymap.del("n", "ae", { buffer = arg.buf })
99 | vim.keymap.del("n", "af", { buffer = arg.buf })
100 | vim.keymap.del("n", "as", { buffer = arg.buf })
101 |
102 | vim.keymap.del("n", "ad", { buffer = arg.buf })
103 | vim.keymap.del("n", "dd", { buffer = arg.buf })
104 |
105 | end,
106 | })
107 |
108 | end,
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/lua/plugins/nvim-dap.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/nvim-dap.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin nvim-dap
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-10-13
9 | --
10 |
11 |
12 | return {
13 |
14 | "mfussenegger/nvim-dap",
15 |
16 | ft = {"python", "c", "cpp"},
17 |
18 | config = function()
19 |
20 | local dap = require("dap")
21 |
22 | dap.adapters.python = function(callback, config)
23 |
24 | if config.request == "launch" then
25 |
26 | callback({
27 | type = "executable",
28 | command = "python3",
29 | args = { "-m", "debugpy.adapter" },
30 | })
31 |
32 | elseif config.request == "attach" then
33 |
34 | local port = config.connect.port
35 | local host = config.connect.host
36 |
37 | callback({
38 | type = "server",
39 | port = port,
40 | host = host,
41 | options = {
42 | source_filetype = "python"
43 | }
44 | })
45 |
46 | end
47 |
48 | end
49 |
50 | dap.configurations.python = {
51 |
52 | {
53 | type = "python",
54 | request = "launch",
55 | name = "Launch a debugging session",
56 | program = "${file}",
57 | pythonPath = function()
58 | return "python3"
59 | end,
60 | console = "integratedTerminal",
61 | },
62 |
63 | {
64 | type = "python",
65 | request = "attach",
66 | name = "Attach a debugging session",
67 | connect = function()
68 | local host = vim.fn.input("Host: ")
69 | local port = tonumber(vim.fn.input("Port: "))
70 | return {host = host, port = port}
71 | end,
72 | console = "integratedTerminal",
73 | },
74 |
75 | {
76 | type = "python",
77 | request = "launch",
78 | name = "Launch a debugging session with arguments",
79 | program = "${file}",
80 | args = function()
81 | local args_string = vim.fn.input("Arguments: ")
82 | local utils = require("dap.utils")
83 | if utils.splitstr and vim.fn.has("nvim-0.10") == 1 then
84 | return utils.splitstr(args_string)
85 | end
86 | return vim.split(args_string, " +")
87 | end,
88 | pythonPath = function()
89 | return "python3"
90 | end,
91 | console = "integratedTerminal",
92 | },
93 |
94 | }
95 |
96 | dap.configurations.quarto = {
97 | {
98 | type = "python",
99 | request = "attach",
100 | name = "Attach a debugging session",
101 | connect = {
102 | host = "127.0.0.1",
103 | port = "5678"
104 | },
105 | console = "integratedTerminal",
106 | },
107 | }
108 |
109 | dap.adapters.cpp = {
110 | type = "executable",
111 | command = "lldb-dap",
112 | name = "lldb",
113 | }
114 |
115 | dap.configurations.cpp = {
116 | {
117 | name = "Launch LLDB",
118 | type = "cpp",
119 | request = "launch",
120 | program = function()
121 | return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file")
122 | end,
123 | cwd = '${workspaceFolder}',
124 | stopOnEntry = false,
125 | args = {},
126 | runInTerminal = false,
127 | }
128 | }
129 |
130 | vim.fn.sign_define(
131 | "DapBreakpoint", {
132 | text = "--",
133 | texthl = "DiagnosticError",
134 | numhl = ""
135 | }
136 | )
137 |
138 | vim.fn.sign_define(
139 | "DapStopped", {
140 | text = "->",
141 | texthl = "DiagnosticHint",
142 | numhl = ""
143 | }
144 | )
145 |
146 | -- configure widgets
147 |
148 | local widgets = require("dap.ui.widgets")
149 |
150 | -- set scopes as right pane
151 | local scopes = widgets.sidebar(widgets.scopes, {}, "vsplit")
152 |
153 | -- set frames as bottom pane
154 | local frames = widgets.sidebar(widgets.frames, {height = 10}, "belowright split")
155 |
156 | vim.keymap.set("n", "dj", dap.continue)
157 | vim.keymap.set("n", "dm", dap.step_over)
158 | vim.keymap.set("n", "di", dap.step_into)
159 | vim.keymap.set("n", "dk", dap.toggle_breakpoint)
160 | vim.keymap.set("n", "dn", dap.clear_breakpoints)
161 | vim.keymap.set("n", "dt", dap.terminate)
162 |
163 | local repl = require("dap.repl")
164 |
165 | vim.keymap.set(
166 | "n", "da",
167 | function()
168 | return repl.toggle({}, "belowright split")
169 | end
170 | )
171 |
172 | vim.keymap.set("n", "ds", scopes.toggle)
173 | vim.keymap.set("n", "du", frames.toggle)
174 | vim.keymap.set("n", "dh", widgets.hover)
175 |
176 | end
177 |
178 | }
179 |
--------------------------------------------------------------------------------
/lua/plugins/nvim-tree.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/nvim-tree.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin nvim-tree
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | return {
13 |
14 | "kyazdani42/nvim-tree.lua",
15 |
16 | keys = {
17 | { "ee", "NvimTreeToggle" },
18 | { "eo", "NvimTreeFindFile" },
19 | },
20 |
21 | config = function()
22 |
23 | local success, nvim_tree = pcall(require, "nvim-tree")
24 | if not success then
25 | vim.notify("Failed to load plugin: nvim-tree")
26 | return
27 | end
28 |
29 | nvim_tree.setup {
30 |
31 | update_focused_file = {
32 | enable = false,
33 | update_cwd = false,
34 | },
35 |
36 | renderer = {
37 |
38 | root_folder_modifier = ":t",
39 |
40 | icons = {
41 |
42 | diagnostics_placement = "signcolumn",
43 | git_placement = "after",
44 |
45 | glyphs = {
46 |
47 | default = "x",
48 | symlink = "s",
49 |
50 | folder = {
51 | arrow_open = "",
52 | arrow_closed = "",
53 | default = "[x]",
54 | open = "]x[",
55 | empty = "[ ]",
56 | empty_open = "] [",
57 | symlink = "[s]",
58 | symlink_open = "]s[",
59 | },
60 |
61 | git = {
62 | unstaged = "*",
63 | staged = "",
64 | deleted = "",
65 | unmerged = "",
66 | renamed = "",
67 | untracked = "",
68 | ignored = "",
69 | },
70 |
71 | },
72 |
73 | },
74 |
75 | },
76 |
77 | diagnostics = {
78 |
79 | enable = true,
80 | show_on_dirs = true,
81 | show_on_open_dirs = false,
82 |
83 | icons = {
84 | hint = "?",
85 | info = "*",
86 | warning = "!",
87 | error = "!",
88 | },
89 |
90 | },
91 |
92 | git = {
93 |
94 | enable = false,
95 | show_on_dirs = false,
96 | show_on_open_dirs = false,
97 |
98 | },
99 |
100 | -- adjust the window size
101 | view = {
102 | width = 32,
103 | side = "left",
104 | },
105 |
106 | -- do not show hidden files
107 | filters = {
108 | dotfiles = true,
109 | custom = { ".*cache.*" },
110 | },
111 |
112 | }
113 |
114 | vim.api.nvim_set_hl(0, "NvimTreeFolderIcon", { fg = "#777777"})
115 |
116 |
117 | local api = require("nvim-tree.api")
118 |
119 | vim.keymap.set(
120 | "n", "er",
121 | function()
122 | api.tree.collapse_all()
123 | end,
124 | { desc = "collapse all node on the file tree" }
125 | )
126 |
127 | vim.keymap.set(
128 | "n", "et",
129 | function()
130 | local node = api.tree.get_node_under_cursor()
131 | vim.cmd("argadd " .. node.absolute_path)
132 | end,
133 | { desc = "add file under cursor to the arglist, to open multi files" }
134 | )
135 |
136 | end,
137 | }
138 |
--------------------------------------------------------------------------------
/lua/plugins/otter.lua:
--------------------------------------------------------------------------------
1 | local convert_to_normal_script = function()
2 |
3 | local filename = "temp.py"
4 |
5 | local query = vim.treesitter.query.parse('markdown', [[
6 | ((code_fence_content) @code)
7 | ]])
8 |
9 | local parser = vim.treesitter.get_parser(0, "markdown")
10 | local tree = parser:parse()[1]
11 | local root = tree:root()
12 |
13 | local lines = {}
14 |
15 | for _, node in query:iter_captures(root, 0) do
16 |
17 | local text = vim.treesitter.get_node_text(node, 0)
18 |
19 | for _, line in ipairs(vim.fn.split(text, '\n')) do
20 | table.insert(lines, line)
21 | end
22 |
23 | end
24 |
25 | local file = io.open(filename, "w")
26 |
27 | for _, line in ipairs(lines) do
28 | file:write(line .. "\n")
29 | end
30 |
31 | file:close()
32 |
33 | vim.cmd("edit " .. filename)
34 |
35 | end
36 |
37 | local move_imports_to_top = function()
38 | local bufnr = 0
39 | local root = vim.treesitter.get_parser(bufnr, "python"):parse()[1]:root()
40 |
41 | local query = vim.treesitter.query.parse("python", [[
42 | (import_statement) @imp
43 | (import_from_statement) @imp
44 | ]])
45 |
46 | local import_nodes = {}
47 | for _, node in query:iter_captures(root, bufnr) do
48 | table.insert(import_nodes, node)
49 | end
50 |
51 | table.sort(import_nodes, function(a,b) return a:start() < b:start() end)
52 |
53 | local lines_to_remove = {}
54 | local import_texts = {}
55 |
56 | for _, node in ipairs(import_nodes) do
57 | local s, _, e, _ = node:range()
58 | for i = s, e do lines_to_remove[i] = true end
59 | table.insert(import_texts, vim.treesitter.get_node_text(node, bufnr))
60 | end
61 |
62 | local buf_lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
63 | for i = #buf_lines - 1, 0, -1 do
64 | if lines_to_remove[i] then table.remove(buf_lines, i + 1) end
65 | end
66 |
67 | local imports_lines = {}
68 | for _, text in ipairs(import_texts) do
69 | for line in text:gmatch("[^\r\n]+") do
70 | table.insert(imports_lines, line)
71 | end
72 | end
73 | table.insert(imports_lines, "")
74 |
75 | for i = #imports_lines, 1, -1 do
76 | table.insert(buf_lines, 1, imports_lines[i])
77 | end
78 |
79 | vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, buf_lines)
80 | end
81 |
82 |
83 | return {
84 |
85 | 'jmbuhr/otter.nvim',
86 |
87 | ft = { "markdown", "quarto" },
88 |
89 | dependencies = {
90 | 'nvim-treesitter/nvim-treesitter',
91 | },
92 |
93 | config = function()
94 |
95 | local success, otter = pcall(require, "otter")
96 | if not success then
97 | vim.notify("Error loading plugin: otter")
98 | return
99 | end
100 |
101 |
102 | otter.setup{
103 |
104 | lsp = {
105 | diagnostic_update_events = { "InsertLeave", "TextChanged" },
106 | root_dir = function(_, bufnr)
107 | return vim.fs.root(bufnr or 0, {
108 | ".git",
109 | "_quarto.yml",
110 | "package.json",
111 | }) or vim.fn.getcwd(0)
112 | end,
113 | },
114 |
115 | buffers = {
116 | set_filetype = true,
117 | write_to_disk = false,
118 | preambles = {},
119 | postambles = {},
120 | ignore_pattern = {
121 | python = "^(%s*[%%!].*)",
122 | },
123 | },
124 |
125 | strip_wrapping_quote_characters = { "'", '"', "`" },
126 | handle_leading_whitespace = true,
127 | extensions = {},
128 | debug = false,
129 |
130 | verbose = {
131 | no_code_found = false
132 | },
133 | }
134 |
135 | vim.api.nvim_set_hl(0, "@markup.raw.block.markdown", {})
136 | vim.api.nvim_set_hl(0, "@label.markdown", { fg = "#555555" })
137 |
138 | vim.keymap.set("n", "op",
139 | function()
140 | otter.activate(
141 | { "python" },
142 | true,
143 | true,
144 | nil
145 | )
146 | end,
147 | { desc = "start otter for Python with language server and completion" }
148 | )
149 |
150 | vim.treesitter.language.register("markdown", "quarto")
151 |
152 |
153 | vim.keymap.set("n", "aj", convert_to_normal_script)
154 | vim.keymap.set("n", "ak", move_imports_to_top)
155 |
156 | vim.api.nvim_create_autocmd(
157 | { "BufEnter", "BufWinEnter", "TextChanged", "InsertLeave" },
158 | {
159 | pattern = { "*.md", "*.qmd" },
160 | callback = function()
161 | local bufnr = vim.api.nvim_get_current_buf()
162 | local ns_id = vim.api.nvim_create_namespace("codeblock_hr")
163 | vim.api.nvim_buf_clear_namespace(bufnr, ns_id, 0, -1)
164 |
165 | for i = 0, vim.api.nvim_buf_line_count(bufnr) - 1 do
166 | local line = vim.api.nvim_buf_get_lines(bufnr, i, i + 1, false)[1]
167 | if line:match("^```.*$") then
168 | vim.api.nvim_buf_set_extmark(bufnr, ns_id, i, 0, {
169 | virt_text = { { string.rep("─", 79), "Comment" } },
170 | virt_text_pos = "overlay",
171 | })
172 | end
173 | end
174 | end,
175 | }
176 | )
177 |
178 | vim.api.nvim_set_hl(0, "@spell", { fg = "#888888" })
179 |
180 | end
181 |
182 | }
183 |
--------------------------------------------------------------------------------
/lua/plugins/terminal.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/terminal.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the terminal plugin
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-12-23
9 | --
10 |
11 |
12 | local opts = {}
13 |
14 | opts.keymaps = {
15 |
16 | terminal = "t",
17 | find_file = "f",
18 | find_buffer = "y",
19 | live_grep = "g",
20 |
21 | normal_mode = "",
22 |
23 | goto_file = "gf",
24 |
25 | }
26 |
27 | opts.window = {
28 |
29 | width = function() return math.floor(vim.o.columns * 0.8) end,
30 | height = function() return math.floor(vim.o.lines * 0.8) end,
31 |
32 | style = "minimal",
33 | border = "single",
34 |
35 | }
36 |
37 | opts.fzf = {
38 |
39 | executable = "fzf",
40 |
41 | args = {
42 | "--layout=reverse",
43 | },
44 |
45 | }
46 |
47 | opts.rg = {
48 |
49 | executable = "rg",
50 |
51 | args = {
52 | "--ignore-case",
53 | },
54 |
55 | }
56 |
57 | opts.fd = {
58 |
59 | executable = "fd",
60 |
61 | args = {
62 | "--type f",
63 | '--exclude "*.png"',
64 | '--exclude "*.pdf"',
65 | '--exclude "*.jp*g"',
66 | '--exclude "*.aux"',
67 |
68 | '--exclude "**/build/**"',
69 | },
70 | }
71 |
72 | return {
73 |
74 | "terminal", dev = true,
75 |
76 | event = "UIEnter",
77 | opts = opts,
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/lua/plugins/treesitter.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/treesitter.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin treesitter
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-08-31
9 | --
10 |
11 |
12 | return {
13 |
14 | "nvim-treesitter/nvim-treesitter",
15 |
16 | event = "UIEnter",
17 |
18 | build = ":TSUpdate",
19 | main = "nvim-treesitter.configs",
20 |
21 | config = function()
22 |
23 | local success, treesitter = pcall(require, "nvim-treesitter.configs")
24 | if not success then
25 | vim.notify("Failed to load plugin: treesitter")
26 | return
27 | end
28 |
29 | treesitter.setup {
30 |
31 | ensure_installed = { "lua", "python", "cpp", "javascript", "markdown", "markdown_inline" },
32 | sync_install = true,
33 | ignore_install = {},
34 |
35 | highlight = {
36 | enable = true,
37 | disable = function(_, bufnr)
38 | return vim.api.nvim_buf_line_count(bufnr) > 2000
39 | end,
40 | },
41 |
42 | indent = { enable = true },
43 |
44 | fold = {
45 | enable = { "python" },
46 | },
47 |
48 | incremental_selection = {
49 | enable = true,
50 | keymaps = {
51 | init_selection = "gnn",
52 | node_incremental = "grn",
53 | scope_incremental = "grc",
54 | node_decremental = "grm",
55 | },
56 | },
57 |
58 | }
59 |
60 | vim.g._ts_force_sync_parsing = true
61 |
62 | end
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/lua/plugins/vimtex.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/plugins/vimtex.lua
3 | --
4 | -- @brief
5 | -- The configuration file for the plugin vimtex
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2025-01-03
9 | --
10 |
11 |
12 | return {
13 |
14 | "lervag/vimtex",
15 | lazy = false,
16 |
17 | init = function()
18 |
19 | vim.g.vimtex_view_method = "zathura"
20 |
21 | vim.g.vimtex_compiler_method = "latexmk"
22 | vim.g.vimtex_compiler_latexmk = {
23 | out_dir = "build",
24 | options = { "-pdf", "-interaction=nonstopmode", "-synctex=1"},
25 | }
26 |
27 | vim.g.vimtex_doc_enabled = 0
28 | vim.g.vimtex_complete_enabled = 0
29 | vim.g.vimtex_syntax_enabled = 0
30 | vim.g.vimtex_imaps_enabled = 0
31 |
32 | vim.g.vimtex_view_forward_search_on_start = 0
33 |
34 | vim.keymap.set("n", "ll", function() vim.cmd("VimtexCompile") end)
35 |
36 | end
37 | }
38 |
--------------------------------------------------------------------------------
/lua/statusline.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file lua/statusline.lua
3 | --
4 | -- @brief
5 | -- Configure the statusline
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-12-20
9 | --
10 |
11 |
12 | -- a function to obtain and format the current git branch
13 |
14 | local function git_branch()
15 |
16 | local branch = vim.b.gitsigns_head
17 |
18 | if branch == nil then
19 | return " -- "
20 | end
21 |
22 | local added = vim.b.gitsigns_status_dict.added or 0
23 | local changed = vim.b.gitsigns_status_dict.changed or 0
24 | local removed = vim.b.gitsigns_status_dict.removed or 0
25 |
26 | return "%#statusline_branch# " .. branch .. " +" .. added .. " -" .. removed .. " ~" .. changed .. " "
27 |
28 | end
29 |
30 | -- a function to obtain and format the file name
31 |
32 | local function file_name()
33 |
34 | local filename = vim.fn.expand("%:t")
35 | if filename == "" then
36 | filename = "[no name]"
37 | end
38 |
39 | if string.match(filename, "NvimTree") then
40 | filename = "NvimTree"
41 | end
42 |
43 | if vim.bo.buftype == "terminal" then
44 | filename = "terminal"
45 | end
46 |
47 | -- change highlight group based on if the file has been modified
48 | local highlight_group = vim.bo.modified and filename ~= "[no name]" and "statusline_modifiedfile" or "statusline_file"
49 |
50 | return "%#" .. highlight_group .. "# " .. filename .. " "
51 |
52 | end
53 |
54 | -- a function to obtain and format the current mode
55 |
56 | local function current_mode()
57 |
58 | local mode = vim.fn.mode()
59 |
60 | local mode_aliases = {
61 | n = "n",
62 | i = "i",
63 | v = "v",
64 | V = "v",
65 | t = "t",
66 | c = "c",
67 | s = "s",
68 | [""] = "v",
69 | }
70 |
71 | mode = mode and mode_aliases[mode] and mode_aliases[mode]:upper() or "?"
72 |
73 | return "%#statusline_mode# " .. mode .. " "
74 |
75 | end
76 |
77 | -- a function to obtain and format the diagnostics
78 |
79 | local function diagnostics()
80 |
81 | local num_warning = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN })
82 | local num_error = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR })
83 | local num_hint = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT })
84 |
85 | return "%#statusline_diagnostics# " .. "E" .. num_error .. " W" .. num_warning .. " H" .. num_hint .. " "
86 |
87 | end
88 |
89 | -- a function to display the current class or function in the statusline
90 |
91 | local function contexts()
92 |
93 | if vim.bo.filetype ~= "python" then
94 | return ""
95 | end
96 |
97 | local success, treesitter = pcall(require, "nvim-treesitter")
98 | if not success then
99 | return ""
100 | end
101 |
102 | local context = treesitter.statusline {
103 |
104 | type_patterns = { "class", "function", "method" },
105 |
106 | transform_fn = function(line)
107 |
108 | line = line:gsub("class%s*", "")
109 | line = line:gsub("def%s*", "")
110 | line = line:gsub(":", "")
111 |
112 | return line:gsub("%s*[%(%{%[].*[%]%}%)]*%s*$", "")
113 |
114 | end,
115 |
116 | separator = " -> ",
117 |
118 | allow_duplicates = false,
119 |
120 | }
121 |
122 | if context == nil then
123 | return ""
124 | end
125 |
126 | return "%#statusline_contexts# " .. context .. " "
127 |
128 | end
129 |
130 | -- a function to assign highlight group to the separator
131 |
132 | local function separator()
133 |
134 | local highlight_group = "statusline_separator"
135 | return "%#" .. highlight_group .. "#%="
136 |
137 | end
138 |
139 | -- a function to call and place the statusline components
140 |
141 | function Status_line()
142 |
143 | return table.concat({
144 |
145 | file_name(),
146 | diagnostics(),
147 | contexts(),
148 |
149 | separator(),
150 |
151 | git_branch(),
152 | current_mode(),
153 |
154 | })
155 |
156 | end
157 |
158 | -- default with statusline but can be toggled with s
159 |
160 | vim.opt["laststatus"] = 3
161 |
162 | vim.keymap.set( "n", "s",
163 |
164 | function()
165 |
166 | if vim.o.laststatus == 0 then
167 | vim.cmd("set laststatus=3")
168 | else
169 | vim.cmd("set laststatus=0")
170 | end
171 |
172 | end
173 |
174 | )
175 |
176 | vim.cmd("set statusline=%!v:lua.Status_line()")
177 |
178 | vim.cmd([[
179 | augroup Statusline
180 | au!
181 | au WinEnter,BufEnter * setlocal cursorline
182 | au WinLeave,BufLeave * setlocal nocursorline
183 | ]])
184 |
185 |
186 | -- set colors for each statusline components
187 |
188 | local group_styles = {
189 |
190 | ["statusline_file"] = { fg = "#EEEEEE", bg = "#333333", bold = true },
191 | ["statusline_modifiedfile"] = { fg = "#000000", bg = "#CCCCCC", bold = true },
192 | ["statusline_diagnostics"] = { fg = "#EEEEEE", bg = "#222222" },
193 | ["statusline_contexts"] = { fg = "#CCCCCC", bg = "None" },
194 |
195 | ["statusline_separator"] = { fg = "#333333", bg = "None" },
196 |
197 | ["statusline_branch"] = { fg = "#EEEEEE", bg = "#222222" },
198 | ["statusline_mode"] = { fg = "#EEEEEE", bg = "#333333", bold = true },
199 |
200 | }
201 |
202 | for group, style in pairs(group_styles) do
203 | vim.api.nvim_set_hl(0, group, style)
204 | end
205 |
--------------------------------------------------------------------------------
/projects/terminal/lua/terminal.lua:
--------------------------------------------------------------------------------
1 | ---
2 | -- @file projects/terminal/lua/terminal.lua
3 | --
4 | -- @brief
5 | -- The plugin file for terminal
6 | --
7 | -- @author Tanuharja, R.A.
8 | -- @date 2024-12-23
9 | --
10 |
11 |
12 | local M = {}
13 |
14 | M.state = {
15 | buffer = -1,
16 | win = -1,
17 | }
18 |
19 | local get_fzf_output = function(buffer)
20 |
21 | local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
22 | local output = ""
23 |
24 | for row = 1, #lines do
25 |
26 | if lines[row] == "" then
27 | return output
28 | end
29 |
30 | output = output .. lines[row]
31 |
32 | end
33 |
34 | end
35 |
36 | M.setup = function(opts)
37 |
38 | M.create_floating_window = function(buf)
39 |
40 | buf = buf or -1
41 |
42 | local width = opts.window.width()
43 | local height = opts.window.height()
44 |
45 | local col = math.floor((vim.o.columns - width) / 2)
46 | local row = math.floor((vim.o.lines - height) / 2)
47 |
48 | local buffer = nil
49 | if vim.api.nvim_buf_is_valid(buf) then
50 | buffer = buf
51 | else
52 | buffer = vim.api.nvim_create_buf(false, true) end
53 |
54 | local win_config = {
55 | relative = "editor",
56 | width = width,
57 | height = height,
58 | col = col,
59 | row = row,
60 | style = opts.window.style,
61 | border =opts.window.border,
62 | }
63 |
64 | local win = vim.api.nvim_open_win(buffer, true, win_config)
65 |
66 | return { buffer = buffer, win = win }
67 |
68 | end
69 |
70 | local fzf_command = opts.fzf.executable
71 |
72 | for _, arg in pairs(opts.fzf.args) do
73 | fzf_command = fzf_command .. " " .. arg
74 | end
75 |
76 | local fd_command = opts.fd.executable
77 |
78 | for _, arg in pairs(opts.fd.args) do
79 | fd_command = fd_command .. " " .. arg
80 | end
81 |
82 | local rg_command = opts.rg.executable .. " --line-number --color=never"
83 |
84 | for _, arg in pairs(opts.rg.args) do
85 | rg_command = rg_command .. " " .. arg
86 | end
87 |
88 | M.toggle_find_file = function()
89 |
90 | local picker = M.create_floating_window()
91 |
92 | vim.fn.jobstart(fd_command .. " | " .. fzf_command, {
93 | term = true,
94 | on_exit = function(_, exit_code)
95 |
96 | if exit_code == 0 then
97 |
98 | local file_name = get_fzf_output(picker.buffer)
99 | local found_file = vim.fn.findfile(file_name, vim.o.path)
100 |
101 | vim.api.nvim_win_close(picker.win, true)
102 |
103 | if found_file ~= "" then
104 | vim.cmd("edit " .. vim.fn.fnameescape(found_file))
105 | end
106 |
107 |
108 | else
109 | vim.api.nvim_win_close(picker.win, true)
110 | end
111 |
112 | end
113 | })
114 |
115 | vim.cmd("startinsert")
116 |
117 | end
118 |
119 | M.toggle_find_buffer = function()
120 |
121 | local picker = M.create_floating_window()
122 | local file_name = ""
123 |
124 | vim.cmd("redir! > .out | silent ls | redir END")
125 |
126 | vim.fn.jobstart([[sed -n 's/.*"\(.*\)".*/\1/p' .out | grep -v -E "term:|No Name" | ]] .. fzf_command, {
127 | term = true,
128 | on_exit = function(_, exit_code)
129 |
130 | if exit_code == 0 then
131 |
132 | local file_name = get_fzf_output(picker.buffer)
133 | local found_file = vim.fn.findfile(file_name, vim.o.path)
134 |
135 | vim.api.nvim_win_close(picker.win, true)
136 |
137 | if found_file ~= "" then
138 | vim.cmd("edit " .. vim.fn.fnameescape(found_file))
139 | end
140 |
141 | else
142 | vim.api.nvim_win_close(picker.win, true)
143 | end
144 |
145 | vim.cmd("silent! !rm .out")
146 |
147 | end
148 | })
149 |
150 | vim.cmd("startinsert")
151 |
152 | end
153 |
154 | M.toggle_live_grep = function()
155 |
156 | local picker = M.create_floating_window()
157 |
158 | vim.fn.jobstart(fzf_command .. ' --bind "change:reload(' .. rg_command .. ' {q} || true)" --ansi', {
159 | term = true,
160 | on_exit = function(_, exit_code)
161 |
162 | if exit_code == 0 then
163 |
164 | local output = get_fzf_output(picker.buffer)
165 | local file_name, line_num = output:match("([^:]+):(%d+)")
166 | local found_file = vim.fn.findfile(file_name, ".")
167 |
168 | vim.api.nvim_win_close(picker.win, true)
169 |
170 | if found_file ~= "" then
171 | vim.cmd("edit " .. vim.fn.fnameescape(found_file))
172 | vim.api.nvim_win_set_cursor(0, {tonumber(line_num), 0})
173 | end
174 |
175 | else
176 | vim.api.nvim_win_close(picker.win, true)
177 | end
178 |
179 | end
180 | })
181 |
182 | vim.cmd("startinsert")
183 |
184 | end
185 |
186 | M.toggle_terminal = function()
187 |
188 | if not vim.api.nvim_win_is_valid(M.state.win) then
189 | M.state = M.create_floating_window(M.state.buffer)
190 |
191 | if vim.bo[M.state.buffer].buftype ~= "terminal" then
192 |
193 | vim.cmd.terminal()
194 |
195 | local is_keyword = vim.bo[M.state.buffer].iskeyword
196 | vim.bo[M.state.buffer].iskeyword = is_keyword .. ",.,/,-"
197 |
198 | end
199 | else
200 | vim.api.nvim_win_hide(M.state.win)
201 | end
202 |
203 | end
204 |
205 | M.goto_file = function()
206 | local file_name = vim.fn.expand("")
207 | local found_file = vim.fn.findfile(file_name, ".")
208 | if found_file ~= "" then
209 | vim.api.nvim_win_hide(M.state.win)
210 | vim.cmd("edit " .. vim.fn.fnameescape(found_file))
211 | end
212 | end
213 |
214 | vim.keymap.set("n", opts.keymaps.terminal, M.toggle_terminal)
215 | vim.keymap.set("n", opts.keymaps.find_file, M.toggle_find_file)
216 | vim.keymap.set("n", opts.keymaps.live_grep, M.toggle_live_grep)
217 | vim.keymap.set("n", opts.keymaps.find_buffer, M.toggle_find_buffer)
218 | vim.keymap.set("t", opts.keymaps.normal_mode, "")
219 | vim.keymap.set("n", opts.keymaps.goto_file, M.goto_file, { buffer = M.state.buffer })
220 | end
221 |
222 | return M
223 |
--------------------------------------------------------------------------------
/queries/python/folds.scm:
--------------------------------------------------------------------------------
1 | ;; fold docstring
2 | (function_definition
3 | body: (block
4 | (expression_statement
5 | (string) @fold
6 | )
7 | )
8 | )
9 |
10 | (class_definition
11 | body: (block
12 | (expression_statement
13 | (string) @fold
14 | )
15 | )
16 | )
17 |
--------------------------------------------------------------------------------
/queries/python/highlights.scm:
--------------------------------------------------------------------------------
1 | ;; extends
2 | (((comment) @comment (#contains? @comment "TODO")) @comment.warning (#set! priority 150))
3 | (((comment) @comment (#contains? @comment "WARN")) @comment.warning (#set! priority 150))
4 | (((comment) @comment (#contains? @comment "BUGS")) @comment.error (#set! priority 150))
5 | (((comment) @comment (#contains? @comment "FIXME")) @comment.error (#set! priority 150))
6 | (((comment) @comment (#contains? @comment "NOTE")) @comment.note (#set! priority 150))
7 |
8 | (function_definition
9 | body: (block
10 | (expression_statement
11 | (string) @comment (#set! priority 125)
12 |
13 | )
14 | )
15 | )
16 |
17 | (class_definition
18 | body: (block
19 | (expression_statement
20 | (string) @comment (#set! priority 125)
21 | )
22 | )
23 | )
24 |
--------------------------------------------------------------------------------
/snippets/markdown.json:
--------------------------------------------------------------------------------
1 | {
2 | "Python code block": {
3 | "prefix": "code",
4 | "body": "```python\n$0\n```",
5 | "description": "A code block inside a markdown file"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/snippets/python.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "Aliased import": {
4 | "prefix": "import",
5 | "body": "import ${1:module} as ${2:alias}\n$0",
6 | "description": "Import a module and assign an alias to it"
7 | },
8 |
9 | "Partial import": {
10 | "prefix": "from",
11 | "body": "from ${1:module} import ${2:item}\n$0",
12 | "description": "Import specific item(s) from a module"
13 | },
14 |
15 | "Function definition": {
16 | "prefix": "def",
17 | "body": [
18 | "def ${1:function_name}(${2:args}):",
19 | "\t",
20 | "\t${3:pass}",
21 | "$0"
22 | ],
23 | "description": "Define a new function"
24 | },
25 |
26 | "Class definition": {
27 | "prefix": "class",
28 | "body": [
29 | "class ${1:class_name}:",
30 | "\t",
31 | "\tdef __init__(${2:self}):",
32 | "\t\t${3:pass}",
33 | "$0"
34 | ],
35 | "description": "Define a new class"
36 | },
37 |
38 | "Main function definition": {
39 | "prefix": "main",
40 | "body": [
41 | "def main():",
42 | "\t",
43 | "\t${1:pass}$0",
44 | " ",
45 | " ",
46 | "if __name__ == \"__main__\":",
47 | "\t",
48 | "\tmain()"
49 | ],
50 | "description": "Create a common Python script structure"
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/snippets/quarto.json:
--------------------------------------------------------------------------------
1 | {
2 | "Python code block": {
3 | "prefix": "python",
4 | "body": "```{python}\n$0\n```",
5 | "description": "A python code block inside a quarto file"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/snippets/tex.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "Skeleton": {
4 | "prefix": "skeleton",
5 | "body": [
6 | "\\documentclass{${1:type}}",
7 | " ",
8 | "${2:% preambles}",
9 | " ",
10 | "\\begin{document}",
11 | " ",
12 | "$0",
13 | " ",
14 | "\\end{document}"
15 | ],
16 | "description": "Create a document skeleton"
17 | },
18 |
19 | "Package": {
20 | "prefix": "package",
21 | "body": "\\usepackage{${1:package_name}}\n$0",
22 | "description": "Import a LaTeX package"
23 | },
24 |
25 | "Environment": {
26 | "prefix": "environment",
27 | "body": "\\begin{${1:env}}\n\t$0\n\\end{${1}}",
28 | "description": "Create the start and end of an environment"
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------