~keving/dotfiles

ref: 3545ff72f5f02c298694406262575d443eecdddd dotfiles/.config/nvim/init.lua -rw-r--r-- 14.0 KiB
3545ff72 — Kevin Guillaumond Cosmetic changes in init.lua 10 months ago
                                                                                
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
local cmd = vim.cmd  -- to execute Vim commands e.g. cmd('pwd')
local g = vim.g      -- a table to access global variables

-- Leader namespaces - for related actions
-- b: Buffers
-- e: Edit file (init.lua, etc)
-- g: Go (code completion)
-- h: Git Hunks
-- r: Refactor
-- s: Spell checker, Source file (init.lua, etc), Sideways plugin
-- t: Tabs, Tests
g['mapleader'] = ','
g['mapleader'] = ','

local utils = require('utils')

-- Keep list of augroups
local augroup_defs = {}

-- Plugins
-- TODO make paq install itself here
vim.cmd 'packadd paq-nvim'         -- Load Paq
local paq = require'paq-nvim'.paq
paq{'savq/paq-nvim', opt=true}     -- Let Paq manage itself

-- General
paq 'scrooloose/nerdtree'     -- View of the file system
paq 'nvim-lua/popup.nvim'     -- Helper for other plugins
paq 'nvim-lua/plenary.nvim'   -- Helper for other plugins
paq 'nvim-telescope/telescope.nvim'
paq 'morhetz/gruvbox'         -- Color scheme
paq 'vim-airline/vim-airline' -- Status line at the bottom
paq 'mileszs/ack.vim'         -- ack/ag in vim
paq 'embear/vim-localvimrc'   -- Local vimrc files for project-specific settings

-- General programming
paq 'vim-syntastic/syntastic'  -- Syntax checker
paq 'tpope/vim-surround'       -- Act on surrounding things (e.g. quotes)
paq 'tpope/vim-repeat'         -- Repeat certain commands such as surround
paq 'tpope/vim-commentary'     -- Comment/uncomment code
paq 'janko/vim-test'           -- Run tests
paq 'tpope/vim-fugitive'       -- git integration
paq 'lewis6991/gitsigns.nvim'  -- Shows git diff in the 'gutter' (sign column)
paq 'neovim/nvim-lspconfig'    -- Code navigation
paq 'hrsh7th/nvim-compe'       -- Code completion
paq 'knsh14/vim-github-link'   -- Generate shareable file permalinks
paq{'nvim-treesitter/nvim-treesitter', run=':TSUpdate'} -- Parser generator (highlighting etc)

-- Python
paq 'numirias/semshi'          -- Syntax highlighting
paq 'nvie/vim-flake8'          -- Python style checker

-- PlantUML
paq 'aklt/plantuml-syntax'     -- Syntax highlighting

-- Load plugin-specific configs
require 'plugin_configs/nvim-lspconfig'
require 'plugin_configs/nvim-compe_config'  -- TODO figure out why just 'nvim-compe' doesn't work

require('gitsigns').setup()


-- Plugin configs

-- NERDTree
-- Shortcut to open NERDTree
utils.map('n', '<leader>ne', ':NERDTreeToggle<Enter>')

-- Ignore some files
cmd [[ let NERDTreeIgnore=['\.pyc$', '\~$', '\.o', '\.lo'] ]]

-- Automatically close NERDTree when you open a file
g['NERDTreeQuitOnOpen'] = 1

-- Automatically close a tab if the only remaining window is NERDTree
vim.cmd('autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif')

-- Automatically delete the buffer of the file you just deleted with NerdTree:
g['NERDTreeAutoDeleteBuffer'] = 1

-- Making it prettier
g['NERDTreeMinimalUI'] = 1
g['NERDTreeDirArrows'] = 1


-- Syntastic
g['syntastic_always_populate_loc_list'] = 1
g['syntastic_auto_loc_list'] = 1
g['syntastic_check_on_open'] = 1
g['syntastic_check_on_wq'] = 0

cmd "let g:syntastic_python_checkers = ['flake8', 'pylint']"

-- Show all levels of pylint messages
cmd 'let g:syntastic_quiet_messages = { "level": [] }'
cmd 'let g:syntastic_python_pylint_quiet_messages = { "level" : [] }'

-- TODO probably need something better, but might just disappear if I find a way
-- to run pylint and flake8 asynchronously.
utils.map('n', '<leader>l', ':SyntasticCheck<CR>', {silent = true})

-- Disable Syntastic for c files - reply on LSP instead
cmd 'let g:syntastic_ignore_files = [".c"]'


-- Telescope
-- Shortcut for 'go to buffer'
utils.map('n', 'gb', ':Telescope buffers<CR>')
utils.map('n', '<leader>ff', ':Telescope find_files<CR>')


-- Treesitter
require'nvim-treesitter.configs'.setup {
  highlight = {
    enable = true,
  },
  indent = {
    enable = false,
  },
  ensure_installed = {
    "c",
	"cpp",
  },
}


-- vim-test
-- Run tests in a split window
cmd "let g:test#strategy = 'neovim'"

-- vim-surround
-- Don't select extra space when working around quotes
-- https://github.com/tpope/vim-surround/issues/276
utils.map('n', [[ysa']], [[ys2i']])
utils.map('n', [[ysa"]], [[ys2i"]])
utils.map('n', [[ysa`]], [[ys2i`]])


--
-- General
--

-- Sets how many lines of history VIM has to remember
vim.o.history = 500

-- Access the system clipboard
cmd 'set clipboard+=unnamedplus'
-- vim.o.clipboard = vim.o.clipboard + { 'unnamedplus' }

-- Quickly edit/reload init.lua
utils.map('n', '<leader>ei', ':e ~/.config/nvim/init.lua<CR>', {silent = true})
utils.map('n', '<leader>si', ':luafile ~/.config/nvim/init.lua<CR>', {silent = true})
utils.map('n', '<leader>sc', ':luafile %<CR>', {silent = true})


--
-- User interface
--

-- Show the number of the current line and the relative number of the others
vim.o.number = true
vim.o.relativenumber = true

-- Show absolute numbers when in insert mode or losing focus
augroup_defs['number_toggle'] = {
    'BufEnter,FocusGained,InsertLeave * set relativenumber',
    'BufLeave,FocusLost,InsertEnter   * set norelativenumber'
}

-- Set 7 lines/columns to the cursor
vim.o.scrolloff = 7
vim.o.sidescrolloff = 7

-- First tab completes the longest common string; next tab completes the first alternative
vim.o.wildmode = 'longest:full,full'

-- Ignore compiled files and version control folders
local wildignore = '*.o,*~,*.pyc'
-- TODO not sure that's working
if vim.fn.has('win16') or vim.fn.has('win32') then
    wildignore = wildignore .. '.git\\*,.hg\\*,.svn\\*'
else
    wildignore = wildignore .. '*/.git/*,*/.hg/*,*/.svn/*,*/.DS_Store'
end
vim.o.wildignore = wildignore

-- Height of the command bar
vim.o.cmdheight = 2

-- A buffer becomes hidden when it is abandoned
vim.o.hidden = true

-- Configure backspace so it acts as it should act
vim.o.backspace = 'eol,start,indent'
cmd 'set whichwrap+=<,>,h,l'

-- Search
vim.o.ignorecase = true -- Ignore case when searching
vim.o.smartcase = true  -- When searching try to be smart about cases

-- Stop highlighting last search pattern
utils.map('n', '<leader><cr>', ':noh<cr>', {silent = true})

-- Don't redraw while executing macros
vim.o.lazyredraw = true

-- Show matching brackets when text indicator is over them
vim.o.showmatch = true

-- How many tenths of a second to blink when matching brackets
vim.o.matchtime = 2

-- Time in milliseconds to wait for a mapped sequence to complete.
vim.o.timeoutlen = 500

-- Update frequency for the sign column
vim.o.updatetime = 250

-- Add a bit extra margin to the left
vim.o.foldcolumn = '1'


-- Colors and Fonts
vim.o.cursorline = true
cmd 'colorscheme gruvbox'
vim.o.termguicolors = true

-- Use Unix as the standard file type
vim.o.fileformats = 'unix,dos,mac'


--
-- Text, tab and indent
--

-- Use spaces instead of tabs
vim.o.expandtab = true

-- 1 tab == 2 spaces
local indent = 2
vim.o.shiftwidth = indent
vim.o.tabstop = indent -- Number of visual spaces per TAB
vim.o.softtabstop = indent -- Number of spaces per TAB when editing
vim.o.shiftround = true -- Indenting rounds to a multiple of 2 (instead of just changing by 2)

-- Limit lines to 80 characters and still wrap longer lines
vim.o.linebreak = true
vim.o.textwidth = 80
vim.o.colorcolumn = '80'

vim.o.smartindent = true


--
-- Visual mode
--

-- Visual mode pressing * or # searches for the current selection
utils.map('v', '*', ':<C-u>call VisualSelection("", "")<CR>/<C-R>=@/<CR><CR>', {silent = true})
utils.map('v', '#', ':<C-u>call VisualSelection("", "")<CR>?<C-R>=@/<CR><CR>', {silent = true})


--
-- Terminal mode
--

-- Better command to switch from insert to normal mode
utils.map('t', '<C-o>', [[<C-\><C-n>]])


--
-- Moving around, tabs, windows and buffers
--

-- Map j to gj so vim behaves as expected with wrapped lines
-- But keep normal behaviour if doing something like 4j
cmd "nnoremap <expr> j v:count ? 'j' : 'gj'"
cmd "nnoremap <expr> k v:count ? 'k' : 'gk'"

-- Specify where splits should occur
vim.o.splitbelow = true
vim.o.splitright = true

 -- Smart way to move between windows
utils.map('n', '<C-j>', '<C-W>j')
utils.map('n', '<C-k>', '<C-W>k')
utils.map('n', '<C-h>', '<C-W>h')
utils.map('n', '<C-l>', '<C-W>l')

-- Close the current buffer
utils.map('n', '<leader>bd', ':Bclose<cr>')

-- Useful mappings for managing tabs
utils.map('n', '<leader>tn', ':tabnew<cr>')
utils.map('n', '<leader>to', ':tabonly<cr>')
utils.map('n', '<leader>tc', ':tabclose<cr>')
utils.map('n', '<leader>tm', ':tabmove ')
utils.map('n', '<leader>t<leader>', ':tabnext ')

-- Opens a new tab with the current buffer's path
utils.map('n', '<leader>te', ':tabedit <c-r>=expand("%:p:h")<cr>/')

-- Switch CWD to the directory of the open buffer
utils.map('n', '<leader>cd', ':cd %:p:h<cr>:pwd<cr>')

-- Specify the behavior when switching between buffers
vim.o.switchbuf = 'useopen,usetab,newtab'
vim.o.showtabline = 1

-- Return to last edit position when opening files
vim.cmd([[autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif]])


--
-- Editing mappings
--

-- Map Y to act like D and C, i.e. to yank until EOL, rather than act as yy,
-- which is the default
utils.map('n', 'Y', 'y$')

-- Don't write to yank buffer when deleting a single character
utils.map('n', 'x', '"_x')
utils.map('n', 'X', '"_X')

-- Delete trailing white space on save
function clean_extra_spaces()
  local save_cursor = vim.fn.getpos(".")
  local old_query = vim.fn.getreg("/")
  vim.cmd([[silent! %s/\s\+$//e]])
  vim.fn.setpos('.', save_cursor)
  vim.fn.setreg('/', old_query)
end

vim.cmd('autocmd BufWritePre *.txt,*.js,*.py,*.sh,*.lua :lua clean_extra_spaces()')


--
-- Code
--

-- Enable code folding
vim.o.foldmethod = 'indent'
vim.o.foldlevel = 99

-- Enable folding with the spacebar
utils.map('n', '<space>', 'za')

-- Show list of tags if there are multiples matches
-- https://stackoverflow.com/a/42078499/
utils.map('n', '<C-]>', 'g<C-]>')

-- Ruby autocomplete
vim.cmd('autocmd FileType ruby,eruby let g:rubycomplete_buffer_loading = 1')
vim.cmd('autocmd FileType ruby,eruby let g:rubycomplete_classes_in_global = 1')
vim.cmd('autocmd FileType ruby,eruby let g:rubycomplete_rails = 1')

-- Run tests
-- Using ,tj because ,tn is used by tabs
utils.map('n', '<leader>tj', ':TestNearest<CR>')
utils.map('n', '<leader>tf', ':TestFile<CR>')
utils.map('n', '<leader>ts', ':TestSuite<CR>')
utils.map('n', '<leader>tl', ':TestLast<CR>')
utils.map('n', '<leader>tg', ':TestVisit<CR>')

-- Toggle between source file and header file in C and C++
utils.map('n', '<leader>gt', ':lua header_file_toggle()<CR>', {silent=true})
function header_file_toggle()
  -- For "/rnd/hello.c", file dir is "/rnd", file name is "hello" and ext is "c"
  local current_file_dir = vim.api.nvim_exec([[echo expand('%:h')]], true)
  local current_file_name = vim.api.nvim_exec([[echo expand('%:t:r')]], true)
  local current_file_ext = vim.api.nvim_exec([[echo expand('%:e')]], true)

  -- TODO don't open a blank buffer if the file doesn't exist
  if current_file_ext == 'c' or current_file_ext == 'cc' then
    vim.cmd('edit ' .. current_file_dir .. '/' .. current_file_name .. '.h')
  elseif current_file_ext == 'h' then
    -- TODO If .cc file doesn't exist, try .cpp and .c
    vim.cmd('edit ' .. current_file_dir .. '/' .. current_file_name .. '.cc')
  end
end


-- Spell checking
-- Toggle and untoggle spell checking
utils.map('n', '<leader>ss', ':setlocal spell!<cr>')

-- Next misspelled word
utils.map('n', '<leader>sn', ']s')
-- Previous misspelled word
utils.map('n', '<leader>sp', '[s')
-- Add to dictionary
utils.map('n', '<leader>sa', 'zg')
-- Suggest corrections
utils.map('n', '<leader>s?', 'z=')
-- Replace with first correction
utils.map('n', '<leader>s1', 'z=1<CR><CR>')

utils.map('n', '<leader>se', ':setlocal spelllang=en_en<CR>')
utils.map('n', '<leader>sf', ':setlocal spelllang=fr<CR>')


--
-- Misc
--

-- Remove the Windows ^M - when the encodings gets messed up
utils.map('n', '<leader>m', "mmHmt:%s/<C-V><cr>//ge<cr>'tzt'm")

-- Quickly open a scratchpad for scribble
utils.map('n', '<leader>q', ':e ~/scratchpad<cr>')

-- Toggle paste mode on and off
utils.map('n', '<leader>pp', ':setlocal paste!<cr>')


-- Helper functions
-- Don't close window, when deleting a buffer
-- TODO find out how to write in lua (can't use <SID> inside nvim_exec)
-- command! Bclose call <SID>BufcloseCloseIt()
-- function! <SID>BufcloseCloseIt()
--    let l:currentBufNum = bufnr("%")
--    let l:alternateBufNum = bufnr("#")

--    if buflisted(l:alternateBufNum)
--      buffer #
--    else
--      bnext
--    endif

--    if bufnr("%") == l:currentBufNum
--      new
--    endif

--    if buflisted(l:currentBufNum)
--      execute("bdelete! ".l:currentBufNum)
--    endif
-- endfunction

vim.api.nvim_exec([[
function! CmdLine(str)
    exe "menu Foo.Bar :" . a:str
    emenu Foo.Bar
    unmenu Foo
endfunction

function! VisualSelection(direction, extra_filter) range
    let l:saved_reg = @"
    execute "normal! vgvy"

    let l:pattern = escape(@", "\\/.*'$^~[]")
    let l:pattern = substitute(l:pattern, "\n$", "", "")

    if a:direction == 'gv'
        call CmdLine("Ack '" . l:pattern . "' " )
    elseif a:direction == 'replace'
        call CmdLine("%s" . '/'. l:pattern . '/')
    endif

    let @/ = l:pattern
    let @" = l:saved_reg
endfunction
]], false)


-- Local configuration
-- TODO make it optional to have that file
require 'local_init'
-- assert(io.open('lua/local_init.lua', 'r'))




_G.tab_complete = function()
  if vim.fn.pumvisible() == 1 then
    return utils.t "<C-n>"
  elseif utils.check_back_space() then
    return utils.t "<Tab>"
  else
    return vim.fn['compe#complete']()
  end
end

_G.s_tab_complete = function()
  if vim.fn.pumvisible() == 1 then
    return utils.t "<C-p>"
  else
    return utils.t "<S-Tab>"
  end
end

utils.map("i", "<Tab>", "v:lua.tab_complete()", {expr = true})
utils.map("s", "<Tab>", "v:lua.tab_complete()", {expr = true})
utils.map("i", "<S-Tab>", "v:lua.s_tab_complete()", {expr = true})
utils.map("s", "<S-Tab>", "v:lua.s_tab_complete()", {expr = true})

-- Create augroups
utils.nvim_create_augroups(augroup_defs)


-- TODO
-- Rewrite usages of cmd and nvim_exec in Lua
-- Tidy code with plugin-specific config to its own files, like https://github.com/ibhagwan/nvim-lua