Skip to content

Instantly share code, notes, and snippets.

@jamesonknutson
Created October 2, 2024 03:03
Show Gist options
  • Save jamesonknutson/2f357629e2759ccee8007fbef698a8f1 to your computer and use it in GitHub Desktop.
Save jamesonknutson/2f357629e2759ccee8007fbef698a8f1 to your computer and use it in GitHub Desktop.
# repl-env.nu
# example:
# > let repl_env = repl-env setup-env
# > $env.repl-env = ($repl_env.repl-env | upsert max_length 5)
# > $env.config = $repl_env.config
#
# use the `@` alias to view the last commands output (or use the repl-env get-history command)
#
# $env.repl-env will look like:
# {
# enabled: bool
# ignore: bool
# }
# Gets the `$env.repl-env` record, filling in default values when they do not already exist.
# Prefers the `$env.repl-env` values for each property, when they do exist.
export def --env 'repl-env get-env' [] {
$env.repl-env?
| default {}
| default true enabled # when false, will not store input/output (also restores hook states to their previous mode)
| default false ignore # when true, will not store the next input/output (intended to switch off the recording thing for when you're viewing the repl-env object itself)
| default [] history # table<input: string, output: any>, where the repl output is saved
| default 50 max_length # maximum length of the history table, in case this gets memory intensive (will make it so the history is limited to the X most recent inputs)
| default '' commandline # most recent commandline input, written to by the pre_execution hook, read by the display_output hook to record the commandline input that produced a given output
| default $env.config.hooks.display_output display_output # previous display_output state, used to restore to old values when toggling on/off
| default $env.config.hooks.pre_execution pre_execution # previous pre_execution state, used to restore to old values when toggling on/off
}
# Creates the hooks used by the repl-env module.
export def --env 'repl-env get-hooks' [] {
let display_output = {||
tee {
if ((term size).columns >= 100) { table -e } else { table }
| print $in
} | do --env {
let output = $in
if $env.repl-env.ignore {
$env.repl-env.ignore = false
return
}
if not $env.repl-env.enabled {
return
}
$env.repl-env.history = (
$env.repl-env.history
| prepend [ { input: $env.repl-env.commandline, output: $output } ]
| first $env.repl-env.max_length
)
}
}
let pre_execution = '$env.repl-env.ignore = false; $env.repl-env.commandline = (commandline)'
{
display_output: $display_output
pre_execution: $pre_execution
}
}
def nc-repl-env-size [] {
$env.repl-env?.history?
| default []
| enumerate
| each {|row| { value: $row.index, description: $row.item.input } }
}
# Gets an element from the repl history
export def --env 'repl-env get-history' [
--whole(-w) # Get the entire object, instead of just the output column
--explore(-x) # Explore the object, instead of returning it
--use-offset(-o) = true # Silly hack to allow aliasing and including no `offset` value to make the alias return the first item
offset: int@nc-repl-env-size = 0 # The history index to get, only used if `--use-offset` is true
] {
# Disable repl-env for the next input/output, so we do not record whatever it is that we are accessing now (dedupes history, basically)
$env.repl-env.ignore = true
$env.repl-env.history
| if $whole { $in } else { get output }
| if (($offset | is-not-empty) and ($offset >= 0) and ($use_offset == true)) { $in | get $offset } else { $in }
| if $explore { $in | explore --peek } else { $in }
}
# Clears the repl history
export def --env 'repl-env clear-history' [] {
$env.repl-env.history = []
}
# Toggles the repl module
export def --env 'repl-env toggle' [] {
let hooks = repl-env get-hooks
let pre_execution = try { view source $hooks.pre_execution } | default $hooks.pre_execution
$env.config.hooks.pre_execution = ($env.config.hooks.pre_execution | filter {|item|
(try { view source $item } | default $item) != $pre_execution
})
if $env.repl-env.enabled {
$env.repl-env.enabled = false
# reset the hooks
$env.config.hooks.display_output = $env.repl-env.display_output
print $'[REPL-ENV]: (ansi red)Disabled ❌(ansi reset)'
} else {
$env.repl-env.enabled = true
$env.config.hooks.display_output = $hooks.display_output
$env.config.hooks.pre_execution = ($env.config.hooks.pre_execution | append $hooks.pre_execution)
print $'[REPL-ENV]: (ansi green)Enabled ✅(ansi reset)'
}
}
# Returns the values needed to setup the repl-env module.
# example:
# > let repl_env = repl-env setup-env
# > $env.repl-env = ($repl_env.repl-env | upsert max_length 5)
# > $env.config = $repl_env.config
export def --env 'repl-env setup-env' [
--apply(-a)
] {
let hooks = repl-env get-hooks
let output = {
'config': (
$env.config?
| default {}
| upsert hooks {
default {}
| upsert display_output { $hooks.display_output }
| upsert pre_execution {
default []
| filter {|t| $t != $hooks.pre_execution }
| append [ $hooks.pre_execution ]
}
}
),
'repl-env': (repl-env get-env)
}
$output
}
export alias '@' = repl-env get-history --use-offset=true
export alias '@@' = repl-env get-history (-1) --use-offset=false --explore --whole
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment