Compare commits
94 Commits
d0c4c84117
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
832cfe42c3 | ||
|
|
bf213e469f | ||
|
|
0bd8a43d4f | ||
|
|
186dfa8096 | ||
|
|
0769d7a789 | ||
|
|
4dfd87462c | ||
|
|
1cc3015bb5 | ||
|
|
a3954fb9dc | ||
|
|
a074d5b67d | ||
|
|
ff04acca3a | ||
|
|
6028f3a023 | ||
|
|
9764ad6f1f | ||
|
|
72850600e5 | ||
|
|
0d3de71e2c | ||
|
|
d318a58bb0 | ||
|
|
299a3c8b51 | ||
|
|
6a3fe358f3 | ||
|
|
a0d78823ae | ||
|
|
8f37eceb9a | ||
|
|
0530d9228b | ||
|
|
15b0116633 | ||
|
|
6bbb12e7b3 | ||
|
|
1a2d91b0d7 | ||
|
|
13bedaa7d3 | ||
|
|
3b839841ac | ||
|
|
9f365fe933 | ||
|
|
62d5edaf29 | ||
|
|
1371b1c8a2 | ||
|
|
e900fc1f35 | ||
|
|
ed8624ef01 | ||
|
|
475bef8131 | ||
|
|
3794862593 | ||
|
|
8bce1b28b3 | ||
|
|
7fc3348d20 | ||
|
|
068de67638 | ||
|
|
00f804c99f | ||
|
|
ee9207d716 | ||
|
|
3c6adda31b | ||
|
|
7a70f07a67 | ||
|
|
33471962fb | ||
|
|
cc3afde694 | ||
|
|
685a3b4c8d | ||
|
|
b0cc6ce138 | ||
|
|
a992796635 | ||
|
|
20f3483f9c | ||
|
|
87a300f0c4 | ||
|
|
908090c41b | ||
|
|
5f346e4848 | ||
|
|
45969796dc | ||
|
|
fa6a52b1a3 | ||
|
|
02239e52a3 | ||
|
|
767ba27c2b | ||
|
|
08aaf050a6 | ||
|
|
1c9a2b446a | ||
|
|
6b2b5ae779 | ||
|
|
d8fff6ec32 | ||
|
|
26abaf99b2 | ||
|
|
0bda01c32e | ||
|
|
6db769365d | ||
|
|
9f55042b33 | ||
|
|
9ffce7022e | ||
|
|
7c5d1f298f | ||
|
|
3768436e21 | ||
|
|
8d1878581b | ||
|
|
e9581ec17d | ||
|
|
7eb3f826fb | ||
|
|
2357c34813 | ||
|
|
1f15f715a6 | ||
|
|
346463127c | ||
|
|
3e58a36599 | ||
|
|
6a240c970c | ||
|
|
e548ab67c8 | ||
|
|
b86b992a6a | ||
|
|
31c62ae69a | ||
|
|
ec7fbad49f | ||
|
|
1bb57985ca | ||
|
|
ac58f6baa9 | ||
|
|
b2c7bcd12a | ||
|
|
e2edc9d2b6 | ||
|
|
70c63ad427 | ||
|
|
ae5183fa58 | ||
|
|
19fc60ef8b | ||
|
|
0701e19f1e | ||
|
|
1ecd621a69 | ||
|
|
b3b69a682a | ||
|
|
180588879c | ||
|
|
0582999ac9 | ||
|
|
fa50579054 | ||
|
|
e27a96f17e | ||
|
|
ebae25d46e | ||
|
|
a145968b49 | ||
|
|
7948d7cd1d | ||
|
|
e304b53c34 | ||
|
|
2e1234e383 |
@@ -1,7 +1,6 @@
|
|||||||
! -- CURSOR --!
|
! -- CURSOR --!
|
||||||
!Xcursor.size: 32
|
Xcursor.size: 48
|
||||||
Xcursor.size: 32
|
Xcursor.theme: Adwaita
|
||||||
Xcursor.theme:
|
|
||||||
xterm.cursorTheme:
|
xterm.cursorTheme:
|
||||||
|
|
||||||
! -- XFT -- !
|
! -- XFT -- !
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
ZONE=codevoid.de
|
|
||||||
|
|
||||||
if [ ! -z $1 ]
|
|
||||||
then
|
|
||||||
ZONE=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ssh -t dns.codevoid.de \
|
|
||||||
"doas vim /var/nsd/zones/master/$ZONE \
|
|
||||||
&& doas nsd-control reload"
|
|
||||||
|
|
||||||
sleep 2
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
. $HOME/.bin/_config
|
|
||||||
|
|
||||||
print "Tarsnap Restore:"
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
doas tarsnap --list-archives | sort
|
|
||||||
printf "Usage: restore <key_id>\n"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
_backup="$(doas tarsnap --list-archives | grep "$1")"
|
|
||||||
if [ -z "$_backup" ]; then
|
|
||||||
print "No backup with key id $1 found."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir "restore_$1"
|
|
||||||
doas tarsnap --humanize-numbers -xvf "$_backup" -C "restore_$1"
|
|
||||||
print "Data restored in $(readlink -f "restore_$1")"
|
|
||||||
@@ -69,7 +69,8 @@ needs() {
|
|||||||
|| add="$add $x"
|
|| add="$add $x"
|
||||||
done
|
done
|
||||||
[ ! -z "$add" ] \
|
[ ! -z "$add" ] \
|
||||||
&& doas pkg_add -- $add
|
&& doas pkg_add -- $add \
|
||||||
|
|| true
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
70
.bin/aria
70
.bin/aria
@@ -3,6 +3,35 @@
|
|||||||
DIR="/home/sdk/.aria2"
|
DIR="/home/sdk/.aria2"
|
||||||
mkdir -p "$DIR"
|
mkdir -p "$DIR"
|
||||||
|
|
||||||
|
SECOPTS="\
|
||||||
|
--bt-enable-lpd=false
|
||||||
|
--enable-peer-exchange=false
|
||||||
|
--enable-dht=false
|
||||||
|
--enable-dht6=false
|
||||||
|
"
|
||||||
|
|
||||||
|
PUBLIC="\
|
||||||
|
--dht-listen-port=55500
|
||||||
|
--bt-enable-lpd=true
|
||||||
|
--enable-peer-exchange=true
|
||||||
|
--enable-dht=true
|
||||||
|
--enable-dht6=true
|
||||||
|
"
|
||||||
|
|
||||||
|
DEFAULT="\
|
||||||
|
--auto-save-interval=60
|
||||||
|
--listen-port=55500
|
||||||
|
--disk-cache=256M
|
||||||
|
--bt-save-metadata=true
|
||||||
|
--bt-load-saved-metadata=true
|
||||||
|
--bt-prioritize-piece=head=10M,tail=10M
|
||||||
|
--content-disposition-default-utf8=true
|
||||||
|
--dht-file-path=$DIR/dht.dat
|
||||||
|
--dht-file-path6=$DIR/dht6.dat
|
||||||
|
--save-cookies=$DIR/cookies.dat
|
||||||
|
--save-session=$DIR/session.dat
|
||||||
|
"
|
||||||
|
|
||||||
for cmd in $@
|
for cmd in $@
|
||||||
do
|
do
|
||||||
case $cmd in
|
case $cmd in
|
||||||
@@ -10,7 +39,7 @@ do
|
|||||||
OPTS="$OPTS
|
OPTS="$OPTS
|
||||||
--seed-ratio=0.0
|
--seed-ratio=0.0
|
||||||
--max-overall-upload-limit=5M
|
--max-overall-upload-limit=5M
|
||||||
--max-overall-download-limit=1
|
--max-overall-download-limit=200K
|
||||||
--check-integrity=true
|
--check-integrity=true
|
||||||
--bt-hash-check-seed=true
|
--bt-hash-check-seed=true
|
||||||
--bt-seed-unverified=true
|
--bt-seed-unverified=true
|
||||||
@@ -19,7 +48,7 @@ do
|
|||||||
shift ;;
|
shift ;;
|
||||||
download|dl)
|
download|dl)
|
||||||
OPTS="$OPTS
|
OPTS="$OPTS
|
||||||
--max-overall-upload-limit=1
|
--max-overall-upload-limit=200K
|
||||||
--max-overall-download-limit=85M
|
--max-overall-download-limit=85M
|
||||||
--seed-time=0
|
--seed-time=0
|
||||||
--lowest-speed-limit=30K
|
--lowest-speed-limit=30K
|
||||||
@@ -28,36 +57,29 @@ do
|
|||||||
-j 6
|
-j 6
|
||||||
"
|
"
|
||||||
shift ;;
|
shift ;;
|
||||||
overwrite|over|force)
|
overwrite|force)
|
||||||
OPTS="$OPTS
|
OPTS="$OPTS
|
||||||
--allow-overwrite=true"
|
--allow-overwrite=true
|
||||||
|
"
|
||||||
shift ;;
|
shift ;;
|
||||||
1) OPTS="$OPTS -j 1"
|
enc|encrypt) OPTS="$OPTS
|
||||||
|
--bt-require-crypto
|
||||||
|
--bt-min-crypto-level=arc4
|
||||||
|
"
|
||||||
|
shift ;;
|
||||||
|
pub|public) SECOPTS="$PUBLIC"
|
||||||
|
shift ;;
|
||||||
|
seq|1) OPTS="$OPTS
|
||||||
|
-j 1 -Z
|
||||||
|
"
|
||||||
shift ;;
|
shift ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
DEFAULT="\
|
|
||||||
--enable-dht=false
|
|
||||||
--enable-dht6=false
|
|
||||||
--bt-force-encryption=true
|
|
||||||
--enable-peer-exchange=false
|
|
||||||
--auto-save-interval=30
|
|
||||||
--save-session-interval=30
|
|
||||||
--bt-enable-lpd=false
|
|
||||||
--bt-save-metadata=true
|
|
||||||
--bt-load-saved-metadata=true
|
|
||||||
--bt-prioritize-piece=head=10M,tail=10M
|
|
||||||
--log=$DIR/aria2.log
|
|
||||||
--dht-file-path=$DIR/dht.dat
|
|
||||||
--dht-file-path6=$DIR/dht6.dat
|
|
||||||
--save-cookies=$DIR/cookies.dat
|
|
||||||
--save-session=$DIR/session.dat
|
|
||||||
"
|
|
||||||
set -x
|
set -x
|
||||||
if [ -z "$@" ]
|
if [ -z "$@" ]
|
||||||
then
|
then
|
||||||
aria2c $DEFAULT $OPTS *.torrent
|
aria2c $DEFAULT $OPTS $SECOPTS *.torrent
|
||||||
else
|
else
|
||||||
aria2c $DEFAULT $OPTS "$@"
|
aria2c $DEFAULT $OPTS $SECOPTS "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
150
.bin/blog
Executable file
150
.bin/blog
Executable file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# hugo cli frontend
|
||||||
|
# needs: sh, fzf, grep, cat, cut tr, date (bsd date...), hugo, vim
|
||||||
|
# deployments are handled using a Makefile (bring your own...)
|
||||||
|
|
||||||
|
cd "$HOME/blog"
|
||||||
|
|
||||||
|
for _arg
|
||||||
|
do
|
||||||
|
case $_arg in
|
||||||
|
update)
|
||||||
|
make update
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# extra options appended to the menu
|
||||||
|
_extra="---
|
||||||
|
maintenance * Maintenance Mode
|
||||||
|
new * New Post
|
||||||
|
quit * Quit Main Menu"
|
||||||
|
|
||||||
|
# main loop
|
||||||
|
while [ -z "$_quit" ]
|
||||||
|
do
|
||||||
|
|
||||||
|
# parse csv, build and show list
|
||||||
|
_selection=$(hugo list all \
|
||||||
|
| grep -Ev ^path \
|
||||||
|
| while read _line
|
||||||
|
do
|
||||||
|
# csv fields:
|
||||||
|
# 1: path
|
||||||
|
# 2: slug
|
||||||
|
# 3: title
|
||||||
|
# 4: date
|
||||||
|
# 5: expiryDate
|
||||||
|
# 6: publishDate
|
||||||
|
# 7: draft
|
||||||
|
# 8: permalink
|
||||||
|
# 9: kind
|
||||||
|
# 10: section
|
||||||
|
_file="$(echo $_line | cut -d"," -f1)"
|
||||||
|
_title="$(echo $_line | cut -d"," -f3)"
|
||||||
|
_draft=$(echo $_line | cut -d"," -f7)
|
||||||
|
_draft_fmt=$([ "$_draft" == "true" ] && echo "(draft)")
|
||||||
|
_date="$(echo $_line | cut -d"," -f4)"
|
||||||
|
_date_fmt=$(date -f "%Y-%m-%dT%H:%M:%S" -j "$_date" +"%Y-%m-%d %H:%M")
|
||||||
|
_type=$(echo "$_file" | grep -q "_index.md$" && echo "page" || echo "post")
|
||||||
|
|
||||||
|
echo "$_file * $_date_fmt | $_type | $_title $_draft_fmt"
|
||||||
|
|
||||||
|
done | (sort -t" " -k 2; echo "$_extra") \
|
||||||
|
| fzf -e --tac +s --with-nth 2.. \
|
||||||
|
| cut -d" " -f1)
|
||||||
|
|
||||||
|
### functions
|
||||||
|
_new() {
|
||||||
|
unset _newquit
|
||||||
|
while [ -z "$_newquit" ]
|
||||||
|
do
|
||||||
|
unset _newtitle
|
||||||
|
unset _filename
|
||||||
|
|
||||||
|
echo "Enter Post Title"
|
||||||
|
echo -n ": "
|
||||||
|
read _newtitle
|
||||||
|
if [ -n "$_newtitle" ]
|
||||||
|
then
|
||||||
|
# Welcome to my awful filename generator / sanitizer.
|
||||||
|
# Improvements are welcome!
|
||||||
|
_filename=$(echo "$_newtitle" \
|
||||||
|
| tr -d '?!%$:\\' \
|
||||||
|
| tr ' ./' '_' \
|
||||||
|
| tr -s '_' \
|
||||||
|
| tr '[:upper:]' '[:lower:]' \
|
||||||
|
| sed 's/_$//g;s/^_//g')
|
||||||
|
fi
|
||||||
|
if [ -n "$_filename" ]
|
||||||
|
then
|
||||||
|
echo "Creating:"
|
||||||
|
echo "File: content/posts/$_filename.md"
|
||||||
|
echo "Title: $_newtitle"
|
||||||
|
echo -n "Ok? [Y/n]: "
|
||||||
|
read _ok
|
||||||
|
case "$_ok" in
|
||||||
|
[nN]) ;;
|
||||||
|
*) hugo new content --editor=vim "content/posts/$_filename.md"
|
||||||
|
_newquit=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
echo "No title entered. Returning to menu."
|
||||||
|
_newquit=1
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
_edit_entry() {
|
||||||
|
unset _quitmenu
|
||||||
|
while [ -z "$_quitmenu" ]
|
||||||
|
do
|
||||||
|
clear
|
||||||
|
_f="${_newname:-$1}"
|
||||||
|
echo "--- $_f:"
|
||||||
|
echo
|
||||||
|
head -15 "$_f"
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
echo "Filename: $(basename "$_f")"
|
||||||
|
echo "Options: [E]dit, [D]elete, [R]ename, [T]oggle draft, [Q]uit Edit Menu"
|
||||||
|
echo -n ": "
|
||||||
|
read _opt
|
||||||
|
case $_opt in
|
||||||
|
[dD]) mkdir -p .trash; mv -f "$_f" .trash/
|
||||||
|
_quitmenu=1 ;;
|
||||||
|
[qQ]) return ;;
|
||||||
|
[tT]) grep -qE '^draft.*=.*false' "$_f" \
|
||||||
|
&& sed -i 's/^draft.*=.*false/draft = true/' "$_f" \
|
||||||
|
|| sed -i 's/^draft.*=.*true/draft = false/' "$_f" ;;
|
||||||
|
[rR]) echo "old: $(basename "$_f")"
|
||||||
|
echo -n "new: "
|
||||||
|
read _newname;
|
||||||
|
echo -n "ok? [Y/n]: "
|
||||||
|
read _ok
|
||||||
|
case "$_ok" in
|
||||||
|
[nN]) unset _newname ;;
|
||||||
|
*) _newname="content/posts/$_newname"
|
||||||
|
mv -vf "$_f" "$_newname"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*) vim "$_f" ;;
|
||||||
|
[qQ]) _quitmenu=1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$_selection" in
|
||||||
|
new) _new ;;
|
||||||
|
---) ;;
|
||||||
|
maintenance) make maintenance ;;
|
||||||
|
quit) _quit=1; echo "Good bye." ;;
|
||||||
|
*) [ -n "$_selection" ] \
|
||||||
|
&& _edit_entry "$_selection" \
|
||||||
|
|| _quit=1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
10
.bin/bupstash-backup
Executable file
10
.bin/bupstash-backup
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
hostname=$(hostname)
|
||||||
|
year=$(date +%Y)
|
||||||
|
month=$(date +%m)
|
||||||
|
day=$(date +%d)
|
||||||
|
timestamp="$year-$month-$day $(date +"%H:%M")"
|
||||||
|
|
||||||
|
set -x
|
||||||
|
bupstash put --print-file-actions --print-stats hostname="$hostname" timestamp="$timestamp" year="$year" month="$month" day="$day" $@
|
||||||
101
.bin/cam
101
.bin/cam
@@ -1,4 +1,101 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#ffplay -f v4l2 -list_formats all -i /dev/video0
|
|
||||||
_SWM_WS=-1 ffplay -loglevel quiet -f v4l2 -input_format mjpeg -video_size 424x240 -i /dev/video0 $@ &
|
|
||||||
|
|
||||||
|
# defaults
|
||||||
|
_format="-input_format mjpeg"
|
||||||
|
_dev="/dev/video0"
|
||||||
|
|
||||||
|
# loop through arguments
|
||||||
|
for arg in $@
|
||||||
|
do
|
||||||
|
# set values based of arguments found
|
||||||
|
case $arg in
|
||||||
|
s|start) _start=1 ;;
|
||||||
|
k|kill|stop) _stop=1 ;;
|
||||||
|
l|list) _list=1 ;;
|
||||||
|
30) _fps="-framerate 30" ;;
|
||||||
|
60) _fps="-framerate 60" ;;
|
||||||
|
raw) _format="-input_format yuyv422" ;;
|
||||||
|
nv12) _format="-input_format nv12" ;;
|
||||||
|
fullhd) _res="-video_size 1920x1080" ;;
|
||||||
|
hd) _res="-video_size 1280x720" ;;
|
||||||
|
sd) _res="-video_size 640x360" ;;
|
||||||
|
max) _res="max" ;;
|
||||||
|
[0-9]*x[0-9]*) _res="-video_size $arg" ;;
|
||||||
|
[0-9]) _dev="/dev/video$arg" ;;
|
||||||
|
*) _unknown="$_unknown $arg" ;;
|
||||||
|
esac
|
||||||
|
shift;
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -z "$_unknown" ]
|
||||||
|
then
|
||||||
|
echo "unknown parameter(s): $_unknown"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set resolution
|
||||||
|
if [ x"$_res" == x"max" ]
|
||||||
|
then
|
||||||
|
_res="-video_size $(ffplay -f v4l2 -list_formats all -i $_dev 2>&1 \
|
||||||
|
| grep mjpeg \
|
||||||
|
| xargs \
|
||||||
|
| cut -d":" -f4 \
|
||||||
|
| tr ' ' '\n' \
|
||||||
|
| sort -n \
|
||||||
|
| tail -1
|
||||||
|
)"
|
||||||
|
_format="-input_format mjpeg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# list supported formats + resolutions
|
||||||
|
if [ ! -z "$_list" ]
|
||||||
|
then
|
||||||
|
command="$(echo "ffplay -f v4l2 -list_formats all -i $_dev")"
|
||||||
|
echo "starting: $command"
|
||||||
|
$command 2>&1 \
|
||||||
|
| grep '^\[video4linux2' \
|
||||||
|
| cut -d: -f3,4 \
|
||||||
|
| sed -e 's/^[ \t]*//;s/ : /: /'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$_start" ]
|
||||||
|
then
|
||||||
|
command="ffplay -loglevel quiet -f v4l2 $_fps $_format $_res -i $_dev"
|
||||||
|
echo "starting: $command" | xargs
|
||||||
|
_SWM_WS=-1 $command > /dev/null 2>&1 &
|
||||||
|
[ $? -ne 0 ] \
|
||||||
|
&& echo "ffplay couldn't start"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$_stop" ]
|
||||||
|
then
|
||||||
|
echo "stopping: ffplay -loglevel quiet -f v4l2"
|
||||||
|
pkill -qf "ffplay -loglevel quiet -f v4l2"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $(( _start + _stop + _list )) -eq 0 ]
|
||||||
|
then
|
||||||
|
echo "usage: cam command [framerate] [format] [resolution] [device]"
|
||||||
|
echo " commands:"
|
||||||
|
echo " start - start camera"
|
||||||
|
echo " stop - stop camera"
|
||||||
|
echo " list - list supported formats and resolutions"
|
||||||
|
echo " formats:"
|
||||||
|
echo " raw - reads the yuyv422 stream (instead of mjpeg)"
|
||||||
|
echo " nv12 - reads the nv12 stream (instead of mjpeg)"
|
||||||
|
echo " resolutions:"
|
||||||
|
echo " sd - set video size to 640x360"
|
||||||
|
echo " hd - set video size to 1280x720"
|
||||||
|
echo " fullhd - set video size to 1920x1080"
|
||||||
|
echo " max - set maximum video size (implies mjpeg format)"
|
||||||
|
echo " <width>x<height> - manually set resolution (see list command)"
|
||||||
|
echo " framerates:"
|
||||||
|
echo " 30 - set framerate to 30 fps"
|
||||||
|
echo " 60 - set framerate to 60 fps"
|
||||||
|
echo " <device> - set video device number (defaults to 0)"
|
||||||
|
echo
|
||||||
|
echo " Note: ffplay may not start or fall back to internal defaults when options (or combinations thereof) are not supported by the camera."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|||||||
11
.bin/cdrip2flac
Executable file
11
.bin/cdrip2flac
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -xe
|
||||||
|
alias flac_encode="flac -e --best --delete-input-file"
|
||||||
|
doas chown sdk /dev/rcd0* /dev/cd0*
|
||||||
|
cdio cdrip
|
||||||
|
for i in *.wav;
|
||||||
|
do
|
||||||
|
flac_encode "$i" -o "${i%%.wav}.flac";
|
||||||
|
done
|
||||||
|
picard *.flac
|
||||||
|
cdio eject
|
||||||
204
.bin/chrome
204
.bin/chrome
@@ -1,62 +1,146 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#/usr/local/bin/ungoogled-chromium \
|
|
||||||
#export DBUS_SESSION_BUS_ADDRESS="unix:path=/dev/null"
|
|
||||||
export ENABLE_WASM=Yes
|
|
||||||
/usr/local/bin/chrome \
|
|
||||||
--no-first-run \
|
|
||||||
--disable-crash-reporter \
|
|
||||||
--disable-logging \
|
|
||||||
--disable-login-animations \
|
|
||||||
--disable-notifications \
|
|
||||||
--disable-infobars \
|
|
||||||
--disable-dev-shm-usage \
|
|
||||||
--log-level=0 \
|
|
||||||
--hide-crash-restore-bubble \
|
|
||||||
--no-default-browser-check \
|
|
||||||
--high-dpi-support=1 \
|
|
||||||
--force-device-scale-factor=1.5 \
|
|
||||||
--new-window "$@"
|
|
||||||
|
|
||||||
# --bwsi \
|
# flag documentation:
|
||||||
# --disable-auto-reload \
|
# https://peter.sh/experiments/chromium-command-line-switches/
|
||||||
# --disable-breakpad \
|
|
||||||
# --disable-client-side-phishing-detection \
|
# helper functions
|
||||||
# --disable-component-cloud-policy \
|
addflag() { FLAGS="$FLAGS $1"; }
|
||||||
# --disable-component-update \
|
enable() { ENABLED_FEATURES="$ENABLED_FEATURES $1"; }
|
||||||
# --disable-crash-reporter \
|
disable() { DISABLED_FEATURES="$DISABLED_FEATURES $1"; }
|
||||||
# --disable-device-discovery-notifications \
|
|
||||||
# --disable-logging \
|
###
|
||||||
# --disable-login-animations \
|
### SETUP ENVIRONMENT
|
||||||
# --disable-notifications \
|
###
|
||||||
# --disable-pinch \
|
|
||||||
# --disable-software-rasterizer \
|
# disable WASM (OpenBSD specific)
|
||||||
# --disable-chrome-browser-cloud-management \
|
#export ENABLE_WASM=0
|
||||||
# --disable-field-trial-config \
|
|
||||||
# --disable-cookie-encryption \
|
# Nuke DBUS
|
||||||
# --disable-cloud-print-proxy \
|
# some webpages suggest value "disabled:"
|
||||||
# --dbus-stub \
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/dev/null"
|
||||||
# --cros-disks-fake \
|
|
||||||
# --disable-stack-profiler \
|
###
|
||||||
# --disable-touch-drag-drop \
|
### CHROMIUM FLAGS
|
||||||
# --disable-usb-keyboard-detect \
|
###
|
||||||
# --disable-default-apps \
|
|
||||||
# --disable-histogram-customizer \
|
# disable pledge (OpenBSD specific)
|
||||||
# --disable-in-process-stack-traces \
|
#addflag "--no-sandbox"
|
||||||
# --no-service-autorun \
|
|
||||||
# --no-experiments \
|
# disable unveil (OpenBSD specific)
|
||||||
# --use-gl=egl \
|
#addflag "--disable-unveil"
|
||||||
# --force-dark-mode \
|
|
||||||
# --enable-features=WebUIDarkMode \
|
# Skip First Run tasks as well as not showing additional dialogs,
|
||||||
# --hide-crash-restore-bubble \
|
# prompts or bubbles. Suppressing dialogs, prompts, and bubbles is
|
||||||
# --no-default-browser-check \
|
# important as this switch is used by automation (including performance
|
||||||
# --no-proxy-server \
|
# benchmarks) where it's important only a browser window is shown. This
|
||||||
# --no-recovery-component \
|
# may not actually be the first run or the What's New page. Overridden
|
||||||
# --password-store=basic \
|
# by kForceFirstRun (for FRE) and kForceWhatsNew (for What's New). This
|
||||||
# --structured-metrics-disabled \
|
# does not drop the First Run sentinel and thus doesn't prevent first run
|
||||||
# --wm-window-animations-disabled \
|
# from occurring the next time chrome is launched without this flag. It
|
||||||
# #--enable-features=RunVideoCaptureServiceInBrowserProcess,WebUIDarkMode \
|
# also does not update the last What's New milestone, so does not prevent
|
||||||
# #--use-gl=egl \
|
# What's New from occurring the next time chrome is launched without this
|
||||||
# --disable-yuv-image-decoding \
|
# flag.
|
||||||
# --use-gl=desktop \
|
addflag "--no-first-run"
|
||||||
# --high-dpi-support=1 \
|
|
||||||
# --force-device-scale-factor=1.5 \
|
# Enables TLS/SSL errors on localhost to be ignored (no interstitial, no
|
||||||
|
# blocking of requests).
|
||||||
|
addflag "--allow-insecure-localhost"
|
||||||
|
|
||||||
|
# If present animations are disabled
|
||||||
|
addflag "--wm-window-animations-disabled"
|
||||||
|
|
||||||
|
# Select which implementation of GL the GPU process should use.
|
||||||
|
# Options are:
|
||||||
|
# desktop: whatever desktop OpenGL the user has installed (Linux and Mac default).
|
||||||
|
# egl: whatever EGL / GLES2 the user has installed (Windows default - actually ANGLE).
|
||||||
|
# swiftshader: The SwiftShader software renderer.
|
||||||
|
addflag "--use-gl=desktop"
|
||||||
|
|
||||||
|
# Disable structured metrics logging of cros actions.
|
||||||
|
addflag "--structured-metrics-disabled"
|
||||||
|
|
||||||
|
# Enables cros disks fake behavior. If the switch is set, fake cros disk
|
||||||
|
# D-Bus client is initialized and USB events do not reach chrome.
|
||||||
|
addflag "--cros-disks-fake"
|
||||||
|
|
||||||
|
# Specifies which encryption storage backend to use. Possible values are
|
||||||
|
# kwallet, kwallet5, kwallet6, gnome-libsecret, basic. Any other value
|
||||||
|
# will lead to Chrome detecting the best backend automatically.
|
||||||
|
addflag "--password-store=basic"
|
||||||
|
|
||||||
|
# Disables the service process from adding itself as an autorun process.
|
||||||
|
# This does not delete existing autorun registrations, it just prevents
|
||||||
|
# the service from registering a new one.
|
||||||
|
addflag "--no-service-autorun"
|
||||||
|
|
||||||
|
# Prevent downloading and running the recovery component.
|
||||||
|
addflag "--no-recovery-component"
|
||||||
|
addflag "--no-proxy-server"
|
||||||
|
addflag "--no-experiments"
|
||||||
|
addflag "--no-default-browser-check"
|
||||||
|
addflag "--log-level=0"
|
||||||
|
addflag "--high-dpi-support=1"
|
||||||
|
addflag "--hide-crash-restore-bubble"
|
||||||
|
addflag "--force-device-scale-factor=1.5"
|
||||||
|
addflag "--force-dark-mode"
|
||||||
|
|
||||||
|
addflag "--enable-gpu-rasterization"
|
||||||
|
addflag "--enable-zero-copy"
|
||||||
|
# addflag "--enable-unsafe-webgpu" # leads to banner "stability and security will suffer
|
||||||
|
addflag "--ignore-gpu-blocklist"
|
||||||
|
|
||||||
|
# fix webcam issues?
|
||||||
|
# addflag "--disable-yuv-image-decoding"
|
||||||
|
#
|
||||||
|
addflag "--disable-usb-keyboard-detect"
|
||||||
|
addflag "--disable-touch-drag-drop"
|
||||||
|
addflag "--disable-stack-profiler"
|
||||||
|
#addflag "--disable-software-rasterizer"
|
||||||
|
addflag "--disable-pinch"
|
||||||
|
addflag "--disable-notifications"
|
||||||
|
addflag "--disable-login-animations"
|
||||||
|
addflag "--disable-logging"
|
||||||
|
addflag "--disable-infobars"
|
||||||
|
addflag "--disable-in-process-stack-traces"
|
||||||
|
addflag "--disable-histogram-customizer"
|
||||||
|
addflag "--disable-field-trial-config"
|
||||||
|
|
||||||
|
addflag "--disable-device-discovery-notifications"
|
||||||
|
# addflag "--disable-dev-shm-usage"
|
||||||
|
addflag "--disable-default-apps"
|
||||||
|
|
||||||
|
# Disable crash reporting
|
||||||
|
addflag "--disable-crash-reporter"
|
||||||
|
addflag "--disable-cookie-encryption"
|
||||||
|
addflag "--disable-component-update"
|
||||||
|
addflag "--disable-component-cloud-policy"
|
||||||
|
addflag "--disable-cloud-print-proxy"
|
||||||
|
addflag "--disable-client-side-phishing-detection"
|
||||||
|
addflag "--disable-chrome-browser-cloud-management"
|
||||||
|
addflag "--disable-breakpad"
|
||||||
|
addflag "--disable-auto-reload"
|
||||||
|
# addflag "--dbus-stub" # default on non chrome-os
|
||||||
|
addflag "--bwsi" # force guest mode (no sign-in)
|
||||||
|
|
||||||
|
###
|
||||||
|
### ENABLE / DISABLE PROCESS FEATURES
|
||||||
|
###
|
||||||
|
|
||||||
|
enable "WebUIDarkMode" # enables dark mode
|
||||||
|
# enable RunVideoCaptureServiceInBrowserProcess # fixes webcam issues by avoiding multiple /dev/video opens
|
||||||
|
enable "VaapiVideoDecoder"
|
||||||
|
enable "VaapiVideoEncoder"
|
||||||
|
disable "IndexedDBCompressValuesWithSnappy" # disable indexdb compression, speeds up facebook
|
||||||
|
disable "Vulkan"
|
||||||
|
disable "UseChromeOSDirectVideoDecoder"
|
||||||
|
enable "VaapiVideoDecodeLinuxGL"
|
||||||
|
enable "VaapiIgnoreDriverChecks"
|
||||||
|
disable "UseSkiaRenderer"
|
||||||
|
|
||||||
|
# add features to flag list
|
||||||
|
addflag "--enable-features=$(echo "$ENABLED_FEATURES" | tr -s " " | sed 's/^ //g' | tr ' ' ',')"
|
||||||
|
addflag "--enable-features=$(echo "$DISABLED_FEATURES" | tr -s " " | sed 's/^ //g' | tr ' ' ',')"
|
||||||
|
|
||||||
|
# finally start chrome...
|
||||||
|
set -x
|
||||||
|
/usr/local/bin/chrome $FLAGS --new-window "$@"
|
||||||
|
|||||||
12
.bin/create-torrent
Executable file
12
.bin/create-torrent
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# source https://github.com/aria2/aria2/issues/663
|
||||||
|
|
||||||
|
export PATH=$HOME/.cargo/bin:$PATH
|
||||||
|
[ ! -f $HOME/.cargo/bin/imdl ] \
|
||||||
|
&& cargo install -f imdl
|
||||||
|
set -x
|
||||||
|
imdl torrent create --input "$1"
|
||||||
|
imdl torrent show --input "$1.torrent"
|
||||||
|
imdl torrent verify --input "$1.torrent" --content "$1"
|
||||||
|
imdl torrent link --input "$1.torrent"
|
||||||
6
.bin/cvs-update
Executable file
6
.bin/cvs-update
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
CVSROOT="sdk@cvs.openbsd.org:/cvs"
|
||||||
|
export CVSROOT
|
||||||
|
|
||||||
|
doas -u sdk cvs -d $CVSROOT -z1 -q up -Pd -A $@
|
||||||
@@ -21,7 +21,7 @@ touch "${HISTFILE}"
|
|||||||
read_input() {
|
read_input() {
|
||||||
local S=$( { echo "paste_from_clipboard"; tail -r ${HISTFILE}; } \
|
local S=$( { echo "paste_from_clipboard"; tail -r ${HISTFILE}; } \
|
||||||
| awk '!seen[$0]++' \
|
| awk '!seen[$0]++' \
|
||||||
| ${DMENU_CMD} -p "Bookmarks" -l 20)
|
| ${DMENU_CMD} -p "Bookmarks")
|
||||||
|
|
||||||
case "${S}" in
|
case "${S}" in
|
||||||
paste_from_clipboard) S=$(xclip -o | head -n 1); ;;
|
paste_from_clipboard) S=$(xclip -o | head -n 1); ;;
|
||||||
@@ -91,7 +91,7 @@ Zalando"
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
local S="$(printf "%s\n%s" "${DEFAULT}" "${SE}" \
|
local S="$(printf "%s\n%s" "${DEFAULT}" "${SE}" \
|
||||||
| ${DMENU_CMD} -p "Search Where?" -l 20)"
|
| ${DMENU_CMD} -p "Search Where?")"
|
||||||
C=$(echo "$C" | sed 's/ /%20/g')
|
C=$(echo "$C" | sed 's/ /%20/g')
|
||||||
case "${S}" in
|
case "${S}" in
|
||||||
OPEN*) URI="${C}"; ;;
|
OPEN*) URI="${C}"; ;;
|
||||||
@@ -136,7 +136,12 @@ choose_browser() {
|
|||||||
gopher://*) DEFAULT="Lagrange (default)"; ;;
|
gopher://*) DEFAULT="Lagrange (default)"; ;;
|
||||||
gemini://*) DEFAULT="Lagrange (default)"; ;;
|
gemini://*) DEFAULT="Lagrange (default)"; ;;
|
||||||
*console.hetzner.cloud*) DEFAULT="Firefox (default)"; ;;
|
*console.hetzner.cloud*) DEFAULT="Firefox (default)"; ;;
|
||||||
*youtube.com/watch*) DEFAULT="Mpv (default)"; ;;
|
*amazon.com*) DEFAULT="Chrome (default)"; ;;
|
||||||
|
*club.de*) DEFAULT="Chrome (default)"; ;;
|
||||||
|
*life.com*) DEFAULT="Chrome (default)"; ;;
|
||||||
|
*videos.com*) DEFAULT="Chrome (default)"; ;;
|
||||||
|
*comdirect.de*) DEFAULT="Chrome (default)"; ;;
|
||||||
|
*youtube.com*) DEFAULT="Chrome (default)"; ;;
|
||||||
*media.ccc.de/v/*) DEFAULT="Mpv (default)"; ;;
|
*media.ccc.de/v/*) DEFAULT="Mpv (default)"; ;;
|
||||||
*.pdf|*.cb|*.ps) DEFAULT="Zathura (default)"; ;;
|
*.pdf|*.cb|*.ps) DEFAULT="Zathura (default)"; ;;
|
||||||
*.mp4|*.m4v|*.mkv) DEFAULT="Mpv (default)"; ;;
|
*.mp4|*.m4v|*.mkv) DEFAULT="Mpv (default)"; ;;
|
||||||
@@ -151,7 +156,7 @@ choose_browser() {
|
|||||||
[Qq]uteb*r*) BROWSER="qutebrowser -R" ;;
|
[Qq]uteb*r*) BROWSER="qutebrowser -R" ;;
|
||||||
[Ss]urf*) BROWSER=surf ;;
|
[Ss]urf*) BROWSER=surf ;;
|
||||||
[Oo]tter*r*) BROWSER=otter-browser ;;
|
[Oo]tter*r*) BROWSER=otter-browser ;;
|
||||||
[Ll]uakit*) BROWSER="luakit -Un" ;;
|
[Ll]uakit*) BROWSER="luakit -v -U" ;;
|
||||||
[Cc]hrome*) BROWSER=chrome ;;
|
[Cc]hrome*) BROWSER=chrome ;;
|
||||||
[Ff]irefox*) BROWSER=firefox ;;
|
[Ff]irefox*) BROWSER=firefox ;;
|
||||||
[Tt]or-B*r*) BROWSER=tor-browser ;;
|
[Tt]or-B*r*) BROWSER=tor-browser ;;
|
||||||
@@ -170,6 +175,6 @@ save_history() {
|
|||||||
# main program starts here.
|
# main program starts here.
|
||||||
read_input
|
read_input
|
||||||
choose_wrapper
|
choose_wrapper
|
||||||
# choose_browser
|
#choose_browser
|
||||||
save_history
|
save_history
|
||||||
$BROWSER "$(printf '%s' "${URI}" | sed 's/ /%20/g')" &
|
$BROWSER "$(printf '%s' "${URI}" | sed 's/ /%20/g')" > /home/sdk/browser.log 2>&1 &
|
||||||
|
|||||||
11
.bin/dexec_man
Executable file
11
.bin/dexec_man
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. $HOME/.bin/_config
|
||||||
|
|
||||||
|
SEL=$(man -k any= | $DMENU_CMD -l 10 -p "Man")
|
||||||
|
|
||||||
|
[ -z "$SEL" ] && exit 0
|
||||||
|
|
||||||
|
N=$(echo "$SEL" | cut -d"(" -f2 | cut -d")" -f1)
|
||||||
|
M=$(echo "$SEL" | cut -d"(" -f1 | cut -d"," -f1)
|
||||||
|
|
||||||
|
sterm -e man -s $N $M
|
||||||
78
.bin/fb-getip.sh
Executable file
78
.bin/fb-getip.sh
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# needs: curl, yq (xq)
|
||||||
|
# usage: fb-getip.sh [ip address]
|
||||||
|
#
|
||||||
|
# Endpoints & Services:
|
||||||
|
# http://fritz.box:49000/tr64desc.xml
|
||||||
|
# AVM TR064 Documentation:
|
||||||
|
# https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_TR-064_first_steps.pdf
|
||||||
|
# https://www.broadband-forum.org/technical/download/TR-064.pdf
|
||||||
|
|
||||||
|
FBHOST="fritz.box"
|
||||||
|
[ ! -z "$1" ] && FBHOST="$1"
|
||||||
|
|
||||||
|
# Variable parts, which can be looked up in the TR-064 documentation
|
||||||
|
SERVICE=WANIPConnection
|
||||||
|
ACTION=GetExternalIPAddress
|
||||||
|
|
||||||
|
# Endpoints supported by the fritzbox, can be looked up at the
|
||||||
|
# "Endpoint & Services" URL.
|
||||||
|
ENDPOINT=WANIPConn1
|
||||||
|
|
||||||
|
# SOAP protocol payload (https://en.wikipedia.org/wiki/SOAP)
|
||||||
|
# This is the language the fritzbox is "speaking". So we create this
|
||||||
|
# payload with the appropriage Service, Action variables.
|
||||||
|
PAYLOAD=\
|
||||||
|
'<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<s:Body>
|
||||||
|
<u:'$ACTION' xmlns:u="urn:schemas-upnp-org:service:'$SERVICE':1" />
|
||||||
|
</s:Body>
|
||||||
|
</s:Envelope>'
|
||||||
|
|
||||||
|
# We use curl to send the payload with the appropriate soap+upnp header
|
||||||
|
# to the fritzbox and receive the SOAP response.
|
||||||
|
#
|
||||||
|
# Header explanation:
|
||||||
|
#
|
||||||
|
# - Header: Content-Type - describes that we send format text/xml with utf8 encoding.
|
||||||
|
# See HTTP Specification:
|
||||||
|
# https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type
|
||||||
|
# (Chapter 8.3)
|
||||||
|
#
|
||||||
|
# - Header: SoapAction... - it's redundant with the payload information.
|
||||||
|
# See SoapAction specification:
|
||||||
|
# https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
|
||||||
|
# (Chapter 6.1.1)
|
||||||
|
#
|
||||||
|
# - SoapAction:<parameter>... - This <parameter> is "urn:schemas-upnp-org:<service>
|
||||||
|
# Each <service> has it's own specifcation.
|
||||||
|
# WANIPConnection Service Specification:
|
||||||
|
# https://upnp.org/specs/gw/UPnP-gw-WANIPConnection-v1-Service.pdf
|
||||||
|
# (Chapter 2.1)
|
||||||
|
|
||||||
|
RESPONSE="$(curl -s "http://$FBHOST:49000/igdupnp/control/$ENDPOINT" \
|
||||||
|
-H "Content-Type: text/xml; charset=utf-8" \
|
||||||
|
-H "SoapAction:urn:schemas-upnp-org:service:$SERVICE:1#$ACTION" \
|
||||||
|
-d "$PAYLOAD")"
|
||||||
|
|
||||||
|
# The SOAP response is ugly XML (just like the requst), so we use "xq",
|
||||||
|
# which converts XML to JSON and allows us to operate on it with "jq"
|
||||||
|
# syntax.
|
||||||
|
# yq/xq documentation: https://kislyuk.github.io/yq
|
||||||
|
# jq documentation: https://jqlang.github.io/jq/manual
|
||||||
|
# Tutorial: https://www.ashbyhq.com/blog/engineering/jq-and-yq
|
||||||
|
#
|
||||||
|
# (once understood, these tools are _very_ powerful! - worth to learn)
|
||||||
|
|
||||||
|
# This "case" is only there so we can do a different kind parsing for
|
||||||
|
# other endpoints. Like when the ACTION variable is changed the parsing
|
||||||
|
# needs to be adapted.
|
||||||
|
case "$ACTION" in
|
||||||
|
GetExternalIPAddress) printf '%s' "$RESPONSE" \
|
||||||
|
| xq -r '."s:Envelope"."s:Body"."u:GetExternalIPAddressResponse".NewExternalIPAddress'
|
||||||
|
;;
|
||||||
|
*) printf '%s' "$RESPONSE"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
export XDG_CACHE_HOME=/tmp firefox
|
export XDG_CACHE_HOME=/tmp
|
||||||
export MOZ_X11_EGL=1
|
export MOZ_X11_EGL=1
|
||||||
|
export MOZ_PLUGIN_PATH=/usr/local/lib/mozilla/plugins
|
||||||
|
unset _SWM_WS
|
||||||
|
|
||||||
/usr/local/bin/firefox "$@"
|
pgrep -qf bin/firefox && args="--new-window"
|
||||||
|
|
||||||
|
/usr/local/bin/firefox $args "$@"
|
||||||
|
|||||||
29
.bin/format-exfat.sh
Executable file
29
.bin/format-exfat.sh
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
_dev="$1"
|
||||||
|
|
||||||
|
[ -z $_dev ] && printf "usage: %s <sd2>\n" "$(basename $0)" && exit 2
|
||||||
|
[ $(id -u) -gt 0 ] && printf "you need superuser rights\n" && exit 2
|
||||||
|
|
||||||
|
dmesg | grep "$_dev" | grep -A1 scsibus | tail -n 2
|
||||||
|
|
||||||
|
printf "Format ${_dev} [y/N]? "
|
||||||
|
read
|
||||||
|
case $REPLY in
|
||||||
|
[yY]) ;;
|
||||||
|
*) exit 0; ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
printf "Overwriting first MBs with zeros:"
|
||||||
|
dd of=/dev/r${_dev}c if=/dev/zero bs=1M count=1 > /dev/null 2>&1
|
||||||
|
printf " ✅\n"
|
||||||
|
|
||||||
|
printf "Creating exFAT / NTFS partition:"
|
||||||
|
echo "edit 0\n07\n\n2048\n*\nw\nq\n" | fdisk -e "$_dev" > /dev/null 2>&1
|
||||||
|
printf " ✅\n"
|
||||||
|
|
||||||
|
printf "Creating exFAT file system (this may take a while)...\n"
|
||||||
|
mkexfatfs -s 2048 "/dev/${_dev}i"
|
||||||
|
printf "Creating exFAT file system: ✅\n"
|
||||||
|
|
||||||
|
printf "Mount:\ndoas mount.exfat /dev/%si /mnt\n" "$_dev"
|
||||||
@@ -19,11 +19,11 @@ dd of=/dev/r${_dev}c if=/dev/zero bs=1M count=1 > /dev/null 2>&1
|
|||||||
printf " ✅\n"
|
printf " ✅\n"
|
||||||
|
|
||||||
printf "Creating FAT32 partition:"
|
printf "Creating FAT32 partition:"
|
||||||
echo "edit 0\n0B\n\n512\n*\nw\nq\n" | fdisk -e "$_dev" > /dev/null 2>&1
|
echo "edit 0\n0B\n\n1024\n*\nw\nq\n" | fdisk -e "$_dev" > /dev/null 2>&1
|
||||||
printf " ✅\n"
|
printf " ✅\n"
|
||||||
|
|
||||||
printf "Creating FAT32 file system (this may take a while)...\n"
|
printf "Creating FAT32 file system (this may take a while)...\n"
|
||||||
newfs_msdos -F32 -b65536 "${_dev}i"
|
newfs_msdos -F32 -b65536 "${_dev}i"
|
||||||
printf "Creating FAT32 file system: ✅\n"
|
printf "Creating FAT32 file system: ✅\n"
|
||||||
|
|
||||||
printf "Mount:\ndoas mkdir -p /mnt/%s && doas mount_msdos /dev/%si /mnt/%s\n" "$_dev" "$_dev" "$_dev"
|
printf "Mount:\ndoas mount_msdos /dev/%si /mnt\n" "$_dev"
|
||||||
81
.bin/g
Executable file
81
.bin/g
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# check if there's .git dir in a parent dir
|
||||||
|
isgit() {
|
||||||
|
_path="$PWD"
|
||||||
|
while [ -n "$_path" ]
|
||||||
|
do
|
||||||
|
if [ -d "$_path/.git" ]
|
||||||
|
then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_path="${_path%/*}"
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! isgit
|
||||||
|
then echo "no git repository"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
_width=$(tput cols)
|
||||||
|
if [ -z "$_width" ]
|
||||||
|
then
|
||||||
|
_width=60
|
||||||
|
fi
|
||||||
|
[ $_width -lt 43 ] \
|
||||||
|
&& _width=43 \
|
||||||
|
|| _width=$(( _width - 3 ))
|
||||||
|
|
||||||
|
_origin=$(git remote get-url origin \
|
||||||
|
2> /dev/null)
|
||||||
|
[ -n "$_origin" ] \
|
||||||
|
&& echo "# origin: $_origin"
|
||||||
|
|
||||||
|
_upstream=$(git remote get-url upstream \
|
||||||
|
2> /dev/null)
|
||||||
|
|
||||||
|
[ -n "$_upstream" ] \
|
||||||
|
&& echo "# upstream: $_upstream"
|
||||||
|
|
||||||
|
_base=$(git --no-pager log \
|
||||||
|
--abbrev-commit \
|
||||||
|
--pretty=format:'%h | %an: %s' \
|
||||||
|
HEAD~2...origin/HEAD~1 \
|
||||||
|
2> /dev/null)
|
||||||
|
|
||||||
|
_branch=$(git --no-pager branch \
|
||||||
|
--no-color \
|
||||||
|
--show-current \
|
||||||
|
2> /dev/null)
|
||||||
|
|
||||||
|
[ -n "$_base" ] \
|
||||||
|
&& printf '%s\n' "# branch ($_branch) fork point: $_base" \
|
||||||
|
| sed "s/\(.\{$_width\}\).*/\1.../"
|
||||||
|
|
||||||
|
_log=$(git --no-pager log \
|
||||||
|
--reverse \
|
||||||
|
--abbrev-commit \
|
||||||
|
--date=format:'%d.%m.%y %H:%S' \
|
||||||
|
--pretty=format:'%h|%ad|%an: %s' \
|
||||||
|
...origin/HEAD \
|
||||||
|
2>/dev/null)
|
||||||
|
if [ -n "$_log" ]
|
||||||
|
then
|
||||||
|
echo "# local commits"
|
||||||
|
printf '%s\n' "$_log" | sed "s/\(.\{$_width\}\).*/\1.../"
|
||||||
|
else
|
||||||
|
echo "# no local commits"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_stat=$(git --no-pager status \
|
||||||
|
--short 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -n "$_stat" ]
|
||||||
|
then
|
||||||
|
echo "# local changes:"
|
||||||
|
echo "$_stat"
|
||||||
|
else
|
||||||
|
echo "# no local changes"
|
||||||
|
fi
|
||||||
23
.bin/got-notes
Executable file
23
.bin/got-notes
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/cat
|
||||||
|
|
||||||
|
init: got init luakit.git
|
||||||
|
download: got clone git@github.com:luakit/luakit luakit.git
|
||||||
|
checkout: got checkout luakit.git luakit
|
||||||
|
commit: got commit
|
||||||
|
diff changes: got diff
|
||||||
|
|
||||||
|
diff branch main with patch: got diff main patch
|
||||||
|
|
||||||
|
list branches: got branch -l
|
||||||
|
switch/create branch: got branch testbranch
|
||||||
|
|
||||||
|
interactive revert: got revert -p -R .
|
||||||
|
|
||||||
|
rebase current branch on top of master: got update -b master
|
||||||
|
|
||||||
|
add file: got add
|
||||||
|
|
||||||
|
repo info: got info
|
||||||
|
|
||||||
|
import from CVS:
|
||||||
|
got import -r /var/git/src.git -I CVS -I obj /tmp/src
|
||||||
296
.bin/ical2rem
296
.bin/ical2rem
@@ -1,296 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
my $debug = 0;
|
|
||||||
#
|
|
||||||
# ical2rem.pl -
|
|
||||||
# Reads iCal files and outputs remind-compatible files. Tested ONLY with
|
|
||||||
# calendar files created by Mozilla Calendar/Sunbird. Use at your own risk.
|
|
||||||
# Copyright (c) 2005, 2007, Justin B. Alcorn
|
|
||||||
|
|
||||||
# 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 2
|
|
||||||
# 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, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# version 0.5.2 2007-03-23
|
|
||||||
# - BUG: leadtime for recurring events had a max of 4 instead of DEFAULT_LEAD_TIME
|
|
||||||
# - remove project-lead-time, since Category was a non-standard attribute
|
|
||||||
# - NOTE: There is a bug in iCal::Parser v1.14 that causes multiple calendars to
|
|
||||||
# fail if a calendar with recurring events is followed by a calendar with no
|
|
||||||
# recurring events. This has been reported to the iCal::Parser author.
|
|
||||||
# version 0.5.1 2007-03-21
|
|
||||||
# - BUG: Handle multiple calendars on STDIN
|
|
||||||
# - add --heading option for priority on section headers
|
|
||||||
# version 0.5 2007-03-21
|
|
||||||
# - Add more help options
|
|
||||||
# - --project-lead-time option
|
|
||||||
# - Supress printing of heading if there are no todos to print
|
|
||||||
# version 0.4
|
|
||||||
# - Version 0.4 changes all written or inspired by, and thanks to Mark Stosberg
|
|
||||||
# - Change to GetOptions
|
|
||||||
# - Change to pipe
|
|
||||||
# - Add --label, --help options
|
|
||||||
# - Add Help Text
|
|
||||||
# - Change to subroutines
|
|
||||||
# - Efficiency and Cleanup
|
|
||||||
# version 0.3
|
|
||||||
# - Convert to GPL (Thanks to Mark Stosberg)
|
|
||||||
# - Add usage
|
|
||||||
# version 0.2
|
|
||||||
# - add command line switches
|
|
||||||
# - add debug code
|
|
||||||
# - add SCHED _sfun keyword
|
|
||||||
# - fix typos
|
|
||||||
# version 0.1 - ALPHA CODE.
|
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
|
||||||
|
|
||||||
cat /path/to/file*.ics | ical2rem.pl > ~/.ical2rem
|
|
||||||
|
|
||||||
All options have reasonable defaults:
|
|
||||||
--label Calendar name (Default: Calendar)
|
|
||||||
--lead-time Advance days to start reminders (Default: 3)
|
|
||||||
--todos, --no-todos Process Todos? (Default: Yes)
|
|
||||||
--heading Define a priority for static entries
|
|
||||||
--help Usage
|
|
||||||
--man Complete man page
|
|
||||||
|
|
||||||
Expects an ICAL stream on STDIN. Converts it to the format
|
|
||||||
used by the C<remind> script and prints it to STDOUT.
|
|
||||||
|
|
||||||
=head2 --label
|
|
||||||
|
|
||||||
ical2rem.pl --label "Bob's Calendar"
|
|
||||||
|
|
||||||
The syntax generated includes a label for the calendar parsed.
|
|
||||||
By default this is "Calendar". You can customize this with
|
|
||||||
the "--label" option.
|
|
||||||
|
|
||||||
=head2 --lead-time
|
|
||||||
|
|
||||||
ical2rem.pl --lead-time 3
|
|
||||||
|
|
||||||
How may days in advance to start getting reminders about the events. Defaults to 3.
|
|
||||||
|
|
||||||
=head2 --no-todos
|
|
||||||
|
|
||||||
ical2rem.pl --no-todos
|
|
||||||
|
|
||||||
If you don't care about the ToDos the calendar, this will surpress
|
|
||||||
printing of the ToDo heading, as well as skipping ToDo processing.
|
|
||||||
|
|
||||||
=head2 --heading
|
|
||||||
|
|
||||||
ical2rem.pl --heading "PRIORITY 9999"
|
|
||||||
|
|
||||||
Set an option on static messages output. Using priorities can made the static messages look different from
|
|
||||||
the calendar entries. See the file defs.rem from the remind distribution for more information.
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use iCal::Parser;
|
|
||||||
use DateTime;
|
|
||||||
use Getopt::Long 2.24 qw':config auto_help';
|
|
||||||
use Pod::Usage;
|
|
||||||
use Data::Dumper;
|
|
||||||
use vars '$VERSION';
|
|
||||||
$VERSION = "0.5.2";
|
|
||||||
|
|
||||||
# Declare how many days in advance to remind
|
|
||||||
my $DEFAULT_LEAD_TIME = 3;
|
|
||||||
my $PROCESS_TODOS = 1;
|
|
||||||
my $HEADING = "";
|
|
||||||
my $help;
|
|
||||||
my $man;
|
|
||||||
|
|
||||||
my $label = 'Calendar';
|
|
||||||
GetOptions (
|
|
||||||
"label=s" => \$label,
|
|
||||||
"lead-time=i" => \$DEFAULT_LEAD_TIME,
|
|
||||||
"todos!" => \$PROCESS_TODOS,
|
|
||||||
"heading=s" => \$HEADING,
|
|
||||||
"help|?" => \$help,
|
|
||||||
"man" => \$man
|
|
||||||
);
|
|
||||||
pod2usage(1) if $help;
|
|
||||||
pod2usage(-verbose => 2) if $man;
|
|
||||||
|
|
||||||
my $month = ['None','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
|
||||||
|
|
||||||
my @calendars;
|
|
||||||
my $in;
|
|
||||||
|
|
||||||
while (<>) {
|
|
||||||
$in .= $_;
|
|
||||||
if (/END:VCALENDAR/) {
|
|
||||||
push(@calendars,$in);
|
|
||||||
$in = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print STDERR "Read all calendars\n" if $debug;
|
|
||||||
my $startdate = DateTime->new( year => 2010,
|
|
||||||
month => 4,
|
|
||||||
day => 1,
|
|
||||||
time_zone => 'US/Eastern',
|
|
||||||
);
|
|
||||||
my $oneyear = DateTime::Duration->new( years => 1);
|
|
||||||
my $oneweek = DateTime::Duration->new( weeks => -1);
|
|
||||||
$startdate = DateTime->now + $oneweek;
|
|
||||||
my $enddate = DateTime->now + $oneyear;
|
|
||||||
print STDERR "About to parse calendars\n" if $debug;
|
|
||||||
my $parser = iCal::Parser->new('start' => $startdate,
|
|
||||||
'debug' => 0,
|
|
||||||
'end' => $enddate);
|
|
||||||
my $hash = $parser->parse_strings(@calendars);
|
|
||||||
print STDERR "Calendars parsed\n" if $debug;
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
#
|
|
||||||
# Subroutines
|
|
||||||
#
|
|
||||||
#############################################################
|
|
||||||
#
|
|
||||||
# _process_todos()
|
|
||||||
# expects 'todos' hashref from iCal::Parser is input
|
|
||||||
# returns String to output
|
|
||||||
sub _process_todos {
|
|
||||||
my $todos = shift;
|
|
||||||
|
|
||||||
my ($todo, @newtodos, $leadtime);
|
|
||||||
my $output = "";
|
|
||||||
|
|
||||||
$output .= 'REM '.$HEADING.' MSG '.$label.' ToDos:%"%"%'."\n";
|
|
||||||
|
|
||||||
# For sorting, make sure everything's got something
|
|
||||||
# To sort on.
|
|
||||||
my $now = DateTime->now;
|
|
||||||
for $todo (@{$todos}) {
|
|
||||||
# remove completed items
|
|
||||||
if ($todo->{'STATUS'} && $todo->{'STATUS'} eq 'COMPLETED') {
|
|
||||||
next;
|
|
||||||
} elsif ($todo->{'DUE'}) {
|
|
||||||
# All we need is a due date, everything else is sugar
|
|
||||||
$todo->{'SORT'} = $todo->{'DUE'}->clone;
|
|
||||||
} elsif ($todo->{'DTSTART'}) {
|
|
||||||
# for sorting, sort on start date if there's no due date
|
|
||||||
$todo->{'SORT'} = $todo->{'DTSTART'}->clone;
|
|
||||||
} else {
|
|
||||||
# if there's no due or start date, just make it now.
|
|
||||||
$todo->{'SORT'} = $now;
|
|
||||||
}
|
|
||||||
push(@newtodos,$todo);
|
|
||||||
}
|
|
||||||
if (! (scalar @newtodos)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
# Now sort on the new Due dates and print them out.
|
|
||||||
for $todo (sort { DateTime->compare($a->{'SORT'}, $b->{'SORT'}) } @newtodos) {
|
|
||||||
my $due = $todo->{'SORT'}->clone();
|
|
||||||
my $priority = "";
|
|
||||||
if (defined($todo->{'PRIORITY'})) {
|
|
||||||
if ($todo->{'PRIORITY'} == 1) {
|
|
||||||
$priority = "PRIORITY 1000";
|
|
||||||
} elsif ($todo->{'PRIORITY'} == 3) {
|
|
||||||
$priority = "PRIORITY 7500";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (defined($todo->{'DTSTART'}) && defined($todo->{'DUE'})) {
|
|
||||||
# Lead time is duration of task + lead time
|
|
||||||
my $diff = ($todo->{'DUE'}->delta_days($todo->{'DTSTART'})->days())+$DEFAULT_LEAD_TIME;
|
|
||||||
$leadtime = "+".$diff;
|
|
||||||
} else {
|
|
||||||
$leadtime = "+".$DEFAULT_LEAD_TIME;
|
|
||||||
}
|
|
||||||
$output .= "REM ".$due->month_abbr." ".$due->day." ".$due->year." $leadtime $priority MSG \%a $todo->{'SUMMARY'}\%\"\%\"\%\n";
|
|
||||||
}
|
|
||||||
$output .= 'REM '.$HEADING.' MSG %"%"%'."\n";
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
|
||||||
#
|
|
||||||
# Main Program
|
|
||||||
#
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
print _process_todos($hash->{'todos'}) if $PROCESS_TODOS;
|
|
||||||
|
|
||||||
my ($leadtime, $yearkey, $monkey, $daykey,$uid,%eventsbyuid);
|
|
||||||
print 'REM '.$HEADING.' MSG '.$label.' Events:%"%"%'."\n";
|
|
||||||
my $events = $hash->{'events'};
|
|
||||||
foreach $yearkey (sort keys %{$events} ) {
|
|
||||||
my $yearevents = $events->{$yearkey};
|
|
||||||
foreach $monkey (sort {$a <=> $b} keys %{$yearevents}){
|
|
||||||
my $monevents = $yearevents->{$monkey};
|
|
||||||
foreach $daykey (sort {$a <=> $b} keys %{$monevents} ) {
|
|
||||||
my $dayevents = $monevents->{$daykey};
|
|
||||||
foreach $uid (sort {
|
|
||||||
DateTime->compare($dayevents->{$a}->{'DTSTART'}, $dayevents->{$b}->{'DTSTART'})
|
|
||||||
} keys %{$dayevents}) {
|
|
||||||
my $event = $dayevents->{$uid};
|
|
||||||
if ($eventsbyuid{$uid}) {
|
|
||||||
my $curreventday = $event->{'DTSTART'}->clone;
|
|
||||||
$curreventday->truncate( to => 'day' );
|
|
||||||
$eventsbyuid{$uid}{$curreventday->epoch()} =1;
|
|
||||||
for (my $i = 0;$i < $DEFAULT_LEAD_TIME && !defined($event->{'LEADTIME'});$i++) {
|
|
||||||
if ($eventsbyuid{$uid}{$curreventday->subtract( days => $i+1 )->epoch() }) {
|
|
||||||
$event->{'LEADTIME'} = $i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$eventsbyuid{$uid} = $event;
|
|
||||||
my $curreventday = $event->{'DTSTART'}->clone;
|
|
||||||
$curreventday->truncate( to => 'day' );
|
|
||||||
$eventsbyuid{$uid}{$curreventday->epoch()} =1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach $yearkey (sort keys %{$events} ) {
|
|
||||||
my $yearevents = $events->{$yearkey};
|
|
||||||
foreach $monkey (sort {$a <=> $b} keys %{$yearevents}){
|
|
||||||
my $monevents = $yearevents->{$monkey};
|
|
||||||
foreach $daykey (sort {$a <=> $b} keys %{$monevents} ) {
|
|
||||||
my $dayevents = $monevents->{$daykey};
|
|
||||||
foreach $uid (sort {
|
|
||||||
DateTime->compare($dayevents->{$a}->{'DTSTART'}, $dayevents->{$b}->{'DTSTART'})
|
|
||||||
} keys %{$dayevents}) {
|
|
||||||
my $event = $dayevents->{$uid};
|
|
||||||
if (exists($event->{'LEADTIME'})) {
|
|
||||||
$leadtime = "+".$event->{'LEADTIME'};
|
|
||||||
} else {
|
|
||||||
$leadtime = "+".$DEFAULT_LEAD_TIME;
|
|
||||||
}
|
|
||||||
my $start = $event->{'DTSTART'};
|
|
||||||
print "REM ".$start->month_abbr." ".$start->day." ".$start->year." $leadtime ";
|
|
||||||
if ($start->hour > 0) {
|
|
||||||
print " AT ";
|
|
||||||
print $start->strftime("%H:%M");
|
|
||||||
# print " SCHED _sfun MSG %a %2 ";
|
|
||||||
# fix 2024-10-04
|
|
||||||
print " +15 MSG %a %2 ";
|
|
||||||
} else {
|
|
||||||
print " MSG %a ";
|
|
||||||
}
|
|
||||||
print "%\"$event->{'SUMMARY'}";
|
|
||||||
print " at $event->{'LOCATION'}" if $event->{'LOCATION'};
|
|
||||||
print "\%\"%\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit 0;
|
|
||||||
#:vim set ft=perl ts=4 sts=4 expandtab :
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
ipmitool -U ADMIN -P $(pass Local/TweetyIPMI | head -1) \
|
ipmitool -U ADMIN -P $(pass Local/TweetyIPMI | head -1) \
|
||||||
-I lanplus -H 10.20.30.21 $@;
|
-I lanplus -H tweety-ipmi.home.codevoid.de $@;
|
||||||
|
|||||||
108
.bin/lddcopy
Executable file
108
.bin/lddcopy
Executable file
@@ -0,0 +1,108 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# FIXME: does not work with space in filenames or directories
|
||||||
|
# (can be fixed by | while read ... the ldd output, but.. why?)
|
||||||
|
# FIXME: directory permissions are not copied
|
||||||
|
# (can be fixed with stat -f '%p %u %g' . and walk the path with mkdir -m ...)
|
||||||
|
|
||||||
|
##
|
||||||
|
## USAGE
|
||||||
|
##
|
||||||
|
|
||||||
|
_usage() {
|
||||||
|
echo "usage: mkchroot [-xn] [-u or executable] directory"
|
||||||
|
echo "options: -u - runs for all executables found in /bin/ directories"
|
||||||
|
echo " -x - copy stuff required to connect to X"
|
||||||
|
echo " -n - copy stuff required for networking"
|
||||||
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
## HANDLE ARGUMENTS
|
||||||
|
##
|
||||||
|
|
||||||
|
while getopts xnuh arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
x) _with_x=1 ;; # creates /tmp with X connection
|
||||||
|
n) _with_network=1 ;; # copies resolv.conf
|
||||||
|
u) _update_mode=1 ;; # updates the existing directory
|
||||||
|
h) _usage; exit 0 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $(($OPTIND - 1))
|
||||||
|
|
||||||
|
if [ -z "$1" ] && [ -z "$_update_mode" ]
|
||||||
|
then
|
||||||
|
_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$2" ] && [ -z "$_update_mode" ]
|
||||||
|
then
|
||||||
|
_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_update_mode" == "1" ]
|
||||||
|
then
|
||||||
|
_indir="$1"
|
||||||
|
else
|
||||||
|
_infile="$1"
|
||||||
|
_indir="$2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
###
|
||||||
|
### FUNCTIONS
|
||||||
|
###
|
||||||
|
|
||||||
|
_ldd_extract() {
|
||||||
|
for _file in $(ldd "$1" | awk '/\// { print $7 }' | xargs)
|
||||||
|
do
|
||||||
|
_name="$(basename "$_file")"
|
||||||
|
_dir="$2/$(dirname "$_file" | cut -b2-)"
|
||||||
|
if [ ! -d "$_dir" ]
|
||||||
|
then
|
||||||
|
echo "mkdir: $_dir"
|
||||||
|
mkdir -p "$_dir"
|
||||||
|
fi
|
||||||
|
if [ ! -f "$_dir/$_name" ]
|
||||||
|
then
|
||||||
|
echo "copy: $_file -> $_dir/$_name"
|
||||||
|
cp -af "$_file" "$_dir/$_name"
|
||||||
|
else
|
||||||
|
echo "skip: $_file -> $_dir/$_name (existing)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_find_binfile() {
|
||||||
|
# remove basedir
|
||||||
|
_f=$(echo "$1" | sed "s|${1%%/*}||g")
|
||||||
|
_ofile="$(readlink -f "$_f" 2> /dev/null)"
|
||||||
|
echo $_ofile
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
### MAIN PROGRAM
|
||||||
|
###
|
||||||
|
|
||||||
|
if [ -z "$_update_mode" ]
|
||||||
|
then
|
||||||
|
_ldd_extract "$_infile" "$_indir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_update_mode" == "1" ]
|
||||||
|
then
|
||||||
|
_binfiles="$(find "$_indir" -type f -path "*/bin/*")"
|
||||||
|
for _binfile in $_binfiles
|
||||||
|
do
|
||||||
|
_infile=
|
||||||
|
_infile=$(_find_binfile "$_binfile")
|
||||||
|
if [ -z "$_infile" ]
|
||||||
|
then
|
||||||
|
echo "skip: $_binfile -> $_infile (not found)"
|
||||||
|
else
|
||||||
|
_ldd_extract "$_infile" "$_indir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
139
.bin/luakit-env
Executable file
139
.bin/luakit-env
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
_dir="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
# load config
|
||||||
|
. $HOME/.lenv
|
||||||
|
_action="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
# validation
|
||||||
|
if [ -z "$_env" ] || [ -z "$_dir" ]
|
||||||
|
then
|
||||||
|
echo "Incomplete environment"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$_action" ]
|
||||||
|
then
|
||||||
|
echo "No action provided"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# now we can start...
|
||||||
|
echo "luakit-$_env: perform $_action $@ (in $_dir)" | xargs
|
||||||
|
|
||||||
|
# change into environment
|
||||||
|
mkdir -p "$_dir"
|
||||||
|
_oldpwd="$PWD"
|
||||||
|
cd "$_dir"
|
||||||
|
|
||||||
|
# perform actions
|
||||||
|
if [ "$_action" == "help" ] || [ "$_action" == "h" ]
|
||||||
|
then
|
||||||
|
echo "usage: l action [args]"
|
||||||
|
echo " actions:"
|
||||||
|
echo " make - build luakit"
|
||||||
|
echo " remake - make with -j1 (for debugging)"
|
||||||
|
echo " test [test] - run luakit test suite [specific test]"
|
||||||
|
echo " debug [luakit args] - start in gdb, stop in main"
|
||||||
|
echo " pr [numbers] - show [pull] PR from luakit/luakit repo"
|
||||||
|
echo " update - update/rebase repository"
|
||||||
|
echo " reset - recreate environment ($_dir)"
|
||||||
|
echo " diff file env - diff file with other environment"
|
||||||
|
echo " update-port - update openbsd port from last commit"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$_action" == "test" ]
|
||||||
|
then
|
||||||
|
export G_ENABLE_DIAGNOSTIC=1;
|
||||||
|
luajit tests/run_test.lua $@;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_action" == "make" ]
|
||||||
|
then
|
||||||
|
set -x
|
||||||
|
gmake clean
|
||||||
|
gmake options
|
||||||
|
gmake -j 8 luakit
|
||||||
|
gmake tests/util.so
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_action" == "remake" ]
|
||||||
|
then
|
||||||
|
gmake -j1 luakit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_action" == "reset" ]
|
||||||
|
then
|
||||||
|
if [ "$_env" == "dev" ]
|
||||||
|
then
|
||||||
|
cd /tmp
|
||||||
|
rm -rf "$_dir"
|
||||||
|
git clone git@github.com:c0dev0id/luakit "$_dir"
|
||||||
|
cd "$_dir"
|
||||||
|
set -xe
|
||||||
|
git remote add upstream git@github.com:luakit/luakit
|
||||||
|
git fetch upstream
|
||||||
|
git checkout develop
|
||||||
|
git rebase upstream/develop
|
||||||
|
git switch -c patch
|
||||||
|
set +xe
|
||||||
|
else
|
||||||
|
cd /tmp
|
||||||
|
rm -rf "$_dir"
|
||||||
|
git clone git@github.com:luakit/luakit "$_dir"
|
||||||
|
cd "$_dir"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$_action" == "update" ]
|
||||||
|
then
|
||||||
|
set -xe
|
||||||
|
if [ "$_env" == "dev" ]
|
||||||
|
then
|
||||||
|
git fetch --all
|
||||||
|
git checkout develop
|
||||||
|
git rebase upstream/develop --autostash
|
||||||
|
git checkout -
|
||||||
|
else
|
||||||
|
git checkout develop
|
||||||
|
git fetch --all
|
||||||
|
git rebase origin/develop
|
||||||
|
fi
|
||||||
|
set +xe
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_action" == "diff" ]
|
||||||
|
then
|
||||||
|
if test -z "$1" || test -z "$2"
|
||||||
|
then
|
||||||
|
echo "args: <file> <env>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
set -x
|
||||||
|
f="$(readlink -f $_oldpwd/$1)"
|
||||||
|
f="${f#$_dir}"
|
||||||
|
vimdiff "$_dir/$f" "${_dir%$_env}$2/$f"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_action" == "pr" ]
|
||||||
|
then
|
||||||
|
if [ -n "$1" ]
|
||||||
|
then
|
||||||
|
for pr in $@
|
||||||
|
do gh pr checkout $pr
|
||||||
|
done
|
||||||
|
else
|
||||||
|
gh pr --repo luakit/luakit list $@ | cat
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$_action" == "update-port" ]
|
||||||
|
then
|
||||||
|
export DEVELOPMENT_PATHS=0
|
||||||
|
cd /usr/ports/mystuff/www/luakit
|
||||||
|
./update.sh
|
||||||
|
fi
|
||||||
|
|
||||||
2
.bin/luakit-formfiller
Executable file
2
.bin/luakit-formfiller
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
sterm "vim $HOME/.local/share/luakit/forms.lua" &
|
||||||
@@ -1,9 +1,60 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -xe
|
# Figure out what's the best directory to put tag files in.
|
||||||
|
# This is usually the top level of the project / source directory.
|
||||||
|
# We can figure this out in a source controlled directories.
|
||||||
|
# git: the top level dir is the one that contains the .git
|
||||||
|
# directory, so we traverse the directory hierarchy backwards and
|
||||||
|
# look for it.
|
||||||
|
# cvs: the top level dir is the first dir that still contains a CVS
|
||||||
|
# directory. So we traverse back the directory hierarchy and check
|
||||||
|
# it the parent directory has no CVS directory. Then it's the current
|
||||||
|
# one.
|
||||||
|
|
||||||
|
gitdir() {
|
||||||
|
set -x
|
||||||
|
_path="$PWD"
|
||||||
|
while [ -n "$_path" ]
|
||||||
|
do [ -d "$_path/.git" ] \
|
||||||
|
&& echo "$_path" \
|
||||||
|
&& break
|
||||||
|
_path="${_path%/*}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cvsdir() {
|
||||||
|
set -x
|
||||||
|
_path="$PWD"
|
||||||
|
while [ -n "$_path" ]
|
||||||
|
do
|
||||||
|
[ ! -d "$_path/../CVS" ] \
|
||||||
|
&& echo "$_path" \
|
||||||
|
&& break
|
||||||
|
_path="${_path%/*}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_gitdir="$(gitdir)"
|
||||||
|
_cvsdir="$(cvsdir)"
|
||||||
|
|
||||||
|
if [ -n "$_gitdir" ]
|
||||||
|
then
|
||||||
|
_tagdir=".git"
|
||||||
|
_wrkdir="$_gitdir"
|
||||||
|
elif [ -n "$_cvsdir" ]
|
||||||
|
then
|
||||||
|
_wrkdir="$_cvsdir"
|
||||||
|
_tagdir=".tags"
|
||||||
|
else
|
||||||
|
_wrkdir=${PWD}
|
||||||
|
_tagdir=".tags"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating tags in $_wrkdir/$_tagdir"
|
||||||
|
mkdir -p "$_wrkdir/$_tagdir"
|
||||||
|
|
||||||
# create files list
|
# create files list
|
||||||
find "${PWD}/"* -type f \
|
find "${_wrkdir}/"* -type f \
|
||||||
\( -iname "*.c" \
|
\( -iname "*.c" \
|
||||||
-o -iname "*.cc" \
|
-o -iname "*.cc" \
|
||||||
-o -iname "*.cpp" \
|
-o -iname "*.cpp" \
|
||||||
@@ -17,7 +68,7 @@ find "${PWD}/"* -type f \
|
|||||||
-o -iname "*.pl" \
|
-o -iname "*.pl" \
|
||||||
-o -iname "*.sh" \
|
-o -iname "*.sh" \
|
||||||
-o -name "Makefile" \
|
-o -name "Makefile" \
|
||||||
\) > ${PWD}/.git/files
|
\) > ${_wrkdir}/${_tagdir}/files
|
||||||
|
|
||||||
# include extra directories
|
# include extra directories
|
||||||
if [ ! -z "$1" ]
|
if [ ! -z "$1" ]
|
||||||
@@ -36,11 +87,11 @@ then
|
|||||||
-o -iname "*.pl" \
|
-o -iname "*.pl" \
|
||||||
-o -iname "*.sh" \
|
-o -iname "*.sh" \
|
||||||
-o -name "Makefile" \
|
-o -name "Makefile" \
|
||||||
\) >> ${PWD}/.git/files
|
\) >> ${_wrkdir}/${_tagdir}/files
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# create cscope database
|
# create cscope database
|
||||||
cscope -qbkCRv -P${PWD} -f ${PWD}/.git/cscope.out -i${PWD}/.git/files
|
cscope -qbkCRv -P${_wrkdir} -f ${_wrkdir}/${_tagdir}/cscope.out -i${_wrkdir}/${_tagdir}/files
|
||||||
|
|
||||||
# create tags file
|
# create tags file
|
||||||
ectags --sort=yes \
|
ectags --sort=yes \
|
||||||
@@ -50,6 +101,6 @@ ectags --sort=yes \
|
|||||||
--fields=+K \
|
--fields=+K \
|
||||||
--totals=yes \
|
--totals=yes \
|
||||||
--fields=fkst \
|
--fields=fkst \
|
||||||
--exclude=.git \
|
--exclude=${_tagdir} \
|
||||||
-L ${PWD}/.git/files \
|
-L ${_wrkdir}/${_tagdir}/files \
|
||||||
-f ${PWD}/.git/tags
|
-f ${_wrkdir}/${_tagdir}/tags
|
||||||
|
|||||||
32
.bin/mount-cryptoffs
Executable file
32
.bin/mount-cryptoffs
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
_dev=${1:-sd2}
|
||||||
|
|
||||||
|
if mount | grep -q "/mnt"
|
||||||
|
then
|
||||||
|
echo "already mounted"
|
||||||
|
mount | grep "/mnt"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if already decrypted
|
||||||
|
_biodev=$(doas bioctl softraid0 | grep -B1 $_dev | head -1 | awk '{print $5}' \
|
||||||
|
|| exit 1)
|
||||||
|
|
||||||
|
# if not
|
||||||
|
if [ -z "$_biodev" ]
|
||||||
|
then
|
||||||
|
# decrypt
|
||||||
|
pass Local/hagibis-usb-nvme | doas bioctl -s -c C -l ${_dev}a softraid0
|
||||||
|
# and read again
|
||||||
|
_biodev=$(doas bioctl softraid0 | grep -B1 $_dev | head -1 | awk '{print $5}' \
|
||||||
|
|| exit 1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# it still might not be there (wrong password etc..)
|
||||||
|
if [ -n "$_biodev" ]
|
||||||
|
then
|
||||||
|
echo "${_dev}a attached as $_biodev"
|
||||||
|
# mount biodev
|
||||||
|
doas mount /dev/${_biodev}a /mnt \
|
||||||
|
&& echo "${_biodev}a mounted to /mnt"
|
||||||
|
fi
|
||||||
3
.bin/mount-exfat
Executable file
3
.bin/mount-exfat
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
_dev=${1:-sd2i}
|
||||||
|
doas mount.exfat-fuse -o nodev,nosuid,noatime,uid=1000,gid=1000 /dev/${_dev} /mnt
|
||||||
3
.bin/mount-fat32
Executable file
3
.bin/mount-fat32
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
_dev=${1:-sd2}
|
||||||
|
doas /sbin/mount_msdos -o nodev,nosuid,noatime -u 1000 -g 1000 /dev/${_dev}i /mnt
|
||||||
3
.bin/mount-ffs
Executable file
3
.bin/mount-ffs
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
_dev=${1:-sd2}
|
||||||
|
doas /sbin/mount_ffs /dev/${_dev}a /mnt
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#/bin/sh
|
|
||||||
doas /sbin/mount_msdos -o nodev,nosuid,noatime -u 1000 -g 1000
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if mount | fgrep '/tank/' -q
|
if mount | fgrep -q '/tank/'
|
||||||
then
|
then
|
||||||
echo "already mounted"
|
echo "already mounted"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
21
.bin/myxmenu
Executable file
21
.bin/myxmenu
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
get_catgirl() {
|
||||||
|
cd ~/.config/catgirl && ls * | xargs -n1 \
|
||||||
|
| while read line
|
||||||
|
do
|
||||||
|
print "\t$line\ttexec \"catgirl $line\""
|
||||||
|
done
|
||||||
|
}
|
||||||
|
IRC="$(get_catgirl)"
|
||||||
|
|
||||||
|
xmenu -i <<EOF | sh &
|
||||||
|
IRC
|
||||||
|
$IRC
|
||||||
|
Applications
|
||||||
|
IMG:./web.png Web Browser firefox
|
||||||
|
IMG:./gimp.png Image editor gimp
|
||||||
|
|
||||||
|
Terminal (xterm) xterm
|
||||||
|
Terminal (st) sterm
|
||||||
|
EOF
|
||||||
38
.bin/network
Executable file
38
.bin/network
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
### DEFAULTS
|
||||||
|
|
||||||
|
|
||||||
|
### ARGUMENTS
|
||||||
|
for arg in "$@"
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
start) _start=1 ;;
|
||||||
|
stop) _stop=1 ;;
|
||||||
|
status) _status=1 ;;
|
||||||
|
route) _route=1 ;;
|
||||||
|
wifi) _wifi=1 ;;
|
||||||
|
hotspot) _hotspot=1 ;;
|
||||||
|
adhoc) _adhoc=1 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
### FUNCTIONS
|
||||||
|
_ifconfig() {
|
||||||
|
[ -z "$_ifdata" ] \
|
||||||
|
&& _ifdata="$(ifconfig)"
|
||||||
|
echo "$_ifdata"
|
||||||
|
}
|
||||||
|
|
||||||
|
### DATA
|
||||||
|
_interfaces="$(_ifconfig | egrep "^[a-z]" | cut -d: -f1 | egrep -v "lo0|enc0|pflog0" | xargs)"
|
||||||
|
|
||||||
|
### MAIN PROGRAM
|
||||||
|
if [ -n "$_status" ]
|
||||||
|
then
|
||||||
|
for _dev in $_interfaces
|
||||||
|
do
|
||||||
|
# something with awk
|
||||||
|
done
|
||||||
|
fi
|
||||||
@@ -75,6 +75,7 @@ case "$EXT" in
|
|||||||
m2ts) EXEC="mpv"; ;;
|
m2ts) EXEC="mpv"; ;;
|
||||||
mp3) EXEC="mpv"; ;;
|
mp3) EXEC="mpv"; ;;
|
||||||
mp4) EXEC="mpv"; ;;
|
mp4) EXEC="mpv"; ;;
|
||||||
|
pdf) EXEC="zathura"; ;;
|
||||||
out) EXEC="kdump -RTf"; ;;
|
out) EXEC="kdump -RTf"; ;;
|
||||||
sid) EXEC="sidplay"; ;;
|
sid) EXEC="sidplay"; ;;
|
||||||
torrent) EXEC="aria2c"; ;;
|
torrent) EXEC="aria2c"; ;;
|
||||||
|
|||||||
35
.bin/obsd-route
Executable file
35
.bin/obsd-route
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ $(id -u) -ne 0 ] && echo "root?" && exit 0
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "obsd-route [start,stop]"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
do_start() {
|
||||||
|
set -x
|
||||||
|
sysctl net.inet.ip.forwarding=1
|
||||||
|
ifconfig trunk0 destroy
|
||||||
|
ifconfig qwx0 inet autoconf
|
||||||
|
ifconfig re0 inet 192.168.23.1 netmask 255.255.255.0
|
||||||
|
rcctl enable dhcpd
|
||||||
|
rcctl set dhcpd flags re0
|
||||||
|
rcctl start dhcpd
|
||||||
|
}
|
||||||
|
|
||||||
|
do_stop() {
|
||||||
|
set -x
|
||||||
|
sysctl net.inet.ip.forwarding=0
|
||||||
|
ifconfig qwx0 -inet
|
||||||
|
ifconfig re0 -inet
|
||||||
|
rcctl stop dhcpd
|
||||||
|
rcctl disable dhcpd
|
||||||
|
sh /etc/netstart
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
start) do_start; ;;
|
||||||
|
stop) do_stop; ;;
|
||||||
|
*) usage;
|
||||||
|
esac
|
||||||
@@ -7,6 +7,9 @@ trap abort 1 2 3 6 9 11
|
|||||||
abort() { echo "Abort with >$0 $ARGS< on $(date)" >> /tmp/obsdmake.log; }
|
abort() { echo "Abort with >$0 $ARGS< on $(date)" >> /tmp/obsdmake.log; }
|
||||||
|
|
||||||
JOBS="${JOBS:=$(sysctl -n hw.ncpuonline)}"
|
JOBS="${JOBS:=$(sysctl -n hw.ncpuonline)}"
|
||||||
|
JOBS=1
|
||||||
|
|
||||||
|
LOG="/home/sdk/obsdmake.log"
|
||||||
|
|
||||||
export CCACHE_DIR="/var/ccache"
|
export CCACHE_DIR="/var/ccache"
|
||||||
export CCACHE_SLOPPINESS="locale,time_macros,random_seed,file_stat_matches,pch_defines"
|
export CCACHE_SLOPPINESS="locale,time_macros,random_seed,file_stat_matches,pch_defines"
|
||||||
@@ -24,12 +27,13 @@ if [ -z "$1" ]; then
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Start with >$0 $ARGS< on $(date)" >> /tmp/obsdmake.log
|
echo "Start with >$0 $ARGS< on $(date)" >> $LOG
|
||||||
|
|
||||||
doas mkdir -p /usr/obj /usr/xobj
|
doas mkdir -p /usr/obj /usr/xobj
|
||||||
doas chown build /usr/obj /usr/xobj
|
doas chown build /usr/obj /usr/xobj
|
||||||
|
|
||||||
mkkernel() {
|
mkkernel() {
|
||||||
|
echo "Step: kernel start ($(date))" >> $LOG
|
||||||
set -xe
|
set -xe
|
||||||
cd /sys/arch/$(machine)/compile/GENERIC.MP
|
cd /sys/arch/$(machine)/compile/GENERIC.MP
|
||||||
doas make clean
|
doas make clean
|
||||||
@@ -39,9 +43,11 @@ mkkernel() {
|
|||||||
doas make install
|
doas make install
|
||||||
doas what /bsd
|
doas what /bsd
|
||||||
doas ln -f /bsd.booted /bsd.backup
|
doas ln -f /bsd.booted /bsd.backup
|
||||||
|
echo "Step: kernel done ($(date))" >> $LOG
|
||||||
}
|
}
|
||||||
|
|
||||||
mkbase() {
|
mkbase() {
|
||||||
|
echo "Step: base start ($(date))" >> $LOG
|
||||||
set -xe
|
set -xe
|
||||||
cd /usr/src
|
cd /usr/src
|
||||||
doas make obj
|
doas make obj
|
||||||
@@ -50,9 +56,11 @@ mkbase() {
|
|||||||
doas sysmerge
|
doas sysmerge
|
||||||
cd /dev
|
cd /dev
|
||||||
doas ./MAKEDEV all
|
doas ./MAKEDEV all
|
||||||
|
echo "Step: base done ($(date))" >> $LOG
|
||||||
}
|
}
|
||||||
|
|
||||||
mkxenocara() {
|
mkxenocara() {
|
||||||
|
echo "Step: xenocara start ($(date))" >> $LOG
|
||||||
set -xe
|
set -xe
|
||||||
doas chown -R sdk /usr/xenocara
|
doas chown -R sdk /usr/xenocara
|
||||||
cd /usr/xenocara
|
cd /usr/xenocara
|
||||||
@@ -61,9 +69,11 @@ mkxenocara() {
|
|||||||
doas make obj
|
doas make obj
|
||||||
doas make -j${JOBS} build
|
doas make -j${JOBS} build
|
||||||
doas make install
|
doas make install
|
||||||
|
echo "Step: xenocara done ($(date))" >> $LOG
|
||||||
}
|
}
|
||||||
|
|
||||||
mkrelease() {
|
mkrelease() {
|
||||||
|
echo "Step: release start ($(date))" >> $LOG
|
||||||
set -xe
|
set -xe
|
||||||
doas mkdir -p /data/{OpenBSD,Release}
|
doas mkdir -p /data/{OpenBSD,Release}
|
||||||
doas chown -R build /data
|
doas chown -R build /data
|
||||||
@@ -86,6 +96,7 @@ mkrelease() {
|
|||||||
cd /usr/src/distrib/$(machine)/iso
|
cd /usr/src/distrib/$(machine)/iso
|
||||||
doas make
|
doas make
|
||||||
doas make install
|
doas make install
|
||||||
|
echo "Step: release done ($(date))" >> $LOG
|
||||||
}
|
}
|
||||||
|
|
||||||
kernelclean() {
|
kernelclean() {
|
||||||
@@ -127,5 +138,5 @@ case "$1" in
|
|||||||
all) mkkernel; mkbase; mkxenocara; ;;
|
all) mkkernel; mkbase; mkxenocara; ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "Finished with >$0 $ARGS< on $(date)" >> /tmp/obsdmake.log
|
echo "Finished with >$0 $ARGS< on $(date)" >> $LOG
|
||||||
sync
|
sync
|
||||||
|
|||||||
26
.bin/osmc
Executable file
26
.bin/osmc
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
USBDISK=/mnt/1TB
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
mount) shift; ssh -tt osmc "sudo /sbin/cryptdisks_start usbdisk" \
|
||||||
|
&& ssh osmc "sudo mount /mnt/1TB" ;;
|
||||||
|
put|push) shift; rsync -rv --progress --append-verify "$@" osmc:$USBDISK/ ;;
|
||||||
|
df) shift; ssh osmc "df -h $USBDISK" ;;
|
||||||
|
ls) shift; ssh osmc "cd $USBDISK && ls $@ | grep -v lost+found" ;;
|
||||||
|
lls) shift; ssh osmc "cd $USBDISK && ls -lh | grep -v lost+found" ;;
|
||||||
|
del) shift; ssh osmc "cd $USBDISK && rm -v $@" ;;
|
||||||
|
ren) shift; ssh osmc "cd $USBDISK && mv \"$1\" \"$2\"" ;;
|
||||||
|
at) shift; ssh -tt osmc "tmux at" ;;
|
||||||
|
*) echo "usage: osmc <command> <args>"
|
||||||
|
echo " mount - mount USB disk"
|
||||||
|
echo " df - show disk space allocation"
|
||||||
|
echo " ls - list files"
|
||||||
|
echo " lls - list files with details"
|
||||||
|
echo " put <files> - copy files to USB disk"
|
||||||
|
echo " ren <old> <new> - rename file"
|
||||||
|
echo " del <files> - delete file"
|
||||||
|
echo " at - attach to tmux session"
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
169
.bin/pkg-depends
Executable file
169
.bin/pkg-depends
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# lazy config
|
||||||
|
_sqlports="/usr/local/share/sqlports"
|
||||||
|
_pkgpath="$(head -1 /etc/installurl)/$(uname -r)/packages/$(uname -m)"
|
||||||
|
|
||||||
|
# parameters can be freely combined
|
||||||
|
_usage() {
|
||||||
|
echo "usage: pkg-depends [options] <pkgpath>"
|
||||||
|
echo "options: -r - list run dependencies (default)"
|
||||||
|
echo " -l - list lib dependencies (default)"
|
||||||
|
echo " -b - list build dependencies"
|
||||||
|
echo " -t - list test dependencies"
|
||||||
|
echo " -p - show packges names (default)"
|
||||||
|
echo " -P - show port paths"
|
||||||
|
echo " -d <dir> - download packages to <dir>"
|
||||||
|
echo
|
||||||
|
echo "Only one flavor / subpackage in pkgpath(7) is supported."
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts rlbtpPd: arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
l) _deps="$_deps 0" ;;
|
||||||
|
r) _deps="$_deps 1" ;;
|
||||||
|
b) _deps="$_deps 2" ;;
|
||||||
|
t) _deps="$_deps 3" ;;
|
||||||
|
p) _showmode=$(( _showmode + 1 )) ;;
|
||||||
|
P) _showmode=$(( _showmode + 2 )) ;;
|
||||||
|
d) _dldir=$OPTARG ;;
|
||||||
|
h) _usage ;;
|
||||||
|
?) _usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $(($OPTIND - 1))
|
||||||
|
|
||||||
|
[ -z "$1" ] \
|
||||||
|
&& _usage
|
||||||
|
|
||||||
|
if [ ! -f "$_sqlports" ]
|
||||||
|
then
|
||||||
|
echo "$_sqlports not found. Install \"sqlports\" to use this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
### FUNCTIONS
|
||||||
|
|
||||||
|
# a little helper in case no pkgpath is provided
|
||||||
|
_do_pkg() {
|
||||||
|
echo "pkg-depends needs pkgpath(7) as argument, pkg_info -P can help."
|
||||||
|
echo "Here, I'm calling it for you:"
|
||||||
|
echo
|
||||||
|
echo "$ pkg_info -P $1"
|
||||||
|
pkg_info -P "$1"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_do_sql() {
|
||||||
|
|
||||||
|
# XXX: This lists all dependencies for the dependencies for the
|
||||||
|
# dependencies. I haven't encountert an endless loop here (yet?).
|
||||||
|
# I guess sqlite takes care or that?
|
||||||
|
# I'm sure the performance can be improved by not using the big
|
||||||
|
# ports view to grab the pkgname. But it's late and it works and
|
||||||
|
# this is a problem for another day.
|
||||||
|
_query="
|
||||||
|
WITH RECURSIVE pkg(x) AS (
|
||||||
|
SELECT \"$1\"
|
||||||
|
UNION
|
||||||
|
SELECT distinct dependspath FROM canonical_depends
|
||||||
|
JOIN pkg ON fullpkgpath=x WHERE type in ($2)
|
||||||
|
) SELECT x, fullpkgname FROM pkg
|
||||||
|
JOIN ports ON fullpkgpath=x;
|
||||||
|
"
|
||||||
|
echo "SQL QUERY: $_query" > $HOME/pkg-depends.log
|
||||||
|
echo "RESULT:" >> $HOME/pkg-depends.log
|
||||||
|
sqlite3 "$_sqlports" "$_query" | tee -a $HOME/pkg-depends.log
|
||||||
|
}
|
||||||
|
|
||||||
|
_handle_list() {
|
||||||
|
# build the comma sparated list that descibes the types
|
||||||
|
# to include in the list. Used in the sql query.
|
||||||
|
# _deps are set in getops, with a leading space when 0
|
||||||
|
# is not set. FIXME: I'm sure there's a better way to do this.
|
||||||
|
if [ -z "$_deps" ]
|
||||||
|
then
|
||||||
|
_deps="0,1"
|
||||||
|
else
|
||||||
|
_deps="$(echo "$_deps" \
|
||||||
|
| tr -s " " \
|
||||||
|
| sed 's/^ //g' \
|
||||||
|
| tr ' ' ',')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# download mode: create directory provided in -d <dir>
|
||||||
|
if [ -n "$_dldir" ]
|
||||||
|
then
|
||||||
|
mkdir -p "$_dldir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Figuring out recursive dependencies, this may take some time..."
|
||||||
|
# FIXME: even though the list ist sorted -u this is only true for
|
||||||
|
# pkgpath, as textproc/libical and textproc/libical,-main are the
|
||||||
|
# going to be the same package. Simply stripping off all ,-main
|
||||||
|
# could fix it.. but it doesn't feel right.
|
||||||
|
_do_sql "$1" "$_deps" | sort -u | while read line
|
||||||
|
do
|
||||||
|
_portpath=$(echo "$line" | cut -d"|" -f1)
|
||||||
|
_pkgname=$(echo "$line" | cut -d"|" -f2)
|
||||||
|
|
||||||
|
# download mode: -d <dir>
|
||||||
|
if [ -n "$_dldir" ]
|
||||||
|
then
|
||||||
|
_extra="(downloading)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# showmode:
|
||||||
|
# unset: shows pkgpath and pkgname
|
||||||
|
# 1: shows pkgname only
|
||||||
|
# 2: shows pkgpath only
|
||||||
|
# 3: equals unset # FIXME: set 3 as default and don't handle unset.
|
||||||
|
# default || both on
|
||||||
|
if [ -z "$_showmode" ] || [ "$_showmode" == "3" ]
|
||||||
|
then
|
||||||
|
echo "$_portpath ($_pkgname) $_extra"
|
||||||
|
fi
|
||||||
|
# pkgname only
|
||||||
|
if [ "$_showmode" == "1" ]
|
||||||
|
then
|
||||||
|
echo "$_pkgname $_extra"
|
||||||
|
fi
|
||||||
|
# portpath only
|
||||||
|
if [ "$_showmode" == "2" ]
|
||||||
|
then
|
||||||
|
echo "$_portpath $_extra"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# download mode: download file from mirror
|
||||||
|
# note: this needs sqlports information and the mirror to be
|
||||||
|
# in sync, which only the case on -release.
|
||||||
|
# FIXME: figure out a way to do this in snaps.
|
||||||
|
# Naive idea: cut off the version, get index list from mirror with
|
||||||
|
# match agains the non-version name and download everything found.
|
||||||
|
if [ -n "$_dldir" ]
|
||||||
|
then
|
||||||
|
ftp -MV -C -o $_dldir/$_pkgname.tgz $_pkgpath/$_pkgname.tgz
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$_dldir" ]
|
||||||
|
then
|
||||||
|
# XXX: Are both variables needed?
|
||||||
|
echo "Set the following environmane variables to enable offline installation:"
|
||||||
|
echo "$ export TRUSTED_PKG_PATH=\"$(readlink -f "$_dldir")\""
|
||||||
|
echo "$ export PKG_PATH=\"$(readlink -f "$_dldir")\""
|
||||||
|
# FIXME: name the package that has been downloaded. But to translate $1
|
||||||
|
# to the package name, another sqlports db call would be necessary.
|
||||||
|
# There is also pkg_info -e ..., but that only works for alread installed
|
||||||
|
# packages.
|
||||||
|
echo "$ pkg_add <package>"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
### MAIN PROGRAM :)
|
||||||
|
case "$1" in
|
||||||
|
*/*) _handle_list "$1" ;;
|
||||||
|
*) _do_pkg "$1" ;;
|
||||||
|
esac
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#!/bin/sh -x
|
#!/bin/sh -x
|
||||||
|
|
||||||
cd /usr/ports
|
cd /usr/ports
|
||||||
doas rm -rf pobj/* plist logs packages bulk update distfiles/*
|
doas rm -rf pobj/* plist logs packages bulk update
|
||||||
|
case "$1" in
|
||||||
|
-a) doas rm -rf distfiles/* ;;
|
||||||
|
esac
|
||||||
mkdir -p plist logs packages bulk update
|
mkdir -p plist logs packages bulk update
|
||||||
doas make fix-permissions
|
doas make fix-permissions
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh -x
|
||||||
|
|
||||||
if [ -z "$1" ]
|
if [ -z "$1" ]
|
||||||
then
|
then
|
||||||
echo "usage: port-search <file pattern> <search term>"
|
echo "usage: port-search [file pattern] <search term>"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
type="$1"
|
if [ -n "$2" ]
|
||||||
shift
|
then
|
||||||
|
_filter="-iname *$1*" \
|
||||||
|
_term="$2"
|
||||||
|
else
|
||||||
|
_term="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
find /usr/ports/ \
|
find /usr/ports/ \
|
||||||
-not \( -path "/usr/ports/pobj" -prune \
|
-not \( -path "/usr/ports/pobj" -prune \
|
||||||
@@ -16,5 +21,5 @@ find /usr/ports/ \
|
|||||||
-o -path "*/CVS" -prune \
|
-o -path "*/CVS" -prune \
|
||||||
\) \
|
\) \
|
||||||
-type f \
|
-type f \
|
||||||
-iname "$type" \
|
$_filter \
|
||||||
-exec ugrep -F -- "$@" {} +
|
-exec ugrep -i -F -- "$_term" {} +
|
||||||
|
|||||||
24
.bin/rec_scr_hw_noaudio.sh
Executable file
24
.bin/rec_scr_hw_noaudio.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# configuration
|
||||||
|
_vidfile="/home/sdk/rec-screen.mkv"
|
||||||
|
_outfile="/home/sdk/rec-encoded-$(date "+%Y-%m-%d_%H%M%S").mp4"
|
||||||
|
|
||||||
|
_res="2880x1800"
|
||||||
|
_fps="60"
|
||||||
|
|
||||||
|
printf 'Press q to stop.\n'
|
||||||
|
set -x
|
||||||
|
|
||||||
|
ffmpeg -y -loglevel error -hide_banner \
|
||||||
|
-vaapi_device /dev/dri/renderD128 \
|
||||||
|
-framerate ${_fps} \
|
||||||
|
-f x11grab \
|
||||||
|
-video_size ${_res} \
|
||||||
|
-i :0 \
|
||||||
|
-vf 'hwupload,scale_vaapi=format=nv12' \
|
||||||
|
-c:v h264_vaapi \
|
||||||
|
-qp 24 \
|
||||||
|
-framerate ${_fps} \
|
||||||
|
"${_outfile}"
|
||||||
69
.bin/rtservermon.pl
Executable file
69
.bin/rtservermon.pl
Executable file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
#
|
||||||
|
# ONLY OpenBSD modules included with the default installation are permitted!
|
||||||
|
#
|
||||||
|
use HTTP::Tiny;
|
||||||
|
use Net::Ping;
|
||||||
|
use Time::HiRes;
|
||||||
|
|
||||||
|
# Configuration hash (editable)
|
||||||
|
my %config = (
|
||||||
|
'timeout' => 0.20, # How long to wait before giving up on server response, in seconds
|
||||||
|
'debug' => 1, # Debug output?
|
||||||
|
'top' => 3, # How many entries to return?
|
||||||
|
'protocol' => 'tcp', # tcp, udp, icmp, et al
|
||||||
|
'port' => 'http', # (used in getservbyname sub)
|
||||||
|
);
|
||||||
|
|
||||||
|
# hash to store servers and response times to protocol/port requests
|
||||||
|
my %serverstats;
|
||||||
|
|
||||||
|
# create HTTP::Tiny instance
|
||||||
|
my $http = HTTP::Tiny->new;
|
||||||
|
|
||||||
|
# Get a list of all current OpenBSD FTP servers
|
||||||
|
my $response = $http->get('http://ftp.eu.openbsd.org/pub/OpenBSD/ftplist');
|
||||||
|
die "Failed!\n" unless $response->{success};
|
||||||
|
|
||||||
|
# Iterate through server list and get TCP/80 response time in ms
|
||||||
|
foreach my $line (split("\n", $response->{content})) {
|
||||||
|
if ($line !~ /(cdn)/) {
|
||||||
|
if ($line =~ /(http:\/\/)(.+?)(\/\S+)/) {
|
||||||
|
my $response = &httping($2);
|
||||||
|
$serverstats{$1.$2.$3} = $response if ($response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sort & print servers by response time in ms
|
||||||
|
my $i = 0;
|
||||||
|
foreach my $key (sort {$serverstats{$a} <=> $serverstats{$b} } keys %serverstats) {
|
||||||
|
$i++;
|
||||||
|
print "$key\n";
|
||||||
|
last if $i eq $config{'top'};
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ping TCP/80 and return response time or 0 if unresponsive + some diagnostic output
|
||||||
|
#
|
||||||
|
|
||||||
|
sub httping ($) {
|
||||||
|
my $host = shift;
|
||||||
|
my $ping = Net::Ping->new($config{'protocol'});
|
||||||
|
$ping->hires();
|
||||||
|
$ping->{port_num} = getservbyname($config{'port'}, $config{'protocol'});
|
||||||
|
print ("Trying $host... ") if $config{'debug'};
|
||||||
|
my ($retval, $duration, $ip) = $ping->ping($host, $config{'timeout'});
|
||||||
|
$ping->close();
|
||||||
|
$duration = int($duration * 1000);
|
||||||
|
|
||||||
|
if ($retval) {
|
||||||
|
print ("$duration ms\n") if $config{'debug'};
|
||||||
|
return $duration;
|
||||||
|
} else {
|
||||||
|
print ("unresponsive\n") if $config{'debug'};;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.bin/samba
Executable file
2
.bin/samba
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
doas doas rcctl -f $1 smbd nmbd;
|
||||||
81
.bin/scr
81
.bin/scr
@@ -1,3 +1,80 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ -z $1 ] && doas wsconsctl -n display.brightness \
|
|
||||||
|| doas wsconsctl display.brightness=$1
|
# devices
|
||||||
|
_primary=$(xrandr | grep -v ^Screen | head -1 | cut -d" " -f1)
|
||||||
|
_max_res=$(xrandr | grep "^ " | head -1 | xargs | cut -d" " -f1)
|
||||||
|
_con_dev=$(xrandr | grep " connected" | grep -v "$_primary" | cut -d" " -f1 | xargs)
|
||||||
|
_dis_dev=$(xrandr | grep "disconnected" | cut -d" " -f1 | xargs)
|
||||||
|
|
||||||
|
if [ "$1" == "auto" ]
|
||||||
|
then
|
||||||
|
xrandr --output $_primary --auto
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" == "mirror" ]
|
||||||
|
then
|
||||||
|
for _dev in $_con_dev
|
||||||
|
do
|
||||||
|
xrandr --output $_dev --same-as $_primary
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
_loop() {
|
||||||
|
set -x
|
||||||
|
for _dev in $1
|
||||||
|
do xrandr --output $_dev $2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$1" == "left" ] \
|
||||||
|
&& _loop "$_con_dev" "--left-of $_primary"
|
||||||
|
|
||||||
|
[ "$1" == "right" ] \
|
||||||
|
&& _loop "$_con_dev" "--right-of $_primary"
|
||||||
|
|
||||||
|
[ "$1" == "above" ] \
|
||||||
|
&& _loop "$_con_dev" "--above $_primary"
|
||||||
|
|
||||||
|
[ "$1" == "auto" ] \
|
||||||
|
&& _loop "$_con_dev $_primary" "--auto"
|
||||||
|
|
||||||
|
[ "$1" == "off" ] \
|
||||||
|
&& _loop "$_con_dev" "--off"
|
||||||
|
|
||||||
|
[ "$1" == "fullhd" ] \
|
||||||
|
&& xrandr --output $_primary --mode "1920x1080"
|
||||||
|
|
||||||
|
[ "$1" == "hd" ] \
|
||||||
|
&& xrandr --output $_primary --mode "1280x720"
|
||||||
|
|
||||||
|
[ "$1" == "max" ] \
|
||||||
|
&& xrandr --output $_primary --mode "$_max_res"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
[0-9]*) doas wsconsctl display.brightness=$1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ "$1" == "r" ] && [ -n "$2" ] \
|
||||||
|
&& xrandr --output $_primary --mode "$2"
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "usage: res [mode]"
|
||||||
|
echo " auto - sets prefered mode for all connected displays"
|
||||||
|
echo " left - put screen left of primary screen"
|
||||||
|
echo " right - put screen right of primary screen"
|
||||||
|
echo " above - put screen above of primary screen"
|
||||||
|
echo " off - turn all connected screens off (except primary)"
|
||||||
|
echo " fullhd - set primary display resolution to FullHD (1920x1080)"
|
||||||
|
echo " hd - set primary display resolution to HD (1280x720)"
|
||||||
|
echo " max - set primary display to highest resolution ($_max_res)"
|
||||||
|
echo " r <res> - set primary display resolution"
|
||||||
|
echo " b <%> - display / set screen brightness"
|
||||||
|
echo
|
||||||
|
echo "Primary: $_primary"
|
||||||
|
echo "Connected: $_con_dev"
|
||||||
|
echo "Brightness: $(doas wsconsctl -n display.brightness)%"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
. ${HOME}/.bin/_config
|
. ${HOME}/.bin/_config
|
||||||
|
|
||||||
|
unset QT_FONT_DPI
|
||||||
|
unset GDK_DPI_SCALE
|
||||||
|
|
||||||
trap cleanup 1 2 3 6
|
trap cleanup 1 2 3 6
|
||||||
cleanup() { rm -f "$file"; }
|
cleanup() { rm -f "$file"; }
|
||||||
|
|
||||||
|
|||||||
97
.bin/subsonic
Executable file
97
.bin/subsonic
Executable file
@@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# subsonic
|
||||||
|
alias subsonic-cli="\subsonic-cli -c $HOME/.subsonic-cli.conf"
|
||||||
|
|
||||||
|
subsonic-play() {
|
||||||
|
# $1 songId
|
||||||
|
for song in $@
|
||||||
|
do
|
||||||
|
echo $song > /tmp/.playing
|
||||||
|
subsonic-cli stream -p id $song \
|
||||||
|
| mpv --force-window=no --loop=no - || exit 0
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
subsonic-random() {
|
||||||
|
while true;
|
||||||
|
do
|
||||||
|
echo "Fetching moar dataaa.."
|
||||||
|
subsonic-play $(subsonic-cli getRandomSongs \
|
||||||
|
| jq -r '.randomSongs[][].id')
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
subsonic-favorites() {
|
||||||
|
while true;
|
||||||
|
do
|
||||||
|
echo "Fetching moar dataaa.."
|
||||||
|
subsonic-play $(subsonic-cli getStarred \
|
||||||
|
| jq -r '.starred[][].id' \
|
||||||
|
| sort -r)
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
subsonic-search() {
|
||||||
|
{
|
||||||
|
echo "|ALBUMID|ID|ALBUM|ARTIST|TITLE|GENRE|"
|
||||||
|
printf "|%s|%s|%s|%s|%s|%s|\n" "--------------------------------"\
|
||||||
|
"--------------------------------"\
|
||||||
|
"--------" "--------" "--------" "--------"
|
||||||
|
subsonic-cli search3 \
|
||||||
|
-p songcount 200 \
|
||||||
|
-p query "$@" \
|
||||||
|
| jq -r '.searchResult3[][]|select(.contentType!=null)|[.albumId,.id,.album,.title,.artist,.genre]' \
|
||||||
|
| tr -d '", ' \
|
||||||
|
| awk '/^\[/ { S++ } \
|
||||||
|
/^\]/ { S-- } \
|
||||||
|
S==0 { NR=0 } \
|
||||||
|
NR==2 { AID=$0 } \
|
||||||
|
NR==3 { ID=$0 } \
|
||||||
|
NR==4 { ALBUM=$0 } \
|
||||||
|
NR==5 { TITLE=$0 } \
|
||||||
|
NR==6 { ARTIST=$0 } \
|
||||||
|
NR==7 { GENRE=$0 } \
|
||||||
|
NR==0 { printf("|%s|%s|%s|%s|%s|%s|\n", AID, ID, ALBUM, ARTIST, TITLE, GENRE) }'
|
||||||
|
} | column -s'|' -t
|
||||||
|
}
|
||||||
|
|
||||||
|
subsonic-star() {
|
||||||
|
[ -f /tmp/.playing ] \
|
||||||
|
&& subsonic-cli star -p id $(cat /tmp/.playing | tail -1) \
|
||||||
|
|| echo bruh.
|
||||||
|
}
|
||||||
|
|
||||||
|
subsonic-unstar() {
|
||||||
|
[ -f /tmp/.playing ] \
|
||||||
|
&& subsonic-cli unstar -p id $(cat /tmp/.playing | tail -1) \
|
||||||
|
|| echo bruh.
|
||||||
|
}
|
||||||
|
|
||||||
|
subsonic-download() {
|
||||||
|
# $1 albumId
|
||||||
|
NAME=$(subsonic-cli getAlbum -p id $1 \
|
||||||
|
| jq -r '.album.artist,.album.name' | xargs | tr ' ' '-')
|
||||||
|
printf "Downloading to %s/subsonic-download/%s.zip\n" "$HOME" "$NAME"
|
||||||
|
mkdir -p "$HOME/subsonic-download"
|
||||||
|
subsonic-cli download -p id $1 | pv > "$HOME/subsonic-download/$NAME.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -z $1 ]
|
||||||
|
then
|
||||||
|
cat <<"EOF"
|
||||||
|
usage: subsonic <command> <args>
|
||||||
|
|
||||||
|
play <song id> - play song with id
|
||||||
|
download <album id> - download album with id
|
||||||
|
[un]star - [un]star currently playing song
|
||||||
|
search <term> - show song/album for term
|
||||||
|
favorites - play starred songs
|
||||||
|
random - play random songs
|
||||||
|
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
subsonic-$1 $2
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
7
.bin/tailscale-tunnel
Executable file
7
.bin/tailscale-tunnel
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/ksh
|
||||||
|
# doas tailscale up --auth-key=tskey-auth-kx3Lf18kgg11CNTRL-5QJ7tUCJ8KAoPqVtJKY6MAzghyuCoaR9F
|
||||||
|
doas tailscale up \
|
||||||
|
--reset \
|
||||||
|
--advertise-exit-node \
|
||||||
|
--accept-routes \
|
||||||
|
--accept-dns=true
|
||||||
6
.bin/tailscale-tunnel-client
Executable file
6
.bin/tailscale-tunnel-client
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/ksh
|
||||||
|
# doas tailscale up --auth-key=tskey-auth-kx3Lf18kgg11CNTRL-5QJ7tUCJ8KAoPqVtJKY6MAzghyuCoaR9F
|
||||||
|
doas tailscale up \
|
||||||
|
--reset \
|
||||||
|
--accept-dns=true \
|
||||||
|
--exit-node=dalek
|
||||||
@@ -1,13 +1,22 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. $HOME/.bin/_config
|
. $HOME/.bin/_config
|
||||||
|
|
||||||
[ -d "$1" ] || ( printf "Usage: backup <target>\n" && exit 2; )
|
_target=$(readlink -f "$1" 2> /dev/null)
|
||||||
|
|
||||||
|
[ ! "$_target" ] \
|
||||||
|
&& printf "Usage: backup <target>\n" \
|
||||||
|
&& exit 2;
|
||||||
|
|
||||||
|
print "pass Internet/Tarsnap.key > /root/tarsnap.key ..."
|
||||||
|
pass Internet/Tarsnap.key | doas tee /root/tarsnap.key > /dev/null
|
||||||
|
doas chown root:sdk /root/tarsnap.key
|
||||||
|
doas chmod 640 /root/tarsnap.key
|
||||||
|
doas chmod 750 /root
|
||||||
|
|
||||||
print "Tarsnap Backup:"
|
print "Tarsnap Backup:"
|
||||||
|
|
||||||
_target=$(readlink -f "$1")
|
|
||||||
_key=$(pwgen -n1 8)
|
_key=$(pwgen -n1 8)
|
||||||
_date=$(date "+%Y-%m-%d %H:%M")
|
_date=$(date "+%Y-%m-%d %H:%M")
|
||||||
_host=$(uname -n)
|
_host=$(uname -n)
|
||||||
|
|
||||||
doas tarsnap --humanize-numbers --checkpoint-bytes 52428800 --exclude "*/.git/*" -cvf "$_host: $_target $_date ($_key)" "$_target"
|
doas tarsnap --humanize-numbers --checkpoint-bytes 52428800 --exclude "*/.git/*" -cvf "$_host: $_target $_date ($_key)" "$_target"
|
||||||
|
|||||||
38
.bin/tarsnap-restore
Executable file
38
.bin/tarsnap-restore
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. $HOME/.bin/_config
|
||||||
|
|
||||||
|
print "Tarsnap Restore:"
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
doas tarsnap --list-archives | sort
|
||||||
|
printf "Usage: restore <key_id>\n"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
_backup="$(doas tarsnap --list-archives | grep "$1")"
|
||||||
|
if [ -z "$_backup" ]; then
|
||||||
|
print "No backup with key id $1 found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print "Found Backup: $_backup"
|
||||||
|
mkdir -p "restore_$1"
|
||||||
|
print "Extracting to: $(readlink -f $PWD/restore_$1)"
|
||||||
|
|
||||||
|
if [ -f "restore_$1/.done" ]
|
||||||
|
then
|
||||||
|
print "Skipping, because restore_$1/.done file exists."
|
||||||
|
else
|
||||||
|
doas tarsnap -tf "$_backup" \
|
||||||
|
| xargs -P 50 -n 1 -t \
|
||||||
|
doas tarsnap --humanize-numbers --resume-extract --chroot -xf "$_backup" -C "restore_$1" --
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]
|
||||||
|
then
|
||||||
|
print "Data restored in $(readlink -f "restore_$1")"
|
||||||
|
touch "restore_$1/.done"
|
||||||
|
else
|
||||||
|
print "Restore aborted..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
print ""
|
||||||
10
.bin/umount-cryptoffs
Executable file
10
.bin/umount-cryptoffs
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
_dev=${1:-sd3}
|
||||||
|
doas umount /mnt 2>&1 | grep -q busy && echo "/mnt is busy" && exit 1
|
||||||
|
_biodev=$(doas bioctl softraid0 | grep -C1 sd3 | grep CRYPTO | awk '{ print $5 }')
|
||||||
|
if [ -n "$_biodev" ]
|
||||||
|
then
|
||||||
|
doas bioctl -d ${_biodev} && echo "bioctl: $_dev detached"
|
||||||
|
else
|
||||||
|
echo "bioctl: $_dev: currently not attached"
|
||||||
|
fi
|
||||||
137
.bin/update-adlist
Executable file
137
.bin/update-adlist
Executable file
@@ -0,0 +1,137 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
trap _restore_all 1 2 3 6
|
||||||
|
|
||||||
|
# list of filenames can can be fetched from $_url
|
||||||
|
_list=/etc/unwind/blocklistproject.txt
|
||||||
|
_url=https://blocklistproject.github.io/Lists/alt-version
|
||||||
|
|
||||||
|
# download blocklists here
|
||||||
|
_dir=/etc/unwind/lists
|
||||||
|
|
||||||
|
# combined, sorted and filtered list of all lists configured in $_list
|
||||||
|
# configure in /etc/unwind.conf:
|
||||||
|
# block list "/etc/unwind/_assembled.txt" log
|
||||||
|
_unwind_blocklist="/etc/unwind/_assembled.txt"
|
||||||
|
|
||||||
|
if [ ! -f $_list ]
|
||||||
|
then
|
||||||
|
echo "Creating new adlist /etc/unwind/blocklistproject.txt:"
|
||||||
|
doas mkdir -p $_dir
|
||||||
|
doas tee $_list <<EOF
|
||||||
|
## from https://github.com/blocklistproject/Lists
|
||||||
|
## ## => comment
|
||||||
|
## # => disabled list (will be deleted if present)
|
||||||
|
abuse-nl.txt
|
||||||
|
adobe-nl.txt
|
||||||
|
ads-nl.txt
|
||||||
|
basic-nl.txt
|
||||||
|
crypto-nl.txt
|
||||||
|
drugs-nl.txt
|
||||||
|
#everything-nl.txt
|
||||||
|
facebook-nl.txt
|
||||||
|
fortnite-nl.txt
|
||||||
|
fraud-nl.txt
|
||||||
|
gambling-nl.txt
|
||||||
|
malware-nl.txt
|
||||||
|
phishing-nl.txt
|
||||||
|
piracy-nl.txt
|
||||||
|
porn-nl.txt
|
||||||
|
ransomware-nl.txt
|
||||||
|
redirect-nl.txt
|
||||||
|
scam-nl.txt
|
||||||
|
smart-tv-nl.txt
|
||||||
|
tiktok-nl.txt
|
||||||
|
torrent-nl.txt
|
||||||
|
tracking-nl.txt
|
||||||
|
twitter-nl.txt
|
||||||
|
vaping-nl.txt
|
||||||
|
whatsapp-nl.txt
|
||||||
|
youtube-nl.txt
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
_restore_all() {
|
||||||
|
echo "Signal received, aborting..."
|
||||||
|
for _f in $_dir/*.old
|
||||||
|
do
|
||||||
|
echo "Restore: $(basename $_f)"
|
||||||
|
doas mv -f "$_f" "${_f%%.old}"
|
||||||
|
done
|
||||||
|
_assemble
|
||||||
|
_restart_unwind
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_backup() {
|
||||||
|
_f=$(basename "$1")
|
||||||
|
if [ -f "$_dir/$_f" ]
|
||||||
|
then
|
||||||
|
echo "Backup: $_f -> $_f.old"
|
||||||
|
doas mv -f "$_dir/$_f" "$_dir/$_f.old"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_restore() {
|
||||||
|
_f=$(basename "$1")
|
||||||
|
if [ -f "$_dir/$_f.old" ]
|
||||||
|
then
|
||||||
|
echo "Restore: $_f.old -> $_f"
|
||||||
|
doas mv -f "$_dir/$_f" "$_dir/$_f.old"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_download() {
|
||||||
|
echo "Download: $_file"
|
||||||
|
doas ftp -V -o "$_dir/$_file" "$_url/$_file" > /dev/null \
|
||||||
|
&& doas rm -f "$_dir/$_file.old"
|
||||||
|
}
|
||||||
|
|
||||||
|
_disabled() {
|
||||||
|
if echo "$1" | grep -q "^#"
|
||||||
|
then
|
||||||
|
_f=$(basename "$1" | tr -d '# ')
|
||||||
|
echo "Skip (disabled): $_f"
|
||||||
|
doas rm -f $_dir/$_f
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_domainfilter() {
|
||||||
|
# chain grep commands used in assemble pipe
|
||||||
|
grep -Ev "torrent|tattoo|xhamster|xvideos|porn|motherless|redgifs" \
|
||||||
|
| grep -Ev "whatsapp\.net|whatsapp\.com|instagram\.com" \
|
||||||
|
| grep -Ev "adobe\.com|adobelogin\.com" \
|
||||||
|
| grep -Ev "microsoft\.com|archive\.org|sony\.com|playstation|psn|fotostelvio"
|
||||||
|
}
|
||||||
|
|
||||||
|
_assemble() {
|
||||||
|
echo "Assemble blocklist: $_unwind_blocklist"
|
||||||
|
cat $_dir/*.txt \
|
||||||
|
| tr -d " " \
|
||||||
|
| grep -v '^#' \
|
||||||
|
| grep -v '^-' \
|
||||||
|
| grep -v '^$' \
|
||||||
|
| cut -d "#" -f1 \
|
||||||
|
| sed 's/\.$//g' \
|
||||||
|
| _domainfilter \
|
||||||
|
| doas sort -uo $_unwind_blocklist
|
||||||
|
}
|
||||||
|
|
||||||
|
_restart_unwind() {
|
||||||
|
doas rcctl restart unwind
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for _file in $(grep -v "^##" $_list \
|
||||||
|
| cut -d "#" -f1 \
|
||||||
|
| xargs)
|
||||||
|
do
|
||||||
|
if ! _disabled $_file
|
||||||
|
then
|
||||||
|
_backup $_file
|
||||||
|
_download || _restore
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
_assemble
|
||||||
|
_restart_unwind
|
||||||
@@ -54,6 +54,10 @@ add "set -A complete_man_1 -- " "$S1 $S5 $S8"
|
|||||||
ARGS="add flush jump load monitor next pause play prev repeat restart show status stop toggle"
|
ARGS="add flush jump load monitor next pause play prev repeat restart show status stop toggle"
|
||||||
add "set -A complete_amused_1 -- " "$ARGS"
|
add "set -A complete_amused_1 -- " "$ARGS"
|
||||||
|
|
||||||
|
add "set -A complete_l_1 -- " "make remake test debug pr update reset diff update-port"
|
||||||
|
|
||||||
|
add "set -A complete_upload_1 -- " "rm rml ls last ren renl fixl sh ksh txt log gz tgz"
|
||||||
|
|
||||||
#
|
#
|
||||||
# GOT
|
# GOT
|
||||||
#
|
#
|
||||||
|
|||||||
10
.bin/update-luakit-adlist
Executable file
10
.bin/update-luakit-adlist
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh -xe
|
||||||
|
|
||||||
|
for list in easylist/easylist \
|
||||||
|
easylist/easyprivacy \
|
||||||
|
easylist/fanboy-social \
|
||||||
|
easylistgermany/easylistgermany
|
||||||
|
do
|
||||||
|
ftp -o $HOME/.local/share/luakit/adblock/$(basename $list).txt \
|
||||||
|
https://easylist.to/${list}.txt
|
||||||
|
done
|
||||||
14
.bin/update-mystuff
Executable file
14
.bin/update-mystuff
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh -xe
|
||||||
|
|
||||||
|
mystuff="
|
||||||
|
/usr/ports/mystuff/x11/st-sdk
|
||||||
|
/usr/ports/mystuff/sysutils/libtree
|
||||||
|
/usr/ports/sysutils/tarsnap
|
||||||
|
"
|
||||||
|
|
||||||
|
for p in $mystuff
|
||||||
|
do
|
||||||
|
cd $p
|
||||||
|
make clean=all
|
||||||
|
make reinstall
|
||||||
|
done
|
||||||
39
.bin/update-pim-all
Executable file
39
.bin/update-pim-all
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#/bin/sh -xe
|
||||||
|
. ~/.bin/_config
|
||||||
|
needs vdirsyncer-- mu-- isync-- git-- p5-iCal-Parser-- remind--
|
||||||
|
|
||||||
|
# snapshot
|
||||||
|
cd /home/sdk/.reminders
|
||||||
|
git add *
|
||||||
|
git commit -m "Update $(date +"%Y-%m-%d %H:%M:%S")" || true
|
||||||
|
|
||||||
|
# copy uugrn calendard to dalek
|
||||||
|
scp -q vorstand@vorstand.uugrn.org:private/Kalender/uugrn.rem \
|
||||||
|
sdk@home.codevoid.de:.reminders/uugrn.rem
|
||||||
|
|
||||||
|
# copy all calendars from dalek to local
|
||||||
|
scp -q sdk@home.codevoid.de:.reminders/\*.rem \
|
||||||
|
/home/sdk/.reminders/
|
||||||
|
|
||||||
|
# download vcal/vcard from icloud / radical
|
||||||
|
vdirsyncer sync
|
||||||
|
|
||||||
|
# create import.rem from ical events (XXX fix this mess)
|
||||||
|
find ~/.isync -name "*.ics" -exec cat {} + \
|
||||||
|
| ical2rem --no-todos \
|
||||||
|
| fgrep -v "REM MSG" \
|
||||||
|
| sed 's,\\n, ,g' \
|
||||||
|
| tr -d '\' \
|
||||||
|
| sed 's/ / /g' \
|
||||||
|
> /home/sdk/.reminders/import.rem
|
||||||
|
|
||||||
|
# create abook addressbook
|
||||||
|
cat /home/sdk/.isync/contacts/*.vcf \
|
||||||
|
| abook --convert --informat vcard --outformat abook \
|
||||||
|
> /home/sdk/.abook/addressbook
|
||||||
|
|
||||||
|
# sync email to offline
|
||||||
|
mbsync -a
|
||||||
|
|
||||||
|
# index email
|
||||||
|
mu index
|
||||||
277
.bin/upload
277
.bin/upload
@@ -1,24 +1,267 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
if [ x"$1" == x"rm" ]
|
# manage files in a webroot
|
||||||
then
|
# needs:
|
||||||
shift
|
# - sh: cp, rm, mv, echo, basename, dirname
|
||||||
for file in $@
|
# - openssh: ssh, scp
|
||||||
do
|
# - coreutils: chmod, sed, tail
|
||||||
ssh sdk@codevoid.de "cd /home/www/htdocs/ptrace/paste/ && rm -v $(basename "$file")" || true
|
# - archivers: gzip, tar
|
||||||
|
# - xclip
|
||||||
|
|
||||||
|
###
|
||||||
|
### CONFIGURATION
|
||||||
|
###
|
||||||
|
|
||||||
|
# remote patch uploaded files should go
|
||||||
|
_rpath="/home/www/htdocs/ptrace/paste"
|
||||||
|
|
||||||
|
# web url where the uploaded files can be accessed
|
||||||
|
_weburi="https://ptrace.org"
|
||||||
|
|
||||||
|
# ssh user@host
|
||||||
|
_sshhost="sdk@codevoid.de"
|
||||||
|
|
||||||
|
# permissions (for the fixl command)
|
||||||
|
_chown="sdk:www"
|
||||||
|
_chmod="u+rw,g+r"
|
||||||
|
|
||||||
|
###
|
||||||
|
### SET ARGUMENT SWITCHES
|
||||||
|
###
|
||||||
|
|
||||||
|
for arg in "$@"
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
# extensions
|
||||||
|
sh) _ext=".sh" ;;
|
||||||
|
ksh) _ext=".ksh" ;;
|
||||||
|
txt) _ext=".txt" ;;
|
||||||
|
log) _ext=".log" ;;
|
||||||
|
# archive mode
|
||||||
|
gz) _gz=1 ;;
|
||||||
|
tgz) _tgz=1 ;;
|
||||||
|
# commands
|
||||||
|
rm) _rm=1 ;;
|
||||||
|
rml) _rmlast=1 ;;
|
||||||
|
ls) _ls=1 ;;
|
||||||
|
l|last) _last="-1" ;;
|
||||||
|
-[0-9]*) _last="$arg" ;;
|
||||||
|
fixl) _fixperm=1 ;;
|
||||||
|
ren|mv) _mv=1 ;;
|
||||||
|
renl|mvl) _mvlast=1 ;;
|
||||||
|
-h) ;; # swallow
|
||||||
|
*) break; ;;
|
||||||
|
esac
|
||||||
|
shift;
|
||||||
|
done
|
||||||
|
|
||||||
|
###
|
||||||
|
### FUNCTIONS
|
||||||
|
###
|
||||||
|
|
||||||
|
# fetches remote file list
|
||||||
|
remote_list() {
|
||||||
|
ssh $_sshhost \
|
||||||
|
"cd $_rpath/ \
|
||||||
|
&& ls -1tr"
|
||||||
|
}
|
||||||
|
|
||||||
|
# formats file list output
|
||||||
|
remote_list_print() {
|
||||||
|
while read f
|
||||||
|
do
|
||||||
|
echo "$_weburi/$(echo "$f" \
|
||||||
|
| sed 's/ /%20/g') ($f)"
|
||||||
done
|
done
|
||||||
elif [ x"$1" == x"ls" ]
|
}
|
||||||
|
|
||||||
|
copy_and_print() {
|
||||||
|
echo "$_weburi/$(basename "$1")" \
|
||||||
|
| sed 's/ /%20/g' \
|
||||||
|
| xclip -f -r
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
### MAIN PROGRAM
|
||||||
|
###
|
||||||
|
|
||||||
|
# HANDLE CASE: "standard input"
|
||||||
|
# upload with provided or generated filename
|
||||||
|
if [[ ! -t 0 ]]
|
||||||
then
|
then
|
||||||
shift
|
fname="$1"
|
||||||
ssh sdk@codevoid.de "cd /home/www/htdocs/ptrace/paste/ && ls -1 | xargs -n1 -I{} echo https://ptrace.org/{}"
|
[ -z "$fname" ] \
|
||||||
else
|
&& fname="$(date +"%Y-%m-%d_%H%M%S").txt"
|
||||||
for file in $@
|
cat - | ssh $_sshhost "cat - > \"$_rpath/$fname\""
|
||||||
|
copy_and_print "$fname"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: "list all remote files"
|
||||||
|
if [ -n "$_ls" ]
|
||||||
|
then
|
||||||
|
remote_list \
|
||||||
|
| remote_list_print
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: "list last N remote files"
|
||||||
|
if [ -n "$_last" ]
|
||||||
|
then
|
||||||
|
remote_list \
|
||||||
|
| tail $_last \
|
||||||
|
| remote_list_print
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: rename remote file
|
||||||
|
if [ -n "$_mv" ]
|
||||||
|
then
|
||||||
|
_arg1=$(basename "$1")
|
||||||
|
_arg2=$(basename "$2")
|
||||||
|
ssh $_sshhost \
|
||||||
|
"cd $_rpath/ \
|
||||||
|
&& mv -v \"$_arg1\" \"$_arg2\""
|
||||||
|
echo "$_arg2" | remote_list_print
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: rename the last uploaded remote file
|
||||||
|
if [ -n "$_mvlast" ]
|
||||||
|
then
|
||||||
|
_arg1=$(basename "$1")
|
||||||
|
lastfile="$(remote_list | tail -1)"
|
||||||
|
ssh $_sshhost \
|
||||||
|
"cd $_rpath/ \
|
||||||
|
&& mv -v \"$lastfile\" \"$_arg1\""
|
||||||
|
echo "$_arg1" | remote_list_print
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: delete remote file
|
||||||
|
if [ -n "$_rm" ]
|
||||||
|
then
|
||||||
|
for file in "$@"
|
||||||
|
do
|
||||||
|
ssh $_sshhost \
|
||||||
|
"cd $_rpath/ \
|
||||||
|
&& rm -v \"$(basename "$file")\"" \
|
||||||
|
|| true
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: delete last uploaded remote file
|
||||||
|
if [ -n "$_rmlast" ]
|
||||||
|
then
|
||||||
|
lastfile="$(remote_list | tail -1)"
|
||||||
|
echo "rm $lastfile"
|
||||||
|
ssh $_sshhost \
|
||||||
|
"cd $_rpath/ \
|
||||||
|
&& rm -f \"$lastfile\"" \
|
||||||
|
|| true
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: fix permission of last file
|
||||||
|
if [ -n "$_fixperm" ]
|
||||||
|
then
|
||||||
|
lastfile="$(remote_list | tail -1)"
|
||||||
|
echo "Fixing: $lastfile"
|
||||||
|
ssh $_sshhost "cd $_rpath/; \
|
||||||
|
chown $_chown \"$lastfile\"; \
|
||||||
|
chmod $_chmod \"$lastfile\"; \
|
||||||
|
ls -lh \"$lastfile\""
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HANDLE CASE: upload of files and folders
|
||||||
|
if [ $# -gt 0 ]
|
||||||
|
then
|
||||||
|
for item in "$@"
|
||||||
do
|
do
|
||||||
chmod o+rw,g+r "$file"
|
# the whole handling shall run in a subshell so all variables
|
||||||
scp "$file" sdk@codevoid.de:/home/www/htdocs/ptrace/paste/
|
# are reset when we leave the scope. Note, that this requires
|
||||||
echo "https://ptrace.org/$(basename "$file")" \
|
# us to "return", instead of "continue" skip to the next loop
|
||||||
| sed 's/ /%20/g' \
|
# iteration
|
||||||
| xclip -f -r
|
(
|
||||||
echo
|
[ ! -e "$item" ] \
|
||||||
|
&& echo "File or directory not found: $item" \
|
||||||
|
&& return
|
||||||
|
|
||||||
|
# target filename
|
||||||
|
file="$(basename "$item")$_ext"
|
||||||
|
|
||||||
|
# CASE "file" "no archive mode"
|
||||||
|
if [ -f "$item" ] && [ -z "$_tgz" ] && [ -z "$_gz" ]
|
||||||
|
then
|
||||||
|
echo "Uploading $item as $file"
|
||||||
|
scp -q "$item" $_sshhost:"$_rpath/$file"
|
||||||
|
copy_and_print "$file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# CASE "folder"
|
||||||
|
[ -d "$item" ] && _tgz=1
|
||||||
|
|
||||||
|
# CASE "tgz archive mode"
|
||||||
|
if [ -n "$_tgz" ]
|
||||||
|
then
|
||||||
|
file="$file.tgz"
|
||||||
|
echo "Uploading $item as $file"
|
||||||
|
# moving closer to the item to not archive the whole path
|
||||||
|
cd $(dirname "$item")
|
||||||
|
tar czf - "$(basename "$item")" \
|
||||||
|
| ssh $_sshhost "cat - > \"$_rpath/$file\""
|
||||||
|
copy_and_print "$file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# CASE "gz archive mode"
|
||||||
|
if [ -f "$item" ] && [ -n "$_gz" ]
|
||||||
|
then
|
||||||
|
file="$file.gz"
|
||||||
|
echo "Uploading \"$item\" as \"$file\""
|
||||||
|
cat "$item" | gzip \
|
||||||
|
| ssh $_sshhost "cat - > \"$_rpath/$file\""
|
||||||
|
copy_and_print "$file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# hopefully never reached
|
||||||
|
echo "Unhandled situation for: $item"
|
||||||
|
|
||||||
|
) # leave scope & reset variables
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# USAGE
|
||||||
|
if [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
echo "usage: upload [command] [ext] [<files>]"
|
||||||
|
echo " upload [filename] < file"
|
||||||
|
echo " cat file | upload [filename]"
|
||||||
|
echo
|
||||||
|
echo " Commands:"
|
||||||
|
echo " rm <files> - remove files"
|
||||||
|
echo " rml - remove last upload"
|
||||||
|
echo " ls - list files"
|
||||||
|
echo " l|last - list last file"
|
||||||
|
echo " -0..N - list N last files"
|
||||||
|
echo " mv|ren <oldname> <newname> - rename file"
|
||||||
|
echo " mvl|renl <newname> - rename last uploaded file"
|
||||||
|
echo " fixl - fix permission of last uploaded file"
|
||||||
|
echo
|
||||||
|
echo " Extensions:"
|
||||||
|
echo " sh, ksh, txt, log - add extension to file"
|
||||||
|
echo " gz, tgz - uploads file as archive (tgz is always used for folders)"
|
||||||
|
echo
|
||||||
|
echo " <files> - files or directories to upload (needs to be the last argument)"
|
||||||
|
echo
|
||||||
|
echo "Special Case:"
|
||||||
|
echo " When data is piped to the script it expects only one"
|
||||||
|
echo " optional argument, which would be the target filename."
|
||||||
|
echo
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ nature
|
|||||||
|
|
||||||
essen
|
essen
|
||||||
🍏🍎🍐🍊🍋🍌🍉🍇🍓🍈🍒🍑🍍🍅🍆🌽🍠🍞🍳🍗🍖 🍔🍟🍕🍝🍜🍲🍛🍣🍱🍤🍚🍧🍨🍦🍮🍭🍬🍫🍩🍪🌰
|
🍏🍎🍐🍊🍋🍌🍉🍇🍓🍈🍒🍑🍍🍅🍆🌽🍠🍞🍳🍗🍖 🍔🍟🍕🍝🍜🍲🍛🍣🍱🍤🍚🍧🍨🍦🍮🍭🍬🍫🍩🍪🌰
|
||||||
🍯🍼☕🍵🍶🍺🍻🍷🍸🍹🍴
|
🍯🍼☕🍵🍶🍺🍻🍷🍸🍹🍴🥂🍾
|
||||||
|
|
||||||
|
|
||||||
activity
|
activity
|
||||||
|
|||||||
1
.bin/xdg-open
Symbolic link
1
.bin/xdg-open
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
nnn.sh
|
||||||
21
.bin/ytdl
21
.bin/ytdl
@@ -5,8 +5,21 @@ then
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$HOME/ytdl/$1/"
|
if [ ! -d "$HOME/ytdl/$1/" ]
|
||||||
ksh-update-completions &
|
then
|
||||||
|
mkdir -p "$HOME/ytdl/$1/"
|
||||||
|
update-ksh-completions
|
||||||
|
. $HOME/.kshrc.autocomplete
|
||||||
|
fi
|
||||||
cd "$HOME/ytdl/$1/"
|
cd "$HOME/ytdl/$1/"
|
||||||
yt-dlp --cookies-from-browser chromium "$2"
|
shift
|
||||||
|
yt-dlp \
|
||||||
|
--print filename \
|
||||||
|
--cookies-from-browser firefox \
|
||||||
|
--user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0" \
|
||||||
|
--preset-alias mp4 \
|
||||||
|
--embed-metadata \
|
||||||
|
--embed-subs \
|
||||||
|
--restrict-filenames \
|
||||||
|
-o "%(channel&{} - |)s%(uploader&{} - |)s%(playlist|&{} - )s%(playlist_index&{} - |)s%(title)s.%(ext)s" \
|
||||||
|
"$@"
|
||||||
|
|||||||
4
.config/gopass/config
Normal file
4
.config/gopass/config
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[mounts]
|
||||||
|
path = /home/sdk/.password-store
|
||||||
|
[audit]
|
||||||
|
concurrency = 1
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
require "lfs"
|
require "lfs"
|
||||||
|
|
||||||
local unique_instance = require "unique_instance"
|
-- local unique_instance = require "unique_instance"
|
||||||
unique_instance.open_links_in_new_window = true
|
-- unique_instance.open_links_in_new_window = true
|
||||||
|
|
||||||
-- Set the number of web processes to use. A value of 0 means 'no limit'.
|
-- Set the number of web processes to use. A value of 0 means 'no limit'.
|
||||||
-- luakit.process_limit = 1
|
-- luakit.process_limit = 1
|
||||||
@@ -57,10 +57,10 @@ local binds = require "binds"
|
|||||||
local settings = require "settings"
|
local settings = require "settings"
|
||||||
local settings_chrome = require "settings_chrome"
|
local settings_chrome = require "settings_chrome"
|
||||||
|
|
||||||
settings.window.home_page = "luakit://newtab"
|
-- settings.window.home_page = "luakit://newtab"
|
||||||
-- settings.window.scroll_step = 20
|
-- settings.window.scroll_step = 600
|
||||||
settings.window.zoom_step = 0.2
|
settings.window.zoom_step = 0.2
|
||||||
settings.webview.zoom_level = 100
|
settings.webview.zoom_level = 90
|
||||||
settings.window.close_with_last_tab = true
|
settings.window.close_with_last_tab = true
|
||||||
|
|
||||||
-- search engines
|
-- search engines
|
||||||
@@ -79,19 +79,19 @@ settings.window.search_engines.default = settings.window.search_engines.ddg
|
|||||||
-- local adblock_chrome = require "adblock_chrome"
|
-- local adblock_chrome = require "adblock_chrome"
|
||||||
|
|
||||||
-- Enable Developer Tools
|
-- Enable Developer Tools
|
||||||
-- local webinspector = require "webinspector"
|
local webinspector = require "webinspector"
|
||||||
|
|
||||||
-- Add uzbl-like form filling
|
-- Add uzbl-like form filling
|
||||||
-- local formfiller = require "formfiller"
|
local formfiller = require "formfiller"
|
||||||
-- formfiller.extend({
|
formfiller.extend({
|
||||||
-- pass = function(s) return io.popen("pass " .. s):read() end
|
pass = function(s) return io.popen("pass " .. s):read() end
|
||||||
-- })
|
})
|
||||||
|
|
||||||
-- Add proxy support & manager
|
-- Add proxy support & manager
|
||||||
-- local proxy = require "proxy"
|
local proxy = require "proxy"
|
||||||
|
|
||||||
-- Add quickmarks support & manager
|
-- Add quickmarks support & manager
|
||||||
-- local quickmarks = require "quickmarks"
|
local quickmarks = require "quickmarks"
|
||||||
|
|
||||||
-- Add session saving/loading support
|
-- Add session saving/loading support
|
||||||
-- local session = require "session"
|
-- local session = require "session"
|
||||||
@@ -100,20 +100,20 @@ settings.window.search_engines.default = settings.window.search_engines.ddg
|
|||||||
local gopher = require "gopher"
|
local gopher = require "gopher"
|
||||||
|
|
||||||
-- Delete website data
|
-- Delete website data
|
||||||
-- local clear_data = require "clear_data"
|
local clear_data = require "clear_data"
|
||||||
|
|
||||||
-- Add command to list closed tabs & bind to open closed tabs
|
-- Add command to list closed tabs & bind to open closed tabs
|
||||||
local undoclose = require "undoclose"
|
local undoclose = require "undoclose"
|
||||||
|
|
||||||
-- Add command to list tab history items
|
-- Add command to list tab history items
|
||||||
-- local tabhistory = require "tabhistory"
|
local tabhistory = require "tabhistory"
|
||||||
|
|
||||||
-- Add greasemonkey-like javascript userscript support
|
-- Add greasemonkey-like javascript userscript support
|
||||||
--- local userscripts = require "userscripts"
|
local userscripts = require "userscripts"
|
||||||
|
|
||||||
-- Add bookmarks support
|
-- Add bookmarks support
|
||||||
-- local bookmarks = require "bookmarks"
|
local bookmarks = require "bookmarks"
|
||||||
-- local bookmarks_chrome = require "bookmarks_chrome"
|
local bookmarks_chrome = require "bookmarks_chrome"
|
||||||
|
|
||||||
-- Add download support
|
-- Add download support
|
||||||
local downloads = require "downloads"
|
local downloads = require "downloads"
|
||||||
@@ -121,7 +121,7 @@ local downloads_chrome = require "downloads_chrome"
|
|||||||
downloads.default_dir = os.getenv("HOME") .. "/Downloads"
|
downloads.default_dir = os.getenv("HOME") .. "/Downloads"
|
||||||
|
|
||||||
-- Add automatic PDF downloading and opening
|
-- Add automatic PDF downloading and opening
|
||||||
local viewpdf = require "viewpdf"
|
-- local viewpdf = require "viewpdf"
|
||||||
|
|
||||||
-- Add vimperator-like link hinting & following
|
-- Add vimperator-like link hinting & following
|
||||||
local follow = require "follow"
|
local follow = require "follow"
|
||||||
@@ -133,7 +133,7 @@ local cmdhist = require "cmdhist"
|
|||||||
local search = require "search"
|
local search = require "search"
|
||||||
|
|
||||||
-- Add ordering of new tabs
|
-- Add ordering of new tabs
|
||||||
-- local taborder = require "taborder"
|
local taborder = require "taborder"
|
||||||
|
|
||||||
-- Save web history
|
-- Save web history
|
||||||
local history = require "history"
|
local history = require "history"
|
||||||
@@ -149,14 +149,17 @@ local completion = require "completion"
|
|||||||
-- Press Control-E while in insert mode to edit the contents of the currently
|
-- Press Control-E while in insert mode to edit the contents of the currently
|
||||||
-- focused <textarea> or <input> element, using `xdg-open`
|
-- focused <textarea> or <input> element, using `xdg-open`
|
||||||
-- local open_editor = require "open_editor"
|
-- local open_editor = require "open_editor"
|
||||||
-- local editor = require "editor"
|
local editor = require "editor"
|
||||||
-- editor.editor_cmd = "hterm vim {file}"
|
editor.editor_cmd = "sterm vim {file}"
|
||||||
|
|
||||||
-- NoScript plugin, toggle scripts and or plugins on a per-domain basis.
|
-- NoScript plugin, toggle scripts and or plugins on a per-domain basis.
|
||||||
-- `,ts` to toggle scripts, `,tp` to toggle plugins, `,tr` to reset.
|
-- `,ts` to toggle scripts, `,tp` to toggle plugins, `,tr` to reset.
|
||||||
-- If you use this module, don't use any site-specific `enable_scripts` or
|
-- If you use this module, don't use any site-specific `enable_scripts` or
|
||||||
-- `enable_plugins` settings, as these will conflict.
|
-- `enable_plugins` settings, as these will conflict.
|
||||||
-- require "noscript"
|
local noscript = require "noscript"
|
||||||
|
noscript.enable_scripts = false
|
||||||
|
noscript.enable_plugins = false
|
||||||
|
|
||||||
|
|
||||||
local follow_selected = require "follow_selected"
|
local follow_selected = require "follow_selected"
|
||||||
local go_input = require "go_input"
|
local go_input = require "go_input"
|
||||||
@@ -164,7 +167,7 @@ local go_next_prev = require "go_next_prev"
|
|||||||
local go_up = require "go_up"
|
local go_up = require "go_up"
|
||||||
|
|
||||||
-- Filter Referer HTTP header if page domain does not match Referer domain
|
-- Filter Referer HTTP header if page domain does not match Referer domain
|
||||||
-- require_web_module("referer_control_wm")
|
require_web_module("referer_control_wm")
|
||||||
|
|
||||||
local error_page = require "error_page"
|
local error_page = require "error_page"
|
||||||
|
|
||||||
@@ -187,9 +190,9 @@ follow.stylesheet = follow.stylesheet .. [===[
|
|||||||
-- local vertical_tabs = require "vertical_tabs"
|
-- local vertical_tabs = require "vertical_tabs"
|
||||||
|
|
||||||
-- Add a stylesheet when showing images
|
-- Add a stylesheet when showing images
|
||||||
-- local image_css = require "image_css"
|
local image_css = require "image_css"
|
||||||
|
|
||||||
-- Add a new tab page
|
-- -- Add a new tab page
|
||||||
local newtab_chrome = require "newtab_chrome"
|
local newtab_chrome = require "newtab_chrome"
|
||||||
newtab_chrome.new_tab_src = [==[
|
newtab_chrome.new_tab_src = [==[
|
||||||
<html>
|
<html>
|
||||||
@@ -207,7 +210,7 @@ local tab_favicons = require "tab_favicons"
|
|||||||
-- tablist.min_width = 100
|
-- tablist.min_width = 100
|
||||||
|
|
||||||
-- Add :view-source command
|
-- Add :view-source command
|
||||||
-- local view_source = require "view_source"
|
local view_source = require "view_source"
|
||||||
|
|
||||||
-- Use "asdfqwerzxcv" for generating labels
|
-- Use "asdfqwerzxcv" for generating labels
|
||||||
local select = require "select"
|
local select = require "select"
|
||||||
@@ -217,75 +220,75 @@ end
|
|||||||
follow.pattern_maker = follow.pattern_styles.match_label
|
follow.pattern_maker = follow.pattern_styles.match_label
|
||||||
|
|
||||||
|
|
||||||
-- -- social media enhancer
|
-- social media enhancer
|
||||||
-- local webview = require "webview"
|
local webview = require "webview"
|
||||||
-- webview.add_signal('init', function (view)
|
webview.add_signal('init', function (view)
|
||||||
-- view:add_signal('navigation-request', function(v, uri)
|
view:add_signal('navigation-request', function(v, uri)
|
||||||
-- if v.uri:match('https://www.reddit.com') then
|
if v.uri:match('https://www.reddit.com') then
|
||||||
-- v.uri = v.uri:gsub('%www.reddit.com', 'old.reddit.com')
|
v.uri = v.uri:gsub('%www.reddit.com', 'old.reddit.com')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- if v.uri:match('https://new.reddit.com') then
|
if v.uri:match('https://new.reddit.com') then
|
||||||
-- v.uri = v.uri:gsub('%new.reddit.com', 'old.reddit.com')
|
v.uri = v.uri:gsub('%new.reddit.com', 'old.reddit.com')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- -- if v.uri:match('https://old.reddit.com') then
|
if v.uri:match('https://old.reddit.com') then
|
||||||
-- -- v.uri = v.uri:gsub('%old.reddit.com', 'libreddit.kylrth.com')
|
v.uri = v.uri:gsub('%old.reddit.com', 'redlib.kylrth.com')
|
||||||
-- -- return true
|
return true
|
||||||
-- -- end
|
end
|
||||||
-- -- if v.uri:match('https://old.reddit.com') then
|
if v.uri:match('https://old.reddit.com') then
|
||||||
-- -- v.uri = v.uri:gsub('%old.reddit.com', 'libreddit.kylrth.com')
|
v.uri = v.uri:gsub('%old.reddit.com', 'redlib.kylrth.com')
|
||||||
-- -- return true
|
return true
|
||||||
-- -- end
|
end
|
||||||
-- if v.uri:match('https://www.twitter.com') then
|
if v.uri:match('https://www.twitter.com') then
|
||||||
-- v.uri = v.uri:gsub('%www.twitter.com', 'nitter.net')
|
v.uri = v.uri:gsub('%www.twitter.com', 'nitter.net')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- if v.uri:match('https://twitter.com') then
|
if v.uri:match('https://twitter.com') then
|
||||||
-- v.uri = v.uri:gsub('%twitter.com', 'nitter.net')
|
v.uri = v.uri:gsub('%twitter.com', 'nitter.net')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- if v.uri:match('https://www.youtube.com') then
|
if v.uri:match('https://www.youtube.com') then
|
||||||
-- v.uri = v.uri:gsub('%www.youtube.com', 'tube.cadence.moe')
|
v.uri = v.uri:gsub('%www.youtube.com', 'tube.cadence.moe')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- if v.uri:match('https://youtube.com') then
|
if v.uri:match('https://youtube.com') then
|
||||||
-- v.uri = v.uri:gsub('%youtube.com', 'tube.cadence.moe')
|
v.uri = v.uri:gsub('%youtube.com', 'tube.cadence.moe')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- if v.uri:match('https://youtu.be') then
|
if v.uri:match('https://youtu.be') then
|
||||||
-- v.uri = v.uri:gsub('%youtu.be/', 'tube.cadence.moe/watch?v=')
|
v.uri = v.uri:gsub('%youtu.be/', 'tube.cadence.moe/watch?v=')
|
||||||
-- return true
|
return true
|
||||||
-- end
|
end
|
||||||
-- end)
|
end)
|
||||||
-- end)
|
end)
|
||||||
|
|
||||||
-- social media blocker
|
-- social media blocker
|
||||||
-- local webview = require "webview"
|
local webview = require "webview"
|
||||||
-- webview.add_signal('init', function (view)
|
webview.add_signal('init', function (view)
|
||||||
-- view:add_signal('navigation-request', function(v, uri)
|
view:add_signal('navigation-request', function(v, uri)
|
||||||
-- local blocklist_pattern = {
|
local blocklist_pattern = {
|
||||||
-- "facebook.com",
|
"facebook.com",
|
||||||
-- ".fb.com",
|
".fb.com",
|
||||||
-- ".fbcdn.com",
|
".fbcdn.com",
|
||||||
-- ".fbsbx.com",
|
".fbsbx.com",
|
||||||
-- ".fbcdn.net",
|
".fbcdn.net",
|
||||||
-- ".tfbnw.net",
|
".tfbnw.net",
|
||||||
-- "whatsapp.com",
|
"whatsapp.com",
|
||||||
-- "online-metrix.net",
|
"online-metrix.net",
|
||||||
-- ".fb.me",
|
".fb.me",
|
||||||
-- "facebook-web-clients.appspot.com",
|
"facebook-web-clients.appspot.com",
|
||||||
-- "fbcdn-profile-a.akamaihd.net"
|
"fbcdn-profile-a.akamaihd.net"
|
||||||
-- }
|
}
|
||||||
-- for key,value in ipairs(blocklist_pattern)
|
for key,value in ipairs(blocklist_pattern)
|
||||||
-- do
|
do
|
||||||
-- if v.uri:match(value) then
|
if v.uri:match(value) then
|
||||||
-- print("Navigation request to " .. v.uri .. " blocked.")
|
print("Navigation request to " .. v.uri .. " blocked.")
|
||||||
-- return false
|
return false
|
||||||
-- end
|
end
|
||||||
-- end
|
end
|
||||||
-- end)
|
end)
|
||||||
-- end)
|
end)
|
||||||
|
|
||||||
-----------------------------
|
-----------------------------
|
||||||
-- End user script loading --
|
-- End user script loading --
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
local theme = {}
|
local theme = {}
|
||||||
|
|
||||||
-- Default settings
|
-- Default settings
|
||||||
theme.font = "16px Terminess"
|
theme.font = "20px IosevkaTerm"
|
||||||
theme.fg = "#D8D8D8"
|
theme.fg = "#D8D8D8"
|
||||||
theme.bg = "#181818"
|
theme.bg = "#181818"
|
||||||
|
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ remove_set() {
|
|||||||
while read file
|
while read file
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"Left") jpegtran -rotate 270 -outfile "$file" "$file" ;;
|
"Right") jpegtran -rotate 270 -outfile "$file" "$file" ;;
|
||||||
"Right") jpegtran -rotate 90 -outfile "$file" "$file" ;;
|
"Left") jpegtran -rotate 90 -outfile "$file" "$file" ;;
|
||||||
"c") copy_to_clipboard "$file" ;;
|
"c") copy_to_clipboard "$file" ;;
|
||||||
"d") rm -f "$file" ;;
|
"d") rm -f "$file" ;;
|
||||||
"e") edit_image "$file" ;;
|
"e") edit_image "$file" ;;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ color_focus_free = rgb:AF/5F/00
|
|||||||
color_unfocus = rgb:44/44/44
|
color_unfocus = rgb:44/44/44
|
||||||
color_unfocus_free = rgb:55/35/00
|
color_unfocus_free = rgb:55/35/00
|
||||||
disable_border = 0
|
disable_border = 0
|
||||||
|
disable_padding = 1
|
||||||
maximize_hide_bar = 0
|
maximize_hide_bar = 0
|
||||||
|
|
||||||
# +--------------------------------------------------
|
# +--------------------------------------------------
|
||||||
@@ -68,7 +69,7 @@ bar_at_bottom = 0
|
|||||||
# ++ A literal ‘+’
|
# ++ A literal ‘+’
|
||||||
# +@ Prefix for text markup sequences
|
# +@ Prefix for text markup sequences
|
||||||
|
|
||||||
bar_format = +S +@bg=2;+L+@bg=0; +W +|R +A
|
bar_format = +S +@bg=2;+L+@bg=0; i:+M +W +|R +A
|
||||||
|
|
||||||
# +--------------------------------------------------
|
# +--------------------------------------------------
|
||||||
# | WORKSPACE LAYOUT
|
# | WORKSPACE LAYOUT
|
||||||
@@ -216,6 +217,7 @@ bind[bar_toggle_ws] = MOD+Shift+b
|
|||||||
# LAYOUT
|
# LAYOUT
|
||||||
bind[cycle_layout] = MOD+l
|
bind[cycle_layout] = MOD+l
|
||||||
bind[flip_layout] = MOD+Shift+l
|
bind[flip_layout] = MOD+Shift+l
|
||||||
|
bind[center_layout] = MOD+Shift+c
|
||||||
bind[float_toggle] = MOD+space
|
bind[float_toggle] = MOD+space
|
||||||
bind[free_toggle] = MOD+Shift+space
|
bind[free_toggle] = MOD+Shift+space
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ indent=30
|
|||||||
tabs=None
|
tabs=None
|
||||||
linespacing=3
|
linespacing=3
|
||||||
wrapped-lines-linespacing=0
|
wrapped-lines-linespacing=0
|
||||||
|
<<<<<<< Updated upstream
|
||||||
font=FuraCode Nerd Font Mono weight=450 14
|
font=FuraCode Nerd Font Mono weight=450 14
|
||||||
|
=======
|
||||||
|
font=.AppleSystemUIFont 17
|
||||||
|
>>>>>>> Stashed changes
|
||||||
justify=
|
justify=
|
||||||
background=#cccccc
|
background=#cccccc
|
||||||
|
|
||||||
@@ -32,7 +36,6 @@ wrap-mode=GTK_WRAP_NONE
|
|||||||
indent=20
|
indent=20
|
||||||
|
|
||||||
[Tag link]
|
[Tag link]
|
||||||
foreground=#8cd3ff
|
|
||||||
|
|
||||||
[Tag tag]
|
[Tag tag]
|
||||||
foreground=#ce5c00
|
foreground=#ce5c00
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
set startup-quietly on
|
set startup-quietly on
|
||||||
|
set follow-fork-mode parent
|
||||||
|
set detach-on-fork off
|
||||||
|
set schedule-multiple on
|
||||||
|
|||||||
4
.gdbinit
4
.gdbinit
@@ -6,7 +6,7 @@ python
|
|||||||
|
|
||||||
# License ----------------------------------------------------------------------
|
# License ----------------------------------------------------------------------
|
||||||
|
|
||||||
# Copyright (c) 2015-2023 Andrea Cardaci <cyrus.and@gmail.com>
|
# Copyright (c) 2015-2024 Andrea Cardaci <cyrus.and@gmail.com>
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -346,7 +346,7 @@ def fetch_breakpoints(watchpoints=False, pending=False):
|
|||||||
parsed_breakpoints[number] = [address_info], is_pending, ''
|
parsed_breakpoints[number] = [address_info], is_pending, ''
|
||||||
elif len(fields) >= 5 and fields[1] == 'catchpoint':
|
elif len(fields) >= 5 and fields[1] == 'catchpoint':
|
||||||
# only take before comma, but ignore commas in quotes
|
# only take before comma, but ignore commas in quotes
|
||||||
what = catch_what_regex.search(' '.join(fields[4:]))[0].strip()
|
what = catch_what_regex.search(' '.join(fields[4:])).group(0).strip()
|
||||||
parsed_breakpoints[number] = [], False, what
|
parsed_breakpoints[number] = [], False, what
|
||||||
elif len(fields) >= 3 and number in parsed_breakpoints:
|
elif len(fields) >= 3 and number in parsed_breakpoints:
|
||||||
# add this address to the list of multiple locations
|
# add this address to the list of multiple locations
|
||||||
|
|||||||
16
.gitconfig
16
.gitconfig
@@ -18,8 +18,8 @@
|
|||||||
name = Stefan Hagen
|
name = Stefan Hagen
|
||||||
email = sh+github@codevoid.de
|
email = sh+github@codevoid.de
|
||||||
[user]
|
[user]
|
||||||
name = c0dev0id
|
name = Stefan Hagen
|
||||||
email = sh+git@codevoid.de
|
email = stefan.hagen@sap.com
|
||||||
[hub]
|
[hub]
|
||||||
host = github.wdf.sap.corp
|
host = github.wdf.sap.corp
|
||||||
protocol = git
|
protocol = git
|
||||||
@@ -39,3 +39,15 @@
|
|||||||
[credential "https://github.wdf.sap.corp"]
|
[credential "https://github.wdf.sap.corp"]
|
||||||
helper =
|
helper =
|
||||||
helper = !/usr/bin/gh auth git-credential
|
helper = !/usr/bin/gh auth git-credential
|
||||||
|
[difftool]
|
||||||
|
prompt = false
|
||||||
|
[filter "lfs"]
|
||||||
|
clean = git-lfs clean -- %f
|
||||||
|
smudge = git-lfs smudge -- %f
|
||||||
|
process = git-lfs filter-process
|
||||||
|
required = true
|
||||||
|
[credential]
|
||||||
|
helper =
|
||||||
|
helper = /usr/local/share/gcm-core/git-credential-manager
|
||||||
|
[credential "https://dev.azure.com"]
|
||||||
|
useHttpPath = true
|
||||||
|
|||||||
122
.kshrc
122
.kshrc
@@ -27,7 +27,7 @@ export LANG LC_MESSAGES LC_NUMERIC LC_TIME
|
|||||||
### SOFTWARE PREFERENCES
|
### SOFTWARE PREFERENCES
|
||||||
EDITOR="vim"
|
EDITOR="vim"
|
||||||
VISUAL="vim"
|
VISUAL="vim"
|
||||||
BROWSER="chrome"
|
BROWSER="firefox"
|
||||||
PAGER="less"
|
PAGER="less"
|
||||||
export EDITOR VISUAL BROWSER PAGER
|
export EDITOR VISUAL BROWSER PAGER
|
||||||
|
|
||||||
@@ -86,8 +86,8 @@ TOG_COLORS=1
|
|||||||
export GOT_AUTHOR TOG_COLORS
|
export GOT_AUTHOR TOG_COLORS
|
||||||
|
|
||||||
# BUPSTASH
|
# BUPSTASH
|
||||||
BUPSTASH_REPOSITORY=ssh://sdk@storage.bupstash.io
|
BUPSTASH_REPOSITORY=ssh://default@storage.bupstash.io
|
||||||
BUPSTASH_KEY_COMMAND="pass Internet/bupstash-key"
|
BUPSTASH_KEY_COMMAND="pass Internet/storage.bupstash.io-key"
|
||||||
export BUPSTASH_REPOSITORY BUPSTASH_KEY_COMMAND
|
export BUPSTASH_REPOSITORY BUPSTASH_KEY_COMMAND
|
||||||
|
|
||||||
# PASSWORD-STORE
|
# PASSWORD-STORE
|
||||||
@@ -127,11 +127,26 @@ RED="\[$(tput setaf 196)\]"
|
|||||||
GREY="\[$(tput setaf 248)\]"
|
GREY="\[$(tput setaf 248)\]"
|
||||||
RESET="\[$(tput op)\]"
|
RESET="\[$(tput op)\]"
|
||||||
|
|
||||||
|
gitstatus() {
|
||||||
|
_path="$PWD"
|
||||||
|
while [ -n "$_path" ]
|
||||||
|
do [ -d "$_path/.git" ] \
|
||||||
|
&& echo "($(git --no-pager branch --no-color --show-current))" \
|
||||||
|
&& break
|
||||||
|
_path="${_path%/*}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
if [ $(id -u) -eq 0 ]
|
if [ $(id -u) -eq 0 ]
|
||||||
then
|
then
|
||||||
PS1="${x}${RED}\${?}|\w\\$ ${RESET}${x}"
|
PS1="${x}${RED}$(hostname -s) \${?}|\w\\$ ${RESET}${x}"
|
||||||
else
|
else
|
||||||
PS1="${x}${GREY}\${?}|\w\\$ ${RESET}${x}"
|
if command -v git > /dev/null
|
||||||
|
then
|
||||||
|
PS1="${x}${GREY}$(hostname -s) \${?}|\w\$(gitstatus)\\$ ${RESET}${x}"
|
||||||
|
else
|
||||||
|
PS1="${x}${GREY}$(hostname -s) \${?}|\w\\$ ${RESET}${x}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -147,19 +162,28 @@ alias luakitrc="vim ~/.config/luakit/rc.lua"
|
|||||||
alias spectrwmrc="vim ~/.config/spectrwm/spectrwm.conf"
|
alias spectrwmrc="vim ~/.config/spectrwm/spectrwm.conf"
|
||||||
alias vifmrc="vim ~/.config/vifm/vifmrc"
|
alias vifmrc="vim ~/.config/vifm/vifmrc"
|
||||||
alias tmuxrc="vim ~/.tmux.conf"
|
alias tmuxrc="vim ~/.tmux.conf"
|
||||||
|
alias annex="git annex"
|
||||||
|
|
||||||
|
pastebinvim() {
|
||||||
|
vim "https://pastebin.com/raw/$(basename "$1")";
|
||||||
|
}
|
||||||
|
|
||||||
# task warrior
|
# task warrior
|
||||||
alias t=task
|
#alias t=task
|
||||||
alias ta="t add"
|
#alias ta="t add"
|
||||||
alias tm="t mod"
|
#alias tm="t mod"
|
||||||
alias tc="t completed"
|
#alias tc="t completed"
|
||||||
alias tlog="t log +LOG"
|
#alias tlog="t log +LOG"
|
||||||
|
alias mc="/usr/local/bin/mc -d"
|
||||||
|
|
||||||
# social media
|
# social media
|
||||||
alias tuta="tut -u 'sh@bsd.network uugrn@chaos.social'"
|
alias tuta="tut -u 'sh@bsd.network uugrn@chaos.social'"
|
||||||
|
|
||||||
# servers
|
# servers
|
||||||
alias x="ssh -t sdk@home.codevoid.de 'tmux -u new-session -d -s main; tmux -u new-session -t main \; set-option destroy-unattached'"
|
alias x="ssh -t sdk@home.codevoid.de \
|
||||||
|
'tmux -u new-session -d -s main; \
|
||||||
|
tmux -u new-session -t main \; \
|
||||||
|
set-option destroy-unattached'"
|
||||||
|
|
||||||
alias inssh="ssh -o HostKeyAlgorithms=+ssh-rsa \
|
alias inssh="ssh -o HostKeyAlgorithms=+ssh-rsa \
|
||||||
-o KexAlgorithms=+diffie-hellman-group1-sha1 \
|
-o KexAlgorithms=+diffie-hellman-group1-sha1 \
|
||||||
@@ -168,11 +192,71 @@ alias inssh="ssh -o HostKeyAlgorithms=+ssh-rsa \
|
|||||||
myps() { ps -fU $(whoami); }
|
myps() { ps -fU $(whoami); }
|
||||||
mytop() { top -u $(whoami); }
|
mytop() { top -u $(whoami); }
|
||||||
|
|
||||||
|
alias pkg-readmes="cd /usr/local/share/doc/pkg-readmes; ls"
|
||||||
|
alias notes="cd $HOME/Documents/notes; nnn"
|
||||||
|
|
||||||
|
# git
|
||||||
|
alias mygit-commit="git commit"
|
||||||
|
alias mygit-rebase="git rebase -i"
|
||||||
|
alias mygit-stage="git add"
|
||||||
|
alias mygit-unstage="git restore --staged"
|
||||||
|
alias mygit-untrack="git rm --cached"
|
||||||
|
alias mygit-track="git add --intent-to-add"
|
||||||
|
alias mygit-update="git fetch --all"
|
||||||
|
alias mygit-diff="git difftool -y ..origin/HEAD"
|
||||||
|
alias mygit-log="git log --graph"
|
||||||
|
alias mygit-list-branches="git --no-pager branch --all"
|
||||||
|
alias mygit-delete-branch="git branch -D"
|
||||||
|
mygit-upstream-sync() {
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "sync with which upstream branch?"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
set -xe
|
||||||
|
git fetch upstream
|
||||||
|
git checkout $1
|
||||||
|
git merge upstream/$1
|
||||||
|
git push origin $1
|
||||||
|
}
|
||||||
|
mygit-checkout() {
|
||||||
|
_local="$(echo "$1" | sed 's,remotes/,,g;s,origin/,,g;')"
|
||||||
|
git checkout -b $_local $1
|
||||||
|
}
|
||||||
|
alias mygit-changed-files="git --no-pager whatchanged origin/HEAD..HEAD | grep -E '^:' | awk '{ print \$6; }'"
|
||||||
|
|
||||||
|
mygot-clone() {
|
||||||
|
if test -z "$1" || test -z "$2"
|
||||||
|
then echo "mygot clone <url> <dir>"
|
||||||
|
else
|
||||||
|
_src="${1%*.git}.git"
|
||||||
|
_dst="${2%*.git}"
|
||||||
|
got clone "$_src" "$_dst.git"
|
||||||
|
got checkout "$_dst.git" "$_dst"
|
||||||
|
cd "$_dst"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# other
|
# other
|
||||||
alias portroach="portroach-cli -m codevoid"
|
alias portroach="portroach-cli -m codevoid"
|
||||||
alias ugrep="\ugrep -nI --exclude=tags --exclude=.tags --exclude='cscope.*'"
|
alias ugrep="\ugrep -nI --exclude=tags --exclude=.tags --exclude='cscope.*'"
|
||||||
alias joplin="firefox https://app.joplincloud.com &"
|
alias tarsnap="doas \tarsnap"
|
||||||
|
alias vpn-on="doas wg-quick up wg0"
|
||||||
|
alias vpn-off="doas wg-quick down wg0"
|
||||||
|
alias edit-pf="doas vim /etc/pf.conf && doas pfctl -f /etc/pf.conf"
|
||||||
|
alias edit-wg="doas vim /etc/hostname.wg0 && doas sh /etc/netstart wg0"
|
||||||
|
alias log-wg="doas ifconfig wg0 debug; doas tail -f /var/log/messages | grep wg0"
|
||||||
|
alias log-wg-remote="ssh shell.codevoid.de 'doas ifconfig wg0 debug; doas tail -f /var/log/messages | grep wg0'"
|
||||||
|
|
||||||
|
|
||||||
|
mystuff() {
|
||||||
|
cd /usr/ports/mystuff
|
||||||
|
g
|
||||||
|
}
|
||||||
|
wip() {
|
||||||
|
cd /usr/ports/openbsd-wip
|
||||||
|
g
|
||||||
|
}
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# AMUSED
|
# AMUSED
|
||||||
@@ -293,8 +377,8 @@ obsd-full-system-update() {(
|
|||||||
# REMIND
|
# REMIND
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
alias rem="remind -@1,1,1 -c+cu4 -wt ~sdk/.reminders.rem"
|
alias rem="remind -@1,1,1 -c+cu4 -wt -m ~sdk/.reminders.rem"
|
||||||
alias remy="remind -@1,1,1 -c+cu52 -wt ~sdk/.reminders.rem | less"
|
alias remy="remind -@1,1,1 -c+cu52 -wt -m ~sdk/.reminders.rem | less"
|
||||||
alias rems="remind -n ~sdk/.reminders | sort -n | head -10"
|
alias rems="remind -n ~sdk/.reminders | sort -n | head -10"
|
||||||
alias remc="remindcal ~sdk/.reminders"
|
alias remc="remindcal ~sdk/.reminders"
|
||||||
alias rem-personal="rem-edit personal"
|
alias rem-personal="rem-edit personal"
|
||||||
@@ -306,11 +390,13 @@ rem-edit() {
|
|||||||
scp -q sdk@home.codevoid.de:.reminders/$1.rem ~sdk/.reminders/$1.rem
|
scp -q sdk@home.codevoid.de:.reminders/$1.rem ~sdk/.reminders/$1.rem
|
||||||
}
|
}
|
||||||
rem-edit-uugrn() {
|
rem-edit-uugrn() {
|
||||||
vim sftp://vorstand@vorstand.uugrn.org/.reminders/uugrn.rem
|
# edit remote file
|
||||||
scp -q vorstand@vorstand.uugrn.org:.reminders/uugrn.rem ~sdk/.reminders/uugrn.rem
|
vim sftp://vorstand@vorstand.uugrn.org/private/Kalender/uugrn.rem
|
||||||
scp -q ~sdk/.reminders/uugrn.rem vorstand@vorstand.uugrn.org:private/Kalender/uugrn.rem
|
# update local file
|
||||||
|
scp -q sdk@vorstand.uugrn.org:~vorstand/private/Kalender/uugrn.rem ~sdk/.reminders/uugrn.rem
|
||||||
|
# run update script
|
||||||
ssh sdk@vorstand.uugrn.org sh \
|
ssh sdk@vorstand.uugrn.org sh \
|
||||||
~sdk/.bin/make_calendar.sh \
|
~vorstand/private/Kalender/scripts/make_calendar.sh \
|
||||||
|| true
|
|| true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,46 +0,0 @@
|
|||||||
@-moz-document domain(old.reddit.com) {
|
|
||||||
* {
|
|
||||||
background-color: #181818 !important;
|
|
||||||
color: #CCC !important;
|
|
||||||
border-color: #555 !important;
|
|
||||||
border-width: 0px !important;
|
|
||||||
}
|
|
||||||
.premium-banner-outer, .premium-banner {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
#header-img.default-header, .side {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.link.promotedlink.promoted, .link.promotedlink.external {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.footer-parent {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.happening-now-wrap {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.stickied {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
input, textarea, button {
|
|
||||||
background-color: #282828 !important;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
font-style: oblique !important;
|
|
||||||
}
|
|
||||||
.expando-button, .thumbnail, .rank, .midcol {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.top-matter, .top-matter > *, .top-matter > * > *, .top-matter > * > * > *, .top-matter > * > * > * > * {
|
|
||||||
background-color: #222 !important;
|
|
||||||
}
|
|
||||||
.linkflairlabel, .linkflairlabel > * {
|
|
||||||
background-color: #999 !important;
|
|
||||||
color: #121212 !important;
|
|
||||||
}
|
|
||||||
.entry {
|
|
||||||
border-left: 5px solid darkred !important;
|
|
||||||
padding-left: 5px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,3 +33,5 @@ color body green default "^\\+"
|
|||||||
color body green default "^\\+.*"
|
color body green default "^\\+.*"
|
||||||
color body green default "> \\+.*"
|
color body green default "> \\+.*"
|
||||||
|
|
||||||
|
color index red default '~F' # flagged
|
||||||
|
color index green default '@~f .' # aliased
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ text/html; w3m -I %{charset} -T %t -cols "$COLUMNS" -s -no-graph -o display_link
|
|||||||
message/*; cat %s; needsterminal;
|
message/*; cat %s; needsterminal;
|
||||||
|
|
||||||
# documents
|
# documents
|
||||||
application/pdf; ~/.mutt/scripts/call.sh mupdf %s; nametemplate=%s.pdf;
|
application/pdf; ~/.mutt/scripts/call.sh zathura %s; nametemplate=%s.pdf;
|
||||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document; ~/.mutt/scripts/call.sh libreoffice %s;
|
application/vnd.openxmlformats-officedocument.wordprocessingml.document; ~/.mutt/scripts/call.sh libreoffice %s;
|
||||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; ~/.mutt/scripts/call.sh libreoffice %s;
|
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; ~/.mutt/scripts/call.sh libreoffice %s;
|
||||||
application/vnd.openxmlformats-officedocument.presentationml.presentation; ~/.mutt/scripts/call.sh libreoffice %s;
|
application/vnd.openxmlformats-officedocument.presentationml.presentation; ~/.mutt/scripts/call.sh libreoffice %s;
|
||||||
|
|||||||
@@ -211,18 +211,16 @@ unalternative_order *
|
|||||||
alternative_order text/plain text/enriched text/html
|
alternative_order text/plain text/enriched text/html
|
||||||
auto_view text/html text/enriched text/calendar
|
auto_view text/html text/enriched text/calendar
|
||||||
|
|
||||||
# Preview HTML
|
# apply inline patch
|
||||||
macro pager,attach \cs "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/apply_patch.sh /tmp/muttpatch.diff<enter>"
|
macro index,pager,attach \cs "| ~/.mutt/scripts/patch.sh patch<enter>"
|
||||||
|
macro index,pager,attach \ca "| ~/.mutt/scripts/patch.sh git<enter>"
|
||||||
# Save Patch
|
|
||||||
#macro pager \cs "<shell-escape>rm -f /tmp/mutt-patch.diff<enter><copy-message>/tmp/mutt-patch.diff<enter><enter-command>echo 'Saved as /tmp/mutt-patch.diff'<enter><shell-escape>~/.mutt/scripts/portpatch.sh /tmp/mutt-patch.diff<enter>"
|
|
||||||
|
|
||||||
# pipe-message
|
# pipe-message
|
||||||
set pipe_decode_weed = no
|
set pipe_decode_weed = no
|
||||||
set pipe_decode = yes # when piping via pipe-message command, strip headers and decode
|
set pipe_decode = yes # when piping via pipe-message command, strip headers and decode
|
||||||
set pipe_split = yes # if several msgs are tagged, do the pipe-message command for each
|
set pipe_split = yes # if several msgs are tagged, do the pipe-message command for each
|
||||||
set prompt_after = no # promt if external pager exits
|
set prompt_after = no # promt if external pager exits
|
||||||
set wait_key = no # wait for a key-press after performing shell/external commands
|
set wait_key = yes # wait for a key-press after performing shell/external commands
|
||||||
set beep_new = no # beep if new message arrives
|
set beep_new = no # beep if new message arrives
|
||||||
set check_new = no # check for new mails, while the mailbox is open
|
set check_new = no # check for new mails, while the mailbox is open
|
||||||
set auto_tag = yes # function will applied to all tagged messages in the index
|
set auto_tag = yes # function will applied to all tagged messages in the index
|
||||||
@@ -321,4 +319,9 @@ set crypt_opportunistic_encrypt_strong_keys = yes # autoselect key with trust fu
|
|||||||
set autocrypt = no
|
set autocrypt = no
|
||||||
set pgp_use_gpg_agent = yes
|
set pgp_use_gpg_agent = yes
|
||||||
|
|
||||||
|
set alias_file=~/.mutt/aliases
|
||||||
|
set sort_alias = alias
|
||||||
|
set reverse_alias = yes
|
||||||
|
|
||||||
|
source ~/.mutt/aliases
|
||||||
source ~/.mutt/colors/codevoid
|
source ~/.mutt/colors/codevoid
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/bin/ksh -e
|
|
||||||
|
|
||||||
# needs converters/qprint
|
|
||||||
# mutt: macro pager,attach \cs "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/apply_patch.sh /tmp/muttpatch.diff<enter>"
|
|
||||||
|
|
||||||
clear
|
|
||||||
|
|
||||||
printf '\n---------------------------------------------------------------------\n'
|
|
||||||
grep -E 'Subject: |^Index|^RCS|^diff --git|^file +|^[-+]{3} ' "${1}"
|
|
||||||
printf '---------------------------------------------------------------------\n\n'
|
|
||||||
|
|
||||||
printf "Base path for the patch?\n"
|
|
||||||
printf "Example: /usr/ports or /usr/src\n"
|
|
||||||
printf ": "
|
|
||||||
read -r _path
|
|
||||||
cd $_path
|
|
||||||
|
|
||||||
print "Using: $_path"
|
|
||||||
|
|
||||||
printf "Fix quoted-printable mangeled patch? [y/N]: "
|
|
||||||
read -r _qprint
|
|
||||||
|
|
||||||
case ${_qprint} in
|
|
||||||
[y|Y]) _catcmd="qprint -d"; ;;
|
|
||||||
*) _catcmd="cat"; ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
printf "Strip? [0]: "
|
|
||||||
read -r _strip
|
|
||||||
|
|
||||||
echo "CMD: ${_catcmd} "${1}" | doas -u sdk patch -E -pp${_strip:=0} -d ${_path}"
|
|
||||||
${_catcmd} "${1}" | doas -u sdk patch -E -N -p${_strip:=0} -d ${_path}
|
|
||||||
echo ${_path} | xclip
|
|
||||||
echo "done."
|
|
||||||
read
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
strip=0
|
|
||||||
|
|
||||||
clear
|
|
||||||
printf '\n---------------------------------------------------------------------\n'
|
|
||||||
egrep '^Index|^RCS|^diff --git|^file +' "$1" | sed 's,/cvs,/usr,g'
|
|
||||||
printf '---------------------------------------------------------------------\n\n'
|
|
||||||
|
|
||||||
printf "Path for patch [/usr/ports]? "
|
|
||||||
read _path
|
|
||||||
|
|
||||||
[ -z "$_path" ] && _path=/usr/ports
|
|
||||||
egrep -q '^diff --git a/' "$1" && strip=1
|
|
||||||
|
|
||||||
#print "Trying to apply patch"
|
|
||||||
#qprint -d "$1" "$1.out"
|
|
||||||
|
|
||||||
doas patch -Ep"$strip" -d $_path < "$1"
|
|
||||||
cd $_path && ksh
|
|
||||||
68
.mutt/scripts/patch.sh
Executable file
68
.mutt/scripts/patch.sh
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/ksh -e
|
||||||
|
# needs converters/qprint
|
||||||
|
|
||||||
|
if [ -t 0 ] || [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "usage: patch.sh [git|patch] < patchfile.diff"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Shortcuts:"
|
||||||
|
echo "ld - luakit-dev"
|
||||||
|
echo "lt - luakit-test"
|
||||||
|
echo "ltmp - luakit-tmp"
|
||||||
|
echo "src - /usr/src"
|
||||||
|
echo "sys - /usr/src/sys"
|
||||||
|
echo "ports - /usr/ports"
|
||||||
|
echo "www - /usr/www"
|
||||||
|
echo
|
||||||
|
printf "Path [$PWD]: "
|
||||||
|
read _reply < /dev/tty
|
||||||
|
|
||||||
|
if [ -z "$_reply" ]
|
||||||
|
then
|
||||||
|
_path="$PWD"
|
||||||
|
else
|
||||||
|
_path="$_reply"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shortcuts!!!
|
||||||
|
case "$_path" in
|
||||||
|
ld) _path="/home/sdk/src/luakit-dev" ;;
|
||||||
|
lt) _path="/home/sdk/src/luakit-test" ;;
|
||||||
|
ltmp) _path="/home/sdk/src/luakit-tmp" ;;
|
||||||
|
src) _path="/usr/src" ;;
|
||||||
|
sys) _path="/usr/src/sys" ;;
|
||||||
|
ports) _path="/usr/ports" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ ! -d "$_path" ]
|
||||||
|
then
|
||||||
|
_path="$(port-jump "$_path")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print "Using: $_path"
|
||||||
|
|
||||||
|
if [ ! -d "$_path" ]
|
||||||
|
then
|
||||||
|
echo "Error with path: $_path"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$_path"
|
||||||
|
if [ "$1" == "git" ]
|
||||||
|
then
|
||||||
|
cat /dev/stdin | git am
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" == "patch" ]
|
||||||
|
then
|
||||||
|
printf "Strip [0]: "
|
||||||
|
read _strip < /dev/tty
|
||||||
|
_strip=${_strip:=0}
|
||||||
|
|
||||||
|
cat /dev/stdin | doas -u sdk patch -E -N -p$_strip -d "$_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$_path" | xclip
|
||||||
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/bin/ksh -e
|
|
||||||
|
|
||||||
# needs converters/qprint
|
|
||||||
# mutt: macro pager,attach \cs "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/portpatch2.sh /tmp/muttpatch.diff<enter>"
|
|
||||||
|
|
||||||
clear
|
|
||||||
|
|
||||||
printf '\n---------------------------------------------------------------------\n'
|
|
||||||
grep -E 'Subject: |^Index|^RCS|^diff --git|^file +|^[-+]{3} ' "${1}"
|
|
||||||
printf '---------------------------------------------------------------------\n\n'
|
|
||||||
|
|
||||||
printf "Base path for the patch?\n"
|
|
||||||
printf "Example: /usr/ports or /usr/src\n"
|
|
||||||
printf ": "
|
|
||||||
read -r _path
|
|
||||||
cd $_path
|
|
||||||
|
|
||||||
print "Using: $_path"
|
|
||||||
|
|
||||||
printf "Fix quoted-printable mangeled patch? [y/N]: "
|
|
||||||
read -r _qprint
|
|
||||||
|
|
||||||
case ${_qprint} in
|
|
||||||
[y|Y]) _catcmd="qprint -d"; ;;
|
|
||||||
*) _catcmd="cat"; ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
printf "Strip? [0]: "
|
|
||||||
read -r _strip
|
|
||||||
|
|
||||||
echo "CMD: ${_catcmd} "${1}" | doas -u sdk patch -E -pp${_strip:=0} -d ${_path}"
|
|
||||||
${_catcmd} "${1}" | doas -u sdk patch -i -E -N -p${_strip:=0} -d ${_path}
|
|
||||||
echo ${_path} | xclip
|
|
||||||
echo "done.
|
|
||||||
read
|
|
||||||
@@ -53,6 +53,10 @@ Host home.codevoid.de
|
|||||||
Hostname home.codevoid.de
|
Hostname home.codevoid.de
|
||||||
User sdk
|
User sdk
|
||||||
|
|
||||||
|
Host backup-fsn.codevoid.de
|
||||||
|
User u475462-sub1
|
||||||
|
Port 23
|
||||||
|
|
||||||
Host dalek
|
Host dalek
|
||||||
Hostname dalek.home.codevoid.de
|
Hostname dalek.home.codevoid.de
|
||||||
User sdk
|
User sdk
|
||||||
|
|||||||
35
.vim/bin/findtagsdir
Executable file
35
.vim/bin/findtagsdir
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
gitdir() {
|
||||||
|
_path="$PWD"
|
||||||
|
while [ -n "$_path" ]
|
||||||
|
do [ -d "$_path/.git" ] \
|
||||||
|
&& echo "$_path" \
|
||||||
|
&& break
|
||||||
|
_path="${_path%/*}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cvsdir() {
|
||||||
|
_path="$PWD"
|
||||||
|
while [ -n "$_path" ]
|
||||||
|
do
|
||||||
|
[ ! -d "$_path/../CVS" ] \
|
||||||
|
&& echo "$_path" \
|
||||||
|
&& break
|
||||||
|
_path="${_path%/*}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_gitdir="$(gitdir)"
|
||||||
|
_cvsdir="$(cvsdir)"
|
||||||
|
|
||||||
|
if [ -n "$_gitdir" ]
|
||||||
|
then
|
||||||
|
echo "$_gitdir/.git"
|
||||||
|
elif [ -n "$_cvsdir" ]
|
||||||
|
then
|
||||||
|
echo "$_cvsdir/.tags"
|
||||||
|
else
|
||||||
|
echo "$PWD/.tags"
|
||||||
|
fi
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
GitHub Copilot is offered under the [GitHub Terms of
|
|
||||||
Service](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features#github-copilot).
|
|
||||||
|
|
||||||
Copyright (C) 2023 GitHub, Inc. - All Rights Reserved.
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# GitHub Copilot for Vim and Neovim
|
|
||||||
|
|
||||||
GitHub Copilot uses OpenAI Codex to suggest code and entire functions in
|
|
||||||
real-time right from your editor. Trained on billions of lines of public
|
|
||||||
code, GitHub Copilot turns natural language prompts including comments and
|
|
||||||
method names into coding suggestions across dozens of languages.
|
|
||||||
|
|
||||||
Copilot.vim is a Vim/Neovim plugin for GitHub Copilot.
|
|
||||||
|
|
||||||
To learn more, visit
|
|
||||||
[https://github.com/features/copilot](https://github.com/features/copilot).
|
|
||||||
|
|
||||||
## Subscription
|
|
||||||
|
|
||||||
GitHub Copilot requires a subscription. It is free for verified students and
|
|
||||||
maintainers of popular open source projects on GitHub.
|
|
||||||
|
|
||||||
GitHub Copilot is subject to the [GitHub Additional Product
|
|
||||||
Terms](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features).
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
1. Install [Neovim][] or the latest patch of [Vim][] (9.0.0185 or newer).
|
|
||||||
|
|
||||||
2. Install [Node.js][].
|
|
||||||
|
|
||||||
3. Install `github/copilot.vim` using vim-plug, packer.nvim, or any other
|
|
||||||
plugin manager. Or to install manually, run one of the following
|
|
||||||
commands:
|
|
||||||
|
|
||||||
* Vim, Linux/macOS:
|
|
||||||
|
|
||||||
git clone https://github.com/github/copilot.vim.git \
|
|
||||||
~/.vim/pack/github/start/copilot.vim
|
|
||||||
|
|
||||||
* Neovim, Linux/macOS:
|
|
||||||
|
|
||||||
git clone https://github.com/github/copilot.vim.git \
|
|
||||||
~/.config/nvim/pack/github/start/copilot.vim
|
|
||||||
|
|
||||||
* Vim, Windows (PowerShell command):
|
|
||||||
|
|
||||||
git clone https://github.com/github/copilot.vim.git `
|
|
||||||
$HOME/vimfiles/pack/github/start/copilot.vim
|
|
||||||
|
|
||||||
* Neovim, Windows (PowerShell command):
|
|
||||||
|
|
||||||
git clone https://github.com/github/copilot.vim.git `
|
|
||||||
$HOME/AppData/Local/nvim/pack/github/start/copilot.vim
|
|
||||||
|
|
||||||
4. Start Vim/Neovim and invoke `:Copilot setup`.
|
|
||||||
|
|
||||||
[Node.js]: https://nodejs.org/en/download/
|
|
||||||
[Neovim]: https://github.com/neovim/neovim/releases/latest
|
|
||||||
[Vim]: https://github.com/vim/vim
|
|
||||||
|
|
||||||
Suggestions are displayed inline and can be accepted by pressing the tab key.
|
|
||||||
See `:help copilot` for more information.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
We’d love to get your help in making GitHub Copilot better! If you have
|
|
||||||
feedback or encounter any problems, please reach out on our [Feedback
|
|
||||||
forum](https://github.com/orgs/community/discussions/categories/copilot).
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
If you discover a security issue in this repo, please submit it through the
|
|
||||||
[GitHub Security Bug Bounty](https://hackerone.com/github).
|
|
||||||
|
|
||||||
Thanks for helping make GitHub Copilot safe for everyone.
|
|
||||||
@@ -1,860 +0,0 @@
|
|||||||
scriptencoding utf-8
|
|
||||||
|
|
||||||
let s:has_nvim_ghost_text = has('nvim-0.7') && exists('*nvim_buf_get_mark')
|
|
||||||
let s:vim_minimum_version = '9.0.0185'
|
|
||||||
let s:has_vim_ghost_text = has('patch-' . s:vim_minimum_version) && has('textprop')
|
|
||||||
let s:has_ghost_text = s:has_nvim_ghost_text || s:has_vim_ghost_text
|
|
||||||
|
|
||||||
let s:hlgroup = 'CopilotSuggestion'
|
|
||||||
let s:annot_hlgroup = 'CopilotAnnotation'
|
|
||||||
|
|
||||||
if s:has_vim_ghost_text && empty(prop_type_get(s:hlgroup))
|
|
||||||
call prop_type_add(s:hlgroup, {'highlight': s:hlgroup})
|
|
||||||
endif
|
|
||||||
if s:has_vim_ghost_text && empty(prop_type_get(s:annot_hlgroup))
|
|
||||||
call prop_type_add(s:annot_hlgroup, {'highlight': s:annot_hlgroup})
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:Echo(msg) abort
|
|
||||||
if has('nvim') && &cmdheight == 0
|
|
||||||
call v:lua.vim.notify(a:msg, v:null, {'title': 'GitHub Copilot'})
|
|
||||||
else
|
|
||||||
echo a:msg
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:EditorConfiguration() abort
|
|
||||||
let filetypes = copy(s:filetype_defaults)
|
|
||||||
if type(get(g:, 'copilot_filetypes')) == v:t_dict
|
|
||||||
call extend(filetypes, g:copilot_filetypes)
|
|
||||||
endif
|
|
||||||
return {
|
|
||||||
\ 'enableAutoCompletions': empty(get(g:, 'copilot_enabled', 1)) ? v:false : v:true,
|
|
||||||
\ 'disabledLanguages': map(sort(keys(filter(filetypes, { k, v -> empty(v) }))), { _, v -> {'languageId': v}}),
|
|
||||||
\ }
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Init(...) abort
|
|
||||||
call copilot#util#Defer({ -> exists('s:client') || s:Start() })
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Running() abort
|
|
||||||
return exists('s:client.job') || exists('s:client.client_id')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Start() abort
|
|
||||||
if s:Running() || exists('s:client.startup_error')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let s:client = copilot#client#New({'editorConfiguration' : s:EditorConfiguration()})
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Stop() abort
|
|
||||||
if exists('s:client')
|
|
||||||
let client = remove(s:, 'client')
|
|
||||||
call client.Close()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Client() abort
|
|
||||||
call s:Start()
|
|
||||||
return s:client
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#RunningClient() abort
|
|
||||||
if s:Running()
|
|
||||||
return s:client
|
|
||||||
else
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if has('nvim-0.7') && !has(luaeval('vim.version().api_prerelease') ? 'nvim-0.8.1' : 'nvim-0.8.0')
|
|
||||||
let s:editor_warning = 'Neovim 0.7 support is deprecated and will be dropped in a future release of copilot.vim.'
|
|
||||||
endif
|
|
||||||
if has('vim_starting') && exists('s:editor_warning')
|
|
||||||
call copilot#logger#Warn(s:editor_warning)
|
|
||||||
endif
|
|
||||||
function! s:EditorVersionWarning() abort
|
|
||||||
if exists('s:editor_warning')
|
|
||||||
echohl WarningMsg
|
|
||||||
echo 'Warning: ' . s:editor_warning
|
|
||||||
echohl None
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Request(method, params, ...) abort
|
|
||||||
let client = copilot#Client()
|
|
||||||
return call(client.Request, [a:method, a:params] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Call(method, params, ...) abort
|
|
||||||
let client = copilot#Client()
|
|
||||||
return call(client.Call, [a:method, a:params] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Notify(method, params, ...) abort
|
|
||||||
let client = copilot#Client()
|
|
||||||
return call(client.Notify, [a:method, a:params] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#NvimNs() abort
|
|
||||||
return nvim_create_namespace('github-copilot')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Clear() abort
|
|
||||||
if exists('g:_copilot_timer')
|
|
||||||
call timer_stop(remove(g:, '_copilot_timer'))
|
|
||||||
endif
|
|
||||||
if exists('b:_copilot')
|
|
||||||
call copilot#client#Cancel(get(b:_copilot, 'first', {}))
|
|
||||||
call copilot#client#Cancel(get(b:_copilot, 'cycling', {}))
|
|
||||||
endif
|
|
||||||
call s:UpdatePreview()
|
|
||||||
unlet! b:_copilot
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Dismiss() abort
|
|
||||||
call copilot#Clear()
|
|
||||||
call s:UpdatePreview()
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:filetype_defaults = {
|
|
||||||
\ 'gitcommit': 0,
|
|
||||||
\ 'gitrebase': 0,
|
|
||||||
\ 'hgcommit': 0,
|
|
||||||
\ 'svn': 0,
|
|
||||||
\ 'cvs': 0,
|
|
||||||
\ '.': 0}
|
|
||||||
|
|
||||||
function! s:BufferDisabled() abort
|
|
||||||
if &buftype =~# '^\%(help\|prompt\|quickfix\|terminal\)$'
|
|
||||||
return 5
|
|
||||||
endif
|
|
||||||
if exists('b:copilot_disabled')
|
|
||||||
return empty(b:copilot_disabled) ? 0 : 3
|
|
||||||
endif
|
|
||||||
if exists('b:copilot_enabled')
|
|
||||||
return empty(b:copilot_enabled) ? 4 : 0
|
|
||||||
endif
|
|
||||||
let short = empty(&l:filetype) ? '.' : split(&l:filetype, '\.', 1)[0]
|
|
||||||
let config = {}
|
|
||||||
if type(get(g:, 'copilot_filetypes')) == v:t_dict
|
|
||||||
let config = g:copilot_filetypes
|
|
||||||
endif
|
|
||||||
if has_key(config, &l:filetype)
|
|
||||||
return empty(config[&l:filetype])
|
|
||||||
elseif has_key(config, short)
|
|
||||||
return empty(config[short])
|
|
||||||
elseif has_key(config, '*')
|
|
||||||
return empty(config['*'])
|
|
||||||
else
|
|
||||||
return get(s:filetype_defaults, short, 1) == 0 ? 2 : 0
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Enabled() abort
|
|
||||||
return get(g:, 'copilot_enabled', 1)
|
|
||||||
\ && empty(s:BufferDisabled())
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:inline_invoked = 1
|
|
||||||
let s:inline_automatic = 2
|
|
||||||
|
|
||||||
function! copilot#Complete(...) abort
|
|
||||||
if exists('g:_copilot_timer')
|
|
||||||
call timer_stop(remove(g:, '_copilot_timer'))
|
|
||||||
endif
|
|
||||||
let target = [bufnr(''), getbufvar('', 'changedtick'), line('.'), col('.')]
|
|
||||||
if !exists('b:_copilot.target') || b:_copilot.target !=# target
|
|
||||||
if exists('b:_copilot.first')
|
|
||||||
call copilot#client#Cancel(b:_copilot.first)
|
|
||||||
endif
|
|
||||||
if exists('b:_copilot.cycling')
|
|
||||||
call copilot#client#Cancel(b:_copilot.cycling)
|
|
||||||
endif
|
|
||||||
let params = {
|
|
||||||
\ 'textDocument': {'uri': bufnr('')},
|
|
||||||
\ 'position': copilot#util#AppendPosition(),
|
|
||||||
\ 'formattingOptions': {'insertSpaces': &expandtab ? v:true : v:false, 'tabSize': shiftwidth()},
|
|
||||||
\ 'context': {'triggerKind': s:inline_automatic}}
|
|
||||||
let b:_copilot = {
|
|
||||||
\ 'target': target,
|
|
||||||
\ 'params': params,
|
|
||||||
\ 'first': copilot#Request('textDocument/inlineCompletion', params)}
|
|
||||||
let g:_copilot_last = b:_copilot
|
|
||||||
endif
|
|
||||||
let completion = b:_copilot.first
|
|
||||||
if !a:0
|
|
||||||
return completion.Await()
|
|
||||||
else
|
|
||||||
call copilot#client#Result(completion, function(a:1, [b:_copilot]))
|
|
||||||
if a:0 > 1
|
|
||||||
call copilot#client#Error(completion, function(a:2, [b:_copilot]))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HideDuringCompletion() abort
|
|
||||||
return get(g:, 'copilot_hide_during_completion', 1)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:SuggestionTextWithAdjustments() abort
|
|
||||||
let empty = ['', 0, 0, {}]
|
|
||||||
try
|
|
||||||
if mode() !~# '^[iR]' || (s:HideDuringCompletion() && pumvisible()) || !exists('b:_copilot.suggestions')
|
|
||||||
return empty
|
|
||||||
endif
|
|
||||||
let choice = get(b:_copilot.suggestions, b:_copilot.choice, {})
|
|
||||||
if !has_key(choice, 'range') || choice.range.start.line != line('.') - 1 || type(choice.insertText) !=# v:t_string
|
|
||||||
return empty
|
|
||||||
endif
|
|
||||||
let line = getline('.')
|
|
||||||
let offset = col('.') - 1
|
|
||||||
let choice_text = strpart(line, 0, copilot#util#UTF16ToByteIdx(line, choice.range.start.character)) . substitute(choice.insertText, "\n*$", '', '')
|
|
||||||
let typed = strpart(line, 0, offset)
|
|
||||||
let end_offset = copilot#util#UTF16ToByteIdx(line, choice.range.end.character)
|
|
||||||
if end_offset < 0
|
|
||||||
let end_offset = len(line)
|
|
||||||
endif
|
|
||||||
let delete = strpart(line, offset, end_offset - offset)
|
|
||||||
if typed =~# '^\s*$'
|
|
||||||
let leading = matchstr(choice_text, '^\s\+')
|
|
||||||
let unindented = strpart(choice_text, len(leading))
|
|
||||||
if strpart(typed, 0, len(leading)) == leading && unindented !=# delete
|
|
||||||
return [unindented, len(typed) - len(leading), strchars(delete), choice]
|
|
||||||
endif
|
|
||||||
elseif typed ==# strpart(choice_text, 0, offset)
|
|
||||||
return [strpart(choice_text, offset), 0, strchars(delete), choice]
|
|
||||||
endif
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception()
|
|
||||||
endtry
|
|
||||||
return empty
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! s:Advance(count, context, ...) abort
|
|
||||||
if a:context isnot# get(b:, '_copilot', {})
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let a:context.choice += a:count
|
|
||||||
if a:context.choice < 0
|
|
||||||
let a:context.choice += len(a:context.suggestions)
|
|
||||||
endif
|
|
||||||
let a:context.choice %= len(a:context.suggestions)
|
|
||||||
call s:UpdatePreview()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:GetSuggestionsCyclingCallback(context, result) abort
|
|
||||||
let callbacks = remove(a:context, 'cycling_callbacks')
|
|
||||||
let seen = {}
|
|
||||||
for suggestion in a:context.suggestions
|
|
||||||
let seen[suggestion.insertText] = 1
|
|
||||||
endfor
|
|
||||||
for suggestion in get(a:result, 'items', [])
|
|
||||||
if !has_key(seen, suggestion.insertText)
|
|
||||||
call add(a:context.suggestions, suggestion)
|
|
||||||
let seen[suggestion.insertText] = 1
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
for Callback in callbacks
|
|
||||||
call Callback(a:context)
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:GetSuggestionsCycling(callback) abort
|
|
||||||
if exists('b:_copilot.cycling_callbacks')
|
|
||||||
call add(b:_copilot.cycling_callbacks, a:callback)
|
|
||||||
elseif exists('b:_copilot.cycling')
|
|
||||||
call a:callback(b:_copilot)
|
|
||||||
elseif exists('b:_copilot.suggestions')
|
|
||||||
let params = deepcopy(b:_copilot.first.params)
|
|
||||||
let params.context.triggerKind = s:inline_invoked
|
|
||||||
let b:_copilot.cycling_callbacks = [a:callback]
|
|
||||||
let b:_copilot.cycling = copilot#Request('textDocument/inlineCompletion',
|
|
||||||
\ params,
|
|
||||||
\ function('s:GetSuggestionsCyclingCallback', [b:_copilot]),
|
|
||||||
\ function('s:GetSuggestionsCyclingCallback', [b:_copilot]),
|
|
||||||
\ )
|
|
||||||
call s:UpdatePreview()
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Next() abort
|
|
||||||
return s:GetSuggestionsCycling(function('s:Advance', [1]))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Previous() abort
|
|
||||||
return s:GetSuggestionsCycling(function('s:Advance', [-1]))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#GetDisplayedSuggestion() abort
|
|
||||||
let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments()
|
|
||||||
|
|
||||||
return {
|
|
||||||
\ 'item': item,
|
|
||||||
\ 'text': text,
|
|
||||||
\ 'outdentSize': outdent,
|
|
||||||
\ 'deleteSize': delete}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ClearPreview() abort
|
|
||||||
if s:has_nvim_ghost_text
|
|
||||||
call nvim_buf_del_extmark(0, copilot#NvimNs(), 1)
|
|
||||||
elseif s:has_vim_ghost_text
|
|
||||||
call prop_remove({'type': s:hlgroup, 'all': v:true})
|
|
||||||
call prop_remove({'type': s:annot_hlgroup, 'all': v:true})
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UpdatePreview() abort
|
|
||||||
try
|
|
||||||
let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments()
|
|
||||||
let text = split(text, "\r\n\\=\\|\n", 1)
|
|
||||||
if empty(text[-1])
|
|
||||||
call remove(text, -1)
|
|
||||||
endif
|
|
||||||
if empty(text) || !s:has_ghost_text
|
|
||||||
return s:ClearPreview()
|
|
||||||
endif
|
|
||||||
if exists('b:_copilot.cycling_callbacks')
|
|
||||||
let annot = '(1/…)'
|
|
||||||
elseif exists('b:_copilot.cycling')
|
|
||||||
let annot = '(' . (b:_copilot.choice + 1) . '/' . len(b:_copilot.suggestions) . ')'
|
|
||||||
else
|
|
||||||
let annot = ''
|
|
||||||
endif
|
|
||||||
call s:ClearPreview()
|
|
||||||
if s:has_nvim_ghost_text
|
|
||||||
let data = {'id': 1}
|
|
||||||
let data.virt_text_pos = 'overlay'
|
|
||||||
let append = strpart(getline('.'), col('.') - 1 + delete)
|
|
||||||
let data.virt_text = [[text[0] . append . repeat(' ', delete - len(text[0])), s:hlgroup]]
|
|
||||||
if len(text) > 1
|
|
||||||
let data.virt_lines = map(text[1:-1], { _, l -> [[l, s:hlgroup]] })
|
|
||||||
if !empty(annot)
|
|
||||||
let data.virt_lines[-1] += [[' '], [annot, s:annot_hlgroup]]
|
|
||||||
endif
|
|
||||||
elseif len(annot)
|
|
||||||
let data.virt_text += [[' '], [annot, s:annot_hlgroup]]
|
|
||||||
endif
|
|
||||||
let data.hl_mode = 'combine'
|
|
||||||
call nvim_buf_set_extmark(0, copilot#NvimNs(), line('.')-1, col('.')-1, data)
|
|
||||||
elseif s:has_vim_ghost_text
|
|
||||||
let new_suffix = text[0]
|
|
||||||
let current_suffix = getline('.')[col('.') - 1 :]
|
|
||||||
let inset = ''
|
|
||||||
while delete > 0 && !empty(new_suffix)
|
|
||||||
let last_char = matchstr(new_suffix, '.$')
|
|
||||||
let new_suffix = matchstr(new_suffix, '^.\{-\}\ze.$')
|
|
||||||
if last_char ==# matchstr(current_suffix, '.$')
|
|
||||||
if !empty(inset)
|
|
||||||
call prop_add(line('.'), col('.') + len(current_suffix), {'type': s:hlgroup, 'text': inset})
|
|
||||||
let inset = ''
|
|
||||||
endif
|
|
||||||
let current_suffix = matchstr(current_suffix, '^.\{-\}\ze.$')
|
|
||||||
let delete -= 1
|
|
||||||
else
|
|
||||||
let inset = last_char . inset
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
if !empty(new_suffix . inset)
|
|
||||||
call prop_add(line('.'), col('.'), {'type': s:hlgroup, 'text': new_suffix . inset})
|
|
||||||
endif
|
|
||||||
for line in text[1:]
|
|
||||||
call prop_add(line('.'), 0, {'type': s:hlgroup, 'text_align': 'below', 'text': line})
|
|
||||||
endfor
|
|
||||||
if !empty(annot)
|
|
||||||
call prop_add(line('.'), col('$'), {'type': s:annot_hlgroup, 'text': ' ' . annot})
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
call copilot#Notify('textDocument/didShowCompletion', {'item': item})
|
|
||||||
catch
|
|
||||||
return copilot#logger#Exception()
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HandleTriggerResult(state, result) abort
|
|
||||||
let a:state.suggestions = type(a:result) == type([]) ? a:result : get(empty(a:result) ? {} : a:result, 'items', [])
|
|
||||||
let a:state.choice = 0
|
|
||||||
if get(b:, '_copilot') is# a:state
|
|
||||||
call s:UpdatePreview()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HandleTriggerError(state, result) abort
|
|
||||||
let a:state.suggestions = []
|
|
||||||
let a:state.choice = 0
|
|
||||||
let a:state.error = a:result
|
|
||||||
if get(b:, '_copilot') is# a:state
|
|
||||||
call s:UpdatePreview()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Suggest() abort
|
|
||||||
if !s:Running()
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
call copilot#Complete(function('s:HandleTriggerResult'), function('s:HandleTriggerError'))
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception()
|
|
||||||
endtry
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Trigger(bufnr, timer) abort
|
|
||||||
let timer = get(g:, '_copilot_timer', -1)
|
|
||||||
if a:bufnr !=# bufnr('') || a:timer isnot# timer || mode() !=# 'i'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
unlet! g:_copilot_timer
|
|
||||||
return copilot#Suggest()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Schedule() abort
|
|
||||||
if !s:has_ghost_text || !s:Running() || !copilot#Enabled()
|
|
||||||
call copilot#Clear()
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call s:UpdatePreview()
|
|
||||||
let delay = get(g:, 'copilot_idle_delay', 45)
|
|
||||||
call timer_stop(get(g:, '_copilot_timer', -1))
|
|
||||||
let g:_copilot_timer = timer_start(delay, function('s:Trigger', [bufnr('')]))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Attach(bufnr, ...) abort
|
|
||||||
try
|
|
||||||
return copilot#Client().Attach(a:bufnr)
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception()
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnFileType() abort
|
|
||||||
if empty(s:BufferDisabled()) && &l:modifiable && &l:buflisted
|
|
||||||
call copilot#util#Defer(function('s:Attach'), bufnr(''))
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Focus(bufnr, ...) abort
|
|
||||||
if s:Running() && copilot#Client().IsAttached(a:bufnr)
|
|
||||||
call copilot#Client().Notify('textDocument/didFocus', {'textDocument': {'uri': copilot#Client().Attach(a:bufnr).uri}})
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnBufEnter() abort
|
|
||||||
let bufnr = bufnr('')
|
|
||||||
call copilot#util#Defer(function('s:Focus'), bufnr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnInsertLeavePre() abort
|
|
||||||
call copilot#Clear()
|
|
||||||
call s:ClearPreview()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnInsertEnter() abort
|
|
||||||
return copilot#Schedule()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnCompleteChanged() abort
|
|
||||||
if s:HideDuringCompletion()
|
|
||||||
return copilot#Clear()
|
|
||||||
else
|
|
||||||
return copilot#Schedule()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnCursorMovedI() abort
|
|
||||||
return copilot#Schedule()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnBufUnload() abort
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#OnVimLeavePre() abort
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#TextQueuedForInsertion() abort
|
|
||||||
try
|
|
||||||
return remove(s:, 'suggestion_text')
|
|
||||||
catch
|
|
||||||
return ''
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Accept(...) abort
|
|
||||||
let s = copilot#GetDisplayedSuggestion()
|
|
||||||
if !empty(s.text)
|
|
||||||
unlet! b:_copilot
|
|
||||||
let text = ''
|
|
||||||
if a:0 > 1
|
|
||||||
let text = substitute(matchstr(s.text, "\n*" . '\%(' . a:2 .'\)'), "\n*$", '', '')
|
|
||||||
endif
|
|
||||||
if empty(text)
|
|
||||||
let text = s.text
|
|
||||||
endif
|
|
||||||
if text ==# s.text && has_key(s.item, 'command')
|
|
||||||
call copilot#Request('workspace/executeCommand', s.item.command)
|
|
||||||
else
|
|
||||||
let line_text = strpart(getline('.'), 0, col('.') - 1) . text
|
|
||||||
call copilot#Notify('textDocument/didPartiallyAcceptCompletion', {
|
|
||||||
\ 'item': s.item,
|
|
||||||
\ 'acceptedLength': copilot#util#UTF16Width(line_text) - s.item.range.start.character})
|
|
||||||
endif
|
|
||||||
call s:ClearPreview()
|
|
||||||
let s:suggestion_text = text
|
|
||||||
let recall = text =~# "\n" ? "\<C-R>\<C-O>=" : "\<C-R>\<C-R>="
|
|
||||||
return repeat("\<Left>\<Del>", s.outdentSize) . repeat("\<Del>", s.deleteSize) .
|
|
||||||
\ recall . "copilot#TextQueuedForInsertion()\<CR>" . (a:0 > 1 ? '' : "\<End>")
|
|
||||||
endif
|
|
||||||
let default = get(g:, 'copilot_tab_fallback', pumvisible() ? "\<C-N>" : "\t")
|
|
||||||
if !a:0
|
|
||||||
return default
|
|
||||||
elseif type(a:1) == v:t_string
|
|
||||||
return a:1
|
|
||||||
elseif type(a:1) == v:t_func
|
|
||||||
try
|
|
||||||
return call(a:1, [])
|
|
||||||
catch
|
|
||||||
return default
|
|
||||||
endtry
|
|
||||||
else
|
|
||||||
return default
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#AcceptWord(...) abort
|
|
||||||
return copilot#Accept(a:0 ? a:1 : '', '\%(\k\@!.\)*\k*')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#AcceptLine(...) abort
|
|
||||||
return copilot#Accept(a:0 ? a:1 : "\r", "[^\n]\\+")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:BrowserCallback(into, code) abort
|
|
||||||
let a:into.code = a:code
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Browser() abort
|
|
||||||
if type(get(g:, 'copilot_browser')) == v:t_list
|
|
||||||
let cmd = copy(g:copilot_browser)
|
|
||||||
elseif type(get(g:, 'open_command')) == v:t_list
|
|
||||||
let cmd = copy(g:open_command)
|
|
||||||
elseif has('win32')
|
|
||||||
let cmd = ['rundll32', 'url.dll,FileProtocolHandler']
|
|
||||||
elseif has('mac')
|
|
||||||
let cmd = ['open']
|
|
||||||
elseif executable('wslview')
|
|
||||||
return ['wslview']
|
|
||||||
elseif executable('xdg-open')
|
|
||||||
return ['xdg-open']
|
|
||||||
else
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
if executable(get(cmd, 0, ''))
|
|
||||||
return cmd
|
|
||||||
else
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:commands = {}
|
|
||||||
|
|
||||||
function! s:EnabledStatusMessage() abort
|
|
||||||
let buf_disabled = s:BufferDisabled()
|
|
||||||
if !s:has_ghost_text
|
|
||||||
if has('nvim')
|
|
||||||
return "Neovim 0.6 required to support ghost text"
|
|
||||||
else
|
|
||||||
return "Vim " . s:vim_minimum_version . " required to support ghost text"
|
|
||||||
endif
|
|
||||||
elseif !get(g:, 'copilot_enabled', 1)
|
|
||||||
return 'Disabled globally by :Copilot disable'
|
|
||||||
elseif buf_disabled is# 5
|
|
||||||
return 'Disabled for current buffer by buftype=' . &buftype
|
|
||||||
elseif buf_disabled is# 4
|
|
||||||
return 'Disabled for current buffer by b:copilot_enabled'
|
|
||||||
elseif buf_disabled is# 3
|
|
||||||
return 'Disabled for current buffer by b:copilot_disabled'
|
|
||||||
elseif buf_disabled is# 2
|
|
||||||
return 'Disabled for filetype=' . &filetype . ' by internal default'
|
|
||||||
elseif buf_disabled
|
|
||||||
return 'Disabled for filetype=' . &filetype . ' by g:copilot_filetypes'
|
|
||||||
elseif !copilot#Enabled()
|
|
||||||
return 'BUG: Something is wrong with enabling/disabling'
|
|
||||||
else
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VerifySetup() abort
|
|
||||||
let error = copilot#Client().StartupError()
|
|
||||||
if !empty(error)
|
|
||||||
echo 'Copilot: ' . error
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let status = copilot#Call('checkStatus', {})
|
|
||||||
|
|
||||||
if !has_key(status, 'user')
|
|
||||||
echo 'Copilot: Not authenticated. Invoke :Copilot setup'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if status.status ==# 'NoTelemetryConsent'
|
|
||||||
echo 'Copilot: Telemetry terms not accepted. Invoke :Copilot setup'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if status.status ==# 'NotAuthorized'
|
|
||||||
echo "Copilot: You don't have access to GitHub Copilot. Sign up by visiting https://github.com/settings/copilot"
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.status(opts) abort
|
|
||||||
if !s:VerifySetup()
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if exists('s:client.status.status') && s:client.status.status =~# 'Warning\|Error'
|
|
||||||
echo 'Copilot: ' . s:client.status.status
|
|
||||||
if !empty(get(s:client.status, 'message', ''))
|
|
||||||
echon ': ' . s:client.status.message
|
|
||||||
endif
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let status = s:EnabledStatusMessage()
|
|
||||||
if !empty(status)
|
|
||||||
echo 'Copilot: ' . status
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
echo 'Copilot: Ready'
|
|
||||||
call s:EditorVersionWarning()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.signout(opts) abort
|
|
||||||
let status = copilot#Call('checkStatus', {'options': {'localChecksOnly': v:true}})
|
|
||||||
if has_key(status, 'user')
|
|
||||||
echo 'Copilot: Signed out as GitHub user ' . status.user
|
|
||||||
else
|
|
||||||
echo 'Copilot: Not signed in'
|
|
||||||
endif
|
|
||||||
call copilot#Call('signOut', {})
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.setup(opts) abort
|
|
||||||
let startup_error = copilot#Client().StartupError()
|
|
||||||
if !empty(startup_error)
|
|
||||||
echo 'Copilot: ' . startup_error
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let browser = copilot#Browser()
|
|
||||||
|
|
||||||
let status = copilot#Call('checkStatus', {})
|
|
||||||
if has_key(status, 'user')
|
|
||||||
let data = {'status': 'AlreadySignedIn', 'user': status.user}
|
|
||||||
else
|
|
||||||
let data = copilot#Call('signInInitiate', {})
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(data, 'verificationUri')
|
|
||||||
let uri = data.verificationUri
|
|
||||||
if has('clipboard')
|
|
||||||
try
|
|
||||||
let @+ = data.userCode
|
|
||||||
catch
|
|
||||||
endtry
|
|
||||||
try
|
|
||||||
let @* = data.userCode
|
|
||||||
catch
|
|
||||||
endtry
|
|
||||||
endif
|
|
||||||
let codemsg = "First copy your one-time code: " . data.userCode . "\n"
|
|
||||||
try
|
|
||||||
if len(&mouse)
|
|
||||||
let mouse = &mouse
|
|
||||||
set mouse=
|
|
||||||
endif
|
|
||||||
if get(a:opts, 'bang')
|
|
||||||
call s:Echo(codemsg . "In your browser, visit " . uri)
|
|
||||||
elseif len(browser)
|
|
||||||
call input(codemsg . "Press ENTER to open GitHub in your browser\n")
|
|
||||||
let status = {}
|
|
||||||
call copilot#job#Stream(browser + [uri], v:null, v:null, function('s:BrowserCallback', [status]))
|
|
||||||
let time = reltime()
|
|
||||||
while empty(status) && reltimefloat(reltime(time)) < 5
|
|
||||||
sleep 10m
|
|
||||||
endwhile
|
|
||||||
if get(status, 'code', browser[0] !=# 'xdg-open') != 0
|
|
||||||
call s:Echo("Failed to open browser. Visit " . uri)
|
|
||||||
else
|
|
||||||
call s:Echo("Opened " . uri)
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
call s:Echo(codemsg . "Could not find browser. Visit " . uri)
|
|
||||||
endif
|
|
||||||
call s:Echo("Waiting (could take up to 10 seconds)")
|
|
||||||
let request = copilot#Request('signInConfirm', {'userCode': data.userCode}).Wait()
|
|
||||||
finally
|
|
||||||
if exists('mouse')
|
|
||||||
let &mouse = mouse
|
|
||||||
endif
|
|
||||||
endtry
|
|
||||||
if request.status ==# 'error'
|
|
||||||
return 'echoerr ' . string('Copilot: Authentication failure: ' . request.error.message)
|
|
||||||
else
|
|
||||||
let status = request.result
|
|
||||||
endif
|
|
||||||
elseif get(data, 'status', '') isnot# 'AlreadySignedIn'
|
|
||||||
return 'echoerr ' . string('Copilot: Something went wrong')
|
|
||||||
endif
|
|
||||||
|
|
||||||
let user = get(status, 'user', '<unknown>')
|
|
||||||
|
|
||||||
echo 'Copilot: Authenticated as GitHub user ' . user
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:commands.auth = s:commands.setup
|
|
||||||
let s:commands.signin = s:commands.setup
|
|
||||||
|
|
||||||
function! s:commands.help(opts) abort
|
|
||||||
return a:opts.mods . ' help ' . (len(a:opts.arg) ? ':Copilot_' . a:opts.arg : 'copilot')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.version(opts) abort
|
|
||||||
echo 'copilot.vim ' .copilot#client#EditorPluginInfo().version
|
|
||||||
let editorInfo = copilot#client#EditorInfo()
|
|
||||||
echo editorInfo.name . ' ' . editorInfo.version
|
|
||||||
if s:Running()
|
|
||||||
let versions = s:client.Request('getVersion', {})
|
|
||||||
if exists('s:client.serverInfo.version')
|
|
||||||
echo s:client.serverInfo.name . ' ' . s:client.serverInfo.version
|
|
||||||
else
|
|
||||||
echo 'GitHub Copilot Language Server ' . versions.Await().version
|
|
||||||
endif
|
|
||||||
if exists('s:client.node_version')
|
|
||||||
echo 'Node.js ' . s:client.node_version
|
|
||||||
else
|
|
||||||
echo 'Node.js ' . substitute(get(versions.Await(), 'runtimeVersion', '?'), '^node/', '', 'g')
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
echo 'Not running'
|
|
||||||
if exists('s:client.node_version')
|
|
||||||
echo 'Node.js ' . s:client.node_version
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
if has('win32')
|
|
||||||
echo 'Windows'
|
|
||||||
elseif has('macunix')
|
|
||||||
echo 'macOS'
|
|
||||||
elseif !has('unix')
|
|
||||||
echo 'Unknown OS'
|
|
||||||
elseif isdirectory('/sys/kernel')
|
|
||||||
echo 'Linux'
|
|
||||||
else
|
|
||||||
echo 'UNIX'
|
|
||||||
endif
|
|
||||||
call s:EditorVersionWarning()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UpdateEditorConfiguration() abort
|
|
||||||
try
|
|
||||||
if s:Running()
|
|
||||||
call copilot#Notify('notifyChangeConfiguration', {'settings': s:EditorConfiguration()})
|
|
||||||
endif
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception()
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:feedback_url = 'https://github.com/orgs/community/discussions/categories/copilot'
|
|
||||||
function! s:commands.feedback(opts) abort
|
|
||||||
echo s:feedback_url
|
|
||||||
let browser = copilot#Browser()
|
|
||||||
if len(browser)
|
|
||||||
call copilot#job#Stream(browser + [s:feedback_url], v:null, v:null, v:null)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.restart(opts) abort
|
|
||||||
call s:Stop()
|
|
||||||
echo 'Copilot: Restarting language server'
|
|
||||||
call s:Start()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.disable(opts) abort
|
|
||||||
let g:copilot_enabled = 0
|
|
||||||
call s:UpdateEditorConfiguration()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.enable(opts) abort
|
|
||||||
let g:copilot_enabled = 1
|
|
||||||
call s:UpdateEditorConfiguration()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.panel(opts) abort
|
|
||||||
if s:VerifySetup()
|
|
||||||
return copilot#panel#Open(a:opts)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:commands.log(opts) abort
|
|
||||||
return a:opts.mods . ' split +$ copilot:///log'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#CommandComplete(arg, lead, pos) abort
|
|
||||||
let args = matchstr(strpart(a:lead, 0, a:pos), 'C\%[opilot][! ] *\zs.*')
|
|
||||||
if args !~# ' '
|
|
||||||
return sort(filter(map(keys(s:commands), { k, v -> tr(v, '_', '-') }),
|
|
||||||
\ { k, v -> strpart(v, 0, len(a:arg)) ==# a:arg }))
|
|
||||||
else
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#Command(line1, line2, range, bang, mods, arg) abort
|
|
||||||
let cmd = matchstr(a:arg, '^\%(\\.\|\S\)\+')
|
|
||||||
let arg = matchstr(a:arg, '\s\zs\S.*')
|
|
||||||
if !empty(cmd) && !has_key(s:commands, tr(cmd, '-', '_'))
|
|
||||||
return 'echoerr ' . string('Copilot: unknown command ' . string(cmd))
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
if empty(cmd)
|
|
||||||
if !s:Running()
|
|
||||||
let cmd = 'restart'
|
|
||||||
else
|
|
||||||
try
|
|
||||||
let opts = copilot#Call('checkStatus', {'options': {'localChecksOnly': v:true}})
|
|
||||||
if opts.status !=# 'OK' && opts.status !=# 'MaybeOK'
|
|
||||||
let cmd = 'setup'
|
|
||||||
else
|
|
||||||
let cmd = 'panel'
|
|
||||||
endif
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception()
|
|
||||||
let cmd = 'log'
|
|
||||||
endtry
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let opts = {'line1': a:line1, 'line2': a:line2, 'range': a:range, 'bang': a:bang, 'mods': a:mods, 'arg': arg}
|
|
||||||
let retval = s:commands[tr(cmd, '-', '_')](opts)
|
|
||||||
if type(retval) == v:t_string
|
|
||||||
return retval
|
|
||||||
else
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
catch /^Copilot:/
|
|
||||||
return 'echoerr ' . string(v:exception)
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
@@ -1,764 +0,0 @@
|
|||||||
scriptencoding utf-8
|
|
||||||
|
|
||||||
let s:plugin_version = copilot#version#String()
|
|
||||||
|
|
||||||
let s:error_canceled = {'code': -32800, 'message': 'Canceled'}
|
|
||||||
let s:error_exit = {'code': -32097, 'message': 'Process exited'}
|
|
||||||
let s:error_connection_inactive = {'code': -32096, 'message': 'Connection inactive'}
|
|
||||||
|
|
||||||
let s:root = expand('<sfile>:h:h:h')
|
|
||||||
|
|
||||||
if !exists('s:instances')
|
|
||||||
let s:instances = {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
" allow sourcing this file to reload the Lua file too
|
|
||||||
if has('nvim')
|
|
||||||
lua package.loaded._copilot = nil
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:Warn(msg) abort
|
|
||||||
if !empty(get(g:, 'copilot_no_startup_warnings'))
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
echohl WarningMsg
|
|
||||||
echomsg 'Copilot: ' . a:msg
|
|
||||||
echohl NONE
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimClose() dict abort
|
|
||||||
if !has_key(self, 'job')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let job = self.job
|
|
||||||
if has_key(self, 'kill')
|
|
||||||
call job_stop(job, 'kill')
|
|
||||||
call copilot#logger#Warn('Process forcefully terminated')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let self.kill = v:true
|
|
||||||
let self.shutdown = self.Request('shutdown', {}, function(self.Notify, ['exit']))
|
|
||||||
call timer_start(2000, { _ -> job_stop(job, 'kill') })
|
|
||||||
call copilot#logger#Debug('Process shutdown initiated')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:LogSend(request, line) abort
|
|
||||||
return '--> ' . a:line
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RejectRequest(request, error) abort
|
|
||||||
if a:request.status !=# 'running'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let a:request.waiting = {}
|
|
||||||
call remove(a:request, 'resolve')
|
|
||||||
let reject = remove(a:request, 'reject')
|
|
||||||
let a:request.status = 'error'
|
|
||||||
let a:request.error = deepcopy(a:error)
|
|
||||||
for Cb in reject
|
|
||||||
let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', Cb]))] = 1
|
|
||||||
endfor
|
|
||||||
if index([s:error_canceled.code, s:error_connection_inactive.code], a:error.code) != -1
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let msg = 'Method ' . a:request.method . ' errored with E' . a:error.code . ': ' . json_encode(a:error.message)
|
|
||||||
if empty(reject)
|
|
||||||
call copilot#logger#Error(msg)
|
|
||||||
else
|
|
||||||
call copilot#logger#Debug(msg)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:AfterInitialized(fn, ...) dict abort
|
|
||||||
call add(self.after_initialized, function(a:fn, a:000))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Send(instance, request) abort
|
|
||||||
if !has_key(a:instance, 'job')
|
|
||||||
return v:false
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
call ch_sendexpr(a:instance.job, a:request)
|
|
||||||
return v:true
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E906:/
|
|
||||||
let a:instance.kill = v:true
|
|
||||||
let job = remove(a:instance, 'job')
|
|
||||||
call job_stop(job)
|
|
||||||
call timer_start(2000, { _ -> job_stop(job, 'kill') })
|
|
||||||
call copilot#logger#Warn('Terminating process after failed write')
|
|
||||||
return v:false
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E631:/
|
|
||||||
return v:false
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimNotify(method, params) dict abort
|
|
||||||
let request = {'method': a:method, 'params': a:params}
|
|
||||||
call self.AfterInitialized(function('s:Send', [self, request]))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RequestWait() dict abort
|
|
||||||
while self.status ==# 'running'
|
|
||||||
sleep 1m
|
|
||||||
endwhile
|
|
||||||
while !empty(get(self, 'waiting', {}))
|
|
||||||
sleep 1m
|
|
||||||
endwhile
|
|
||||||
return self
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RequestAwait() dict abort
|
|
||||||
call self.Wait()
|
|
||||||
if has_key(self, 'result')
|
|
||||||
return self.result
|
|
||||||
endif
|
|
||||||
throw 'Copilot:E' . self.error.code . ': ' . self.error.message
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RequestClient() dict abort
|
|
||||||
return get(s:instances, self.client_id, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if !exists('s:id')
|
|
||||||
let s:id = 0
|
|
||||||
endif
|
|
||||||
if !exists('s:progress_token_id')
|
|
||||||
let s:progress_token_id = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:SetUpRequest(instance, id, method, params, progress, ...) abort
|
|
||||||
let request = {
|
|
||||||
\ 'client_id': a:instance.id,
|
|
||||||
\ 'id': a:id,
|
|
||||||
\ 'method': a:method,
|
|
||||||
\ 'params': a:params,
|
|
||||||
\ 'Client': function('s:RequestClient'),
|
|
||||||
\ 'Wait': function('s:RequestWait'),
|
|
||||||
\ 'Await': function('s:RequestAwait'),
|
|
||||||
\ 'Cancel': function('s:RequestCancel'),
|
|
||||||
\ 'resolve': [],
|
|
||||||
\ 'reject': [],
|
|
||||||
\ 'progress': a:progress,
|
|
||||||
\ 'status': 'running'}
|
|
||||||
let args = a:000[2:-1]
|
|
||||||
if len(args)
|
|
||||||
if !empty(a:1)
|
|
||||||
call add(request.resolve, { v -> call(a:1, [v] + args)})
|
|
||||||
endif
|
|
||||||
if !empty(a:2)
|
|
||||||
call add(request.reject, { v -> call(a:2, [v] + args)})
|
|
||||||
endif
|
|
||||||
return request
|
|
||||||
endif
|
|
||||||
if a:0 && !empty(a:1)
|
|
||||||
call add(request.resolve, a:1)
|
|
||||||
endif
|
|
||||||
if a:0 > 1 && !empty(a:2)
|
|
||||||
call add(request.reject, a:2)
|
|
||||||
endif
|
|
||||||
return request
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UrlEncode(str) abort
|
|
||||||
return substitute(iconv(a:str, 'latin1', 'utf-8'),'[^A-Za-z0-9._~!$&''()*+,;=:@/-]','\="%".printf("%02X",char2nr(submatch(0)))','g')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:slash = exists('+shellslash') ? '\' : '/'
|
|
||||||
function! s:UriFromBufnr(bufnr) abort
|
|
||||||
let absolute = tr(bufname(a:bufnr), s:slash, '/')
|
|
||||||
if absolute !~# '^\a\+:\|^/\|^$' && getbufvar(a:bufnr, 'buftype') =~# '^\%(nowrite\)\=$'
|
|
||||||
let absolute = substitute(tr(getcwd(), s:slash, '/'), '/\=$', '/', '') . absolute
|
|
||||||
endif
|
|
||||||
return s:UriFromPath(absolute)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UriFromPath(absolute) abort
|
|
||||||
let absolute = a:absolute
|
|
||||||
if has('win32') && absolute =~# '^\a://\@!'
|
|
||||||
return 'file:///' . strpart(absolute, 0, 2) . s:UrlEncode(strpart(absolute, 2))
|
|
||||||
elseif absolute =~# '^/'
|
|
||||||
return 'file://' . s:UrlEncode(absolute)
|
|
||||||
elseif absolute =~# '^\a[[:alnum:].+-]*:\|^$'
|
|
||||||
return absolute
|
|
||||||
else
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:BufferText(bufnr) abort
|
|
||||||
return join(getbufline(a:bufnr, 1, '$'), "\n") . "\n"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:valid_request_key = '^\%(id\|method\|params\)$'
|
|
||||||
function! s:SendRequest(instance, request, ...) abort
|
|
||||||
if !has_key(a:instance, 'job') || get(a:instance, 'shutdown', a:request) isnot# a:request
|
|
||||||
return s:RejectRequest(a:request, s:error_connection_inactive)
|
|
||||||
endif
|
|
||||||
let json = filter(copy(a:request), 'v:key =~# s:valid_request_key')
|
|
||||||
if empty(s:Send(a:instance, json)) && has_key(a:request, 'id') && has_key(a:instance.requests, a:request.id)
|
|
||||||
call s:RejectRequest(remove(a:instance.requests, a:request.id), {'code': -32099, 'message': 'Write failed'})
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RegisterWorkspaceFolderForBuffer(instance, buf) abort
|
|
||||||
let root = getbufvar(a:buf, 'workspace_folder')
|
|
||||||
if type(root) != v:t_string
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let root = s:UriFromPath(substitute(root, '[\/]$', '', ''))
|
|
||||||
if empty(root) || has_key(a:instance.workspaceFolders, root)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let a:instance.workspaceFolders[root] = v:true
|
|
||||||
call a:instance.Notify('workspace/didChangeWorkspaceFolders', {'event': {'added': [{'uri': root, 'name': fnamemodify(root, ':t')}], 'removed': []}})
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:PreprocessParams(instance, params) abort
|
|
||||||
let bufnr = v:null
|
|
||||||
for doc in filter([get(a:params, 'textDocument', {})], 'type(get(v:val, "uri", "")) == v:t_number')
|
|
||||||
let bufnr = doc.uri
|
|
||||||
call s:RegisterWorkspaceFolderForBuffer(a:instance, bufnr)
|
|
||||||
call extend(doc, a:instance.Attach(bufnr))
|
|
||||||
endfor
|
|
||||||
let progress_tokens = []
|
|
||||||
for key in keys(a:params)
|
|
||||||
if key =~# 'Token$' && type(a:params[key]) == v:t_func
|
|
||||||
let s:progress_token_id += 1
|
|
||||||
let a:instance.progress[s:progress_token_id] = a:params[key]
|
|
||||||
call add(progress_tokens, s:progress_token_id)
|
|
||||||
let a:params[key] = s:progress_token_id
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return [bufnr, progress_tokens]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimAttach(bufnr) dict abort
|
|
||||||
if !bufloaded(a:bufnr)
|
|
||||||
return {'uri': '', 'version': 0}
|
|
||||||
endif
|
|
||||||
let bufnr = a:bufnr
|
|
||||||
let doc = {
|
|
||||||
\ 'uri': s:UriFromBufnr(bufnr),
|
|
||||||
\ 'version': getbufvar(bufnr, 'changedtick', 0),
|
|
||||||
\ 'languageId': getbufvar(bufnr, '&filetype'),
|
|
||||||
\ }
|
|
||||||
if has_key(self.open_buffers, bufnr) && (
|
|
||||||
\ self.open_buffers[bufnr].uri !=# doc.uri ||
|
|
||||||
\ self.open_buffers[bufnr].languageId !=# doc.languageId)
|
|
||||||
call self.Notify('textDocument/didClose', {'textDocument': {'uri': self.open_buffers[bufnr].uri}})
|
|
||||||
call remove(self.open_buffers, bufnr)
|
|
||||||
endif
|
|
||||||
if !has_key(self.open_buffers, bufnr)
|
|
||||||
call self.Notify('textDocument/didOpen', {'textDocument': extend({'text': s:BufferText(bufnr)}, doc)})
|
|
||||||
let self.open_buffers[bufnr] = doc
|
|
||||||
else
|
|
||||||
call self.Notify('textDocument/didChange', {
|
|
||||||
\ 'textDocument': {'uri': doc.uri, 'version': doc.version},
|
|
||||||
\ 'contentChanges': [{'text': s:BufferText(bufnr)}]})
|
|
||||||
let self.open_buffers[bufnr].version = doc.version
|
|
||||||
endif
|
|
||||||
return doc
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimIsAttached(bufnr) dict abort
|
|
||||||
return bufloaded(a:bufnr) && has_key(self.open_buffers, a:bufnr) ? v:true : v:false
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimRequest(method, params, ...) dict abort
|
|
||||||
let s:id += 1
|
|
||||||
let params = deepcopy(a:params)
|
|
||||||
let [_, progress] = s:PreprocessParams(self, params)
|
|
||||||
let request = call('s:SetUpRequest', [self, s:id, a:method, params, progress] + a:000)
|
|
||||||
call self.AfterInitialized(function('s:SendRequest', [self, request]))
|
|
||||||
let self.requests[s:id] = request
|
|
||||||
return request
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Call(method, params, ...) dict abort
|
|
||||||
let request = call(self.Request, [a:method, a:params] + a:000)
|
|
||||||
if a:0
|
|
||||||
return request
|
|
||||||
endif
|
|
||||||
return request.Await()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Cancel(request) dict abort
|
|
||||||
if has_key(self.requests, get(a:request, 'id', ''))
|
|
||||||
call self.Notify('$/cancelRequest', {'id': a:request.id})
|
|
||||||
call s:RejectRequest(remove(self.requests, a:request.id), s:error_canceled)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RequestCancel() dict abort
|
|
||||||
let instance = self.Client()
|
|
||||||
if !empty(instance)
|
|
||||||
call instance.Cancel(self)
|
|
||||||
elseif get(self, 'status', '') ==# 'running'
|
|
||||||
call s:RejectRequest(self, s:error_canceled)
|
|
||||||
endif
|
|
||||||
return self
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:DispatchMessage(instance, method, handler, id, params, ...) abort
|
|
||||||
try
|
|
||||||
let response = {'result': call(a:handler, [a:params, a:instance])}
|
|
||||||
if response.result is# 0
|
|
||||||
let response.result = v:null
|
|
||||||
endif
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception('lsp.request.' . a:method)
|
|
||||||
let response = {'error': {'code': -32000, 'message': v:exception}}
|
|
||||||
endtry
|
|
||||||
if a:id isnot# v:null
|
|
||||||
call s:Send(a:instance, extend({'id': a:id}, response))
|
|
||||||
endif
|
|
||||||
if !has_key(s:notifications, a:method)
|
|
||||||
return response
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:OnMessage(instance, body, ...) abort
|
|
||||||
if !has_key(a:body, 'method')
|
|
||||||
return s:OnResponse(a:instance, a:body)
|
|
||||||
endif
|
|
||||||
let request = a:body
|
|
||||||
let id = get(request, 'id', v:null)
|
|
||||||
let params = get(request, 'params', v:null)
|
|
||||||
if has_key(a:instance.methods, request.method)
|
|
||||||
return s:DispatchMessage(a:instance, request.method, a:instance.methods[request.method], id, params)
|
|
||||||
elseif id isnot# v:null
|
|
||||||
call s:Send(a:instance, {"id": id, "error": {"code": -32700, "message": "Method not found: " . request.method}})
|
|
||||||
call copilot#logger#Debug('Unexpected request ' . request.method . ' called with ' . json_encode(params))
|
|
||||||
elseif request.method !~# '^\$/'
|
|
||||||
call copilot#logger#Debug('Unexpected notification ' . request.method . ' called with ' . json_encode(params))
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:OnResponse(instance, response, ...) abort
|
|
||||||
let response = a:response
|
|
||||||
let id = get(a:response, 'id', v:null)
|
|
||||||
if !has_key(a:instance.requests, id)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let request = remove(a:instance.requests, id)
|
|
||||||
for progress_token in request.progress
|
|
||||||
if has_key(a:instance.progress, progress_token)
|
|
||||||
call remove(a:instance.progress, progress_token)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
if request.status !=# 'running'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if has_key(response, 'result')
|
|
||||||
let request.waiting = {}
|
|
||||||
let resolve = remove(request, 'resolve')
|
|
||||||
call remove(request, 'reject')
|
|
||||||
let request.status = 'success'
|
|
||||||
let request.result = response.result
|
|
||||||
for Cb in resolve
|
|
||||||
let request.waiting[timer_start(0, function('s:Callback', [request, 'result', Cb]))] = 1
|
|
||||||
endfor
|
|
||||||
else
|
|
||||||
call s:RejectRequest(request, response.error)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:OnErr(instance, ch, line, ...) abort
|
|
||||||
if !has_key(a:instance, 'serverInfo')
|
|
||||||
call copilot#logger#Bare('<-! ' . a:line)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:OnExit(instance, code, ...) abort
|
|
||||||
let a:instance.exit_status = a:code
|
|
||||||
if has_key(a:instance, 'job')
|
|
||||||
call remove(a:instance, 'job')
|
|
||||||
endif
|
|
||||||
if has_key(a:instance, 'client_id')
|
|
||||||
call remove(a:instance, 'client_id')
|
|
||||||
endif
|
|
||||||
let message = 'Process exited with status ' . a:code
|
|
||||||
if a:code >= 18 && a:code < 100
|
|
||||||
let message = 'Node.js too old. ' .
|
|
||||||
\ (get(a:instance.node, 0, 'node') ==# 'node' ? 'Upgrade' : 'Change g:copilot_node_command') .
|
|
||||||
\ ' to ' . a:code . '.x or newer'
|
|
||||||
endif
|
|
||||||
if !has_key(a:instance, 'serverInfo') && !has_key(a:instance, 'startup_error')
|
|
||||||
let a:instance.startup_error = message
|
|
||||||
endif
|
|
||||||
for id in sort(keys(a:instance.requests), { a, b -> +a > +b })
|
|
||||||
call s:RejectRequest(remove(a:instance.requests, id), s:error_exit)
|
|
||||||
endfor
|
|
||||||
if has_key(a:instance, 'after_initialized')
|
|
||||||
let a:instance.AfterInitialized = function('copilot#util#Defer')
|
|
||||||
for Fn in remove(a:instance, 'after_initialized')
|
|
||||||
call copilot#util#Defer(Fn)
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
call copilot#util#Defer({ -> get(s:instances, a:instance.id) is# a:instance ? remove(s:instances, a:instance.id) : {} })
|
|
||||||
if a:code == 0
|
|
||||||
call copilot#logger#Info(message)
|
|
||||||
else
|
|
||||||
call copilot#logger#Warn(message)
|
|
||||||
if !has_key(a:instance, 'kill')
|
|
||||||
call copilot#util#Defer(function('s:Warn'), message)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#LspInit(id, initialize_result) abort
|
|
||||||
if !has_key(s:instances, a:id)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call s:PostInit(a:initialize_result, s:instances[a:id])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#LspExit(id, code, signal) abort
|
|
||||||
if !has_key(s:instances, a:id)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let instance = remove(s:instances, a:id)
|
|
||||||
call s:OnExit(instance, a:code)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#LspResponse(id, opts, ...) abort
|
|
||||||
if !has_key(s:instances, a:id)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call s:OnResponse(s:instances[a:id], a:opts)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimAttach(bufnr) dict abort
|
|
||||||
if !bufloaded(a:bufnr)
|
|
||||||
return {'uri': '', 'version': 0}
|
|
||||||
endif
|
|
||||||
call luaeval('pcall(vim.lsp.buf_attach_client, _A[1], _A[2])', [a:bufnr, self.id])
|
|
||||||
return luaeval('{uri = vim.uri_from_bufnr(_A), version = vim.lsp.util.buf_versions[_A]}', a:bufnr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimIsAttached(bufnr) dict abort
|
|
||||||
return bufloaded(a:bufnr) ? luaeval('vim.lsp.buf_is_attached(_A[1], _A[2])', [a:bufnr, self.id]) : v:false
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimRequest(method, params, ...) dict abort
|
|
||||||
let params = deepcopy(a:params)
|
|
||||||
let [bufnr, progress] = s:PreprocessParams(self, params)
|
|
||||||
let request = call('s:SetUpRequest', [self, v:null, a:method, params, progress] + a:000)
|
|
||||||
call self.AfterInitialized(function('s:NvimDoRequest', [self, request, bufnr]))
|
|
||||||
return request
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimDoRequest(client, request, bufnr) abort
|
|
||||||
let request = a:request
|
|
||||||
if has_key(a:client, 'client_id') && !has_key(a:client, 'kill')
|
|
||||||
let request.id = eval("v:lua.require'_copilot'.lsp_request(a:client.id, a:request.method, a:request.params, a:bufnr)")
|
|
||||||
endif
|
|
||||||
if request.id isnot# v:null
|
|
||||||
let a:client.requests[request.id] = request
|
|
||||||
else
|
|
||||||
if has_key(a:client, 'client_id')
|
|
||||||
call copilot#client#LspExit(a:client.client_id, -1, -1)
|
|
||||||
endif
|
|
||||||
call copilot#util#Defer(function('s:RejectRequest'), request, s:error_connection_inactive)
|
|
||||||
endif
|
|
||||||
return request
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimClose() dict abort
|
|
||||||
if !has_key(self, 'client_id')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let self.kill = v:true
|
|
||||||
return luaeval('vim.lsp.get_client_by_id(_A).stop()', self.client_id)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimNotify(method, params) dict abort
|
|
||||||
call self.AfterInitialized(function('s:NvimDoNotify', [self.client_id, a:method, a:params]))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimDoNotify(client_id, method, params) abort
|
|
||||||
return eval("v:lua.require'_copilot'.rpc_notify(a:client_id, a:method, a:params)")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#LspHandle(id, request) abort
|
|
||||||
if !has_key(s:instances, a:id)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
return s:OnMessage(s:instances[a:id], a:request)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:script_name = 'dist/language-server.js'
|
|
||||||
function! s:Command() abort
|
|
||||||
if !has('nvim-0.7') && v:version < 900
|
|
||||||
return [[], [], 'Vim version too old']
|
|
||||||
endif
|
|
||||||
let script = get(g:, 'copilot_command', '')
|
|
||||||
if type(script) == type('')
|
|
||||||
let script = [expand(script)]
|
|
||||||
endif
|
|
||||||
if empty(script) || !filereadable(script[0])
|
|
||||||
let script = [s:root . '/' . s:script_name]
|
|
||||||
if !filereadable(script[0])
|
|
||||||
return [[], [], 'Could not find ' . s:script_name . ' (bad install?)']
|
|
||||||
endif
|
|
||||||
elseif script[0] !~# '\.js$'
|
|
||||||
return [[], script + ['--stdio'], '']
|
|
||||||
endif
|
|
||||||
let node = get(g:, 'copilot_node_command', '')
|
|
||||||
if empty(node)
|
|
||||||
let node = ['node']
|
|
||||||
elseif type(node) == type('')
|
|
||||||
let node = [expand(node)]
|
|
||||||
endif
|
|
||||||
if !executable(get(node, 0, ''))
|
|
||||||
if get(node, 0, '') ==# 'node'
|
|
||||||
return [[], [], 'Node.js not found in PATH']
|
|
||||||
else
|
|
||||||
return [[], [], 'Node.js executable `' . get(node, 0, '') . "' not found"]
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return [node, script + ['--stdio'], '']
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UrlDecode(str) abort
|
|
||||||
return substitute(a:str, '%\(\x\x\)', '\=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")', 'g')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#EditorInfo() abort
|
|
||||||
if !exists('s:editor_version')
|
|
||||||
if has('nvim')
|
|
||||||
let s:editor_version = matchstr(execute('version'), 'NVIM v\zs[^[:space:]]\+')
|
|
||||||
else
|
|
||||||
let s:editor_version = (v:version / 100) . '.' . (v:version % 100) . (exists('v:versionlong') ? printf('.%04d', v:versionlong % 10000) : '')
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return {'name': has('nvim') ? 'Neovim': 'Vim', 'version': s:editor_version}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#EditorPluginInfo() abort
|
|
||||||
return {'name': 'copilot.vim', 'version': s:plugin_version}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#Settings() abort
|
|
||||||
let settings = {
|
|
||||||
\ 'http': {
|
|
||||||
\ 'proxy': get(g:, 'copilot_proxy', v:null),
|
|
||||||
\ 'proxyStrictSSL': get(g:, 'copilot_proxy_strict_ssl', v:null)},
|
|
||||||
\ 'github-enterprise': {'uri': get(g:, 'copilot_auth_provider_url', v:null)},
|
|
||||||
\ }
|
|
||||||
if type(settings.http.proxy) ==# v:t_string && settings.http.proxy =~# '^[^/]\+$'
|
|
||||||
let settings.http.proxy = 'http://' . settings.http.proxy
|
|
||||||
endif
|
|
||||||
if type(get(g:, 'copilot_settings')) == v:t_dict
|
|
||||||
call extend(settings, g:copilot_settings)
|
|
||||||
endif
|
|
||||||
return settings
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:PostInit(result, instance) abort
|
|
||||||
let a:instance.serverInfo = get(a:result, 'serverInfo', {})
|
|
||||||
if !has_key(a:instance, 'node_version') && has_key(a:result.serverInfo, 'nodeVersion')
|
|
||||||
let a:instance.node_version = a:result.serverInfo.nodeVersion
|
|
||||||
endif
|
|
||||||
let a:instance.AfterInitialized = function('copilot#util#Defer')
|
|
||||||
for Fn in remove(a:instance, 'after_initialized')
|
|
||||||
call copilot#util#Defer(Fn)
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:InitializeResult(result, instance) abort
|
|
||||||
call s:Send(a:instance, {'method': 'initialized', 'params': {}})
|
|
||||||
call s:PostInit(a:result, a:instance)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:InitializeError(error, instance) abort
|
|
||||||
if !has_key(a:instance, 'startup_error')
|
|
||||||
let a:instance.startup_error = 'Unexpected error E' . a:error.code . ' initializing language server: ' . a:error.message
|
|
||||||
call a:instance.Close()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:StartupError() dict abort
|
|
||||||
while (has_key(self, 'job') || has_key(self, 'client_id')) && !has_key(self, 'startup_error') && !has_key(self, 'serverInfo')
|
|
||||||
sleep 10m
|
|
||||||
endwhile
|
|
||||||
if has_key(self, 'serverInfo')
|
|
||||||
return ''
|
|
||||||
else
|
|
||||||
return get(self, 'startup_error', 'Something unexpected went wrong spawning the language server')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:StatusNotification(params, instance) abort
|
|
||||||
let a:instance.status = a:params
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Nop(...) abort
|
|
||||||
return v:null
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:False(...) abort
|
|
||||||
return v:false
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Progress(params, instance) abort
|
|
||||||
if has_key(a:instance.progress, a:params.token)
|
|
||||||
call a:instance.progress[a:params.token](a:params.value)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:notifications = {
|
|
||||||
\ '$/progress': function('s:Progress'),
|
|
||||||
\ 'featureFlagsNotification': function('s:Nop'),
|
|
||||||
\ 'statusNotification': function('s:StatusNotification'),
|
|
||||||
\ 'window/logMessage': function('copilot#handlers#window_logMessage'),
|
|
||||||
\ }
|
|
||||||
|
|
||||||
let s:vim_handlers = {
|
|
||||||
\ 'window/showMessageRequest': function('copilot#handlers#window_showMessageRequest'),
|
|
||||||
\ 'window/showDocument': function('copilot#handlers#window_showDocument'),
|
|
||||||
\ }
|
|
||||||
|
|
||||||
let s:vim_capabilities = {
|
|
||||||
\ 'workspace': {'workspaceFolders': v:true},
|
|
||||||
\ 'window': {'showDocument': {'support': v:true}},
|
|
||||||
\ }
|
|
||||||
|
|
||||||
function! copilot#client#New(...) abort
|
|
||||||
let opts = a:0 ? a:1 : {}
|
|
||||||
let instance = {'requests': {},
|
|
||||||
\ 'progress': {},
|
|
||||||
\ 'workspaceFolders': {},
|
|
||||||
\ 'after_initialized': [],
|
|
||||||
\ 'status': {'status': 'Starting', 'message': ''},
|
|
||||||
\ 'AfterInitialized': function('s:AfterInitialized'),
|
|
||||||
\ 'Close': function('s:Nop'),
|
|
||||||
\ 'Notify': function('s:False'),
|
|
||||||
\ 'Request': function('s:VimRequest'),
|
|
||||||
\ 'Attach': function('s:Nop'),
|
|
||||||
\ 'IsAttached': function('s:False'),
|
|
||||||
\ 'Call': function('s:Call'),
|
|
||||||
\ 'Cancel': function('s:Cancel'),
|
|
||||||
\ 'StartupError': function('s:StartupError'),
|
|
||||||
\ }
|
|
||||||
let instance.methods = copy(s:notifications)
|
|
||||||
let [node, argv, command_error] = s:Command()
|
|
||||||
if !empty(command_error)
|
|
||||||
let instance.id = -1
|
|
||||||
let instance.startup_error = command_error
|
|
||||||
call copilot#logger#Error(command_error)
|
|
||||||
return instance
|
|
||||||
endif
|
|
||||||
let instance.node = node
|
|
||||||
let command = node + argv
|
|
||||||
let opts = {}
|
|
||||||
let opts.initializationOptions = {
|
|
||||||
\ 'editorInfo': copilot#client#EditorInfo(),
|
|
||||||
\ 'editorPluginInfo': copilot#client#EditorPluginInfo(),
|
|
||||||
\ }
|
|
||||||
let opts.workspaceFolders = []
|
|
||||||
let settings = extend(copilot#client#Settings(), get(opts, 'editorConfiguration', {}))
|
|
||||||
if type(get(g:, 'copilot_workspace_folders')) == v:t_list
|
|
||||||
for folder in g:copilot_workspace_folders
|
|
||||||
if type(folder) == v:t_string && !empty(folder) && folder !~# '\*\*\|^/$'
|
|
||||||
for path in glob(folder . '/', 0, 1)
|
|
||||||
let uri = s:UriFromPath(substitute(path, '[\/]*$', '', ''))
|
|
||||||
call add(opts.workspaceFolders, {'uri': uri, 'name': fnamemodify(uri, ':t')})
|
|
||||||
endfor
|
|
||||||
elseif type(folder) == v:t_dict && has_key(v:t_dict, 'uri') && !empty(folder.uri) && has_key(folder, 'name')
|
|
||||||
call add(opts.workspaceFolders, folder)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
for folder in opts.workspaceFolders
|
|
||||||
let instance.workspaceFolders[folder.uri] = v:true
|
|
||||||
endfor
|
|
||||||
if has('nvim')
|
|
||||||
call extend(instance, {
|
|
||||||
\ 'Close': function('s:NvimClose'),
|
|
||||||
\ 'Notify': function('s:NvimNotify'),
|
|
||||||
\ 'Request': function('s:NvimRequest'),
|
|
||||||
\ 'Attach': function('s:NvimAttach'),
|
|
||||||
\ 'IsAttached': function('s:NvimIsAttached'),
|
|
||||||
\ })
|
|
||||||
let instance.client_id = eval("v:lua.require'_copilot'.lsp_start_client(command, keys(instance.methods), opts, settings)")
|
|
||||||
let instance.id = instance.client_id
|
|
||||||
else
|
|
||||||
call extend(instance, {
|
|
||||||
\ 'Close': function('s:VimClose'),
|
|
||||||
\ 'Notify': function('s:VimNotify'),
|
|
||||||
\ 'Attach': function('s:VimAttach'),
|
|
||||||
\ 'IsAttached': function('s:VimIsAttached'),
|
|
||||||
\ })
|
|
||||||
let state = {'headers': {}, 'mode': 'headers', 'buffer': ''}
|
|
||||||
let instance.open_buffers = {}
|
|
||||||
let instance.methods = extend(s:vim_handlers, instance.methods)
|
|
||||||
let instance.job = job_start(command, {
|
|
||||||
\ 'cwd': copilot#job#Cwd(),
|
|
||||||
\ 'noblock': 1,
|
|
||||||
\ 'stoponexit': '',
|
|
||||||
\ 'in_mode': 'lsp',
|
|
||||||
\ 'out_mode': 'lsp',
|
|
||||||
\ 'out_cb': { j, d -> copilot#util#Defer(function('s:OnMessage'), instance, d) },
|
|
||||||
\ 'err_cb': function('s:OnErr', [instance]),
|
|
||||||
\ 'exit_cb': { j, d -> copilot#util#Defer(function('s:OnExit'), instance, d) },
|
|
||||||
\ })
|
|
||||||
let instance.id = job_info(instance.job).process
|
|
||||||
let opts.capabilities = s:vim_capabilities
|
|
||||||
let opts.processId = getpid()
|
|
||||||
let request = instance.Request('initialize', opts, function('s:InitializeResult'), function('s:InitializeError'), instance)
|
|
||||||
call call(remove(instance.after_initialized, 0), [])
|
|
||||||
call instance.Notify('workspace/didChangeConfiguration', {'settings': settings})
|
|
||||||
endif
|
|
||||||
let s:instances[instance.id] = instance
|
|
||||||
return instance
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#Cancel(request) abort
|
|
||||||
if type(a:request) == type({}) && has_key(a:request, 'Cancel')
|
|
||||||
call a:request.Cancel()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Callback(request, type, callback, timer) abort
|
|
||||||
call remove(a:request.waiting, a:timer)
|
|
||||||
if has_key(a:request, a:type)
|
|
||||||
call a:callback(a:request[a:type])
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#Result(request, callback) abort
|
|
||||||
if has_key(a:request, 'resolve')
|
|
||||||
call add(a:request.resolve, a:callback)
|
|
||||||
elseif has_key(a:request, 'result')
|
|
||||||
let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'result', a:callback]))] = 1
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#client#Error(request, callback) abort
|
|
||||||
if has_key(a:request, 'reject')
|
|
||||||
call add(a:request.reject, a:callback)
|
|
||||||
elseif has_key(a:request, 'error')
|
|
||||||
let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', a:callback]))] = 1
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:CloseBuffer(bufnr) abort
|
|
||||||
for instance in values(s:instances)
|
|
||||||
try
|
|
||||||
if has_key(instance, 'job') && has_key(instance.open_buffers, a:bufnr)
|
|
||||||
let buffer = remove(instance.open_buffers, a:bufnr)
|
|
||||||
call instance.Notify('textDocument/didClose', {'textDocument': {'uri': buffer.uri}})
|
|
||||||
endif
|
|
||||||
catch
|
|
||||||
call copilot#logger#Exception()
|
|
||||||
endtry
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
augroup copilot_close
|
|
||||||
autocmd!
|
|
||||||
if !has('nvim')
|
|
||||||
autocmd BufUnload * call s:CloseBuffer(+expand('<abuf>'))
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
function! copilot#handlers#window_logMessage(params, ...) abort
|
|
||||||
call copilot#logger#Raw(get(a:params, 'type', 6), get(a:params, 'message', ''))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#handlers#window_showMessageRequest(params, ...) abort
|
|
||||||
let choice = inputlist([a:params.message . "\n\nRequest Actions:"] +
|
|
||||||
\ map(copy(get(a:params, 'actions', [])), { i, v -> (i + 1) . '. ' . v.title}))
|
|
||||||
return choice > 0 ? get(a:params.actions, choice - 1, v:null) : v:null
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:BrowserCallback(into, code) abort
|
|
||||||
let a:into.code = a:code
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#handlers#window_showDocument(params, ...) abort
|
|
||||||
echo a:params.uri
|
|
||||||
if empty(get(a:params, 'external'))
|
|
||||||
return {'success': v:false}
|
|
||||||
endif
|
|
||||||
let browser = copilot#Browser()
|
|
||||||
if empty(browser)
|
|
||||||
return {'success': v:false}
|
|
||||||
endif
|
|
||||||
let status = {}
|
|
||||||
call copilot#job#Stream(browser + [a:params.uri], v:null, v:null, function('s:BrowserCallback', [status]))
|
|
||||||
let time = reltime()
|
|
||||||
while empty(status) && reltimefloat(reltime(time)) < 1
|
|
||||||
sleep 10m
|
|
||||||
endwhile
|
|
||||||
return {'success': get(status, 'code') ? v:false : v:true}
|
|
||||||
endfunction
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
scriptencoding utf-8
|
|
||||||
|
|
||||||
function! copilot#job#Nop(...) abort
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Jobs(job_or_jobs) abort
|
|
||||||
let jobs = type(a:job_or_jobs) == v:t_list ? copy(a:job_or_jobs) : [a:job_or_jobs]
|
|
||||||
call map(jobs, { k, v -> type(v) == v:t_dict ? get(v, 'job', '') : v })
|
|
||||||
call filter(jobs, { k, v -> type(v) !=# type('') })
|
|
||||||
return jobs
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:job_stop = exists('*job_stop') ? 'job_stop' : 'jobstop'
|
|
||||||
function! copilot#job#Stop(job) abort
|
|
||||||
for job in s:Jobs(a:job)
|
|
||||||
call call(s:job_stop, [job])
|
|
||||||
endfor
|
|
||||||
return copilot#job#Wait(a:job)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:sleep = has('patch-8.2.2366') ? 'sleep! 1m' : 'sleep 1m'
|
|
||||||
function! copilot#job#Wait(jobs) abort
|
|
||||||
let jobs = s:Jobs(a:jobs)
|
|
||||||
if exists('*jobwait')
|
|
||||||
call jobwait(jobs)
|
|
||||||
else
|
|
||||||
for job in jobs
|
|
||||||
while ch_status(job) !=# 'closed' || job_status(job) ==# 'run'
|
|
||||||
exe s:sleep
|
|
||||||
endwhile
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
return a:jobs
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimExitCallback(result, exit_cb, job, data) abort
|
|
||||||
let a:result.exit_status = a:data
|
|
||||||
if !has_key(a:result, 'closed')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call remove(a:result, 'closed')
|
|
||||||
call a:exit_cb(a:result.exit_status)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:VimCloseCallback(result, exit_cb, job) abort
|
|
||||||
if !has_key(a:result, 'exit_status')
|
|
||||||
let a:result.closed = v:true
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call a:exit_cb(a:result.exit_status)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimCallback(cb, job, data, type) dict abort
|
|
||||||
let self[a:type][0] .= remove(a:data, 0)
|
|
||||||
call extend(self[a:type], a:data)
|
|
||||||
while len(self[a:type]) > 1
|
|
||||||
call a:cb(substitute(remove(self[a:type], 0), "\r$", '', ''))
|
|
||||||
endwhile
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NvimExitCallback(out_cb, err_cb, exit_cb, job, data, type) dict abort
|
|
||||||
if len(self.stderr[0])
|
|
||||||
call a:err_cb(substitute(self.stderr[0], "\r$", '', ''))
|
|
||||||
endif
|
|
||||||
call a:exit_cb(a:data)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#job#Cwd() abort
|
|
||||||
let home = expand("~")
|
|
||||||
if !isdirectory(home) && isdirectory($VIM)
|
|
||||||
return $VIM
|
|
||||||
endif
|
|
||||||
return home
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#job#Stream(argv, out_cb, err_cb, ...) abort
|
|
||||||
let exit_status = []
|
|
||||||
let ExitCb = function(a:0 && !empty(a:1) ? a:1 : { e -> add(exit_status, e) }, a:000[2:-1])
|
|
||||||
let OutCb = function(empty(a:out_cb) ? 'copilot#job#Nop' : a:out_cb, a:000[2:-1])
|
|
||||||
let ErrCb = function(empty(a:err_cb) ? 'copilot#job#Nop' : a:err_cb, a:000[2:-1])
|
|
||||||
let state = {'headers': {}, 'mode': 'headers', 'buffer': ''}
|
|
||||||
if exists('*job_start')
|
|
||||||
let result = {}
|
|
||||||
let job = job_start(a:argv, {
|
|
||||||
\ 'cwd': copilot#job#Cwd(),
|
|
||||||
\ 'out_mode': 'raw',
|
|
||||||
\ 'out_cb': { j, d -> OutCb(d) },
|
|
||||||
\ 'err_cb': { j, d -> ErrCb(d) },
|
|
||||||
\ 'exit_cb': function('s:VimExitCallback', [result, ExitCb]),
|
|
||||||
\ 'close_cb': function('s:VimCloseCallback', [result, ExitCb]),
|
|
||||||
\ })
|
|
||||||
else
|
|
||||||
let jopts = {
|
|
||||||
\ 'cwd': copilot#job#Cwd(),
|
|
||||||
\ 'stderr': [''],
|
|
||||||
\ 'on_stdout': { j, d, t -> OutCb(join(d, "\n")) },
|
|
||||||
\ 'on_stderr': function('s:NvimCallback', [ErrCb]),
|
|
||||||
\ 'on_exit': function('s:NvimExitCallback', [OutCb, ErrCb, ExitCb])}
|
|
||||||
let job = jobstart(a:argv, jopts)
|
|
||||||
endif
|
|
||||||
if a:0
|
|
||||||
return job
|
|
||||||
endif
|
|
||||||
call copilot#job#Wait(job)
|
|
||||||
return exit_status[0]
|
|
||||||
endfunction
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
if !exists('s:log_file')
|
|
||||||
let s:log_file = tempname() . '-copilot.log'
|
|
||||||
try
|
|
||||||
call writefile([], s:log_file)
|
|
||||||
catch
|
|
||||||
endtry
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:logs = []
|
|
||||||
|
|
||||||
function! copilot#logger#BufReadCmd() abort
|
|
||||||
try
|
|
||||||
setlocal modifiable noreadonly
|
|
||||||
silent call deletebufline('', 1, '$')
|
|
||||||
if !empty(s:logs)
|
|
||||||
call setline(1, s:logs)
|
|
||||||
endif
|
|
||||||
finally
|
|
||||||
setlocal buftype=nofile bufhidden=wipe nobuflisted nomodified nomodifiable
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:level_prefixes = ['', '[ERROR] ', '[WARN] ', '[INFO] ', '[DEBUG] ', '[DEBUG] ']
|
|
||||||
|
|
||||||
function! copilot#logger#Raw(level, message) abort
|
|
||||||
let lines = type(a:message) == v:t_list ? copy(a:message) : split(a:message, "\n", 1)
|
|
||||||
let lines[0] = strftime('[%Y-%m-%d %H:%M:%S] ') . get(s:level_prefixes, a:level, '[UNKNOWN] ') . get(lines, 0, '')
|
|
||||||
try
|
|
||||||
if !filewritable(s:log_file)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call map(lines, { k, L -> type(L) == v:t_func ? call(L, []) : L })
|
|
||||||
call extend(s:logs, lines)
|
|
||||||
let overflow = len(s:logs) - get(g:, 'copilot_log_history', 10000)
|
|
||||||
if overflow > 0
|
|
||||||
call remove(s:logs, 0, overflow - 1)
|
|
||||||
endif
|
|
||||||
let bufnr = bufnr('copilot:///log')
|
|
||||||
if bufnr > 0 && bufloaded(bufnr)
|
|
||||||
call setbufvar(bufnr, '&modifiable', 1)
|
|
||||||
call setbufline(bufnr, 1, s:logs)
|
|
||||||
call setbufvar(bufnr, '&modifiable', 0)
|
|
||||||
for winid in win_findbuf(bufnr)
|
|
||||||
if has('nvim') && winid != win_getid()
|
|
||||||
call nvim_win_set_cursor(winid, [len(s:logs), 0])
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
catch
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#logger#Debug(...) abort
|
|
||||||
if empty(get(g:, 'copilot_debug'))
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call copilot#logger#Raw(4, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#logger#Info(...) abort
|
|
||||||
call copilot#logger#Raw(3, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#logger#Warn(...) abort
|
|
||||||
call copilot#logger#Raw(2, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#logger#Error(...) abort
|
|
||||||
call copilot#logger#Raw(1, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#logger#Bare(...) abort
|
|
||||||
call copilot#logger#Raw(0, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#logger#Exception(...) abort
|
|
||||||
if !empty(v:exception) && v:exception !=# 'Vim:Interrupt'
|
|
||||||
call copilot#logger#Error('Exception: ' . v:exception . ' @ ' . v:throwpoint)
|
|
||||||
let client = copilot#RunningClient()
|
|
||||||
if !empty(client)
|
|
||||||
let [_, type, code, message; __] = matchlist(v:exception, '^\%(\(^[[:alnum:]_#]\+\)\%((\a\+)\)\=\%(\(:E-\=\d\+\)\)\=:\s*\)\=\(.*\)$')
|
|
||||||
let stacklines = []
|
|
||||||
for frame in split(substitute(v:throwpoint, ', \S\+ \(\d\+\)$', '[\1]', ''), '\.\@<!\.\.\.\@!')
|
|
||||||
let fn_line = matchlist(frame, '^\%(function \)\=\(\S\+\)\[\(\d\+\)\]$')
|
|
||||||
if !empty(fn_line)
|
|
||||||
call add(stacklines, {'function': substitute(fn_line[1], '^<SNR>\d\+_', '<SID>', ''), 'lineno': +fn_line[2]})
|
|
||||||
elseif frame =~# ' Autocmds for "\*"$'
|
|
||||||
call add(stacklines, {'function': frame})
|
|
||||||
elseif frame =~# ' Autocmds for ".*"$'
|
|
||||||
call add(stacklines, {'function': substitute(frame, ' for ".*"$', ' for "[redacted]"', '')})
|
|
||||||
else
|
|
||||||
call add(stacklines, {'function': '[redacted]'})
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return client.Request('telemetry/exception', {
|
|
||||||
\ 'transaction': a:0 ? a:1 : '',
|
|
||||||
\ 'platform': 'other',
|
|
||||||
\ 'exception_detail': [{
|
|
||||||
\ 'type': type . code,
|
|
||||||
\ 'value': message,
|
|
||||||
\ 'stacktrace': stacklines}]
|
|
||||||
\ }, v:null, function('copilot#util#Nop'))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
scriptencoding utf-8
|
|
||||||
|
|
||||||
if !exists('s:panel_id')
|
|
||||||
let s:panel_id = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:separator = repeat('─', 72)
|
|
||||||
|
|
||||||
function! s:Render(state) abort
|
|
||||||
let bufnr = bufnr('^' . a:state.panel . '$')
|
|
||||||
let state = a:state
|
|
||||||
if !bufloaded(bufnr)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let sorted = a:state.items
|
|
||||||
if !empty(get(a:state, 'error'))
|
|
||||||
let lines = ['Error: ' . a:state.error.message]
|
|
||||||
let sorted = []
|
|
||||||
elseif get(a:state, 'percentage') == 100
|
|
||||||
let lines = ['Synthesized ' . (len(sorted) == 1 ? '1 completion' : len(sorted) . ' completions')]
|
|
||||||
else
|
|
||||||
let lines = [substitute('Synthesizing ' . matchstr(get(a:state, 'message', ''), '\d\+\%(/\d\+\)\=') . ' completions', ' \+', ' ', 'g')]
|
|
||||||
endif
|
|
||||||
if len(sorted)
|
|
||||||
call add(lines, 'Press <CR> on a completion to accept')
|
|
||||||
endif
|
|
||||||
let leads = {}
|
|
||||||
for item in sorted
|
|
||||||
let insert = split(item.insertText, "\r\n\\=\\|\n", 1)
|
|
||||||
let insert[0] = strpart(a:state.line, 0, copilot#util#UTF16ToByteIdx(a:state.line, item.range.start.character)) . insert[0]
|
|
||||||
let lines += [s:separator] + insert
|
|
||||||
if !has_key(leads, string(item.range.start))
|
|
||||||
let match = insert[0 : a:state.position.line - item.range.start.line]
|
|
||||||
let match[-1] = strpart(match[-1], 0, copilot#util#UTF16ToByteIdx(match[-1], a:state.position.character))
|
|
||||||
call map(match, { k, v -> escape(v, '][^$.*\~') })
|
|
||||||
let leads[string(item.range.start)] = join(match, '\n')
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
try
|
|
||||||
call setbufvar(bufnr, '&modifiable', 1)
|
|
||||||
call setbufvar(bufnr, '&readonly', 0)
|
|
||||||
call setbufline(bufnr, 1, lines)
|
|
||||||
finally
|
|
||||||
call setbufvar(bufnr, '&modifiable', 0)
|
|
||||||
endtry
|
|
||||||
call clearmatches()
|
|
||||||
call matchadd('CopilotSuggestion', '\C^' . s:separator . '\n\zs\%(' . join(sort(values(leads), { a, b -> len(b) - len(a) }), '\|') . '\)', 10, 4)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:PartialResult(state, value) abort
|
|
||||||
let items = type(a:value) == v:t_list ? a:value : a:value.items
|
|
||||||
call extend(a:state.items, items)
|
|
||||||
call s:Render(a:state)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:WorkDone(state, value) abort
|
|
||||||
if has_key(a:value, 'message')
|
|
||||||
let a:state.message = a:value.message
|
|
||||||
endif
|
|
||||||
if has_key(a:value, 'percentage')
|
|
||||||
let a:state.percentage = a:value.percentage
|
|
||||||
call s:Render(a:state)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#panel#Accept(...) abort
|
|
||||||
let state = get(b:, 'copilot_panel', {})
|
|
||||||
if empty(state.items)
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
if !has_key(state, 'bufnr') || !bufloaded(get(state, 'bufnr', -1))
|
|
||||||
return "echoerr 'Buffer was closed'"
|
|
||||||
endif
|
|
||||||
let at = a:0 ? a:1 : line('.')
|
|
||||||
let index = 0
|
|
||||||
for lnum in range(1, at)
|
|
||||||
if getline(lnum) ==# s:separator
|
|
||||||
let index += 1
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
if index > 0 && index <= len(state.items)
|
|
||||||
let item = state.items[index - 1]
|
|
||||||
let lnum = item.range.start.line + 1
|
|
||||||
if getbufline(state.bufnr, lnum) !=# [state.line]
|
|
||||||
return 'echoerr "Buffer has changed since synthesizing completion"'
|
|
||||||
endif
|
|
||||||
let lines = split(item.insertText, "\n", 1)
|
|
||||||
let old_first = getbufline(state.bufnr, item.range.start.line + 1)[0]
|
|
||||||
let lines[0] = strpart(old_first, 0, copilot#util#UTF16ToByteIdx(old_first, item.range.start.character)) . lines[0]
|
|
||||||
let old_last = getbufline(state.bufnr, item.range.end.line + 1)[0]
|
|
||||||
let lines[-1] .= strpart(old_last, copilot#util#UTF16ToByteIdx(old_last, item.range.end.character))
|
|
||||||
call deletebufline(state.bufnr, item.range.start.line + 1, item.range.end.line + 1)
|
|
||||||
call appendbufline(state.bufnr, item.range.start.line, lines)
|
|
||||||
call copilot#Request('workspace/executeCommand', item.command)
|
|
||||||
bwipeout
|
|
||||||
let win = bufwinnr(state.bufnr)
|
|
||||||
if win > 0
|
|
||||||
exe win . 'wincmd w'
|
|
||||||
exe item.range.start.line + len(lines)
|
|
||||||
if state.was_insert
|
|
||||||
startinsert!
|
|
||||||
else
|
|
||||||
normal! $
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Initialize(state) abort
|
|
||||||
let &l:filetype = 'copilot' . (empty(a:state.filetype) ? '' : '.' . a:state.filetype)
|
|
||||||
let &l:tabstop = a:state.tabstop
|
|
||||||
nmap <buffer><script> <CR> <Cmd>exe copilot#panel#Accept()<CR>
|
|
||||||
nmap <buffer><script> [[ <Cmd>call search('^─\{9,}\n.', 'bWe')<CR>
|
|
||||||
nmap <buffer><script> ]] <Cmd>call search('^─\{9,}\n.', 'We')<CR>
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:BufReadCmd() abort
|
|
||||||
setlocal bufhidden=wipe buftype=nofile nobuflisted nomodifiable
|
|
||||||
let state = get(b:, 'copilot_panel')
|
|
||||||
if type(state) != v:t_dict
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call s:Initialize(state)
|
|
||||||
call s:Render(state)
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Result(state, result) abort
|
|
||||||
let a:state.percentage = 100
|
|
||||||
call s:PartialResult(a:state, a:result)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Error(state, error) abort
|
|
||||||
let a:state.error = a:error
|
|
||||||
call s:Render(a:state)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#panel#Open(opts) abort
|
|
||||||
let s:panel_id += 1
|
|
||||||
let state = {'items': [], 'filetype': &filetype, 'was_insert': mode() =~# '^[iR]', 'bufnr': bufnr(''), 'tabstop': &tabstop}
|
|
||||||
let state.panel = 'copilot:///panel/' . s:panel_id
|
|
||||||
if state.was_insert
|
|
||||||
let state.position = copilot#util#AppendPosition()
|
|
||||||
stopinsert
|
|
||||||
else
|
|
||||||
let state.position = {'line': a:opts.line1 >= 1 ? a:opts.line1 - 1 : 0, 'character': copilot#util#UTF16Width(getline('.'))}
|
|
||||||
endif
|
|
||||||
let state.line = getline(state.position.line + 1)
|
|
||||||
let params = {
|
|
||||||
\ 'textDocument': {'uri': state.bufnr},
|
|
||||||
\ 'position': state.position,
|
|
||||||
\ 'partialResultToken': function('s:PartialResult', [state]),
|
|
||||||
\ 'workDoneToken': function('s:WorkDone', [state]),
|
|
||||||
\ }
|
|
||||||
let response = copilot#Request('textDocument/copilotPanelCompletion', params, function('s:Result', [state]), function('s:Error', [state]))
|
|
||||||
exe substitute(a:opts.mods, '\C\<tab\>', '-tab', 'g') 'keepalt split' state.panel
|
|
||||||
let b:copilot_panel = state
|
|
||||||
call s:Initialize(state)
|
|
||||||
call s:Render(state)
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
augroup github_copilot_panel
|
|
||||||
autocmd!
|
|
||||||
autocmd BufReadCmd copilot:///panel/* exe s:BufReadCmd()
|
|
||||||
augroup END
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
let s:deferred = []
|
|
||||||
|
|
||||||
function! copilot#util#Nop(...) abort
|
|
||||||
return v:null
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#util#Defer(fn, ...) abort
|
|
||||||
call add(s:deferred, function(a:fn, a:000))
|
|
||||||
return timer_start(0, function('s:RunDeferred'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RunDeferred(...) abort
|
|
||||||
if empty(s:deferred)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let Fn = remove(s:deferred, 0)
|
|
||||||
call timer_start(0, function('s:RunDeferred'))
|
|
||||||
call call(Fn, [])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! copilot#util#UTF16Width(str) abort
|
|
||||||
return strchars(substitute(a:str, "\\%#=2[^\u0001-\uffff]", " ", 'g'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if exists('*utf16idx')
|
|
||||||
|
|
||||||
function! copilot#util#UTF16ToByteIdx(str, utf16_idx) abort
|
|
||||||
return byteidx(a:str, a:utf16_idx, 1)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
elseif has('nvim')
|
|
||||||
|
|
||||||
function! copilot#util#UTF16ToByteIdx(str, utf16_idx) abort
|
|
||||||
try
|
|
||||||
return v:lua.vim.str_byteindex(a:str, a:utf16_idx, 1)
|
|
||||||
catch /^Vim(return):E5108:/
|
|
||||||
return -1
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
function! copilot#util#UTF16ToByteIdx(str, utf16_idx) abort
|
|
||||||
if copilot#util#UTF16Width(a:str) < a:utf16_idx
|
|
||||||
return -1
|
|
||||||
endif
|
|
||||||
let end_offset = len(a:str)
|
|
||||||
while copilot#util#UTF16Width(strpart(a:str, 0, end_offset)) > a:utf16_idx && end_offset > 0
|
|
||||||
let end_offset -= 1
|
|
||||||
endwhile
|
|
||||||
return end_offset
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! copilot#util#AppendPosition() abort
|
|
||||||
let line = getline('.')
|
|
||||||
let col_byte = col('.') - (mode() =~# '^[iR]' || empty(line))
|
|
||||||
let col_utf16 = copilot#util#UTF16Width(strpart(line, 0, col_byte))
|
|
||||||
return {'line': line('.') - 1, 'character': col_utf16}
|
|
||||||
endfunction
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
function! copilot#version#String() abort
|
|
||||||
return '1.41.0'
|
|
||||||
endfunction
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.vim/pack/plugins/opt/vim-copilot/dist/crypt32.node
vendored
BIN
.vim/pack/plugins/opt/vim-copilot/dist/crypt32.node
vendored
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user