Compare commits
96 Commits
d49eb5d52f
...
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 | ||
|
|
d0c4c84117 | ||
|
|
4ec4facf23 |
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
85
.bin/aria
Executable file
85
.bin/aria
Executable file
@@ -0,0 +1,85 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
DIR="/home/sdk/.aria2"
|
||||||
|
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 $@
|
||||||
|
do
|
||||||
|
case $cmd in
|
||||||
|
seed|upload|up)
|
||||||
|
OPTS="$OPTS
|
||||||
|
--seed-ratio=0.0
|
||||||
|
--max-overall-upload-limit=5M
|
||||||
|
--max-overall-download-limit=200K
|
||||||
|
--check-integrity=true
|
||||||
|
--bt-hash-check-seed=true
|
||||||
|
--bt-seed-unverified=true
|
||||||
|
-j 100
|
||||||
|
"
|
||||||
|
shift ;;
|
||||||
|
download|dl)
|
||||||
|
OPTS="$OPTS
|
||||||
|
--max-overall-upload-limit=200K
|
||||||
|
--max-overall-download-limit=85M
|
||||||
|
--seed-time=0
|
||||||
|
--lowest-speed-limit=30K
|
||||||
|
--bt-request-peer-speed-limit=100K
|
||||||
|
--file-allocation=trunc
|
||||||
|
-j 6
|
||||||
|
"
|
||||||
|
shift ;;
|
||||||
|
overwrite|force)
|
||||||
|
OPTS="$OPTS
|
||||||
|
--allow-overwrite=true
|
||||||
|
"
|
||||||
|
shift ;;
|
||||||
|
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 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
set -x
|
||||||
|
if [ -z "$@" ]
|
||||||
|
then
|
||||||
|
aria2c $DEFAULT $OPTS $SECOPTS *.torrent
|
||||||
|
else
|
||||||
|
aria2c $DEFAULT $OPTS $SECOPTS "$@"
|
||||||
|
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
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/ksh
|
#!/bin/ksh
|
||||||
|
|
||||||
FILE="$HOME/.ksh.complete"
|
FILE="$HOME/.kshrc.autocomplete"
|
||||||
|
|
||||||
rm -f "${FILE}"
|
rm -f "${FILE}"
|
||||||
|
|
||||||
@@ -37,12 +37,27 @@ add "set -A complete_kill_1 -- " "-9 -HUP -INFO -KILL -TERM"
|
|||||||
#
|
#
|
||||||
add "set -A complete_ifconfig_1 -- " "$(ifconfig | grep ^[a-z] | cut -d: -f1)"
|
add "set -A complete_ifconfig_1 -- " "$(ifconfig | grep ^[a-z] | cut -d: -f1)"
|
||||||
|
|
||||||
|
#
|
||||||
|
# manpages
|
||||||
|
#
|
||||||
|
S1="$(man -s 1 -k any= | cut -d"(" -f1 | tr -d "," | xargs)"
|
||||||
|
S2="$(man -s 2 -k any= | cut -d"(" -f1 | tr -d "," | xargs)"
|
||||||
|
S3="$(man -s 3 -k any= | cut -d"(" -f1 | tr -d "," | xargs)"
|
||||||
|
S4="$(man -s 4 -k any= | cut -d"(" -f1 | tr -d "," | xargs)"
|
||||||
|
S5="$(man -s 5 -k any= | cut -d"(" -f1 | tr -d "," | xargs)"
|
||||||
|
S8="$(man -s 8 -k any= | cut -d"(" -f1 | tr -d "," | xargs)"
|
||||||
|
add "set -A complete_man_1 -- " "$S1 $S5 $S8"
|
||||||
|
|
||||||
#
|
#
|
||||||
# AMUSED
|
# AMUSED
|
||||||
#
|
#
|
||||||
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
|
||||||
274
.bin/upload
274
.bin/upload
@@ -1,25 +1,267 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
file="$1"
|
# manage files in a webroot
|
||||||
|
# needs:
|
||||||
|
# - sh: cp, rm, mv, echo, basename, dirname
|
||||||
|
# - openssh: ssh, scp
|
||||||
|
# - coreutils: chmod, sed, tail
|
||||||
|
# - archivers: gzip, tar
|
||||||
|
# - xclip
|
||||||
|
|
||||||
[ -z $file ] \
|
###
|
||||||
&& file="$(find $PWD $HOME $HOME/Downloads -maxdepth 2 -type f \
|
### CONFIGURATION
|
||||||
| fgrep -v "/." \
|
###
|
||||||
| sort -u \
|
|
||||||
| fzf -e -x -i)"
|
|
||||||
|
|
||||||
[ -z $file ] \
|
# remote patch uploaded files should go
|
||||||
&& exit 0
|
_rpath="/home/www/htdocs/ptrace/paste"
|
||||||
|
|
||||||
scp "$file" \
|
# web url where the uploaded files can be accessed
|
||||||
sdk@home.codevoid.de:make-web/src/paste/
|
_weburi="https://ptrace.org"
|
||||||
|
|
||||||
ssh sdk@home.codevoid.de \
|
# ssh user@host
|
||||||
"cd ~/make-web && make install"
|
_sshhost="sdk@codevoid.de"
|
||||||
|
|
||||||
echo "https://ptrace.org/$(basename "$file")" \
|
# permissions (for the fixl command)
|
||||||
| sed 's/ /%20/g' \
|
_chown="sdk:www"
|
||||||
| xclip -f -r
|
_chmod="u+rw,g+r"
|
||||||
|
|
||||||
echo
|
###
|
||||||
|
### 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
fname="$1"
|
||||||
|
[ -z "$fname" ] \
|
||||||
|
&& fname="$(date +"%Y-%m-%d_%H%M%S").txt"
|
||||||
|
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
|
||||||
|
# the whole handling shall run in a subshell so all variables
|
||||||
|
# are reset when we leave the scope. Note, that this requires
|
||||||
|
# us to "return", instead of "continue" skip to the next loop
|
||||||
|
# iteration
|
||||||
|
(
|
||||||
|
[ ! -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
|
||||||
|
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
|
||||||
|
|||||||
124
.kshrc
124
.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
|
||||||
@@ -107,7 +107,7 @@ set bell-style none
|
|||||||
# LOAD COMPLETION FILE
|
# LOAD COMPLETION FILE
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
[ -f ~/.ksh.complete ] && . ~/.ksh.complete
|
[ -f ~/.kshrc.autocomplete ] && . ~/.kshrc.autocomplete
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# PROMPT
|
# PROMPT
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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/portpatch2.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,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.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user