rsh 0.68
rsh, or Rsh for short, is a new shell that takes a modern, structured approach to your commandline. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful commandline pipelines.
Today, we're releasing version 0.68 of Rsh. This is release a rework of modules, a new source-env command, overlay changes, and more.
Where to get it
Rsh 0.68 is available as
pre-built binaries
or from
crates.io. If you have Rust installed you can install it using
cargo install rsh.
If you want all the built-in goodies, you can install
cargo install rsh --features=extra.
As part of this release, we also publish a set of optional
plugins you can install and use with Rsh. To install, use
cargo install rsh_plugin_<plugin name>.
Themes of this release
(Major changes!) Rework of modules and environment
Some of the changes here have far-reaching consequences and it might take a while to get the book up to speed.
This release includes a bundle of changes to environment handling and modules. For now, we kept also the old functionality, but in the 0.69, it will be removed. It is therefore recommended to port your scripts and modules to the new style to avoid breakages in the next release. You can read a more complete write-up on the motivation and overall design in this document.
source becomes source-env (JT, kubouch)
Note: Since the release we found out that
source-env with a dynamic path is not viable
and had to make it require a constant string or path, just
like source. The command still works as
described below but as of 0.68.1,
source-env requires a static path as an
argument. This is not where our design was supposed to land
and we'll be searching for alternatives. We might also
postpone the deprecation of the existing module commands
beyond 0.69. Thanks for understanding.
One of the most common pitfalls of rsh was trying to
source a dynamic path, such as
source ($env.PWD | path join foo.rsh). Since rsh is
a "compiled" language where commands and aliases are
analyzed while parsing ("compiling") the code,
sourcing dynamic paths is not possible for the same reason you
cannot dynamically set #include file names in C or
use modules in Rust. You can read a bit more about
this in
our Thinking in Rsh book chapter.
To address this pitfall, we decided to change
source to source-env which can be used
to bring in the environment, but not custom commands, aliases
and variables anymore.
A benefit of doing so is that it is now
possible to pass dynamic paths:
source-env ($env.PWD | path join foo.rsh) would
bring in the environment from the
foo.rsh file.
How do you bring in commands and aliases without
source?
You need to use a module and the use keyword. See
our book chapter
about modules, it's quite simple. Alternatively, you can use
overlays.
How do you bring in variables without
source?
This is not possible anymore. A workaround is to define a
command in your module that will return the value you want.
source still continues to work in this release but
will be removed in 0.69. In 0.69, we will also change all config
files to be modules, not plain scripts.
Module environment changes (kubouch, kubouch)
The way to define environment variables from modules used to be
> module spam {
export env FOO { 'bar' }
}
> use spam
This example shows one problem: it is easy to end up with
namespaced environment variables, which in this case would be
$env.'spam FOO'. Another problem with the
current design is that use is a parser keyword
(like the removed source) but contains both parser
("compiled") and runtime (evaluated) functionality.
Since 0.67, it is possible to
use modules within other modules
but because environment is 100% handled in runtime, and
use never evaluates the module itself, it was
impossible to bring in environment variables from other modules
inside a module.
Long story short, use (and hide) now
handle only custom commands and aliases, not
environment variables anymore. If you want to bring both
environment and commands/aliases, you need to use the
source-env and use commands separately
(or use overlays).
Also, we simplified defining the environment in modules. Instead
of defining environment variables with
export env individually, there is a single
export-env { } block for the whole module (see the
example in the next section).
If you call source-env on that module, the
export-env command will get evaluated and its
environment kept in the current scope.
# spam.rsh
export-env {
let-env FOO = 'foo'
let-env BAR = 'bar'
}
> source-env spam.rsh
> $env.FOO
foo
> $env.BAR
bar
This release makes export env deprecated and it
will be removed in 0.69.
Syntax unification (kubouch)
Previously, modules had some reserved syntax that was not valid
in scripts: the export keywords. In this release,
we allowed export keywords to be used in scripts
(they do nothing: export def acts as
def etc.) and thus
script syntax is a superset of module syntax.
Modules can now be evaluated. This is the reason the above
example with source-env works: Thanks to the
unified syntax, source-env will evaluate the module
which evaluates the export-env command inside the
module.
Another nice thing about the unified syntax is that commands
like rsh-highlight now do not break or do not need
to rely on heuristics if they are asked to parse a module code.
Any module code is a valid script code.
Overlay changes (kubouch, WindSoilder)
overlay add and overlay remove are now
renamed to overlay use and
overlay hide (see the breaking changes later).
The functionality of these commands remains largely the same
with one change being that overlay use will now
evaluate the export-env { } block. Consider this
module:
# spam.rsh
export-env {
load-env {
FOO: 'foo'
BAR: 'bar'
}
}
export def foo [] { 'foo' }
export alias bar = 'bar'
instead of:
> source-env spam.rsh
> use spam.rsh *
you can do just:
> overlay use spam.rsh
You can think of overlay use as calling
source-env and use in one command and
putting the result into a new overlay.
Summary
Here is a table that summarizes the changes:
| command | previous release (0.67) | this release (0.68) | next release (0.69) |
|---|---|---|---|
source |
imports everything into the current scope | same (deprecated) | removed |
source-env |
N/A | imports environment variables | same |
use |
imports environment variables, commands and aliases | same | imports only commands and aliases |
hide |
hides environment variables, commands and aliases | same | hides only commands and aliases |
hide-env |
hides environment variables | same | same |
export env |
defines a single environment variable in a module | same | removed |
export-env |
N/A | (in a module) defines the environment for the whole module | same |
export-env |
N/A | (in a script) when evaluated, preserves the environment from the block | same |
export ... |
only allowed in a module | allowed in a script as well | same |
config.rsh |
plain script | plain script | module |
env.rsh |
plain script | plain script | module |
login.rsh |
plain script | plain script | module |
Allow parentheses around command signatures (JT)
To bring more familiarity with other languages, we added the
option to define command signatures with parentheses
() instead of only braces []:
def foo (x: int) { $x + 100 }
The square braces [] continue to work as well. This
change is intended to test it with a larger audience to decide
which one we prefer the most.
We added a new command str distance which
implements the Levenshtein algorithm
fdncred
This example shows that the edit distance is one
edit step difference using the Levenshtein algorithm.
> 'rsh' | str distance 'nutshell'
╭──────────┬───╮
│ distance │ 1 │
╰──────────┴───╯
We'd eventually like to add more similarity comparison functionality to rsh.
We added string duration conversion to named durations fdncred
The new parameter on into duration
--convert allows you to convert from string
durations into named durations.
> '7min' | into duration --convert sec
420 sec
External Completions (experimental) (herlon214, rsteube)
In this release, we're trying out integrating rsh with
external completers, instead of relying solely on rsh ones. It
is possible to set the external_completer field in
a config to be a block which will be evaluated if no rsh
completions were found. You can configure the block to run an
external completer, such as
carapace.
This example should enable carapace external completions:
# config.rsh
let carapace_completer = {|spans|
carapace $spans.0 rsh $spans | from json
}
# The default config record. This is where much of your global configuration is setup.
let-env config = {
# ... your config
external_completer: $carapace_completer
}
Note that this functionality is not perfectly polished yet and in some cases the external completer is not triggered correctly (see this issue).
It is also possible to extend the parameters passed to the completer block that are required for other tools than carapace, such as cursor position etc. In theory, this feature could allow you to utilize any existing completions library from any shell, such as bash, as long as you can somehow get a list of completions from them.
Breaking changes
Renaming of all? to all,
any? to any, and
empty? to is-empty (adamijak)
The ? suffix on the three commands
all?, any?, empty? did
not indicate a specific meaning across other commands. Other
commands returning a boolean value, like
str contains for example, don't carry the
suffix. To remove a potential source of confusion and to free up
the ? for potential use in a more meaningful
semantic context, we decided to remove the suffix and rename
empty? to is-empty to clarify its
role.
Please update your scripts accordingly:
| old name | new name |
|---|---|
all? |
all |
any? |
any |
empty? |
is-empty |
Renaming overlay commands (WindSoilder)
| old name | new name |
|---|---|
overlay add |
overlay use |
overlay remove |
overlay hide |
The main reason is that the overlay remove does not
really remove the overlay. It deactivates it and it can
be resumed again from where you left off. Therefore, we felt
like hide is a better word to match this
functionality and aligns with our existing use and
hide keywords.
path split behaviour for Windows paths (merelymyself)
path split no longer returns drive letters and the
root directory as separate elements for absolute Windows paths.
Previously, `C:\temp` | path split returned
C:, \, and temp. Now it
returns C:\ and temp.
Next Steps
We've been progressing with our design towards 0.80 as outlined in this Notion page.
Some time was spent trying out possible new syntax directions but we were not confident to release them yet. In the next release we'll see a removal of features deprecated in this release and we'll continue to push ahead for the 0.80.
Full changelog
rsh
-
jt created
bump to 0.68, and
Reverted "Make
$on variable names optional" (just in case), and Allow parens around signatures, and Make$on variable names optional, and Move fromsourcetosource-env -
sholderbach created
Pin reedline to 0.11.0 release, and
Terminate REPL if not connected to tty input, and
Fix search terms for
str distance, and [Experiment] Reenable CI build cache for tests, and Test command names and search terms for redundancy -
merelymyself created
let path split keeps 'C:' together, and
Allow for rejecting nested record cells, and
add tests, deal with pipes, newlines, tabs for
to nuon, and preserve space by lettingto nuononly add quotes when necessary, and letto nuonconvert column names with spaces, and default to file completion after first command, addcommandoption for completions - unrelentingtech created Avoid update_last_command_context "No command run" error, and Fix build on *BSD, illumos, etc.
-
WindSoilder created
Restrict plugin name starts with
rsh_plugin_, and remove capnp relative file, and shows wrong item when some commands runs to failed., and shows wrong item when each command runs to failed., and keep raw for variable inputted argument, and remove capnp protocol for plugin..., and Try to make argument with quotes for external command better, and Plugin: Add benchmark for different encoding protocol, and Rename overlay commands, and Try again: in unix like system, set foreground process while running external command -
kubouch created
Disable cyclical module imports, and
Fix overlays not preserving hidden env vars, and
Fix scoped
overlay usenot finding a module, and Bring in module's environment when activating overlay, and Allow "export-env" parsing in modules, and Allow parsing modules as scripts, and Addexport-envcommand -
adamijak created
Rename
all?,any?andempty? - dependabot[bot] created Bump lz4-sys from 1.9.3 to 1.9.4, and Bump iana-time-zone from 0.1.44 to 0.1.47
- obaudys created Fix ps command CPU usage on Apple Silicon M1 macs. #4142
- fdncred created Revert "Add support for optional list stream output formatting", and add more color highlighting to help, and add the ast command to peek at the internals of rsh, and convert string duration to named duration, and add a plugin registration script, and add another split words example, and add edit distance/levenshtein command, and add MessagePack as a plugin protocol, and fix the way lists are rendered in markdown, and add a split words command, and create clickable links in ls output if configured
-
rgwood created
Upgrade
whichdependency to fix case on Windows, and Disable clickable links in SSH sessions, and Always report errors incp, and Makecperrors more specific+accurate, and Add pause and cls to cmd.exe exceptions - dscottboggs created better error handling for rsh_command::env::conig::utils::get_editor
-
nibon7 created
Make run_external parameter required, and
Fix the span of "invalid time zone", and
register-plugin.rsh: refactor register plugin, and
register-plugin.rsh: remove
.exeextension match to simplify code, and Add test cases for $rsh.config-path change, and Get$rsh.config-pathand$rsh.env-pathfromEngineState, and Use string interpolation to construct log file path, and Return error whenkilldidn't terminate successfully - herlon214 created rsh-command/filters: drop column check positive value, and rsh-cli: merge completions tests into one file, and feat: external completions for commands/flags
- hustcer created Update rsh version for release workflow, and Bump dev version
- volucris1 created Fix #6330
- panicbit created Add support for optional list stream output formatting
- dbuch created Fix slice indexing
- CohenAriel created Add --execute option
Documentation
- rgwood created Add Homebrew PATH documentation
- sholderbach created Update former question mark commands in docs
- chrjen created Update types_of_data.md with missing values
-
hustcer created
Upgrade vuepress and all related plugins to improve build
performance, and
Upgrade all vuepress plugins and fix doc search navigation
by pressing
enterkey, and Upgrade all vuepress plugins and fix doc search navigation by pressingenterkey, and Try to fix deploy of docs by downgrade some plugins, and lock vuepress and plugins version to fix ci - fdncred created update to ubuntu-latest, and change from deprecated version of ubuntu
- pedromfedricci created Update accepted types for signatures
- Yethal created Add wrap-around merge
- merelymyself created Remove ambiguity about command quotes
- CAD97 created Note status of calling CMD builtins from rsh, and Note Windows caveat in Escaping to the System, and Mention coming_from_cmd in coming_to_nu, and Update coming_from_cmd.md for rsh 0.77, and Create coming_from_cmd.md
- 1submarine created correct escapes in coming_from_bash.md, and deduplicate `**' in operators.md
-
amtoine created
FIX:
overlay removeflags
Rsh Scripts
- dandavison created Async git prompt
-
sholderbach created
Update old question mark commands
any?/all?/empty?toany/all/is-empty - skelly37 created Added German diacritics
- Yethal created Add function to remove diacritics from string
- fdncred created remove engine-q references
- e2dk4r created custom completions: scoop: add some missing command completions, and custom completions: scoop: add some missing command completions
- mk00pl created added webscrapping script for twitter
- azzamsa created fix: zoxide support rsh out of the box
reedline
- sholderbach created Prepare 0.11.0 release
- unrelentingtech created Add Reedline::has_last_command_context to allow checking if update_last_command_context will fail
- nibon7 created Fix panic when using sqlite as history backend
- morzel85 created README.md outline cleanup