forked from astralarya/to
-
Notifications
You must be signed in to change notification settings - Fork 0
/
to.sh
167 lines (154 loc) · 4.29 KB
/
to.sh
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# to
# Bookmark locations in bash
#
# Copyright (C) 2013 Mara Kim
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see http://www.gnu.org/licenses/.
TO_BOOKMARK_FILE=~/.bookmarks
TO_ECHO=\echo
TO_CD=\cd
TO_CAT=\cat
TO_PWD=\pwd
TO_BASENAME=\basename
TO_SED=\sed
function to {
if [ "$1" ]
then
if [ "$1" = "-b" ]
then
local path="$("$TO_PWD")"
local name
if [ "$2" ]
then
if [ $("$TO_SED" -rn "s/(.*\/.*)/\1/p" <<< "$2") ]
then
"$TO_ECHO" "bookmark name may not contain forward slashes" >&2
return 1
fi
name="$2"
else
name="$("$TO_BASENAME" "$path")"
fi
# add bookmark
_to_rm "$name"
"$TO_ECHO" "$name|$path" >> "$TO_BOOKMARK_FILE"
elif [ "$1" = "-r" ]
then
# remove bookmark
_to_rm "$2"
elif [ -e "$TO_BOOKMARK_FILE" ]
then
# go to bookmark if found
local bookmark="$(_to_path_head "$1")"
local extra="$(_to_path_tail "$1")"
local todir="$(_to_dir "$bookmark")"
if [ "$todir" ]
then
"$TO_CD" "$(_to_reldir "$1")"
else
"$TO_ECHO" "No shortcut: $bookmark"
fi
else
"$TO_ECHO" "No shortcut: $bookmark"
fi
elif [ -e "$TO_BOOKMARK_FILE" ]
then
# show bookmarks
"$TO_CAT" "$TO_BOOKMARK_FILE"
fi
}
# get the directory referred to by a bookmark
function _to_dir {
"$TO_SED" -rn "s/^$1\|(.*)/\1/p" "$TO_BOOKMARK_FILE"
}
# get the first part of the path
function _to_path_head {
"$TO_SED" -rn "s/^([^/]*)(\/.*)?$/\1/p" <<<"$1"
}
# get the rest of the path
function _to_path_tail {
"$TO_SED" -rn "s/^[^/]*(\/.*)$/\1/p" <<<"$1"
}
# get the expanded path of a bookmark/path
function _to_reldir {
local todir="$(_to_dir "$(_to_path_head "$1")" )"
if [ "$todir" = "/" ]
then
# special case for root dir
"$TO_ECHO" "$(_to_path_tail "$1")"
else
"$TO_ECHO" "$todir$(_to_path_tail "$1")"
fi
}
# remove bookmark
function _to_rm {
if [ -e "$TO_BOOKMARK_FILE" ]
then
"$TO_SED" -ri "/^$1\|.*/ d" "$TO_BOOKMARK_FILE"
fi
}
# clean input for sed search
function _to_regex {
if [ "$1" = "/" ]
then
# special case for root dir
"$TO_ECHO"
else
"$TO_ECHO" $1 | "$TO_SED" -e 's/[\/&]/\\&/g'
fi
}
# tab completion bash
function _to {
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local bookmark="$(_to_path_head "$cur")"
local todir="$( _to_dir "$bookmark")"
if [ "$prev" = "-b" -o "$prev" = "-r" ]
then
if [ "$prev" = "-b" ]
then
# add current directory
COMPREPLY="$("$TO_BASENAME" "$($TO_PWD)" )"
fi
if [ -e "$TO_BOOKMARK_FILE" ]
then
# get bookmarks
COMPREPLY="$("$TO_SED" -rn "s/(.*)\|.*/\1/p" "$TO_BOOKMARK_FILE") $COMPREPLY"
fi
elif [ -e "$TO_BOOKMARK_FILE" ]
then
if [ "$todir" ]
then
# add subdirectories
COMPREPLY="$(compgen -S "/" -d "$(_to_reldir $cur)" | $TO_SED -r "s/^$(_to_regex "$todir")/$bookmark/")"
else
# get bookmarks (with slash)
COMPREPLY="$("$TO_SED" -rn "s/(.*)\|.*/\1\//p" "$TO_BOOKMARK_FILE") $COMPREPLY"
fi
fi
# generate reply
COMPREPLY=( $(compgen -W "$COMPREPLY" -- "$cur") )
}
# tab completion zsh
function _to_zsh {
if [ -e "$TO_BOOKMARK_FILE" ]
then
reply=(`"$TO_SED" -rn "s/(.*)\|.*/\1/p" "$TO_BOOKMARK_FILE"`)
fi
}
if [ "$ZSH_VERSION" ]; then
compctl -K _to_zsh to
else
complete -o filenames -o nospace -F _to to
fi