neovim.nix 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. { lib
  2. , stdenv
  3. , writeShellScriptBin
  4. , writeTextFile
  5. , neovim-unwrapped
  6. , makeWrapper
  7. , fd
  8. , ripgrep
  9. , node-lsp
  10. , vimPlugins
  11. , fetchFromGitHub
  12. , withPlayground ? false
  13. , withLuadev ? false
  14. }:
  15. let
  16. buildNeovimPlugin = attrs: stdenv.mkDerivation ({
  17. forceShare= [ "man" "info" ];
  18. installPhase = ''
  19. cp -r . $out
  20. if [ -d "$out/doc" ]; then
  21. ${neovim-unwrapped}/bin/nvim -N -u NONE -i NONE -n -E -s -V1 -c "helptags $out/doc" +quit!
  22. fi
  23. '';
  24. } // attrs);
  25. extra-treesitter-textobjects = writeTextFile {
  26. name = "extra-treesitter-textobjects";
  27. destination = "/queries/ecma/textobjects.scm";
  28. text = ''
  29. ;; extends
  30. ; consider array elements as @parameter text objects too
  31. (array
  32. "," @_start .
  33. (_) @parameter.inner
  34. (#make-range! "parameter.outer" @_start @parameter.inner))
  35. (array
  36. . (_) @parameter.inner
  37. . ","? @_end
  38. (#make-range! "parameter.outer" @parameter.inner @_end))
  39. '';
  40. };
  41. tsc = writeShellScriptBin "tsc" ''
  42. if [ -x "./node_modules/.bin/tsc" ]; then
  43. exec ./node_modules/.bin/tsc "$@"
  44. else
  45. exec ${node-lsp}/lib/node_modules/node-lsp/node_modules/.bin/tsc "$@"
  46. fi
  47. '';
  48. extraPath = [
  49. fd
  50. ripgrep
  51. node-lsp
  52. tsc
  53. ];
  54. nixpkgsPlugins =
  55. let
  56. # we take nvim-treesitter from nixpkgs as the plugin and grammar versions
  57. # must match exactly
  58. nvim-treesitter = (vimPlugins.nvim-treesitter.withPlugins (p: with p; [
  59. tree-sitter-bash
  60. tree-sitter-css
  61. tree-sitter-elvish
  62. tree-sitter-go
  63. tree-sitter-javascript
  64. tree-sitter-json
  65. tree-sitter-lua
  66. tree-sitter-markdown
  67. tree-sitter-nix
  68. tree-sitter-ruby
  69. tree-sitter-tsx
  70. tree-sitter-typescript
  71. ] ++ lib.optionals withPlayground [
  72. tree-sitter-query
  73. ]));
  74. in
  75. [ nvim-treesitter ] ++ nvim-treesitter.dependencies
  76. ++ (lib.optionals withPlayground [
  77. vimPlugins.playground
  78. ])
  79. ++ (lib.optionals withLuadev [
  80. vimPlugins.nvim-luadev
  81. ]);
  82. pinnedPlugins = import ./plugins {
  83. inherit buildNeovimPlugin fetchFromGitHub;
  84. };
  85. plugins = (lib.attrValues pinnedPlugins)
  86. ++ nixpkgsPlugins
  87. ++ [
  88. extra-treesitter-textobjects
  89. ];
  90. generic = { initText ? "", enabledPlugins ? [], passthru ? {} }: stdenv.mkDerivation {
  91. pname = "nvim";
  92. version = neovim-unwrapped.version;
  93. initVim = ''
  94. let g:loaded_python3_provider = 0
  95. let g:loaded_ruby_provider = 0
  96. let g:loaded_node_provider = 0
  97. let g:loaded_perl_provider = 0
  98. set runtimepath^=${placeholder "out"}/lib
  99. set packpath^=${placeholder "out"}/lib
  100. ${initText}
  101. '';
  102. passAsFile = [ "initVim" ];
  103. nativeBuildInputs = [ makeWrapper ];
  104. unpackPhase = ":";
  105. buildPhase = ''
  106. # build pack / runtime dir
  107. mkdir -p lib/pack/nixpkgs/start
  108. ${lib.concatMapStringsSep "\n" (p: ''
  109. ln -s "${p}" "lib/pack/nixpkgs/start/${lib.getName p}"
  110. '') enabledPlugins}
  111. # create config file
  112. mkdir etc
  113. cp "$initVimPath" etc/init.vim
  114. # symlink in man pages
  115. mkdir -p share
  116. ln -s ${neovim-unwrapped}/share/man share/man
  117. # make bin
  118. mkdir bin
  119. makeWrapper ${neovim-unwrapped}/bin/nvim bin/nvim \
  120. --prefix PATH : ${lib.makeBinPath extraPath} \
  121. --add-flags -u \
  122. --add-flags $out/etc/init.vim
  123. '';
  124. inherit passthru;
  125. installPhase = ''
  126. mkdir $out
  127. cp -r * $out
  128. '';
  129. };
  130. in
  131. generic {
  132. initText = ''
  133. source ${./settings.lua}
  134. source ${./plugins.lua}
  135. source ${./mappings.lua}
  136. source ${./autocmd.lua}
  137. source ${./lsp.lua}
  138. source ${./make.lua}
  139. source ${./theme.lua}
  140. '' + lib.optionalString withPlayground ''
  141. source ${./playground.lua}
  142. '' + lib.optionalString withLuadev ''
  143. source ${./luadev.lua}
  144. '';
  145. enabledPlugins = plugins;
  146. passthru = {
  147. minimal = generic {};
  148. };
  149. }