forked from extern/nushell
2e01bf9cba
# Description Prototype replacement for `enter`, `n`, `p`, `exit` built-ins implemented as scripts in standard library. MVP-level capabilities (rough hack), for feedback please. Not intended to merge and ship as is. _(Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience.)_ # User-Facing Changes New command in standard library ```nushell 〉use ~/src/rust/nushell/crates/nu-utils/standard_library/dirs.nu ---------------------------------------------- /home/bobhy ---------------------------------------------- 〉help dirs module dirs.nu -- maintain list of remembered directories + navigate them todo: * expand relative to absolute paths (or relative to some prefix?) * what if user does `cd` by hand? Module: dirs Exported commands: add (dirs add), drop, next (dirs next), prev (dirs prev), show (dirs show) This module exports environment. ---------------------------------------------- /home/bobhy ---------------------------------------------- 〉dirs add ~/src/rust/nushell /etc ~/.cargo -------------------------------------- /home/bobhy/src/rust/nushell -------------------------------------- 〉dirs next 2 ------------------------------------------- /home/bobhy/.cargo ------------------------------------------- 〉dirs show ╭───┬─────────┬────────────────────╮ │ # │ current │ path │ ├───┼─────────┼────────────────────┤ │ 0 │ │ /home/bobhy │ │ 1 │ │ ~/src/rust/nushell │ │ 2 │ │ /etc │ │ 3 │ ==> │ ~/.cargo │ ╰───┴─────────┴────────────────────╯ ------------------------------------------- /home/bobhy/.cargo ------------------------------------------- 〉dirs drop ---------------------------------------------- /home/bobhy ---------------------------------------------- 〉dirs show ╭───┬─────────┬────────────────────╮ │ # │ current │ path │ ├───┼─────────┼────────────────────┤ │ 0 │ ==> │ /home/bobhy │ │ 1 │ │ ~/src/rust/nushell │ │ 2 │ │ /etc │ ╰───┴─────────┴────────────────────╯ ---------------------------------------------- /home/bobhy ---------------------------------------------- 〉 ``` # Tests + Formatting Haven't even looked at stdlib `tests.nu` yet. Other todos: * address module todos. * integrate into std lib, rather than as standalone module. Somehow arrange for `use .../standard_library/std.nu` to load this module without having to put all the source in `std.nu`? * Maybe command should be `std dirs ...`? * what else do `enter` and `exit` do that this should do? Then deprecate those commands. Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
84 lines
2.3 KiB
Plaintext
84 lines
2.3 KiB
Plaintext
# Maintain a list of working directories and navigates them
|
|
|
|
# the directory stack
|
|
export-env {
|
|
let-env DIRS_POSITION = 0
|
|
let-env DIRS_LIST = [($env.PWD | path expand)]
|
|
}
|
|
|
|
# Add one or more directories to the list.
|
|
# PWD becomes first of the newly added directories.
|
|
export def-env "add" [
|
|
...paths: string # directory or directories to add to working list
|
|
] {
|
|
mut abspaths = []
|
|
for p in $paths {
|
|
let exp = ($p | path expand)
|
|
if ($exp | path type) != 'dir' {
|
|
let span = (metadata $p).span
|
|
error make {msg: "not a directory", label: {text: "not a directory", start: $span.start, end: $span.end } }
|
|
}
|
|
$abspaths = ($abspaths | append $exp)
|
|
|
|
}
|
|
let-env DIRS_LIST = ($env.DIRS_LIST | insert ($env.DIRS_POSITION + 1) $abspaths | flatten)
|
|
let-env DIRS_POSITION = $env.DIRS_POSITION + 1
|
|
|
|
_fetch 0
|
|
}
|
|
|
|
# Advance to the next directory in the list or wrap to beginning.
|
|
export def-env "next" [
|
|
N:int = 1 # number of positions to move.
|
|
] {
|
|
_fetch $N
|
|
}
|
|
|
|
# Back up to the previous directory or wrap to the end.
|
|
export def-env "prev" [
|
|
N:int = 1 # number of positions to move.
|
|
] {
|
|
_fetch (-1 * $N)
|
|
}
|
|
|
|
# Drop the current directory from the list, if it's not the only one.
|
|
# PWD becomes the next working directory
|
|
export def-env "drop" [] {
|
|
if ($env.DIRS_LIST | length) > 1 {
|
|
let-env DIRS_LIST = (
|
|
($env.DIRS_LIST | take $env.DIRS_POSITION)
|
|
| append ($env.DIRS_LIST | skip ($env.DIRS_POSITION + 1))
|
|
)
|
|
}
|
|
|
|
_fetch 0
|
|
}
|
|
|
|
# Display current working directories.
|
|
export def-env "show" [] {
|
|
mut out = []
|
|
for $p in ($env.DIRS_LIST | enumerate) {
|
|
$out = ($out | append [
|
|
[active, path];
|
|
[($p.index == $env.DIRS_POSITION), $p.item]
|
|
])
|
|
}
|
|
|
|
$out
|
|
}
|
|
|
|
# fetch item helper
|
|
def-env _fetch [
|
|
offset: int, # signed change to position
|
|
] {
|
|
# nushell 'mod' operator is really 'remainder', can return negative values.
|
|
# see: https://stackoverflow.com/questions/13683563/whats-the-difference-between-mod-and-remainder
|
|
let pos = ($env.DIRS_POSITION
|
|
+ $offset
|
|
+ ($env.DIRS_LIST | length)
|
|
) mod ($env.DIRS_LIST | length)
|
|
let-env DIRS_POSITION = $pos
|
|
|
|
cd ($env.DIRS_LIST | get $pos )
|
|
}
|