ion issueshttps://gitlab.redox-os.org/redox-os/ion/-/issues2023-04-26T19:04:04Zhttps://gitlab.redox-os.org/redox-os/ion/-/issues/1005Implement set -o pipefail2023-04-26T19:04:04ZAndrey BienkowskiImplement set -o pipefailfeat: I want `set -o pipefail`. #272 asked for both `errexit` and `pipefail`, but so far only `errexit` is implemented.
BREAKING CHANGE: it is possible to add `pipefail` without breaking existing scripts by defaulting it to off. In the ...feat: I want `set -o pipefail`. #272 asked for both `errexit` and `pipefail`, but so far only `errexit` is implemented.
BREAKING CHANGE: it is possible to add `pipefail` without breaking existing scripts by defaulting it to off. In the perfect world both `errexit` and `pipefail` would have been always on without any way to disable them (just like in all programming languages that have exceptions except for Visual Basic), but that might break existing scripts.
perf: impact
performance none
usability increase
maintainability increase
code: input
```
set -eo pipefail
echo 1
false | true
echo 2
```
expect: output
```
1
```
reason: I want my script to fail fast by default if an external command fails.
context:
Executing an external command can fail for a million different reasons. Here are some examples:
1. The external command is not installed
2. It encounters an internal bug and [fails fast and loud](https://en.wikipedia.org/wiki/Fail-fast)
3. It receives bad input due to a bug in my script
4. An admin kills it
5. The OOM Killer kills it https://linuxwheel.com/oom-killer-explained/
6. It tries to talk to another process possibly on a different machine and that fails for any reason
7. It uses a temporary file for internal buffering and /tmp is full
8. It tries to read or write a file and that fails for any reason
A robust script can not afford to ignore the possibility that any of the external commands it executes may fail. Often the right choice of action is to fail fast because the code that follows requires that the preceding commands executed successfully.
Unix-y pipelines have an issue:
```sh
foo | bar
```
If `foo` exits successfully `bar` sees EOF. If `foo` fails `bar` also sees EOF. `bar` has no way to know whether `foo` failed or not. In many cases `bar` will exit successfully even if `foo` fails. The script has to detect that and fail. This is why you often see `set -o errexit -o pipefail` in bash.
Unfortunately `set -o errexit` is [very broken](https://mywiki.wooledge.org/BashFAQ/105) in bash which is why I'm looking for a different shell.
<!--behavior of bash/dash/zsh/fish/oil-->https://gitlab.redox-os.org/redox-os/ion/-/issues/805Easy substring removal2023-03-10T13:53:44ZColeman McFarlandEasy substring removalI want to use ion to parse a config that looks like this, where the unique name given before the underscore `_`
is treated as part of a set.
```sh
HOST1_USERFILE=cloud-config/one.yml
HOST1_OS=ubuntu_18_04
HOST1_FACILITY=sjc1
HOST2_USE...I want to use ion to parse a config that looks like this, where the unique name given before the underscore `_`
is treated as part of a set.
```sh
HOST1_USERFILE=cloud-config/one.yml
HOST1_OS=ubuntu_18_04
HOST1_FACILITY=sjc1
HOST2_USERFILE=cloud-config/two.yml
HOST2_OS=ubuntu_18_04
HOST2_FACILITY=sjc1
```
I am using hashmap as a set. The following doesn't _quite_ work, because the "" empty string is not treated as an argument to `@replace`.
```
let hosts:hmap[] = [ ]
let name = $replace("HOST1_USERFILE", "_USERFILE" "")
let hosts[$name] = $name
```
I could do use a space instead of empty string:
```
let name = $replace("HOST1_USERFILE", "_USERFILE" " ") # a space, inst
```
... but the space is preserved in the value of `$name`.
I could use trim #802 when it lands, but a dedicated substring removal method might be nice.Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/834Cannot write functions with variable argument count2023-01-31T05:35:01ZZach ButtonCannot write functions with variable argument countIt appears to only be possible to define functions with a fixed number of arguments.
Perhaps the simplest solution would be some basic polymorphism. Example:
```shell
fn doStuff a b
echo a: $a, b: $b
end
fn doStuff a
doStuff $a "not...It appears to only be possible to define functions with a fixed number of arguments.
Perhaps the simplest solution would be some basic polymorphism. Example:
```shell
fn doStuff a b
echo a: $a, b: $b
end
fn doStuff a
doStuff $a "not_specified"
end
doStuff "test"
# "a: test, b: not_specified"
```
Or, perhaps cleaner, argument expansion:
```shell
fn printSection label ...list
echo -e "\n\n$label:"
for item in @list
echo "- $item"
end
end
printSection todo "type foo" "make bar"
# todo:
# - type foo
# - make bar
```unplannedhttps://gitlab.redox-os.org/redox-os/ion/-/issues/981Add HISTTIMEFORMAT variable to allow custom history date formatting2021-11-25T17:32:58ZPerry ThompsonAdd HISTTIMEFORMAT variable to allow custom history date formattingIt would be nice to have some sort of way to use the timestamps saved by HISTORY_TIMESTAMP. In Bash, I use `HISTTIMEFORMAT='%F %T '` and that gives a nicely formatted history with timestamp, like:
188296 2020-10-17 18:42:47 vim ....It would be nice to have some sort of way to use the timestamps saved by HISTORY_TIMESTAMP. In Bash, I use `HISTTIMEFORMAT='%F %T '` and that gives a nicely formatted history with timestamp, like:
188296 2020-10-17 18:42:47 vim .config/ion/initrc
188297 2020-10-17 18:50:26 historyunplannedhttps://gitlab.redox-os.org/redox-os/ion/-/issues/910Nicer error messages2021-07-18T05:53:40ZDiego GanglNicer error messagesRight now, Ion throws error messages like this:
```ion: pipeline execution error: command exec error: Permission denied (os error 13)```
While they are correct and tell you what the problem is, they could be more polished like rustc's e...Right now, Ion throws error messages like this:
```ion: pipeline execution error: command exec error: Permission denied (os error 13)```
While they are correct and tell you what the problem is, they could be more polished like rustc's errors (I'm only talking about the interactive prompt in this case).
### No permissions
```
You don't have permission to open [FILE]. The owner is [USER].
Permissions are: rw--x---
```
### Executables that can't be run
If it doesn't have any exec permissions:
```
Can't run [FILE]. It's not an executable.
Try running chmod +x [FILE].
```
If it has one, but we can't run it:
```
[FILE] is an executable but you don't have permission to run it.
The owner is [USER]. Permissions are: rwx-w---
Try running chmod +x [FILE].
```
### Command not found
```Command not found: pyothn. Did you mean "python"?```
If the command ends with a forward slash, it's a path not a command. The error should be more like:
```Directory not found```Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/1003Add quiet flag to math command2021-06-17T13:47:39ZDavid PurdumAdd quiet flag to math commandfeat: For some automation tasks it would be nice to enter the interactive math mode without any welcome text. For this we could use a -q/--quiet flag to silence this (similar to R).
current
```
me:~# math
Ion's integrated calculator
Ty...feat: For some automation tasks it would be nice to enter the interactive math mode without any welcome text. For this we could use a -q/--quiet flag to silence this (similar to R).
current
```
me:~# math
Ion's integrated calculator
Type in expressions to have them evaluated.
Type "help" for help.
ion-math:
```
change
```
me:~# math -q
ion-math:
```https://gitlab.redox-os.org/redox-os/ion/-/issues/929cdpath (cd/autocomplete to specified directories from anywhere)2021-06-03T10:25:35Zunrelentingtechcdpath (cd/autocomplete to specified directories from anywhere)In zsh, you can set e.g. `cdpath=(~/src/github.com/myfreeweb)` and then from any directory you can type `dotfiles` to cd to `~/src/github.com/myfreeweb/dotfiles`, and autocompletion would offer these directories (subdirectories of anythi...In zsh, you can set e.g. `cdpath=(~/src/github.com/myfreeweb)` and then from any directory you can type `dotfiles` to cd to `~/src/github.com/myfreeweb/dotfiles`, and autocompletion would offer these directories (subdirectories of anything on `cdpath`) anywhere too.unplannedhttps://gitlab.redox-os.org/redox-os/ion/-/issues/582Improve status Builtin2021-06-01T12:47:38ZMichael Aaron Murphymmstick@pm.meImprove status BuiltinStatus: https://fishshell.com/docs/current/commands.html#status
Might be useful to have similar feature-parity within the Ion shell.Status: https://fishshell.com/docs/current/commands.html#status
Might be useful to have similar feature-parity within the Ion shell.unplannedhttps://gitlab.redox-os.org/redox-os/ion/-/issues/418prompt: Syntax Highlighting in Prompt2021-06-01T12:33:57ZMichael Aaron Murphymmstick@pm.meprompt: Syntax Highlighting in PromptWill require some seirous modifications to [liner](https://github.com/MovingtoMars/liner) in order to get this to work. I'm insure of the best approach for implementing this feature at the moment. Regex or a parsing crate may be ideal. S...Will require some seirous modifications to [liner](https://github.com/MovingtoMars/liner) in order to get this to work. I'm insure of the best approach for implementing this feature at the moment. Regex or a parsing crate may be ideal. Solution needs to focus on performance though. The following needs to occur:
- [ ] Color the command based on if the command exists or not
- [ ] Single quoted text should have a different color from double quoted text
- [ ] Operators should have their own unique colors
- [ ] Specific keywords should be highlighted, such as `end` and `if`
- [ ] Variables should also be highlighted
- [ ] Arrays should have a different color than variables
- [ ] Functions and aliases may also have different colors
- [ ] The coloring should be user-configurable and ideally match the grammar usage (in treesitter)Ion Shell v1.0.0Sag0Sag0Sag0Sag0https://gitlab.redox-os.org/redox-os/ion/-/issues/803Methods for hmap and bmap handling2021-06-01T12:30:15ZRoland KovácsMethods for hmap and bmap handlingAdd support for getting keys or key-value pairs from maps, as currently only values can be extracted.
```
@keys(map)
@entries(map)
```Add support for getting keys or key-value pairs from maps, as currently only values can be extracted.
```
@keys(map)
@entries(map)
```Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/531Create a JobSplitter to Increase Flexibility of Statement Parsing2021-06-01T11:38:10ZMichael Aaron Murphymmstick@pm.meCreate a JobSplitter to Increase Flexibility of Statement ParsingWe are currently limited when processing commands like the following:
```
true && let a = 5
```
What happens is that the entire pipeline is considered as a command, and each job in the pipeline is executed as a command. Let is not a co...We are currently limited when processing commands like the following:
```
true && let a = 5
```
What happens is that the entire pipeline is considered as a command, and each job in the pipeline is executed as a command. Let is not a command though, so this will fail. This would require some more advanced restructuring, though, so it won't be easy. We'd have to add a job splitter to split statements into jobs, and make a number of possible changes within pipeline execution to account for jobs possibly being keywords.unplannedhttps://gitlab.redox-os.org/redox-os/ion/-/issues/508Ideas on Plugins and Security2021-06-01T11:37:18ZMichael Aaron Murphymmstick@pm.meIdeas on Plugins and SecurityWe should probably have a `ION_PLUGINS_ENABLED` variable that is set to 1 by default, but can be set to 0 to disable support for plugins. In addition, maybe we could also implement an optional `ION_PLUGINS_METHOD_WHITELIST` and `ION_PLUG...We should probably have a `ION_PLUGINS_ENABLED` variable that is set to 1 by default, but can be set to 0 to disable support for plugins. In addition, maybe we could also implement an optional `ION_PLUGINS_METHOD_WHITELIST` and `ION_PLUGINS_NAMESPACE_WHITELIST` array which can be used to designate plugins that are explicitly allowed to execute. Then maybe we could have a means of protecting certain variables from being set within scripts, or even only allowing certain variables to be set from an environment file. Suggestions welcome for ways to make Ion more secure.Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/409Tracking Issue: List of Builtins to Implement2021-06-01T11:16:08ZMichael Aaron Murphymmstick@pm.meTracking Issue: List of Builtins to ImplementIf you have an idea for a builtin which is not on this list, discuss it below.
# Conditional Builtins
- [x] `true`: Simply returns a `SUCCESS` status
- [x] `false`: Simply returns a `FAILED` status
- [x] `not <command>`: Reverses the ex...If you have an idea for a builtin which is not on this list, discuss it below.
# Conditional Builtins
- [x] `true`: Simply returns a `SUCCESS` status
- [x] `false`: Simply returns a `FAILED` status
- [x] `not <command>`: Reverses the exit status value of the given command. (@drosseau)
- [x] `contains $key @values`: Returns 0 exit status if the key is contained within the values.
- [x] `starts-with $key @values`
- [x] `ends-with $key @values`
- [x] `matches $key $regex`: A regex-based evaluator
- [ ] `isatty [FD]`: Returns 0 exit status if the supplied FD is a tty
- [x] `and <command>`: Execute the command only if the shell's previous status is 0
- `true; and echo true`
- [x] `or <command>`: The reverse of `and`.
- `false; or echo false`
- [x] `exists -b BINARY`: Returns 0 exit status if the binary is in PATH
- [x] `exists -f PATH`: Returns 0 exit status if the path is a file
- [x] `exists -d PATH`: Returns 0 exit status if the path is a directory
- [x] `exists -s STRING`: Returns 0 exit status if the string var is not empty
- [x] `exists -a ARRAY`: Returns 0 exit status if the array var is not empty
- [x] `exists STRING`: Returns 0 exit status if the string is not empty
- [ ] `is $var $value`: Returns 0 exit status if both arguments are the same
- [ ] `is not $var $value`: The opposite of the above
- [ ] `bool $value`: If the value is "1" or "true", return 0 exit status
- [ ] < (Polish Notation)
- [ ] <= (Polish Notation)
- [ ] > (Polish Notation)
- [ ] >= (Polish Notation)
- [ ] = (Polish Notation)
# Job Control
- [x] `jobs`: Lists available background jobs
- [x] `bg`: Sends **SIGCONT** to a given background job
- [x] `fg`: Does the same as `bg`, but also brings it to the foreground via `tcsetpgrp`
- [x] `wait`: waits until background jobs have finished
- [x] `exit`: waits until background jobs have finished, and exits
- [x] `suspend`: suspends the shell via a `SIGTSTOP`
# Misc
- [x] `ion-docs`: Opens the locally-installed Ion documentation in a web browser
- [x] `which`: Prints the kind and/or path of the given command
# Math & Crypto
- [x] `calc`: built-in calculator that will eventually be arbitrary precision
- [ ] `random`: generate random numbers
# I/O
- [x] `echo`: Prints the evaluated expression to standard output
- [x] `read`: Stores the next line of input to standard input into a specified variable
- [ ] `printf`: Implement the same as other shells
- [ ] `printr`: Rusty variant maybe?
- [ ] `cat`: Perhaps copy `cat` from coreutils into Ion.
# Command Execution
- [x] `eval`: Evaluates and executes the evaluated expression
- [x] `time`: Prints timing statistics once it's job has finished
- [ ] `exec`: Replace the shell process with the specified command
# Possible Builtins From POSIX Shells
- [ ] `command -v`: often used to determine if a binary exists in a PATHIon Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/441Tracking Issue: List of Methods in Ion2021-06-01T11:15:56ZMichael Aaron Murphymmstick@pm.meTracking Issue: List of Methods in Ion# String Methods
String methods return strings
- [x] $len(string) -> n string
- [x] $len(array) -> n string (@mmstick)
- [x] $len_bytes(string) -> n string
- [x] $join(array) -> string
- [x] $find(string, string) -> n string
- [x] $sta...# String Methods
String methods return strings
- [x] $len(string) -> n string
- [x] $len(array) -> n string (@mmstick)
- [x] $len_bytes(string) -> n string
- [x] $join(array) -> string
- [x] $find(string, string) -> n string
- [x] $starts_with(string, string) -> 0/1 string (@mmstick)
- [x] $ends_with(string, string) -> 0/1 string (@mmstick)
- [x] $contains(string, string) -> 0/1 string (@mmstick)
- [x] $replace(string, string) -> string (@mmstick)
- [x] $replacen(string, string) -> string (@mmstick)
- [x] $to_lowercase(string) -> string (@pithonsmear)
- [x] $to_uppercase(string) -> string (@pithonsmear)
- [x] $repeat(string, n) -> string (@mmstick)
- [x] $extension(filepath) -> string (@pithonsmear)
- [x] $basename(filepath) -> string (@pithonsmear)
- [x] $parent(filepath) -> string (@pithonsmear)
- [x] $filename(filepath) -> string (@pithonsmear)
- [ ] $or(string, expr) -> string
- If the given string does not exist, use the given expression
- [x] $reverse(string) -> string (@pithonsmear)
- [ ] $fold(array, string) -> string
- Apply a reduce/fold function to an array
- The supplied string should name a command to apply to the array
- [ ] $open(string) -> string
- Open a file and buffer the entire file into memory
- [x] $regex_replace(string, string)
- Same as $replace(), but the pattern is a regex expression
# Array Methods
Array methods return arrays
- [x] @split(string, opt<string>) -> array
- [x] @bytes(string) -> array
- [x] @chars(string) -> array
- [x] @graphemes(string) -> array
- [x] @reverse(array) -> array
- [x] @lines(string) -> array
- Split a given string by newlines
- [ ] @filter(array, string) -> array
- Apply a filter command to each element in the array
- Exit status determines which values to filter
- `@filter(array, x => matches $x '([F])\w+')`
- [ ] @map(array, string) -> array
- Apply a command to each element in the array
- Output of the command is the new value for that index
- `@map(array, x => calc $x + $x)`
- [ ] @open(array, opt<string>) -> array
- If no pattern string is supplied, split the file by newlines
- [x] @split_at(string, n) -> [string, string]
- Splits a string into a two-element array; Rust's std
- [ ] @split_args(string)
- Provides an interface for the `ArgumentSplitter` functionality in the shell.Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/397shellac: Application-Specific Tab Completions2021-06-01T11:05:12ZMichael Aaron Murphymmstick@pm.meshellac: Application-Specific Tab Completions*Created by: xTibor*
The `sudo` command should have command completions. At the moment the tab completions suggests files and directories for this command.
**Build information**:
`git rev-parse HEAD`: eb13ba645bad3b311843f38f84455ce3a5...*Created by: xTibor*
The `sudo` command should have command completions. At the moment the tab completions suggests files and directories for this command.
**Build information**:
`git rev-parse HEAD`: eb13ba645bad3b311843f38f84455ce3a53fdb8d
`rustc -V`: rustc 1.20.0-nightly (720c596ec 2017-07-08)Ion Shell v1.0.0BafDyceBafDycehttps://gitlab.redox-os.org/redox-os/ion/-/issues/336Builtin: Array Arithmetic Expressions2021-06-01T11:04:02ZMichael Aaron Murphymmstick@pm.meBuiltin: Array Arithmetic ExpressionsNow that we have support for string-based arithmetic, perhaps we might want to also implement array-based arithmetic? This issue will discuss possible syntax ideas that we could pursue.
# Proposal # 1
This approach is commonly used in ...Now that we have support for string-based arithmetic, perhaps we might want to also implement array-based arithmetic? This issue will discuss possible syntax ideas that we could pursue.
# Proposal # 1
This approach is commonly used in functional languages, so it might also be a natural fit here. Define a variable name to describe each element in the array, and then follow it with a mathematical expression to apply with each element in the array.
```ion
@[ELEMENT -> EXPR, ARRAY EXPR]
```
## Examples
### Example # 1
```ion
let array = [1 2 3]
for result in @[x -> x * x, array]
echo $result
end
```
### Output # 1
```ion
1
4
9
```
### Example # 2
```ion
let array = [1 2 3]
let value = 3
for result in @[x -> x * value, array]
echo $result
end
```
### Output # 2
```ion
3
6
9
```unplannedhttps://gitlab.redox-os.org/redox-os/ion/-/issues/247Implement `mapfile` as builtin2021-06-01T10:54:12ZMichael Aaron Murphymmstick@pm.meImplement `mapfile` as builtinUnlike associated arrays, these should be stored in vectors, and empty lines should be skipped.
See here how it works: https://origin.geeksforgeeks.org/mapfile-command-in-linux-with-examples/Unlike associated arrays, these should be stored in vectors, and empty lines should be skipped.
See here how it works: https://origin.geeksforgeeks.org/mapfile-command-in-linux-with-examples/Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/195Add Syntax Highlighting Support for ion2021-06-01T10:51:43ZMichael Aaron Murphymmstick@pm.meAdd Syntax Highlighting Support for ionThe editor-independent solution to go for is treesitter.
While the script sizes will not require incremental parsing, treesitter is a C program and thus widely portable and supported.
The bits that are missing so far are only making fu...The editor-independent solution to go for is treesitter.
While the script sizes will not require incremental parsing, treesitter is a C program and thus widely portable and supported.
The bits that are missing so far are only making functions with arguments and references work.
`amend` will not be part of ion, because globally mutable state is very, very bad and easily to mess up things (besides making ion slower).Ion Shell v1.0.0https://gitlab.redox-os.org/redox-os/ion/-/issues/986setup CI and regression tests for macOS2021-06-01T10:24:06ZRoland Teppsetup CI and regression tests for macOSmacOS: install: illegal option -- D
I was trying to install ion shell on macOS and this is the error I am getting when executing `sudo make install`
```bash
❯ sudo make install prefix=/usr
install -Dm0755 target/release/ion //usr/bin/i...macOS: install: illegal option -- D
I was trying to install ion shell on macOS and this is the error I am getting when executing `sudo make install`
```bash
❯ sudo make install prefix=/usr
install -Dm0755 target/release/ion //usr/bin/ion
install: illegal option -- D
usage: install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]
[-o owner] file1 file2
install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]
[-o owner] file1 ... fileN directory
install -d [-v] [-g group] [-m mode] [-o owner] directory ...
make: *** [install] Error 64
```
Google search suggests that -D option does not exist under macOS/Darwin and suggests using -d instead, but I am not experienced enough with install utility (or Makefile) to understand the subtle differences of the two and fix it myself.Ion Shell v1.0.0betahttps://gitlab.redox-os.org/redox-os/ion/-/issues/928auto pushd mode (ability to customize try_cd)2021-03-19T16:30:53Zunrelentingtechauto pushd mode (ability to customize try_cd)In zsh, it is possible to `setopt auto_pushd`, which turns ordinary `cd` — including implicit/auto cd (!) — into pushd. Would be very useful to have the ability to pushd when just typing the directory name only in ion.In zsh, it is possible to `setopt auto_pushd`, which turns ordinary `cd` — including implicit/auto cd (!) — into pushd. Would be very useful to have the ability to pushd when just typing the directory name only in ion.