vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' vim.opt.number = true vim.opt.mouse = 'a' vim.opt.showmode = false vim.opt.clipboard = 'unnamedplus' vim.opt.breakindent = true vim.opt.undofile = true vim.opt.ignorecase = true vim.opt.smartcase = true vim.opt.signcolumn = 'yes' vim.opt.updatetime = 250 vim.opt.timeoutlen = 300 vim.opt.splitright = true vim.opt.splitbelow = true vim.opt.list = true vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } vim.opt.inccommand = 'split' vim.opt.autoread = true vim.opt.cursorline = true vim.opt.scrolloff = 10 vim.opt.termguicolors = true local path_package = vim.fn.stdpath 'data' .. '/site/' local mini_path = path_package .. 'pack/deps/start/mini.nvim' if not vim.uv.fs_stat(mini_path) then vim.cmd 'echo "Installing mini.nvim" | redraw' vim.fn.system { 'git', 'clone', '--filter=blob:none', 'https://github.com/echasnovski/mini.nvim', mini_path } vim.cmd 'packadd mini.nvim | helptags ALL' end require('mini.deps').setup { path = { package = path_package } } local add, now, later = MiniDeps.add, MiniDeps.now, MiniDeps.later add 'folke/snacks.nvim' add 'stevearc/quicker.nvim' add 'stevearc/oil.nvim' add 'A7Lavinraj/fyler.nvim' add 'williamboman/mason.nvim' add 'williamboman/mason-lspconfig.nvim' add 'neovim/nvim-lspconfig' add 'folke/lazydev.nvim' add 'Bilal2453/luvit-meta' add 'NeogitOrg/neogit' add 'nvim-lua/plenary.nvim' add 'sindrets/diffview.nvim' add 'folke/which-key.nvim' add { source = 'saghen/blink.cmp', checkout = 'v1.8.0' } add 'stevearc/conform.nvim' add 'coder/claudecode.nvim' add 'mbbill/undotree' add 'cbochs/grapple.nvim' add 'fang2hou/blink-copilot' add 'aserowy/tmux.nvim' add 'NMAC427/guess-indent.nvim' add 'wakatime/vim-wakatime' add 'OXY2DEV/markview.nvim' add { source = 'R-nvim/R.nvim', depends = { 'nvim-treesitter/nvim-treesitter' } } add 'nvim-treesitter/nvim-treesitter' add 'nvim-treesitter/nvim-treesitter-textobjects' -- color themes add 'EdenEast/nightfox.nvim' now(function() require('mail-count').setup { accounts = { { name = 'U', query = 'tag:unread AND path:uchicago/**' }, { name = 'P', query = 'tag:unread AND path:personal/**' }, }, interval = 60000, -- 60 seconds } require('mini.statusline').setup { use_icons = true, content = { active = function() local mode, mode_hl = MiniStatusline.section_mode { trunc_width = 120 } local git = MiniStatusline.section_git { trunc_width = 40 } local diff = MiniStatusline.section_diff { trunc_width = 75 } local diagnostics = MiniStatusline.section_diagnostics { trunc_width = 75 } local lsp = MiniStatusline.section_lsp { trunc_width = 75 } local filename = MiniStatusline.section_filename { trunc_width = 140 } local fileinfo = MiniStatusline.section_fileinfo { trunc_width = 120 } local location = MiniStatusline.section_location { trunc_width = 75 } local search = MiniStatusline.section_searchcount { trunc_width = 75 } local mail = require('mail-count').get() return MiniStatusline.combine_groups { { hl = mode_hl, strings = { mode } }, { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, '%<', { hl = 'MiniStatuslineFilename', strings = { filename } }, '%=', { hl = 'MiniStatuslineMail', strings = { mail } }, { hl = 'MiniStatuslineFileinfo', strings = { fileinfo } }, { hl = mode_hl, strings = { search, location } }, } end, }, } require('mini.icons').setup { extension = { lua = { glyph = '󰢱', hl = 'MiniIconsAzure' }, }, file = { ['init.lua'] = { glyph = '󰢱', hl = 'MiniIconsAzure' }, }, default = { file = { glyph = '󰈔', hl = 'MiniIconsGrey' }, directory = { glyph = '󰉋', hl = 'MiniIconsBlue' }, }, } -- require('nightfox').setup {} -- vim.cmd.colorscheme 'nightfox' require('raytheme').setup { transparent = false, italic_comments = true, bold_keywords = false, } vim.cmd.colorscheme 'noctis_azureus_ghostty' end) later(function() require('guess-indent').setup {} require('snacks').setup { picker = { prompt = '󰍉 ', icons = { enabled = true, }, win = { input = { keys = { [''] = false, }, }, }, }, } require('quicker').setup { keys = { { '>', function() require('quicker').expand { before = 2, after = 2, add_to_existing = true } end, desc = 'Expand quickfix context', }, { '<', function() require('quicker').collapse() end, desc = 'Collapse quickfix context', }, }, } -- Function to show current directory in oil winbar _G.get_oil_winbar = function() local bufnr = vim.api.nvim_win_get_buf(vim.g.statusline_winid or 0) local dir = require('oil').get_current_dir(bufnr) if dir then return vim.fn.fnamemodify(dir, ':~') else return vim.api.nvim_buf_get_name(bufnr) end end require('oil').setup { view_options = { show_hidden = true }, columns = { 'icon', 'permissions', 'size', 'mtime', }, win_options = { winbar = '%!v:lua.get_oil_winbar()', }, float = { padding = 2, max_width = 0, max_height = 10, border = 'rounded', win_options = { winblend = 0, }, override = function(conf) conf.anchor = 'SW' conf.row = vim.o.lines - vim.o.cmdheight - 1 conf.col = 0 conf.width = vim.o.columns return conf end, }, keymaps = { ['q'] = 'actions.close', [''] = 'actions.close', ['D'] = 'dd', -- Emacs-like navigation (up/down) [''] = 'k', [''] = 'j', -- Preview with Ctrl+Space [''] = 'actions.preview', -- Copy current directory path to clipboard ['gy'] = { callback = function() local oil = require 'oil' local dir = oil.get_current_dir() if dir then vim.fn.setreg('+', dir) vim.notify('Copied: ' .. dir, vim.log.levels.INFO) end end, desc = 'Copy current directory path', }, }, } require('fyler').setup { views = { ---@diagnostic disable finder = { confirm_simple = true, close_on_select = false, watcher = { enabled = true, }, win = { kind = 'replace', kinds = { split_left_most = { width = '10%', win_opts = { winfixwidth = true, }, }, }, }, }, ---@diagnostic enable }, } require('find-file').setup { max_matches = 8, on_directory_enter = function(dir) require('oil').open(dir) end, } require('compile-mode').setup {} require('neogit').setup { integrations = { diffview = true, snacks = true, }, } require('diffview').setup { enhanced_diff_hl = true, } require('which-key').setup { preset = 'modern', icons = { separator = '→', group = '', }, win = { border = 'rounded', }, } require('claudecode').setup {} require('grapple').setup { scope = 'git_branch', icons = false, } require('tmux').setup {} -- Ensure treesitter parsers are installed require('nvim-treesitter.configs').setup { ensure_installed = { 'r', 'rnoweb', 'lua', 'python', 'rust', 'c', 'cpp', 'javascript', 'typescript', 'tsx', 'json', 'yaml', 'html', 'css', 'markdown', 'markdown_inline', 'nix', 'bash', 'vim', 'vimdoc', 'query', 'diff', 'git_rebase', 'gitcommit', }, auto_install = true, highlight = { enable = true }, incremental_selection = { enable = true, keymaps = { init_selection = 'vv', node_incremental = '', scope_incremental = '', node_decremental = '', }, }, textobjects = { select = { enable = true, lookahead = true, keymaps = { ['af'] = { query = '@function.outer', desc = 'Select outer function' }, ['if'] = { query = '@function.inner', desc = 'Select inner function' }, ['ac'] = { query = '@class.outer', desc = 'Select outer class' }, ['ic'] = { query = '@class.inner', desc = 'Select inner class' }, ['aa'] = { query = '@parameter.outer', desc = 'Select outer argument' }, ['ia'] = { query = '@parameter.inner', desc = 'Select inner argument' }, ['ai'] = { query = '@conditional.outer', desc = 'Select outer conditional' }, ['ii'] = { query = '@conditional.inner', desc = 'Select inner conditional' }, ['al'] = { query = '@loop.outer', desc = 'Select outer loop' }, ['il'] = { query = '@loop.inner', desc = 'Select inner loop' }, ['ab'] = { query = '@block.outer', desc = 'Select outer block' }, ['ib'] = { query = '@block.inner', desc = 'Select inner block' }, }, }, move = { enable = true, set_jumps = true, goto_next_start = { [']f'] = { query = '@function.outer', desc = 'Next function start' }, [']c'] = { query = '@class.outer', desc = 'Next class start' }, [']a'] = { query = '@parameter.inner', desc = 'Next argument' }, }, goto_next_end = { [']F'] = { query = '@function.outer', desc = 'Next function end' }, [']C'] = { query = '@class.outer', desc = 'Next class end' }, }, goto_previous_start = { ['[f'] = { query = '@function.outer', desc = 'Previous function start' }, ['[c'] = { query = '@class.outer', desc = 'Previous class start' }, ['[a'] = { query = '@parameter.inner', desc = 'Previous argument' }, }, goto_previous_end = { ['[F'] = { query = '@function.outer', desc = 'Previous function end' }, ['[C'] = { query = '@class.outer', desc = 'Previous class end' }, }, }, swap = { enable = true, swap_next = { ['a'] = { query = '@parameter.inner', desc = 'Swap with next argument' }, }, swap_previous = { ['A'] = { query = '@parameter.inner', desc = 'Swap with previous argument' }, }, }, }, } require('r').setup { hook = { on_filetype = function() vim.keymap.set('n', 'rs', 'RStart', { buffer = true, desc = 'Start R' }) vim.keymap.set('n', 'rq', 'RClose', { buffer = true, desc = 'Close R' }) vim.keymap.set('n', 'rl', 'RSendLine', { buffer = true, desc = 'Send line to R' }) vim.keymap.set('v', 'rs', 'RSendSelection', { buffer = true, desc = 'Send selection to R' }) vim.keymap.set('n', 'rf', 'RSendFile', { buffer = true, desc = 'Send file to R' }) vim.keymap.set('n', 'ro', 'RShowArgs', { buffer = true, desc = 'Show function args' }) vim.keymap.set('n', 'rh', 'RHelp', { buffer = true, desc = 'R help' }) end, }, } end) later(function() require('conform').setup { formatters_by_ft = { lua = { 'stylua' }, python = { 'isort', 'black' }, rust = { 'rustfmt' }, javascript = { 'prettierd', 'prettier', stop_after_first = true }, typescript = { 'prettierd', 'prettier', stop_after_first = true }, javascriptreact = { 'prettierd', 'prettier', stop_after_first = true }, typescriptreact = { 'prettierd', 'prettier', stop_after_first = true }, json = { 'prettierd', 'prettier', stop_after_first = true }, yaml = { 'prettierd', 'prettier', stop_after_first = true }, markdown = { 'prettierd', 'prettier', stop_after_first = true }, html = { 'prettierd', 'prettier', stop_after_first = true }, css = { 'prettierd', 'prettier', stop_after_first = true }, c = { 'clang_format' }, cpp = { 'clang_format' }, nix = { 'nixfmt' }, }, } vim.api.nvim_create_user_command( 'Format', function(_) require('conform').format { async = true, lsp_format = 'fallback' } end, { desc = 'Format current buffer' } ) end) later(function() local has_words_before = function() local col = vim.api.nvim_win_get_cursor(0)[2] if col == 0 then return false end local line = vim.api.nvim_get_current_line() return line:sub(col, col):match '%s' == nil end require('blink.cmp').setup { keymap = { preset = 'none', [''] = { 'show', 'show_documentation', 'hide_documentation' }, [''] = { 'hide' }, [''] = { 'accept', 'fallback' }, [''] = { function(cmp) if has_words_before() then return cmp.insert_next() end end, 'fallback', }, [''] = { 'insert_prev' }, [''] = { 'select_next', 'fallback' }, [''] = { 'select_prev', 'fallback' }, }, appearance = { use_nvim_cmp_as_default = true, nerd_font_variant = 'mono', }, sources = { default = { 'lsp', 'path', 'snippets', 'buffer', 'copilot' }, providers = { copilot = { name = 'copilot', module = 'blink-copilot', async = true, }, }, }, completion = { trigger = { show_on_trigger_character = true, }, menu = { enabled = true, border = 'rounded', }, list = { selection = { preselect = false, }, cycle = { from_top = false, }, }, documentation = { window = { border = 'rounded', }, auto_show = true, auto_show_delay_ms = 200, }, }, signature = { enabled = true, window = { border = 'rounded', }, }, } end) later( function() require('markview').setup { markdown_inline = { checkboxes = { checked = { text = '󰗠', hl = 'MarkviewCheckboxChecked', scope_hl = 'MarkviewCheckboxStriked', }, }, }, } end ) later(function() require('mason').setup { ui = { border = 'rounded', icons = { package_installed = '✓', package_pending = '➜', package_uninstalled = '✗', }, }, } require('mason-lspconfig').setup { ensure_installed = { 'lua_ls', -- Lua 'pyright', -- Python 'rust_analyzer', -- Rust 'clangd', -- C/C++ 'copilot', 'marksman', -- Markdown + Zettelkasten }, automatic_installation = true, } -- Ensure formatters are installed local mason_registry = require 'mason-registry' local formatters = { 'stylua', } for _, formatter in ipairs(formatters) do local package = mason_registry.get_package(formatter) if not package:is_installed() then package:install() end end -- LSP keybindings and options vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('UserLspConfig', {}), callback = function(ev) local opts = { buffer = ev.buf } vim.keymap.set('n', 'gd', function() require('snacks').picker.lsp_definitions() end, vim.tbl_extend('force', opts, { desc = 'Goto Definition' })) vim.keymap.set('n', 'gD', function() require('snacks').picker.lsp_declarations() end, vim.tbl_extend('force', opts, { desc = 'Goto Declaration' })) vim.keymap.set('n', 'gr', function() require('snacks').picker.lsp_references() end, vim.tbl_extend('force', opts, { desc = 'References', nowait = true })) vim.keymap.set('n', 'gI', function() require('snacks').picker.lsp_implementations() end, vim.tbl_extend('force', opts, { desc = 'Goto Implementation' })) vim.keymap.set( 'n', 'gy', function() require('snacks').picker.lsp_type_definitions() end, vim.tbl_extend('force', opts, { desc = 'Goto T[y]pe Definition' }) ) vim.keymap.set('n', 'gai', function() require('snacks').picker.lsp_incoming_calls() end, vim.tbl_extend('force', opts, { desc = 'C[a]lls Incoming' })) vim.keymap.set('n', 'gao', function() require('snacks').picker.lsp_outgoing_calls() end, vim.tbl_extend('force', opts, { desc = 'C[a]lls Outgoing' })) vim.keymap.set('n', 'K', vim.lsp.buf.hover, vim.tbl_extend('force', opts, { desc = 'Hover documentation (press K again to focus)' })) -- vim.keymap.set('n', '', vim.lsp.buf.signature_help, vim.tbl_extend('force', opts, { desc = 'Signature help' })) vim.keymap.set('n', 'rn', vim.lsp.buf.rename, vim.tbl_extend('force', opts, { desc = 'Rename symbol' })) vim.keymap.set({ 'n', 'v' }, 'ca', vim.lsp.buf.code_action, vim.tbl_extend('force', opts, { desc = 'Code action' })) vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, vim.tbl_extend('force', opts, { desc = 'Previous diagnostic' })) vim.keymap.set('n', ']d', vim.diagnostic.goto_next, vim.tbl_extend('force', opts, { desc = 'Next diagnostic' })) vim.keymap.set('n', 'd', vim.diagnostic.open_float, vim.tbl_extend('force', opts, { desc = 'Show diagnostic' })) end, }) -- Diagnostic UI improvements vim.diagnostic.config { virtual_text = true, signs = true, underline = true, update_in_insert = false, severity_sort = true, float = { border = 'rounded', source = 'always', }, } -- Add borders to hover windows local orig_util_open_floating_preview = vim.lsp.util.open_floating_preview function vim.lsp.util.open_floating_preview(contents, syntax, opts, ...) opts = opts or {} opts.border = opts.border or 'rounded' return orig_util_open_floating_preview(contents, syntax, opts, ...) end -- Setup lazydev for better plugin type support require('lazydev').setup { library = { { path = 'luvit-meta/library', words = { 'vim%.uv' } }, }, } -- Setup language servers using vim.lsp.config -- Lua (settings in .luarc.json, library paths handled by lazydev) vim.lsp.config.lua_ls = { cmd = { 'lua-language-server' }, root_markers = { '.luarc.json', '.luarc.jsonc', '.luacheckrc', '.stylua.toml', 'stylua.toml', 'selene.toml', 'selene.yml', '.git' }, } -- TypeScript/JavaScript vim.lsp.config.ts_ls = { cmd = { 'typescript-language-server', '--stdio' }, root_markers = { 'package.json', 'tsconfig.json', 'jsconfig.json', '.git' }, } -- Python vim.lsp.config.pyright = { cmd = { 'pyright-langserver', '--stdio' }, root_markers = { 'pyproject.toml', 'setup.py', 'setup.cfg', 'requirements.txt', 'Pipfile', '.git' }, } -- Rust vim.lsp.config.rust_analyzer = { cmd = { 'rust-analyzer' }, root_markers = { 'Cargo.toml', 'rust-project.json', '.git' }, } -- C/C++ vim.lsp.config.clangd = { cmd = { 'clangd', '--background-index', '--clang-tidy', '--header-insertion=iwyu' }, root_markers = { 'compile_commands.json', 'compile_flags.txt', '.clangd', '.git' }, } -- Nix vim.lsp.config.nixd = { cmd = { 'nixd' }, root_markers = { 'flake.nix', 'default.nix', 'shell.nix', '.git' }, } -- Markdown (marksman) vim.lsp.config.marksman = { cmd = { 'marksman', 'server' }, filetypes = { 'markdown', 'markdown.mdx' }, root_markers = { '.marksman.toml', '.git', '.editorconfig' }, } -- R vim.lsp.config.r_language_server = { cmd = { 'R', '--slave', '-e', 'languageserver::run()' }, filetypes = { 'r', 'rmd' }, root_markers = { '.Rproj', 'DESCRIPTION', '.git' }, } -- Enable language servers vim.lsp.enable { 'lua_ls', 'ts_ls', 'pyright', 'rust_analyzer', 'clangd', 'copilot', 'nixd', 'marksman', 'r_language_server' } end) local map = function(mode, lhs, rhs, opts) if type(opts) == 'string' then opts = { desc = opts } end require('snacks').keymap.set(mode, lhs, rhs, opts) end map('n', 'ex', function() require('fyler').toggle { kind = 'split_left_most' } end, 'Toggle file tree') map('n', 'fs', 'w', 'Save file') map('n', 'ff', function() require('find-file').open() end, 'Find file') map('n', 'fr', function() require('snacks').picker.recent() end, 'Find recent file') map('n', ':', function() require('snacks').picker.command_history() end, 'Command history') -- map('n', 'ex', function() require('snacks').explorer() end, 'Toggle file tree') map('n', 'bb', function() require('snacks').picker.buffers() end, 'List buffers') map('n', '', function() require('snacks').picker.buffers() end, 'List buffers') map('n', 'bd', function() require('snacks').bufdelete() end, 'Buffer delete') map('n', '.', function() require('snacks').scratch() end, 'Scratch buffer') map('n', 'sf', function() require('snacks').picker.git_files() end, 'Search file') map('n', 'sg', function() require('snacks').picker.grep() end, 'Search grep') map('n', 'sw', function() require('snacks').picker.grep_word() end, 'Search grep word') map('n', 'sb', function() require('snacks').picker.lines() end, 'Buffer lines') map('n', 'sB', function() require('snacks').picker.lines() end, 'Grep open buffers') map('n', 'ls', function() require('snacks').picker.lsp_symbols() end, 'LSP Symbols') map('n', 'lS', function() require('snacks').picker.lsp_workspace_symbols() end, 'LSP Workspace Symbols') map('n', 'zz', function() require('snacks').zen() end, 'Toggle zen mode') map('n', 'zm', function() require('snacks').zen.zoom() end, 'Toggle Zoom') map('n', 'qq', function() require('quicker').open { focus = true } end, 'Open/focus quickfix') map('n', 'ql', function() require('quicker').toggle { loclist = true } end, 'Toggle loclist') map('n', 'cc', function() require('compile-mode').compile() end, 'Compile') map('n', 'cC', function() require('compile-mode').recompile() end, 'Recompile') map('n', 'cr', 'source $MYVIMRC', 'Reload config') map('n', 'ce', 'edit $MYVIMRC', 'Edit config') map('n', 'ch', 'checkhealth', 'Check health') map('n', 'cf', 'Format', 'Format buffer') -- git map('n', 'gg', function() require('neogit').open() end, 'Open Neogit') map('n', 'gb', function() require('snacks').picker.git_branches() end, 'Git Branches') map('n', 'gl', function() require('snacks').picker.git_log() end, 'Git Log') map('n', 'gL', function() require('snacks').picker.git_log_file() end, 'Git Log File') map('n', 'gs', function() require('snacks').picker.git_status() end, 'Git Status') map('n', 'gS', function() require('snacks').picker.git_stash() end, 'Git Stash') -- gh map('n', 'gd', function() require('snacks').picker.git_diff() end, 'Git Diff (Hunks)') map('n', 'gi', function() require('snacks').picker.gh_issue() end, 'GitHub Issues (open)') map('n', 'gI', function() require('snacks').picker.gh_issue { state = 'all' } end, 'GitHub Issues (all)') map('n', 'gp', function() require('snacks').picker.gh_pr() end, 'GitHub Pull Requests (open)') map('n', 'gP', function() require('snacks').picker.gh_pr { state = 'all' } end, 'GitHub Pull Requests (all)') map('n', 'ut', 'UndotreeToggle', 'Toggle undotree') -- Grapple keymaps (harpoon-style) map('n', 'ma', 'Grapple toggle', 'Grapple toggle tag') map('n', 'mm', 'Grapple toggle_tags', 'Grapple tags menu') map('n', 'm1', 'Grapple select index=1', 'Grapple select 1') map('n', 'm2', 'Grapple select index=2', 'Grapple select 2') map('n', 'm3', 'Grapple select index=3', 'Grapple select 3') map('n', 'm4', 'Grapple select index=4', 'Grapple select 4') map('n', 'mn', 'Grapple cycle_tags next', 'Grapple next tag') map('n', 'mp', 'Grapple cycle_tags prev', 'Grapple prev tag') map('n', 'mga', 'Grapple toggle scope=global', 'Grapple add global tag') map('n', 'mgm', 'Grapple toggle_tags scope=global', 'Grapple global tags menu') -- Claude Code keymaps map('n', 'ac', 'ClaudeCode', 'Toggle Claude') map('n', 'af', 'ClaudeCodeFocus', 'Focus Claude') map('n', 'ar', 'ClaudeCode --resume', 'Resume Claude') map('n', 'aC', 'ClaudeCode --continue', 'Continue Claude') map('n', 'am', 'ClaudeCodeSelectModel', 'Select Claude model') map('n', 'ab', 'ClaudeCodeAdd %', 'Add current buffer') map('v', 'as', 'ClaudeCodeSend', 'Send to Claude') map('n', 'aa', 'ClaudeCodeDiffAccept', 'Accept diff') map('n', 'ad', 'ClaudeCodeDiffDeny', 'Deny diff') -- File tree specific keymap for Claude Code vim.api.nvim_create_autocmd('FileType', { pattern = { 'oil' }, callback = function() vim.keymap.set('n', 'as', 'ClaudeCodeTreeAdd', { buffer = true, desc = 'Add file to Claude' }) end, }) map('n', 'wh', 'h', 'Window left') map('n', 'wj', 'j', 'Window down') map('n', 'wk', 'k', 'Window up') map('n', 'wl', 'l', 'Window right') map('n', 'ws', 'split', 'Split window horizontally') map('n', 'wv', 'vsplit', 'Split window vertically') map('n', 'wq', 'q', 'Close window') -- Visual mode map('v', '', function() require('tmux').move_left() end, 'Move to left tmux pane') map('v', '', function() require('tmux').move_right() end, 'Move to right tmux pane') map('v', '', function() require('tmux').move_bottom() end, 'Move to bottom tmux pane') map('v', '', function() require('tmux').move_top() end, 'Move to top tmux pane') -- Terminal mode map('t', '', function() require('tmux').move_left() end, 'Move to left tmux pane') map('t', '', function() require('tmux').move_right() end, 'Move to right tmux pane') -- C-j is Shift+Enter in terminal mode, so we avoid mapping it -- map('t', '', function() require('tmux').move_bottom() end, 'Move to bottom tmux pane') -- map('t', '', function() require('tmux').move_top() end, 'Move to top tmux pane') map('t', '', '', 'Unfocus terminal and return to editor') -- Auto commands vim.api.nvim_create_autocmd('QuickFixCmdPost', { callback = function() vim.cmd 'redraw!' vim.schedule(function() require('quicker').open { focus = true } end) end, }) vim.api.nvim_create_autocmd({ 'FocusGained', 'BufEnter' }, { command = "if mode() != 'c' | checktime | endif", pattern = '*', }) -- Restore gitrebase keybindings (overridden by clipboard=unnamedplus) vim.api.nvim_create_autocmd('FileType', { pattern = 'gitrebase', callback = function() local opts = { buffer = true, silent = true } vim.keymap.set('n', 'p', 'Pick', opts) vim.keymap.set('n', 'r', 'Reword', opts) vim.keymap.set('n', 'e', 'Edit', opts) vim.keymap.set('n', 's', 'Squash', opts) vim.keymap.set('n', 'f', 'Fixup', opts) vim.keymap.set('n', 'd', 'Drop', opts) vim.keymap.set('n', 'x', 'Exec', opts) vim.keymap.set('n', '', 'move +1', opts) vim.keymap.set('n', '', 'move -2', opts) vim.keymap.set('n', '', 'move +1', opts) vim.keymap.set('n', '', 'move -2', opts) end, })