;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013 Cyril Roelandt ;;; Copyright © 2016, 2017, 2018 Efraim Flashner ;;; Copyright © 2016, 2017 Nils Gillmann ;;; Copyright © 2017 Ricardo Wurmus ;;; Copyright © 2017 Marius Bakke ;;; Copyright © 2018 Tobias Geerinckx-Rice ;;; ;;; 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 t
aboutsummaryrefslogtreecommitdiff
# GNU Guix --- Functional package management for GNU
# Copyright © 2014-2022, 2024 Ludovic Courtès <ludo@gnu.org>
# Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
# Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
#
# 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/>.

#
# Test 'guix system', mostly error reporting.
#

set -e

guix system --version

tmpfile="t-guix-system-$$"
errorfile="t-guix-system-error-$$"

# Note: This directory is chosen outside $builddir so that relative file name
# canonicalization doesn't mess up with 'current-source-directory', used by
# 'local-file' ('load' forces 'relative' for
# %FILE-PORT-NAME-CANONICALIZATION.)
tmpdir="${TMPDIR:-/tmp}/t-guix-system-$$"
mkdir "$tmpdir"

trap 'rm -f "$tmpfile" "$errorfile" "$tmpdir"/*; rmdir "$tmpdir"' EXIT

# Reporting of syntax errors.

cat > "$tmpfile"<<EOF
;; This is line 1, and the next one is line 2.
   (operating-system)
;; The 'T' is at column 3.
EOF

if guix system vm "$tmpfile" 2> "$errorfile"
then
    # This must not succeed.
    exit 1
else
    cat "$errorfile"
    grep "$tmpfile:2:3:.*missing.* initializers" "$errorfile"
fi


cat > "$tmpfile"<<EOF
;; This is line 1, and the next one is line 2.
   (operating-system
;; This is line 3, and there is no closing paren!
EOF

if guix system vm "$tmpfile" 2> "$errorfile"
then
    # This must not succeed.
    exit 1
else
    cat "$errorfile"

    # Guile 3.0.6 gets line/column numbers for 'read-error' wrong
    # (zero-indexed): <https://bugs.gnu.org/48089>.
    grep "$tmpfile:4:1: missing closing paren" "$errorfile" || \
    grep "$tmpfile:3:0: missing closing paren" "$errorfile"
fi


# Reporting of module not found errors.

cat > "$tmpfile" <<EOF
;; Line 1.
(use-modules (gnu))
  (use-service-modules openssh)
EOF

if guix system build "$tmpfile" -n 2> "$errorfile"
then false
else
    grep "$tmpfile:3:2: .*module .*openssh.*not found" "$errorfile"
    grep "Try.*use-service-modules ssh" "$errorfile"
fi

cat > "$tmpfile" <<EOF
;; Line 1.
(use-modules (gnu))
  (use-package-modules qemu)
EOF

if guix system build "$tmpfile" -n 2> "$errorfile"
then false
else
    grep "$tmpfile:3:2: .*module .*qemu.*not found" "$errorfile"
    grep "Try.*use-package-modules virtualization" "$errorfile"
fi

# Reporting of unbound variables.

cat > "$tmpfile" <<EOF
(use-modules (gnu))                                   ; 1
(use-service-modules networking)                      ; 2

(operating-system                                     ; 4
  (host-name "antelope")                              ; 5
  (timezone "Europe/Paris")                           ; 6
  (locale "en_US.UTF-8")                              ; 7

  (bootloader (GRUB-config (targets (list "/dev/sdX"))))        ; 9
  (file-systems (cons (file-system
                        (device (file-system-label "root"))
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems)))
EOF

if guix system build "$tmpfile" -n 2> "$errorfile"
then false
else
    if test "`guile -c '(display (effective-version))'`" = 3.0
    then
	# FIXME: With Guile 3.3.0 the error is reported on line 11.
	# See <https://bugs.gnu.org/38388>.
	grep "$tmpfile:[0-9]\+:[0-9]\+:.*GRUB-config.*[Uu]nbound variable" "$errorfile"
    elif test "`guile -c '(display (effective-version))'`" = 2.2
    then
	# FIXME: With Guile 2.2.0 the error is reported on line 4.
	# See <http://bugs.gnu.org/26107>.
	grep "$tmpfile:[49]:[0-9]\+:.*GRUB-config.*[Uu]nbound variable" "$errorfile"
    else
	grep "$tmpfile:9:[0-9]\+:.*GRUB-config.*[Uu]nbound variable" "$errorfile"
    fi
fi

cat > "$tmpfile" <<EOF
(use-modules (gnu))                                    ; 1

(operating-system                                      ; 3
  (file-systems (cons (file-system                     ; 4
                        (device (file-system-label "root"))
                        (mount-point "/")              ; 6
                        (type "ext4"))))               ; 7 (!!)
                      %base-file-systems)
EOF

if guix system build "$tmpfile" -n 2> "$errorfile"
then false
else
    # Here '%base-file-systems' appears as if it were a field specified of the
    # enclosing 'operating-system' form due to parenthesis mismatch.
    grep "$tmpfile:3:[0-9]\+:.*%base-file-system.*invalid field specifier" \
	 "$errorfile"
fi

OS_BASE='
  (host-name "antelope")
  (timezone "Europe/Paris")
  (locale "en_US.UTF-8")

  (bootloader (bootloader-configuration
               (bootloader grub-bootloader)
               (targets (list "/dev/sdX"))))
  (file-systems (cons (file-system
                        (device (file-system-label "root"))
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems))
'

# Reporting of duplicate service identifiers.

cat > "$tmpfile" <<EOF
(use-modules (gnu))
(use-service-modules networking)

(operating-system
  $OS_BASE
  (services (cons* (service dhcp-client-service-type)
                   (service dhcp-client-service-type) ;twice!
                   %base-services)))
EOF

if guix system vm "$tmpfile" 2> "$errorfile"
then
    # This must not succeed.
    exit 1
else
    grep "service 'networking'.*more than once" "$errorfile"
fi

# Reporting unmet shepherd requirements.

cat > "$tmpfile" <<EOF
(use-modules (gnu) (gnu services shepherd))
(use-service-modules networking)

(define buggy-service-type
  (shepherd-service-type
    'buggy
    (lambda _
      (shepherd-service
        (provision '(buggy!))
        (requirement '(does-not-exist))
        (start #t)))
    (description "Buggy.")))

(operating-system
  $OS_BASE
  (services (cons (service buggy-service-type #t)
                  %base-services)))
EOF

if guix system build "$tmpfile" 2> "$errorfile"
then
    exit 1
else
    grep "service 'buggy!'.*'does-not-exist'.*not provided" "$errorfile"
fi

# Reporting inconsistent user accounts.

make_user_config ()
{
    cat > "$tmpfile" <<EOF
(use-modules (gnu))
(use-service-modules networking)

(operating-system
  (host-name "antelope")
  (timezone "Europe/Paris")
  (locale "en_US.UTF-8")

  (bootloader (bootloader-configuration
                (bootloader grub-bootloader)
                (targets (list "/dev/sdX"))))
  (file-systems (cons (file-system
                        (device (file-system-label "root"))
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems))
  (users (list (user-account
                 (name "dave")
                 (home-directory "/home/dave")
                 (group "$1")
                 (supplementary-groups '("$2"))))))
EOF
}

make_user_config "users" "wheel"
guix system build "$tmpfile" -n       # succeeds

guix system build "$tmpfile" -d	      # succeeds
guix system build "$tmpfile" -d | grep '\.drv$'

guix system vm "$tmpfile" -d	      # succeeds
guix system vm "$tmpfile" -d | grep '\.drv$'

# Make sure the behavior is deterministic (<https://bugs.gnu.org/32652>).
drv1="`guix system vm "$tmpfile" -d`"
drv2="`guix system vm "$tmpfile" -d`"
test "$drv1" = "$drv2"
drv1="`guix system image -t iso9660 "$tmpfile" -d`"
drv2="`guix system image -t iso9660 "$tmpfile" -d`"
test "$drv1" = "$drv2"

# Check whether the graph commands work as expected.
guix system extension-graph "$tmpfile" | grep 'label = "file-systems"'
guix system shepherd-graph "$tmpfile" | grep 'label = "guix-daemon"'

make_user_config "group-that-does-not-exist" "users"
if guix system build "$tmpfile" -n 2> "$errorfile"
then false
else grep "primary group.*group-that-does-not-exist.*undeclared" "$errorfile"; fi

make_user_config "users" "group-that-does-not-exist"
if guix system build "$tmpfile" -n 2> "$errorfile"
then false
else grep "supplementary group.*group-that-does-not-exist.*undeclared" "$errorfile"; fi

# Try 'local-file' and relative file name resolution.

cat > "$tmpdir/config.scm"<<EOF
(use-modules (gnu))
(use-service-modules networking)

(operating-system
  $OS_BASE
  (services (cons (service tor-service-type
                           (tor-configuration
                             (config-file (local-file "my-torrc"))))
                  %base-services)))
EOF

cat > "$tmpdir/my-torrc"<<EOF
# This is an example file.
EOF

# In both cases 'my-torrc' should be properly resolved.
guix system build "$tmpdir/config.scm" -n
(cd "$tmpdir"; guix system build "config.scm" -n)

# Check that we get a warning when passing 'local-file' a non-literal relative
# file name.
cat > "$tmpdir/config.scm" <<EOF
(use-modules (guix))

(define (bad-local-file file)
  (local-file file))

(bad-local-file "whatever.scm")
EOF
guix system build "$tmpdir/config.scm" -n && false
guix system build "$tmpdir/config.scm" -n 2>&1 | \
    grep "config\.scm:4:2: warning:.*whatever.*relative to current directory"

# Searching.
guix system search tor | grep "^name: tor"
guix system search tor | grep "^shepherdnames: tor"
guix system search anonym network | grep "^name: tor"
guix system search . > "$tmpdir/search"
test $(wc -l < "$tmpdir/search") -gt 500
rm "$tmpdir/search"

# Below, use -n (--dry-run) for the tests because if we actually tried to
# build these images, the commands would take hours to run in the worst case.

# Verify that the examples can be built.
for example in gnu/system/examples/*.tmpl; do
    case "$example" in
	*hurd*)
            options="--target=i586-pc-gnu";;
	*asus*)
	    # 'asus-c201.tmpl' uses 'linux-libre-arm-generic', which is an
	    # ARM-only package.
            options="--system=armhf-linux";;
        *raspberry*)
	    # The Raspberry Pi templates 'linux-libre-arm64-generic', which is
	    # an ARM-only package.
            options="--system=aarch64-linux";;
        *plasma*)
            # Some architectures do not support all the packages Plasma
            # depends on so restrict to x86_64-linux.
            options="--system=x86_64-linux";;
	*vm-image*)
	    # The VM image tries to build 'current-guix' as per 'guix pull'.
	    # Skip it.
	    continue
	    ;;
	*desktop*)
	    # This image uses 'grub-efi-bootloader' so it needs a GPT
	    # partition.
	    options="-t efi-raw --system=x86_64-linux";;
	*)
	    options=""
	    ;;
    esac
    guix system -n image $options "$example"
done

# Make sure the desktop image can be built on major architectures.
for system in x86_64-linux aarch64-linux
do
    guix system -n image -s "$system" -t efi-raw \
	 gnu/system/examples/desktop.tmpl
done

# Verify that the images can be built.
guix system -n vm gnu/system/examples/bare-bones.tmpl
guix system -n image gnu/system/images/pinebook-pro.scm
guix system -n image -t qcow2 gnu/system/examples/bare-bones.tmpl
guix system -n image -t iso9660 gnu/system/examples/bare-bones.tmpl
guix system -n docker-image gnu/system/examples/docker-image.tmpl

# Verify that at least the raw image type is available.
guix system --list-image-types | grep "raw"
ely "colors" colors) #t)))))) (synopsis "Dark color theme for Vim") (description "@code{vim-luna} is a dark color theme for Vim.") (home-page "https://github.com/notpratheek/vim-luna") (license license:expat)))) ;; There are no tarball releases. (define-public vim-context-filetype (let ((commit "5e85f8cae26806f391aefe2661791a6de53bcea2") (revision "1")) (package (name "vim-context-filetype") (version (string-append "0.0.0-" revision "." (string-take commit 7))) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/Shougo/context_filetype.vim") (commit commit))) (file-name (string-append name "-" version "-checkout")) (sha256 (base32 "0alvrfhmd91zkd9h83s8wvgyq4iakcf6rybsyjd369qbgpcqky89")))) (build-system gnu-build-system) (arguments `(#:tests? #f #:phases (modify-phases %standard-phases (delete 'configure) (delete 'build) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vimfiles (string-append out "/share/vim/vimfiles")) (doc (string-append vimfiles "/doc")) (autoload (string-append vimfiles "/autoload"))) (copy-recursively "doc" doc) (copy-recursively "autoload" autoload) #t)))))) (synopsis "Context filetype library for Vim") (description "@code{vim-context-filetype} is context filetype library for Vim script.") (home-page "https://github.com/Shougo/context_filetype.vim") (license license:expat)))) ; ??? check again (define-public vim-fugitive (package (name "vim-fugitive") (version "2.3") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/tpope/vim-fugitive.git") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "17s94a8g5z0lrs7yy4nyqyvp9ykys5ws2ar3m3c0bjsn0iazd7m3")))) (build-system gnu-build-system) (arguments '(#:tests? #f #:phases (modify-phases %standard-phases (delete 'configure) (delete 'build) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vimfiles (string-append out "/share/vim/vimfiles")) (doc (string-append vimfiles "/doc")) (plugin (string-append vimfiles "/plugin"))) (copy-recursively "doc" doc) (copy-recursively "plugin" plugin) #t)))))) (home-page "https://github.com/tpope/vim-fugitive") (synopsis "Vim plugin to work with Git") (description "Vim-fugitive is a wrapper for Vim that complements the command window, where you can stage and review your changes before the next commit or run any Git arbitrary command.") (license license:vim))) ; distributed under the same license as vim (define-public vim-airline (package (name "vim-airline") (version "0.9") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/vim-airline/vim-airline") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "0hq3304rhakx7x1v7wll7gxinmfz6561bq97qpj8jrk19rhcab75")))) (build-system gnu-build-system) (arguments `(#:tests? #f #:phases (modify-phases %standard-phases (delete 'configure) (delete 'build) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vimfiles (string-append out "/share/vim/vimfiles")) (autoload (string-append vimfiles "/autoload")) (doc (string-append vimfiles "/doc")) (t (string-append vimfiles "/t")) (plugin (string-append vimfiles "/plugin"))) (copy-recursively "autoload" autoload) (copy-recursively "doc" doc) (copy-recursively "plugin" plugin) (copy-recursively "t" t) #t)))))) (synopsis "Statusline for Vim") (description "@code{vim-airline} is an extensible statusline for Vim. It can be extended and costumized with themes, works with unicode fonts and powerline symbols, etc.") (home-page "https://github.com/vim-airline/vim-airline") (license license:expat))) ;; There are no tarball releases. (define-public vim-airline-themes (let ((commit "6026eb78bf362cb3aa875aff8487f65728d0f7d8") (revision "1")) (package (name "vim-airline-themes") (version (string-append "0.0.0-" revision "." (string-take commit 7))) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/vim-airline/vim-airline-themes") (commit commit))) (file-name (string-append name "-" version "-checkout")) (sha256 (base32 "13ijkavh1r0935cn2rjsfbdd1q3ka8bi26kw0bdkrqlrqxwvpss8")))) (build-system gnu-build-system) (arguments `(#:tests? #f #:phases (modify-phases %standard-phases (delete 'configure) (delete 'build) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vimfiles (string-append out "/share/vim/vimfiles")) (doc (string-append vimfiles "/doc")) (plugin (string-append vimfiles "/plugin")) (autoload (string-append vimfiles "/autoload"))) (copy-recursively "doc" doc) (copy-recursively "autoload" autoload) (copy-recursively "plugin" plugin) #t)))))) (synopsis "Collection of themes for Vim-airline") (description "@code{vim-airline-themes} is a collection of themes for @code{vim-airline}.") (home-page "https://github.com/vim-airline/vim-airline-themes") (license license:expat)))) (define-public vim-syntastic (package (name "vim-syntastic") (version "3.9.0") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/vim-syntastic/syntastic") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "121a1mxgfng2y5zmivyyk02mca8pyw72crivf4f1q9nhn0barf57")))) (build-system gnu-build-system) (arguments `(#:tests? #f #:phases (modify-phases %standard-phases (delete 'configure) (delete 'build) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vimfiles (string-append out "/share/vim/vimfiles")) (doc (string-append vimfiles "/doc")) (plugin (string-append vimfiles "/plugin")) (autoload (string-append vimfiles "/autoload")) (syntax-checkers (string-append vimfiles "/syntax_checkers"))) (copy-recursively "doc" doc) (copy-recursively "autoload" autoload) (copy-recursively "plugin" plugin) (copy-recursively "syntax_checkers" syntax-checkers) #t)))))) (synopsis "Syntax checking plugin for Vim") (description "Vim-syntastic is a syntax checking plugin for Vim. It runs files through external syntax checkers and displays any resulting errors to the user. This can be done on demand, or automatically as files are saved. If syntax errors are detected, the user is notified.") (home-page "https://github.com/vim-syntastic/syntastic") (license license:wtfpl2))) (define-public neovim-syntastic (package (inherit vim-syntastic) (name "neovim-syntastic") (arguments `(#:tests? #f #:phases (modify-phases %standard-phases (delete 'configure) (delete 'build) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vimfiles (string-append out "/share/nvim/site")) (doc (string-append vimfiles "/doc")) (plugin (string-append vimfiles "/plugin")) (autoload (string-append vimfiles "/autoload")) (syntax-checkers (string-append vimfiles "/syntax_checkers"))) (copy-recursively "doc" doc) (copy-recursively "autoload" autoload) (copy-recursively "plugin" plugin) (copy-recursively "syntax_checkers" syntax-checkers) #t)))))) (synopsis "Syntax checking plugin for Neovim") (description "Vim-syntastic is a syntax checking plugin for Neovim. It runs files through external syntax checkers and displays any resulting errors to the user. This can be done on demand, or automatically as files are saved. If syntax errors are detected, the user is notified."))) (define-public neovim (package (name "neovim") (version "0.2.0") (source (origin (method url-fetch) (uri (string-append "https://github.com/neovim/neovim/" "archive/v" version ".tar.gz")) (file-name (string-append name "-" version ".tar.gz")) (sha256 (base32 "1db27zm6cldm1aw0570vii1bxc16a34x8lissl1h9rizsbwn7qkj")))) (build-system cmake-build-system) (arguments `(#:modules ((srfi srfi-26) (guix build cmake-build-system) (guix build utils)) #:phases (modify-phases %standard-phases (add-after 'unpack 'set-lua-paths (lambda* (#:key inputs #:allow-other-keys) (let* ((lua-version "5.2") (lua-cpath-spec (lambda (prefix) (let ((path (string-append prefix "/lib/lua/" lua-version))) (string-append path "/?.so;" path "/?/?.so")))) (lua-path-spec (lambda (prefix) (let ((path (string-append prefix "/share/lua/" lua-version))) (string-append path "/?.lua;" path "/?/?.lua")))) (lua-inputs (map (cute assoc-ref %build-inputs <>) '("lua" "lua-lpeg" "lua-bitop" "lua-libmpack")))) (setenv "LUA_PATH" (string-join (map lua-path-spec lua-inputs) ";")) (setenv "LUA_CPATH" (string-join (map lua-cpath-spec lua-inputs) ";")) #t)))))) (inputs `(("libuv" ,libuv) ("msgpack" ,msgpack) ("libtermkey" ,libtermkey) ("libvterm" ,libvterm) ("unibilium" ,unibilium) ("jemalloc" ,jemalloc) ("libiconv" ,libiconv) ("lua" ,lua-5.2) ("lua-lpeg" ,lua5.2-lpeg) ("lua-bitop" ,lua5.2-bitop) ("lua-libmpack" ,lua5.2-libmpack))) (native-inputs `(("pkg-config" ,pkg-config) ("gettext" ,gettext-minimal) ("gperf" ,gperf))) (home-page "http://neovim.io") (synopsis "Fork of vim focused on extensibility and agility") (description "Neovim is a project that seeks to aggressively refactor Vim in order to: @itemize @item Simplify maintenance and encourage contributions @item Split the work between multiple developers @item Enable advanced external UIs without modifications to the core @item Improve extensibility with a new plugin architecture @end itemize\n") ;; Neovim is licensed under the terms of the Apache 2.0 license, ;; except for parts that were contributed under the Vim license. (license (list license:asl2.0 license:vim)))) (define-public vifm (package (name "vifm") (version "0.9.1") (source (origin (method url-fetch) (uri (list (string-append "https://github.com/vifm/vifm/releases/download/v" version "/vifm-" version ".tar.bz2") (string-append "https://sourceforge.net/projects/vifm/files/vifm/" "vifm-" version ".tar.bz2"))) (sha256 (base32 "1cz7vjjmghgdxd1lvsdwv85gvx4kz8idq14qijpwkpfrf2va9f98")))) (build-system gnu-build-system) (arguments '(#:configure-flags '("--disable-build-timestamp") #:phases (modify-phases %standard-phases (add-after 'patch-source-shebangs 'patch-test-shebangs (lambda _ (substitute* (cons* "src/background.c" "src/cfg/config.c" (find-files "tests" "\\.c$")) (("/bin/sh") (which "sh")) (("/bin/bash") (which "bash"))) ;; This test segfaults (substitute* "tests/Makefile" (("misc") "")) #t)) (add-after 'install 'install-vim-plugin-files (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (vifm (string-append out "/share/vifm")) (vimfiles (string-append out "/share/vim/vimfiles"))) (copy-recursively (string-append vifm "/colors") (string-append vimfiles "/colors")) (copy-recursively (string-append vifm "/vim") vimfiles) (delete-file-recursively (string-append vifm "/colors")) (delete-file-recursively (string-append vifm "/vim"))) #t))))) (native-inputs `(("groff" ,groff))) ; for the documentation (inputs `(("libx11" ,libx11) ("ncurses" ,ncurses) ("perl" ,perl))) (home-page "https://vifm.info/") (synopsis "Flexible vi-like file manager using ncurses") (description "Vifm is a file manager providing a @command{vi}-like usage experience. It has similar keybindings and modes (e.g. normal, command line, visual). The interface uses ncurses, thus vifm can be used in text-only environments. It supports a wide range of features, some of which are known from the @command{vi}-editor: @enumerate @item utf8 support @item user mappings (almost like in @code{vi}) @item ranges in command @item line commands @item user defined commands (with support for ranges) @item registers @item operation undoing/redoing @item fuse file systems support @item trash @item multiple files renaming @item support of filename modifiers @item colorschemes support @item file name color according to file type @item path specific colorscheme customization @item bookmarks @item operation backgrounding @item customizable file viewers @item handy @code{less}-like preview mode @item filtering out and searching for files using regular expressions @item one or two panes view @end enumerate With the package comes a plugin to use vifm as a vim file selector.") (license license:gpl2+)))