From 11581a9a582809a9a0c15728200f1a873922a1af Mon Sep 17 00:00:00 2001 From: RiverMatsumoto Date: Thu, 1 Jan 2026 01:47:52 -1000 Subject: [PATCH] cursor smear and cleaned up lots of settings --- init.lua | 639 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 484 insertions(+), 155 deletions(-) diff --git a/init.lua b/init.lua index 2116ebcc..7f44a6d9 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,7 @@ vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' +-- for chatgpt +_G.chatgpt_model = 'gpt-5.1-codex-mini' -- ========================= -- Lazy.nvim bootstrap @@ -21,7 +23,6 @@ vim.opt.rtp:prepend(lazypath) -- PLUGINS -- ========================= require('lazy').setup({ - -- Git 'voldikss/vim-floaterm', 'tpope/vim-fugitive', @@ -32,6 +33,28 @@ require('lazy').setup({ { 'numToStr/Comment.nvim', opts = {} }, + { + 'nvim-treesitter/nvim-treesitter', + lazy = false, + build = ':TSUpdate', + }, + + { + 'MeanderingProgrammer/treesitter-modules.nvim', + dependencies = { 'nvim-treesitter/nvim-treesitter' }, + opts = { + incremental_selection = { + enable = true, + keymaps = { + init_selection = '', -- Alt+Space + node_incremental = '', -- Alt+Space (expand) + node_decremental = '', -- Alt+Backspace (shrink) + scope_incremental = '', -- Alt+Shift+Space (scope expand) + }, + }, + }, + }, + 'rhysd/git-messenger.vim', { 'jackMort/ChatGPT.nvim', @@ -43,7 +66,29 @@ require('lazy').setup({ }, config = function() require('chatgpt').setup { - api_key_cmd = 'echo $OPENAI_API_KEY', + openai_params = { + -- NOTE: model can be a function returning the model name + -- this is useful if you want to change the model on the fly + -- using commands + -- Example: + -- model = function() + -- if some_condition() then + -- return "gpt-5" + -- else + -- return "gpt-5-mini" + -- end + -- end, + model = function() + return _G.chatgpt_model + end, + frequency_penalty = 0, + presence_penalty = 0, + max_tokens = 4095, + temperature = 0.2, + top_p = 0.1, + n = 1, + api_key_cmd = 'echo $OPENAI_API_KEY', + }, } end, }, @@ -112,15 +157,28 @@ require('lazy').setup({ { 'sphamba/smear-cursor.nvim', - opts = { -- Default Range - stiffness = 0.6, -- 0.6 [0, 1] - trailing_stiffness = 0.4, -- 0.45 [0, 1] - stiffness_insert_mode = 0.7, -- 0.5 [0, 1] - trailing_stiffness_insert_mode = 0.7, -- 0.5 [0, 1] - damping = 0.8, -- 0.85 [0, 1] - damping_insert_mode = 0.8, -- 0.9 [0, 1] - distance_stop_animating = 0.1, -- 0.1 > 0 - }, + opts = { + time_interval = 3, + cursor_color = '#ff4000', + particles_enabled = true, + stiffness = 0.5, + trailing_stiffness = 0.2, + trailing_exponent = 5, + damping = 0.6, + gradient_exponent = 0, + gamma = 1, + never_draw_over_target = true, + hide_target_hack = true, + particle_spread = 1, + particles_per_second = 500, + particles_per_length = 50, + particle_max_lifetime = 800, + particle_max_initial_velocity = 20, + particle_velocity_from_cursor = 0.5, + particle_damping = 0.15, + particle_gravity = -50, + min_distance_emit_particles = 0, + }, }, { @@ -417,7 +475,7 @@ require('lazy').setup({ -- Telescope { 'nvim-telescope/telescope.nvim', - branch = '0.1.x', + branch = 'master', dependencies = { 'nvim-lua/plenary.nvim', { @@ -868,6 +926,247 @@ require('lazy').setup({ }, }, {}) +-- ========================================= +-- ============ START SMEAR PROFILE ======== +-- ========================================= +local smear = require 'smear_cursor' + +local smear_profiles = { + silver_blade = { + -- General + cursor_color = "#ffe6b2", + smear_between_buffers = true, + smear_between_neighbor_lines = true, + min_horizontal_distance_smear = 0, + min_vertical_distance_smear = 0, + smear_horizontally = true, + smear_vertically = true, + smear_diagonally = true, + smear_to_cmd = true, + scroll_buffer_space = true, + + legacy_computing_symbols_support = false, + legacy_computing_symbols_support_vertical_bars = false, + use_diagonal_blocks = true, + + vertical_bar_cursor = false, + smear_insert_mode = true, + vertical_bar_cursor_insert_mode = true, + smear_replace_mode = false, + smear_terminal_mode = false, + horizontal_bar_cursor_replace_mode = true, + + never_draw_over_target = false, + hide_target_hack = false, + + max_kept_windows = 50, + windows_zindex = 300, + filetypes_disabled = {}, + + -- High FPS (smooth) + time_interval = 7, + delay_disable = nil, + delay_event_to_smear = 1, + delay_after_key = 6, + + -- Physics: fast head, laggy tail, smooth decay + stiffness = 0.95, + trailing_stiffness = 0.33, + anticipation = 0.06, + damping = 0.90, + trailing_exponent = 5.5, + distance_stop_animating = 0.06, + + -- Insert mode: match feel + stiffness_insert_mode = 0.95, + trailing_stiffness_insert_mode = 0.7, + damping_insert_mode = 0.92, + trailing_exponent_insert_mode = 5.5, + distance_stop_animating_vertical_bar = 0.25, + + -- Diagonal + shading tuned for “pretty” + max_slope_horizontal = (1 / 3) / 1.7, + min_slope_vertical = 2 * 1.7, + max_angle_difference_diagonal = math.pi / 18, + max_offset_diagonal = 0.18, + min_shade_no_diagonal = 0.22, + min_shade_no_diagonal_vertical_bar = 0.55, + + -- Rich blending (costly but nice) + color_levels = 24, + gamma = 2.2, + gradient_exponent = 2.8, + max_shade_no_matrix = 0.78, + matrix_pixel_threshold = 0.72, + matrix_pixel_threshold_vertical_bar = 0.28, + matrix_pixel_min_factor = 0.55, + volume_reduction_exponent = 0.22, + minimum_volume_factor = 0.78, + + -- Longer trail + max_length = 34, + max_length_insert_mode = 2, + + -- Particles off + particles_enabled = false, + particle_max_num = 100, + particle_spread = 0.5, + particles_per_second = 200, + particles_per_length = 1.0, + particle_max_lifetime = 300, + particle_lifetime_distribution_exponent = 5, + particle_max_initial_velocity = 10, + particle_velocity_from_cursor = 0.2, + particle_random_velocity = 100, + particle_damping = 0.2, + particle_gravity = 20, + min_distance_emit_particles = 1.5, + particle_switch_octant_braille = 0.3, + particles_over_text = false, + }, + -- 1) Frost Mist + eco_smear = { + -- General (keep core behavior) + smear_between_buffers = true, + smear_between_neighbor_lines = true, + min_horizontal_distance_smear = 1, -- reduces tiny smears + min_vertical_distance_smear = 1, + smear_horizontally = true, + smear_vertically = true, + smear_diagonally = false, -- big CPU win + smear_to_cmd = true, + scroll_buffer_space = false, -- cheaper on scroll + + legacy_computing_symbols_support = false, + legacy_computing_symbols_support_vertical_bars = false, + use_diagonal_blocks = true, + + vertical_bar_cursor = false, + smear_insert_mode = true, + vertical_bar_cursor_insert_mode = true, + smear_replace_mode = false, + smear_terminal_mode = false, + horizontal_bar_cursor_replace_mode = true, + + never_draw_over_target = false, + hide_target_hack = false, + + max_kept_windows = 20, -- fewer render windows kept + windows_zindex = 300, + filetypes_disabled = {}, + + -- Lower FPS (much cheaper) + time_interval = 14, + delay_disable = nil, + delay_event_to_smear = 2, + delay_after_key = 10, + + -- Physics: still fast head, shorter/cheaper tail + stiffness = 0.90, + trailing_stiffness = 0.28, + anticipation = 0.04, + damping = 0.88, + trailing_exponent = 3.0, + distance_stop_animating = 0.12, + + -- Insert mode: keep it tight + stiffness_insert_mode = 0.90, + trailing_stiffness_insert_mode = 0.28, + damping_insert_mode = 0.90, + trailing_exponent_insert_mode = 3.0, + distance_stop_animating_vertical_bar = 0.30, + + -- Simpler shading (cheaper) + max_slope_horizontal = (1 / 3) / 1.6, + min_slope_vertical = 2 * 1.6, + max_angle_difference_diagonal = math.pi / 16, + max_offset_diagonal = 0.2, + min_shade_no_diagonal = 0.30, + min_shade_no_diagonal_vertical_bar = 0.60, + + -- Reduced blending cost + color_levels = 16, + gamma = 2.2, + gradient_exponent = 1.3, + max_shade_no_matrix = 0.80, + matrix_pixel_threshold = 0.80, + matrix_pixel_threshold_vertical_bar = 0.35, + matrix_pixel_min_factor = 0.65, + volume_reduction_exponent = 0.35, + minimum_volume_factor = 0.82, + + -- Shorter trail + max_length = 18, + max_length_insert_mode = 1, + + -- Particles off + particles_enabled = false, + particle_max_num = 100, + particle_spread = 0.5, + particles_per_second = 200, + particles_per_length = 1.0, + particle_max_lifetime = 300, + particle_lifetime_distribution_exponent = 5, + particle_max_initial_velocity = 10, + particle_velocity_from_cursor = 0.2, + particle_random_velocity = 100, + particle_damping = 0.2, + particle_gravity = 20, + min_distance_emit_particles = 1.5, + particle_switch_octant_braille = 0.3, + particles_over_text = false, + }, + +} + +local smear_profile_order = { + 'silver_blade', + 'eco_smear', +} + +local current_idx = 1 + +local function apply_smear_profile(name) + local p = smear_profiles[name] + if not p then + vim.notify('Unknown smear profile: ' .. tostring(name), vim.log.levels.ERROR) + return + end + smear.setup(vim.deepcopy(p)) + vim.g.smear_cursor_profile = name + vim.notify('smear-cursor → ' .. name) +end + +-- Commands +vim.api.nvim_create_user_command('SmearProfile', function(opts) + apply_smear_profile(opts.args) +end, { + nargs = 1, + complete = function() + return smear_profile_order + end, +}) + +vim.api.nvim_create_user_command('SmearProfileNext', function() + current_idx = (current_idx % #smear_profile_order) + 1 + apply_smear_profile(smear_profile_order[current_idx]) +end, {}) + +vim.api.nvim_create_user_command('SmearProfilePrev', function() + current_idx = ((current_idx - 2) % #smear_profile_order) + 1 + apply_smear_profile(smear_profile_order[current_idx]) +end, {}) + +-- Keybindings (edit if you want) +vim.keymap.set('n', 'pn', 'SmearProfileNext', { desc = 'Smear profile: next' }) +vim.keymap.set('n', 'pp', 'SmearProfilePrev', { desc = 'Smear profile: prev' }) + +-- Apply a default on startup (pick one) +apply_smear_profile 'silver_blade' +-- ========================================= +-- ============ END SMEAR PROFILE ========== +-- ========================================= + -- ========================= -- Editor settings -- ========================= @@ -899,6 +1198,40 @@ vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = tr vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) vim.opt.termguicolors = true +-- ============================ +-- ====== TABSTOP START ======= +-- ============================ +local function set_indent(ts) + vim.opt_local.expandtab = true + vim.opt_local.tabstop = ts + vim.opt_local.shiftwidth = ts + vim.opt_local.softtabstop = ts +end + +vim.api.nvim_create_autocmd("FileType", { + pattern = { "lua", "javascript", "typescript", "tsx", "json", "yaml", "toml", "html", "css", "rust", "c", "cpp" }, + callback = function() set_indent(2) end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = { "python", "sh", "bash", "zsh", "go" }, + callback = function() set_indent(4) end, +}) + +-- Makefiles must use real tabs +vim.api.nvim_create_autocmd("FileType", { + pattern = { "make" }, + callback = function() + vim.opt_local.expandtab = false + vim.opt_local.tabstop = 8 + vim.opt_local.shiftwidth = 8 + vim.opt_local.softtabstop = 0 + end, +}) +-- ============================ +-- ====== TABSTOP END ========= +-- ============================ + local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true }) vim.api.nvim_create_autocmd('TextYankPost', { callback = function() @@ -927,127 +1260,170 @@ vim.api.nvim_create_autocmd({ 'BufLeave', 'InsertEnter', 'FocusLost' }, { -- ========================= -- Keymaps (treesitter keymaps removed) -- ========================= -vim.keymap.set('n', '', 'zz') -vim.keymap.set('n', '', 'zz') -vim.keymap.set('n', 'n', 'nzzzv') -vim.keymap.set('n', 'N', 'Nzzzv') -vim.keymap.set('v', 'J', ":m '>+1gv=gv") -vim.keymap.set('v', 'K', ":m '<-2gv=gv") -vim.keymap.set('n', '', 'h') -vim.keymap.set('n', '', 'j') -vim.keymap.set('n', '', 'k') -vim.keymap.set('n', '', 'l') +-- scrolling / search centering +vim.keymap.set('n', '', 'zz', { desc = 'Scroll down and center cursor' }) +vim.keymap.set('n', '', 'zz', { desc = 'Scroll up and center cursor' }) +vim.keymap.set('n', 'n', 'nzzzv', { desc = 'Next search result and center' }) +vim.keymap.set('n', 'N', 'Nzzzv', { desc = 'Previous search result and center' }) -vim.keymap.set('x', 'p', [["_dP]]) -vim.keymap.set('n', 'ya', ':%y+') +-- move selected lines +vim.keymap.set('v', 'J', ":m '>+1gv=gv", { desc = 'Move selection down' }) +vim.keymap.set('v', 'K', ":m '<-2gv=gv", { desc = 'Move selection up' }) -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next) -vim.keymap.set('n', 'e', vim.diagnostic.open_float) -vim.keymap.set('n', 'q', vim.diagnostic.setloclist) -vim.keymap.set('n', 'dd', vim.diagnostic.disable) -vim.keymap.set('n', 'de', vim.diagnostic.enable) +-- window navigation +vim.keymap.set('n', '', 'h', { desc = 'Go to left window' }) +vim.keymap.set('n', '', 'j', { desc = 'Go to lower window' }) +vim.keymap.set('n', '', 'k', { desc = 'Go to upper window' }) +vim.keymap.set('n', '', 'l', { desc = 'Go to right window' }) -vim.keymap.set('n', 'cw', ':cd %:p:h:pwd') -vim.keymap.set('n', '', '', { noremap = true }) -vim.keymap.set('n', '', ':write') -vim.keymap.set('n', 'cd', ':ToggleAutoComplete') -vim.keymap.set('n', 'ce', ':ToggleAutoComplete') +-- clipboard / yank +vim.keymap.set('x', 'p', [["_dP]], { desc = 'Paste without overwriting register' }) +vim.keymap.set('n', 'ya', ':%y+', { desc = 'Yank entire buffer to clipboard' }) --- Telescope keymaps -vim.keymap.set('n', '?', require('telescope.builtin').oldfiles) -vim.keymap.set('n', '', require('telescope.builtin').buffers) +-- diagnostics +vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Previous diagnostic' }) +vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Next diagnostic' }) +vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Show diagnostic under cursor' }) +vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Diagnostics to loclist' }) +vim.keymap.set('n', 'dd', vim.diagnostic.disable, { desc = 'Disable diagnostics' }) +vim.keymap.set('n', 'de', vim.diagnostic.enable, { desc = 'Enable diagnostics' }) + +-- misc +vim.keymap.set('n', 'cw', ':cd %:p:h:pwd', { desc = 'cd to current file directory' }) +vim.keymap.set('n', '', '', { noremap = true, desc = 'Jump forward in jumplist' }) +vim.keymap.set('n', '', ':write', { desc = 'Save file' }) +vim.keymap.set('n', 'cd', ':ToggleAutoComplete', { desc = 'Toggle autocomplete' }) +vim.keymap.set('n', 'ce', ':ToggleAutoComplete', { desc = 'Toggle autocomplete (alias)' }) + +-- Telescope +vim.keymap.set('n', '?', require('telescope.builtin').oldfiles, { desc = 'Find recently opened files' }) +vim.keymap.set('n', '', require('telescope.builtin').buffers, { desc = 'List open buffers' }) vim.keymap.set('n', '/', function() require('telescope.builtin').current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { previewer = false, sorting_strategy = 'ascending', }) -end) +end, { desc = 'Fuzzy search in current buffer' }) + +vim.keymap.set('n', 'sf', require('telescope.builtin').find_files, { desc = 'Find files' }) +vim.keymap.set('n', 'sh', require('telescope.builtin').help_tags, { desc = 'Search help tags' }) +vim.keymap.set('n', 'sw', require('telescope.builtin').grep_string, { desc = 'Search word under cursor' }) +vim.keymap.set('n', 'sg', require('telescope.builtin').live_grep, { desc = 'Live grep' }) +vim.keymap.set('n', 'sd', require('telescope.builtin').diagnostics, { desc = 'Search diagnostics' }) +vim.keymap.set('n', 'sp', require('telescope.builtin').spell_suggest, { desc = 'Spell suggestions' }) +vim.keymap.set('n', 'sk', require('telescope.builtin').keymaps, { desc = 'Search keymaps' }) +vim.keymap.set('n', 'gf', require('telescope.builtin').git_files, { desc = 'Find git files' }) +vim.keymap.set('n', 'sc', require('telescope.builtin').git_commits, { desc = 'Search git commits' }) +vim.keymap.set('n', 'sr', require('telescope.builtin').resume, { desc = 'Resume last Telescope picker' }) -vim.keymap.set('n', 'sf', require('telescope.builtin').find_files) -vim.keymap.set('n', 'sh', require('telescope.builtin').help_tags) -vim.keymap.set('n', 'sw', require('telescope.builtin').grep_string) -vim.keymap.set('n', 'sg', require('telescope.builtin').live_grep) -vim.keymap.set('n', 'sd', require('telescope.builtin').diagnostics) -vim.keymap.set('n', 'sp', require('telescope.builtin').spell_suggest) -vim.keymap.set('n', 'sk', require('telescope.builtin').keymaps) -vim.keymap.set('n', 'gf', require('telescope.builtin').git_files) -vim.keymap.set('n', 'sc', require('telescope.builtin').git_commits) -vim.keymap.set('n', 'sr', require('telescope.builtin').resume) vim.keymap.set('n', 's/', function() require('telescope.builtin').live_grep { grep_open_files = true, prompt_title = 'Live Grep in Open Files', } -end) +end, { desc = 'Live grep in open files' }) + vim.keymap.set('n', 'sn', function() require('telescope.builtin').find_files { cwd = vim.fn.stdpath 'config' } -end) +end, { desc = 'Search Neovim config files' }) -vim.keymap.set('n', 'ru', ':w:!%:p') -vim.keymap.set('n', 'me', ':!chmod +x %:p') -vim.keymap.set('n', 'P', require('spectre').open) +-- run / permissions +vim.keymap.set('n', 'ru', ':w:!%:p', { desc = 'Save and run current file' }) +vim.keymap.set('n', 'me', ':!chmod +x %:p', { desc = 'Make file executable' }) +vim.keymap.set('n', 'P', require('spectre').open, { desc = 'Open Spectre search/replace' }) -vim.keymap.set('n', 'xx', 'TroubleToggle', { silent = true, noremap = true }) -vim.keymap.set('n', 'xw', 'TroubleToggle workspace_diagnostics', { silent = true, noremap = true }) -vim.keymap.set('n', 'xd', 'TroubleToggle document_diagnostics', { silent = true, noremap = true }) +-- Trouble +vim.keymap.set('n', 'xx', 'TroubleToggle', { silent = true, noremap = true, desc = 'Toggle Trouble' }) +vim.keymap.set('n', 'xw', 'TroubleToggle workspace_diagnostics', { silent = true, noremap = true, desc = 'Workspace diagnostics (Trouble)' }) +vim.keymap.set('n', 'xd', 'TroubleToggle document_diagnostics', { silent = true, noremap = true, desc = 'Document diagnostics (Trouble)' }) --- DAP keymaps -vim.keymap.set('n', '', ":lua require('dapui').toggle()") -vim.keymap.set('n', 'dc', ":lua require('dap').continue()") -vim.keymap.set('n', 'do', ":lua require('dap').step_over()") -vim.keymap.set('n', 'di', ":lua require('dap').step_into()") +-- DAP +vim.keymap.set('n', '', ":lua require('dapui').toggle()", { desc = 'Toggle DAP UI' }) +vim.keymap.set('n', 'dc', ":lua require('dap').continue()", { desc = 'DAP continue' }) +vim.keymap.set('n', 'do', ":lua require('dap').step_over()", { desc = 'DAP step over' }) +vim.keymap.set('n', 'di', ":lua require('dap').step_into()", { desc = 'DAP step into' }) vim.keymap.set('n', 'dk', function() require('dap.ui.widgets').hover() -end) +end, { desc = 'DAP hover value' }) vim.keymap.set('n', 'd?', function() local widgets = require 'dap.ui.widgets' widgets.centered_float(widgets.scopes) -end) -vim.keymap.set('n', 'du', ":lua require('dap').step_out()") -vim.keymap.set('n', 'dl', ":lua require('dapui').float_element()", { silent = true, noremap = true }) -vim.keymap.set('n', 'dt', ":lua require('dap').toggle_breakpoint()", { silent = true, noremap = true }) -vim.keymap.set('n', 'dm', ":lua require('dap-python').test_method()", { silent = true, noremap = true }) -vim.keymap.set('n', 'df', ":lua require('dap-python').test_class()", { silent = true, noremap = true }) +end, { desc = 'DAP scopes' }) +vim.keymap.set('n', 'du', ":lua require('dap').step_out()", { desc = 'DAP step out' }) +vim.keymap.set('n', 'dl', ":lua require('dapui').float_element()", { silent = true, noremap = true, desc = 'DAP floating window' }) +vim.keymap.set('n', 'dt', ":lua require('dap').toggle_breakpoint()", { silent = true, noremap = true, desc = 'Toggle breakpoint' }) +vim.keymap.set('n', 'dm', ":lua require('dap-python').test_method()", { silent = true, noremap = true, desc = 'DAP test method' }) +vim.keymap.set('n', 'df', ":lua require('dap-python').test_class()", { silent = true, noremap = true, desc = 'DAP test class' }) -- barbar -vim.keymap.set('n', '', 'BufferPrevious', { silent = true, noremap = true }) -vim.keymap.set('n', '', 'BufferNext', { silent = true, noremap = true }) -vim.keymap.set('n', '', 'BufferClose', { silent = true, noremap = true }) +vim.keymap.set('n', '', 'BufferPrevious', { silent = true, noremap = true, desc = 'Previous buffer' }) +vim.keymap.set('n', '', 'BufferNext', { silent = true, noremap = true, desc = 'Next buffer' }) +vim.keymap.set('n', '', 'BufferClose', { silent = true, noremap = true, desc = 'Close buffer' }) + local opts = { noremap = true, silent = true } -vim.keymap.set('n', '', 'BufferGoto 1', opts) -vim.keymap.set('n', '', 'BufferGoto 2', opts) -vim.keymap.set('n', '', 'BufferGoto 3', opts) -vim.keymap.set('n', '', 'BufferGoto 4', opts) -vim.keymap.set('n', '', 'BufferGoto 5', opts) -vim.keymap.set('n', '', 'BufferGoto 6', opts) -vim.keymap.set('n', '', 'BufferGoto 7', opts) -vim.keymap.set('n', '', 'BufferGoto 8', opts) -vim.keymap.set('n', '', 'BufferGoto 9', opts) -vim.keymap.set('n', '', 'BufferLast', opts) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 1', vim.tbl_extend('force', opts, { desc = 'Go to buffer 1' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 2', vim.tbl_extend('force', opts, { desc = 'Go to buffer 2' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 3', vim.tbl_extend('force', opts, { desc = 'Go to buffer 3' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 4', vim.tbl_extend('force', opts, { desc = 'Go to buffer 4' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 5', vim.tbl_extend('force', opts, { desc = 'Go to buffer 5' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 6', vim.tbl_extend('force', opts, { desc = 'Go to buffer 6' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 7', vim.tbl_extend('force', opts, { desc = 'Go to buffer 7' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 8', vim.tbl_extend('force', opts, { desc = 'Go to buffer 8' })) +vim.keymap.set('n', '', 'BufferLineGoToBuffer 9', vim.tbl_extend('force', opts, { desc = 'Go to buffer 9' })) +vim.keymap.set('n', '', 'BufferLast', vim.tbl_extend('force', opts, { desc = 'Go to last buffer' })) -- quickfix -vim.keymap.set('n', 'cn', ':cnext') -vim.keymap.set('n', 'cp', ':cprevious') +vim.keymap.set('n', 'cn', ':cnext', { desc = 'Next quickfix item' }) +vim.keymap.set('n', 'cp', ':cprevious', { desc = 'Previous quickfix item' }) -- markdown -vim.keymap.set('n', 'mp', ':MarkdownPreview') +vim.keymap.set('n', 'mp', ':MarkdownPreview', { desc = 'Markdown preview' }) --- git coauthors -vim.keymap.set('n', 'ga', ':Telescope coauthors') +-- git +vim.keymap.set('n', 'ga', ':Telescope coauthors', { desc = 'Select git co-authors' }) --- Comment.nvim keymaps -vim.api.nvim_set_keymap('n', '', 'lua require("Comment.api").toggle.linewise.current()', { noremap = true, silent = true }) -vim.api.nvim_set_keymap('v', '', 'lua require("Comment.api").toggle.linewise(vim.fn.visualmode())', { noremap = true, silent = true }) -vim.api.nvim_set_keymap('i', '', '', { noremap = true }) +-- AI model switching +vim.keymap.set('n', 'an', function() + _G.chatgpt_model = 'gpt-5-nano' + print 'ChatGPT → gpt-5-nano' +end, { desc = 'ChatGPT model: gpt-5-nano' }) --- Floaterm -vim.api.nvim_set_keymap('n', '', ':FloatermToggle', { noremap = true }) -vim.api.nvim_set_keymap('i', '', ':FloatermToggle', { noremap = true }) -vim.api.nvim_set_keymap('t', '', ':FloatermToggle', { noremap = true, silent = true }) +vim.keymap.set('n', 'ac', function() + _G.chatgpt_model = 'gpt-5.1-codex-mini' + print 'ChatGPT → gpt-5.1-codex-mini' +end, { desc = 'ChatGPT model: gpt-5.1-codex-mini' }) --- Neo-tree toggle +vim.keymap.set('n', 'ai', 'ChatGPT', { desc = 'Open ChatGPT prompt' }) + +-- delete backwards +vim.keymap.set({ 'i', 'c' }, '', '', { noremap = true, desc = 'Delete previous word' }) + +vim.keymap.set('n', '', 'BufferLineCycleNext', { desc = 'Go to next tab' }) +vim.keymap.set('n', '', 'BufferLineCyclePrev', { desc = 'Go backwards a tab' }) + +-- install treesitter parsers +require('nvim-treesitter').install { 'c', 'rust' } + +vim.keymap.set('n', 'tc', ':tabclose', { desc = 'Close current tab' }) +vim.keymap.set('n', 'fk', ':FloatermKill!', { desc = 'Kill all floaterm terminals' }) +vim.keymap.set('x', 'S', '(nvim-surround-visual)', { remap = true }, { desc = 'Surround selected text' }) + +-- yank binding +vim.api.nvim_set_keymap('n', 'Y', 'yy', { noremap = true, silent = true }) + +-- exit and save +vim.keymap.set('n', '', 'wqa') + +-- split views +vim.keymap.set('n', 'sv', 'vsplit') +vim.keymap.set('n', 'sh', 'split') + +-- signature help +vim.api.nvim_set_keymap('i', '', 'lua vim.lsp.buf.signature_help()', { noremap = true, silent = true }) +vim.api.nvim_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', { noremap = true, silent = true }) + +-- toggle neotree local function toggle_neotree() local manager = require 'neo-tree.sources.manager' local renderer = require 'neo-tree.ui.renderer' @@ -1062,65 +1438,18 @@ end _G.toggle_neotree = toggle_neotree vim.api.nvim_set_keymap('n', '', ':lua toggle_neotree()', { noremap = true, silent = true }) -vim.api.nvim_set_keymap('i', '', 'lua vim.lsp.buf.signature_help()', { noremap = true, silent = true }) -vim.api.nvim_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', { noremap = true, silent = true }) +-- Floaterm +vim.api.nvim_set_keymap('n', '', ':FloatermToggle', { noremap = true }) +vim.api.nvim_set_keymap('i', '', ':FloatermToggle', { noremap = true }) +vim.api.nvim_set_keymap('t', '', ':FloatermToggle', { noremap = true, silent = true }) -vim.api.nvim_create_augroup('EnsureTextWindowFocus', { clear = true }) -vim.api.nvim_create_autocmd('VimEnter', { - group = 'EnsureTextWindowFocus', - callback = function() - vim.defer_fn(function() - vim.cmd 'wincmd p' - end, 100) - end, -}) +-- Comment.nvim keymaps +vim.api.nvim_set_keymap('n', '', 'lua require("Comment.api").toggle.linewise.current()', { noremap = true, silent = true }) +vim.api.nvim_set_keymap('n', '', 'lua require("Comment.api").toggle.blockwise.current()', { noremap = true, silent = true }) +vim.api.nvim_set_keymap('v', '', 'lua require("Comment.api").toggle.linewise(vim.fn.visualmode())', { noremap = true, silent = true }) +vim.api.nvim_set_keymap('v', '', 'lua require("Comment.api").toggle.blockwise(vim.fn.visualmode())', { noremap = true, silent = true }) +vim.api.nvim_set_keymap('i', '', '', { noremap = true }) -vim.api.nvim_create_augroup('CppIndent', { clear = true }) -vim.api.nvim_create_autocmd('FileType', { - pattern = { 'cpp', 'c', 'cc', 'h', 'hpp' }, - group = 'CppIndent', - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.expandtab = true - end, -}) +-- git coauthors +vim.keymap.set('n', 'ga', ':Telescope coauthors') -vim.api.nvim_set_keymap('n', 'Y', 'yy', { noremap = true, silent = true }) -vim.api.nvim_set_keymap('i', '{', '{}', { noremap = true, silent = true }) -vim.keymap.set('n', '', 'wqa') - -vim.keymap.set('n', 'sv', 'vsplit') -vim.keymap.set('n', 'sh', 'split') - --- AI wrapper -local ai_enabled = true -vim.keymap.set('n', 'at', function() - ai_enabled = not ai_enabled - print(ai_enabled and 'AI enabled' or 'AI disabled') -end) - -local function ai_safe(cmd) - return function() - if not ai_enabled then - print 'AI is disabled' - return - end - vim.cmd(cmd) - end -end - -vim.keymap.set('n', 'ai', ai_safe 'ChatGPT') -vim.keymap.set('v', 'ac', ai_safe 'ChatGPTEditWithInstruction') -vim.keymap.set('v', 'ae', ai_safe 'ChatGPTExplain') - -vim.keymap.set('n', 'tn', ':tabnew') -vim.keymap.set('n', 'tc', ':tabclose') -vim.keymap.set('n', 'fk', ':FloatermKill!') - -vim.keymap.set('x', 'S', '(nvim-surround-visual)', { remap = true }) -vim.keymap.set('i', '', '', { noremap = true }) -vim.keymap.set('c', '', '', { noremap = true }) - -vim.keymap.set('n', '', 'BufferLineCycleNext') -vim.keymap.set('n', '', 'BufferLineCyclePrev')