build-system: Add vim-build-system.

* guix/build-system/vim.scm,
* guix/build/vim-build-system.scm: New modules.
* Makefile.am (MODULES): Register new files.
* doc/guix.texi: Document it.

Co-authored-by: Efraim Flashner <efraim@flashner.co.il>
Signed-off-by: Efraim Flashner <efraim@flashner.co.il>
This commit is contained in:
Jonathan Scoresby 2023-10-16 12:15:12 +03:00 committed by Efraim Flashner
parent b17567d45c
commit 8882ec71dd
No known key found for this signature in database
GPG key ID: 41AAE7DCCA3D8351
4 changed files with 314 additions and 1 deletions

View file

@ -13,7 +13,7 @@
# Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
# Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
# Copyright © 2018 Alex Vong <alexvong1995@gmail.com>
# Copyright © 2019 Efraim Flashner <efraim@flashner.co.il>
# Copyright © 2019, 2023 Efraim Flashner <efraim@flashner.co.il>
# Copyright © 2020, 2021, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
# Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
# Copyright © 2021 Andrew Tropin <andrew@trop.in>
@ -185,6 +185,7 @@ MODULES = \
guix/build-system/texlive.scm \
guix/build-system/tree-sitter.scm \
guix/build-system/trivial.scm \
guix/build-system/vim.scm \
guix/build-system/zig.scm \
guix/ftp-client.scm \
guix/http-client.scm \
@ -243,6 +244,7 @@ MODULES = \
guix/build/scons-build-system.scm \
guix/build/texlive-build-system.scm \
guix/build/tree-sitter-build-system.scm \
guix/build/vim-build-system.scm \
guix/build/waf-build-system.scm \
guix/build/haskell-build-system.scm \
guix/build/julia-build-system.scm \

View file

@ -9448,6 +9448,41 @@ e.g., install @file{foo/sub/file} to @file{share/my-app/sub/file}.
@end itemize
@end defvar
@defvar vim-build-system
This variable is exported by @code{(guix build-system vim)}. It is an
extension of the @code{copy-build-system}, installing Vim and Neovim plugins
into locations where these two text editors know to find their plugins, using
their packpaths.
Packages which are prefixed with @code{vim-} will be installed in Vim's
packpath, while those prefixed with @code{neovim-} will be installed in
Neovim's packpath. If there is a @code{doc} directory with the plugin then
helptags will be generated automatically.
There are a couple of keywords added with the @code{vim-build-system}:
@itemize
@item With @code{plugin-name} it is possible to set the name of the plugin.
While by default this is set to the name and version of the package, it is
often more helpful to set this to name which the upstream author calls their
plugin. This is the name used for @command{:packadd} from inside Vim.
@item With @code{install-plan} it is possible to augment the built-in
install-plan of the @code{vim-build-system}. This is particularly helpful if
you have files which should be installed in other locations. For more
information about using the @code{install-plan}, see the
@code{copy-build-system} (@pxref{Build Systems, @code{copy-build-system}}).
@item With @code{#:vim} it is possible to add this package to Vim's packpath,
in addition to if it is added automatically because of the @code{vim-} prefix
in the package's name.
@item With @code{#:neovim} it is possible to add this package to Neovim's
packpath, in addition to if it is added automatically because of the
@code{neovim-} prefix in the package's name.
@item With @code{#:mode} it is possible to adjust the path which the plugin is
installed into. By default the plugin is installed into @code{start} and other
options are available, including @code{opt}. Adding a plugin into @code{opt}
will mean you will need to run, for example, @command{:packadd foo} to load the
@code{foo} plugin from inside of Vim.
@end itemize
@end defvar
@cindex Clojure (programming language)
@cindex simple Clojure build system

157
guix/build-system/vim.scm Normal file
View file

@ -0,0 +1,157 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2022 Jonathan Scoresby <me@jonscoresby.com>
;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix build-system vim)
#:use-module (guix store)
#:use-module (guix utils)
#:use-module (guix gexp)
#:use-module (guix monads)
#:use-module (guix packages)
#:use-module (guix search-paths)
#:use-module (guix build-system)
#:use-module (guix build-system copy)
#:use-module (guix build-system gnu)
#:export (%vim-build-system-modules vim-build vim-build-system))
;; Commentary:
;;
;; Standard package installer for vim and neovim plugins.
;; This is implemented as an extension of the `copy-build-system'
;; and takes advantage of vim and neovim's built-in package manager.
;; It extends the installation procedure from the copy-build-system
;; to put files in the correct place and then generates help tags.
;;
;; Code:
(define %vim-build-system-modules
;; Build-side modules imported by default.
`((guix build vim-build-system)
,@%copy-build-system-modules))
(define (default-vim)
"Return the default Vim package."
;; Lazily resolve the binding to avoid a circular dependency.
(let ((vim (resolve-interface '(gnu packages vim))))
(module-ref vim 'vim)))
(define (default-neovim)
"Return the default Neovim package."
(let ((vim (resolve-interface '(gnu packages vim))))
(module-ref vim 'neovim)))
(define* (lower name
#:key source
inputs
native-inputs
outputs
system
target
(vim? #f)
(neovim? #f)
(plugin-name name)
(vim (default-vim))
(neovim (default-neovim))
#:allow-other-keys #:rest arguments)
"Return a bag for NAME."
(let* ((private-keywords '(#:target #:vim #:neovim #:inputs #:native-inputs))
(vim? (or (string-prefix? "vim-" name)
vim?))
(neovim? (or (string-prefix? "neovim-" name)
neovim?))
(vim-inputs (append (if vim?
`(("vim" ,vim))
'())
(if neovim?
`(("neovim" ,neovim))
'())))
(vim-arguments (append arguments
`(#:vim? ,vim?
#:neovim? ,neovim?))))
(bag (name name)
(system system)
(host-inputs `(,@(if source
`(("source" ,source))
'()) ,@inputs
;; Keep the standard inputs of 'gnu-build-system'.
,@(standard-packages)))
(build-inputs `(,@vim-inputs ,@native-inputs))
(outputs outputs)
(build vim-build)
(arguments (strip-keyword-arguments private-keywords vim-arguments)))))
(define* (vim-build name inputs
#:key guile
source
(vim? #f)
(neovim? #f)
(mode "start")
(plugin-name name)
(install-plan ''())
(phases '(@ (guix build vim-build-system) %standard-phases))
(outputs '("out"))
(search-paths '())
(system (%current-system))
(substitutable? #t)
(imported-modules %vim-build-system-modules)
(modules '((guix build vim-build-system)
(guix build utils))))
(define build
(with-imported-modules imported-modules
#~(begin
(use-modules #$@modules)
#$(with-build-variables inputs outputs
#~(vim-build #:name #$name
#:vim? #$vim?
#:neovim? #$neovim?
#:mode #$mode
#:plugin-name #$plugin-name
#:install-plan #$(if (pair? install-plan)
(sexp->gexp install-plan)
install-plan)
#:source #+source
#:system #$system
#:phases #$(if (pair? phases)
(sexp->gexp phases)
phases)
#:outputs %outputs
#:search-paths '#$(sexp->gexp
(map search-path-specification->sexp
search-paths))
#:inputs
%build-inputs)))))
(mlet %store-monad
((guile (package->derivation (or guile (default-guile))
system #:graft? #f)))
(gexp->derivation name
build
#:system system
#:target #f
#:graft? #f
#:substitutable? substitutable?
#:guile-for-build guile)))
(define vim-build-system
(build-system (name 'vim)
(description "The standard Vim build system")
(lower lower)))
;;; vim.scm ends here

View file

@ -0,0 +1,119 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2022 Jonathan Scoresby <me@jonscoresby.com>
;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix build vim-build-system)
#:use-module ((guix build copy-build-system)
#:prefix copy:)
#:use-module (guix build utils)
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (%standard-phases vim-build))
;; Commentary:
;;
;; System for installing vim and neovim plugins. It downloads
;; the source and copies the appropriate files to vim and nvim
;; packpaths. It then generates helptags.
;;
;; Code:
(define copy:install
(assoc-ref copy:%standard-phases 'install))
(define vim-path
"/share/vim/vimfiles/pack/guix/")
(define nvim-path
"/share/nvim/site/pack/guix/")
(define* (install #:key plugin-name
install-plan
neovim?
vim?
mode
outputs
#:allow-other-keys)
(let* ((include-regexp '(".*\\/.*\\/.*"))
(exclude-regexp '("^scripts/.*"
"tests?/.*" "^t/.*"
"assets/.*"
".*\\/\\..*"))
(vim-install
(if vim?
`(("." ,(string-append vim-path mode "/" plugin-name "/")
#:include-regexp ,include-regexp
#:exclude-regexp ,exclude-regexp))
'()))
(neovim-install
(if neovim?
`(("." ,(string-append nvim-path mode "/" plugin-name "/")
#:include-regexp ,include-regexp
#:exclude-regexp ,exclude-regexp))
'())))
(copy:install #:outputs outputs
#:install-plan (append vim-install
neovim-install
install-plan))))
(define* (generate-helptags #:key plugin-name
neovim?
vim?
mode
outputs
#:allow-other-keys)
(define (vim-generate-helptags output)
(invoke "vim" "--clean" "-en" "--cmd"
(string-append "helptags "
output vim-path mode "/" plugin-name "/doc")
"--cmd" "q"))
(define (neovim-generate-helptags output)
(invoke "nvim" "--clean" "--headless" "-en" "--cmd"
(string-append "helptags "
output nvim-path mode "/" plugin-name "/doc")
"--cmd" "q"))
(when (scandir "./doc")
(let ((out (assoc-ref outputs "out")))
(when vim?
(vim-generate-helptags out))
(when neovim?
(neovim-generate-helptags out)))))
(define %standard-phases
;; Everything is as with the Copy Build System except for
;; the addition of the generate-helptags phase and a few
;; custom actions are added to the install phase
(modify-phases copy:%standard-phases
(replace 'install install)
(add-after 'install 'generate-helptags generate-helptags)))
(define* (vim-build #:key inputs
(phases %standard-phases)
#:allow-other-keys #:rest args)
"Build the given package, applying all of PHASES in order."
(apply copy:copy-build
#:inputs inputs
#:phases phases
args))
;;; vim-build-system.scm ends here