diff --git a/README.md b/README.md index 093e42a6dd9..24a70f5be70 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,11 @@ External Requirements: - If you want to write Typescript, you need `npm` - If you want to write Golang, you will need `go` - etc. +- [llama.cpp](https://github.com/ggml-org/llama.cpp) (optional, for local AI code completion via llama.vim) + - macOS: `brew install llama.cpp` + - Other platforms: see [llama.cpp installation](https://github.com/ggml-org/llama.cpp#installation) + - Start the server with: `:LlamaStart` inside Neovim (uses `qwen2.5` FIM model by default) + - Stop the server with: `:LlamaStop` (also stops automatically when Neovim exits) > [!NOTE] > See [Install Recipes](#Install-Recipes) for additional Windows and Linux specific notes diff --git a/init.lua b/init.lua index 8d1f19a10d4..63cfeef8aa3 100644 --- a/init.lua +++ b/init.lua @@ -93,6 +93,14 @@ vim.g.maplocalleader = ' ' -- Set to true if you have a Nerd Font installed and selected in the terminal vim.g.have_nerd_font = false +-- Neovide configuration +if vim.g.neovide then + vim.g.neovide_cursor_animation_length = 0 + vim.g.neovide_cursor_trail_size = 0 + vim.g.neovide_scroll_animation_length = 0 + vim.g.neovide_position_animation_length = 0 +end + -- [[ Setting options ]] -- See `:help vim.o` -- NOTE: You can change these options as you wish! @@ -212,6 +220,52 @@ vim.keymap.set('n', '', '', { desc = 'Move focus to the right win vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) +vim.keymap.set('n', 'sv', 'vsp', { desc = '[S]plit [V]ertical' }) +vim.keymap.set('n', 'sh', 'sp', { desc = '[S]plit [H]orizontal' }) + +local llama_job_id = nil + +vim.api.nvim_create_user_command('LlamaToggle', function() + vim.cmd 'call llama#toggle()' +end, { desc = 'Toggle llama.vim completion' }) + +vim.api.nvim_create_user_command('LlamaStart', function() + if llama_job_id then + vim.notify('llama-server is already running', vim.log.levels.WARN) + return + end + llama_job_id = vim.fn.jobstart('llama-server --fim-qwen-3b-default -c 16384', { detach = true }) + vim.notify('llama-server started', vim.log.levels.INFO) +end, { desc = 'Start llama-server' }) + +vim.api.nvim_create_user_command('LlamaStop', function() + if not llama_job_id then + vim.notify('llama-server is not running', vim.log.levels.WARN) + return + end + vim.fn.jobstop(llama_job_id) + llama_job_id = nil + vim.notify('llama-server stopped', vim.log.levels.INFO) +end, { desc = 'Stop llama-server' }) + +vim.api.nvim_create_autocmd('InsertLeave', { + callback = function() + if vim.bo.modified and vim.bo.buftype == '' and vim.fn.expand '%' ~= '' then + vim.cmd 'silent! write' + end + end, +}) + +vim.api.nvim_create_autocmd('VimLeavePre', { + callback = function() + if llama_job_id then + vim.fn.jobstop(llama_job_id) + llama_job_id = nil + end + end, +}) + + -- NOTE: Some terminals have colliding keymaps or are not able to send distinct keycodes -- vim.keymap.set("n", "", "H", { desc = "Move window to the left" }) -- vim.keymap.set("n", "", "L", { desc = "Move window to the right" }) @@ -358,9 +412,6 @@ require('lazy').setup({ cond = function() return vim.fn.executable 'make' == 1 end, }, { 'nvim-telescope/telescope-ui-select.nvim' }, - - -- Useful for getting pretty icons, but requires a Nerd Font. - { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, }, config = function() -- Telescope is a fuzzy finder that comes with a lot of different things that @@ -385,15 +436,34 @@ require('lazy').setup({ -- [[ Configure Telescope ]] -- See `:help telescope` and `:help telescope.setup()` require('telescope').setup { - -- You can put your default mappings / updates / etc. in here - -- All the info you're looking for is in `:help telescope.setup()` - -- - -- defaults = { - -- mappings = { - -- i = { [''] = 'to_fuzzy_refine' }, - -- }, - -- }, - -- pickers = {} + defaults = { + mappings = { + i = { [''] = require('telescope.actions').delete_buffer }, + n = { [''] = require('telescope.actions').delete_buffer }, + }, + vimgrep_arguments = { + 'rg', + '--color=never', + '--no-heading', + '--with-filename', + '--line-number', + '--column', + '--smart-case', + '--hidden', + '--glob=!.git/', + }, + file_ignore_patterns = { + 'node_modules', + 'package%-lock%.json', + 'yarn%.lock', + 'pnpm%-lock%.yaml', + '%.git/', + 'dist/', + 'build/', + '%.next/', + '%.cache/', + }, + }, extensions = { ['ui-select'] = { require('telescope.themes').get_dropdown() }, }, @@ -407,7 +477,9 @@ require('lazy').setup({ local builtin = require 'telescope.builtin' vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) - vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) + vim.keymap.set('n', 'sf', function() + builtin.find_files { find_command = { 'fd', '--type', 'f', '--hidden', '--exclude', '.git' } } + end, { desc = '[S]earch [F]iles' }) vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) vim.keymap.set({ 'n', 'v' }, 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) @@ -609,7 +681,7 @@ require('lazy').setup({ -- https://github.com/pmizio/typescript-tools.nvim -- -- But for many setups, the LSP (`ts_ls`) will work just fine - -- ts_ls = {}, + ts_ls = {}, stylua = {}, -- Used to format Lua code @@ -657,7 +729,8 @@ require('lazy').setup({ -- You can press `g?` for help in this menu. local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { - -- You can add other tools here that you want Mason to install + 'prettier', + 'eslint_d', }) require('mason-tool-installer').setup { ensure_installed = ensure_installed } @@ -702,12 +775,13 @@ require('lazy').setup({ }, -- You can also specify external formatters in here. formatters_by_ft = { - -- rust = { 'rustfmt' }, - -- Conform can also run multiple formatters sequentially - -- python = { "isort", "black" }, - -- - -- You can use 'stop_after_first' to run the first available formatter from the list - -- javascript = { "prettierd", "prettier", stop_after_first = true }, + lua = { 'stylua' }, + javascript = { 'prettier', stop_after_first = true }, + typescript = { 'prettier', stop_after_first = true }, + javascriptreact = { 'prettier', stop_after_first = true }, + typescriptreact = { 'prettier', stop_after_first = true }, + json = { 'prettier', stop_after_first = true }, + css = { 'prettier', stop_after_first = true }, }, }, }, @@ -786,7 +860,7 @@ require('lazy').setup({ }, sources = { - default = { 'lsp', 'path', 'snippets' }, + default = { 'lsp', 'path', 'snippets', 'buffer' }, }, snippets = { preset = 'luasnip' }, @@ -810,20 +884,12 @@ require('lazy').setup({ -- change the command in the config to whatever the name of that colorscheme is. -- -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`. - 'folke/tokyonight.nvim', - priority = 1000, -- Make sure to load this before all the other start plugins. + 'rose-pine/neovim', + name = 'rose-pine', + priority = 1000, config = function() - ---@diagnostic disable-next-line: missing-fields - require('tokyonight').setup { - styles = { - comments = { italic = false }, -- Disable italics in comments - }, - } - - -- Load the colorscheme here. - -- Like many other themes, this one has different styles, and you could load - -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'. - vim.cmd.colorscheme 'tokyonight-night' + require('rose-pine').setup { variant = 'moon' } + vim.cmd.colorscheme 'rose-pine' end, }, @@ -949,16 +1015,16 @@ require('lazy').setup({ -- -- require 'kickstart.plugins.debug', -- require 'kickstart.plugins.indent_line', - -- require 'kickstart.plugins.lint', - -- require 'kickstart.plugins.autopairs', - -- require 'kickstart.plugins.neo-tree', + require 'kickstart.plugins.lint', + require 'kickstart.plugins.autopairs', + require 'kickstart.plugins.neo-tree', -- require 'kickstart.plugins.gitsigns', -- adds gitsigns recommended keymaps -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. - -- { import = 'custom.plugins' }, + { import = 'custom.plugins' }, -- -- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec` -- Or use telescope! diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index b3ddcfdd3aa..a3296aae928 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -5,4 +5,45 @@ ---@module 'lazy' ---@type LazySpec -return {} +return { + { + 'famiu/bufdelete.nvim', + keys = { + { 'bd', 'Bdelete', desc = '[B]uffer [D]elete' }, + }, + }, + { 'editorconfig/editorconfig-vim' }, + { + 'ggml-org/llama.vim', + init = function() + vim.g.llama_config = { + n_predict = 256, -- longer suggestions + ring_n_chunks = 64, -- more project context chunks + ring_chunk_size = 64, -- smaller chunks for speed + ring_scope = 2048, -- wider scope around cursor + show_info = 0, -- disable inline timing/info display + } + end, + }, + { + 'folke/flash.nvim', + event = 'VeryLazy', + keys = { + { 's', function() require('flash').jump() end, mode = { 'n', 'x', 'o' }, desc = 'Flash jump' }, + { 'S', function() require('flash').treesitter() end, mode = { 'n', 'x', 'o' }, desc = 'Flash treesitter' }, + }, + }, + { + 'mg979/vim-visual-multi', + event = 'VeryLazy', + }, + { + 'akinsho/toggleterm.nvim', + version = '*', + opts = { + open_mapping = [[]], + direction = 'vertical', + size = 80, + }, + }, +} diff --git a/lua/kickstart/plugins/lint.lua b/lua/kickstart/plugins/lint.lua index 556f3178811..1a398424404 100644 --- a/lua/kickstart/plugins/lint.lua +++ b/lua/kickstart/plugins/lint.lua @@ -9,6 +9,10 @@ return { local lint = require 'lint' lint.linters_by_ft = { markdown = { 'markdownlint' }, -- Make sure to install `markdownlint` via mason / npm + javascript = { 'eslint_d' }, + typescript = { 'eslint_d' }, + javascriptreact = { 'eslint_d' }, + typescriptreact = { 'eslint_d' }, } -- To allow other plugins to add linters to require('lint').linters_by_ft, @@ -52,7 +56,15 @@ return { -- Only run the linter in buffers that you can modify in order to -- avoid superfluous noise, notably within the handy LSP pop-ups that -- describe the hovered symbol using Markdown. - if vim.bo.modifiable then lint.try_lint() end + if vim.bo.modifiable then + local linters = lint.linters_by_ft[vim.bo.filetype] or {} + local available = vim.tbl_filter(function(l) + local linter = lint.linters[l] + local cmd = type(linter) == 'table' and linter.cmd or l + return type(cmd) == 'string' and vim.fn.executable(cmd) == 1 + end, linters) + if #available > 0 then lint.try_lint(available) end + end end, }) end,