Skip to content

Latest commit

 

History

History
273 lines (207 loc) · 14 KB

File metadata and controls

273 lines (207 loc) · 14 KB

DEVLOG

Development-related notes, not really a CHANGELOG.

Motivation & Goals

The goal of this project is to deepen my understanding of shell scripting, specifically Bash and Zsh, by building something useful. While I recognize there are excellent existing solutions for directory navigation, this project serves as a creative opportunity to experiment and learn.

Maybe I'll get around to learning POSIX-compliant scripting for portability later.

Table of Contents

April 2025

[2025-04-17]

  • Features: _UP_EXCLUDED_PATHS environment variable that defines an array of exact paths to exclude from history log.
  • Other: Feature complete, minus minor changes such as adding _UP_PAGER environment variable.

[2025-04-14]

  • Refactoring: Changed sub-function names from up:: and _up:: to _up:: and __up:: to obscure from Bash completion. _up:: denotes sub-functions for up and __up:: for _up tab completion.
  • Changes:
    • Hiding sub-functions from Zsh autocompletion with `zstyle ':completion:' ignored-patterns '_up::|__up::*'. Could not figure out how to do the same with Bash.
    • Skipping tab completion for most flags such as -h, -f, --list-hist, etc.
  • Features: Added verbose mode output to -c/--clear to display and confirm history removal. Note: The verbose flag must be passed before the clear flag for this to work, e.g., up -vc 1d.

[2025-04-13]

  • Fixes:
    • Tab completion properly escapes multiple whitespace characters in a row, e.g., a dir_name 2 spaces should be a\ dir_name\ \2\ spaces/. Directory names with more than one space were collapsed.
    • Properly handle paths with multiple whitespace characters in a row for -m/--fzf-freq, -F/--fzf-hist, and -R/--fzf-recent flags, i.e., options using fzf. Paths with spaces were not being shown; mostly incorrect awk invocations.
  • Changes:
    • Added header and history line numbers of removed paths for verbose mode output with the -p/--prune flag.
    • Generalized up::pluralize_dir to up::pluralize; moved from up.bash to up_lib/up_utils.bash.

[2025-04-12]

  • Fixes:
    • Changed awk '{print $3}' "$LOG_FILE" to awk '{print substr($0, index($0, $3))}' in up::print_paths_by_frequency and up::filter_most_frequent_paths within up_history.bash. {print $3} truncates path names with whitespace.
    • Changed awk '{print $3 " " $4 " " $5}') to cut -d' ' -f3- to avoid truncating path names with whitespace in up::jump_from_history within up_history.bash.
  • Documentation: Fixed improperly escaped characters of examples of fzf options in man page.
  • Features: Added verbose mode output to -p/--prune showing removed paths. Note: The verbose flag must be passed before the prune flag for this to work, e.g. up -vp.

[2025-04-11]

  • Documentation:
    • Added dynamic check for config file in -h / --help output.
    • Fixed minor errors in man page.

[2025-04-10]

  • Fixes: Parsing comments in arrays (up::load_config_file).

[2025-04-09]

  • Fixes: Updated all instances of cd in up.bash and up_lib/up_history.bash to use cd --, ensuring compatibility with directory names that begin with a hyphen (e.g., -exampleDir). This change is now documented under the EDGE CASES subsection within the EXAMPLES section of the man page.
  • Features: Introduced support for a centralized configuration file to define environment variables in one location.
    • _UP_CONFIG_FILE: A new environment variable allowing users to specify a custom path to the configuration file (default: ~/.config/up/up_settings.conf).
    • To avoid external parsers such as tomlq, the configuration file format defines environment variables using simple key-value pairs, such as:
      _UP_ENVIRONMENT_VARIABLE_NAME=value

[2025-04-08]

  • Changes: Set -i / --ignore-case flag to use standard regex matching (-r) when not combined with other regex flags. It used to require explicit use of other regex flags.
  • Documentation: More additions and refinements to man page.

[2025-04-07]

  • Documentation:
    • Created up.1 man page in groff derived from the --help output and available Markdown.
      • README for man page installation instructions.
      • The simple install_up_man_page.bash script automates installation of the manual.
  • Features: Modified the -c / --clear function to take <integer>(min|h|d|m) argument.

[2025-04-06]

  • Refactoring: Modularized pagination code from up::show_history into up::run_with_pagination.
  • Features:
    • L / --list-freq flags display the history sorted by frequency of paths visited.
    • m / --fzf-freq opens fzf with the most frequently visited list, sorted by most to least visited; only displays existing paths.

[2025-04-05]

  • Refactoring: Path history functions only sourced when _UP_ENABLE_HIST=true. up.bash history flags displays message when using and logging disabled.

[2025-04-04]

  • Features: Added -R, --fzf-recent to open fzf for recent paths by <integer>[min|h|d|m] for timeframes representing hours, days, and months.
  • Documentation:
    • Updated -h / --help text by organizing flags by sections "PWD Navigation" and "Path History Management".

[2025-04-02]

  • Refactoring:
    • Modularized monolithic up.bash into multiple files (1200+ raw lines).
      • up_lib/up_environment_vars.bash: Definitions of constants defined by environment variables, etc.
      • up_lib/up_wrappers.bash: Definitions of wrapper functions such as ph and up_passthru.
      • up_lib/up_history.bash: Definitions of path history functions.
      • up_lib/up_utils.bash: Definitions of miscellanous helper functions.
    • Moved bats test files into tests/ directory.
    • Linting: Turned on Bash LSP support for Neovim by using bash-language-server and shellcheck; fixing basic mistakes and closing most warnings, e.g., missing quotes, etc.
  • Changes: Added checks for ustat and gstat for fzf options defaults; the macOS BSD version of stat is harder to visually parse.
  • Features: Added -p / --prune-hist to remove dead paths in history file.

[2025-04-01]

  • Fixes: Flag processing behavior for up and ph on arbitrary combinations of flag ordering. Issues around flags that should not immediately return an exit value such as fzf-related commands.
  • Documentation: Added programmatic vhs animated demo source code at assets/up_vhs_demo.tape; the file is asset/up_vhs_demo_animation.gif.
  • Changes: Dynamically check for eza installation for use with fzf; default to ls and tree when not available.

March 2025

Regular commits to main branch.

[2025-03-31]

  • Fixes: Verbose flag handling for wrapper function ph -v.
  • Refactoring: Minor changes to up-completion.bash.
  • Documentation:
    • Added ph -help screenshot to README.md.
    • Moved contributing section in README.md to CONTRIBUTING.md.

[2025-03-30]

  • Features:
    • History features must be enabled by setting export _UP_ENABLE_HIST=true in shell config.
      • Display message when history-related flags used and history not enabled.
    • Added -H / --hist-status flags to check whether history logging is on/off.
  • Changes: up::filter_history_with_fzf omits missing/deleted paths; only valid paths listed by fzf.

[2025-03-29]

  • Documentation: Fixed typos and inaccuracies.
  • Fixes: Added rudimentary file locking code for writing path history; possible race conditions on multiple shell instances.
  • Refactor:
    • up::construct_dotted_path:
      • Swapped for loop to printf "../%.0s" $(seq 1 "$jump_index").
      • Check to see if the passed index value is not larger than possible for PWD.
    • if $verbose_mode; ... -> if [[ "$verbose_mode" == true ]] ... for Boolean checks (best practice).
  • Features:
    • Added up::filter_ancestors_with_fzf (-f / --fzf) to jump to ancestor paths within PWD only.
    • _UP_FZF_HISTOPTS: Environment variable for setting fzf options for path history.
    • _UP_FZF_PWDOPTS: Environment variable for setting fzf options for PWD.
  • Changes: up::filter_history_with_fzf now uses -F / --fzf-hist flags.

[2025-03-28]

  • Features:
    • ph (path history): Added convenience function for printing and jumping history log.
    • Added up::print_history_size to show current size/percent in history log.
    • Added fzf preview toggle for -f / --fzf, ^P to toggle; PGDN/PGUP in preview window ^J / ^K.
  • Documentation:
    • Help -h / --help flags display information for ph, up_passthru
    • More general verbiage polishing in help output.
    • Moved TODOs and Known Issues sections to this DEVLOG.md file.
    • Updated help screenshot.
  • Fixes: return statements now returning numeric values, forgot to prefix variables with $—this is not C! 🙈

[2025-03-27]

  • Documentation:
    • Corrected directory terminology within the project; removed words "subdirectory" and "subdirectories".
      • The proper terminology is "parent", "ancestor", and "directory".
    • Added examples section for up --help output; simplified usage section.
  • Changes: Updated tab completion script to check for sed access, along with some minor refactoring.
    • Now using the previous character-escaping code as a fallback. However, this code will only properly escape ASCII directory names, losing Unicode support.
  • Refactor: Using local -r where possible for immutable variables.
  • Features: Started writing code for history log file. New flags and environment variables:
    • -l / --list-hist: List the content of history log file.
    • -j / --jump-hist: Jump to path in history by most recent index, i.e, 1 is the previous, etc.
    • -f / --fzf: Supports fuzzy search if user has fzf installed; drop down menu appears below command prompt.
    • -c / --clear: Clears all history in log file.
    • _UP_HISTFILE: Environment variable for the path of the history log file, default: ~/.cache/up_history.zsh`
    • _UP_HISTSIZE: Environment variable for the maximum number of history entries, i.e., the number of lines in the log file.
    • up_passthru: Function to use with aliases to track directory changes universally in the shell.
      • alias cd='up_passthru cd' for shell buitin cd support.
      • alias z='up_passthru z' for zoxide support.
  • Fixes: Removed return from up::num_of_dirs_changed; now a call to "return" echo instead.
    • return only handles unsigned 8-bit integers.

[2025-03-26]

  • Features: Added support for regular expressions. Need to add tests.
    • Added -r / --regex, -s / --starts-with, -e / --ends-with, and -i / --ignore-case flags.
  • Features: Added _UP_REGEX_STYLE, _UP_REGEX_DEFAULT, _UP_ALWAY_IGNORE_CASE environment varibles for regex support.
  • Changes: Removed naked (non-tack) flags. All flags must have one or two dashes.

[2025-03-23]

  • Committed initial version of project to GitHub.

🐞 Known Issues

There may be skill-related limitations: I’m not a Bash scripting expert.

  • No color support for tab completion list
    • I could not get Zsh to use LS_COLORS via zstyle settings.
  • Tab completion list not in order of PWD
    • There’s no guarantee of the completion list order.

✅ TODOs and 💡Future Ideas

TODOs

March 2025

  • Add pager environment variable.
  • Clean and refactor up.bash to make it more readable and maintainable.
  • Add bats tests for up.bash related to:
    • Regex flags
    • History tracking and navigation
  • Add more styling examples in README.md, e.g., Dracula, gruvbox.

Ideas

March 2025

  • Write a fish-compatible version.
    • I'm not using fish as my primary shell.
  • Write a binary version of up.bash in a language like Go or Rust for universal shell compatibility. (Better idea than this script?)
    • Only completion scripts for target shells would need to be created.
  • History session management.
  • Bookmarking paths.

🍿Credits

Thanks to the original script writers and public shell configs!

Originally, I used Derek Taylor's up function unmodified within his .zshrc:

up () {
  local d=""
  local limit="$1"

  # Default to limit of 1
  if [ -z "$limit" ] || [ "$limit" -le 0 ]; then
    limit=1
  fi

  for ((i=1;i<=limit;i++)); do
    d="../$d"
  done

  # perform cd. Show error if cd fails
  if ! cd "$d"; then
    echo "Couldn't go up $limit dirs.";
  fi
}

This minimalist function works well for navigating up by the number of directories.

I later found this simple up Bash script to navigate by directory name, complete with tab completion and bats scripts.

up() {
  (($# == 0)) && cd .. && return
  [[ $1 == / ]] && cd / && return

  # shellcheck disable=SC2164
  cd "${PWD%"${PWD##*/"$1"/}"}"
}

My modifications are a result of combining the functionalities of these two up functions.

Instead of writing ANSI escape codes manually, use this simple list of 15 colors and a reset value in your shell config.