-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmarks.zsh
83 lines (70 loc) · 2.27 KB
/
marks.zsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/zsh
export MARKSPATH=${MARKSPATH:-$HOME/.marks}
# Jump *to* a mark.
# No argument is the same as `cd`.
# If the argument is a valid directory, cd to it. (If "-", cd to prev. dir.)
# If the argument is a mark, cd to that. Otherwise bail.
function to {
[[ -z "$1" ]] && cd && return
[[ -d "$1" || "$1" == "-" ]] && cd "$1" && return
cd -P "$MARKSPATH/$1" 2> /dev/null || \
echo "$0: no such mark or directory: $1" 1>&2
}
# Save a mark.
# Zero arguments marks the current directory.
# One argument gives it a name (perhaps different from the mark's basename).
# With two arguments, the first argument explicitly specifies the directory.
function mark {
local src_dir=${2:+$(realpath $1)}
src_dir=${src_dir:-$PWD}
local mark_name=${2:-${1:-$(basename "$src_dir")}}
if [[ -e "$MARKSPATH/$mark_name" ]]
then
echo "$0: mark exists: $mark_name" 1>&2
elif [[ -d "$src_dir" ]]
then
echo "new mark: $mark_name -> $src_dir"
\mkdir -p "$MARKSPATH"
\ln -s "$src_dir" "$MARKSPATH/$mark_name"
else
echo "$0: not a directory: $src_dir" 1>&2
fi
}
# Remove one or more marks.
function rmmark {
[[ $# -eq 0 ]] && echo "usage: $0 MARK..." 1>&2 && return
for mark in "$@"
do
if [[ ! -e $MARKSPATH/$mark ]]
then
echo "$0: no such mark: $mark" 1>&2
else
\rm $MARKSPATH/$mark && echo "removed mark: $mark"
fi
done
}
# List all marks and which directory they each reference.
function marks {
setopt localoptions nullglob
local marks=("$MARKSPATH"/*)
[[ ${#marks} -eq 0 ]] && echo "No bookmarks." && return
for mark in "${marks[@]}"
do
echo $(basename "$mark") '->' $(readlink "$mark")
done
}
# Completion function for the `to` and `rmmark` commands.
# TODO: complete second argument as subdirectory of mark.
# TODO: complete regular expressions?
function complete_marks {
setopt localoptions nullglob
for m in "$MARKSPATH"/*
do
reply+=($(basename "$m"))
done
}
# Add marks completion to commands `to` and `rmmark`.
# TODO: use new completion system instead of old one.
# TODO: use directory completion for second argument of `mark` command.
compctl -K complete_marks to
compctl -K complete_marks rmmark