regular backup

- feat(home-manager): mount Dropbox on startup
- feat(nvim): switch to nvim-lsp
This commit is contained in:
arielherself 2025-01-14 20:46:01 +08:00
parent 88c8e77031
commit 11e10c3292
Signed by: arielherself
SSH Key Fingerprint: SHA256:AK3cyo9tFsp7Mox7K0sYphleC8hReXhnRKxwuDT5LBc
3 changed files with 413 additions and 79 deletions

177
.vimrc
View File

@ -85,8 +85,8 @@ let g:mapleader = " "
" Install vim-plug
let data_dir = '~/.vim'
if empty(glob(data_dir . '/autoload/plug.vim'))
silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
call plug#begin('~/.vim/plugged')
@ -105,12 +105,12 @@ endif
Plug 'wakatime/vim-wakatime'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-commentary'
Plug 'arielherself/vim-lsp'
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'
" Plug 'arielherself/vim-lsp'
" Plug 'prabirshrestha/asyncomplete.vim'
" Plug 'prabirshrestha/asyncomplete-lsp.vim'
" Plug 'Shougo/ddc.vim'
" Plug 'shun/ddc-vim-lsp'
Plug 'mattn/vim-lsp-settings'
" Plug 'mattn/vim-lsp-settings'
Plug 'jdhao/better-escape.vim'
Plug 'jiangmiao/auto-pairs'
Plug 'easymotion/vim-easymotion'
@ -121,18 +121,45 @@ Plug 'ryanoasis/vim-devicons'
" this plugin slows vim down when dealing
" with large files, so I switch to the Nvim version
" Plug 'airblade/vim-gitgutter'
if has('nvim')
Plug 'lewis6991/gitsigns.nvim'
endif
Plug 'lewis6991/gitsigns.nvim'
Plug 'tpope/vim-fugitive'
Plug 'Yggdroot/indentLine'
Plug '907th/vim-auto-save'
Plug 'markonm/traces.vim'
Plug 'stevearc/oil.nvim'
Plug 'vim-scripts/LargeFile'
Plug 'lambdalisue/vim-fern'
Plug 'lambdalisue/vim-fern-git-status'
Plug 'lambdalisue/vim-fern-renderer-nerdfont'
Plug 'lambdalisue/nerdfont.vim'
" Use Neovim LSP
Plug 'neovim/nvim-lspconfig'
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'saadparwaiz1/cmp_luasnip'
Plug 'L3MON4D3/LuaSnip'
Plug 'hrsh7th/cmp-emoji'
Plug 'chrisgrieser/cmp-nerdfont'
Plug 'hrsh7th/cmp-calc'
Plug 'arielherself/lspkind.nvim'
Plug 'nvim-tree/nvim-web-devicons'
Plug 'folke/trouble.nvim'
Plug 'kevinhwang91/nvim-ufo'
Plug 'kevinhwang91/promise-async'
Plug 'rmagatti/goto-preview'
call plug#end()
" Why?!
set noshowmode
set showcmd
" Color scheme
set background=dark
let g:embark_terminal_italics = 1
@ -174,11 +201,11 @@ let g:lsp_settings = {
\ 'clangd': { 'cmd': [ 'clangd' ] },
\}
function! s:truncate(str)
if len(a:str) > 50
return a:str[:50] . '...'
else
return a:str
endif
if len(a:str) > 50
return a:str[:50] . '...'
else
return a:str
endif
endfunction
function! s:truncate_labels(options, matches) abort
let l:items = []
@ -209,14 +236,15 @@ nnoremap <leader>w <Plug>(easymotion-bd-w)
vnoremap <leader>w <Plug>(easymotion-bd-w)
nnoremap <leader>o <Cmd>Files<CR>
nnoremap <leader>g <Cmd>Rg<CR>
nnoremap gpd <Cmd>LspPeekDefinition<CR>
nnoremap gd <Cmd>LspDefinition<CR>
nnoremap <leader>dd <Cmd>LspDocumentDiagnostics<CR>
nnoremap <leader>dn <Cmd>LspNextDiagnostic<CR>
nnoremap <leader>dp <Cmd>LspPreviousDiagnostic<CR>
nnoremap grr <Cmd>LspRename<CR>
nnoremap <leader>a <Cmd>LspCodeAction<CR>
nnoremap K <Cmd>LspHover<CR>
nnoremap <leader>. <Cmd>Fern . -drawer<CR>
" nnoremap gpd <Cmd>LspPeekDefinition<CR>
" nnoremap gd <Cmd>LspDefinition<CR>
" nnoremap <leader>dd <Cmd>LspDocumentDiagnostics<CR>
" nnoremap <leader>dn <Cmd>LspNextDiagnostic<CR>
" nnoremap <leader>dp <Cmd>LspPreviousDiagnostic<CR>
" nnoremap grr <Cmd>LspRename<CR>
" nnoremap <leader>a <Cmd>LspCodeAction<CR>
" nnoremap K <Cmd>LspHover<CR>
nnoremap Q q
nnoremap q <Nop>
inoremap <C-e> {<ESC>A}<ESC>%li<CR><ESC>$i<CR><ESC>k^i
@ -239,18 +267,18 @@ nnoremap <leader>x <Cmd>%s/\s\+$//e<CR>
" Delete buffer while keeping window layout (don't close buffer's windows).
" Version 2008-11-18 from http://vim.wikia.com/wiki/VimTip165
if v:version < 700 || exists('loaded_bclose') || &cp
finish
finish
endif
let loaded_bclose = 1
if !exists('bclose_multiple')
let bclose_multiple = 1
let bclose_multiple = 1
endif
" Display an error message.
function! s:Warn(msg)
echohl ErrorMsg
echomsg a:msg
echohl NONE
echohl ErrorMsg
echomsg a:msg
echohl NONE
endfunction
" Command ':Bclose' executes ':bd' to delete buffer in current window.
@ -259,52 +287,52 @@ endfunction
" Command ':Bclose!' is the same, but executes ':bd!' (discard changes).
" An optional argument can specify which buffer to close (name or number).
function! s:Bclose(bang, buffer)
if empty(a:buffer)
let btarget = bufnr('%')
elseif a:buffer =~ '^\d\+$'
let btarget = bufnr(str2nr(a:buffer))
else
let btarget = bufnr(a:buffer)
endif
if btarget < 0
call s:Warn('No matching buffer for '.a:buffer)
return
endif
if empty(a:bang) && getbufvar(btarget, '&modified')
call s:Warn('No write since last change for buffer '.btarget.' (use :Bclose!)')
return
endif
" Numbers of windows that view target buffer which we will delete.
let wnums = filter(range(1, winnr('$')), 'winbufnr(v:val) == btarget')
if !g:bclose_multiple && len(wnums) > 1
call s:Warn('Buffer is in multiple windows (use ":let bclose_multiple=1")')
return
endif
let wcurrent = winnr()
for w in wnums
execute w.'wincmd w'
let prevbuf = bufnr('#')
if prevbuf > 0 && buflisted(prevbuf) && prevbuf != btarget
buffer #
if empty(a:buffer)
let btarget = bufnr('%')
elseif a:buffer =~ '^\d\+$'
let btarget = bufnr(str2nr(a:buffer))
else
bprevious
let btarget = bufnr(a:buffer)
endif
if btarget == bufnr('%')
" Numbers of listed buffers which are not the target to be deleted.
let blisted = filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != btarget')
" Listed, not target, and not displayed.
let bhidden = filter(copy(blisted), 'bufwinnr(v:val) < 0')
" Take the first buffer, if any (could be more intelligent).
let bjump = (bhidden + blisted + [-1])[0]
if bjump > 0
execute 'buffer '.bjump
else
execute 'enew'.a:bang
endif
if btarget < 0
call s:Warn('No matching buffer for '.a:buffer)
return
endif
endfor
execute 'bdelete'.a:bang.' '.btarget
execute wcurrent.'wincmd w'
if empty(a:bang) && getbufvar(btarget, '&modified')
call s:Warn('No write since last change for buffer '.btarget.' (use :Bclose!)')
return
endif
" Numbers of windows that view target buffer which we will delete.
let wnums = filter(range(1, winnr('$')), 'winbufnr(v:val) == btarget')
if !g:bclose_multiple && len(wnums) > 1
call s:Warn('Buffer is in multiple windows (use ":let bclose_multiple=1")')
return
endif
let wcurrent = winnr()
for w in wnums
execute w.'wincmd w'
let prevbuf = bufnr('#')
if prevbuf > 0 && buflisted(prevbuf) && prevbuf != btarget
buffer #
else
bprevious
endif
if btarget == bufnr('%')
" Numbers of listed buffers which are not the target to be deleted.
let blisted = filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != btarget')
" Listed, not target, and not displayed.
let bhidden = filter(copy(blisted), 'bufwinnr(v:val) < 0')
" Take the first buffer, if any (could be more intelligent).
let bjump = (bhidden + blisted + [-1])[0]
if bjump > 0
execute 'buffer '.bjump
else
execute 'enew'.a:bang
endif
endif
endfor
execute 'bdelete'.a:bang.' '.btarget
execute wcurrent.'wincmd w'
endfunction
command! -bang -complete=buffer -nargs=? Bclose call <SID>Bclose(<q-bang>, <q-args>)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@ -333,10 +361,17 @@ highlight VertSplit guifg=#585273
" airline styling
" ref: https://github.com/vim-airline/vim-airline/issues/323#issuecomment-27336312
if !exists('g:airline_symbols')
let g:airline_symbols = {}
endif
let g:airline_left_sep = ''
let g:airline_left_alt_sep = ''
let g:airline_right_sep = ''
let g:airline_right_alt_sep = ''
let g:airline_symbols.notexists = ' '
let g:airline_symbols.dirty = ' '
let g:fern#renderer = "nerdfont"
if has('nvim')
lua require('local-highlight').setup { cw_hlgroup = 'LspReferenceText' }
@ -347,5 +382,3 @@ endif
" ref: https://github.com/tpope/vim-commentary/issues/15#issuecomment-23127749
autocmd FileType c,cpp,cs,java setlocal commentstring=//\ %s
" Why?!
set noshowmode

View File

@ -116,13 +116,7 @@ in {
'';
};
"nvim/lua/config.lua" = {
text = ''
require('oil').setup {
view_options = {
show_hidden = true,
},
}
'';
source = config.lib.file.mkOutOfStoreSymlink ../nvim2/config.lua;
};
"nvim/ftplugin/java.lua" = {
text = ''
@ -316,6 +310,7 @@ in {
# pkgs.screenkey
pkgs.ipatool # Search and download IPAs
unstable.open-webui
pkgs.web-ext
# My version of BerkeleyMono NF is incomplete. Should add some fallback fonts.
# (pkgs.nerdfonts.override { fonts = [
@ -516,6 +511,23 @@ in {
Restart = "always";
};
};
rclone-dropbox = {
Unit = {
Description = "mount Dropbox.";
After = [ "network-online.target" ];
};
Install = {
WantedBy = [ "default.target" ];
};
Service = {
Type = "forking";
Environment = [ "PATH=/run/wrappers/bin/:$PATH" ];
ExecStart = "${pkgs.rclone}/bin/rclone mount dropbox: /mnt/dropbox --copy-links --allow-other --allow-non-empty --umask 000 --daemon --vfs-cache-mode writes --buffer-size 10M";
ExecStop = "fusermount -u /mnt/dropbox";
Restart = "always";
RestartSec = 10;
};
};
};
}

289
nvim2/config.lua Normal file
View File

@ -0,0 +1,289 @@
# vim:foldmethod=marker:foldmarker={{{,}}}:
require('oil').setup {
columns = {
"icon",
"permissions",
"size",
"mtime",
},
keymaps = {
["<C-v>"] = { "actions.select", opts = { vertical = true } },
["<C-x>"] = { "actions.select", opts = { horizontal = true } },
},
view_options = {
show_hidden = true,
},
}
-- {{{ LSP Related
vim.diagnostic.config({ virtual_text = false })
--- {{{ nvim-treesitter setup
local config = require("nvim-treesitter.configs")
config.setup {
ensure_installed = {"lua", "cpp", "rust", "javascript", "python", "typescript", "html", "css", "scss"},
auto_install = true,
highlight = { enable = true},
indent = { enable = true},
}
--- }}}
--- {{{ nvim-cmp setup
local cmp_status, cmp = pcall(require, "cmp")
if not cmp_status then
return
end
local luasnip_status, luasnip = pcall(require, "luasnip")
if not luasnip_status then
return
end
vim.opt.completeopt = "menu,menuone,noselect"
local has_words_before = function()
unpack = unpack or table.unpack
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
local is_empty_line = function()
unpack = unpack or table.unpack
local line, _ = unpack(vim.api.nvim_win_get_cursor(0))
return vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:match("%S") == nil
end
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
local lspkind = require('lspkind')
cmp.setup {
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = {
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
if not is_empty_line() then
cmp.confirm({ select = true })
else
fallback()
end
elseif luasnip_status and luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function()
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn["vsnip#jumpable"](-1) == 1 then
feedkey("<Plug>(vsnip-jump-prev)", "")
end
end, { "i", "s" }),
['<C-k>'] = cmp.mapping.select_prev_item(),
['<C-j>'] = cmp.mapping.select_next_item(),
['<ESC>'] = cmp.mapping.abort(),
},
-- sources for autocompletion
sources = cmp.config.sources({
{ name = "cody" },
{
name = "nvim_lsp",
option = {
markdown_oxide = { keyword_pattern = [[\(\k\| \|\/\|#\)\+]] }
}
}, -- LSP
{ name = "luasnip" }, -- snippets
{ name = "buffer" }, -- text within the current buffer
{ name = "path" }, -- file system paths
{ name = "emoji" },
{ name = "nerdfont" },
{ name = "calc" },
}),
formatting = {
fields = { cmp.ItemField.Abbr, cmp.ItemField.Kind, cmp.ItemField.Menu },
format = lspkind.cmp_format({
mode = 'symbol_text', -- show only symbol annotations
maxwidth = 50, -- prevent the popup from showing more than provided characters (e.g 50 will not show more than 50 characters)
-- can also be a function to dynamically calculate max width such as
-- maxwidth = function() return math.floor(0.45 * vim.o.columns) end,
ellipsis_char = '', -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead (must define maxwidth first)
show_labelDetails = true, -- show labelDetails in menu. Disabled by default
-- The function below will be called before any actual modifications from lspkind
-- so that you can provide more controls on popup customization. (See [#30](https://github.com/onsails/lspkind-nvim/pull/30))
before = function (entry, vim_item)
-- local word = entry:get_insert_text()
-- if entry.completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet then
-- word = word
-- -- word = vim.lsp.util.parse_snippet(word)
-- end
-- word = str.oneline(word)
-- if entry.completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet and string.sub(vim_item.abbr, -1, -1) == "~" then
-- word = word .. "~"
-- end
-- vim_item.abbr = word
return vim_item
end
})
}
}
--- }}}
--- {{{ Configuration for specific LSPs
local lspconfig = require('lspconfig')
local capabilities = require('cmp_nvim_lsp').default_capabilities()
-- local extended_caps = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities)
-- lspconfig.svls.setup {
-- capabilities = capabilities
-- }
lspconfig.clangd.setup {
capabilities = capabilities,
root_dir = function(fname)
return lspconfig.util.root_pattern('compile_commands.json')(fname) or lspconfig.util.find_git_ancestor(fname) or vim.fn.getcwd()
end,
cmd = {
"clangd",
-- "--header-insertion=never",
"--clang-tidy",
"--clang-tidy-checks=*",
}
}
lspconfig.pyright.setup {
capabilities = capabilities
}
lspconfig.ts_ls.setup {
capabilities = capabilities
}
lspconfig.rust_analyzer.setup {
capabilities = capabilities,
-- Server-specific settings. See `:help lspconfig-setup`
settings = {
['rust-analyzer'] = {
checkOnSave = {
command = 'clippy',
}
},
},
}
lspconfig.hls.setup {}
lspconfig.lua_ls.setup {
capabilities = capabilities
}
lspconfig.cmake.setup {}
lspconfig.asm_lsp.setup {
capabilities = capabilities
}
lspconfig.nil_ls.setup {
capabilities = capabilities
}
lspconfig.mojo.setup {}
lspconfig.nushell.setup {}
--- }}}
--- {{{ Smart inlay hints
vim.api.nvim_create_autocmd("LspAttach", {
callback = function()
vim.lsp.inlay_hint.enable(true)
end,
})
vim.api.nvim_create_autocmd('InsertEnter', {
callback = function()
vim.lsp.inlay_hint.enable(false)
end
})
vim.api.nvim_create_autocmd('InsertLeave', {
callback = function()
vim.lsp.inlay_hint.enable(true)
end
})
--- }}}
--- {{{ trouble.nvim keybinds
require('trouble').setup()
vim.keymap.set('n', '<leader>dd', '<Cmd>Trouble diagnostics toggle focus=true filter.buf=0<CR>');
vim.keymap.set('n', '<leader>dw', '<Cmd>Trouble diagnostics toggle focus=true<CR>');
vim.keymap.set('n', '<leader>dq', '<Cmd>Trouble qflist toggle focus=true<CR>');
vim.keymap.set('n', '<leader>w', '<Cmd>Trouble lsp toggle focus=true<CR>');
--- }}}
--- {{{ Common diagnostics keybinds
vim.keymap.set('n', 'qq', vim.diagnostic.open_float);
vim.keymap.set('n', 'qn', vim.diagnostic.goto_next);
vim.keymap.set('n', 'qp', vim.diagnostic.goto_prev);
--- }}}
--- {{{ LSP keybinds
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
-- Enable completion triggered by <c-x><c-o>
-- vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
local opts = { buffer = ev.buf }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
vim.keymap.set('n', '<space>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, opts)
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action, opts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
end,
})
--- }}}
require('goto-preview').setup {
default_mappings = true
}
-- }}}
-- {{{ Fold Management
vim.o.foldcolumn = '1' -- '0' is not bad
vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
vim.o.foldlevelstart = 99
vim.o.foldenable = true
-- Using ufo provider need remap `zR` and `zM`. If Neovim is 0.6.1, remap yourself
vim.keymap.set('n', 'zR', require('ufo').openAllFolds)
vim.keymap.set('n', 'zM', require('ufo').closeAllFolds)
-- Option 2: nvim lsp as LSP client
-- Tell the server the capability of foldingRange,
-- Neovim hasn't added foldingRange to default capabilities, users must add it manually
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true
}
local language_servers = require("lspconfig").util.available_servers() -- or list servers manually like {'gopls', 'clangd'}
for _, ls in ipairs(language_servers) do
require('lspconfig')[ls].setup({
capabilities = capabilities
-- you can add other fields for setting up lsp server in this table
})
end
require('ufo').setup()
-- }}}