Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aartaka/trivial-toplevel-commands
Common Lisp library to portably (un)define REPL toplevel commands.
https://github.com/aartaka/trivial-toplevel-commands
command compiler implementation lisp portability shell
Last synced: about 1 month ago
JSON representation
Common Lisp library to portably (un)define REPL toplevel commands.
- Host: GitHub
- URL: https://github.com/aartaka/trivial-toplevel-commands
- Owner: aartaka
- License: bsd-3-clause
- Created: 2023-09-23T17:58:44.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-03-02T18:54:50.000Z (11 months ago)
- Last Synced: 2024-03-02T20:47:39.903Z (11 months ago)
- Topics: command, compiler, implementation, lisp, portability, shell
- Language: Common Lisp
- Homepage:
- Size: 31.3 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
#+TITLE:Trivial Toplevel Commands
Most CL implementations provide convenient toplevel commands, like
#+begin_src lisp
;; ECL command to load a Lisp file
:ld file.lisp
#+end_srcThese commands tend to start with a colon and end with a newline,
possibly including space-separated arguments. Such commands are too
similar to not want a portable way to define them. Trivial Toplevel
Commands is such a portability layer. It allows to define and remove
toplevel commands on SBCL, CCL, ECL, ABCL, CLISP, and Allegro CL.Couple of caveats:
- There are no toplevel commands on SBCL :: there are only debugger
commands. Trivial Toplevel Commands only defines debugger command to
not interfere with default SBCL REPL. If you want to access defined
commands, enter the debugger by signaling some condition (~(break)~,
at least) or contribute a more involved REPL to SBCL directly.
- You can also ~(require "sb-aclrepl")~ to enable an Allegro-like
REPL. Trivial Toplevel Commands supports it.
- CCL commands only accept evaluated arguments :: macro-like commands
are thus not possible. If you want to have maximum portability, only
use ~define-toplevel-command/eval~ or constant arguments. Contribute
a new REPL to CCL if you want to change that.
- ECL ~/read~ and ~/string~ commands remove a layer of quotes from strings :: I.e. ""hello"
hello" will be read as "hello hello". Plan accordingly. ~/eval~
commands are unaffected.
- Help with making it work on CLASP, CMUCL, and LispWorks :: I don't
have access to these implementations. Like, at all. Thanks.* Getting Started
Clone the Git repository:
#+begin_src sh
git clone --recursive https://github.com/aartaka/trivial-toplevel-commands ~/common-lisp/
#+end_srcAnd then load ~:trivial-toplevel-commands~ in the REPL:
#+begin_src lisp
(asdf:load-system :trivial-toplevel-commands)
;; or, if you use Quicklisp
(ql:quickload :trivial-toplevel-commands)
#+end_srcYou can also install Trivial Toplevel Commands via Guix, using the
bundled =guix.scm= file:
#+begin_src sh
guix package -f guix.scm
#+end_src* Examples
A simple shell-invoking command mimicking [[https://github.com/ruricolist/cmd/][ruricolist/cmd]]. Obviously
quite primitive:
#+begin_src lisp
(tpl-cmds:define-command/eval (:cmd :!) (command)
"Shell invocation shortcut."
(uiop:launch-program command));; Used like:
:! "touch ~/cmd-test.txt";; With an apparent result
(uiop:file-exists-p #p"~/cmd-test.txt")
;; => #P"~/cmd-test.txt"
#+end_srcA much more involved command processing raw string argument, say, for your MP3 player setup:
#+begin_src lisp
(tpl-cmds:define-command/string (:list-mp3s :lm) (path)
"Recursively list all MP3 files in PATH, be it directory or file."
(labels ((ls (file)
(cond
((uiop:directory-pathname-p file)
(format t "~&Directory ~a..." file)
(mapc #'ls (uiop:subdirectories file))
(mapc #'ls (uiop:directory-files file)))
((equalp "mp3" (pathname-type file))
(format t "~&File ~a..." file)))))
(ls (uiop:merge-pathnames* (uiop:parse-native-namestring path) (uiop:getcwd)))));; Used like:
:list-mp3s /path/to/your/mp3/files
;; or
:lm /path/to/your/mp3/files;; Directory ...
;; Directory ...
;; File ...
;; Directory ...
;; Directory ...
;; File ...
;; File ...
;; File ...
;; File ...
#+end_srcYou can also undefine previously defined commands with ~remove-command~:
#+begin_src lisp
;; By alias:
(tpl-cmds:remove-command :lm)
;; Or by full name:
(tpl-cmds:remove-command :list-mp3s)
#+end_srcMost of the information for command is accessible too, via helper
functions:
- Command char for implementation (setf-able) :: ~command-char~.
- Command alias by name :: ~command-alias~.
- And vice versa :: ~command-name~.
- The handler function for the command :: ~command-handler~.
- Documentation for the command can be fetched with ~(documentation (command-handler :command) 'function)~.You can also see the practical uses for commands [[https://github.com/aartaka/lisp-config/blob/master/commands.lisp][in my config]].
* Similar Libraries
- [[https://web.archive.org/web/20160826073800/http://heim.ifi.uio.no/~pok/download/commands.lisp][Peder Klingenberg's commands.lisp]] :: CMUCL-specific, could possibly
work on SBCL.
- [[https://web.archive.org/web/20170511215618/http://users.actrix.co.nz/mycroft/toplevel.tar.gz][Paul Foley's Toplevel]] :: CMUCL-specific.