Standard Library
core:stdlib gives plugin authors small helpers that many plugins need: selections, lists, files, downloads and archives, git, command arguments, reports, word splitting, config validation and a picker keymap. Each one is an editor command reached through call!, never a plain Scheme function.
Setup
(load-plugin! "core:stdlib")Core Plugins explains why this call should stay a plain load-plugin!. Depending on another plugin shows how to check it's available before your plugin relies on it.
Selections
| Call | Effect |
|---|---|
stdlib/single-selection? | (call! "stdlib/single-selection?" sels) #t if sels holds one selection |
stdlib/all-single-char? | (call! "stdlib/all-single-char?" sels) #t if every selection in sels covers one character |
stdlib/cursor-char-offset | (call! "stdlib/cursor-char-offset" sels) The char offset of the primary selection's cursor in sels, or #f |
stdlib/primary-selection | (call! "stdlib/primary-selection" sels) The primary selection in sels, or #f |
sels is the list of selections (buffer-selections pane) returns; read one selection with the selection-* calls. All four return #f when sels is #f.
Lists
| Call | Effect |
|---|---|
stdlib/find | (call! "stdlib/find" pred? lst) The first element of lst satisfying pred?, or #f |
stdlib/concat | (call! "stdlib/concat" lists) The lists in lists joined into one, in order, however many there are |
Filesystem
| Call | Effect |
|---|---|
stdlib/write-file! | (call! "stdlib/write-file!" path content) Write content to path, creating or truncating it |
stdlib/delete-dir! | (call! "stdlib/delete-dir!" dir) Recursively delete dir; a missing dir is no error |
stdlib/delete-file! | (call! "stdlib/delete-file!" path) Delete path; a missing path is no error |
stdlib/list-entries | (call! "stdlib/list-entries" dir) Sorted basenames of every entry of dir, files and directories |
stdlib/list-subdirs | (call! "stdlib/list-subdirs" dir) Sorted basenames of dir's subdirectories |
stdlib/path-absolute? | (call! "stdlib/path-absolute?" path) Whether path names the same place from any working directory |
Unlike remove-dir! and Steel's own delete-file!, stdlib/delete-dir! and stdlib/delete-file! treat a missing target as no error. list-subdirs skips stray non-directory entries such as .DS_Store. list-entries and list-subdirs raise when dir can't be read, a missing one included; check it with path-exists? first when a missing directory means there is nothing to list.
path-absolute? is #t for a path starting with / on macOS and Linux. On Windows it is #t for a drive path (C:\x or C:/x) or a network path (\\server\share), and /x is not absolute there.
Downloads
| Call | Effect |
|---|---|
stdlib/download! | (call! "stdlib/download!" url path [offset size]) Download url to the file path with curl, or only size bytes starting at byte offset. Raises on an HTTP error |
stdlib/verify-sha256! | (call! "stdlib/verify-sha256!" path hex) Raise unless the file at path has the SHA-256 hex, in upper or lower case |
stdlib/find-extractor | (call! "stdlib/find-extractor" format) The program stdlib/extract-archive! runs for format, "tar" or "zip", or #f when none is installed. Raises for any other format |
stdlib/extract-archive! | (call! "stdlib/extract-archive!" format archive dir) Extract archive, a "tar" or "zip" archive, into dir (created if missing), and return the extracted regular files. Raises if the archive holds a symlink pointing outside dir |
stdlib/download! and stdlib/extract-archive! run their program in the terminal, so call them only from a command defined with #:inline-output #t (see Commands); anywhere else they raise. verify-sha256! and find-extractor work anywhere.
The digest and the archives use the platform's own tools: shasum on macOS, sha256sum on Linux and certutil on Windows, and tar or unzip. tar reads gzip-compressed archives too. On Windows, both kinds of archive are extracted with Windows' own tar.
Git
| Call | Effect |
|---|---|
stdlib/git-repo? | (call! "stdlib/git-repo?") #t when the editor's working directory is inside a git work tree |
stdlib/git-toplevel | (call! "stdlib/git-toplevel") The absolute repository root of the editor's working directory, or #f when git is missing or the directory is outside a work tree |
Both answer for HUME's own working directory (:pwd), not necessarily the current buffer's. git-repo? is #f inside a bare repository.
Command arguments
| Call | Effect |
|---|---|
stdlib/resolve-lang-arg | (call! "stdlib/resolve-lang-arg" pane cmd arg) A typed language-name argument, else pane's buffer's language, else #f after an info message naming cmd |
Use it for a typed command that takes an optional language name. arg is what the user typed after the command, or #f if they typed nothing.
Reports
| Call | Effect |
|---|---|
stdlib/report-section | (call! "stdlib/report-section" title items hint) One section as text: title (count), then , hint when items is not empty (hint may be #f), then one indented line per item, or none |
stdlib/show-report! | (call! "stdlib/show-report!" pane name sections) Show sections, separated by blank lines, on pane in the read-only buffer [name] |
Use these for a typed command that lists things, since a list longer than one line does not fit on the statusline. A later call with the same name replaces that buffer's text.
Word tokenization
| Call | Effect |
|---|---|
stdlib/split-words | (call! "stdlib/split-words" pane str) Every word in str, split by pane's buffer's own word-chars setting |
This is (split-words str (get-buffer-option pane "word-chars")), so a word here is what the w/b motions and word text objects would select in that buffer. Use it when str is that buffer's own content, typically one of its lines. Call split-words directly for text not tied to a buffer, or to split words differently from that buffer's setting.
Plugin configuration
| Call | Effect |
|---|---|
stdlib/config-boolean | (call! "stdlib/config-boolean" plugin cfg key default) cfg's value for key, or default if absent; raises if the value isn't #t/#f |
stdlib/config-string | (call! "stdlib/config-string" plugin cfg key default) The same, raising if the value isn't a string |
stdlib/config-enum | (call! "stdlib/config-enum" plugin cfg key default allowed) The same, raising if the value isn't one of the symbols in allowed |
stdlib/config-integer | (call! "stdlib/config-integer" plugin cfg key default minimum) The same, raising if the value isn't an integer, or is below the integer minimum |
stdlib/config-list | (call! "stdlib/config-list" plugin cfg key default) The same, raising if the value isn't a list of strings |
cfg is what (plugin-config) returns, and key a symbol, like 'signs. Every error names the calling plugin (plugin) and the offending key, so a bad #:config value fails at load time naming what to fix. Configuring a plugin covers reading #:config in full.
Picker keymap
| Call | Effect |
|---|---|
stdlib/picker-keymap | (call! "stdlib/picker-keymap" handler) A keymap for picker!/live-picker! that calls handler with the chosen item; keys below |
stdlib/with-tab | (call! "stdlib/with-tab" handler) Wrap handler: open a new tab, then call handler with the picker's payload |
stdlib/with-vsplit | (call! "stdlib/with-vsplit" handler) Wrap handler: split the focused pane side by side, then call handler in the new pane with the picker's payload |
stdlib/with-split | (call! "stdlib/with-split" handler) Wrap handler: split the focused pane stacked, then call handler in the new pane with the picker's payload |
The keymap's keys:
Down/Ctrl-nandUp/Ctrl-pmove the selection;PageDown/PageUpmove it a page,Ctrl-d/Ctrl-uhalf a page.Esccloses the picker.Enter/Ctrl-oclose it and callhandlerwith the selected item.Ctrl-t,Ctrl-vandCtrl-sdo the same in a new tab, a vertical split and a horizontal split.
handler takes one argument, the selected item's payload, or #f when nothing matches. picker-keymap returns a hash, so a plugin changes or adds a key with hash-insert (see Custom pickers).
with-tab/with-vsplit/with-split are its building blocks, for a binding of your own that opens the item somewhere else. With a #f payload they open nothing and still call handler. When the focused pane is too small to split, with-vsplit and with-split leave it as it is and don't call handler.