stockholm/tv/2configs/vim.nix
2019-02-02 21:21:48 +01:00

509 lines
14 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ config, lib, pkgs, ... }:
with import <stockholm/lib>;
let {
body = {
environment.systemPackages = [
vim-wrapper
];
environment.etc.vimrc.source = vimrc;
environment.variables.EDITOR = mkForce "vim";
environment.variables.VIMINIT = ":so /etc/vimrc";
};
extra-runtimepath = concatMapStringsSep "," (pkg: "${pkg.rtp}") [
# cannot use pkgs.vimPlugins.fzf-vim as it's missing :Rg
(pkgs.vimUtils.buildVimPlugin {
name = "fzf-2018-11-14";
src = pkgs.fetchgit {
url = https://github.com/junegunn/fzf.vim;
rev = "ad1833ecbc9153b6e34a4292dc089a58c4bcb8dc";
sha256 = "1z2q71q6l9hq9fqfqpj1svhyk4yk1bzw1ljhksx4bnpz8gkfbx2m";
};
})
pkgs.vimPlugins.fzfWrapper
pkgs.vimPlugins.undotree
(pkgs.vimUtils.buildVimPlugin {
name = "vim-elixir-2018-08-17";
src = pkgs.fetchgit {
url = https://github.com/elixir-editors/vim-elixir;
rev = "0a847f0faed5ba2d94bb3d51f355c50f37ba025b";
sha256 = "1jl85wpgywhcvhgw02y8zpvqf0glr4i8522kxpvhsiacb1v1xh04";
};
})
(pkgs.vimUtils.buildVimPlugin {
name = "vim-syntax-jq";
src = pkgs.fetchgit {
url = https://github.com/vito-c/jq.vim;
rev = "99d55a300047946a82ecdd7617323a751199ad2d";
sha256 = "09c94nah47wx0cr556w61h6pfznxld18pfblc3nv51ivbw7cjqyx";
};
})
(pkgs.vimUtils.buildVimPlugin {
name = "file-line-1.0";
src = pkgs.fetchgit {
url = git://github.com/bogado/file-line;
rev = "refs/tags/1.0";
sha256 = "0z47zq9rqh06ny0q8lpcdsraf3lyzn9xvb59nywnarf3nxrk6hx0";
};
})
((rtp: rtp // { inherit rtp; }) (pkgs.writeTextFile (let
name = "hack";
in {
name = "vim-color-${name}-1.0.2";
destination = "/colors/${name}.vim";
text = /* vim */ ''
set background=dark
hi clear
if exists("syntax_on")
syntax clear
endif
let colors_name = ${toJSON name}
hi Normal ctermbg=235
hi Comment ctermfg=242
hi Constant ctermfg=255
hi Identifier ctermfg=253
hi Function ctermfg=253
hi Statement ctermfg=253
hi PreProc ctermfg=251
hi Type ctermfg=251
hi Delimiter ctermfg=251
hi Special ctermfg=255
hi Garbage ctermbg=088
hi TabStop ctermbg=016
hi Todo ctermfg=174 ctermbg=NONE
hi NixCode ctermfg=040
hi NixData ctermfg=046
hi NixQuote ctermfg=071
hi diffNewFile ctermfg=207
hi diffFile ctermfg=207
hi diffLine ctermfg=207
hi diffSubname ctermfg=207
hi diffAdded ctermfg=010
hi diffRemoved ctermfg=009
hi Search cterm=NONE ctermbg=216
'';
})))
((rtp: rtp // { inherit rtp; }) (pkgs.writeTextFile (let
name = "vim";
in {
name = "vim-syntax-${name}-1.0.0";
destination = "/syntax/${name}.vim";
text = /* vim */ ''
${concatMapStringsSep "\n" (s: /* vim */ ''
syn keyword vimColor${s} ${s}
\ containedin=ALLBUT,vimComment,vimLineComment
hi vimColor${s} ctermfg=${s}
'') (map (i: lpad 3 "0" (toString i)) (range 0 255))}
'';
})))
((rtp: rtp // { inherit rtp; }) (pkgs.writeTextFile (let
name = "showsyntax";
in {
name = "vim-plugin-${name}-1.0.0";
destination = "/plugin/${name}.vim";
text = /* vim */ ''
if exists('g:loaded_showsyntax')
finish
endif
let g:loaded_showsyntax = 0
fu! ShowSyntax()
let id = synID(line("."), col("."), 1)
let name = synIDattr(id, "name")
let transName = synIDattr(synIDtrans(id),"name")
if name != transName
let name .= " (" . transName . ")"
endif
echo "Syntax: " . name
endfu
command! -n=0 -bar ShowSyntax :call ShowSyntax()
'';
})))
((rtp: rtp // { inherit rtp; }) (pkgs.write "vim-tv" {
#
# Haskell
#
"/ftplugin/haskell.vim".text = ''
if exists("g:vim_tv_ftplugin_haskell_loaded")
finish
endif
let g:vim_tv_ftplugin_haskell_loaded = 1
setlocal iskeyword+='
'';
#
# TODO
#
"/ftdetect/todo.vim".text = ''
au BufRead,BufNewFile TODO set ft=todo
'';
"/ftplugin/todo.vim".text = ''
setlocal foldmethod=syntax
'';
"/syntax/todo.vim".text = ''
syn match Comment /#.*/
syn match todoDate /^[1-9]\S*/
\ nextgroup=todoSummary
syn region todoSummary
\ contained
\ contains=todoTag
\ start="." end="$\n"
\ nextgroup=todoBlock
syn match todoTag /\[[a-z]\+\]/hs=s+1,he=e-1
\ contained
syn region todoBlock
\ contained
\ contains=Comment
\ fold
\ start="^[^1-9]" end="^[1-9]"re=s-1,he=s-1,me=s-1
syn sync minlines=1000
hi todoDate ctermfg=255
hi todoSummary ctermfg=229
hi todoBlock ctermfg=248
hi todoTag ctermfg=217
'';
}))
((rtp: rtp // { inherit rtp; }) (pkgs.write "vim-syntax-nix-nested" {
"/syntax/haskell.vim".text = ''
syn region String start=+\[[[:alnum:]]*|+ end=+|]+
hi link ConId Identifier
hi link VarId Identifier
hi link hsDelimiter Delimiter
'';
"/syntax/nix.vim".text = ''
"" Quit when a (custom) syntax file was already loaded
"if exists("b:current_syntax")
" finish
"endif
"setf nix
" Ref <nix/src/libexpr/lexer.l>
syn match NixID /[a-zA-Z\_][a-zA-Z0-9\_\'\-]*/
syn match NixINT /\<[0-9]\+\>/
syn match NixPATH /[a-zA-Z0-9\.\_\-\+]*\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match NixHPATH /\~\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match NixSPATH /<[a-zA-Z0-9\.\_\-\+]\+\(\/[a-zA-Z0-9\.\_\-\+]\+\)*>/
syn match NixURI /[a-zA-Z][a-zA-Z0-9\+\-\.]*:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']\+/
syn region NixSTRING
\ matchgroup=NixSTRING
\ start='"'
\ skip='\\"'
\ end='"'
syn region NixIND_STRING
\ matchgroup=NixIND_STRING
\ start="'''"
\ skip="'''\('\|[$]\|\\[nrt]\)"
\ end="'''"
syn match NixOther /[-!+&<>|():/;=.,?\[\]*@]/
syn match NixCommentMatch /\(^\|\s\)#.*/
syn region NixCommentRegion start="/\*" end="\*/"
hi link NixCode Statement
hi link NixData Constant
hi link NixComment Comment
hi link NixCommentMatch NixComment
hi link NixCommentRegion NixComment
hi link NixID NixCode
hi link NixINT NixData
hi link NixPATH NixData
hi link NixHPATH NixData
hi link NixSPATH NixData
hi link NixURI NixData
hi link NixSTRING NixData
hi link NixIND_STRING NixData
hi link NixEnter NixCode
hi link NixOther NixCode
hi link NixQuote NixData
syn cluster nix_has_dollar_curly contains=@nix_ind_strings,@nix_strings
syn cluster nix_ind_strings contains=NixIND_STRING
syn cluster nix_strings contains=NixSTRING
${concatStringsSep "\n" (mapAttrsToList (name: {
extraStart ? null,
lang ? name
}:
let
startAlts = filter isString [
''/\* ${name} \*/''
extraStart
];
sigil = ''\(${concatStringsSep ''\|'' startAlts}\)[ \t\r\n]*'';
in /* vim */ ''
syn include @nix_${lang}_syntax syntax/${lang}.vim
if exists("b:current_syntax")
unlet b:current_syntax
endif
syn match nix_${lang}_sigil
\ X${replaceStrings ["X"] ["\\X"] sigil}\ze\('''\|"\)X
\ nextgroup=nix_${lang}_region_IND_STRING,nix_${lang}_region_STRING
\ transparent
syn region nix_${lang}_region_STRING
\ matchgroup=NixSTRING
\ start='"'
\ skip='\\"'
\ end='"'
\ contained
\ contains=@nix_${lang}_syntax
\ transparent
syn region nix_${lang}_region_IND_STRING
\ matchgroup=NixIND_STRING
\ start="'''"
\ skip="'''\('\|[$]\|\\[nrt]\)"
\ end="'''"
\ contained
\ contains=@nix_${lang}_syntax
\ transparent
syn cluster nix_ind_strings
\ add=nix_${lang}_region_IND_STRING
syn cluster nix_strings
\ add=nix_${lang}_region_STRING
" This is required because containedin isn't transitive.
syn cluster nix_has_dollar_curly
\ add=@nix_${lang}_syntax
'') (let
capitalize = s: let
xs = stringToCharacters s;
in
toUpper (head xs) + concatStrings (tail xs);
alts = xs: ''\(${concatStringsSep ''\|'' xs}\)'';
def = k: ''${k}[ \t\r\n]*='';
writer = k: ''write${k}[^ \t\r\n]*[ \t\r\n]*\("[^"]*"\|[a-z]\+\)'';
writerExt = k: writerName ''[^"]*\.${k}'';
writerName = k: ''write[^ \t\r\n]*[ \t\r\n]*"${k}"'';
in {
c = {};
cabal = {};
diff = {};
haskell = {};
jq.extraStart = alts [
(writer "Jq")
(writerExt "jq")
];
javascript.extraStart = ''/\* js \*/'';
lua = {};
python.extraStart = ''/\* py \*/'';
sed.extraStart = writer "Sed";
sh.extraStart = let
phases = [
"unpack"
"patch"
"configure"
"build"
"check"
"install"
"fixup"
"installCheck"
"dist"
];
shells = [
"ash"
"bash"
"dash"
];
in alts [
(def "shellHook")
(def "${alts phases}Phase")
(def "${alts ["pre" "post"]}${alts (map capitalize phases)}")
(writer (alts (map capitalize shells)))
];
yaml = {};
vim.extraStart = alts [
(def ''"[^"]*\.vim"\.text'')
(writerExt "vim")
(writerName ''\([^"]*\.\)\?vimrc'')
];
xdefaults = {};
}))}
" Clear syntax that interferes with nixINSIDE_DOLLAR_CURLY.
syn clear shVarAssign
syn region nixINSIDE_DOLLAR_CURLY
\ matchgroup=NixEnter
\ start="[$]{"
\ end="}"
\ contains=TOP
\ containedin=@nix_has_dollar_curly
\ transparent
syn region nix_inside_curly
\ matchgroup=NixEnter
\ start="{"
\ end="}"
\ contains=TOP
\ containedin=nixINSIDE_DOLLAR_CURLY,nix_inside_curly
\ transparent
syn match NixQuote /'''\(''$\|\\.\)/he=s+2
\ containedin=@nix_ind_strings
\ contained
syn match NixQuote /'''\('\|\\.\)/he=s+1
\ containedin=@nix_ind_strings
\ contained
syn match NixQuote /\\./he=s+1
\ containedin=@nix_strings
\ contained
syn sync fromstart
let b:current_syntax = "nix"
set isk=@,48-57,_,192-255,-,'
'';
"/syntax/sed.vim".text = ''
syn region sedBranch
\ matchgroup=sedFunction start="T"
\ matchgroup=sedSemicolon end=";\|$"
\ contains=sedWhitespace
'';
}))
];
dirs = {
backupdir = "$HOME/.cache/vim/backup";
swapdir = "$HOME/.cache/vim/swap";
undodir = "$HOME/.cache/vim/undo";
};
files = {
viminfo = "$HOME/.cache/vim/info";
};
need-dirs = let
dirOf = s: let out = concatStringsSep "/" (init (splitString "/" s));
in assert out != ""; out;
alldirs = attrValues dirs ++ map dirOf (attrValues files);
in unique (sort lessThan alldirs);
vim-wrapper = pkgs.symlinkJoin {
name = "vim";
paths = [
(pkgs.writeDashBin "vim" ''
set -efu
export FZF_DEFAULT_COMMAND='${pkgs.ripgrep}/bin/rg --files'
export PATH=$PATH:${makeBinPath [
pkgs.fzf
pkgs.ripgrep
]}
(umask 0077; exec ${pkgs.coreutils}/bin/mkdir -p ${toString need-dirs})
exec ${pkgs.vim}/bin/vim "$@"
'')
pkgs.vim
];
};
vimrc = pkgs.writeText "vimrc" ''
set nocompatible
set autoindent
set backspace=indent,eol,start
set backup
set backupdir=${dirs.backupdir}/
set directory=${dirs.swapdir}//
set hlsearch
set incsearch
set mouse=a
set noruler
set pastetoggle=<INS>
set runtimepath=$VIMRUNTIME,${extra-runtimepath}
set shortmess+=I
set showcmd
set showmatch
set timeoutlen=0
set ttimeoutlen=0
set undodir=${dirs.undodir}
set undofile
set undolevels=1000000
set undoreload=1000000
set viminfo='20,<1000,s100,h,n${files.viminfo}
set visualbell
set wildignore+=*.o,*.class,*.hi,*.dyn_hi,*.dyn_o
set wildmenu
set wildmode=longest,full
set et ts=2 sts=2 sw=2
filetype plugin indent on
set t_Co=256
colorscheme hack
syntax on
au Syntax * syn match Garbage containedin=ALL /\s\+$/
\ | syn match TabStop containedin=ALL /\t\+/
\ | syn keyword Todo containedin=ALL TODO
au BufRead,BufNewFile *.nix set ft=nix
au BufRead,BufNewFile /dev/shm/* set nobackup nowritebackup noswapfile
cnoremap <C-A> <Home>
noremap <C-c> :q<cr>
nnoremap <esc>[5^ :tabp<cr>
nnoremap <esc>[6^ :tabn<cr>
nnoremap <esc>[5@ :tabm -1<cr>
nnoremap <esc>[6@ :tabm +1<cr>
nnoremap <f1> :tabp<cr>
nnoremap <f2> :tabn<cr>
inoremap <f1> <esc>:tabp<cr>
inoremap <f2> <esc>:tabn<cr>
" <C-{Up,Down,Right,Left>
noremap <esc>Oa <nop> | noremap! <esc>Oa <nop>
noremap <esc>Ob <nop> | noremap! <esc>Ob <nop>
noremap <esc>Oc <nop> | noremap! <esc>Oc <nop>
noremap <esc>Od <nop> | noremap! <esc>Od <nop>
" <[C]S-{Up,Down,Right,Left>
noremap <esc>[a <nop> | noremap! <esc>[a <nop>
noremap <esc>[b <nop> | noremap! <esc>[b <nop>
noremap <esc>[c <nop> | noremap! <esc>[c <nop>
noremap <esc>[d <nop> | noremap! <esc>[d <nop>
vnoremap u <nop>
" fzf
nnoremap <esc>q :Files<cr>
nnoremap <esc>w :Rg<cr>
" edit alternate buffer
" For some reason neither putting <ctrl>6 nor <ctrl>^ works here...
nnoremap <esc>a 
'';
}