mirror of
https://github.com/Smaug123/nix-dotfiles
synced 2025-10-13 02:18:42 +00:00
Big neovim overhaul (#38)
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
autocd = true;
|
||||
enableAutosuggestions = true;
|
||||
autosuggestion.enable = true;
|
||||
enableCompletion = true;
|
||||
history = {
|
||||
expireDuplicatesFirst = true;
|
||||
@@ -47,7 +47,7 @@
|
||||
EDITOR = "vim";
|
||||
LC_ALL = "en_US.UTF-8";
|
||||
LC_CTYPE = "en_US.UTF-8";
|
||||
RUSTFLAGS = "-L ${nixpkgs.libiconv}/lib -L ${nixpkgs.libcxxabi}/lib -L ${nixpkgs.libcxx}/lib";
|
||||
RUSTFLAGS = "-L ${nixpkgs.libiconv}/lib -L ${nixpkgs.libcxx}/lib";
|
||||
RUST_BACKTRACE = "full";
|
||||
};
|
||||
shellAliases = {
|
||||
@@ -139,65 +139,132 @@
|
||||
};
|
||||
|
||||
programs.neovim = let
|
||||
pynvimpp = nixpkgs.python3.pkgs.buildPythonPackage {
|
||||
pname = "pynvim-pp";
|
||||
version = "unstable-2024-03-24";
|
||||
pyproject = true;
|
||||
|
||||
src = nixpkgs.fetchFromGitHub {
|
||||
owner = "ms-jpq";
|
||||
repo = "pynvim_pp";
|
||||
rev = "34e3a027c595981886d7efd1c91071f3eaa4715d";
|
||||
hash = "sha256-2+jDRJXlg9q4MN9vOhmeq4cWVJ0wp5r5xAh3G8lqgOg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [nixpkgs.python3.pkgs.setuptools];
|
||||
|
||||
propagatedBuildInputs = [nixpkgs.python3.pkgs.pynvim];
|
||||
};
|
||||
in let
|
||||
pythonEnv = nixpkgs.python3.withPackages (ps: [
|
||||
ps.pynvim
|
||||
ps.pynvim-pp
|
||||
pynvimpp
|
||||
ps.pyyaml
|
||||
ps.std2
|
||||
]);
|
||||
debugPyEnv = nixpkgs.python3.withPackages (ps: [ps.debugpy]);
|
||||
in {
|
||||
enable = true;
|
||||
plugins = [
|
||||
nixpkgs.vimPlugins.molokai
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.which-key-nvim;
|
||||
type = "lua";
|
||||
config = builtins.readFile ./nvim/which-key.lua;
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.tokyonight-nvim;
|
||||
config = builtins.readFile ./nvim/tokyonight.lua;
|
||||
type = "lua";
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.nvim-treesitter.withAllGrammars;
|
||||
config = builtins.readFile ./nvim/treesitter.lua;
|
||||
type = "lua";
|
||||
}
|
||||
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.nvim-lspconfig;
|
||||
config = builtins.readFile ./nvim/lspconfig.lua;
|
||||
type = "lua";
|
||||
}
|
||||
nixpkgs.vimPlugins.telescope-nvim
|
||||
nixpkgs.vimPlugins.tagbar
|
||||
nixpkgs.vimPlugins.fzf-vim
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.roslyn-nvim;
|
||||
config = builtins.readFile ./nvim/roslyn-nvim.lua;
|
||||
type = "lua";
|
||||
}
|
||||
{
|
||||
plugin = let
|
||||
name = "coq.artifacts";
|
||||
rev = "9c5067a471322c6bb866545e88e5b28c82511865";
|
||||
in
|
||||
nixpkgs.vimUtils.buildVimPlugin {
|
||||
name = name;
|
||||
src = nixpkgs.fetchFromGitHub {
|
||||
owner = "ms-jpq";
|
||||
repo = name;
|
||||
rev = rev;
|
||||
hash = "sha256-BHm7U3pINtYamY7m26I4lQee7ccJ6AcHmYx7j1MRFDA=";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
plugin = let
|
||||
name = "venv-selector.nvim";
|
||||
rev = "2ad34f36d498ff5193ea10f79c87688bd5284172";
|
||||
in
|
||||
nixpkgs.vimUtils.buildVimPlugin {
|
||||
name = name;
|
||||
src = nixpkgs.fetchFromGitHub {
|
||||
owner = "linux-cultist";
|
||||
repo = name;
|
||||
rev = rev;
|
||||
hash = "sha256-aOga7kJ1y3T2vDyYFl/XHOwk35ZqeUcfPUk+Pr1mIeo=";
|
||||
};
|
||||
};
|
||||
config = builtins.readFile ./nvim/venv-selector.lua;
|
||||
type = "lua";
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.Ionide-vim;
|
||||
config = ''
|
||||
let g:fsharp#fsautocomplete_command = ['dotnet', 'fsautocomplete', '--background-service-enabled']
|
||||
let g:fsharp#show_signature_on_cursor_move = 1
|
||||
if has('nvim') && exists('*nvim_open_win')
|
||||
augroup FSharpGroup
|
||||
autocmd!
|
||||
autocmd FileType fsharp nnoremap <leader>t :call fsharp#showTooltip()<CR>
|
||||
augroup END
|
||||
endif
|
||||
'';
|
||||
type = "lua";
|
||||
config = builtins.readFile ./nvim/ionide-vim.lua;
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.chadtree;
|
||||
config = "let g:chadtree_settings = {'xdg': v:true}";
|
||||
config = builtins.readFile ./nvim/chadtree.vim;
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.coq_nvim;
|
||||
config = ''let g:coq_settings = { 'auto_start': v:true, 'xdg': v:true }'';
|
||||
config = ''let g:coq_settings = { 'auto_start': 'shut-up', 'xdg': v:true }'';
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.rust-vim;
|
||||
config = "let g:rustfmt_autosave = 1";
|
||||
plugin = nixpkgs.vimPlugins.rustaceanvim;
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.LanguageClient-neovim;
|
||||
config = "let g:LanguageClient_serverCommands = { 'nix': ['rnix-lsp'] }";
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.syntastic;
|
||||
config = '' let g:syntastic_rust_checkers = ['cargo']
|
||||
let g:syntastic_always_populate_loc_list = 1
|
||||
let g:syntastic_auto_loc_list = 1
|
||||
let g:syntastic_check_on_open = 1
|
||||
let g:syntastic_check_on_wq = 0'';
|
||||
plugin = nixpkgs.vimPlugins.nvim-dap;
|
||||
config = builtins.readFile ./nvim/nvim-dap.lua;
|
||||
type = "lua";
|
||||
}
|
||||
{
|
||||
plugin = nixpkgs.vimPlugins.nvim-dap-python;
|
||||
config = builtins.replaceStrings ["%PYTHONENV%"] ["${debugPyEnv}"] (builtins.readFile ./nvim/nvim-dap-python.lua);
|
||||
type = "lua";
|
||||
}
|
||||
|
||||
nixpkgs.vimPlugins.tagbar
|
||||
];
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
vimdiffAlias = true;
|
||||
withPython3 = true;
|
||||
|
||||
extraLuaConfig = ''vim.g.python3_host_prog="${pythonEnv}/bin/python"'';
|
||||
extraConfig = builtins.readFile ./init.vim;
|
||||
extraLuaConfig = builtins.replaceStrings ["%PYTHONENV%"] ["${pythonEnv}"] (builtins.readFile ./nvim/init.lua);
|
||||
|
||||
package = nixpkgs.neovim-nightly;
|
||||
};
|
||||
|
||||
programs.direnv = {
|
||||
@@ -218,6 +285,10 @@
|
||||
};
|
||||
|
||||
home.packages = [
|
||||
nixpkgs.csharp-ls
|
||||
nixpkgs.netcoredbg
|
||||
nixpkgs.nil
|
||||
nixpkgs.fsautocomplete
|
||||
nixpkgs.keepassxc
|
||||
nixpkgs.rust-analyzer
|
||||
nixpkgs.tmux
|
||||
@@ -244,7 +315,6 @@
|
||||
nixpkgs.git-lfs
|
||||
nixpkgs.imagemagick
|
||||
nixpkgs.nixpkgs-fmt
|
||||
nixpkgs.rnix-lsp
|
||||
nixpkgs.grpc-tools
|
||||
nixpkgs.element-desktop
|
||||
nixpkgs.ihp-new
|
||||
@@ -252,6 +322,7 @@
|
||||
nixpkgs.lnav
|
||||
nixpkgs.age
|
||||
nixpkgs.nodejs
|
||||
nixpkgs.nodePackages.pyright
|
||||
nixpkgs.sqlitebrowser
|
||||
nixpkgs.typst
|
||||
nixpkgs.poetry
|
||||
@@ -262,6 +333,8 @@
|
||||
nixpkgs.ffmpeg
|
||||
nixpkgs.bat
|
||||
nixpkgs.pandoc
|
||||
nixpkgs.fd
|
||||
nixpkgs.sumneko-lua-language-server
|
||||
(nixpkgs.nerdfonts.override {fonts = ["FiraCode" "DroidSansMono"];})
|
||||
];
|
||||
|
||||
|
@@ -1,357 +0,0 @@
|
||||
set nu
|
||||
colorscheme molokai
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Maintainer:
|
||||
" Amir Salihefendic — @amix3k
|
||||
"
|
||||
" Awesome_version:
|
||||
" Get this config, nice color schemes and lots of plugins!
|
||||
"
|
||||
" Install the awesome version from:
|
||||
"
|
||||
" https://github.com/amix/vimrc
|
||||
"
|
||||
" Sections:
|
||||
" -> General
|
||||
" -> VIM user interface
|
||||
" -> Colors and Fonts
|
||||
" -> Files and backups
|
||||
" -> Text, tab and indent related
|
||||
" -> Visual mode related
|
||||
" -> Moving around, tabs and buffers
|
||||
" -> Status line
|
||||
" -> Editing mappings
|
||||
" -> vimgrep searching and cope displaying
|
||||
" -> Spell checking
|
||||
" -> Misc
|
||||
" -> Helper functions
|
||||
"
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => General
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Sets how many lines of history VIM has to remember
|
||||
set history=500
|
||||
|
||||
" Enable filetype plugins
|
||||
filetype plugin on
|
||||
filetype indent on
|
||||
|
||||
" Set to auto read when a file is changed from the outside
|
||||
set autoread
|
||||
|
||||
" With a map leader it's possible to do extra key combinations
|
||||
" like <leader>w saves the current file
|
||||
let mapleader = "`"
|
||||
|
||||
" :W sudo saves the file
|
||||
" (useful for handling the permission-denied error)
|
||||
command W w !sudo tee % > /dev/null
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => VIM user interface
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Set 7 lines to the cursor - when moving vertically using j/k
|
||||
set so=7
|
||||
|
||||
" Avoid garbled characters in Chinese language windows OS
|
||||
let $LANG='en'
|
||||
set langmenu=en
|
||||
source $VIMRUNTIME/delmenu.vim
|
||||
source $VIMRUNTIME/menu.vim
|
||||
|
||||
" Turn on the Wild menu
|
||||
set wildmenu
|
||||
|
||||
" Ignore compiled files
|
||||
set wildignore=*.o,*~,*.pyc
|
||||
if has("win16") || has("win32")
|
||||
set wildignore+=.git\*,.hg\*,.svn\*
|
||||
else
|
||||
set wildignore+=*/.git/*,*/.hg/*,*/.svn/*,*/.DS_Store
|
||||
endif
|
||||
|
||||
"Always show current position
|
||||
set ruler
|
||||
|
||||
" Height of the command bar
|
||||
set cmdheight=2
|
||||
|
||||
" A buffer becomes hidden when it is abandoned
|
||||
set hid
|
||||
|
||||
" Ignore case when searching
|
||||
set ignorecase
|
||||
|
||||
" When searching try to be smart about cases
|
||||
set smartcase
|
||||
|
||||
" Highlight search results
|
||||
set hlsearch
|
||||
|
||||
" Makes search act like search in modern browsers
|
||||
set incsearch
|
||||
|
||||
" Don't redraw while executing macros (good performance config)
|
||||
set lazyredraw
|
||||
|
||||
" For regular expressions turn magic on
|
||||
set magic
|
||||
|
||||
" Show matching brackets when text indicator is over them
|
||||
set showmatch
|
||||
" How many tenths of a second to blink when matching brackets
|
||||
set mat=2
|
||||
|
||||
" No annoying sound on errors
|
||||
set noerrorbells
|
||||
set novisualbell
|
||||
set t_vb=
|
||||
set tm=500
|
||||
|
||||
" Properly disable sound on errors on MacVim
|
||||
if has("gui_macvim")
|
||||
autocmd GUIEnter * set vb t_vb=
|
||||
endif
|
||||
|
||||
|
||||
" Add a bit extra margin to the left
|
||||
set foldcolumn=1
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Colors and Fonts
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Enable syntax highlighting
|
||||
syntax enable
|
||||
|
||||
" Enable 256 colors palette in Gnome Terminal
|
||||
if $COLORTERM == 'gnome-terminal'
|
||||
set t_Co=256
|
||||
endif
|
||||
|
||||
set background=dark
|
||||
|
||||
" Set extra options when running in GUI mode
|
||||
if has("gui_running")
|
||||
set guioptions-=T
|
||||
set guioptions-=e
|
||||
set t_Co=256
|
||||
set guitablabel=%M\ %t
|
||||
endif
|
||||
|
||||
" Set utf8 as standard encoding and en_US as the standard language
|
||||
set encoding=utf8
|
||||
|
||||
" Use Unix as the standard file type
|
||||
set ffs=unix,mac
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Files, backups and undo
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Turn backup off, since most stuff is in SVN, git et.c anyway...
|
||||
set nobackup
|
||||
set nowb
|
||||
set noswapfile
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Text, tab and indent related
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Use spaces instead of tabs
|
||||
set expandtab
|
||||
|
||||
" Be smart when using tabs ;)
|
||||
set smarttab
|
||||
|
||||
" 1 tab == 4 spaces
|
||||
set shiftwidth=4
|
||||
set tabstop=4
|
||||
|
||||
" Linebreak on 500 characters
|
||||
set lbr
|
||||
set tw=500
|
||||
|
||||
set ai "Auto indent
|
||||
set si "Smart indent
|
||||
set wrap "Wrap lines
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Moving around, tabs, windows and buffers
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Map <Space> to / (search) and Ctrl-<Space> to ? (backwards search)
|
||||
map <space> /
|
||||
map <c-space> ?
|
||||
|
||||
" Disable highlight when <leader><cr> is pressed
|
||||
map <silent> <leader><cr> :noh<cr>
|
||||
|
||||
" Smart way to move between windows
|
||||
map <C-j> <C-W>j
|
||||
map <C-k> <C-W>k
|
||||
map <C-h> <C-W>h
|
||||
map <C-l> <C-W>l
|
||||
|
||||
" Close the current buffer
|
||||
map <leader>bd :Bclose<cr>:tabclose<cr>gT
|
||||
|
||||
" Close all the buffers
|
||||
map <leader>ba :bufdo bd<cr>
|
||||
|
||||
map <leader>l :bnext<cr>
|
||||
map <leader>h :bprevious<cr>
|
||||
|
||||
" Useful mappings for managing tabs
|
||||
map <leader>tn :tabnew<cr>
|
||||
map <leader>to :tabonly<cr>
|
||||
map <leader>tc :tabclose<cr>
|
||||
map <leader>tm :tabmove
|
||||
map <leader>t<leader> :tabnext
|
||||
|
||||
" Let 'tl' toggle between this and the last accessed tab
|
||||
let g:lasttab = 1
|
||||
nmap <Leader>tl :exe "tabn ".g:lasttab<CR>
|
||||
au TabLeave * let g:lasttab = tabpagenr()
|
||||
|
||||
|
||||
" Opens a new tab with the current buffer's path
|
||||
" Super useful when editing files in the same directory
|
||||
map <leader>te :tabedit <c-r>=expand("%:p:h")<cr>/
|
||||
|
||||
" Switch CWD to the directory of the open buffer
|
||||
map <leader>cd :cd %:p:h<cr>:pwd<cr>
|
||||
|
||||
" Specify the behavior when switching between buffers
|
||||
try
|
||||
set switchbuf=useopen,usetab,newtab
|
||||
set stal=2
|
||||
catch
|
||||
endtry
|
||||
|
||||
" Return to last edit position when opening files (You want this!)
|
||||
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
|
||||
|
||||
|
||||
""""""""""""""""""""""""""""""
|
||||
" => Status line
|
||||
""""""""""""""""""""""""""""""
|
||||
" Always show the status line
|
||||
set laststatus=2
|
||||
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Editing mappings
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Delete trailing white space on save, useful for some filetypes ;)
|
||||
fun! CleanExtraSpaces()
|
||||
let save_cursor = getpos(".")
|
||||
let old_query = getreg('/')
|
||||
silent! %s/\s\+$//e
|
||||
call setpos('.', save_cursor)
|
||||
call setreg('/', old_query)
|
||||
endfun
|
||||
|
||||
if has("autocmd")
|
||||
autocmd BufWritePre *.fs,*.fsi,*.txt,*.js,*.py,*.wiki,*.sh,*.coffee :call CleanExtraSpaces()
|
||||
endif
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Spell checking
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Pressing ,ss will toggle and untoggle spell checking
|
||||
map <leader>ss :setlocal spell!<cr>
|
||||
|
||||
" Shortcuts using <leader>
|
||||
map <leader>sn ]s
|
||||
map <leader>sp [s
|
||||
map <leader>sa zg
|
||||
map <leader>s? z=
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Misc
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Remove the Windows ^M - when the encodings gets messed up
|
||||
noremap <Leader>m mmHmt:%s/<C-V><cr>//ge<cr>'tzt'm
|
||||
|
||||
" Quickly open a buffer for scribble
|
||||
map <leader>q :e ~/buffer<cr>
|
||||
|
||||
" Quickly open a markdown buffer for scribble
|
||||
map <leader>x :e ~/buffer.md<cr>
|
||||
|
||||
" Toggle paste mode on and off
|
||||
map <leader>pp :setlocal paste!<cr>
|
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Helper functions
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Returns true if paste mode is enabled
|
||||
function! HasPaste()
|
||||
if &paste
|
||||
return 'PASTE MODE '
|
||||
endif
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Don't close window, when deleting a buffer
|
||||
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
|
||||
|
||||
function! CmdLine(str)
|
||||
call feedkeys(":" . a:str)
|
||||
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
|
||||
|
||||
nnoremap <leader>c :!cargo clippy
|
||||
nnoremap <leader>j :%!python -m json.tool
|
||||
|
||||
set statusline+=%#warningmsg#
|
||||
set statusline+=%{SyntasticStatuslineFlag()}
|
||||
set statusline+=%*
|
||||
" Format the status line
|
||||
set statusline=\ %{HasPaste()}%F%m%r%h\ %w\ \ CWD:\ %r%{getcwd()}%h\ \ \ Line:\ %l\ \ Column:\ %c
|
||||
|
||||
set fileformat=unix
|
4
home-manager/nvim/chadtree.vim
Normal file
4
home-manager/nvim/chadtree.vim
Normal file
@@ -0,0 +1,4 @@
|
||||
let g:chadtree_settings = {'xdg': v:true}
|
||||
|
||||
autocmd VimEnter * CHADopen --nofocus
|
||||
autocmd bufenter * if (winnr("$") == 1 && &filetype == 'CHADtree') | q | endif
|
256
home-manager/nvim/init.lua
Normal file
256
home-manager/nvim/init.lua
Normal file
@@ -0,0 +1,256 @@
|
||||
vim.g.python3_host_prog = "%PYTHONENV%/bin/python"
|
||||
vim.opt.mouse = ""
|
||||
vim.opt.history = 500
|
||||
vim.opt.background = "dark"
|
||||
|
||||
vim.opt.wildmenu = true
|
||||
vim.opt.wildignore = vim.opt.wildignore + { "*/.git/*", "*/.hg/*", "*/.svn/*", "*/.DS_Store" }
|
||||
|
||||
vim.opt.ignorecase = true
|
||||
vim.opt.smartcase = true
|
||||
vim.opt.incsearch = true
|
||||
vim.opt.magic = true
|
||||
vim.opt.hlsearch = true
|
||||
|
||||
vim.opt.autoindent = true
|
||||
vim.opt.smartindent = true
|
||||
|
||||
vim.opt.wrap = true
|
||||
vim.opt.linebreak = true
|
||||
vim.opt.textwidth = 500
|
||||
|
||||
vim.opt.switchbuf = "useopen"
|
||||
|
||||
vim.opt.laststatus = 2
|
||||
-- I don't use tabs, but one day I might!
|
||||
vim.opt.showtabline = 2
|
||||
|
||||
vim.opt.langmenu = "en"
|
||||
|
||||
vim.opt.ffs = "unix"
|
||||
vim.opt.encoding = "utf8"
|
||||
|
||||
-- Always show current position
|
||||
vim.opt.ruler = true
|
||||
vim.opt.number = true
|
||||
|
||||
-- A bit of extra margin to the left
|
||||
vim.opt.foldcolumn = "1"
|
||||
|
||||
vim.opt.autoread = true
|
||||
vim.opt.backup = false
|
||||
vim.opt.writebackup = true
|
||||
vim.opt.swapfile = false
|
||||
|
||||
vim.opt.cmdheight = 2
|
||||
|
||||
-- Use spaces instead of tabs
|
||||
vim.opt.expandtab = true
|
||||
vim.opt.smarttab = true
|
||||
vim.opt.shiftwidth = 4
|
||||
vim.opt.tabstop = 4
|
||||
|
||||
vim.opt.lazyredraw = true
|
||||
|
||||
-- Show matching brackets when text indicator is on one of them
|
||||
vim.opt.showmatch = true
|
||||
vim.opt.mat = 2
|
||||
|
||||
-- Turn off sound
|
||||
vim.opt.errorbells = false
|
||||
vim.opt.visualbell = false
|
||||
|
||||
vim.opt.timeoutlen = 500
|
||||
|
||||
vim.opt.scrolloff = 2
|
||||
|
||||
-- Return to last edit position when opening files
|
||||
vim.api.nvim_create_autocmd("BufReadPost", {
|
||||
pattern = "*",
|
||||
callback = function()
|
||||
local line = vim.fn.line
|
||||
local last_pos = line("'\"")
|
||||
if last_pos > 1 and last_pos <= line("$") then
|
||||
vim.cmd("normal! g'\"")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Trim trailing whitespace on save
|
||||
function CleanExtraSpaces()
|
||||
local save_cursor = vim.api.nvim_win_get_cursor(0)
|
||||
local old_query = vim.fn.getreg("/")
|
||||
vim.cmd("%s/\\s\\+$//e")
|
||||
vim.api.nvim_win_set_cursor(0, save_cursor)
|
||||
vim.fn.setreg("/", old_query)
|
||||
end
|
||||
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||
pattern = { "*.fs", "*.fsi", "*.txt", "*.js", "*.py", "*.wiki", "*.sh", "*.coffee" },
|
||||
callback = CleanExtraSpaces,
|
||||
})
|
||||
|
||||
-- Status line
|
||||
|
||||
-- Returns true if paste mode is enabled
|
||||
function HasPaste()
|
||||
if vim.opt.paste:get() then
|
||||
return "PASTE MODE "
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
vim.o.statusline = vim.o.statusline .. "%{v:lua.HasPaste()}%F%m%r%h %w CWD: %r%{getcwd()}%h Line: %l Column: %c"
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
vim.api.nvim_set_keymap("n", ";", "<Nop>", { noremap = true })
|
||||
vim.api.nvim_set_var("maplocalleader", ";")
|
||||
|
||||
function MarkdownPreview()
|
||||
local temp_file = vim.fn.tempname() .. ".md"
|
||||
local file_name = vim.fn.substitute(vim.fn.tolower(vim.fn.expand("%:t")), "\\W", "_", "g")
|
||||
local temp_html = "/tmp/" .. file_name .. "_tmp.html"
|
||||
|
||||
-- Write the current buffer to the temp file
|
||||
vim.cmd("write! " .. temp_file)
|
||||
|
||||
local pandoc_cmd = "pandoc " .. temp_file .. " -o " .. temp_html
|
||||
|
||||
-- Execute the pandoc command
|
||||
vim.fn.system(pandoc_cmd)
|
||||
|
||||
-- Use tmux and lynx to preview the HTML file
|
||||
local lynx_cmd = "tmux split-window -h lynx " .. temp_html
|
||||
vim.fn.jobstart(vim.split(lynx_cmd, " "), { silent = true })
|
||||
|
||||
-- Delete the temp markdown file
|
||||
vim.fn.delete(temp_file, "rf")
|
||||
end
|
||||
|
||||
function RemoveCarriageReturn()
|
||||
vim.cmd("mark m")
|
||||
vim.cmd("normal! Hmt")
|
||||
vim.cmd("%s/\r//ge")
|
||||
vim.cmd("normal! 'tzt'm")
|
||||
end
|
||||
|
||||
function FormatJson()
|
||||
vim.cmd("%!python -m json.tool")
|
||||
end
|
||||
|
||||
function ChangeToCurrentDirectory()
|
||||
vim.cmd(":cd %:p:h")
|
||||
vim.cmd(":pwd")
|
||||
end
|
||||
|
||||
local function close_loclist_if_orphaned()
|
||||
local win = vim.fn.expand("<afile>")
|
||||
vim.fn.win_execute(win, "lclose")
|
||||
end
|
||||
|
||||
-- Set up an autocmd using the nvim_create_autocmd API
|
||||
vim.api.nvim_create_autocmd("WinClosed", {
|
||||
pattern = "*",
|
||||
callback = close_loclist_if_orphaned,
|
||||
})
|
||||
|
||||
local status, whichkey = pcall(require, "which-key")
|
||||
if status then
|
||||
local pickers = require("telescope.pickers")
|
||||
local action_state = require("telescope.actions.state")
|
||||
local actions = require("telescope.actions")
|
||||
local finders = require("telescope.finders")
|
||||
local conf = require("telescope.config").values
|
||||
|
||||
function DisplayAllMappingsWithTelescope()
|
||||
local mappings = {}
|
||||
local commands = {} -- Store commands keyed by the display string
|
||||
|
||||
local function accumulate(tree)
|
||||
tree:walk(function(node)
|
||||
-- Note: we could (if desired) view all groups, because the `node.mapping` table looks like this:
|
||||
-- { prefix = "g", group = true, keys = {...}}
|
||||
if node.mapping then
|
||||
local mapping = node.mapping
|
||||
if not mapping.group then
|
||||
local description = mapping.desc or mapping.label or mapping.cmd
|
||||
-- Some actions are just there for which-key to hook into to display prefixes; they don't have a description.
|
||||
if description then
|
||||
local displayString = description .. " | " .. mapping.prefix
|
||||
commands[displayString] = mapping.prefix
|
||||
mappings[#mappings + 1] = displayString
|
||||
else
|
||||
for k, v in pairs(mapping) do
|
||||
print("Nothing: " .. k .. " : " .. tostring(v) .. " (type: " .. type(v) .. ")")
|
||||
end
|
||||
print("-----")
|
||||
end
|
||||
end
|
||||
-- TODO: If a command is a prefix of an existing command, prepend its description to those commands' descriptions, and append a '...' to the parent's description.
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local cur_buf = vim.api.nvim_win_get_buf(0)
|
||||
|
||||
accumulate(require("which-key.keys").get_tree("n").tree)
|
||||
accumulate(require("which-key.keys").get_tree("n", cur_buf).tree)
|
||||
|
||||
pickers
|
||||
.new({}, {
|
||||
prompt_title = "Actions",
|
||||
finder = finders.new_table({
|
||||
results = mappings,
|
||||
}),
|
||||
sorter = conf.generic_sorter({}),
|
||||
attach_mappings = function(_, map)
|
||||
map("i", "<CR>", function(bufnr)
|
||||
local selection = action_state.get_selected_entry()
|
||||
actions.close(bufnr)
|
||||
local cmd = commands[selection.value]
|
||||
if cmd then
|
||||
vim.api.nvim_command(":normal " .. vim.api.nvim_replace_termcodes(cmd, true, true, true))
|
||||
else
|
||||
print("no command found")
|
||||
end
|
||||
end)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
:find()
|
||||
end
|
||||
|
||||
function ToggleSpell()
|
||||
vim.cmd("setlocal spell!")
|
||||
end
|
||||
|
||||
whichkey.register({
|
||||
-- TODO: this isn't working for the FSI ones - maybe we've moved to a different buffer by the time we ask for the keymap?
|
||||
[vim.api.nvim_get_var("maplocalleader")] = {
|
||||
DisplayAllMappingsWithTelescope,
|
||||
"View all mappings",
|
||||
},
|
||||
m = {
|
||||
p = { MarkdownPreview, "Preview Markdown in Lynx" },
|
||||
d = { RemoveCarriageReturn, "Delete carriage returns from file" },
|
||||
},
|
||||
["j"] = {
|
||||
FormatJson,
|
||||
"Auto-format JSON",
|
||||
},
|
||||
["cd"] = {
|
||||
ChangeToCurrentDirectory,
|
||||
"Switch CWD to the directory of the open buffer",
|
||||
},
|
||||
["ss"] = {
|
||||
ToggleSpell,
|
||||
"Toggle spell-checker on or off",
|
||||
},
|
||||
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
|
||||
else
|
||||
vim.api.nvim_set_keymap("n", "<localleader>mp", ":lua MarkdownPreview()<CR>", { noremap = true, silent = true })
|
||||
-- Remove the Windows ^M - when the encodings gets messed up
|
||||
vim.api.nvim_set_keymap("n", "<localleader>md", ":lua RemoveCarriageReturn()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>j", ":lua FormatJson()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>cd", ":lua ChangeToCurrentDirectory()<CR>", { noremap = true })
|
||||
end
|
263
home-manager/nvim/ionide-vim.lua
Normal file
263
home-manager/nvim/ionide-vim.lua
Normal file
@@ -0,0 +1,263 @@
|
||||
vim.g["fsharp#fsautocomplete_command"] = { "fsautocomplete" }
|
||||
vim.g["fsharp#show_signature_on_cursor_move"] = 1
|
||||
vim.g["fsharp#fsi_keymap"] = "none"
|
||||
|
||||
-- MASSIVE HACK - raised https://github.com/ionide/Ionide-vim/pull/78
|
||||
local function captureLoadedProjects()
|
||||
vim.fn.execute("redir => g:massive_hack_patrick_capture")
|
||||
vim.fn.execute("call fsharp#showLoadedProjects()")
|
||||
vim.fn.execute("redir END")
|
||||
local output = vim.fn.eval("g:massive_hack_patrick_capture")
|
||||
|
||||
local projects = {}
|
||||
|
||||
for line in output:gmatch("[^\r\n]+") do
|
||||
local project = line:gsub("^%s*-%s*", "")
|
||||
table.insert(projects, project)
|
||||
end
|
||||
|
||||
return projects
|
||||
end
|
||||
|
||||
-- Supply nil to get all loaded F# projects and build them.
|
||||
local function BuildFSharpProjects(projects)
|
||||
local function on_output(context, prefix, err, data)
|
||||
if err or data then
|
||||
vim.schedule(function()
|
||||
if err then
|
||||
-- Append the error message to the buffer
|
||||
local count = vim.api.nvim_buf_line_count(context.buf)
|
||||
vim.api.nvim_buf_set_lines(context.buf, count, count, false, { "error " .. prefix .. ": " .. err })
|
||||
end
|
||||
if data then
|
||||
-- Append the data to the buffer
|
||||
local count = vim.api.nvim_buf_line_count(context.buf)
|
||||
vim.api.nvim_buf_set_lines(
|
||||
context.buf,
|
||||
count,
|
||||
count,
|
||||
false,
|
||||
vim.tbl_map(function(line)
|
||||
return prefix .. ": " .. line
|
||||
end, vim.split(data, "\n"))
|
||||
)
|
||||
end
|
||||
if vim.api.nvim_win_is_valid(context.window) then
|
||||
local cur_win = vim.api.nvim_get_current_win()
|
||||
local cur_buf = vim.api.nvim_win_get_buf(cur_win)
|
||||
if cur_buf ~= context.buf then
|
||||
local new_line_count = vim.api.nvim_buf_line_count(context.buf)
|
||||
vim.api.nvim_win_set_cursor(context.window, { new_line_count, 0 })
|
||||
end
|
||||
end
|
||||
-- Keep the window alive if there were warnings
|
||||
if string.match(data, "%s[1-9]%d* Warning%(s%)") then
|
||||
context.warn = context.warn + 1
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_next(context)
|
||||
if context.completed == context.expected then
|
||||
if context.errs == 0 and context.warn == 0 then
|
||||
local cur_win = vim.api.nvim_get_current_win()
|
||||
local cur_buf = vim.api.nvim_win_get_buf(cur_win)
|
||||
if cur_buf ~= context.buf then
|
||||
vim.api.nvim_win_close(context.window, 1)
|
||||
end
|
||||
print("All builds successful")
|
||||
end
|
||||
else
|
||||
local handle
|
||||
local stdout = vim.loop.new_pipe(false)
|
||||
local stderr = vim.loop.new_pipe(false)
|
||||
|
||||
handle, _ = vim.loop.spawn(
|
||||
"dotnet",
|
||||
{
|
||||
args = { "build", context.projects[context.completed + 1] },
|
||||
stdio = { nil, stdout, stderr },
|
||||
},
|
||||
vim.schedule_wrap(function(code, signal)
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
stdout:close()
|
||||
stderr:close()
|
||||
handle:close()
|
||||
print("Build process exited with code " .. code .. " and signal " .. signal)
|
||||
if code ~= 0 then
|
||||
context.errs = context.errs + 1
|
||||
end
|
||||
context.completed = context.completed + 1
|
||||
|
||||
print(
|
||||
"Completed: "
|
||||
.. context.completed
|
||||
.. " out of "
|
||||
.. context.expected
|
||||
.. " (errors: "
|
||||
.. context.errs
|
||||
.. ", warnings: "
|
||||
.. context.warn
|
||||
.. ")"
|
||||
)
|
||||
|
||||
spawn_next(context)
|
||||
end)
|
||||
)
|
||||
|
||||
if not handle then
|
||||
print("Failed to start build process.")
|
||||
return
|
||||
end
|
||||
|
||||
vim.loop.read_start(stdout, function(err, data)
|
||||
on_output(context, "OUT", err, data)
|
||||
end)
|
||||
vim.loop.read_start(stderr, function(err, data)
|
||||
on_output(context, "ERR", err, data)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if not projects then
|
||||
projects = captureLoadedProjects()
|
||||
end
|
||||
if projects then
|
||||
local total_projects = 0
|
||||
for _, _ in ipairs(projects) do
|
||||
total_projects = total_projects + 1
|
||||
end
|
||||
|
||||
-- Create a new buffer for build output
|
||||
local buf = vim.api.nvim_create_buf(false, true) -- No listed, scratch buffer
|
||||
|
||||
-- Calculate window size and position here (example: full width, 10 lines high at the bottom)
|
||||
local width = vim.api.nvim_get_option("columns")
|
||||
local height = vim.api.nvim_get_option("lines")
|
||||
local win_height = math.min(10, math.floor(height * 0.2)) -- 20% of total height or 10 lines
|
||||
local original_win = vim.api.nvim_get_current_win()
|
||||
local win_opts = {
|
||||
relative = "editor",
|
||||
width = width,
|
||||
height = win_height,
|
||||
col = 0,
|
||||
row = height - win_height,
|
||||
style = "minimal",
|
||||
border = "single",
|
||||
}
|
||||
|
||||
local win = vim.api.nvim_open_win(buf, true, win_opts)
|
||||
-- Switch back to the original window
|
||||
vim.api.nvim_set_current_win(original_win)
|
||||
|
||||
local build_context = {
|
||||
warn = 0,
|
||||
errs = 0,
|
||||
completed = 0,
|
||||
expected = total_projects,
|
||||
window = win,
|
||||
projects = projects,
|
||||
buf = buf,
|
||||
}
|
||||
|
||||
spawn_next(build_context)
|
||||
end
|
||||
end
|
||||
|
||||
-- local function fsprojAndDirCompletion(ArgLead, _, _)
|
||||
-- local results = {}
|
||||
-- local loc = ArgLead
|
||||
-- if not loc then
|
||||
-- loc = "."
|
||||
-- end
|
||||
-- local command = string.format(
|
||||
-- "find "
|
||||
-- .. vim.fn.shellescape(loc)
|
||||
-- .. " -maxdepth 2 \\( -type f -name '*.fsproj' -o -type d \\) -print0 2> /dev/null"
|
||||
-- )
|
||||
-- local handle = io.popen(command)
|
||||
-- if handle then
|
||||
-- local stdout = handle:read("*all")
|
||||
-- handle:close()
|
||||
--
|
||||
-- local allResults = {}
|
||||
-- for match in string.gmatch(stdout, "([^%z]+)") do
|
||||
-- table.insert(allResults, match)
|
||||
-- end
|
||||
-- table.sort(allResults, function(a, b)
|
||||
-- local aEndsWithProj = a:match("proj$")
|
||||
-- local bEndsWithProj = b:match("proj$")
|
||||
-- if aEndsWithProj and not bEndsWithProj then
|
||||
-- return true
|
||||
-- elseif not aEndsWithProj and bEndsWithProj then
|
||||
-- return false
|
||||
-- else
|
||||
-- return a < b -- If both or neither end with 'proj', sort alphabetically
|
||||
-- end
|
||||
-- end)
|
||||
--
|
||||
-- for _, line in ipairs(allResults) do
|
||||
-- table.insert(results, line)
|
||||
-- end
|
||||
-- end
|
||||
-- return results
|
||||
-- end
|
||||
|
||||
vim.api.nvim_create_user_command("BuildFSharpProject", function(opts)
|
||||
if opts.fargs and opts.fargs[1] then
|
||||
BuildFSharpProjects(opts.fargs)
|
||||
else
|
||||
local pickers = require("telescope.pickers")
|
||||
local finders = require("telescope.finders")
|
||||
local conf = require("telescope.config").values
|
||||
local action_state = require("telescope.actions.state")
|
||||
local actions = require("telescope.actions")
|
||||
pickers
|
||||
.new({}, {
|
||||
prompt_title = "Actions",
|
||||
finder = finders.new_table({
|
||||
results = captureLoadedProjects(),
|
||||
}),
|
||||
sorter = conf.generic_sorter({}),
|
||||
attach_mappings = function(prompt_buf, _)
|
||||
actions.select_default:replace(function()
|
||||
actions.close(prompt_buf)
|
||||
local selection = action_state.get_selected_entry()
|
||||
BuildFSharpProjects({ selection.value })
|
||||
end)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
:find()
|
||||
end
|
||||
end, { nargs = "?", complete = "file" })
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = "fsharp",
|
||||
callback = function()
|
||||
local status, whichkey = pcall(require, "which-key")
|
||||
if status then
|
||||
whichkey.register({
|
||||
f = {
|
||||
t = { ":call fsharp#showTooltip()<CR>", "Show F# Tooltip" },
|
||||
["si"] = { ":call fsharp#toggleFsi()<CR>", "Toggle FSI (F# Interactive)" },
|
||||
["sl"] = { ":call fsharp#sendLineToFsi()<cr>", "Send line to FSI (F# Interactive)" },
|
||||
},
|
||||
b = {
|
||||
p = {
|
||||
a = { BuildFSharpProjects, "Build all projects" },
|
||||
s = { ":BuildFSharpProject", "Build specified project" },
|
||||
},
|
||||
},
|
||||
}, { prefix = vim.api.nvim_get_var("maplocalleader"), buffer = vim.api.nvim_get_current_buf() })
|
||||
else
|
||||
vim.api.nvim_set_keymap("n", "<localleader>ft", ":call fsharp#showTooltip()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>fsi", ":call fsharp#toggleFsi()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>fsl", ":call fsharp#sendLineToFsi()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>bpa", BuildFSharpProjects, { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>bps", ":BuildFSharpProject", { noremap = true })
|
||||
end
|
||||
end,
|
||||
})
|
170
home-manager/nvim/lspconfig.lua
Normal file
170
home-manager/nvim/lspconfig.lua
Normal file
@@ -0,0 +1,170 @@
|
||||
local coq = require("coq")
|
||||
|
||||
-- Using rustaceanvim means we shouldn't set up the LSP for Rust manually.
|
||||
-- Similarly csharp_ls is unnecessary given roslyn.nvim
|
||||
-- require("lspconfig")["csharp_ls"].setup({})
|
||||
|
||||
require("lspconfig")["lua_ls"].setup({
|
||||
on_init = function(client)
|
||||
local path = client.workspace_folders[1].name
|
||||
if vim.loop.fs_stat(path .. "/.luarc.json") or vim.loop.fs_stat(path .. "/.luarc.jsonc") then
|
||||
return
|
||||
end
|
||||
|
||||
client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, {
|
||||
runtime = {
|
||||
-- Tell the language server which version of Lua you're using
|
||||
-- (most likely LuaJIT in the case of Neovim)
|
||||
version = "LuaJIT",
|
||||
},
|
||||
-- Make the server aware of Neovim runtime files
|
||||
workspace = {
|
||||
checkThirdParty = false,
|
||||
library = {
|
||||
vim.env.VIMRUNTIME,
|
||||
-- Depending on the usage, you might want to add additional paths here.
|
||||
-- "${3rd}/luv/library"
|
||||
-- "${3rd}/busted/library",
|
||||
},
|
||||
-- or pull in all of 'runtimepath'. NOTE: this is a lot slower
|
||||
-- library = vim.api.nvim_get_runtime_file("", true)
|
||||
},
|
||||
})
|
||||
end,
|
||||
settings = {
|
||||
Lua = {},
|
||||
},
|
||||
})
|
||||
|
||||
require("lspconfig").pyright.setup(coq.lsp_ensure_capabilities({
|
||||
handlers = {
|
||||
["textDocument/publishDiagnostics"] = function(...)
|
||||
vim.lsp.diagnostic.on_publish_diagnostics(...)
|
||||
|
||||
local window = vim.api.nvim_get_current_win()
|
||||
vim.diagnostic.setloclist({ open_loclist = true })
|
||||
vim.api.nvim_set_current_win(window)
|
||||
end,
|
||||
},
|
||||
}))
|
||||
|
||||
require("lspconfig").nil_ls.setup(coq.lsp_ensure_capabilities({
|
||||
settings = {
|
||||
nix = {
|
||||
flake = {
|
||||
autoArchive = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
function ToggleLocList()
|
||||
local winid = vim.fn.getloclist(0, { winid = 0 }).winid
|
||||
if winid == 0 then
|
||||
local window = vim.api.nvim_get_current_win()
|
||||
vim.cmd.lopen()
|
||||
vim.api.nvim_set_current_win(window)
|
||||
else
|
||||
vim.cmd.lclose()
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local whichkey_status, whichkey = pcall(require, "which-key")
|
||||
if whichkey_status then
|
||||
whichkey.register({
|
||||
l = {
|
||||
name = "loclist-related commands",
|
||||
p = { vim.diagnostic.goto_prev, "Go to previous entry in loclist" },
|
||||
n = { vim.diagnostic.goto_next, "Go to next entry in loclist" },
|
||||
l = { ToggleLocList, "Toggle loclist" },
|
||||
f = { vim.diagnostic.open_float, "Open current loclist entry in floating window" },
|
||||
},
|
||||
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
|
||||
else
|
||||
vim.keymap.set("n", "<localleader>lp", vim.diagnostic.goto_prev)
|
||||
vim.keymap.set("n", "<localleader>ln", vim.diagnostic.goto_next)
|
||||
vim.keymap.set("n", "<localleader>ll", ToggleLocList)
|
||||
vim.keymap.set("n", "<localleader>lf", vim.diagnostic.open_float)
|
||||
end
|
||||
end
|
||||
|
||||
-- Use LspAttach autocommand to only map the following keys
|
||||
-- after the language server attaches to the current buffer
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
|
||||
callback = function(ev)
|
||||
local whichkey_status, whichkey = pcall(require, "which-key")
|
||||
-- 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 }
|
||||
if whichkey_status then
|
||||
whichkey.register({
|
||||
g = {
|
||||
name = "Go-to related commands",
|
||||
D = { vim.lsp.buf.declaration, "Go to declaration" },
|
||||
d = { vim.lsp.buf.definition, "Go to definition" },
|
||||
i = { vim.lsp.buf.implementation, "Go to implementation" },
|
||||
r = {
|
||||
function()
|
||||
require("telescope.builtin").lsp_references()
|
||||
end,
|
||||
"Find references",
|
||||
},
|
||||
},
|
||||
K = { vim.lsp.buf.hover, "Display information about symbol under cursor" },
|
||||
})
|
||||
whichkey.register({
|
||||
["<C-k>"] = { vim.lsp.buf.signature_help, "Display signature information about symbol under cursor" },
|
||||
})
|
||||
whichkey.register({
|
||||
w = {
|
||||
a = { vim.lsp.buf.add_workspace_folder, "Add a path to the workspace folders list" },
|
||||
r = { vim.lsp.buf.add_workspace_folder, "Remove a path from the workspace folders list" },
|
||||
l = {
|
||||
function()
|
||||
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
|
||||
end,
|
||||
"Show the workspace folders list",
|
||||
},
|
||||
},
|
||||
f = {
|
||||
function()
|
||||
vim.lsp.buf.format({ async = true })
|
||||
end,
|
||||
"Autoformat",
|
||||
},
|
||||
c = {
|
||||
a = { vim.lsp.buf.code_action, "Select a code action" },
|
||||
},
|
||||
r = {
|
||||
n = { vim.lsp.buf.rename, "Rename variable" },
|
||||
},
|
||||
D = { vim.lsp.buf.type_definition, "Go to type definition" },
|
||||
}, { prefix = "<space>" })
|
||||
else
|
||||
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", function()
|
||||
require("telescope.builtin").lsp_references()
|
||||
end, opts)
|
||||
vim.keymap.set("n", "<space>f", function()
|
||||
vim.lsp.buf.format({ async = true })
|
||||
end, opts)
|
||||
end
|
||||
end,
|
||||
})
|
1
home-manager/nvim/nvim-dap-python.lua
Normal file
1
home-manager/nvim/nvim-dap-python.lua
Normal file
@@ -0,0 +1 @@
|
||||
require("dap-python").setup("%PYTHONENV%/bin/python")
|
99
home-manager/nvim/nvim-dap.lua
Normal file
99
home-manager/nvim/nvim-dap.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
local dap = require("dap")
|
||||
local dap_ui = require("dap.ui.widgets")
|
||||
dap.adapters.coreclr = {
|
||||
type = "executable",
|
||||
command = "netcoredbg",
|
||||
args = { "--interpreter=vscode" },
|
||||
}
|
||||
|
||||
dap.configurations.fsharp = {
|
||||
{
|
||||
type = "coreclr",
|
||||
name = "launch - netcoredbg",
|
||||
request = "launch",
|
||||
program = function()
|
||||
return vim.fn.input("Path to dll: ", vim.fn.getcwd() .. "/bin/Debug/", "file")
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
dap.configurations.cs = {
|
||||
{
|
||||
type = "coreclr",
|
||||
name = "launch - netcoredbg",
|
||||
request = "launch",
|
||||
program = function()
|
||||
return vim.fn.input("Path to dll: ", vim.fn.getcwd() .. "/bin/Debug/", "file")
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
do
|
||||
local status, whichkey = pcall(require, "which-key")
|
||||
if status then
|
||||
whichkey.register({
|
||||
d = {
|
||||
name = "Debugger-related commands",
|
||||
o = { dap.step_over, "Step over" },
|
||||
i = { dap.step_into, "Step into" },
|
||||
c = { dap.continue, "Continue" },
|
||||
C = { dap.run_last, "Run with last debug configuration" },
|
||||
b = { dap.toggle_breakpoint, "Toggle breakpoint" },
|
||||
r = { dap.repl.open, "Open debug repl" },
|
||||
v = {
|
||||
name = "Commands to view debugger state",
|
||||
v = {
|
||||
function()
|
||||
dap_ui.hover()
|
||||
end,
|
||||
"View value of expression under cursor",
|
||||
},
|
||||
s = {
|
||||
function()
|
||||
dap_ui.sidebar(dap_ui.scopes).open()
|
||||
end,
|
||||
"View values of all variables in all scopes",
|
||||
},
|
||||
f = {
|
||||
function()
|
||||
dap_ui.sidebar(dap_ui.frames).open()
|
||||
end,
|
||||
"View stack frames",
|
||||
},
|
||||
},
|
||||
t = { dap.terminate, "Terminate/stop/end debug session" },
|
||||
},
|
||||
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
|
||||
else
|
||||
vim.api.nvim_set_keymap("n", "<localleader>do", ":lua require('dap').step_over()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>di", ":lua require('dap').step_into()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>dc", ":lua require('dap').continue()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>dC", ":lua require('dap').run_last()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap(
|
||||
"n",
|
||||
"<localleader>db",
|
||||
":lua require('dap').toggle_breakpoint()<CR>",
|
||||
{ noremap = true }
|
||||
)
|
||||
vim.api.nvim_set_keymap("n", "<localleader>dr", ":lua require('dap').repl.open()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap(
|
||||
"n",
|
||||
"<localleader>dvv",
|
||||
":lua require('dap.ui.widgets').hover()<CR>",
|
||||
{ noremap = true }
|
||||
)
|
||||
vim.api.nvim_set_keymap(
|
||||
"n",
|
||||
"<localleader>dvs",
|
||||
":lua require('dap.ui.widgets').sidebar(require('dap.ui.widgets').scopes).open()<CR>",
|
||||
{ noremap = true }
|
||||
)
|
||||
vim.api.nvim_set_keymap(
|
||||
"n",
|
||||
"<localleader>dvf",
|
||||
":lua require('dap.ui.widgets').sidebar(require('dap.ui.widgets').frames).open()<CR>",
|
||||
{ noremap = true }
|
||||
)
|
||||
vim.api.nvim_set_keymap("n", "<localleader>dt", ":lua require('dap').terminate()<CR>", { noremap = true })
|
||||
end
|
||||
end
|
4
home-manager/nvim/roslyn-nvim.lua
Normal file
4
home-manager/nvim/roslyn-nvim.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
require("roslyn").setup({
|
||||
on_attach = function(_, _) end,
|
||||
capabilities = vim.lsp.protocol.make_client_capabilities(),
|
||||
})
|
5
home-manager/nvim/tokyonight.lua
Normal file
5
home-manager/nvim/tokyonight.lua
Normal file
@@ -0,0 +1,5 @@
|
||||
require("tokyonight").setup({
|
||||
style = "night",
|
||||
})
|
||||
|
||||
vim.cmd([[colorscheme tokyonight]])
|
9
home-manager/nvim/treesitter.lua
Normal file
9
home-manager/nvim/treesitter.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
require("nvim-treesitter.configs").setup({
|
||||
-- Automatically install missing parsers when entering buffer
|
||||
-- Recommendation: set to false if you don't have `tree-sitter` CLI installed locally
|
||||
auto_install = false,
|
||||
|
||||
highlight = {
|
||||
enable = true,
|
||||
},
|
||||
})
|
199
home-manager/nvim/venv-selector.lua
Normal file
199
home-manager/nvim/venv-selector.lua
Normal file
@@ -0,0 +1,199 @@
|
||||
local venv_selector = require("venv-selector")
|
||||
|
||||
venv_selector.setup({
|
||||
changed_venv_hooks = { venv_selector.hooks.pyright },
|
||||
name = { "venv", ".venv" },
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("VimEnter", {
|
||||
desc = "Auto select virtualenv Nvim open",
|
||||
pattern = "*",
|
||||
callback = function()
|
||||
-- Mystery: this seems to be being called twice whenever we open nvim
|
||||
local venv = vim.fn.findfile("pyproject.toml", vim.fn.getcwd() .. ";")
|
||||
if venv ~= "" then
|
||||
require("venv-selector").retrieve_from_cache()
|
||||
end
|
||||
end,
|
||||
once = true,
|
||||
})
|
||||
|
||||
function SelectVenv()
|
||||
local old_path = vim.fn.getenv("PATH")
|
||||
vim.cmd("VenvSelectCached")
|
||||
local new_path = vim.fn.getenv("PATH")
|
||||
if old_path == new_path then
|
||||
-- Failed to source venv. Get the user to choose one.
|
||||
vim.cmd("VenvSelect")
|
||||
end
|
||||
end
|
||||
|
||||
local function find_requirements_txt(start_path)
|
||||
local path = vim.fn.fnamemodify(start_path, ":p")
|
||||
while path and #path > 1 do
|
||||
local req_path = path .. "requirements.txt"
|
||||
if vim.fn.filereadable(req_path) ~= 0 then
|
||||
return req_path
|
||||
end
|
||||
path = vim.fn.fnamemodify(path, ":h")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- TODO: make this one work
|
||||
local function load_venv(venv_dir)
|
||||
require("venv-selector.venv").load()
|
||||
require("venv-selector.venv").set_venv_and_system_paths(venv_dir)
|
||||
require("venv-selector.venv").cache_venv(venv_dir)
|
||||
end
|
||||
|
||||
function CreateVenv()
|
||||
local requirements_path = find_requirements_txt(vim.fn.getcwd())
|
||||
local venv_dir
|
||||
if not requirements_path then
|
||||
print("requirements.txt not found; creating fresh venv in current working directory.")
|
||||
venv_dir = vim.fn.getcwd() .. "/.venv"
|
||||
else
|
||||
venv_dir = vim.fn.fnamemodify(requirements_path, ":h") .. "/.venv"
|
||||
end
|
||||
|
||||
print("Creating virtual environment in " .. venv_dir)
|
||||
|
||||
-- Create virtual environment
|
||||
vim.fn.system("python -m venv " .. vim.fn.shellescape(venv_dir))
|
||||
|
||||
-- Install requirements
|
||||
if requirements_path then
|
||||
print("Installing requirements from " .. requirements_path)
|
||||
local handle
|
||||
local stdout = vim.loop.new_pipe(false)
|
||||
local stderr = vim.loop.new_pipe(false)
|
||||
|
||||
local function on_output(context, prefix, err, data)
|
||||
if err or data then
|
||||
vim.schedule(function()
|
||||
if err then
|
||||
-- Append the error message to the buffer
|
||||
local count = vim.api.nvim_buf_line_count(context.buf)
|
||||
vim.api.nvim_buf_set_lines(
|
||||
context.buf,
|
||||
count,
|
||||
count,
|
||||
false,
|
||||
{ "error " .. prefix .. ": " .. err }
|
||||
)
|
||||
end
|
||||
if data then
|
||||
-- Append the data to the buffer
|
||||
local count = vim.api.nvim_buf_line_count(context.buf)
|
||||
vim.api.nvim_buf_set_lines(
|
||||
context.buf,
|
||||
count,
|
||||
count,
|
||||
false,
|
||||
vim.tbl_map(function(line)
|
||||
return prefix .. ": " .. line
|
||||
end, vim.split(data, "\n"))
|
||||
)
|
||||
end
|
||||
if vim.api.nvim_win_is_valid(context.window) then
|
||||
local cur_win = vim.api.nvim_get_current_win()
|
||||
local cur_buf = vim.api.nvim_win_get_buf(cur_win)
|
||||
if cur_buf ~= context.buf then
|
||||
local new_line_count = vim.api.nvim_buf_line_count(context.buf)
|
||||
vim.api.nvim_win_set_cursor(context.window, { new_line_count, 0 })
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: commonise wth what's in ionide-vim
|
||||
|
||||
-- Create a new buffer for build output
|
||||
local buf = vim.api.nvim_create_buf(false, true) -- No listed, scratch buffer
|
||||
|
||||
-- Calculate window size and position here (example: full width, 10 lines high at the bottom)
|
||||
local width = vim.api.nvim_get_option("columns")
|
||||
local height = vim.api.nvim_get_option("lines")
|
||||
local win_height = math.min(10, math.floor(height * 0.2)) -- 20% of total height or 10 lines
|
||||
local original_win = vim.api.nvim_get_current_win()
|
||||
local win_opts = {
|
||||
relative = "editor",
|
||||
width = width,
|
||||
height = win_height,
|
||||
col = 0,
|
||||
row = height - win_height,
|
||||
style = "minimal",
|
||||
border = "single",
|
||||
}
|
||||
|
||||
local win = vim.api.nvim_open_win(buf, true, win_opts)
|
||||
-- Switch back to the original window
|
||||
vim.api.nvim_set_current_win(original_win)
|
||||
|
||||
local context = {
|
||||
window = win,
|
||||
buf = buf,
|
||||
}
|
||||
|
||||
handle, _ = vim.loop.spawn(
|
||||
-- TODO: do we need to escape this? Don't know whether spawn goes via a shell
|
||||
venv_dir .. "/bin/python",
|
||||
{
|
||||
-- TODO: and do we need to escape this?
|
||||
args = { "-m", "pip", "install", "-r", requirements_path },
|
||||
stdio = { nil, stdout, stderr },
|
||||
},
|
||||
vim.schedule_wrap(function(code, signal)
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
stdout:close()
|
||||
stderr:close()
|
||||
handle:close()
|
||||
print("Venv creation completed, exit code " .. code .. " and signal " .. signal)
|
||||
load_venv(venv_dir)
|
||||
end)
|
||||
)
|
||||
|
||||
if not handle then
|
||||
print("Failed to start venv install process.")
|
||||
return
|
||||
end
|
||||
|
||||
vim.loop.read_start(stdout, function(err, data)
|
||||
on_output(context, "OUT", err, data)
|
||||
end)
|
||||
vim.loop.read_start(stderr, function(err, data)
|
||||
on_output(context, "ERR", err, data)
|
||||
end)
|
||||
else
|
||||
load_venv(venv_dir)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local status, whichkey = pcall(require, "which-key")
|
||||
if status then
|
||||
whichkey.register({
|
||||
p = {
|
||||
name = "Python-related commands",
|
||||
v = {
|
||||
name = "Virtual environment-related commands",
|
||||
c = { CreateVenv, "Create virtual environment" },
|
||||
l = { SelectVenv, "Load virtual environment" },
|
||||
o = {
|
||||
function()
|
||||
vim.cmd("VenvSelect")
|
||||
end,
|
||||
"Choose (override) new virtual environment",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, { prefix = vim.api.nvim_get_var("maplocalleader"), buffer = vim.api.nvim_get_current_buf() })
|
||||
else
|
||||
vim.api.nvim_set_keymap("n", "<localleader>pvc", ":lua CreateVenv()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>pvl", ":lua SelectVenv()<CR>", { noremap = true })
|
||||
vim.api.nvim_set_keymap("n", "<localleader>pvo", ":VenvSelect<CR>", { noremap = true })
|
||||
end
|
||||
end
|
88
home-manager/nvim/which-key.lua
Normal file
88
home-manager/nvim/which-key.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
require("which-key").setup({
|
||||
plugins = {
|
||||
marks = true, -- shows a list of your marks on ' and `
|
||||
registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
|
||||
-- the presets plugin, adds help for a bunch of default keybindings in Neovim
|
||||
-- No actual key bindings are created
|
||||
spelling = {
|
||||
enabled = true, -- enabling this will show WhichKey when pressing z= to select spelling suggestions
|
||||
suggestions = 20, -- how many suggestions should be shown in the list?
|
||||
},
|
||||
presets = {
|
||||
operators = true, -- adds help for operators like d, y, ...
|
||||
motions = true, -- adds help for motions
|
||||
text_objects = true, -- help for text objects triggered after entering an operator
|
||||
windows = true, -- default bindings on <c-w>
|
||||
nav = true, -- misc bindings to work with windows
|
||||
z = true, -- bindings for folds, spelling and others prefixed with z
|
||||
g = true, -- bindings for prefixed with g
|
||||
},
|
||||
},
|
||||
-- add operators that will trigger motion and text object completion
|
||||
-- to enable all native operators, set the preset / operators plugin above
|
||||
operators = { gc = "Comments" },
|
||||
key_labels = {
|
||||
-- override the label used to display some keys. It doesn't effect WK in any other way.
|
||||
-- For example:
|
||||
-- ["<space>"] = "SPC",
|
||||
-- ["<cr>"] = "RET",
|
||||
-- ["<tab>"] = "TAB",
|
||||
},
|
||||
motions = {
|
||||
count = true,
|
||||
},
|
||||
icons = {
|
||||
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
|
||||
separator = "➜", -- symbol used between a key and it's label
|
||||
group = "+", -- symbol prepended to a group
|
||||
},
|
||||
popup_mappings = {
|
||||
scroll_down = "<c-d>", -- binding to scroll down inside the popup
|
||||
scroll_up = "<c-u>", -- binding to scroll up inside the popup
|
||||
},
|
||||
window = {
|
||||
border = "none", -- none, single, double, shadow
|
||||
position = "bottom", -- bottom, top
|
||||
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
|
||||
padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
|
||||
winblend = 0, -- value between 0-100 0 for fully opaque and 100 for fully transparent
|
||||
zindex = 1000, -- positive value to position WhichKey above other floating windows.
|
||||
},
|
||||
layout = {
|
||||
height = { min = 4, max = 25 }, -- min and max height of the columns
|
||||
width = { min = 20, max = 50 }, -- min and max width of the columns
|
||||
spacing = 3, -- spacing between columns
|
||||
align = "left", -- align columns left, center or right
|
||||
},
|
||||
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
|
||||
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
|
||||
show_help = true, -- show a help message in the command line for using WhichKey
|
||||
show_keys = true, -- show the currently pressed key and its label as a message in the command line
|
||||
triggers = "auto", -- automatically setup triggers
|
||||
-- triggers = {"<leader>"} -- or specifiy a list manually
|
||||
-- list of triggers, where WhichKey should not wait for timeoutlen and show immediately
|
||||
triggers_nowait = {
|
||||
-- marks
|
||||
"`",
|
||||
"'",
|
||||
"g`",
|
||||
"g'",
|
||||
-- registers
|
||||
'"',
|
||||
"<c-r>",
|
||||
-- spelling
|
||||
"z=",
|
||||
},
|
||||
triggers_blacklist = {
|
||||
-- list of mode / prefixes that should never be hooked by WhichKey
|
||||
-- this is mostly relevant for keymaps that start with a native binding
|
||||
i = { "j", "k" },
|
||||
v = { "j", "k" },
|
||||
},
|
||||
-- disable the WhichKey popup for certain buf types and file types.
|
||||
-- Disabled by default for Telescope
|
||||
disable = {
|
||||
buftypes = {},
|
||||
filetypes = {},
|
||||
},
|
||||
})
|
Reference in New Issue
Block a user