Artboard 16light, inspiration, solution, idea, innovation,Google Sheets iconSwift icon
Published at
Updated at
Reading time
2min

If you're working on multiple projects, you know that there are countless ways to run a project. The project might bet on npm run commands; others are a mix of make commands, and the "best ones" rely on cryptic variables or flags being set.

Today I found Nate Meyers' jog GitHub project, and it makes navigating all these projects with different commands so much easier.

jog allows accessing commands from your history filtered by the current working directory. 😲 That's a beautiful idea!

The project doesn't come with an automated setup and boils down to two shell functions.

# write all commands and the directory they've been run in to `.zsh_history_ext`
function zshaddhistory() {
  echo "${1%%$'\n'}${PWD}   " >> ~/.zsh_history_ext
}

# filter commands by the current working directory
function jog() {
  grep -v "jog" ~/.zsh_history_ext | grep -a --color=never "${PWD}   " | cut -f1 -d"⋮" | tail
}

zshaddhistory is a shell hook that runs before anything is written to the default history file (~/.zsh_history). You can leverage this hook to create another history file that includes the ran command but also the directory it was used in.

The jog command then filters all entries and presents the ones run in the current working directory.

That's great and all, but I went on and tweaked things a little bit.

An interactive directory history

I adjusted the jog functions and added/changed the following:

  • rename jog to lc ("last commands" – way better!)
  • store entries in ~/.lc_history
  • filter useless history entries (ls, git, cd, etc.)
  • bring in fzf for some nice interactivity

Be warned; I'm not a shell expert, but my "try and error script" below works. (I'm up for improvements, though!)

# things for the `lc` command
LC_DELIMITER_START="⋮";
LC_DELIMITER_END="⭐";

# write current command location to `.zsh_history_ext` whenever a command is ran
# `.zsh_history_ext` is used in `lc` command
function zshaddhistory() {
  # ignore empty commands
  if [[ $1 == $'\n' ]]; then return; fi

  # ignore specific commands
  local COMMANDS_TO_IGNORE=( ls ll cd j git gss gap lc ggpush ggpull);
  for i in "${COMMANDS_TO_IGNORE[@]}"
  do
    if [[ $1 == "$i"* ]]; then
      return;
    fi
  done

  echo "${1%%$'\n'}${LC_DELIMITER_START}${PWD}${LC_DELIMITER_END}" >> ~/.lc_history
}

# `lc` – last command
function lc() {
  SELECTED_COMMAND=$(grep -a --color=never "${PWD}${LC_DELIMITER_END}" ~/.lc_history | cut -f1 -d "${LC_DELIMITER_START}" | tail -r | fzf);

  # handle case of selecting no command via fzf
  if [[ ${#SELECTED_COMMAND} -gt 0 ]]; then
    echo "Running '$SELECTED_COMMAND'..."
    echo "**************************"
    eval " $SELECTED_COMMAND";
  fi
}

Before you copy the snippet above, make sure to have a look at my .zshrc file to see the most recent implementation. I'll continue tweaking it.

And with that, have fun!

Related Topics

Related Articles