summaryrefslogtreecommitdiff
path: root/plugins/wd/wd.sh
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/wd/wd.sh')
-rwxr-xr-x[-rw-r--r--]plugins/wd/wd.sh257
1 files changed, 201 insertions, 56 deletions
diff --git a/plugins/wd/wd.sh b/plugins/wd/wd.sh
index 840e92d61..56c029252 100644..100755
--- a/plugins/wd/wd.sh
+++ b/plugins/wd/wd.sh
@@ -1,4 +1,4 @@
-#!/bin/zsh
+#!/usr/bin/env zsh
# WARP DIRECTORY
# ==============
@@ -8,7 +8,7 @@
# @github.com/mfaerevaag/wd
# version
-readonly WD_VERSION=0.5.0
+readonly WD_VERSION=0.10.1
# colors
readonly WD_BLUE="\033[96m"
@@ -57,12 +57,11 @@ wd_print_msg()
{
if [[ -z $wd_quiet_mode ]]
then
- local color=$1
- local msg=$2
+ local color="${1:-$WD_BLUE}" # Default to blue if no color is provided
+ local msg="$2"
- if [[ $color == "" || $msg == "" ]]
- then
- print " ${WD_RED}*${WD_NOC} Could not print message. Sorry!"
+ if [[ -z "$msg" ]]; then
+ print "${WD_RED}*${WD_NOC} Could not print message. Sorry!"
else
print " ${color}*${WD_NOC} ${msg}"
fi
@@ -75,21 +74,23 @@ wd_print_usage()
Usage: wd [command] [point]
Commands:
- <point> Warps to the directory specified by the warp point
- <point> <path> Warps to the directory specified by the warp point with path appended
- add <point> Adds the current working directory to your warp points
- add Adds the current working directory to your warp points with current directory's name
- rm <point> Removes the given warp point
- rm Removes the given warp point with current directory's name
- show <point> Print path to given warp point
- show Print warp points to current directory
- list Print all stored warp points
- ls <point> Show files from given warp point (ls)
- path <point> Show the path to given warp point (pwd)
- clean Remove points warping to nonexistent directories (will prompt unless --force is used)
+ <point> Warps to the directory specified by the warp point
+ <point> <path> Warps to the directory specified by the warp point with path appended
+ add <point> Adds the current working directory to your warp points
+ add Adds the current working directory to your warp points with current directory's name
+ addcd <path> Adds a path to your warp points with the directory's name
+ addcd <path> <point> Adds a path to your warp points with a custom name
+ rm <point> Removes the given warp point
+ rm Removes the given warp point with current directory's name
+ show <point> Print path to given warp point
+ show Print warp points to current directory
+ list Print all stored warp points
+ ls <point> Show files from given warp point (ls)
+ open <point> Open the warp point in the default file explorer (open / xdg-open)
+ path <point> Show the path to given warp point (pwd)
+ clean Remove points warping to nonexistent directories (will prompt unless --force is used)
-v | --version Print version
- -d | --debug Exit after execution with exit codes (for testing)
-c | --config Specify config file (default ~/.warprc)
-q | --quiet Suppress all output
-f | --force Allows overwriting without warning (for add & clean)
@@ -145,14 +146,17 @@ wd_warp()
else
(( n = $#1 - 1 ))
cd -$n > /dev/null
+ WD_EXIT_CODE=$?
fi
elif [[ ${points[$point]} != "" ]]
then
if [[ $sub != "" ]]
then
cd ${points[$point]/#\~/$HOME}/$sub
+ WD_EXIT_CODE=$?
else
cd ${points[$point]/#\~/$HOME}
+ WD_EXIT_CODE=$?
fi
else
wd_exit_fail "Unknown warp point '${point}'"
@@ -170,6 +174,11 @@ wd_add()
point=$(basename "$PWD")
fi
+ if [ ! -w "$wd_config_file" ]; then
+ wd_exit_fail "\'$wd_config_file\' is not writeable."
+ return
+ fi
+
if [[ $point =~ "^[\.]+$" ]]
then
wd_exit_fail "Warp point cannot be just dots"
@@ -185,11 +194,11 @@ wd_add()
elif [[ ${points[$point]} == "" ]] || [ ! -z "$force" ]
then
wd_remove "$point" > /dev/null
- printf "%q:%s\n" "${point}" "${PWD/#$HOME/~}" >> "$WD_CONFIG"
+ printf "%q:%s\n" "${point}" "${PWD/#$HOME/~}" >> "$wd_config_file"
if (whence sort >/dev/null); then
local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
- # use 'cat' below to ensure we respect $WD_CONFIG as a symlink
- command sort -o "${config_tmp}" "$WD_CONFIG" && command cat "${config_tmp}" >| "$WD_CONFIG" && command rm "${config_tmp}"
+ # use 'cat' below to ensure we respect $wd_config_file as a symlink
+ command sort -o "${config_tmp}" "$wd_config_file" && command cat "${config_tmp}" >| "$wd_config_file" && command rm "${config_tmp}"
fi
wd_export_static_named_directories
@@ -204,6 +213,28 @@ wd_add()
fi
}
+wd_addcd() {
+ local folder="$1"
+ local point=$2
+ local force=$3
+ local currentdir=$PWD
+
+ if [[ -z "$folder" ]]; then
+ wd_exit_fail "You must specify a path"
+ return
+ fi
+
+ if [[ ! -d "$folder" ]]; then
+ wd_exit_fail "The directory does not exist"
+ return
+ fi
+
+ cd "$folder" || return
+ wd_add "$point" "$force"
+ cd "$currentdir" || return
+}
+
+
wd_remove()
{
local point_list=$1
@@ -213,12 +244,17 @@ wd_remove()
point_list=$(basename "$PWD")
fi
+ if [ ! -w "$wd_config_file" ]; then
+ wd_exit_fail "\'$wd_config_file\' is not writeable."
+ return
+ fi
+
for point_name in $point_list ; do
if [[ ${points[$point_name]} != "" ]]
then
local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
# Copy and delete in two steps in order to preserve symlinks
- if sed -n "/^${point_name}:.*$/!p" "$WD_CONFIG" >| "$config_tmp" && command cp "$config_tmp" "$WD_CONFIG" && command rm "$config_tmp"
+ if sed -n "/^${point_name}:.*$/!p" "$wd_config_file" >| "$config_tmp" && command cp "$config_tmp" "$wd_config_file" && command rm "$config_tmp"
then
wd_print_msg "$WD_GREEN" "Warp point removed"
else
@@ -230,11 +266,92 @@ wd_remove()
done
}
+wd_browse() {
+ # Check if fzf is installed
+ if ! command -v fzf >/dev/null; then
+ wd_print_msg "$WD_RED" "This functionality requires fzf. Please install fzf first."
+ return 1
+ fi
+
+ # Ensure wd_config_file is properly set
+ if [[ -z $wd_config_file ]]; then
+ wd_config_file="${WD_CONFIG:-$HOME/.warprc}"
+ fi
+
+ # Check if config file exists
+ if [[ ! -f $wd_config_file ]]; then
+ wd_print_msg "$WD_RED" "Config file $wd_config_file does not exist. Please create it first."
+ return 1
+ fi
+
+ # Read entries from the config file
+ local entries=("${(@f)$(sed "s:${HOME}:~:g" "$wd_config_file" | awk -F ':' '{print $1 " -> " $2}')}")
+ if [[ -z $entries ]]; then
+ wd_print_msg "$WD_YELLOW" "You don't have any warp points to browse"
+ return 1
+ fi
+
+ # Temp file for remove operations
+ local script_path="${${(%):-%x}:h}"
+ local wd_remove_output=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
+
+ # Create fzf bindings
+ entries=("All warp points:" "Press enter to select. Press delete to remove" "${entries[@]}")
+ local fzf_bind="delete:execute(echo {} | awk -F ' -> ' '{print \$1}' | xargs -I {} \"$script_path/wd.sh\" rm {} > \"$wd_remove_output\")+abort"
+
+ # Run fzf
+ local selected_entry=$(printf '%s\n' "${entries[@]}" | fzf --height 100% --reverse --header-lines=2 --bind="$fzf_bind")
+
+ # Handle selection
+ if [[ -e $wd_remove_output ]]; then
+ cat "$wd_remove_output"
+ rm -f "$wd_remove_output"
+ fi
+
+ if [[ -n $selected_entry ]]; then
+ local selected_point="${selected_entry%% ->*}"
+ selected_point=$(echo "$selected_point" | xargs)
+ wd $selected_point
+ fi
+}
+
+wd_browse_widget() {
+ # Ensure wd_config_file is properly set
+ if [[ -z $wd_config_file ]]; then
+ wd_config_file="${WD_CONFIG:-$HOME/.warprc}"
+ fi
+
+ # Check if config file exists
+ if [[ ! -f $wd_config_file ]]; then
+ wd_print_msg "$WD_RED" "Config file $wd_config_file does not exist. Please create it first."
+ return 1
+ fi
+
+ # Call wd_browse to handle the selection
+ wd_browse
+
+ # Restore the zsh buffer and cursor after running wd_browse
+ saved_buffer=$BUFFER
+ saved_cursor=$CURSOR
+ BUFFER=
+ zle redisplay
+ zle accept-line
+}
+
+wd_restore_buffer() {
+ if [[ -n $saved_buffer ]]; then
+ BUFFER=$saved_buffer
+ CURSOR=$saved_cursor
+ fi
+ saved_buffer=
+ saved_cursor=1
+}
+
wd_list_all()
{
wd_print_msg "$WD_BLUE" "All warp points:"
- entries=$(sed "s:${HOME}:~:g" "$WD_CONFIG")
+ entries=$(sed "s:${HOME}:~:g" "$wd_config_file")
max_warp_point_length=0
while IFS= read -r line
@@ -271,6 +388,21 @@ wd_ls()
ls "${dir/#\~/$HOME}"
}
+wd_open()
+{
+ wd_getdir "$1"
+ if command -v open >/dev/null 2>&1; then
+ # MacOS, Ubuntu (alias)
+ open "${dir/#\~/$HOME}"
+ elif command -v xdg-open >/dev/null 2>&1; then
+ # Most Linux desktops
+ xdg-open "${dir/#\~/$HOME}"
+ else
+ echo "No known file opener found (need 'open' or 'xdg-open')." >&2
+ exit 1
+ fi
+}
+
wd_path()
{
wd_getdir "$1"
@@ -280,6 +412,7 @@ wd_path()
wd_show()
{
local name_arg=$1
+ local show_pwd
# if there's an argument we look up the value
if [[ -n $name_arg ]]
then
@@ -294,12 +427,12 @@ wd_show()
local wd_matches
wd_matches=()
# do a reverse lookup to check whether PWD is in $points
- PWD="${PWD/$HOME/~}"
- if [[ ${points[(r)$PWD]} == "$PWD" ]]
+ show_pwd="${PWD/$HOME/~}"
+ if [[ ${points[(r)$show_pwd]} == "$show_pwd" ]]
then
for name in ${(k)points}
do
- if [[ $points[$name] == "$PWD" ]]
+ if [[ $points[$name] == "$show_pwd" ]]
then
wd_matches[$(($#wd_matches+1))]=$name
fi
@@ -307,7 +440,7 @@ wd_show()
wd_print_msg "$WD_BLUE" "$#wd_matches warp point(s) to current directory: ${WD_GREEN}$wd_matches${WD_NOC}"
else
- wd_print_msg "$WD_YELLOW" "No warp point to $(echo "$PWD" | sed "s:$HOME:~:")"
+ wd_print_msg "$WD_YELLOW" "No warp point to $show_pwd"
fi
fi
}
@@ -317,6 +450,11 @@ wd_clean() {
local count=0
local wd_tmp=""
+ if [ ! -w "$wd_config_file" ]; then
+ wd_exit_fail "\'$wd_config_file\' is not writeable."
+ return
+ fi
+
while read -r line
do
if [[ $line != "" ]]
@@ -333,7 +471,7 @@ wd_clean() {
count=$((count+1))
fi
fi
- done < "$WD_CONFIG"
+ done < "$wd_config_file"
if [[ $count -eq 0 ]]
then
@@ -341,7 +479,7 @@ wd_clean() {
else
if [ ! -z "$force" ] || wd_yesorno "Removing ${count} warp points. Continue? (y/n)"
then
- echo "$wd_tmp" >! "$WD_CONFIG"
+ echo "$wd_tmp" >! "$wd_config_file"
wd_print_msg "$WD_GREEN" "Cleanup complete. ${count} warp point(s) removed"
else
wd_print_msg "$WD_BLUE" "Cleanup aborted"
@@ -352,16 +490,15 @@ wd_clean() {
wd_export_static_named_directories() {
if [[ ! -z $WD_EXPORT ]]
then
- command grep '^[0-9a-zA-Z_-]\+:' "$WD_CONFIG" | sed -e "s,~,$HOME," -e 's/:/=/' | while read -r warpdir ; do
+ command grep '^[0-9a-zA-Z_-]\+:' "$wd_config_file" | sed -e "s,~,$HOME," -e 's/:/=/' | while read -r warpdir ; do
hash -d "$warpdir"
done
fi
}
-local WD_CONFIG=${WD_CONFIG:-$HOME/.warprc}
+WD_CONFIG=${WD_CONFIG:-$HOME/.warprc}
local WD_QUIET=0
local WD_EXIT_CODE=0
-local WD_DEBUG=0
# Parse 'meta' options first to avoid the need to have them before
# other commands. The `-D` flag consumes recognized options so that
@@ -371,7 +508,6 @@ zparseopts -D -E \
c:=wd_alt_config -config:=wd_alt_config \
q=wd_quiet_mode -quiet=wd_quiet_mode \
v=wd_print_version -version=wd_print_version \
- d=wd_debug_mode -debug=wd_debug_mode \
f=wd_force_mode -force=wd_force_mode
if [[ ! -z $wd_print_version ]]
@@ -379,16 +515,19 @@ then
echo "wd version $WD_VERSION"
fi
+# set the config file from variable or default
+typeset wd_config_file=${WD_CONFIG:-$HOME/.warprc}
if [[ ! -z $wd_alt_config ]]
then
- WD_CONFIG=$wd_alt_config[2]
+ # prefer the flag if provided
+ wd_config_file=$wd_alt_config[2]
fi
# check if config file exists
-if [ ! -e "$WD_CONFIG" ]
+if [ ! -e "$wd_config_file" ]
then
# if not, create config file
- touch "$WD_CONFIG"
+ touch "$wd_config_file"
else
wd_export_static_named_directories
fi
@@ -396,7 +535,9 @@ fi
# disable extendedglob for the complete wd execution time
setopt | grep -q extendedglob
wd_extglob_is_set=$?
-(( ! $wd_extglob_is_set )) && setopt noextendedglob
+if (( wd_extglob_is_set == 0 )); then
+ setopt noextendedglob
+fi
# load warp points
typeset -A points
@@ -408,23 +549,15 @@ do
val=${(j,:,)arr[2,-1]}
points[$key]=$val
-done < "$WD_CONFIG"
+done < "$wd_config_file"
# get opts
-args=$(getopt -o a:r:c:lhs -l add:,rm:,clean,list,ls:,path:,help,show -- $*)
+args=$(getopt -o a:r:c:lhs -l add:,rm:,clean,list,ls:,open:,path:,help,show -- $*)
# check if no arguments were given, and that version is not set
if [[ ($? -ne 0 || $#* -eq 0) && -z $wd_print_version ]]
then
wd_print_usage
-
-# check if config file is writeable
-elif [ ! -w "$WD_CONFIG" ]
-then
- # do nothing
- # can't run `exit`, as this would exit the executing shell
- wd_exit_fail "\'$WD_CONFIG\' is not writeable."
-
else
# parse rest of options
local wd_o
@@ -436,6 +569,14 @@ else
wd_add "$2" "$wd_force_mode"
break
;;
+ "-b"|"browse")
+ wd_browse
+ break
+ ;;
+ "-c"|"--addcd"|"addcd")
+ wd_addcd "$2" "$3" "$wd_force_mode"
+ break
+ ;;
"-e"|"export")
wd_export_static_named_directories
break
@@ -453,6 +594,10 @@ else
wd_ls "$2"
break
;;
+ "-o"|"--open"|"open")
+ wd_open "$2"
+ break
+ ;;
"-p"|"--path"|"path")
wd_path "$2"
break
@@ -484,11 +629,14 @@ fi
# if not, next time warp will pick up variables from this run
# remember, there's no sub shell
-(( ! $wd_extglob_is_set )) && setopt extendedglob
+if (( wd_extglob_is_set == 0 )); then
+ setopt extendedglob
+fi
unset wd_extglob_is_set
unset wd_warp
unset wd_add
+unset wd_addcd
unset wd_remove
unset wd_show
unset wd_list_all
@@ -496,8 +644,10 @@ unset wd_print_msg
unset wd_yesorno
unset wd_print_usage
unset wd_alt_config
+#unset wd_config_file do not unset this - breaks keybind
unset wd_quiet_mode
unset wd_print_version
+unset wd_force_mode
unset wd_export_static_named_directories
unset wd_o
@@ -505,9 +655,4 @@ unset args
unset points
unset val &> /dev/null # fixes issue #1
-if [[ -n $wd_debug_mode ]]
-then
- exit $WD_EXIT_CODE
-else
- unset wd_debug_mode
-fi
+return $WD_EXIT_CODE