aboutsummaryrefslogtreecommitdiff
path: root/user/nvim/init.lua
blob: a05a7f9ff9e2b5b5d9aac2ccb31c43d3cb5a99b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
-- Don't break words in the middle.
vim.opt.linebreak = true

-- Use the system clipboard.
vim.opt.clipboard = "unnamedplus"

-- Ignore case in search unless the pattern contains uppercase.
vim.opt.ignorecase = true
vim.opt.smartcase = true

-- Color scheme
require('vscode').setup({
  -- Enable transparent background.
  transparent = true,
})
vim.cmd.colorscheme "vscode"

-- File picker
local pick = require('mini.pick')
-- Disable icons in mini.pick (my font doesn't have them).
pick.setup({ source = { show = pick.default_show } })
-- Reuse Neovim's popup-menu selection color for mini.pick's selected item.
vim.api.nvim_set_hl(0, 'MiniPickMatchCurrent', { link = 'PmenuSel' })

-- Enable language servers when they are available (for example, from a nix shell).
local language_servers = {
  { name = 'rust_analyzer', cmd = { 'rust-analyzer' } },
  { name = 'pyright', cmd = { 'pyright-langserver', '--stdio' } },
  { name = 'ts_ls', cmd = { 'typescript-language-server', '--stdio' } },
  { name = 'gopls', cmd = { 'gopls' } },
  { name = 'nixd', cmd = { 'nixd' } },
  { name = 'svelte', cmd = { 'svelteserver', '--stdio' } },
}

for _, server in ipairs(language_servers) do
  local command = vim.fn.exepath(server.cmd[1])
  if command ~= '' then
    server.cmd[1] = command
    vim.lsp.config(server.name, { cmd = server.cmd })
    vim.lsp.enable(server.name)
  end
end

require('blink.cmp').setup({
  keymap = {
    preset = 'default',
    ['<CR>'] = { 'accept', 'fallback' },
  },
  sources = {
    -- Only show completion items provided by an attached LSP. This disables
    -- blink.cmp's default buffer/path/snippet sources, which otherwise trigger
    -- completions in plain text and Markdown files.
    default = { 'lsp' },
  },
  completion = {
    documentation = { auto_show = true },
  },
})

-- Keyboard shortcuts

-- Clear search highlighting with Escape.
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>', { desc = 'Clear search highlight' })

vim.keymap.set('n', '<C-p>', function()
  pick.builtin.files()
end, { desc = 'Pick files' })

vim.keymap.set('n', 'gd', vim.lsp.buf.definition, {
  desc = 'LSP: Go to definition',
})
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, {
  desc = 'LSP: Go to declaration',
})

-- Disable netrw's directory browser; directory arguments are handled below with MiniPick.
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- When Neovim is started with a directory, use MiniPick instead of netrw.
vim.api.nvim_create_autocmd('VimEnter', {
  callback = function()
    local dir = vim.fn.argc() == 1 and vim.fn.argv(0) or nil
    if not dir or vim.fn.isdirectory(dir) == 0 then
      return
    end

    vim.fn.chdir(vim.fn.fnamemodify(dir, ':p'))

    local buf = vim.api.nvim_get_current_buf()
    vim.cmd.enew()
    vim.api.nvim_buf_delete(buf, { force = true })

    pick.builtin.files(nil, {
      source = {
        -- Without this filetype detection doesn't run for some reason.
        choose = function(path)
          vim.schedule(function()
            vim.cmd.edit(vim.fn.fnameescape(path))
          end)
        end,
      },
    })
  end,
})