mirror of
https://github.com/notwa/rc
synced 2025-02-05 07:43:22 -08:00
actual submodules?
This commit is contained in:
parent
cc5b057607
commit
d5ae7c8eb8
19 changed files with 20 additions and 1001 deletions
15
.gitmodules
vendored
Normal file
15
.gitmodules
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
[submodule "sh/z"]
|
||||
path = sh/z
|
||||
url = https://github.com/rupa/z.git
|
||||
[submodule "sh/meow.sh"]
|
||||
path = sh/meow.sh
|
||||
url = https://github.com/notwa/meow.sh.git
|
||||
[submodule "sh/lsf.sh"]
|
||||
path = sh/lsf.sh
|
||||
url = https://gist.github.com/5581118.git
|
||||
[submodule "sh/danny.sh"]
|
||||
path = sh/danny.sh
|
||||
url = https://gist.github.com/3393717.git
|
||||
[submodule "sh/4graze.sh"]
|
||||
path = sh/4graze.sh
|
||||
url = https://gist.github.com/2975511.git
|
1
sh/4graze.sh
Submodule
1
sh/4graze.sh
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 8a20da818363a275a2a176fa0569af709e4c1119
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash
|
||||
url="${1:-}"
|
||||
[[ "$url" =~ ^https?://boards.4chan.org/([A-Za-z]+)/res/([0-9]+) ]] || exit 1
|
||||
board="${BASH_REMATCH[1]}"
|
||||
threadnum="${BASH_REMATCH[2]}"
|
||||
|
||||
# TODO: curl version
|
||||
|
||||
wgetflags="-erobots=off --no-verbose"
|
||||
wgetflags+=" --no-clobber --recursive --level=1 --span-hosts"
|
||||
wgetflags+=" --no-directories --directory-prefix=-$board-$threadnum"
|
||||
wgetflags+=" --accept=jpg,gif,png --domains=images.4chan.org"
|
||||
wget $wgetflags $url
|
1
sh/danny.sh
Submodule
1
sh/danny.sh
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit f78ef75f435317df2c22a89f87b3c7ebc413ab04
|
|
@ -1,76 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -o nounset
|
||||
|
||||
# danny wants $20 to search for more than 2 tags
|
||||
# so we'll search for realtags and grep for faketags
|
||||
# note that special tags like "score:>10" must be a realtag
|
||||
realtags="$1"
|
||||
faketags=${2:-}
|
||||
|
||||
ip="67.202.114.134" # danbooru.donmai.us
|
||||
webpage="post/index?tags=$realtags&limit=100&page="
|
||||
pages=0
|
||||
tempfile=`mktemp`
|
||||
current=
|
||||
|
||||
term()
|
||||
{
|
||||
rm $current # don't leave it incomplete so it may be redownloaded
|
||||
exit 1
|
||||
}
|
||||
trap 'term' TERM INT
|
||||
|
||||
#get='wget -q -erobots=off -O-' # mimic curl
|
||||
get='curl -s'
|
||||
|
||||
page=1
|
||||
while true; do
|
||||
$get "http://$ip/${webpage}${page}" > "$tempfile"
|
||||
|
||||
posts=$(grep 'Post\.register({' "$tempfile")
|
||||
IFS=$'\n'
|
||||
for post in $posts; do
|
||||
IFS=' '
|
||||
tags=$(echo $post | grep -oP '(?<=tags":")([^"]+)')
|
||||
if [ -z "$tags" ]; then continue; fi
|
||||
|
||||
badmatch=0
|
||||
for faketag in $faketags; do
|
||||
unwanted=0
|
||||
if [[ $faketag == -* ]]; then
|
||||
faketag=${faketag:1}
|
||||
unwanted=1
|
||||
fi
|
||||
echo $tags | grep -F -- "$faketag" > /dev/null
|
||||
result=$?
|
||||
if [[ $result != $unwanted ]]; then
|
||||
badmatch=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if (($badmatch)); then continue; fi
|
||||
|
||||
url=$(echo "$post" | grep -oP '(?<=file_url":")([^"]+)')
|
||||
if [ -z "$url" ]; then continue; fi
|
||||
name=$(echo "$url" | cut -d/ -f5)
|
||||
current="$name"
|
||||
if [ -n "$name" ]; then
|
||||
echo $name
|
||||
$get "$url" > $name
|
||||
fi
|
||||
done
|
||||
IFS=' '
|
||||
|
||||
if (("$pages" == "0")); then
|
||||
# first iteration, discover pagecount
|
||||
pages=$(grep -oPm1 \
|
||||
'(?<=>)\d+(?=</a> <a href="/post/index[^"]+" >>>)' \
|
||||
$tempfile)
|
||||
pages=${pages:-1}
|
||||
fi
|
||||
|
||||
let page++
|
||||
if (("$page" > "$pages")); then break; fi
|
||||
done
|
||||
|
||||
rm $tempfile
|
1
sh/lsf.sh
Submodule
1
sh/lsf.sh
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit dceb0894b35c55f750ce680f8b5e0d0919308042
|
172
sh/lsf.sh/lsf.sh
172
sh/lsf.sh/lsf.sh
|
@ -1,172 +0,0 @@
|
|||
#!/bin/bash
|
||||
# ultra-fancy ultra-pointless `ls -l` alternative
|
||||
# to be sourced by bash or zsh
|
||||
# similar project: https://github.com/trapd00r/ls--
|
||||
|
||||
# to maintain zsh compatibility:
|
||||
# $() is surrounded in double quotes
|
||||
# echo -E is used to avoid \033 expanding
|
||||
# bare asterisks are escaped to prevent globbing
|
||||
# arrays are used instead of relying on word expansion
|
||||
# for loops over "${array[@]}" as it works the same in both
|
||||
|
||||
# TODO: set better defaults for quick glances at filesize
|
||||
# TODO: include sorting somehow
|
||||
# TODO: handle symlinks nicely
|
||||
# TODO: append WHI / clr to dir names
|
||||
|
||||
_lsf_begin(){
|
||||
local begin='
|
||||
me='$UID'
|
||||
'"$(
|
||||
awk -F: '{print "unames["$3"]=\""$1"\""}' < /etc/passwd
|
||||
awk -F: '{print "gnames["$3"]=\""$1"\""}' < /etc/group
|
||||
for x in $(groups); do echo "us[\"$x\"]=1"; done
|
||||
i=0;for x in bla red gre yel blu pur cya whi; do
|
||||
echo -E $x'="\033[3'${i}'m"'
|
||||
echo -n "$x" | tr a-z A-Z
|
||||
echo -E '="\033[1;3'${i}'m"'
|
||||
let i++
|
||||
done
|
||||
)"'
|
||||
clr="\033[0m"
|
||||
BLD="\033[1m"
|
||||
s=1
|
||||
m=60*s
|
||||
h=60*m
|
||||
d=24*h
|
||||
y=365*d
|
||||
B=1
|
||||
K=1024*B
|
||||
M=1024*K
|
||||
G=1024*M
|
||||
T=1024*G
|
||||
ff["time"]="%3d%s " clr
|
||||
ff["size"]="%4d" clr "%s "
|
||||
'"$(
|
||||
for x in s m h d y;do echo "u[\"time,$x\"]=$x";done
|
||||
for x in B K M G T;do echo "u[\"size,$x\"]=$x";done
|
||||
ft=(-1 m m\*10 h h\*12 d d\*7 30\*d y y\*2 y\*10)
|
||||
fut=(s s s m m h h d d d y y)
|
||||
fct=(RED PUR pur YEL yel GRE gre CYA cya BLU blu BLA)
|
||||
fs=( 0 K K\*8 M M\*8 G G\*8 T T\*8)
|
||||
fus=(B B B K K M M G G T)
|
||||
fcs=(BLA cya CYA CYA yel yel pur pur red red)
|
||||
pc=(BLA WHI yel YEL blu BLU gre GRE)
|
||||
i=0;for x in "${ft[@]}"; do echo "f[\"time,$i\"]=$x"; let i++;done
|
||||
echo "f[\"times\"]=$i"
|
||||
i=0;for x in "${fs[@]}"; do echo "f[\"size,$i\"]=$x"; let i++;done
|
||||
echo "f[\"sizes\"]=$i"
|
||||
i=0;for x in "${fut[@]}";do echo "fu[\"time,$i\"]=\"$x\"";let i++;done
|
||||
i=0;for x in "${fus[@]}";do echo "fu[\"size,$i\"]=\"$x\"";let i++;done
|
||||
i=0;for x in "${fct[@]}";do echo "fc[\"time,$i\"]=$x"; let i++;done
|
||||
i=0;for x in "${fcs[@]}";do echo "fc[\"size,$i\"]=$x"; let i++;done
|
||||
i=0;for x in "${pc[@]}"; do echo "pc[$i]=$x"; let i++;done
|
||||
)"
|
||||
echo -E "$begin"
|
||||
}
|
||||
|
||||
_lsf_cached=
|
||||
_lsf_program='
|
||||
function printff(id, n) {
|
||||
len=f[id "s"]
|
||||
for(i=0;i<=len;i++) {
|
||||
idi=id "," i
|
||||
if(i!=len && n>f[idi]) continue
|
||||
unit=fu[idi]
|
||||
printf(fc[idi] ff[id], n/u[id "," unit], unit)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function trunc(str, len) {
|
||||
e=length(str)>len?"…":""
|
||||
return substr(str,0,len-(e?1:0)) e
|
||||
}
|
||||
function fixlen(str, len) {
|
||||
return trunc(sprintf("%" len "s", str), len)
|
||||
}
|
||||
{
|
||||
printff("size", $(NF-14))
|
||||
|
||||
uid=$(NF-11)
|
||||
gid=$(NF-10)
|
||||
is_me=(uid==me)
|
||||
is_us=(gnames[gid] in us)
|
||||
|
||||
bits=("0x" $(NF-12))+0
|
||||
# note: we ignore the set and sticky bits... for now
|
||||
type=rshift(and(bits, 0170000), 12)
|
||||
operm=and(bits, 07)
|
||||
gperm=rshift(and(bits, 070), 3)
|
||||
uperm=rshift(and(bits, 0700), 6)
|
||||
our_perm=or(or((is_me)?uperm:0, (is_us)?gperm:0), operm)
|
||||
|
||||
printf(pc[our_perm] "%o " clr, our_perm)
|
||||
if(OSP) {
|
||||
printf(pc[uperm] "%o" clr, uperm)
|
||||
printf(pc[gperm] "%o" clr, gperm)
|
||||
printf(pc[operm] "%o " clr, operm)
|
||||
}
|
||||
|
||||
if(OSU) {
|
||||
name=fixlen((uid in unames)?unames[uid]:uid, 6)
|
||||
if(is_me) name=WHI name clr
|
||||
printf("%s ", name)
|
||||
}
|
||||
|
||||
if(OSG) {
|
||||
name=fixlen((gid in gnames)?gnames[gid]:gid, 6)
|
||||
if(is_us) name=WHI name clr
|
||||
printf("%s ", name)
|
||||
}
|
||||
|
||||
da=$(NF-4)
|
||||
dc=$(NF-3)
|
||||
dm=$(NF-2)
|
||||
if(OMR) {
|
||||
max=(da>dm)?da:dm
|
||||
max=(max>dc)?max:dc
|
||||
printff("time", now-max)
|
||||
} else {
|
||||
printff("time", now-da)
|
||||
printff("time", now-dm)
|
||||
printff("time", now-dc)
|
||||
}
|
||||
|
||||
# acquire filename by killing all fields not part of it
|
||||
NF-=15
|
||||
fn=$0
|
||||
|
||||
if (!OSPA) {
|
||||
if (NR!=1) fn=substr(fn,firstlen)
|
||||
else firstlen=length(fn)+2-(fn ~ /\/$/)
|
||||
}
|
||||
|
||||
print fn
|
||||
}'
|
||||
|
||||
lsf(){
|
||||
local o_showallperm=1 o_showuser=1 o_showgroup=1
|
||||
local o_mostrecent=0 o_showpath=1 opts=mgupfs opt
|
||||
while getopts $opts'h' opt; do
|
||||
case $opt in
|
||||
f) _lsf_cached=;;
|
||||
p) o_showallperm=0;;
|
||||
u) o_showuser=0;;
|
||||
g) o_showgroup=0;;
|
||||
m) o_mostrecent=1;;
|
||||
s) o_showpath=0;;
|
||||
?) echo "usage: $0 [-$opts] [dir]"
|
||||
return 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$_lsf_cached" ] || _lsf_cached="$(_lsf_begin)"
|
||||
|
||||
shift $((OPTIND-1))
|
||||
find "${1:-.}" -maxdepth 1 -exec stat -t {} + | awk --non-decimal-data \
|
||||
-v"now=$(date +%s)" -v"OMR=$o_mostrecent" -v"OSU=$o_showuser" \
|
||||
-v"OSG=$o_showgroup" -v"OSP=$o_showallperm" -v"OSPA=$o_showpath" \
|
||||
"BEGIN{$_lsf_cached}$_lsf_program"
|
||||
}
|
1
sh/meow.sh
Submodule
1
sh/meow.sh
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 264706a6df14307bf3c791bd639d055c4f14dda3
|
|
@ -1,20 +0,0 @@
|
|||
# meow.sh
|
||||
|
||||
Prints out the title, torrent link, and timestamp
|
||||
for every new release matching your regular expressions
|
||||
and reminds you that your taste in anime is shit.
|
||||
|
||||
## Usage
|
||||
|
||||
Just take a peek at `run` and `config.sh` for now.
|
||||
If you can't figure it out, you're too sane to use this.
|
||||
|
||||
## License
|
||||
|
||||
These scripts are hardly unique so
|
||||
I'm not signing my name on them and
|
||||
I'm not applying any license.
|
||||
Just pretend they're under the [WTFPL][0]
|
||||
if you really want to.
|
||||
|
||||
[0]: http://www.wtfpl.net/txt/copying/
|
|
@ -1,3 +0,0 @@
|
|||
watch Commie 'Yuyushiki - \d\d' 'Aiura - \d\d'
|
||||
watch rori 'Hentai Ouji to Warawanai Neko - '
|
||||
watch FFF 'DATE A LIVE - \d\d(?!v0)'
|
|
@ -1,89 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
SEP=$'\1'
|
||||
|
||||
die() {
|
||||
echo -E "$@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
nullcheck() {
|
||||
[[ -n "$1" ]] || die "Null group name";
|
||||
}
|
||||
|
||||
sanitize() {
|
||||
sed -e 's/[^0-9a-zA-Z_]/_/g'
|
||||
}
|
||||
|
||||
splittags() {
|
||||
awk -v tag="$1" -f "$SRCDIR/splittags.awk"
|
||||
}
|
||||
|
||||
scrape() {
|
||||
TZ=UTC0 awk -v g="$1" -v timestamp="${2:-0}" -v sep="$SEP" -f "$SRCDIR/scrape.awk"
|
||||
}
|
||||
|
||||
declare -A groupinsane # unsanitized group names
|
||||
declare -A groupshows # regexes
|
||||
watch() { # {group name} [regex...]
|
||||
nullcheck "$1"
|
||||
local gs="$(sanitize<<<"$1")"
|
||||
groupinsane[$gs]="$1"
|
||||
shift
|
||||
while (( "$#" )); do
|
||||
groupshows[$gs]+="|($1)"
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
declare -A grouptimes # last times timestamp
|
||||
touchgroup() { # {group name} {unix time}
|
||||
nullcheck "$1"
|
||||
local gs="$(sanitize<<<"$1")"
|
||||
grouptimes[$gs]="$2"
|
||||
}
|
||||
|
||||
groupreleases() { # groupname [timestamp]
|
||||
nullcheck "$1"
|
||||
# TODO: escapeurl $1
|
||||
local URL="http://www.nyaa.eu/?page=search&term=%5B$1%5D&page=rss"
|
||||
curl -LsS "$URL" > "$1.xml" || die "Failed to retrieve releases for $1"
|
||||
tr -d '\r\n'"$SEP" < "$1.xml" | splittags item | scrape "$1" "${2:-}"
|
||||
}
|
||||
|
||||
groupfilter() { # groupname regex [timestamp]
|
||||
groupreleases "$1" "${3:-}" | while IFS=$SEP read -r title etc; do
|
||||
grep -P "$2" <<< "$title" 1>/dev/null && echo -E "$title$SEP$etc"
|
||||
done
|
||||
[ ${PIPESTATUS[0]} = 0 ] || exit 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
for gs in "${!grouptimes[@]}"; do
|
||||
local v="${grouptimes[$gs]}"
|
||||
echo -E "touchgroup $gs $v" >> times.sh
|
||||
[ -e "$gs.xml" ] && rm "$gs.xml"
|
||||
done
|
||||
exit ${1:-1}
|
||||
}
|
||||
|
||||
rungroup() {
|
||||
local insane regex timestamp res recent
|
||||
insane="${groupinsane[$1]}"
|
||||
regex="${groupshows[$1]:1}"
|
||||
timestamp="${grouptimes[$1]}"
|
||||
res="$(groupfilter "$insane" "$regex" "$timestamp")"
|
||||
[ $? = 0 ] || return $?
|
||||
IFS=$SEP read -r _ _ recent <<< "$res"
|
||||
[ -n "$recent" ] && {
|
||||
grouptimes[$1]="$recent"
|
||||
echo -E "$res"
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
runall() {
|
||||
trap cleanup INT
|
||||
ret=0
|
||||
for gs in "${!groupshows[@]}"; do rungroup "$gs" || ret=1; done
|
||||
cleanup $ret
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
SRCDIR="$(readlink -f "$(dirname "$0")" )"
|
||||
|
||||
# TODO: a way to pass opts to transmission-remote
|
||||
|
||||
declare -a actions
|
||||
while getopts 'aph' opt; do
|
||||
case $opt in
|
||||
a) actions+=(addtorrent);;
|
||||
p) actions+=(prettify);;
|
||||
?) echo -E "usage: $0 [-ap]" 1>&2;;
|
||||
esac
|
||||
done
|
||||
|
||||
prettify() {
|
||||
echo -E "$1"$'\n'"dl:"$'\t'"$2"$'\n'"at:"$'\t'"$(date -d @"$3")"
|
||||
}
|
||||
|
||||
declare -a torrents
|
||||
addtorrent() {
|
||||
torrents+=("$2")
|
||||
}
|
||||
|
||||
runactions() {
|
||||
[ ${#actions} = 0 ] && {
|
||||
cat
|
||||
return
|
||||
}
|
||||
while IFS=$SEP read -r title torrent time; do
|
||||
for a in "${actions[@]}"; do
|
||||
"$a" "$title" "$torrent" "$time"
|
||||
done
|
||||
done
|
||||
[ ${#torrents} = 0 ] || transmission-remote -a "${torrents[@]}"
|
||||
}
|
||||
|
||||
. "$SRCDIR/meow.sh"
|
||||
. config.sh
|
||||
[ -e times.sh ] && { . times.sh; mv times.sh times.sh.old; }
|
||||
runall | runactions
|
||||
exit ${PIPESTATUS[0]}
|
|
@ -1,39 +0,0 @@
|
|||
function opentag(str, tag) {
|
||||
topen="<"tag">"
|
||||
tclose="</"tag">"
|
||||
len=length(tag)
|
||||
begin=index(str, topen)
|
||||
end=index(str, tclose)
|
||||
return (begin && end) ? substr(str, begin+len+2, end-begin-len-2) : ""
|
||||
}
|
||||
|
||||
function unescape(str) {
|
||||
while (match(str, /&#([0-9]+);/, b))
|
||||
str=substr(str, 1, RSTART-1) sprintf("%c",b[1]) substr(str, RSTART+RLENGTH)
|
||||
return str
|
||||
}
|
||||
|
||||
function hotdate(str) {
|
||||
split(str, d, "[ :]")
|
||||
return mktime(d[4]" "months[d[3]]" "d[2]" "d[5]" "d[6]" "d[7])
|
||||
}
|
||||
|
||||
BEGIN{
|
||||
# http://stackoverflow.com/a/2123002
|
||||
m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
|
||||
for(o=1;o<=m;o++) months[d[o]]=sprintf("%02d",o)
|
||||
glen=length(g)
|
||||
}
|
||||
|
||||
function run(str) {
|
||||
title=unescape(opentag(str, "title"))
|
||||
if (substr(title,1,glen+2) != "["g"]") return
|
||||
pub=unescape(opentag($0, "pubDate"))
|
||||
# "date -d \""pub "\" +%s" | getline pubunix
|
||||
pubunix=hotdate(pub)
|
||||
if (pubunix <= timestamp) return
|
||||
torrent=unescape(opentag(str, "link"))
|
||||
print title sep torrent sep pubunix
|
||||
}
|
||||
|
||||
{run($0)}
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
str=$0
|
||||
topen="<"tag">"
|
||||
tclose="</"tag">"
|
||||
len=length(tag)
|
||||
for (;;) {
|
||||
begin=index(str, topen)
|
||||
end=index(str,tclose)
|
||||
if (!(begin || end)) break
|
||||
print substr(str, begin+len+2, end-begin-len-2)
|
||||
str=substr(str, end+len+3)
|
||||
}
|
||||
}
|
1
sh/z
Submodule
1
sh/z
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit ea574b79df7b0d9b648e73c7d78cf3f05a6d97ea
|
|
@ -1,4 +0,0 @@
|
|||
readme:
|
||||
@groff -man -Tascii z.1 | col -bx
|
||||
|
||||
.PHONY: readme
|
137
sh/z/README
137
sh/z/README
|
@ -1,137 +0,0 @@
|
|||
Z(1) User Commands Z(1)
|
||||
|
||||
|
||||
|
||||
NAME
|
||||
z - jump around
|
||||
|
||||
SYNOPSIS
|
||||
z [-chlrtx] [regex1 regex2 ... regexn]
|
||||
|
||||
AVAILABILITY
|
||||
bash, zsh
|
||||
|
||||
DESCRIPTION
|
||||
Tracks your most used directories, based on 'frecency'.
|
||||
|
||||
After a short learning phase, z will take you to the most 'frecent'
|
||||
directory that matches ALL of the regexes given on the command line.
|
||||
|
||||
OPTIONS
|
||||
-c restrict matches to subdirectories of the current directory
|
||||
|
||||
-h show a brief help message
|
||||
|
||||
-l list only
|
||||
|
||||
-r match by rank only
|
||||
|
||||
-t match by recent access only
|
||||
|
||||
-x remove the current directory from the datafile
|
||||
|
||||
EXAMPLES
|
||||
z foo cd to most frecent dir matching foo
|
||||
|
||||
z foo bar cd to most frecent dir matching foo and bar
|
||||
|
||||
z -r foo cd to highest ranked dir matching foo
|
||||
|
||||
z -t foo cd to most recently accessed dir matching foo
|
||||
|
||||
z -l foo list all dirs matching foo (by frecency)
|
||||
|
||||
NOTES
|
||||
Installation:
|
||||
Put something like this in your $HOME/.bashrc or $HOME/.zshrc:
|
||||
|
||||
. /path/to/z.sh
|
||||
|
||||
cd around for a while to build up the db.
|
||||
|
||||
PROFIT!!
|
||||
|
||||
Optionally:
|
||||
Set $_Z_CMD to change the command name (default z).
|
||||
Set $_Z_DATA to change the datafile (default $HOME/.z).
|
||||
Set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution.
|
||||
Set $_Z_NO_PROMPT_COMMAND to handle PROMPT_COMMAND/precmd your-
|
||||
self.
|
||||
Set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
|
||||
(These settings should go in .bashrc/.zshrc before the lines
|
||||
added above.)
|
||||
Install the provided man page z.1 somewhere like
|
||||
/usr/local/man/man1.
|
||||
|
||||
Aging:
|
||||
The rank of directories maintained by z undergoes aging based on a sim-
|
||||
ple formula. The rank of each entry is incremented every time it is
|
||||
accessed. When the sum of ranks is greater than 6000, all ranks are
|
||||
multiplied by 0.99. Entries with a rank lower than 1 are forgotten.
|
||||
|
||||
Frecency:
|
||||
Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted
|
||||
rank that depends on how often and how recently something occurred. As
|
||||
far as I know, Mozilla came up with the term.
|
||||
|
||||
To z, a directory that has low ranking but has been accessed recently
|
||||
will quickly have higher rank than a directory accessed frequently a
|
||||
long time ago.
|
||||
|
||||
Frecency is determined at runtime.
|
||||
|
||||
Common:
|
||||
When multiple directories match all queries, and they all have a common
|
||||
prefix, z will cd to the shortest matching directory, without regard to
|
||||
priority. This has been in effect, if undocumented, for quite some
|
||||
time, but should probably be configurable or reconsidered.
|
||||
|
||||
Tab Completion:
|
||||
z supports tab completion. After any number of arguments, press TAB to
|
||||
complete on directories that match each argument. Due to limitations of
|
||||
the completion implementations, only the last argument will be com-
|
||||
pleted in the shell.
|
||||
|
||||
Internally, z decides you've requested a completion if the last argu-
|
||||
ment passed is an absolute path to an existing directory. This may
|
||||
cause unexpected behavior if the last argument to z begins with /.
|
||||
|
||||
ENVIRONMENT
|
||||
A function _z() is defined.
|
||||
|
||||
The contents of the variable $_Z_CMD is aliased to _z 2>&1. If not set,
|
||||
$_Z_CMD defaults to z.
|
||||
|
||||
The environment variable $_Z_DATA can be used to control the datafile
|
||||
location. If it is not defined, the location defaults to $HOME/.z.
|
||||
|
||||
The environment variable $_Z_NO_RESOLVE_SYMLINKS can be set to prevent
|
||||
resolving of symlinks. If it is not set, symbolic links will be
|
||||
resolved when added to the datafile.
|
||||
|
||||
In bash, z appends a command to the PROMPT_COMMAND environment variable
|
||||
to maintain its database. In zsh, z appends a function _z_precmd to the
|
||||
precmd_functions array.
|
||||
|
||||
The environment variable $_Z_NO_PROMPT_COMMAND can be set if you want
|
||||
to handle PROMPT_COMMAND or precmd yourself.
|
||||
|
||||
The environment variable $_Z_EXCLUDE_DIRS can be set to an array of
|
||||
directories to exclude from tracking. $HOME is always excluded. Direc-
|
||||
tories must be full paths without trailing slashes.
|
||||
|
||||
FILES
|
||||
Data is stored in $HOME/.z. This can be overridden by setting the
|
||||
$_Z_DATA environment variable. When initialized, z will raise an error
|
||||
if this path is a directory, and not function correctly.
|
||||
|
||||
A man page (z.1) is provided.
|
||||
|
||||
SEE ALSO
|
||||
regex(7), pushd, popd, autojump, cdargs
|
||||
|
||||
Please file bugs at https://github.com/rupa/z/
|
||||
|
||||
|
||||
|
||||
z January 2013 Z(1)
|
158
sh/z/z.1
158
sh/z/z.1
|
@ -1,158 +0,0 @@
|
|||
.TH "Z" "1" "January 2013" "z" "User Commands"
|
||||
.SH
|
||||
NAME
|
||||
z \- jump around
|
||||
.SH
|
||||
SYNOPSIS
|
||||
z [\-chlrtx] [regex1 regex2 ... regexn]
|
||||
.SH
|
||||
AVAILABILITY
|
||||
bash, zsh
|
||||
.SH
|
||||
DESCRIPTION
|
||||
Tracks your most used directories, based on 'frecency'.
|
||||
.P
|
||||
After a short learning phase, \fBz\fR will take you to the most 'frecent'
|
||||
directory that matches ALL of the regexes given on the command line.
|
||||
.SH
|
||||
OPTIONS
|
||||
.TP
|
||||
\fB\-c\fR
|
||||
restrict matches to subdirectories of the current directory
|
||||
.TP
|
||||
\fB\-h\fR
|
||||
show a brief help message
|
||||
.TP
|
||||
\fB\-l\fR
|
||||
list only
|
||||
.TP
|
||||
\fB\-r\fR
|
||||
match by rank only
|
||||
.TP
|
||||
\fB\-t\fR
|
||||
match by recent access only
|
||||
.TP
|
||||
\fB\-x\fR
|
||||
remove the current directory from the datafile
|
||||
.SH EXAMPLES
|
||||
.TP 14
|
||||
\fBz foo\fR
|
||||
cd to most frecent dir matching foo
|
||||
.TP 14
|
||||
\fBz foo bar\fR
|
||||
cd to most frecent dir matching foo and bar
|
||||
.TP 14
|
||||
\fBz -r foo\fR
|
||||
cd to highest ranked dir matching foo
|
||||
.TP 14
|
||||
\fBz -t foo\fR
|
||||
cd to most recently accessed dir matching foo
|
||||
.TP 14
|
||||
\fBz -l foo\fR
|
||||
list all dirs matching foo (by frecency)
|
||||
.SH
|
||||
NOTES
|
||||
.SS
|
||||
Installation:
|
||||
.P
|
||||
Put something like this in your \fB$HOME/.bashrc\fR or \fB$HOME/.zshrc\fR:
|
||||
.RS
|
||||
.P
|
||||
\fB. /path/to/z.sh\fR
|
||||
.RE
|
||||
.P
|
||||
\fBcd\fR around for a while to build up the db.
|
||||
.P
|
||||
PROFIT!!
|
||||
.P
|
||||
Optionally:
|
||||
.RS
|
||||
Set \fB$_Z_CMD\fR to change the command name (default \fBz\fR).
|
||||
.RE
|
||||
.RS
|
||||
Set \fB$_Z_DATA\fR to change the datafile (default \fB$HOME/.z\fR).
|
||||
.RE
|
||||
.RS
|
||||
Set \fB$_Z_NO_RESOLVE_SYMLINKS\fR to prevent symlink resolution.
|
||||
.RE
|
||||
.RS
|
||||
Set \fB$_Z_NO_PROMPT_COMMAND\fR to handle \fBPROMPT_COMMAND/precmd\fR yourself.
|
||||
.RE
|
||||
.RS
|
||||
Set \fB$_Z_EXCLUDE_DIRS\fR to an array of directories to exclude.
|
||||
.RE
|
||||
.RS
|
||||
(These settings should go in .bashrc/.zshrc before the lines added above.)
|
||||
.RE
|
||||
.RS
|
||||
Install the provided man page \fBz.1\fR somewhere like \fB/usr/local/man/man1\fR.
|
||||
.RE
|
||||
.SS
|
||||
Aging:
|
||||
The rank of directories maintained by \fBz\fR undergoes aging based on a simple
|
||||
formula. The rank of each entry is incremented every time it is accessed. When
|
||||
the sum of ranks is greater than 6000, all ranks are multiplied by 0.99. Entries
|
||||
with a rank lower than 1 are forgotten.
|
||||
.SS
|
||||
Frecency:
|
||||
Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted rank
|
||||
that depends on how often and how recently something occurred. As far as I
|
||||
know, Mozilla came up with the term.
|
||||
.P
|
||||
To \fBz\fR, a directory that has low ranking but has been accessed recently
|
||||
will quickly have higher rank than a directory accessed frequently a long time
|
||||
ago.
|
||||
.P
|
||||
Frecency is determined at runtime.
|
||||
.SS
|
||||
Common:
|
||||
When multiple directories match all queries, and they all have a common prefix,
|
||||
\fBz\fR will cd to the shortest matching directory, without regard to priority.
|
||||
This has been in effect, if undocumented, for quite some time, but should
|
||||
probably be configurable or reconsidered.
|
||||
.SS
|
||||
Tab Completion:
|
||||
\fBz\fR supports tab completion. After any number of arguments, press TAB to
|
||||
complete on directories that match each argument. Due to limitations of the
|
||||
completion implementations, only the last argument will be completed in the
|
||||
shell.
|
||||
.P
|
||||
Internally, \fBz\fR decides you've requested a completion if the last argument
|
||||
passed is an absolute path to an existing directory. This may cause unexpected
|
||||
behavior if the last argument to \fBz\fR begins with \fB/\fR.
|
||||
.SH
|
||||
ENVIRONMENT
|
||||
A function \fB_z()\fR is defined.
|
||||
.P
|
||||
The contents of the variable \fB$_Z_CMD\fR is aliased to \fB_z 2>&1\fR. If not
|
||||
set, \fB$_Z_CMD\fR defaults to \fBz\fR.
|
||||
.P
|
||||
The environment variable \fB$_Z_DATA\fR can be used to control the datafile
|
||||
location. If it is not defined, the location defaults to \fB$HOME/.z\fR.
|
||||
.P
|
||||
The environment variable \fB$_Z_NO_RESOLVE_SYMLINKS\fR can be set to prevent
|
||||
resolving of symlinks. If it is not set, symbolic links will be resolved when
|
||||
added to the datafile.
|
||||
.P
|
||||
In bash, \fBz\fR appends a command to the \fBPROMPT_COMMAND\fR environment
|
||||
variable to maintain its database. In zsh, \fBz\fR appends a function
|
||||
\fB_z_precmd\fR to the \fBprecmd_functions\fR array.
|
||||
.P
|
||||
The environment variable \fB$_Z_NO_PROMPT_COMMAND\fR can be set if you want to
|
||||
handle \fBPROMPT_COMMAND\fR or \fBprecmd\fR yourself.
|
||||
.P
|
||||
The environment variable \fB$_Z_EXCLUDE_DIRS\fR can be set to an array of
|
||||
directories to exclude from tracking. \fB$HOME\fR is always excluded.
|
||||
Directories must be full paths without trailing slashes.
|
||||
.SH
|
||||
FILES
|
||||
Data is stored in \fB$HOME/.z\fR. This can be overridden by setting the
|
||||
\fB$_Z_DATA\fR environment variable. When initialized, \fBz\fR will raise an
|
||||
error if this path is a directory, and not function correctly.
|
||||
.P
|
||||
A man page (\fBz.1\fR) is provided.
|
||||
.SH
|
||||
SEE ALSO
|
||||
regex(7), pushd, popd, autojump, cdargs
|
||||
.P
|
||||
Please file bugs at https://github.com/rupa/z/
|
236
sh/z/z.sh
236
sh/z/z.sh
|
@ -1,236 +0,0 @@
|
|||
# Copyright (c) 2009 rupa deadwyler under the WTFPL license
|
||||
|
||||
# maintains a jump-list of the directories you actually use
|
||||
#
|
||||
# INSTALL:
|
||||
# * put something like this in your .bashrc/.zshrc:
|
||||
# . /path/to/z.sh
|
||||
# * cd around for a while to build up the db
|
||||
# * PROFIT!!
|
||||
# * optionally:
|
||||
# set $_Z_CMD in .bashrc/.zshrc to change the command (default z).
|
||||
# set $_Z_DATA in .bashrc/.zshrc to change the datafile (default ~/.z).
|
||||
# set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution.
|
||||
# set $_Z_NO_PROMPT_COMMAND if you're handling PROMPT_COMMAND yourself.
|
||||
# set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
|
||||
#
|
||||
# USE:
|
||||
# * z foo # cd to most frecent dir matching foo
|
||||
# * z foo bar # cd to most frecent dir matching foo and bar
|
||||
# * z -r foo # cd to highest ranked dir matching foo
|
||||
# * z -t foo # cd to most recently accessed dir matching foo
|
||||
# * z -l foo # list matches instead of cd
|
||||
# * z -c foo # restrict matches to subdirs of $PWD
|
||||
|
||||
[ -d "${_Z_DATA:-$HOME/.z}" ] && {
|
||||
echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory."
|
||||
}
|
||||
|
||||
_z() {
|
||||
|
||||
local datafile="${_Z_DATA:-$HOME/.z}"
|
||||
|
||||
# bail if we don't own ~/.z (we're another user but our ENV is still set)
|
||||
[ -f "$datafile" -a ! -O "$datafile" ] && return
|
||||
|
||||
# add entries
|
||||
if [ "$1" = "--add" ]; then
|
||||
shift
|
||||
|
||||
# $HOME isn't worth matching
|
||||
[ "$*" = "$HOME" ] && return
|
||||
|
||||
# don't track excluded dirs
|
||||
local exclude
|
||||
for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do
|
||||
[ "$*" = "$exclude" ] && return
|
||||
done
|
||||
|
||||
# maintain the file
|
||||
local tempfile
|
||||
tempfile="$datafile.$RANDOM"
|
||||
while read line; do
|
||||
# only count directories
|
||||
[ -d "${line%%\|*}" ] && echo $line
|
||||
done < "$datafile" | awk -v path="$*" -v now="$(date +%s)" -F"|" '
|
||||
BEGIN {
|
||||
rank[path] = 1
|
||||
time[path] = now
|
||||
}
|
||||
$2 >= 1 {
|
||||
if( $1 == path ) {
|
||||
rank[$1] = $2 + 1
|
||||
time[$1] = now
|
||||
} else {
|
||||
rank[$1] = $2
|
||||
time[$1] = $3
|
||||
}
|
||||
count += $2
|
||||
}
|
||||
END {
|
||||
if( count > 6000 ) {
|
||||
# aging
|
||||
for( i in rank ) print i "|" 0.99*rank[i] "|" time[i]
|
||||
} else for( i in rank ) print i "|" rank[i] "|" time[i]
|
||||
}
|
||||
' 2>/dev/null >| "$tempfile"
|
||||
if [ $? -ne 0 -a -f "$datafile" ]; then
|
||||
env rm -f "$tempfile"
|
||||
else
|
||||
env mv -f "$tempfile" "$datafile" || env rm -f "$tmpfile"
|
||||
fi
|
||||
|
||||
# tab completion
|
||||
elif [ "$1" = "--complete" ]; then
|
||||
while read line; do
|
||||
[ -d "${line%%\|*}" ] && echo $line
|
||||
done < "$datafile" | awk -v q="$2" -F"|" '
|
||||
BEGIN {
|
||||
if( q == tolower(q) ) nocase = 1
|
||||
split(substr(q,3),fnd," ")
|
||||
}
|
||||
{
|
||||
if( nocase ) {
|
||||
for( i in fnd ) tolower($1) !~ tolower(fnd[i]) && $1 = ""
|
||||
} else {
|
||||
for( i in fnd ) $1 !~ fnd[i] && $1 = ""
|
||||
}
|
||||
if( $1 ) print $1
|
||||
}
|
||||
' 2>/dev/null
|
||||
|
||||
else
|
||||
# list/go
|
||||
while [ "$1" ]; do case "$1" in
|
||||
--) while [ "$1" ]; do shift; local fnd="$fnd $1";done;;
|
||||
-*) local opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in
|
||||
c) local fnd="^$PWD $fnd";;
|
||||
h) echo "${_Z_CMD:-z} [-chlrtx] args" >&2; return;;
|
||||
x) sed -i "\:^${PWD}|.*:d" "$datafile";;
|
||||
l) local list=1;;
|
||||
r) local typ="rank";;
|
||||
t) local typ="recent";;
|
||||
esac; opt=${opt:1}; done;;
|
||||
*) local fnd="$fnd $1";;
|
||||
esac; local last=$1; shift; done
|
||||
[ "$fnd" -a "$fnd" != "^$PWD " ] || local list=1
|
||||
|
||||
# if we hit enter on a completion just go there
|
||||
case "$last" in
|
||||
# completions will always start with /
|
||||
/*) [ -z "$list" -a -d "$last" ] && cd "$last" && return;;
|
||||
esac
|
||||
|
||||
# no file yet
|
||||
[ -f "$datafile" ] || return
|
||||
|
||||
local cd
|
||||
cd="$(while read line; do
|
||||
[ -d "${line%%\|*}" ] && echo $line
|
||||
done < "$datafile" | awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" '
|
||||
function frecent(rank, time) {
|
||||
# relate frequency and time
|
||||
dx = t-time
|
||||
if( dx < 3600 ) return rank*4
|
||||
if( dx < 86400 ) return rank*2
|
||||
if( dx < 604800 ) return rank/2
|
||||
return rank/4
|
||||
}
|
||||
function output(files, toopen, common) {
|
||||
# list or return the desired directory
|
||||
if( list ) {
|
||||
cmd = "sort -n >&2"
|
||||
for( i in files ) {
|
||||
if( files[i] ) printf "%-10s %s\n", files[i], i | cmd
|
||||
}
|
||||
if( common ) {
|
||||
printf "%-10s %s\n", "common:", common > "/dev/stderr"
|
||||
}
|
||||
} else {
|
||||
if( common ) toopen = common
|
||||
print toopen
|
||||
}
|
||||
}
|
||||
function common(matches) {
|
||||
# find the common root of a list of dirs, if it exists
|
||||
for( i in matches ) {
|
||||
if( matches[i] && (!short || length(i) < length(short)) ) {
|
||||
short = i
|
||||
}
|
||||
}
|
||||
if( short == "/" ) return
|
||||
# use a copy to escape special characters, as we want to return
|
||||
# the original.
|
||||
clean_short = short
|
||||
gsub(/[\(\)\[\]\|]/, "\\\\&", clean_short)
|
||||
for( i in matches ) if( matches[i] && i !~ clean_short ) return
|
||||
return short
|
||||
}
|
||||
BEGIN { split(q, a, " "); oldf = noldf = -9999999999 }
|
||||
{
|
||||
if( typ == "rank" ) {
|
||||
f = $2
|
||||
} else if( typ == "recent" ) {
|
||||
f = $3-t
|
||||
} else f = frecent($2, $3)
|
||||
wcase[$1] = nocase[$1] = f
|
||||
for( i in a ) {
|
||||
if( $1 !~ a[i] ) delete wcase[$1]
|
||||
if( tolower($1) !~ tolower(a[i]) ) delete nocase[$1]
|
||||
}
|
||||
if( wcase[$1] && wcase[$1] > oldf ) {
|
||||
cx = $1
|
||||
oldf = wcase[$1]
|
||||
} else if( nocase[$1] && nocase[$1] > noldf ) {
|
||||
ncx = $1
|
||||
noldf = nocase[$1]
|
||||
}
|
||||
}
|
||||
END {
|
||||
if( cx ) {
|
||||
output(wcase, cx, common(wcase))
|
||||
} else if( ncx ) output(nocase, ncx, common(nocase))
|
||||
}
|
||||
')"
|
||||
[ $? -gt 0 ] && return
|
||||
[ "$cd" ] && cd "$cd"
|
||||
fi
|
||||
}
|
||||
|
||||
alias ${_Z_CMD:-z}='_z 2>&1'
|
||||
|
||||
[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P"
|
||||
|
||||
if compctl &> /dev/null; then
|
||||
# zsh
|
||||
[ "$_Z_NO_PROMPT_COMMAND" ] || {
|
||||
# populate directory list, avoid clobbering any other precmds
|
||||
if [ "$_Z_NO_RESOLVE_SYMLINKS" ]; then
|
||||
_z_precmd() {
|
||||
_z --add "${PWD:a}"
|
||||
}
|
||||
else
|
||||
_z_precmd() {
|
||||
_z --add "${PWD:A}"
|
||||
}
|
||||
fi
|
||||
precmd_functions+=(_z_precmd)
|
||||
}
|
||||
_z_zsh_tab_completion() {
|
||||
# tab completion
|
||||
local compl
|
||||
read -l compl
|
||||
reply=(${(f)"$(_z --complete "$compl")"})
|
||||
}
|
||||
compctl -U -K _z_zsh_tab_completion _z
|
||||
elif complete &> /dev/null; then
|
||||
# bash
|
||||
# tab completion
|
||||
complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z}
|
||||
[ "$_Z_NO_PROMPT_COMMAND" ] || {
|
||||
# bash populate directory list. avoid clobbering other PROMPT_COMMANDs.
|
||||
grep -q "_z --add" <<< "$PROMPT_COMMAND" || {
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''_z --add "$(pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null;'
|
||||
}
|
||||
}
|
||||
fi
|
Loading…
Add table
Reference in a new issue