88cc595583
only overwrite makeprg to just if justfile is found, otherwise default to the default 'make' or whatever else makeprg was selected by the compiler plugin
1131 lines
38 KiB
Lua
1131 lines
38 KiB
Lua
-- vim:foldmethod=marker
|
|
|
|
local function get_python_venv_path() --{{{1
|
|
return vim.fn.stdpath('config') .. '/.venv/bin/python'
|
|
end
|
|
|
|
vim.g.python3_host_prog = get_python_venv_path()
|
|
|
|
-- POPULATE QFLIST ON ERROR {{{1
|
|
do
|
|
local function full_trace()
|
|
local lines = {}
|
|
local level = 2
|
|
while true do
|
|
local info = debug.getinfo(level, "Sln")
|
|
if not info then break end
|
|
local src = info.source or "?"
|
|
local file = src:gsub("^@", "") -- remove @ prefix
|
|
local line = string.format(
|
|
"%s:%d: in %s",
|
|
file,
|
|
info.currentline or 0,
|
|
info.name or "?"
|
|
)
|
|
table.insert(lines, line)
|
|
level = level + 1
|
|
end
|
|
return table.concat(lines, "\n")
|
|
end
|
|
|
|
local orig = debug.traceback
|
|
---@diagnostic disable-next-line: duplicate-set-field, redundant-parameter
|
|
debug.traceback = function(thread, message, level)
|
|
local trace = vim.split(full_trace(), "\n")
|
|
local orig_trace = orig(thread, message, level)
|
|
if type(thread) ~= 'thread' then
|
|
level = message
|
|
message = thread
|
|
end
|
|
assert(type(message) == 'nil' or type(message) == 'string')
|
|
local qflist_items = vim.split(message, "\n")
|
|
-- doing this to remove truncated file location at the start of the error message
|
|
for i, msg in ipairs(qflist_items) do
|
|
local match = string.match(msg, ".*:%s*(.*)")
|
|
if match ~= nil then
|
|
qflist_items[i] = match
|
|
end
|
|
end
|
|
for _, loc in ipairs(trace) do
|
|
table.insert(qflist_items, loc)
|
|
end
|
|
vim.fn.setqflist({}, "a", {
|
|
title = "Traceback",
|
|
lines = qflist_items,
|
|
})
|
|
return orig_trace
|
|
end
|
|
end
|
|
|
|
-- GENERAL SETTINGS {{{1
|
|
vim.cmd [=[
|
|
set autowriteall
|
|
set exrc
|
|
set secure
|
|
set clipboard=unnamedplus
|
|
set tabstop=4
|
|
set shiftwidth=0
|
|
set rnu
|
|
set nu
|
|
set nowrap
|
|
set shiftround
|
|
set expandtab
|
|
set nohlsearch
|
|
set incsearch
|
|
set guicursor=n-v-c:block-Cursor
|
|
set cursorline
|
|
set noswapfile
|
|
set list
|
|
set tags+=~/tags
|
|
|
|
nnoremap ,co :copen<CR>
|
|
nnoremap ,cc :cclose<CR>
|
|
nnoremap ,cq :call setqflist([])<CR>:cclose<CR>
|
|
nnoremap <c-n> :cnext<CR>zz
|
|
nnoremap <c-p> :cprevious<CR>zz
|
|
nnoremap ,cu :colder<CR>
|
|
nnoremap ,cr :cnewer<CR>
|
|
nnoremap ,h H
|
|
nnoremap ,l L
|
|
nnoremap H ^
|
|
nnoremap L $
|
|
xnoremap H ^
|
|
xnoremap L $
|
|
nnoremap <C-a> <Nop>
|
|
nnoremap <C-x> <Nop>
|
|
nnoremap ,a <C-a>
|
|
nnoremap ,x <C-x>
|
|
nnoremap ,rl :checktime<CR>
|
|
nnoremap ,m :wa<CR>:make<CR>
|
|
|
|
nnoremap ,cD :call setqflist(filter(getqflist(), 'v:val != getqflist()[getqflist({"idx": 0}).idx - 1]'))<CR>
|
|
|
|
nnoremap ,t <c-w>v<c-w>l:terminal<CR>a
|
|
|
|
" Don't include curdir, it just causes pain.
|
|
set viewoptions=folds,cursor
|
|
autocmd BufWinLeave *.* silent! mkview
|
|
autocmd BufWinEnter *.* silent! loadview
|
|
|
|
nnoremap <c-h> <c-w>h
|
|
nnoremap <c-j> <c-w>j
|
|
nnoremap <c-k> <c-w>k
|
|
nnoremap <c-l> <c-w>l
|
|
|
|
nnoremap <c-d> <c-d>zz
|
|
nnoremap <c-u> <c-u>zz
|
|
|
|
tnoremap <c-w>c <c-\><c-n><c-w>c
|
|
|
|
autocmd TextYankPost * silent! lua vim.highlight.on_yank {higroup='Visual', timeout=100}
|
|
autocmd BufEnter *__virtual* setlocal buftype=nofile bufhidden=hide noswapfile
|
|
|
|
" Disable STUPID default rust plugin. And others
|
|
filetype plugin off
|
|
|
|
" remove annoying and bad indentation
|
|
autocmd FileType * setlocal indentexpr=
|
|
]=]
|
|
|
|
vim.keymap.set('n', ',cf', function()
|
|
local qf = vim.fn.getqflist()
|
|
for i, item in ipairs(qf) do
|
|
if item.valid == 1 then
|
|
vim.cmd('cc '..i)
|
|
return
|
|
end
|
|
end
|
|
print('no jumpable items')
|
|
end)
|
|
|
|
vim.keymap.set('n', ',cl', function()
|
|
local qf = vim.fn.getqflist()
|
|
for i = #qf, 1, -1 do
|
|
local item = qf[i]
|
|
|
|
if item.valid == 1 then
|
|
vim.cmd('cc '..i)
|
|
return
|
|
end
|
|
end
|
|
print('no jumpable items')
|
|
end)
|
|
|
|
vim.keymap.set('n', ',ct', function()
|
|
vim.fn.system('ctags -R .')
|
|
end)
|
|
do
|
|
local function escaped(text)
|
|
local _escaped = vim.fn.escape(text, "\\/.*$^~[]")
|
|
local pattern = "\\V" .. _escaped
|
|
return pattern
|
|
end
|
|
---@param pattern string
|
|
local function recursive_literal_vimgrep(pattern)
|
|
vim.cmd("vimgrep /" .. pattern .. "/ **/*")
|
|
end
|
|
---@param keymap string
|
|
---@param search_for fun(): string
|
|
local function search_for_in_same_filetype(keymap, search_for)
|
|
vim.keymap.set('n', keymap, function()
|
|
recursive_literal_vimgrep(search_for())
|
|
end, { desc = "Search for word under cursor in same filetype" })
|
|
end
|
|
|
|
search_for_in_same_filetype(',vs', function() return escaped(vim.fn.expand("<cword>")) end)
|
|
search_for_in_same_filetype(',vS', function() return escaped(vim.fn.expand("<cWORD>")) end)
|
|
local file_specific = {
|
|
odin=function()
|
|
search_for_in_same_filetype(',vd', function()
|
|
local word = vim.fn.expand("<cword>")
|
|
local pattern = "\\v"..word.." *: *[:=]"
|
|
return pattern
|
|
end)
|
|
end
|
|
}
|
|
vim.api.nvim_create_autocmd("FileType", {
|
|
callback=function()
|
|
local conf = file_specific[vim.bo.filetype]
|
|
if conf then conf() end
|
|
end
|
|
})
|
|
end
|
|
|
|
vim.api.nvim_create_autocmd({
|
|
'BufRead',
|
|
'BufNewFile'
|
|
}, {
|
|
pattern = {'*.h'},
|
|
callback = function()
|
|
vim.bo.filetype = 'c'
|
|
end
|
|
})
|
|
|
|
-- FILE SPECIFIC AND AUTOCMDS {{{1
|
|
local file_specific = {
|
|
c = function()
|
|
vim.bo.expandtab = false
|
|
end,
|
|
tsv = function()
|
|
vim.bo.tabstop = 32
|
|
vim.bo.expandtab = false
|
|
end,
|
|
odin = function()
|
|
vim.bo.expandtab = false
|
|
end,
|
|
go = function()
|
|
vim.bo.expandtab = false
|
|
end,
|
|
yaml = function()
|
|
vim.bo.tabstop = 2
|
|
end
|
|
}
|
|
|
|
vim.api.nvim_create_autocmd('BufEnter', {
|
|
callback = function()
|
|
local conf = file_specific[vim.bo.filetype]
|
|
if conf then conf() end
|
|
end,
|
|
})
|
|
|
|
-- CENTER TEXT "zen mode" {{{1
|
|
do
|
|
-- one shared statusline looks better for the split.
|
|
vim.o.laststatus = 3
|
|
|
|
local ID = '4f2de2e3-a1bf-481f-919c-7f68ec6511c9'
|
|
local function is_padding_window(win)
|
|
local ok, _ = pcall(vim.api.nvim_buf_get_var, vim.api.nvim_win_get_buf(win), ID)
|
|
return ok
|
|
end
|
|
|
|
local function calculate_padding()
|
|
local screen_width = vim.o.columns
|
|
local padding = math.floor((screen_width / 2 - 84 / 2) + 0.5)
|
|
if padding <= 0 then
|
|
return
|
|
end
|
|
return padding
|
|
end
|
|
|
|
local function get_padding_window()
|
|
local windows = vim.api.nvim_list_wins()
|
|
for _, win in ipairs(windows) do
|
|
if is_padding_window(win) then
|
|
return win
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local padding_buffer = _G[ID]
|
|
if padding_buffer == nil then
|
|
padding_buffer = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_set_option_value('buftype', 'nofile', {buf = padding_buffer})
|
|
vim.api.nvim_set_option_value('modifiable', false, {buf = padding_buffer})
|
|
vim.api.nvim_create_autocmd('WinEnter', {
|
|
callback = function()
|
|
local curr_buff = vim.api.nvim_get_current_buf()
|
|
if curr_buff == padding_buffer then
|
|
if #vim.api.nvim_list_wins() == 1 then
|
|
vim.cmd"q"
|
|
end
|
|
local padding_window = vim.api.nvim_get_current_win()
|
|
|
|
vim.cmd"wincmd p"
|
|
local prev_win = vim.api.nvim_get_current_win()
|
|
local padding_window_info = vim.fn.getwininfo(padding_window)[1]
|
|
local prev_win_info = vim.fn.getwininfo(prev_win)[1]
|
|
if padding_window ~= prev_win and padding_window_info.wincol ~= prev_win_info.wincol then
|
|
return
|
|
end
|
|
|
|
local windows = vim.api.nvim_list_wins()
|
|
local leftmost_non_padding_window = nil
|
|
local min_col = math.huge
|
|
for _, win in ipairs(windows) do
|
|
local info = vim.fn.getwininfo(win)[1]
|
|
if info.wincol < min_col and padding_window_info.wincol < info.wincol then
|
|
min_col = info.wincol
|
|
leftmost_non_padding_window = win
|
|
end
|
|
end
|
|
if leftmost_non_padding_window ~= nil then
|
|
vim.api.nvim_set_current_win(leftmost_non_padding_window)
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
vim.api.nvim_create_autocmd('VimResized', {
|
|
callback = function()
|
|
local padding_window = get_padding_window()
|
|
if padding_window ~= nil then
|
|
local padding = calculate_padding()
|
|
if padding == nil then
|
|
vim.api.nvim_win_close(padding_window, true)
|
|
else
|
|
vim.api.nvim_win_set_width(padding_window, padding)
|
|
end
|
|
end
|
|
vim.cmd"wincmd ="
|
|
end,
|
|
})
|
|
vim.api.nvim_buf_set_var(padding_buffer, ID, true)
|
|
_G[ID] = padding_buffer
|
|
end
|
|
|
|
local function toggle_padding()
|
|
local padding_window = get_padding_window()
|
|
if padding_window == nil then
|
|
vim.cmd"only"
|
|
local padding = calculate_padding()
|
|
if padding == nil then
|
|
return
|
|
end
|
|
local win = vim.api.nvim_open_win(padding_buffer, false, {
|
|
split = 'left',
|
|
win = -1,
|
|
width = padding,
|
|
})
|
|
vim.api.nvim_set_option_value('number', false, {win = win})
|
|
vim.api.nvim_set_option_value('relativenumber', false, {win = win})
|
|
vim.api.nvim_set_option_value('cursorline', false, {win = win})
|
|
vim.api.nvim_set_option_value('winfixwidth', true, {win = win})
|
|
vim.api.nvim_set_option_value("fillchars", "eob: ", { win = win })
|
|
vim.cmd"wincmd ="
|
|
else
|
|
vim.api.nvim_win_close(padding_window, true)
|
|
end
|
|
end
|
|
|
|
vim.keymap.set('n', ',z', toggle_padding)
|
|
end
|
|
|
|
-- auto select compiler {{{1
|
|
do
|
|
-- TODO: vendor the compiler plugins so I can use e.g. basedpyright instead of pyright and add matching for failing tests in c using criterion.
|
|
-- did a similar thing for the vim config.
|
|
local compiler_mapping = {
|
|
dotnet={'*.csproj', '*.sln'},
|
|
pyright={'requirements.txt', 'pyproject.toml'},
|
|
go={'go.mod'},
|
|
gcc={'*.c'},
|
|
['g++']={'*.cpp'},
|
|
cargo={'Cargo.toml'},
|
|
}
|
|
|
|
---@param pattern string
|
|
---@return boolean
|
|
local function look_for_file(pattern)
|
|
---@type string[]
|
|
local folders = {vim.fn.getcwd()}
|
|
for dir in vim.fs.parents(vim.fn.getcwd()) do
|
|
table.insert(folders, dir)
|
|
end
|
|
|
|
for _, dir in ipairs(folders) do
|
|
local result = vim.fn.globpath(dir, pattern, false, false, false)
|
|
if result ~= '' then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
for compiler, patterns in pairs(compiler_mapping) do
|
|
for _, pattern in ipairs(patterns) do
|
|
if look_for_file(pattern) then
|
|
vim.cmd('compiler! '..compiler)
|
|
end
|
|
end
|
|
end
|
|
if look_for_file('justfile') then
|
|
vim.go.makeprg = 'just'
|
|
end
|
|
end
|
|
|
|
|
|
-- LAZY.NVIM BOOTSTRAP {{{1
|
|
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
|
|
if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
|
vim.fn.system({
|
|
'git',
|
|
'clone',
|
|
'--filter=blob:none',
|
|
'https://github.com/folke/lazy.nvim.git',
|
|
'--branch=stable', -- latest stable release
|
|
lazypath,
|
|
})
|
|
end
|
|
vim.opt.rtp:prepend(lazypath)
|
|
|
|
require'lazy'.setup{ --{{{1
|
|
{ "romus204/tree-sitter-manager.nvim", --{{{2
|
|
dependencies = {}, -- tree-sitter CLI must be installed system-wide
|
|
config = function()
|
|
require("tree-sitter-manager").setup({
|
|
auto_install = true
|
|
})
|
|
end
|
|
},
|
|
{ 'stevearc/oil.nvim', --{{{2
|
|
---@module 'oil'
|
|
---@type oil.SetupOpts
|
|
opts = {},
|
|
lazy = false,
|
|
config = function ()
|
|
require('oil').setup({
|
|
default_file_explorer = true,
|
|
columns = {
|
|
'icon',
|
|
'permissions',
|
|
'size',
|
|
'mtime',
|
|
},
|
|
buf_options = {
|
|
buflisted = false,
|
|
bufhidden = 'hide',
|
|
},
|
|
win_options = {
|
|
wrap = false,
|
|
signcolumn = 'no',
|
|
cursorcolumn = false,
|
|
foldcolumn = '0',
|
|
spell = false,
|
|
list = false,
|
|
conceallevel = 3,
|
|
concealcursor = 'nvic',
|
|
},
|
|
delete_to_trash = false,
|
|
skip_confirm_for_simple_edits = false,
|
|
prompt_save_on_select_new_entry = true,
|
|
cleanup_delay_ms = 2000,
|
|
lsp_file_methods = {
|
|
enabled = true,
|
|
timeout_ms = 1000,
|
|
autosave_changes = false,
|
|
},
|
|
constrain_cursor = 'editable',
|
|
watch_for_changes = true,
|
|
keymaps = {
|
|
['g?'] = { 'actions.show_help', mode = 'n' },
|
|
['<C-y>'] = { 'actions.yank_entry', opts = { modify=":." }, mode = 'n' }, -- :. makes it a relative path
|
|
['<C-h>'] = false, ['<C-j>'] = false, ['<C-k>'] = false, ['<C-l>'] = false, -- I use those keys for navigation
|
|
['<CR>'] = 'actions.select',
|
|
['-'] = { 'actions.parent', mode = 'n' },
|
|
['_'] = { 'actions.open_cwd', mode = 'n' },
|
|
[',cd'] = { 'actions.cd', mode = 'n' },
|
|
[',CD'] = { 'actions.cd', opts = { scope = 'tab' }, mode = 'n' },
|
|
['gx'] = 'actions.open_external',
|
|
['g.'] = { 'actions.toggle_hidden', mode = 'n' },
|
|
},
|
|
use_default_keymaps = true,
|
|
view_options = {
|
|
show_hidden = true,
|
|
is_hidden_file = function(name, _)
|
|
local m = name:match('^%.')
|
|
return m ~= nil
|
|
end,
|
|
is_always_hidden = function(_, _)
|
|
return false
|
|
end,
|
|
natural_order = 'fast',
|
|
case_insensitive = false,
|
|
sort = {
|
|
{ 'type', 'asc' },
|
|
{ 'name', 'asc' },
|
|
},
|
|
highlight_filename = function(_, _, _, _)
|
|
return nil
|
|
end,
|
|
},
|
|
extra_scp_args = {},
|
|
float = {
|
|
padding = 2,
|
|
max_width = 0,
|
|
max_height = 0,
|
|
border = 'rounded',
|
|
win_options = {
|
|
winblend = 0,
|
|
},
|
|
get_win_title = nil,
|
|
preview_split = 'auto',
|
|
override = function(conf)
|
|
return conf
|
|
end,
|
|
},
|
|
preview_win = {
|
|
update_on_cursor_moved = true,
|
|
preview_method = 'fast_scratch',
|
|
disable_preview = function(_)
|
|
return false
|
|
end,
|
|
win_options = {},
|
|
},
|
|
confirmation = {
|
|
max_width = 0.9,
|
|
min_width = { 40, 0.4 },
|
|
width = nil,
|
|
max_height = 0.9,
|
|
min_height = { 5, 0.1 },
|
|
height = nil,
|
|
border = 'rounded',
|
|
win_options = {
|
|
winblend = 0,
|
|
},
|
|
},
|
|
progress = {
|
|
max_width = 0.9,
|
|
min_width = { 40, 0.4 },
|
|
width = nil,
|
|
max_height = { 10, 0.9 },
|
|
min_height = { 5, 0.1 },
|
|
height = nil,
|
|
border = 'rounded',
|
|
minimized_border = 'none',
|
|
win_options = {
|
|
winblend = 0,
|
|
},
|
|
},
|
|
ssh = {
|
|
border = 'rounded',
|
|
},
|
|
keymaps_help = {
|
|
border = 'rounded',
|
|
},
|
|
})
|
|
|
|
-- oil fix relative path
|
|
vim.api.nvim_create_augroup('OilRelPathFix', {})
|
|
vim.api.nvim_create_autocmd('BufLeave', {
|
|
group = 'OilRelPathFix',
|
|
pattern = 'oil:///*',
|
|
callback = function ()
|
|
vim.cmd('cd .')
|
|
end
|
|
})
|
|
|
|
local actions = require('oil.actions')
|
|
vim.keymap.set('n', '-', actions.parent.callback, { desc = actions.parent.desc })
|
|
vim.keymap.set('n', '_', actions.open_cwd.callback, { desc = actions.open_cwd.desc })
|
|
end
|
|
},
|
|
{ 'github/copilot.vim', --{{{2
|
|
config = function()
|
|
-- q for qomplete ;)
|
|
vim.keymap.set('i', '<c-q>', 'copilot#Accept("\\<CR>")', {
|
|
expr = true,
|
|
replace_keycodes = false,
|
|
})
|
|
vim.g.copilot_no_tab_map = true
|
|
vim.keymap.set('n', '<c-q>', ':Copilot panel<CR>', { noremap = true })
|
|
vim.keymap.set('n', ',cd', ':Copilot disable<CR>', { noremap = true })
|
|
vim.keymap.set('n', ',ce', ':Copilot enable<CR>', { noremap = true })
|
|
end,
|
|
},
|
|
{ 'f-person/git-blame.nvim', --{{{2
|
|
keys = {',g'},
|
|
config = function ()
|
|
require'gitblame'.setup{
|
|
enabled = false,
|
|
}
|
|
vim.cmd[[
|
|
nnoremap ,g :GitBlameToggle<CR>
|
|
]]
|
|
end
|
|
},
|
|
{ 'unblevable/quick-scope', --{{{2
|
|
init = function()
|
|
vim.cmd [[
|
|
let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']
|
|
]]
|
|
end,
|
|
},
|
|
{ 'michaeljsmith/vim-indent-object', --{{{2
|
|
},
|
|
{ 'kylechui/nvim-surround', --{{{2
|
|
version = '*', -- Use for stability; omit to use `main` branch for the latest features
|
|
event = 'VeryLazy',
|
|
config = function()
|
|
require('nvim-surround').setup{}
|
|
end
|
|
},
|
|
{ 'echasnovski/mini.align', --{{{2
|
|
version = false,
|
|
config = function()
|
|
require'mini.align'.setup()
|
|
end,
|
|
},
|
|
{ 'miikanissi/modus-themes.nvim', --{{{2
|
|
lazy = false,
|
|
priority = 1000,
|
|
config = function()
|
|
vim.o.termguicolors = true
|
|
vim.cmd.colorscheme('modus_vivendi')
|
|
end,
|
|
},
|
|
{ 'folke/lazydev.nvim', --{{{2
|
|
ft = 'lua', -- only load on lua files
|
|
opts = {
|
|
library = {
|
|
{ path = '${3rd}/luv/library', words = { 'vim%.uv' } },
|
|
{ path = '${3rd}/love2d/library', words = { 'love' } },
|
|
},
|
|
},
|
|
},
|
|
{ "seblyng/roslyn.nvim", --{{{2
|
|
dependencies = {
|
|
'williamboman/mason.nvim',
|
|
},
|
|
cond = function()
|
|
mason_registry = require'mason-registry'
|
|
return mason_registry.is_installed('roslyn')
|
|
end,
|
|
opts = {
|
|
---function to pick which .sln file to use when opening a cs file
|
|
---@param targets string[]
|
|
choose_target=function (targets)
|
|
if targets == nil then return end
|
|
if #targets == 0 then return end
|
|
table.sort(targets, function(a, b)
|
|
return #a < #b
|
|
end)
|
|
return targets[1]
|
|
end
|
|
},
|
|
},
|
|
{ 'neovim/nvim-lspconfig', --{{{2
|
|
dependencies = {
|
|
'williamboman/mason.nvim',
|
|
'williamboman/mason-lspconfig.nvim',
|
|
},
|
|
config = function()
|
|
vim.diagnostic.config{
|
|
severity_sort=true
|
|
}
|
|
|
|
require'mason'.setup{
|
|
registries={
|
|
"github:mason-org/mason-registry",
|
|
"github:Crashdummyy/mason-registry",
|
|
}
|
|
}
|
|
require'mason-lspconfig'.setup()
|
|
vim.lsp.config.zls = {
|
|
before_init = function(_, _)
|
|
vim.g.zig_fmt_autosave = false -- may not be needed anymore?
|
|
end,
|
|
}
|
|
vim.lsp.config.lua_ls = {
|
|
settings = {
|
|
Lua = { runtime = { version = 'LuaJIT' } }
|
|
}
|
|
}
|
|
vim.lsp.config.gopls = {
|
|
filetypes = { -- unsure if this is entirely correct...
|
|
'go',
|
|
'gomod',
|
|
'gowork',
|
|
'gotmpl',
|
|
'html'
|
|
},
|
|
settings = {
|
|
gopls = {
|
|
templateExtensions = {'html', 'gotmpl'}
|
|
}
|
|
}
|
|
}
|
|
vim.lsp.config.basedpyright = {
|
|
settings = {
|
|
basedpyright = {
|
|
analysis = {
|
|
useLibraryCodeForTypes = true
|
|
},
|
|
},
|
|
},
|
|
}
|
|
vim.lsp.config.sourcekit = {
|
|
filetypes = {"swift"}
|
|
}
|
|
vim.lsp.config.ols = {
|
|
settings = {
|
|
verbose=true,
|
|
}
|
|
}
|
|
|
|
vim.lsp.enable('gdscript')
|
|
vim.lsp.config('hls', {
|
|
filetypes = { 'haskell', 'lhaskell', 'cabal' },
|
|
})
|
|
vim.lsp.enable('hls')
|
|
vim.lsp.enable('sourcekit')
|
|
|
|
vim.api.nvim_create_autocmd('LspAttach', {
|
|
callback = function(args)
|
|
vim.bo[args.buf].tagfunc = nil
|
|
end,
|
|
})
|
|
|
|
vim.keymap.set( 'n', ',fd', vim.lsp.buf.definition, { noremap = true, silent = true})
|
|
|
|
vim.cmd [[
|
|
nnoremap ,rn :lua vim.lsp.buf.rename()<CR>
|
|
nnoremap ,ft :lua vim.lsp.buf.type_definition()<CR>
|
|
nnoremap ,fi :lua vim.lsp.buf.implementation()<CR>
|
|
nnoremap ,fr :lua vim.lsp.buf.references()<CR>
|
|
nnoremap ,ca :lua vim.lsp.buf.code_action()<CR>
|
|
nnoremap ,oe :lua vim.diagnostic.open_float()<CR>
|
|
|
|
nnoremap ,ea :lua vim.diagnostic.setqflist()<CR>
|
|
nnoremap ,ee :lua vim.diagnostic.setqflist{severity='ERROR'}<CR>
|
|
nnoremap ,ew :lua vim.diagnostic.setqflist{severity='WARN'}<CR>
|
|
nnoremap ,ei :lua vim.diagnostic.setqflist{severity='INFO'}<CR>
|
|
nnoremap ,eh :lua vim.diagnostic.setqflist{severity='HINT'}<CR>
|
|
|
|
nnoremap ,eA :lua vim.diagnostic.setloclist()<CR>
|
|
nnoremap ,eE :lua vim.diagnostic.setloclist{severity='ERROR'}<CR>
|
|
nnoremap ,eW :lua vim.diagnostic.setloclist{severity='WARN'}<CR>
|
|
nnoremap ,eI :lua vim.diagnostic.setloclist{severity='INFO'}<CR>
|
|
nnoremap ,eH :lua vim.diagnostic.setloclist{severity='HINT'}<CR>
|
|
|
|
nnoremap ,fm :lua vim.lsp.buf.format()<CR>
|
|
]]
|
|
end
|
|
},
|
|
{ 'mfussenegger/nvim-dap', --{{{2
|
|
dependencies = {
|
|
'leoluz/nvim-dap-go',
|
|
'mfussenegger/nvim-dap-python',
|
|
'nicholasmata/nvim-dap-cs',
|
|
},
|
|
keys = {
|
|
',b',
|
|
',db',
|
|
',B',
|
|
'<B',
|
|
',dh',
|
|
',ds',
|
|
',df',
|
|
},
|
|
config = function()
|
|
require'dap-go'.setup()
|
|
require'dap-python'.setup('debugpy-adapter')
|
|
require('dap-cs').setup()
|
|
|
|
local dap = require'dap'
|
|
dap.adapters.godot = { type = 'server', host = '127.0.0.1', port = 6006, }
|
|
dap.configurations.gdscript = { {type = 'godot', request = 'launch', name = 'Launch scene', project = '${workspaceFolder}',} }
|
|
|
|
dap.adapters.lldb = {
|
|
type = 'executable',
|
|
command = vim.fn.exepath('codelldb'),
|
|
name = 'lldb'
|
|
}
|
|
|
|
dap.configurations.c = {
|
|
{
|
|
name = 'Launch',
|
|
type = 'lldb',
|
|
request = 'launch',
|
|
program = function()
|
|
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
|
|
end,
|
|
cwd = '${workspaceFolder}',
|
|
stopOnEntry = false,
|
|
args = function()
|
|
local i = vim.fn.input('input args: ')
|
|
return vim.fn.split(i)
|
|
end,
|
|
runInTerminal = true,
|
|
},
|
|
}
|
|
dap.configurations.cpp = dap.configurations.c
|
|
dap.configurations.rust = dap.configurations.c
|
|
local widgets = require'dap.ui.widgets'
|
|
|
|
local inspections = {}
|
|
local function map_inspection(keys, func)
|
|
local function wrapper()
|
|
if inspections[keys] == nil then
|
|
inspections[keys] = func()
|
|
return
|
|
end
|
|
inspections[keys].toggle()
|
|
end
|
|
vim.keymap.set('n', keys, wrapper, {noremap=true})
|
|
end
|
|
local function refresh_inspections()
|
|
for _, widget in pairs(inspections) do
|
|
if widget.win ~= nil then
|
|
widget.refresh()
|
|
end
|
|
end
|
|
end
|
|
local function close_inspections()
|
|
for _, widget in pairs(inspections) do
|
|
if widget.win ~= nil then
|
|
widget.close()
|
|
end
|
|
end
|
|
end
|
|
map_inspection(',dh', widgets.hover)
|
|
map_inspection(',ds', function () return widgets.centered_float(widgets.scopes) end)
|
|
map_inspection(',df', function () return widgets.centered_float(widgets.frames) end)
|
|
vim.keymap.set('n', '<Down>', dap.step_over)
|
|
vim.keymap.set('n', '<Right>', dap.step_into)
|
|
vim.keymap.set('n', '<Left>', dap.step_out)
|
|
vim.keymap.set('n', '<Up>', dap.restart_frame)
|
|
vim.keymap.set('n', ',b', dap.toggle_breakpoint)
|
|
vim.keymap.set('n', ',B', dap.clear_breakpoints)
|
|
vim.keymap.set('n', '<B', dap.clear_breakpoints)
|
|
vim.keymap.set('n', ',db', dap.continue)
|
|
vim.keymap.set('n', ',dc', close_inspections)
|
|
vim.keymap.set('n', ',dr', refresh_inspections)
|
|
|
|
end
|
|
},
|
|
{ 'dcampos/nvim-snippy', --{{{2
|
|
config = function()
|
|
require'snippy'.setup{ enable_auto = true, }
|
|
vim.cmd [[
|
|
imap <expr> <c-l> '<Plug>(snippy-next)'
|
|
imap <expr> <c-k> '<Plug>(snippy-previous)'
|
|
smap <expr> <c-l> '<Plug>(snippy-next)'
|
|
smap <expr> <c-k> '<Plug>(snippy-previous)'
|
|
nmap g; <Plug>(snippy-cut-text)
|
|
xmap g; <Plug>(snippy-cut-text)
|
|
]]
|
|
end
|
|
},
|
|
{ 'hrsh7th/nvim-cmp', --{{{2
|
|
dependencies = {
|
|
'hrsh7th/cmp-nvim-lsp',
|
|
'hrsh7th/cmp-path',
|
|
'dcampos/nvim-snippy',
|
|
'dcampos/cmp-snippy',
|
|
'quangnguyen30192/cmp-nvim-tags',
|
|
},
|
|
config = function()
|
|
local cmp = require'cmp'
|
|
cmp.setup{
|
|
snippet = {
|
|
expand = function(args)
|
|
require'snippy'.expand_snippet(args.body)
|
|
end,
|
|
},
|
|
mapping = {
|
|
['<C-y>'] = cmp.mapping.confirm{ select = true },
|
|
['<C-n>'] = cmp.mapping.select_next_item(),
|
|
['<C-p>'] = cmp.mapping.select_prev_item(),
|
|
},
|
|
sources = cmp.config.sources(
|
|
{
|
|
{ name = 'snippy', priority = 100000000000000000000 },
|
|
{ name = 'nvim_lsp', priority = 1000000000},
|
|
{ name = 'tags', priority = 100 },
|
|
{ name = 'path', priority = 1},
|
|
}
|
|
),
|
|
preselect = cmp.PreselectMode.None,
|
|
}
|
|
end,
|
|
},
|
|
{ 'nvim-telescope/telescope.nvim', --{{{2
|
|
tag = '0.1.8',
|
|
dependencies = {
|
|
'nvim-lua/plenary.nvim',
|
|
'nvim-telescope/telescope-ui-select.nvim',
|
|
},
|
|
config = function()
|
|
local actions = require'telescope.actions'
|
|
vim.o.splitright = true
|
|
require'telescope'.setup{
|
|
defaults = {
|
|
file_ignore_patterns = {'%__virtual.cs$'},
|
|
mappings = {
|
|
i = {
|
|
['<C-Q>'] = actions.smart_send_to_qflist + actions.open_qflist,
|
|
['<C-j>'] = actions.select_default,
|
|
},
|
|
n = {
|
|
['<C-Q>'] = actions.smart_send_to_qflist + actions.open_qflist,
|
|
['<C-j>'] = actions.select_default,
|
|
},
|
|
}
|
|
},
|
|
pickers = {
|
|
help_tags = {
|
|
attach_mappings = function(_, map)
|
|
map("i", "<CR>", actions.select_vertical)
|
|
map("n", "<CR>", actions.select_vertical)
|
|
map("i", "<C-j>", actions.select_vertical)
|
|
map("n", "<C-j>", actions.select_vertical)
|
|
return true
|
|
end,
|
|
},
|
|
},
|
|
extensions = { ['ui-select'] = { require'telescope.themes'.get_dropdown{}, }, },
|
|
}
|
|
|
|
vim.cmd [[
|
|
nnoremap ,fw :lua require'telescope.builtin'.lsp_dynamic_workspace_symbols()<CR>
|
|
nnoremap ,fa :lua require'telescope.builtin'.find_files({hidden=true, no_ignore=true, no_ignore_parent=true})<CR>
|
|
nnoremap ,ff :lua require'telescope.builtin'.find_files()<CR>
|
|
nnoremap ,fo :lua require'telescope.builtin'.oldfiles()<CR>
|
|
nnoremap ,fg :lua require'telescope.builtin'.live_grep()<CR>
|
|
nnoremap ,fs :lua require'telescope.builtin'.grep_string()<CR>
|
|
nnoremap ,fz :lua require'telescope.builtin'.current_buffer_fuzzy_find()<CR>
|
|
nnoremap ,fh :lua require'telescope.builtin'.help_tags()<CR>
|
|
nnoremap ,fb :lua require'telescope.builtin'.buffers()<CR>
|
|
nnoremap ,fc :lua require'telescope.builtin'.tags({default_text=vim.fn.expand("<cword>")})<CR>
|
|
nnoremap ,fC :lua require'telescope.builtin'.tags({default_text=vim.fn.expand("<cWORD>")})<CR>
|
|
|
|
nnoremap ,fea :lua require'telescope.builtin'.diagnostics()<CR>
|
|
nnoremap ,fee :lua require'telescope.builtin'.diagnostics{severity='ERROR'}<CR>
|
|
nnoremap ,few :lua require'telescope.builtin'.diagnostics{severity='WARN'}<CR>
|
|
nnoremap ,fei :lua require'telescope.builtin'.diagnostics{severity='INFO'}<CR>
|
|
nnoremap ,feh :lua require'telescope.builtin'.diagnostics{severity='HINT'}<CR>
|
|
]]
|
|
|
|
require'telescope'.load_extension'ui-select'
|
|
end,
|
|
},
|
|
}
|
|
|
|
do -- split line {{{1
|
|
local SPLIT_DELIMETERS = { -- single characters only
|
|
[','] = true,
|
|
[';'] = true,
|
|
['|'] = true,
|
|
}
|
|
local SPLIT_BETWEEN = { -- single characters only
|
|
['('] = ')',
|
|
['['] = ']',
|
|
['{'] = '}',
|
|
['<'] = '>',
|
|
}
|
|
local SPLIT_IGNORE_BETWEEN = { --single characters only
|
|
['"'] = '"',
|
|
["'"] = "'",
|
|
}
|
|
|
|
local split_line = function()
|
|
local SPLIT_WHITESPACE = ' '
|
|
if vim.o.expandtab then
|
|
SPLIT_WHITESPACE = ''
|
|
for _ = 1, vim.o.tabstop do
|
|
SPLIT_WHITESPACE = SPLIT_WHITESPACE .. ' '
|
|
end
|
|
end
|
|
|
|
local line = vim.api.nvim_get_current_line()
|
|
local _, col = unpack(vim.api.nvim_win_get_cursor(0))
|
|
col = col + 1 -- Doing this to make it 1-indexed
|
|
|
|
---@type integer?
|
|
local first_bracket_i = nil
|
|
for i = col, #line do
|
|
local char = line:sub(i, i)
|
|
if SPLIT_BETWEEN[char] ~= nil then
|
|
first_bracket_i = i
|
|
break
|
|
end
|
|
end
|
|
|
|
if not first_bracket_i then
|
|
print('No opening brackets found after cursor on this line.')
|
|
return
|
|
end
|
|
|
|
---@type integer[]
|
|
local split_indexes = {} -- Populate this array
|
|
---@type integer?
|
|
local last_bracket_i = nil -- And find this index
|
|
|
|
do
|
|
---@type string[]
|
|
local closing_bracket_stack = {}
|
|
local icon_to_close_ignore = ''
|
|
local in_ignore = false
|
|
|
|
for i = first_bracket_i, #line do
|
|
local char = line:sub(i,i)
|
|
|
|
if in_ignore then
|
|
in_ignore = not (char == icon_to_close_ignore)
|
|
goto continue
|
|
end
|
|
|
|
if SPLIT_IGNORE_BETWEEN[char] ~= nil then
|
|
icon_to_close_ignore = SPLIT_IGNORE_BETWEEN[char]
|
|
in_ignore = true
|
|
goto continue
|
|
end
|
|
-- string handling complete
|
|
|
|
if SPLIT_BETWEEN[char] ~= nil then
|
|
table.insert(
|
|
closing_bracket_stack,
|
|
SPLIT_BETWEEN[char]
|
|
)
|
|
end
|
|
|
|
if char == closing_bracket_stack[#closing_bracket_stack] then
|
|
table.remove(closing_bracket_stack)
|
|
end
|
|
|
|
if #closing_bracket_stack == 1 and SPLIT_DELIMETERS[char] then
|
|
table.insert(split_indexes, i)
|
|
end
|
|
|
|
if #closing_bracket_stack == 0 then
|
|
last_bracket_i = i
|
|
break
|
|
end
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
if not last_bracket_i then
|
|
print('The first opening bracket found after the cursor was not closed on this line.')
|
|
return
|
|
end
|
|
|
|
---@type string
|
|
local leading_whitespace = string.match(line, '^%s*')
|
|
local first_line = line:sub(1, first_bracket_i)
|
|
local last_line = leading_whitespace .. line:sub(last_bracket_i, #line)
|
|
if #split_indexes == 0 then
|
|
if (last_bracket_i - first_bracket_i == 1) then return end
|
|
local row, _ = unpack(vim.api.nvim_win_get_cursor(0))
|
|
line = line:sub(first_bracket_i+1, last_bracket_i-1)
|
|
local leading_pattern = '^[%s'
|
|
for k, _ in pairs(SPLIT_DELIMETERS) do
|
|
leading_pattern = leading_pattern .. k
|
|
end
|
|
leading_pattern = leading_pattern .. ']*'
|
|
line = line:gsub(leading_pattern, leading_whitespace .. SPLIT_WHITESPACE, 1)
|
|
line = line:gsub('[%s]*$', '', 1)
|
|
vim.api.nvim_buf_set_lines(0, row-1, row, false, {first_line})
|
|
vim.api.nvim_buf_set_lines(0, row, row, false, {last_line})
|
|
vim.api.nvim_buf_set_lines(0, row, row, false, {line})
|
|
return
|
|
end
|
|
|
|
local middle_lines = {}
|
|
table.insert(
|
|
middle_lines,
|
|
line:sub(first_bracket_i+1, split_indexes[1])
|
|
)
|
|
for i = 1, #split_indexes-1 do
|
|
table.insert(
|
|
middle_lines,
|
|
line:sub(split_indexes[i], split_indexes[i+1])
|
|
)
|
|
end
|
|
table.insert(
|
|
middle_lines,
|
|
line:sub(split_indexes[#split_indexes], last_bracket_i-1)
|
|
)
|
|
|
|
local leading_pattern = '^[%s'
|
|
for k, _ in pairs(SPLIT_DELIMETERS) do
|
|
leading_pattern = leading_pattern .. k
|
|
end
|
|
leading_pattern = leading_pattern .. ']*'
|
|
|
|
-- Cleanup step
|
|
for i, middle_line in ipairs(middle_lines) do
|
|
middle_line = middle_line:gsub(leading_pattern, leading_whitespace .. SPLIT_WHITESPACE, 1)
|
|
middle_line = middle_line:gsub('[%s]*$', '', 1)
|
|
middle_lines[i] = middle_line
|
|
end
|
|
|
|
if middle_lines[#middle_lines]:match('^%s*$') ~= nil then
|
|
table.remove(middle_lines)
|
|
end
|
|
|
|
local row, _ = unpack(vim.api.nvim_win_get_cursor(0))
|
|
vim.api.nvim_buf_set_lines(0, row-1, row, false, {first_line})
|
|
vim.api.nvim_buf_set_lines(0, row, row, false, {last_line})
|
|
vim.api.nvim_buf_set_lines(0, row, row, false, middle_lines)
|
|
end
|
|
|
|
vim.keymap.set(
|
|
'n',
|
|
',s',
|
|
split_line,
|
|
{ silent = true }
|
|
)
|
|
end
|
|
|
|
do --screenshot paste {{{1
|
|
local function save_clipboard_image()
|
|
local is_mac = vim.fn.has("mac")
|
|
if not is_mac then
|
|
error("only supported for mac")
|
|
end
|
|
local filename = vim.fn.input("image name: ")
|
|
local path = filename .. ".png"
|
|
local cmd = "pngpaste " .. vim.fn.shellescape(path)
|
|
local res = os.execute(cmd)
|
|
if res == 0 then
|
|
print("saved image to ".. path)
|
|
else
|
|
error("failed to save image")
|
|
end
|
|
|
|
local row, _ = unpack(vim.api.nvim_win_get_cursor(0))
|
|
vim.api.nvim_buf_set_lines(0, row, row, false, {
|
|
""
|
|
})
|
|
end
|
|
|
|
vim.keymap.set(
|
|
'n',
|
|
',q',
|
|
save_clipboard_image,
|
|
{}
|
|
)
|
|
end
|