Initial commit
This commit is contained in:
commit
cefd40b6dc
6
README.md
Normal file
6
README.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# crater's script collection
|
||||||
|
|
||||||
|
Some scripts that I wrote over the years and wanted to store with versioning
|
||||||
|
somewhere. Maybe some of them are useful for others.
|
||||||
|
|
||||||
|
Documentation may or may not follow, some scripts include a `--help` output.
|
3
bin/alert
Executable file
3
bin/alert
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
time=$1; shift
|
||||||
|
echo "DISPLAY=:0.0 sm \"$@\"" | at $time
|
14
bin/autoless
Executable file
14
bin/autoless
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
if [[ -n "$@" ]]; then
|
||||||
|
out=$(<"$@")
|
||||||
|
else
|
||||||
|
out=$(cat)
|
||||||
|
fi
|
||||||
|
((lim=$LINES-1))
|
||||||
|
numlines=$(echo $out | wc -l)
|
||||||
|
if (( $numlines > $lim ))
|
||||||
|
then
|
||||||
|
echo $out | less -R
|
||||||
|
else
|
||||||
|
echo $out
|
||||||
|
fi
|
17
bin/dbus-find
Executable file
17
bin/dbus-find
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
if [[ $1 == "-u" ]]; then
|
||||||
|
USER=$2
|
||||||
|
SUDO="sudo -u $USER"
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
SUDO=
|
||||||
|
fi
|
||||||
|
|
||||||
|
export "$({for i in $(pgrep -u $USER dbus-daemon); grep -z DBUS_SESSION_BUS_ADDRESS /proc/$i/environ} | head -n 1)"
|
||||||
|
if [[ -z $DBUS_SESSION_BUS_ADDRESS ]]; then
|
||||||
|
echo "No DBUS found"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exec $=SUDO "$@"
|
||||||
|
fi
|
66
bin/dmjavadoc
Executable file
66
bin/dmjavadoc
Executable file
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'dmenu'
|
||||||
|
|
||||||
|
JAVA_DOC_LOCATION = "/usr/share/doc/api"
|
||||||
|
JAVAFX_DOC_LOCATION = "/usr/share/doc/javafx-sdk-docs-*"
|
||||||
|
|
||||||
|
USER_DOC_LOCATION = (ENV['XDG_DATA_HOME'] || ENV['HOME'] + '/.local/share') + '/javadoc/*'
|
||||||
|
|
||||||
|
class DocIndex
|
||||||
|
attr_reader :items
|
||||||
|
|
||||||
|
def initialize(path)
|
||||||
|
@items = []
|
||||||
|
find_entries(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def gen_candidates(dir)
|
||||||
|
Dir.entries(dir).reject {|e| e == '.' ||
|
||||||
|
e == '..' ||
|
||||||
|
e == 'class-use' ||
|
||||||
|
e == 'src-html' ||
|
||||||
|
(e =~ /^[a-z].*\..*/ && e != 'package-summary.html')}
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_entries(dir, path = [])
|
||||||
|
candidates = gen_candidates(dir)
|
||||||
|
candidates.each do |entry|
|
||||||
|
if entry == "package-summary.html"
|
||||||
|
@items << Dmenu::Item.new(path.join(?.), dir + ?/ + entry)
|
||||||
|
elsif entry.end_with? ".html"
|
||||||
|
@items << Dmenu::Item.new(
|
||||||
|
path.join(?.) + ?. + File.basename(entry, '.html'),
|
||||||
|
dir + ?/ + entry
|
||||||
|
)
|
||||||
|
elsif File.directory?(dir + ?/ + entry)
|
||||||
|
find_entries(dir + ?/ + entry, path + [entry])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
user_libs = Dir.glob(USER_DOC_LOCATION)
|
||||||
|
java_folder = Dir.glob(JAVA_DOC_LOCATION).last
|
||||||
|
jfx_folder = Dir.glob(JAVAFX_DOC_LOCATION).last + "/html"
|
||||||
|
|
||||||
|
|
||||||
|
libmenu = Dmenu.new
|
||||||
|
libmenu.items = [
|
||||||
|
Dmenu::Item.new("Java Standard Library (std)", java_folder),
|
||||||
|
Dmenu::Item.new("javafx", jfx_folder)
|
||||||
|
] + user_libs.map{|f| Dmenu::Item.new(File.basename(f), f)}
|
||||||
|
|
||||||
|
libmenu.case_insensitive = true
|
||||||
|
libmenu.prompt = "Library:"
|
||||||
|
libmenu.lines = 20
|
||||||
|
|
||||||
|
menu = Dmenu.new
|
||||||
|
menu.items = DocIndex.new(libmenu.run.value).items
|
||||||
|
menu.case_insensitive = true
|
||||||
|
menu.prompt = "Javadoc:"
|
||||||
|
menu.lines = 20
|
||||||
|
system("xdg-open #{menu.run.value}")
|
91
bin/dmpc
Executable file
91
bin/dmpc
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
dmenu_opts=("" "-i")
|
||||||
|
replace=("-r")
|
||||||
|
|
||||||
|
zparseopts -E -D -K -help=help \
|
||||||
|
a=artist -artist=artist \
|
||||||
|
b=album -album=album \
|
||||||
|
t=title -title=title \
|
||||||
|
j=jump -jump=jump \
|
||||||
|
r=replace -replace=replace R=replace -no-replace=replace \
|
||||||
|
o:=dmenu_opts -dmenu-opts:=dmenu_opts \
|
||||||
|
h:=host -host:=host \
|
||||||
|
p:=port -port:=port
|
||||||
|
|
||||||
|
if [ -n "$help" ]; then
|
||||||
|
<<-HELP
|
||||||
|
dmpc: manage mpd playlist with dmenu
|
||||||
|
|
||||||
|
Usage: dmpc {-a|-b|-t|-j} [OPTION]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-a, --artist search for artist
|
||||||
|
-b, --album search for album
|
||||||
|
-t, --title search for title
|
||||||
|
-j, --jump jump to song in current playlist (requires rofi)
|
||||||
|
(if given in addition to searches, jumps after changes)
|
||||||
|
|
||||||
|
-r, --replace replace current playlist
|
||||||
|
-R, --no-replace do not replace current playlist
|
||||||
|
-o, --dmenu-opts additional options for dmenu
|
||||||
|
|
||||||
|
-h, --host MPD host server
|
||||||
|
-p, --port server port
|
||||||
|
|
||||||
|
dmpc lets you select all tracks from an artist or album or a single track.
|
||||||
|
HELP
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$artist" && -z "$album" && -z "$title" ]]; then
|
||||||
|
<<-ERR
|
||||||
|
At least one of -a, -b, -t or -j must be given. See --help for more information.
|
||||||
|
ERR
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
typeset -a queries
|
||||||
|
|
||||||
|
mpc_() {
|
||||||
|
mpc $=host $=port "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dmenu_search() {
|
||||||
|
local type=$1
|
||||||
|
mpc_ list $type "${queries[@]}" | dmenu ${=dmenu_opts[2]}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_query() {
|
||||||
|
local type=$1
|
||||||
|
local query=$2
|
||||||
|
|
||||||
|
queries+=$type
|
||||||
|
queries+=$query
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -n $artist ]]; then
|
||||||
|
add_query albumartist "$(dmenu_search artist)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $album ]]; then
|
||||||
|
add_query album "$(dmenu_search album)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $title ]]; then
|
||||||
|
add_query title "$(dmenu_search title)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${replace[1]} == "-r" || "${replace[1]}" == "--replace" ]]; then
|
||||||
|
mpc_ clear
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ ${#queries} -gt 0 ]]; then
|
||||||
|
mpc_ search "${queries[@]}" | mpc_ add
|
||||||
|
mpc_ play
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $jump ]]; then
|
||||||
|
mpc play "$(mpc playlist | rofi -dmenu -format d)"
|
||||||
|
fi
|
52
bin/dmscaladoc
Executable file
52
bin/dmscaladoc
Executable file
|
@ -0,0 +1,52 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'dmenu'
|
||||||
|
|
||||||
|
JAVA_DOC_LOCATION = "/home/crater2150/manuals/scala-*"
|
||||||
|
|
||||||
|
USER_DOC_LOCATION = (ENV['XDG_DATA_HOME'] || ENV['HOME'] + '/.local') + '/scaladoc/*'
|
||||||
|
|
||||||
|
class DocIndex
|
||||||
|
attr_reader :items
|
||||||
|
|
||||||
|
def initialize(path)
|
||||||
|
@items = []
|
||||||
|
find_entries(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def gen_candidates(dir)
|
||||||
|
Dir.entries(dir).reject {|e| e == '.' ||
|
||||||
|
e == '..' ||
|
||||||
|
e == 'class-use' ||
|
||||||
|
e == 'src-html' ||
|
||||||
|
(e =~ /^[a-z].*\..*/ && e != 'package-summary.html')}
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_entries(dir, path = [])
|
||||||
|
candidates = gen_candidates(dir)
|
||||||
|
candidates.each do |entry|
|
||||||
|
if entry == "package-summary.html"
|
||||||
|
@items << Dmenu::Item.new(path.join(?.), dir + ?/ + entry)
|
||||||
|
elsif entry.end_with? ".html"
|
||||||
|
@items << Dmenu::Item.new(
|
||||||
|
path.join(?.) + ?. + File.basename(entry, '.html'),
|
||||||
|
dir + ?/ + entry
|
||||||
|
)
|
||||||
|
elsif File.directory?(dir + ?/ + entry)
|
||||||
|
find_entries(dir + ?/ + entry, path + [entry])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
scala_folder = Dir.glob(JAVA_DOC_LOCATION).last + "/api/scala-library/"
|
||||||
|
|
||||||
|
menu = Dmenu.new
|
||||||
|
menu.items = DocIndex.new(scala_folder).items
|
||||||
|
menu.case_insensitive = true
|
||||||
|
menu.prompt = "Javadoc:"
|
||||||
|
menu.lines = 20
|
||||||
|
system("xdg-open #{menu.run.value}")
|
30
bin/dmscrot
Executable file
30
bin/dmscrot
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'dmenu'
|
||||||
|
|
||||||
|
def run_menu(items, prompt)
|
||||||
|
menu = Dmenu.new
|
||||||
|
menu.case_insensitive = true
|
||||||
|
menu.lines = items.length
|
||||||
|
menu.items = items
|
||||||
|
menu.prompt = prompt
|
||||||
|
menu.run.value
|
||||||
|
end
|
||||||
|
modes = [
|
||||||
|
Dmenu::Item.new('multidisp', '-m'),
|
||||||
|
Dmenu::Item.new('select', '-s'),
|
||||||
|
Dmenu::Item.new('focused', '-u -d 1'),
|
||||||
|
Dmenu::Item.new('normal', '')
|
||||||
|
]
|
||||||
|
|
||||||
|
actions = [
|
||||||
|
Dmenu::Item.new('move to screenshots', 'mv $f ~/media/screenshots'),
|
||||||
|
Dmenu::Item.new('view image', 'xdg-open $f'),
|
||||||
|
Dmenu::Item.new('make draggable', 'dragon -x $f'),
|
||||||
|
Dmenu::Item.new('nothing', 'true')
|
||||||
|
]
|
||||||
|
|
||||||
|
mode = run_menu(modes, "Screenshot type")
|
||||||
|
action = run_menu(actions, "and then")
|
||||||
|
|
||||||
|
system('scrot', mode, '-e', action)
|
187
bin/dmsearch
Executable file
187
bin/dmsearch
Executable file
|
@ -0,0 +1,187 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
emulate -L zsh
|
||||||
|
|
||||||
|
SYSTEM_CONFIG_PATH='/etc/dmsearch'
|
||||||
|
CONFIG_PATH="$HOME/.config/dmsearch"
|
||||||
|
CACHE_PATH="$HOME/.cache/dmsearch"
|
||||||
|
mkdir -p "${CACHE_PATH}"
|
||||||
|
|
||||||
|
# required software
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
local script="$1"; shift;
|
||||||
|
local missing
|
||||||
|
local i
|
||||||
|
|
||||||
|
for i in "$@"; do
|
||||||
|
type "$i" &>/dev/null || {
|
||||||
|
echo >&2 "$i is required for ${script}. Please install it"
|
||||||
|
missing=1
|
||||||
|
}
|
||||||
|
done
|
||||||
|
[ -n "$missing" ] && exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
depend dmsearch \
|
||||||
|
rofi \
|
||||||
|
mv \
|
||||||
|
tail \
|
||||||
|
cut
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# helpers
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
urlencode() {
|
||||||
|
setopt extendedglob
|
||||||
|
input=$(</dev/stdin)
|
||||||
|
# by jkramer, source: http://stackoverflow.com/a/187853/928769
|
||||||
|
echo "${${(j: :)input}//(#b)(?)/%$[[##16]##${match[1]}]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# define a module option
|
||||||
|
# Parameters:
|
||||||
|
# 1: module id
|
||||||
|
# 2: option name
|
||||||
|
# 3: default value
|
||||||
|
# 4: description
|
||||||
|
optdef() {
|
||||||
|
typeset -A -g opts_${1}
|
||||||
|
local optname="opt_${1}_${2}"
|
||||||
|
eval "if [ -z \"\$${optname}\" ]; then
|
||||||
|
${optname}=\"$3\";
|
||||||
|
fi"
|
||||||
|
eval "opts_${1}[$2]=\"${4:-"undocumented"}\""
|
||||||
|
}
|
||||||
|
|
||||||
|
# get history for a search
|
||||||
|
# parameters:
|
||||||
|
# 1: search, for which to get history
|
||||||
|
dmhist() {
|
||||||
|
local search=$1
|
||||||
|
local dmhistfile="$CACHE_PATH/history_$search"
|
||||||
|
if [[ -e "$dmhistfile" ]] then
|
||||||
|
<"$dmhistfile"
|
||||||
|
else
|
||||||
|
</dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# add history for a search.
|
||||||
|
#
|
||||||
|
# Older entries can be truncated by specifying the maximum history length.
|
||||||
|
#
|
||||||
|
# parameters:
|
||||||
|
# 1: search, for which to add history
|
||||||
|
# 2: the new entry for the history file
|
||||||
|
# 3: (optional) maximum number of history items to store
|
||||||
|
dmhistadd() {
|
||||||
|
local search=$1
|
||||||
|
local line=$2
|
||||||
|
[[ -z "$2" ]] && return
|
||||||
|
local truncate=${3:-"+0"}
|
||||||
|
local dmhistfile="$CACHE_PATH/history_$search"
|
||||||
|
echo "$line" >> "$dmhistfile"
|
||||||
|
mv "$dmhistfile" "${dmhistfile}.tmp"
|
||||||
|
tail -n ${truncate} "${dmhistfile}.tmp" > "${dmhistfile}"
|
||||||
|
rm "${dmhistfile}.tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
# freetext rofi with a default value.
|
||||||
|
#
|
||||||
|
# When called, opens a rofi with only one choice. Pressing enter without any
|
||||||
|
dmdefault() {
|
||||||
|
value=$(echo "$2" | rofi -dmenu -l 1 -p "$1" -sort-method fzf)
|
||||||
|
if [[ "$value" == "$2" ]]; then
|
||||||
|
$=3
|
||||||
|
else
|
||||||
|
echo "$value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# plugin loading
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# system plugins are loaded first, so they can be overridden by user plugins
|
||||||
|
for i in "(${SYSTEM_CONFIG_PATH}/searchers/"*(N) \
|
||||||
|
"${CONFIG_PATH}/searchers/"*(N); do
|
||||||
|
. "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Configurable Options
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# querystring
|
||||||
|
|
||||||
|
SERCHILO="https://www.findfind.it/u/crater2150?query="
|
||||||
|
|
||||||
|
# some default values. all of them can be overridden by rc.zsh
|
||||||
|
typeset -A searches
|
||||||
|
searches=( g Google w Wikipedia )
|
||||||
|
webbrowser_cmd="xdg-open"
|
||||||
|
|
||||||
|
[[ -e "${SYSTEM_CONFIG_PATH}/rc.zsh" ]] && . "${SYSTEM_CONFIG_PATH}/rc.zsh"
|
||||||
|
[[ -e "${CONFIG_PATH}/rc.zsh" ]] && . "${CONFIG_PATH}/rc.zsh"
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# main script
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
zparseopts -D -E -help=help h=help
|
||||||
|
|
||||||
|
if [ -n "$help" ]; then
|
||||||
|
<<-HELP
|
||||||
|
dmsearch [-h]
|
||||||
|
Opens dmenu and lets you run web searches
|
||||||
|
|
||||||
|
configured searches:
|
||||||
|
HELP
|
||||||
|
|
||||||
|
for k in ${(k)searches}; do
|
||||||
|
echo " ${k}:\t${(Q)searches[$k]}";
|
||||||
|
done
|
||||||
|
|
||||||
|
<<-HELP
|
||||||
|
|
||||||
|
defined module options:
|
||||||
|
HELP
|
||||||
|
for k in ${(k)searches}; do
|
||||||
|
eval "if [ \"\${#opts_$k}\" -gt 0 ]; then
|
||||||
|
echo \" Module ${(Q)searches[$k]}:\";
|
||||||
|
for o in \${(k)opts_${k}}; do
|
||||||
|
echo \" opt_${k}_\${o}: \${opts_${k}[\$o]}\";
|
||||||
|
done
|
||||||
|
fi"
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start dmenu
|
||||||
|
coproc dmenu -i -l 20 -p 'serchilo widget:'
|
||||||
|
|
||||||
|
# generate menu elements
|
||||||
|
for i in ${(k)searches}; do print -p "${i} - ${searches[$i]}"; done
|
||||||
|
|
||||||
|
# close coproc stdin
|
||||||
|
exec 5>&p 6<&p; coproc exit; exec 5>&-
|
||||||
|
|
||||||
|
# get dmenu result
|
||||||
|
search=$(read -eu 6 | cut -d" " -f1)
|
||||||
|
|
||||||
|
[[ -z "$search" ]] && exit 1 #user aborted
|
||||||
|
|
||||||
|
|
||||||
|
if which "s_${search}" &>/dev/null; then
|
||||||
|
qs=$(s_${search})
|
||||||
|
else
|
||||||
|
qs="${SERCHILO}${search}"
|
||||||
|
result=$(dmhist "$search" | dmenu -i -l 20 -p "params to $search")
|
||||||
|
dmhistadd "$search" "$result"
|
||||||
|
qs+="+$(echo $result| urlencode)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ${webbrowser_cmd} $qs
|
||||||
|
${webbrowser_cmd} $qs
|
17
bin/dmtexdoc
Executable file
17
bin/dmtexdoc
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
zparseopts -D -E -help=help h=help -update=update u=update
|
||||||
|
|
||||||
|
CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/dtexdoc.list"
|
||||||
|
SOURCES_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/dmtexdoc/sources"
|
||||||
|
|
||||||
|
if [[ -n "$help" ]]; then
|
||||||
|
echo "Usage: $0 [-u|--update]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$update" || ! -e "$CACHE_FILE" ]]; then
|
||||||
|
find -L ${$(which texdoc):h:h:h}/texmf-dist/doc/ "${(@f)$(<$SOURCES_FILE)}" \
|
||||||
|
-iname '*.pdf' -printf "%f\n" \
|
||||||
|
| sed -e 's/\..*//' | sort | uniq > $CACHE_FILE
|
||||||
|
fi
|
||||||
|
texdoc $(dmenu < $CACHE_FILE)
|
5
bin/dmumount
Executable file
5
bin/dmumount
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
device=$(udiskie-info -a -o '{mount_path}' | grep -ve '^$' | dmenu -l 20)
|
||||||
|
if [[ -n "$device" ]]; then
|
||||||
|
udiskie-umount $device
|
||||||
|
fi
|
39
bin/dmxrandr
Executable file
39
bin/dmxrandr
Executable file
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'xrandr'
|
||||||
|
require 'dmenu'
|
||||||
|
|
||||||
|
menu = Dmenu.new
|
||||||
|
menu.case_insensitive = true
|
||||||
|
menu.lines = 20
|
||||||
|
|
||||||
|
outputs = Xrandr::Parser.new.parse[1].group_by(&:connected)
|
||||||
|
|
||||||
|
menu.items = (outputs[true] + outputs[false]).map{
|
||||||
|
|o| Dmenu::Item.new(o.name + (o.connected ? ' (connected)' : ''), o)
|
||||||
|
}
|
||||||
|
menu.prompt = "output:"
|
||||||
|
output = menu.run.value
|
||||||
|
|
||||||
|
menu.items = output.modes.map{
|
||||||
|
|mode|Dmenu::Item.new(mode.resolution, {mode: mode.resolution})
|
||||||
|
}
|
||||||
|
menu.items << Dmenu::Item.new("off", {off: true})
|
||||||
|
|
||||||
|
menu.prompt = "Current resolution: #{output.resolution}"
|
||||||
|
mode = menu.run.value
|
||||||
|
|
||||||
|
unless mode[:off]
|
||||||
|
menu.items = [:"left-of", :"right-of", :"above", :"below"].flat_map{|dir|
|
||||||
|
outputs[true].reject{|o| o == output}.map{|out| [dir,out]}
|
||||||
|
}.map{|setting|
|
||||||
|
Dmenu::Item.new(setting[0].to_s.gsub('-',' ') + " " + setting[1].name,
|
||||||
|
{setting[0] => setting[1].name})
|
||||||
|
}
|
||||||
|
menu.items << Dmenu::Item.new("don't change", {})
|
||||||
|
menu.prompt = "Select position:"
|
||||||
|
mode.merge! menu.run.value
|
||||||
|
end
|
||||||
|
control = Xrandr::Control.new
|
||||||
|
control.configure(output, mode)
|
||||||
|
control.apply!
|
5
bin/fixenc
Executable file
5
bin/fixenc
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
for i in "$@"; do
|
||||||
|
dos2unix $i &>/dev/null
|
||||||
|
iconv -fLATIN1 -tUTF8 $i | sponge $i
|
||||||
|
done
|
6
bin/idea
Executable file
6
bin/idea
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
unset JAVA_HOME
|
||||||
|
source /etc/profile.d/11_oracle-jdk.sh
|
||||||
|
export IBUS_ENABLE_SYNC_MODE=1
|
||||||
|
export XMODIFIERS=""
|
||||||
|
exec $(ls ${XDG_DATA_HOME:-~/.local/share}/idea-IU-*/bin/idea.sh | sort | tail -n 1)
|
20
bin/ipy
Executable file
20
bin/ipy
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
if [[ -n $VIRTUAL_ENV ]]; then
|
||||||
|
pip install ipython &>/dev/null
|
||||||
|
else
|
||||||
|
cd ~/toy-projects/playground_venv/
|
||||||
|
. bin/activate
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e $VIRTUAL_ENV/ipython_profile ]]; then
|
||||||
|
ipy_profile="--profile=$(<$VIRTUAL_ENV/ipython_profile)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "pip" ]]; then
|
||||||
|
exec "$@"
|
||||||
|
elif [[ $1 == "-s" ]]; then
|
||||||
|
exec $SHELL
|
||||||
|
else
|
||||||
|
exec ipython $ipy_profile "$@"
|
||||||
|
fi
|
11
bin/mdcat
Executable file
11
bin/mdcat
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
MDCAT=/usr/bin/mdcat
|
||||||
|
encoding=$(file -i "$1" | sed "s/.*charset=\(.*\)$/\1/")
|
||||||
|
if ! iconv -f $encoding <<<"" &> /dev/null; then
|
||||||
|
cat "$1"
|
||||||
|
elif [[ $encoding != 'utf-8' ]]; then
|
||||||
|
iconv -f $encoding -t 'utf-8' < "$1" | $MDCAT /dev/stdin
|
||||||
|
else
|
||||||
|
$MDCAT $1
|
||||||
|
fi
|
13
bin/mkscript
Executable file
13
bin/mkscript
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
BINDIR=$HOME/.local/bin
|
||||||
|
if [[ -e $BINDIR/$1 ]]; then
|
||||||
|
echo Script $1 exists, opening for edit
|
||||||
|
$EDITOR $BINDIR/$1
|
||||||
|
else
|
||||||
|
touch $BINDIR/$1
|
||||||
|
chmod a+x $BINDIR/$1
|
||||||
|
echo "#!$SHELL" >> $BINDIR/$1
|
||||||
|
$EDITOR $BINDIR/$1
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
75
bin/newmails
Executable file
75
bin/newmails
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
DEFAULT=raw
|
||||||
|
ICON=/usr/share/icons/Adwaita/48x48/actions/mail-message-new.png
|
||||||
|
|
||||||
|
opt() {
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
contains() {
|
||||||
|
arr=$1
|
||||||
|
value=$2
|
||||||
|
[[ ${${(P)arr}[(ie)$value]} -lt ${#${(P)arr}} ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
zparseopts -D -E h=help -help=help \
|
||||||
|
r=raw -raw=raw \
|
||||||
|
n=number -number=number \
|
||||||
|
p=pretty -pretty=pretty
|
||||||
|
|
||||||
|
if [ -n "$help" ]; then
|
||||||
|
cat <<HELP
|
||||||
|
Usage: newmails [OPTIONS] [MAILDIR]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h --help Show this help
|
||||||
|
-r --raw Show full paths to new mail files (default)
|
||||||
|
-n --number Only show number of new mails
|
||||||
|
-p --pretty Show formatted output of new mails (TODO)
|
||||||
|
|
||||||
|
HELP
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local md=${MAILDIR:-${MAIL:-$HOME/Mail}}
|
||||||
|
local cache=${XDG_CACHE_HOME:-$HOME/.cache}/seen-mails
|
||||||
|
|
||||||
|
newmails=$(find $md/ -type f -a \
|
||||||
|
\( -regex ".*:2,[PRTDF]*" \) -exec realpath \{\} \;)
|
||||||
|
|
||||||
|
decode(){
|
||||||
|
perl -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \
|
||||||
|
sed -e 's/&/\&/' -e 's/</\</' -e 's/>/\>/'
|
||||||
|
}
|
||||||
|
|
||||||
|
from() { formail -zcb -xFrom | tail -n 1 | decode }
|
||||||
|
subject() { formail -zcb -xSubject | decode }
|
||||||
|
|
||||||
|
|
||||||
|
if opt $number; then
|
||||||
|
echo -n $newmails | wc -l
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if opt $pretty; then
|
||||||
|
touch $cache
|
||||||
|
seen=$(<$cache)
|
||||||
|
truncate --size 0 $cache
|
||||||
|
notify-send --icon=$ICON "$(
|
||||||
|
echo -n $newmails | while read mail; do
|
||||||
|
if ! contains seen $mail; then
|
||||||
|
echo -n "<b>$(from < $mail):</b> $(subject < $mail)<br>"
|
||||||
|
fi
|
||||||
|
echo $mail >> $cache
|
||||||
|
done
|
||||||
|
)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
#otherwise
|
||||||
|
echo -n $newmails
|
7
bin/pdftosvg
Executable file
7
bin/pdftosvg
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
for i in "$@"; do
|
||||||
|
inkscape --without-gui --file=$i --export-plain-svg=/dev/stdout \
|
||||||
|
| tr -d '\n' \
|
||||||
|
| sed -e 's!</\?tspan[^>]*>!!g' \
|
||||||
|
| xmllint --compress /dev/stdin --output ${i:r}.svg
|
||||||
|
done
|
74
bin/pomdep-graph
Executable file
74
bin/pomdep-graph
Executable file
|
@ -0,0 +1,74 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
zparseopts -D -K -E h=help -help=help -renderer:=renderer r:=renderer \
|
||||||
|
f:=filter -filter:=filter \
|
||||||
|
o:=output -output:=output \
|
||||||
|
l:=leaf_color -leaf-color:=leaf_color \
|
||||||
|
G=graph_only -graph-only=graph_only
|
||||||
|
|
||||||
|
renderer=${renderer[2]:-dot}
|
||||||
|
output=${output[2]:-deps.png}
|
||||||
|
leaf_color=${leaf_color[2]:-green}
|
||||||
|
|
||||||
|
if [[ $output == "-" ]]; then output=/dev/stdout; fi
|
||||||
|
if [[ -n $graph_only ]]; then
|
||||||
|
renderer=cat
|
||||||
|
output=/dev/stdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
echo "Usage: $0 [options] POM_FILE..."
|
||||||
|
echo
|
||||||
|
echo "Options:"
|
||||||
|
echo " -f, --filter=TEXT only show dependencies with TEXT in their group id"
|
||||||
|
echo " -r, --renderer=PROGRAM use PROGRAM for rendering. May contain additional parameters"
|
||||||
|
echo " e.g. -r \"dot -Goverlap=false\""
|
||||||
|
echo " default: dot -Tpng"
|
||||||
|
echo " -o, --output=FILE output to FILE, defaults to deps.png"
|
||||||
|
echo " -l, --leaf-color=COLOR color of leaf nodes (packages without dependencies)"
|
||||||
|
echo " -G, --graph-only output unlayouted graph code, overrides -r and -o"
|
||||||
|
echo " equivalent to \"-r cat -o /dev/stdout\""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $filter ]]; then
|
||||||
|
DEP_PATH="//dependencies//groupId[contains(text(),'${filter[2]}')]/following-sibling::artifactId/text()"
|
||||||
|
else
|
||||||
|
DEP_PATH="//dependencies//groupId/following-sibling::artifactId/text()"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PKG_PATH="/project/artifactId/text()"
|
||||||
|
|
||||||
|
xpath() {
|
||||||
|
xmllint --shell <(sed -e "s/xmlns=/ignore=/" $2) <<<"cat $1" | grep -v '^\(/ >\| --\)'
|
||||||
|
}
|
||||||
|
|
||||||
|
remove-disconnected() {
|
||||||
|
gvpr -c "N[$.degree==0]{delete(NULL, $)}" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
color-leaf-deps() {
|
||||||
|
gvpr -c "N[$.outdegree==0]{$.color ='$1'}"
|
||||||
|
}
|
||||||
|
|
||||||
|
graph-from-poms() {
|
||||||
|
echo 'digraph deps {'
|
||||||
|
|
||||||
|
for pom in "$@"; do
|
||||||
|
pkg=$(xpath $PKG_PATH $pom)
|
||||||
|
deps=($(xpath $DEP_PATH $pom | grep '^[a-zA-Z]'))
|
||||||
|
|
||||||
|
echo " \"$pkg\""
|
||||||
|
for i in $deps; do
|
||||||
|
echo " \"$pkg\" -> \"$i\""
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
echo '}'
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
$=renderer > $output
|
||||||
|
}
|
||||||
|
|
||||||
|
graph-from-poms "$@" | remove-disconnected | color-leaf-deps $leaf_color | render
|
2
bin/qrshow
Executable file
2
bin/qrshow
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
qrencode -s 40 "$*" -o - | feh -ZF -
|
40
bin/re
Executable file
40
bin/re
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
SCRIPTDIR=$XDG_CONFIG_HOME/re/
|
||||||
|
|
||||||
|
zparseopts -D h=help -help=help d:=dir -dir:=dir n=dry_run -dry-run=dry_run e=edit -edit=edit
|
||||||
|
if [[ -z "$@" || -n $help ]]; then
|
||||||
|
<<-HELP
|
||||||
|
re - execute regular jobs without cluttering your path
|
||||||
|
|
||||||
|
Usage: re [opts] <scriptname> [scriptopts]
|
||||||
|
1. put script in $SCRIPTDIR
|
||||||
|
2. run "re <scriptname>"
|
||||||
|
3. ...
|
||||||
|
4. PROFIT!
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-d, --dir=DIR change to given directory
|
||||||
|
-n, --dry-run just display the script, that would be executed
|
||||||
|
-e, --edit open the script in an editor
|
||||||
|
HELP
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $dir ]]; then
|
||||||
|
cd $dir[2]
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e $SCRIPTDIR/$1 ]]; then
|
||||||
|
if [[ -n $dry_run ]]; then
|
||||||
|
$PAGER -F $SCRIPTDIR/$1
|
||||||
|
elif [[ -n $edit ]]; then
|
||||||
|
$EDITOR $SCRIPTDIR/$1
|
||||||
|
else
|
||||||
|
script=$1
|
||||||
|
shift
|
||||||
|
. $SCRIPTDIR/$script "$@"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Script \"$1\" not found"
|
||||||
|
fi
|
5
bin/tmux-url-fuzz
Executable file
5
bin/tmux-url-fuzz
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
target=$(tmux capture-pane -e -p -J -S -20 \
|
||||||
|
| grep -oP "(https?://|www\.)[^\"<>') \e]*" \
|
||||||
|
| ifne fzf-tmux --tac)
|
||||||
|
if [[ -n $target ]]; then xdg-open $target; fi
|
56
bin/unlock-parse
Executable file
56
bin/unlock-parse
Executable file
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'time'
|
||||||
|
|
||||||
|
def valid_log(lines)
|
||||||
|
lines.reduce(["L",true]){|acc,line|
|
||||||
|
if acc[1] && line[0] != acc[0] then
|
||||||
|
[line[0], true]
|
||||||
|
else
|
||||||
|
[nil, false]
|
||||||
|
end
|
||||||
|
}[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV[0] == '-h' then
|
||||||
|
puts <<~HELP
|
||||||
|
Usage: unlock-parse [-s] DAY...
|
||||||
|
-s short output, total only
|
||||||
|
HELP
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV[0] == '-s' then
|
||||||
|
short=true
|
||||||
|
days=ARGV[1..-1]
|
||||||
|
else
|
||||||
|
short=false
|
||||||
|
days=ARGV
|
||||||
|
end
|
||||||
|
|
||||||
|
days.empty? && days = [Date.today.iso8601]
|
||||||
|
|
||||||
|
days.each do |logday|
|
||||||
|
|
||||||
|
|
||||||
|
path = if File.exists? logday then logday else ENV['XDG_DATA_HOME'] + '/log/locktime/' + logday end
|
||||||
|
|
||||||
|
log = File.readlines(path)
|
||||||
|
|
||||||
|
if ! valid_log(log) then puts "Invalid log file"; exit 1 end
|
||||||
|
|
||||||
|
if log.length % 2 != 0 then
|
||||||
|
log << "L " + Time.now.iso8601
|
||||||
|
end
|
||||||
|
|
||||||
|
times = log.each_slice(2).map{|e|
|
||||||
|
Time.parse(e[1][2..-1]) - Time.parse(e[0][2..-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! short then
|
||||||
|
times.map{|t| Time.at(t).utc.strftime("%H:%M:%S")}.each{|s|puts s}
|
||||||
|
puts "\nTotal:"
|
||||||
|
end
|
||||||
|
puts Time.at(times.sum).utc.strftime("%H:%M:%S")
|
||||||
|
|
||||||
|
end
|
22
bin/unlock-track
Executable file
22
bin/unlock-track
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
lockstate() { pidof slimlock &>/dev/null }
|
||||||
|
|
||||||
|
lockstate; was_locked=$?
|
||||||
|
|
||||||
|
LOGDIR=${XDG_DATA_HOME:-$HOME/.local/share}/log/locktime
|
||||||
|
mkdir -p $LOGDIR
|
||||||
|
logfile=$LOGDIR/$(date --iso-8601)
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if lockstate && [[ $was_locked -gt 0 ]]; then
|
||||||
|
echo "L $(date --iso-8601=minute)" >> $logfile
|
||||||
|
was_locked=0
|
||||||
|
elif ! lockstate && [[ $was_locked == 0 ]]; then
|
||||||
|
# change daily logfile on first unlock
|
||||||
|
logfile=$LOGDIR/$(date --iso-8601)
|
||||||
|
echo "U $(date --iso-8601=minute)" >> $logfile
|
||||||
|
was_locked=1
|
||||||
|
fi
|
||||||
|
sleep 60
|
||||||
|
done
|
13
bin/update-amm
Executable file
13
bin/update-amm
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
versions=$(curl -L https://api.github.com/repos/lihaoyi/Ammonite/releases/latest)
|
||||||
|
|
||||||
|
download-version() {
|
||||||
|
(
|
||||||
|
echo "#/usr/bin/env python --version sh" && \
|
||||||
|
curl -L $( echo $versions \
|
||||||
|
| jq -r ".assets | map(select(.name | startswith(\"$1\")))[0].browser_download_url")
|
||||||
|
) > $2
|
||||||
|
chmod +x $2
|
||||||
|
}
|
||||||
|
download-version 2.13 $(which amm)
|
||||||
|
download-version 2.12 $(which amm)2.12
|
36
bin/venv
Executable file
36
bin/venv
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
zparseopts -D -E c=cdhere -cdhere=cdhere h=help -help=help
|
||||||
|
if [[ -n $help ]]; then
|
||||||
|
<<-HELP
|
||||||
|
Usage: ${0:t} [-c] [DIR]
|
||||||
|
|
||||||
|
If DIR contains bin/activate, start a shell with that virtualenv.
|
||||||
|
Otherwise recursively look up virtualenvs in DIR (by looking for dirs ending
|
||||||
|
in "venv") and select one with fzf.
|
||||||
|
|
||||||
|
-c, --cdhere Change back to the current working directory instead of the
|
||||||
|
virtual env's base dir
|
||||||
|
HELP
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
ORIGDIR=$PWD
|
||||||
|
|
||||||
|
venvsh() {
|
||||||
|
cd $1
|
||||||
|
. bin/activate
|
||||||
|
if [[ -n $cdhere ]]; then
|
||||||
|
cd $ORIGDIR
|
||||||
|
fi
|
||||||
|
$SHELL
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -n $1 && -e $1/bin/activate ]]; then
|
||||||
|
exec venvsh $1
|
||||||
|
fi
|
||||||
|
|
||||||
|
venv=$(fd -I -t d 'venv$' $1 | fzf)
|
||||||
|
if [[ -n $venv ]]; then
|
||||||
|
venvsh $venv
|
||||||
|
fi
|
20
bin/vf
Executable file
20
bin/vf
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
zparseopts -D -E -ext:=ext e:=ext h=help -help=help
|
||||||
|
|
||||||
|
if [[ -n $help ]]; then
|
||||||
|
<<-HELP
|
||||||
|
Usage: ${0:t} [-e EXT | PATTERN] [DIR...]
|
||||||
|
|
||||||
|
Find files with fd, show them with fzf and open selected files via xdg-open.
|
||||||
|
|
||||||
|
Either -e with a file extension or a pattern can be given to narrow search.
|
||||||
|
Any further arguments are passed to fd as search path.
|
||||||
|
HELP
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $ext ]]; then
|
||||||
|
fd -e ${ext[2]} . "$@"
|
||||||
|
else
|
||||||
|
fd "$@"
|
||||||
|
fi | fzf | xargs --null xdg-open
|
10
bin/webapp
Executable file
10
bin/webapp
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
profile="${0:t}"
|
||||||
|
|
||||||
|
need firefox
|
||||||
|
need firejail
|
||||||
|
|
||||||
|
mkdir -p $HOME/.jails/firefox-$profile
|
||||||
|
|
||||||
|
exec firejail --private=$HOME/.jails/firefox-$profile \
|
||||||
|
firefox --no-remote "$@"
|
3
bin/webapp-cp
Executable file
3
bin/webapp-cp
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
profile="${${0:t}%%-cp}"
|
||||||
|
cp "$@" $HOME/.jails/firefox-$profile
|
83
bin/xc
Executable file
83
bin/xc
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
# install this program with the name xc and symlink it as xs.
|
||||||
|
# xc will use the clipboard selection, while xs while use the primary selection
|
||||||
|
|
||||||
|
source $(which need)
|
||||||
|
need xclip
|
||||||
|
|
||||||
|
function get_primary() { xclip -o -selection primary }
|
||||||
|
function get_clipboard() { xclip -o -selection clipboard }
|
||||||
|
function set_primary() { xclip -i -selection primary }
|
||||||
|
function set_clipboard() { xclip -i -selection clipboard }
|
||||||
|
function show_both() {
|
||||||
|
printf "\e[1;94mPrimary\e[0m\n"
|
||||||
|
get_primary
|
||||||
|
echo
|
||||||
|
printf "\e[1;94mClipboard\e[0m\n"
|
||||||
|
get_clipboard
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_both() {
|
||||||
|
need pee moreutils
|
||||||
|
pee "xclip -i -selection primary" "xclip -i -selection clipboard"
|
||||||
|
}
|
||||||
|
|
||||||
|
function common() {
|
||||||
|
cmd=$1
|
||||||
|
getc=$2
|
||||||
|
setc=$3
|
||||||
|
shift 3
|
||||||
|
case "$cmd" in
|
||||||
|
"read") $setc;;
|
||||||
|
"readboth") read_both ;;
|
||||||
|
"showboth") show_both ;;
|
||||||
|
"sed") $getc | sed -e "$@" | $setc; $getc;;
|
||||||
|
"pipe") $getc | "$@" | $setc; $getc;;
|
||||||
|
"edit") need vipe moreutils; $getc | vipe | $setc; $getc;;
|
||||||
|
"") $getc ;;
|
||||||
|
*) <<-HELP
|
||||||
|
Usage: xc [COMMAND]
|
||||||
|
xc fromxs|toxs
|
||||||
|
xs [COMMAND]
|
||||||
|
xs fromxc|toxc
|
||||||
|
|
||||||
|
The used X selection is determined by the name the program is called as:
|
||||||
|
xc: clipboard (Ctrl-C / Ctrl-V)
|
||||||
|
xs: primary selection (middle mouse button)
|
||||||
|
For showboth/readboth, the action is done for both selections.
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
show/showboth: show contents of clipboard (default if no command given)
|
||||||
|
read/readboth: store input to clipboard
|
||||||
|
sed: modify contents using a sed expression
|
||||||
|
pipe: modify contents by piping through a command
|
||||||
|
edit: edit clipboard contents using \$EDITOR
|
||||||
|
|
||||||
|
fromxs/toxs: xc only: copy contents from or to primary selection
|
||||||
|
fromxc/toxc: xs only: copy contents from or to clipboard
|
||||||
|
HELP
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd=$1
|
||||||
|
[[ -n $1 ]] && shift
|
||||||
|
|
||||||
|
case "${0:t}" in
|
||||||
|
xc)
|
||||||
|
case "$cmd" in
|
||||||
|
"fromxs"|"fromXS") get_primary | set_clipboard ;;
|
||||||
|
"toxs"|"toXS") get_clipboard | set_primary ;;
|
||||||
|
*) common "$cmd" get_clipboard set_clipboard "$@";;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
xs)
|
||||||
|
case "$cmd" in
|
||||||
|
"fromxc"|"fromXC") get_clipboard | set_primary ;;
|
||||||
|
"toxc"|"toXC") get_primary | set_clipboard ;;
|
||||||
|
*) common "$cmd" get_primary set_primary "$@";;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
Loading…
Reference in a new issue