neovim.nix 3.9 KB

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