Compare commits
94 Commits
d0c4c84117
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
832cfe42c3 | ||
|
|
bf213e469f | ||
|
|
0bd8a43d4f | ||
|
|
186dfa8096 | ||
|
|
0769d7a789 | ||
|
|
4dfd87462c | ||
|
|
1cc3015bb5 | ||
|
|
a3954fb9dc | ||
|
|
a074d5b67d | ||
|
|
ff04acca3a | ||
|
|
6028f3a023 | ||
|
|
9764ad6f1f | ||
|
|
72850600e5 | ||
|
|
0d3de71e2c | ||
|
|
d318a58bb0 | ||
|
|
299a3c8b51 | ||
|
|
6a3fe358f3 | ||
|
|
a0d78823ae | ||
|
|
8f37eceb9a | ||
|
|
0530d9228b | ||
|
|
15b0116633 | ||
|
|
6bbb12e7b3 | ||
|
|
1a2d91b0d7 | ||
|
|
13bedaa7d3 | ||
|
|
3b839841ac | ||
|
|
9f365fe933 | ||
|
|
62d5edaf29 | ||
|
|
1371b1c8a2 | ||
|
|
e900fc1f35 | ||
|
|
ed8624ef01 | ||
|
|
475bef8131 | ||
|
|
3794862593 | ||
|
|
8bce1b28b3 | ||
|
|
7fc3348d20 | ||
|
|
068de67638 | ||
|
|
00f804c99f | ||
|
|
ee9207d716 | ||
|
|
3c6adda31b | ||
|
|
7a70f07a67 | ||
|
|
33471962fb | ||
|
|
cc3afde694 | ||
|
|
685a3b4c8d | ||
|
|
b0cc6ce138 | ||
|
|
a992796635 | ||
|
|
20f3483f9c | ||
|
|
87a300f0c4 | ||
|
|
908090c41b | ||
|
|
5f346e4848 | ||
|
|
45969796dc | ||
|
|
fa6a52b1a3 | ||
|
|
02239e52a3 | ||
|
|
767ba27c2b | ||
|
|
08aaf050a6 | ||
|
|
1c9a2b446a | ||
|
|
6b2b5ae779 | ||
|
|
d8fff6ec32 | ||
|
|
26abaf99b2 | ||
|
|
0bda01c32e | ||
|
|
6db769365d | ||
|
|
9f55042b33 | ||
|
|
9ffce7022e | ||
|
|
7c5d1f298f | ||
|
|
3768436e21 | ||
|
|
8d1878581b | ||
|
|
e9581ec17d | ||
|
|
7eb3f826fb | ||
|
|
2357c34813 | ||
|
|
1f15f715a6 | ||
|
|
346463127c | ||
|
|
3e58a36599 | ||
|
|
6a240c970c | ||
|
|
e548ab67c8 | ||
|
|
b86b992a6a | ||
|
|
31c62ae69a | ||
|
|
ec7fbad49f | ||
|
|
1bb57985ca | ||
|
|
ac58f6baa9 | ||
|
|
b2c7bcd12a | ||
|
|
e2edc9d2b6 | ||
|
|
70c63ad427 | ||
|
|
ae5183fa58 | ||
|
|
19fc60ef8b | ||
|
|
0701e19f1e | ||
|
|
1ecd621a69 | ||
|
|
b3b69a682a | ||
|
|
180588879c | ||
|
|
0582999ac9 | ||
|
|
fa50579054 | ||
|
|
e27a96f17e | ||
|
|
ebae25d46e | ||
|
|
a145968b49 | ||
|
|
7948d7cd1d | ||
|
|
e304b53c34 | ||
|
|
2e1234e383 |
@@ -1,7 +1,6 @@
|
||||
! -- CURSOR --!
|
||||
!Xcursor.size: 32
|
||||
Xcursor.size: 32
|
||||
Xcursor.theme:
|
||||
Xcursor.size: 48
|
||||
Xcursor.theme: Adwaita
|
||||
xterm.cursorTheme:
|
||||
|
||||
! -- 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"
|
||||
done
|
||||
[ ! -z "$add" ] \
|
||||
&& doas pkg_add -- $add
|
||||
&& doas pkg_add -- $add \
|
||||
|| true
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
70
.bin/aria
70
.bin/aria
@@ -3,6 +3,35 @@
|
||||
DIR="/home/sdk/.aria2"
|
||||
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
|
||||
@@ -10,7 +39,7 @@ do
|
||||
OPTS="$OPTS
|
||||
--seed-ratio=0.0
|
||||
--max-overall-upload-limit=5M
|
||||
--max-overall-download-limit=1
|
||||
--max-overall-download-limit=200K
|
||||
--check-integrity=true
|
||||
--bt-hash-check-seed=true
|
||||
--bt-seed-unverified=true
|
||||
@@ -19,7 +48,7 @@ do
|
||||
shift ;;
|
||||
download|dl)
|
||||
OPTS="$OPTS
|
||||
--max-overall-upload-limit=1
|
||||
--max-overall-upload-limit=200K
|
||||
--max-overall-download-limit=85M
|
||||
--seed-time=0
|
||||
--lowest-speed-limit=30K
|
||||
@@ -28,36 +57,29 @@ do
|
||||
-j 6
|
||||
"
|
||||
shift ;;
|
||||
overwrite|over|force)
|
||||
overwrite|force)
|
||||
OPTS="$OPTS
|
||||
--allow-overwrite=true"
|
||||
--allow-overwrite=true
|
||||
"
|
||||
shift ;;
|
||||
1) OPTS="$OPTS -j 1"
|
||||
enc|encrypt) OPTS="$OPTS
|
||||
--bt-require-crypto
|
||||
--bt-min-crypto-level=arc4
|
||||
"
|
||||
shift ;;
|
||||
pub|public) SECOPTS="$PUBLIC"
|
||||
shift ;;
|
||||
seq|1) OPTS="$OPTS
|
||||
-j 1 -Z
|
||||
"
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
DEFAULT="\
|
||||
--enable-dht=false
|
||||
--enable-dht6=false
|
||||
--bt-force-encryption=true
|
||||
--enable-peer-exchange=false
|
||||
--auto-save-interval=30
|
||||
--save-session-interval=30
|
||||
--bt-enable-lpd=false
|
||||
--bt-save-metadata=true
|
||||
--bt-load-saved-metadata=true
|
||||
--bt-prioritize-piece=head=10M,tail=10M
|
||||
--log=$DIR/aria2.log
|
||||
--dht-file-path=$DIR/dht.dat
|
||||
--dht-file-path6=$DIR/dht6.dat
|
||||
--save-cookies=$DIR/cookies.dat
|
||||
--save-session=$DIR/session.dat
|
||||
"
|
||||
set -x
|
||||
if [ -z "$@" ]
|
||||
then
|
||||
aria2c $DEFAULT $OPTS *.torrent
|
||||
aria2c $DEFAULT $OPTS $SECOPTS *.torrent
|
||||
else
|
||||
aria2c $DEFAULT $OPTS "$@"
|
||||
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
|
||||
#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
|
||||
#/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 \
|
||||
# --disable-auto-reload \
|
||||
# --disable-breakpad \
|
||||
# --disable-client-side-phishing-detection \
|
||||
# --disable-component-cloud-policy \
|
||||
# --disable-component-update \
|
||||
# --disable-crash-reporter \
|
||||
# --disable-device-discovery-notifications \
|
||||
# --disable-logging \
|
||||
# --disable-login-animations \
|
||||
# --disable-notifications \
|
||||
# --disable-pinch \
|
||||
# --disable-software-rasterizer \
|
||||
# --disable-chrome-browser-cloud-management \
|
||||
# --disable-field-trial-config \
|
||||
# --disable-cookie-encryption \
|
||||
# --disable-cloud-print-proxy \
|
||||
# --dbus-stub \
|
||||
# --cros-disks-fake \
|
||||
# --disable-stack-profiler \
|
||||
# --disable-touch-drag-drop \
|
||||
# --disable-usb-keyboard-detect \
|
||||
# --disable-default-apps \
|
||||
# --disable-histogram-customizer \
|
||||
# --disable-in-process-stack-traces \
|
||||
# --no-service-autorun \
|
||||
# --no-experiments \
|
||||
# --use-gl=egl \
|
||||
# --force-dark-mode \
|
||||
# --enable-features=WebUIDarkMode \
|
||||
# --hide-crash-restore-bubble \
|
||||
# --no-default-browser-check \
|
||||
# --no-proxy-server \
|
||||
# --no-recovery-component \
|
||||
# --password-store=basic \
|
||||
# --structured-metrics-disabled \
|
||||
# --wm-window-animations-disabled \
|
||||
# #--enable-features=RunVideoCaptureServiceInBrowserProcess,WebUIDarkMode \
|
||||
# #--use-gl=egl \
|
||||
# --disable-yuv-image-decoding \
|
||||
# --use-gl=desktop \
|
||||
# --high-dpi-support=1 \
|
||||
# --force-device-scale-factor=1.5 \
|
||||
# flag documentation:
|
||||
# https://peter.sh/experiments/chromium-command-line-switches/
|
||||
|
||||
# helper functions
|
||||
addflag() { FLAGS="$FLAGS $1"; }
|
||||
enable() { ENABLED_FEATURES="$ENABLED_FEATURES $1"; }
|
||||
disable() { DISABLED_FEATURES="$DISABLED_FEATURES $1"; }
|
||||
|
||||
###
|
||||
### SETUP ENVIRONMENT
|
||||
###
|
||||
|
||||
# disable WASM (OpenBSD specific)
|
||||
#export ENABLE_WASM=0
|
||||
|
||||
# Nuke DBUS
|
||||
# some webpages suggest value "disabled:"
|
||||
export DBUS_SESSION_BUS_ADDRESS="unix:path=/dev/null"
|
||||
|
||||
###
|
||||
### CHROMIUM FLAGS
|
||||
###
|
||||
|
||||
# disable pledge (OpenBSD specific)
|
||||
#addflag "--no-sandbox"
|
||||
|
||||
# disable unveil (OpenBSD specific)
|
||||
#addflag "--disable-unveil"
|
||||
|
||||
# Skip First Run tasks as well as not showing additional dialogs,
|
||||
# prompts or bubbles. Suppressing dialogs, prompts, and bubbles is
|
||||
# important as this switch is used by automation (including performance
|
||||
# benchmarks) where it's important only a browser window is shown. This
|
||||
# may not actually be the first run or the What's New page. Overridden
|
||||
# by kForceFirstRun (for FRE) and kForceWhatsNew (for What's New). This
|
||||
# does not drop the First Run sentinel and thus doesn't prevent first run
|
||||
# from occurring the next time chrome is launched without this flag. It
|
||||
# also does not update the last What's New milestone, so does not prevent
|
||||
# What's New from occurring the next time chrome is launched without this
|
||||
# flag.
|
||||
addflag "--no-first-run"
|
||||
|
||||
# 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() {
|
||||
local S=$( { echo "paste_from_clipboard"; tail -r ${HISTFILE}; } \
|
||||
| awk '!seen[$0]++' \
|
||||
| ${DMENU_CMD} -p "Bookmarks" -l 20)
|
||||
| ${DMENU_CMD} -p "Bookmarks")
|
||||
|
||||
case "${S}" in
|
||||
paste_from_clipboard) S=$(xclip -o | head -n 1); ;;
|
||||
@@ -91,7 +91,7 @@ Zalando"
|
||||
esac
|
||||
|
||||
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')
|
||||
case "${S}" in
|
||||
OPEN*) URI="${C}"; ;;
|
||||
@@ -136,7 +136,12 @@ choose_browser() {
|
||||
gopher://*) DEFAULT="Lagrange (default)"; ;;
|
||||
gemini://*) DEFAULT="Lagrange (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)"; ;;
|
||||
*.pdf|*.cb|*.ps) DEFAULT="Zathura (default)"; ;;
|
||||
*.mp4|*.m4v|*.mkv) DEFAULT="Mpv (default)"; ;;
|
||||
@@ -151,7 +156,7 @@ choose_browser() {
|
||||
[Qq]uteb*r*) BROWSER="qutebrowser -R" ;;
|
||||
[Ss]urf*) BROWSER=surf ;;
|
||||
[Oo]tter*r*) BROWSER=otter-browser ;;
|
||||
[Ll]uakit*) BROWSER="luakit -Un" ;;
|
||||
[Ll]uakit*) BROWSER="luakit -v -U" ;;
|
||||
[Cc]hrome*) BROWSER=chrome ;;
|
||||
[Ff]irefox*) BROWSER=firefox ;;
|
||||
[Tt]or-B*r*) BROWSER=tor-browser ;;
|
||||
@@ -170,6 +175,6 @@ save_history() {
|
||||
# main program starts here.
|
||||
read_input
|
||||
choose_wrapper
|
||||
# choose_browser
|
||||
#choose_browser
|
||||
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
|
||||
export XDG_CACHE_HOME=/tmp firefox
|
||||
export XDG_CACHE_HOME=/tmp
|
||||
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 "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 "Creating FAT32 file system (this may take a while)...\n"
|
||||
newfs_msdos -F32 -b65536 "${_dev}i"
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
find "${PWD}/"* -type f \
|
||||
find "${_wrkdir}/"* -type f \
|
||||
\( -iname "*.c" \
|
||||
-o -iname "*.cc" \
|
||||
-o -iname "*.cpp" \
|
||||
@@ -17,7 +68,7 @@ find "${PWD}/"* -type f \
|
||||
-o -iname "*.pl" \
|
||||
-o -iname "*.sh" \
|
||||
-o -name "Makefile" \
|
||||
\) > ${PWD}/.git/files
|
||||
\) > ${_wrkdir}/${_tagdir}/files
|
||||
|
||||
# include extra directories
|
||||
if [ ! -z "$1" ]
|
||||
@@ -36,11 +87,11 @@ then
|
||||
-o -iname "*.pl" \
|
||||
-o -iname "*.sh" \
|
||||
-o -name "Makefile" \
|
||||
\) >> ${PWD}/.git/files
|
||||
\) >> ${_wrkdir}/${_tagdir}/files
|
||||
fi
|
||||
|
||||
# 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
|
||||
ectags --sort=yes \
|
||||
@@ -50,6 +101,6 @@ ectags --sort=yes \
|
||||
--fields=+K \
|
||||
--totals=yes \
|
||||
--fields=fkst \
|
||||
--exclude=.git \
|
||||
-L ${PWD}/.git/files \
|
||||
-f ${PWD}/.git/tags
|
||||
--exclude=${_tagdir} \
|
||||
-L ${_wrkdir}/${_tagdir}/files \
|
||||
-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
|
||||
|
||||
if mount | fgrep '/tank/' -q
|
||||
if mount | fgrep -q '/tank/'
|
||||
then
|
||||
echo "already mounted"
|
||||
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"; ;;
|
||||
mp3) EXEC="mpv"; ;;
|
||||
mp4) EXEC="mpv"; ;;
|
||||
pdf) EXEC="zathura"; ;;
|
||||
out) EXEC="kdump -RTf"; ;;
|
||||
sid) EXEC="sidplay"; ;;
|
||||
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; }
|
||||
|
||||
JOBS="${JOBS:=$(sysctl -n hw.ncpuonline)}"
|
||||
JOBS=1
|
||||
|
||||
LOG="/home/sdk/obsdmake.log"
|
||||
|
||||
export CCACHE_DIR="/var/ccache"
|
||||
export CCACHE_SLOPPINESS="locale,time_macros,random_seed,file_stat_matches,pch_defines"
|
||||
@@ -24,12 +27,13 @@ if [ -z "$1" ]; then
|
||||
exit 2
|
||||
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 chown build /usr/obj /usr/xobj
|
||||
|
||||
mkkernel() {
|
||||
echo "Step: kernel start ($(date))" >> $LOG
|
||||
set -xe
|
||||
cd /sys/arch/$(machine)/compile/GENERIC.MP
|
||||
doas make clean
|
||||
@@ -39,9 +43,11 @@ mkkernel() {
|
||||
doas make install
|
||||
doas what /bsd
|
||||
doas ln -f /bsd.booted /bsd.backup
|
||||
echo "Step: kernel done ($(date))" >> $LOG
|
||||
}
|
||||
|
||||
mkbase() {
|
||||
echo "Step: base start ($(date))" >> $LOG
|
||||
set -xe
|
||||
cd /usr/src
|
||||
doas make obj
|
||||
@@ -50,9 +56,11 @@ mkbase() {
|
||||
doas sysmerge
|
||||
cd /dev
|
||||
doas ./MAKEDEV all
|
||||
echo "Step: base done ($(date))" >> $LOG
|
||||
}
|
||||
|
||||
mkxenocara() {
|
||||
echo "Step: xenocara start ($(date))" >> $LOG
|
||||
set -xe
|
||||
doas chown -R sdk /usr/xenocara
|
||||
cd /usr/xenocara
|
||||
@@ -61,9 +69,11 @@ mkxenocara() {
|
||||
doas make obj
|
||||
doas make -j${JOBS} build
|
||||
doas make install
|
||||
echo "Step: xenocara done ($(date))" >> $LOG
|
||||
}
|
||||
|
||||
mkrelease() {
|
||||
echo "Step: release start ($(date))" >> $LOG
|
||||
set -xe
|
||||
doas mkdir -p /data/{OpenBSD,Release}
|
||||
doas chown -R build /data
|
||||
@@ -86,6 +96,7 @@ mkrelease() {
|
||||
cd /usr/src/distrib/$(machine)/iso
|
||||
doas make
|
||||
doas make install
|
||||
echo "Step: release done ($(date))" >> $LOG
|
||||
}
|
||||
|
||||
kernelclean() {
|
||||
@@ -127,5 +138,5 @@ case "$1" in
|
||||
all) mkkernel; mkbase; mkxenocara; ;;
|
||||
esac
|
||||
|
||||
echo "Finished with >$0 $ARGS< on $(date)" >> /tmp/obsdmake.log
|
||||
echo "Finished with >$0 $ARGS< on $(date)" >> $LOG
|
||||
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
|
||||
|
||||
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
|
||||
doas make fix-permissions
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -x
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "usage: port-search <file pattern> <search term>"
|
||||
echo "usage: port-search [file pattern] <search term>"
|
||||
exit 2
|
||||
fi
|
||||
type="$1"
|
||||
shift
|
||||
if [ -n "$2" ]
|
||||
then
|
||||
_filter="-iname *$1*" \
|
||||
_term="$2"
|
||||
else
|
||||
_term="$1"
|
||||
fi
|
||||
|
||||
find /usr/ports/ \
|
||||
-not \( -path "/usr/ports/pobj" -prune \
|
||||
@@ -16,5 +21,5 @@ find /usr/ports/ \
|
||||
-o -path "*/CVS" -prune \
|
||||
\) \
|
||||
-type f \
|
||||
-iname "$type" \
|
||||
-exec ugrep -F -- "$@" {} +
|
||||
$_filter \
|
||||
-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
|
||||
[ -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
|
||||
|
||||
unset QT_FONT_DPI
|
||||
unset GDK_DPI_SCALE
|
||||
|
||||
trap cleanup 1 2 3 6
|
||||
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
|
||||
. $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:"
|
||||
|
||||
_target=$(readlink -f "$1")
|
||||
_key=$(pwgen -n1 8)
|
||||
_date=$(date "+%Y-%m-%d %H:%M")
|
||||
_host=$(uname -n)
|
||||
|
||||
doas tarsnap --humanize-numbers --checkpoint-bytes 52428800 --exclude "*/.git/*" -cvf "$_host: $_target $_date ($_key)" "$_target"
|
||||
doas tarsnap --humanize-numbers --checkpoint-bytes 52428800 --exclude "*/.git/*" -cvf "$_host: $_target $_date ($_key)" "$_target"
|
||||
|
||||
38
.bin/tarsnap-restore
Executable file
38
.bin/tarsnap-restore
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
. $HOME/.bin/_config
|
||||
|
||||
print "Tarsnap Restore:"
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
doas tarsnap --list-archives | sort
|
||||
printf "Usage: restore <key_id>\n"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
_backup="$(doas tarsnap --list-archives | grep "$1")"
|
||||
if [ -z "$_backup" ]; then
|
||||
print "No backup with key id $1 found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print "Found Backup: $_backup"
|
||||
mkdir -p "restore_$1"
|
||||
print "Extracting to: $(readlink -f $PWD/restore_$1)"
|
||||
|
||||
if [ -f "restore_$1/.done" ]
|
||||
then
|
||||
print "Skipping, because restore_$1/.done file exists."
|
||||
else
|
||||
doas tarsnap -tf "$_backup" \
|
||||
| xargs -P 50 -n 1 -t \
|
||||
doas tarsnap --humanize-numbers --resume-extract --chroot -xf "$_backup" -C "restore_$1" --
|
||||
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
print "Data restored in $(readlink -f "restore_$1")"
|
||||
touch "restore_$1/.done"
|
||||
else
|
||||
print "Restore aborted..."
|
||||
fi
|
||||
fi
|
||||
print ""
|
||||
10
.bin/umount-cryptoffs
Executable file
10
.bin/umount-cryptoffs
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
_dev=${1:-sd3}
|
||||
doas umount /mnt 2>&1 | grep -q busy && echo "/mnt is busy" && exit 1
|
||||
_biodev=$(doas bioctl softraid0 | grep -C1 sd3 | grep CRYPTO | awk '{ print $5 }')
|
||||
if [ -n "$_biodev" ]
|
||||
then
|
||||
doas bioctl -d ${_biodev} && echo "bioctl: $_dev detached"
|
||||
else
|
||||
echo "bioctl: $_dev: currently not attached"
|
||||
fi
|
||||
137
.bin/update-adlist
Executable file
137
.bin/update-adlist
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/bin/sh -e
|
||||
trap _restore_all 1 2 3 6
|
||||
|
||||
# list of filenames can can be fetched from $_url
|
||||
_list=/etc/unwind/blocklistproject.txt
|
||||
_url=https://blocklistproject.github.io/Lists/alt-version
|
||||
|
||||
# download blocklists here
|
||||
_dir=/etc/unwind/lists
|
||||
|
||||
# combined, sorted and filtered list of all lists configured in $_list
|
||||
# configure in /etc/unwind.conf:
|
||||
# block list "/etc/unwind/_assembled.txt" log
|
||||
_unwind_blocklist="/etc/unwind/_assembled.txt"
|
||||
|
||||
if [ ! -f $_list ]
|
||||
then
|
||||
echo "Creating new adlist /etc/unwind/blocklistproject.txt:"
|
||||
doas mkdir -p $_dir
|
||||
doas tee $_list <<EOF
|
||||
## from https://github.com/blocklistproject/Lists
|
||||
## ## => comment
|
||||
## # => disabled list (will be deleted if present)
|
||||
abuse-nl.txt
|
||||
adobe-nl.txt
|
||||
ads-nl.txt
|
||||
basic-nl.txt
|
||||
crypto-nl.txt
|
||||
drugs-nl.txt
|
||||
#everything-nl.txt
|
||||
facebook-nl.txt
|
||||
fortnite-nl.txt
|
||||
fraud-nl.txt
|
||||
gambling-nl.txt
|
||||
malware-nl.txt
|
||||
phishing-nl.txt
|
||||
piracy-nl.txt
|
||||
porn-nl.txt
|
||||
ransomware-nl.txt
|
||||
redirect-nl.txt
|
||||
scam-nl.txt
|
||||
smart-tv-nl.txt
|
||||
tiktok-nl.txt
|
||||
torrent-nl.txt
|
||||
tracking-nl.txt
|
||||
twitter-nl.txt
|
||||
vaping-nl.txt
|
||||
whatsapp-nl.txt
|
||||
youtube-nl.txt
|
||||
EOF
|
||||
fi
|
||||
|
||||
_restore_all() {
|
||||
echo "Signal received, aborting..."
|
||||
for _f in $_dir/*.old
|
||||
do
|
||||
echo "Restore: $(basename $_f)"
|
||||
doas mv -f "$_f" "${_f%%.old}"
|
||||
done
|
||||
_assemble
|
||||
_restart_unwind
|
||||
exit 1
|
||||
}
|
||||
|
||||
_backup() {
|
||||
_f=$(basename "$1")
|
||||
if [ -f "$_dir/$_f" ]
|
||||
then
|
||||
echo "Backup: $_f -> $_f.old"
|
||||
doas mv -f "$_dir/$_f" "$_dir/$_f.old"
|
||||
fi
|
||||
}
|
||||
|
||||
_restore() {
|
||||
_f=$(basename "$1")
|
||||
if [ -f "$_dir/$_f.old" ]
|
||||
then
|
||||
echo "Restore: $_f.old -> $_f"
|
||||
doas mv -f "$_dir/$_f" "$_dir/$_f.old"
|
||||
fi
|
||||
}
|
||||
|
||||
_download() {
|
||||
echo "Download: $_file"
|
||||
doas ftp -V -o "$_dir/$_file" "$_url/$_file" > /dev/null \
|
||||
&& doas rm -f "$_dir/$_file.old"
|
||||
}
|
||||
|
||||
_disabled() {
|
||||
if echo "$1" | grep -q "^#"
|
||||
then
|
||||
_f=$(basename "$1" | tr -d '# ')
|
||||
echo "Skip (disabled): $_f"
|
||||
doas rm -f $_dir/$_f
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
_domainfilter() {
|
||||
# chain grep commands used in assemble pipe
|
||||
grep -Ev "torrent|tattoo|xhamster|xvideos|porn|motherless|redgifs" \
|
||||
| grep -Ev "whatsapp\.net|whatsapp\.com|instagram\.com" \
|
||||
| grep -Ev "adobe\.com|adobelogin\.com" \
|
||||
| grep -Ev "microsoft\.com|archive\.org|sony\.com|playstation|psn|fotostelvio"
|
||||
}
|
||||
|
||||
_assemble() {
|
||||
echo "Assemble blocklist: $_unwind_blocklist"
|
||||
cat $_dir/*.txt \
|
||||
| tr -d " " \
|
||||
| grep -v '^#' \
|
||||
| grep -v '^-' \
|
||||
| grep -v '^$' \
|
||||
| cut -d "#" -f1 \
|
||||
| sed 's/\.$//g' \
|
||||
| _domainfilter \
|
||||
| doas sort -uo $_unwind_blocklist
|
||||
}
|
||||
|
||||
_restart_unwind() {
|
||||
doas rcctl restart unwind
|
||||
}
|
||||
|
||||
|
||||
for _file in $(grep -v "^##" $_list \
|
||||
| cut -d "#" -f1 \
|
||||
| xargs)
|
||||
do
|
||||
if ! _disabled $_file
|
||||
then
|
||||
_backup $_file
|
||||
_download || _restore
|
||||
fi
|
||||
done
|
||||
_assemble
|
||||
_restart_unwind
|
||||
@@ -54,6 +54,10 @@ add "set -A complete_man_1 -- " "$S1 $S5 $S8"
|
||||
ARGS="add flush jump load monitor next pause play prev repeat restart show status stop toggle"
|
||||
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
|
||||
#
|
||||
|
||||
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
|
||||
275
.bin/upload
275
.bin/upload
@@ -1,24 +1,267 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
if [ x"$1" == x"rm" ]
|
||||
then
|
||||
shift
|
||||
for file in $@
|
||||
# manage files in a webroot
|
||||
# needs:
|
||||
# - sh: cp, rm, mv, echo, basename, dirname
|
||||
# - openssh: ssh, scp
|
||||
# - coreutils: chmod, sed, tail
|
||||
# - archivers: gzip, tar
|
||||
# - xclip
|
||||
|
||||
###
|
||||
### CONFIGURATION
|
||||
###
|
||||
|
||||
# remote patch uploaded files should go
|
||||
_rpath="/home/www/htdocs/ptrace/paste"
|
||||
|
||||
# web url where the uploaded files can be accessed
|
||||
_weburi="https://ptrace.org"
|
||||
|
||||
# ssh user@host
|
||||
_sshhost="sdk@codevoid.de"
|
||||
|
||||
# permissions (for the fixl command)
|
||||
_chown="sdk:www"
|
||||
_chmod="u+rw,g+r"
|
||||
|
||||
###
|
||||
### SET ARGUMENT SWITCHES
|
||||
###
|
||||
|
||||
for arg in "$@"
|
||||
do
|
||||
case "$arg" in
|
||||
# extensions
|
||||
sh) _ext=".sh" ;;
|
||||
ksh) _ext=".ksh" ;;
|
||||
txt) _ext=".txt" ;;
|
||||
log) _ext=".log" ;;
|
||||
# archive mode
|
||||
gz) _gz=1 ;;
|
||||
tgz) _tgz=1 ;;
|
||||
# commands
|
||||
rm) _rm=1 ;;
|
||||
rml) _rmlast=1 ;;
|
||||
ls) _ls=1 ;;
|
||||
l|last) _last="-1" ;;
|
||||
-[0-9]*) _last="$arg" ;;
|
||||
fixl) _fixperm=1 ;;
|
||||
ren|mv) _mv=1 ;;
|
||||
renl|mvl) _mvlast=1 ;;
|
||||
-h) ;; # swallow
|
||||
*) break; ;;
|
||||
esac
|
||||
shift;
|
||||
done
|
||||
|
||||
###
|
||||
### FUNCTIONS
|
||||
###
|
||||
|
||||
# fetches remote file list
|
||||
remote_list() {
|
||||
ssh $_sshhost \
|
||||
"cd $_rpath/ \
|
||||
&& ls -1tr"
|
||||
}
|
||||
|
||||
# formats file list output
|
||||
remote_list_print() {
|
||||
while read f
|
||||
do
|
||||
ssh sdk@codevoid.de "cd /home/www/htdocs/ptrace/paste/ && rm -v $(basename "$file")" || true
|
||||
echo "$_weburi/$(echo "$f" \
|
||||
| sed 's/ /%20/g') ($f)"
|
||||
done
|
||||
elif [ x"$1" == x"ls" ]
|
||||
}
|
||||
|
||||
copy_and_print() {
|
||||
echo "$_weburi/$(basename "$1")" \
|
||||
| sed 's/ /%20/g' \
|
||||
| xclip -f -r
|
||||
echo
|
||||
}
|
||||
|
||||
###
|
||||
### MAIN PROGRAM
|
||||
###
|
||||
|
||||
# HANDLE CASE: "standard input"
|
||||
# upload with provided or generated filename
|
||||
if [[ ! -t 0 ]]
|
||||
then
|
||||
shift
|
||||
ssh sdk@codevoid.de "cd /home/www/htdocs/ptrace/paste/ && ls -1 | xargs -n1 -I{} echo https://ptrace.org/{}"
|
||||
else
|
||||
for file in $@
|
||||
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
|
||||
chmod o+rw,g+r "$file"
|
||||
scp "$file" sdk@codevoid.de:/home/www/htdocs/ptrace/paste/
|
||||
echo "https://ptrace.org/$(basename "$file")" \
|
||||
| sed 's/ /%20/g' \
|
||||
| xclip -f -r
|
||||
echo
|
||||
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
|
||||
🍏🍎🍐🍊🍋🍌🍉🍇🍓🍈🍒🍑🍍🍅🍆🌽🍠🍞🍳🍗🍖 🍔🍟🍕🍝🍜🍲🍛🍣🍱🍤🍚🍧🍨🍦🍮🍭🍬🍫🍩🍪🌰
|
||||
🍯🍼☕🍵🍶🍺🍻🍷🍸🍹🍴
|
||||
🍯🍼☕🍵🍶🍺🍻🍷🍸🍹🍴🥂🍾
|
||||
|
||||
|
||||
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
|
||||
fi
|
||||
|
||||
mkdir -p "$HOME/ytdl/$1/"
|
||||
ksh-update-completions &
|
||||
if [ ! -d "$HOME/ytdl/$1/" ]
|
||||
then
|
||||
mkdir -p "$HOME/ytdl/$1/"
|
||||
update-ksh-completions
|
||||
. $HOME/.kshrc.autocomplete
|
||||
fi
|
||||
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"
|
||||
|
||||
local unique_instance = require "unique_instance"
|
||||
unique_instance.open_links_in_new_window = true
|
||||
-- local unique_instance = require "unique_instance"
|
||||
-- unique_instance.open_links_in_new_window = true
|
||||
|
||||
-- Set the number of web processes to use. A value of 0 means 'no limit'.
|
||||
-- luakit.process_limit = 1
|
||||
@@ -57,10 +57,10 @@ local binds = require "binds"
|
||||
local settings = require "settings"
|
||||
local settings_chrome = require "settings_chrome"
|
||||
|
||||
settings.window.home_page = "luakit://newtab"
|
||||
-- settings.window.scroll_step = 20
|
||||
-- settings.window.home_page = "luakit://newtab"
|
||||
-- settings.window.scroll_step = 600
|
||||
settings.window.zoom_step = 0.2
|
||||
settings.webview.zoom_level = 100
|
||||
settings.webview.zoom_level = 90
|
||||
settings.window.close_with_last_tab = true
|
||||
|
||||
-- search engines
|
||||
@@ -79,19 +79,19 @@ settings.window.search_engines.default = settings.window.search_engines.ddg
|
||||
-- local adblock_chrome = require "adblock_chrome"
|
||||
|
||||
-- Enable Developer Tools
|
||||
-- local webinspector = require "webinspector"
|
||||
local webinspector = require "webinspector"
|
||||
|
||||
-- Add uzbl-like form filling
|
||||
-- local formfiller = require "formfiller"
|
||||
-- formfiller.extend({
|
||||
-- pass = function(s) return io.popen("pass " .. s):read() end
|
||||
-- })
|
||||
local formfiller = require "formfiller"
|
||||
formfiller.extend({
|
||||
pass = function(s) return io.popen("pass " .. s):read() end
|
||||
})
|
||||
|
||||
-- Add proxy support & manager
|
||||
-- local proxy = require "proxy"
|
||||
local proxy = require "proxy"
|
||||
|
||||
-- Add quickmarks support & manager
|
||||
-- local quickmarks = require "quickmarks"
|
||||
local quickmarks = require "quickmarks"
|
||||
|
||||
-- Add session saving/loading support
|
||||
-- local session = require "session"
|
||||
@@ -100,20 +100,20 @@ settings.window.search_engines.default = settings.window.search_engines.ddg
|
||||
local gopher = require "gopher"
|
||||
|
||||
-- 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
|
||||
local undoclose = require "undoclose"
|
||||
|
||||
-- Add command to list tab history items
|
||||
-- local tabhistory = require "tabhistory"
|
||||
local tabhistory = require "tabhistory"
|
||||
|
||||
-- Add greasemonkey-like javascript userscript support
|
||||
--- local userscripts = require "userscripts"
|
||||
local userscripts = require "userscripts"
|
||||
|
||||
-- Add bookmarks support
|
||||
-- local bookmarks = require "bookmarks"
|
||||
-- local bookmarks_chrome = require "bookmarks_chrome"
|
||||
local bookmarks = require "bookmarks"
|
||||
local bookmarks_chrome = require "bookmarks_chrome"
|
||||
|
||||
-- Add download support
|
||||
local downloads = require "downloads"
|
||||
@@ -121,7 +121,7 @@ local downloads_chrome = require "downloads_chrome"
|
||||
downloads.default_dir = os.getenv("HOME") .. "/Downloads"
|
||||
|
||||
-- Add automatic PDF downloading and opening
|
||||
local viewpdf = require "viewpdf"
|
||||
-- local viewpdf = require "viewpdf"
|
||||
|
||||
-- Add vimperator-like link hinting & following
|
||||
local follow = require "follow"
|
||||
@@ -133,7 +133,7 @@ local cmdhist = require "cmdhist"
|
||||
local search = require "search"
|
||||
|
||||
-- Add ordering of new tabs
|
||||
-- local taborder = require "taborder"
|
||||
local taborder = require "taborder"
|
||||
|
||||
-- Save web 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
|
||||
-- focused <textarea> or <input> element, using `xdg-open`
|
||||
-- local open_editor = require "open_editor"
|
||||
-- local editor = require "editor"
|
||||
-- editor.editor_cmd = "hterm vim {file}"
|
||||
local editor = require "editor"
|
||||
editor.editor_cmd = "sterm vim {file}"
|
||||
|
||||
-- NoScript plugin, toggle scripts and or plugins on a per-domain basis.
|
||||
-- `,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
|
||||
-- `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 go_input = require "go_input"
|
||||
@@ -164,7 +167,7 @@ local go_next_prev = require "go_next_prev"
|
||||
local go_up = require "go_up"
|
||||
|
||||
-- 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"
|
||||
|
||||
@@ -187,9 +190,9 @@ follow.stylesheet = follow.stylesheet .. [===[
|
||||
-- local vertical_tabs = require "vertical_tabs"
|
||||
|
||||
-- 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"
|
||||
newtab_chrome.new_tab_src = [==[
|
||||
<html>
|
||||
@@ -207,7 +210,7 @@ local tab_favicons = require "tab_favicons"
|
||||
-- tablist.min_width = 100
|
||||
|
||||
-- Add :view-source command
|
||||
-- local view_source = require "view_source"
|
||||
local view_source = require "view_source"
|
||||
|
||||
-- Use "asdfqwerzxcv" for generating labels
|
||||
local select = require "select"
|
||||
@@ -217,75 +220,75 @@ end
|
||||
follow.pattern_maker = follow.pattern_styles.match_label
|
||||
|
||||
|
||||
-- -- social media enhancer
|
||||
-- local webview = require "webview"
|
||||
-- webview.add_signal('init', function (view)
|
||||
-- view:add_signal('navigation-request', function(v, uri)
|
||||
-- if v.uri:match('https://www.reddit.com') then
|
||||
-- v.uri = v.uri:gsub('%www.reddit.com', 'old.reddit.com')
|
||||
-- return true
|
||||
-- end
|
||||
-- if v.uri:match('https://new.reddit.com') then
|
||||
-- v.uri = v.uri:gsub('%new.reddit.com', 'old.reddit.com')
|
||||
-- return true
|
||||
-- end
|
||||
-- -- if v.uri:match('https://old.reddit.com') then
|
||||
-- -- v.uri = v.uri:gsub('%old.reddit.com', 'libreddit.kylrth.com')
|
||||
-- -- return true
|
||||
-- -- end
|
||||
-- -- if v.uri:match('https://old.reddit.com') then
|
||||
-- -- v.uri = v.uri:gsub('%old.reddit.com', 'libreddit.kylrth.com')
|
||||
-- -- return true
|
||||
-- -- end
|
||||
-- if v.uri:match('https://www.twitter.com') then
|
||||
-- v.uri = v.uri:gsub('%www.twitter.com', 'nitter.net')
|
||||
-- return true
|
||||
-- end
|
||||
-- if v.uri:match('https://twitter.com') then
|
||||
-- v.uri = v.uri:gsub('%twitter.com', 'nitter.net')
|
||||
-- return true
|
||||
-- end
|
||||
-- if v.uri:match('https://www.youtube.com') then
|
||||
-- v.uri = v.uri:gsub('%www.youtube.com', 'tube.cadence.moe')
|
||||
-- return true
|
||||
-- end
|
||||
-- if v.uri:match('https://youtube.com') then
|
||||
-- v.uri = v.uri:gsub('%youtube.com', 'tube.cadence.moe')
|
||||
-- return true
|
||||
-- end
|
||||
-- if v.uri:match('https://youtu.be') then
|
||||
-- v.uri = v.uri:gsub('%youtu.be/', 'tube.cadence.moe/watch?v=')
|
||||
-- return true
|
||||
-- end
|
||||
-- end)
|
||||
-- end)
|
||||
-- social media enhancer
|
||||
local webview = require "webview"
|
||||
webview.add_signal('init', function (view)
|
||||
view:add_signal('navigation-request', function(v, uri)
|
||||
if v.uri:match('https://www.reddit.com') then
|
||||
v.uri = v.uri:gsub('%www.reddit.com', 'old.reddit.com')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://new.reddit.com') then
|
||||
v.uri = v.uri:gsub('%new.reddit.com', 'old.reddit.com')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://old.reddit.com') then
|
||||
v.uri = v.uri:gsub('%old.reddit.com', 'redlib.kylrth.com')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://old.reddit.com') then
|
||||
v.uri = v.uri:gsub('%old.reddit.com', 'redlib.kylrth.com')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://www.twitter.com') then
|
||||
v.uri = v.uri:gsub('%www.twitter.com', 'nitter.net')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://twitter.com') then
|
||||
v.uri = v.uri:gsub('%twitter.com', 'nitter.net')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://www.youtube.com') then
|
||||
v.uri = v.uri:gsub('%www.youtube.com', 'tube.cadence.moe')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://youtube.com') then
|
||||
v.uri = v.uri:gsub('%youtube.com', 'tube.cadence.moe')
|
||||
return true
|
||||
end
|
||||
if v.uri:match('https://youtu.be') then
|
||||
v.uri = v.uri:gsub('%youtu.be/', 'tube.cadence.moe/watch?v=')
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-- social media blocker
|
||||
-- local webview = require "webview"
|
||||
-- webview.add_signal('init', function (view)
|
||||
-- view:add_signal('navigation-request', function(v, uri)
|
||||
-- local blocklist_pattern = {
|
||||
-- "facebook.com",
|
||||
-- ".fb.com",
|
||||
-- ".fbcdn.com",
|
||||
-- ".fbsbx.com",
|
||||
-- ".fbcdn.net",
|
||||
-- ".tfbnw.net",
|
||||
-- "whatsapp.com",
|
||||
-- "online-metrix.net",
|
||||
-- ".fb.me",
|
||||
-- "facebook-web-clients.appspot.com",
|
||||
-- "fbcdn-profile-a.akamaihd.net"
|
||||
-- }
|
||||
-- for key,value in ipairs(blocklist_pattern)
|
||||
-- do
|
||||
-- if v.uri:match(value) then
|
||||
-- print("Navigation request to " .. v.uri .. " blocked.")
|
||||
-- return false
|
||||
-- end
|
||||
-- end
|
||||
-- end)
|
||||
-- end)
|
||||
local webview = require "webview"
|
||||
webview.add_signal('init', function (view)
|
||||
view:add_signal('navigation-request', function(v, uri)
|
||||
local blocklist_pattern = {
|
||||
"facebook.com",
|
||||
".fb.com",
|
||||
".fbcdn.com",
|
||||
".fbsbx.com",
|
||||
".fbcdn.net",
|
||||
".tfbnw.net",
|
||||
"whatsapp.com",
|
||||
"online-metrix.net",
|
||||
".fb.me",
|
||||
"facebook-web-clients.appspot.com",
|
||||
"fbcdn-profile-a.akamaihd.net"
|
||||
}
|
||||
for key,value in ipairs(blocklist_pattern)
|
||||
do
|
||||
if v.uri:match(value) then
|
||||
print("Navigation request to " .. v.uri .. " blocked.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-----------------------------
|
||||
-- End user script loading --
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local theme = {}
|
||||
|
||||
-- Default settings
|
||||
theme.font = "16px Terminess"
|
||||
theme.font = "20px IosevkaTerm"
|
||||
theme.fg = "#D8D8D8"
|
||||
theme.bg = "#181818"
|
||||
|
||||
|
||||
@@ -109,8 +109,8 @@ remove_set() {
|
||||
while read file
|
||||
do
|
||||
case "$1" in
|
||||
"Left") jpegtran -rotate 270 -outfile "$file" "$file" ;;
|
||||
"Right") jpegtran -rotate 90 -outfile "$file" "$file" ;;
|
||||
"Right") jpegtran -rotate 270 -outfile "$file" "$file" ;;
|
||||
"Left") jpegtran -rotate 90 -outfile "$file" "$file" ;;
|
||||
"c") copy_to_clipboard "$file" ;;
|
||||
"d") rm -f "$file" ;;
|
||||
"e") edit_image "$file" ;;
|
||||
|
||||
@@ -21,6 +21,7 @@ color_focus_free = rgb:AF/5F/00
|
||||
color_unfocus = rgb:44/44/44
|
||||
color_unfocus_free = rgb:55/35/00
|
||||
disable_border = 0
|
||||
disable_padding = 1
|
||||
maximize_hide_bar = 0
|
||||
|
||||
# +--------------------------------------------------
|
||||
@@ -68,7 +69,7 @@ bar_at_bottom = 0
|
||||
# ++ A literal ‘+’
|
||||
# +@ 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
|
||||
@@ -216,6 +217,7 @@ bind[bar_toggle_ws] = MOD+Shift+b
|
||||
# LAYOUT
|
||||
bind[cycle_layout] = MOD+l
|
||||
bind[flip_layout] = MOD+Shift+l
|
||||
bind[center_layout] = MOD+Shift+c
|
||||
bind[float_toggle] = MOD+space
|
||||
bind[free_toggle] = MOD+Shift+space
|
||||
|
||||
|
||||
@@ -4,7 +4,11 @@ indent=30
|
||||
tabs=None
|
||||
linespacing=3
|
||||
wrapped-lines-linespacing=0
|
||||
<<<<<<< Updated upstream
|
||||
font=FuraCode Nerd Font Mono weight=450 14
|
||||
=======
|
||||
font=.AppleSystemUIFont 17
|
||||
>>>>>>> Stashed changes
|
||||
justify=
|
||||
background=#cccccc
|
||||
|
||||
@@ -32,7 +36,6 @@ wrap-mode=GTK_WRAP_NONE
|
||||
indent=20
|
||||
|
||||
[Tag link]
|
||||
foreground=#8cd3ff
|
||||
|
||||
[Tag tag]
|
||||
foreground=#ce5c00
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
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 ----------------------------------------------------------------------
|
||||
|
||||
# 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
|
||||
# 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, ''
|
||||
elif len(fields) >= 5 and fields[1] == 'catchpoint':
|
||||
# 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
|
||||
elif len(fields) >= 3 and number in parsed_breakpoints:
|
||||
# add this address to the list of multiple locations
|
||||
|
||||
16
.gitconfig
16
.gitconfig
@@ -18,8 +18,8 @@
|
||||
name = Stefan Hagen
|
||||
email = sh+github@codevoid.de
|
||||
[user]
|
||||
name = c0dev0id
|
||||
email = sh+git@codevoid.de
|
||||
name = Stefan Hagen
|
||||
email = stefan.hagen@sap.com
|
||||
[hub]
|
||||
host = github.wdf.sap.corp
|
||||
protocol = git
|
||||
@@ -39,3 +39,15 @@
|
||||
[credential "https://github.wdf.sap.corp"]
|
||||
helper =
|
||||
helper = !/usr/bin/gh auth git-credential
|
||||
[difftool]
|
||||
prompt = false
|
||||
[filter "lfs"]
|
||||
clean = git-lfs clean -- %f
|
||||
smudge = git-lfs smudge -- %f
|
||||
process = git-lfs filter-process
|
||||
required = true
|
||||
[credential]
|
||||
helper =
|
||||
helper = /usr/local/share/gcm-core/git-credential-manager
|
||||
[credential "https://dev.azure.com"]
|
||||
useHttpPath = true
|
||||
|
||||
122
.kshrc
122
.kshrc
@@ -27,7 +27,7 @@ export LANG LC_MESSAGES LC_NUMERIC LC_TIME
|
||||
### SOFTWARE PREFERENCES
|
||||
EDITOR="vim"
|
||||
VISUAL="vim"
|
||||
BROWSER="chrome"
|
||||
BROWSER="firefox"
|
||||
PAGER="less"
|
||||
export EDITOR VISUAL BROWSER PAGER
|
||||
|
||||
@@ -86,8 +86,8 @@ TOG_COLORS=1
|
||||
export GOT_AUTHOR TOG_COLORS
|
||||
|
||||
# BUPSTASH
|
||||
BUPSTASH_REPOSITORY=ssh://sdk@storage.bupstash.io
|
||||
BUPSTASH_KEY_COMMAND="pass Internet/bupstash-key"
|
||||
BUPSTASH_REPOSITORY=ssh://default@storage.bupstash.io
|
||||
BUPSTASH_KEY_COMMAND="pass Internet/storage.bupstash.io-key"
|
||||
export BUPSTASH_REPOSITORY BUPSTASH_KEY_COMMAND
|
||||
|
||||
# PASSWORD-STORE
|
||||
@@ -127,11 +127,26 @@ RED="\[$(tput setaf 196)\]"
|
||||
GREY="\[$(tput setaf 248)\]"
|
||||
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 ]
|
||||
then
|
||||
PS1="${x}${RED}\${?}|\w\\$ ${RESET}${x}"
|
||||
PS1="${x}${RED}$(hostname -s) \${?}|\w\\$ ${RESET}${x}"
|
||||
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
|
||||
|
||||
########################################################################
|
||||
@@ -147,19 +162,28 @@ alias luakitrc="vim ~/.config/luakit/rc.lua"
|
||||
alias spectrwmrc="vim ~/.config/spectrwm/spectrwm.conf"
|
||||
alias vifmrc="vim ~/.config/vifm/vifmrc"
|
||||
alias tmuxrc="vim ~/.tmux.conf"
|
||||
alias annex="git annex"
|
||||
|
||||
pastebinvim() {
|
||||
vim "https://pastebin.com/raw/$(basename "$1")";
|
||||
}
|
||||
|
||||
# task warrior
|
||||
alias t=task
|
||||
alias ta="t add"
|
||||
alias tm="t mod"
|
||||
alias tc="t completed"
|
||||
alias tlog="t log +LOG"
|
||||
#alias t=task
|
||||
#alias ta="t add"
|
||||
#alias tm="t mod"
|
||||
#alias tc="t completed"
|
||||
#alias tlog="t log +LOG"
|
||||
alias mc="/usr/local/bin/mc -d"
|
||||
|
||||
# social media
|
||||
alias tuta="tut -u 'sh@bsd.network uugrn@chaos.social'"
|
||||
|
||||
# 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 \
|
||||
-o KexAlgorithms=+diffie-hellman-group1-sha1 \
|
||||
@@ -168,11 +192,71 @@ alias inssh="ssh -o HostKeyAlgorithms=+ssh-rsa \
|
||||
myps() { ps -fU $(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
|
||||
alias portroach="portroach-cli -m codevoid"
|
||||
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
|
||||
@@ -293,8 +377,8 @@ obsd-full-system-update() {(
|
||||
# REMIND
|
||||
########################################################################
|
||||
|
||||
alias rem="remind -@1,1,1 -c+cu4 -wt ~sdk/.reminders.rem"
|
||||
alias remy="remind -@1,1,1 -c+cu52 -wt ~sdk/.reminders.rem | less"
|
||||
alias rem="remind -@1,1,1 -c+cu4 -wt -m ~sdk/.reminders.rem"
|
||||
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 remc="remindcal ~sdk/.reminders"
|
||||
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
|
||||
}
|
||||
rem-edit-uugrn() {
|
||||
vim sftp://vorstand@vorstand.uugrn.org/.reminders/uugrn.rem
|
||||
scp -q vorstand@vorstand.uugrn.org:.reminders/uugrn.rem ~sdk/.reminders/uugrn.rem
|
||||
scp -q ~sdk/.reminders/uugrn.rem vorstand@vorstand.uugrn.org:private/Kalender/uugrn.rem
|
||||
# edit remote file
|
||||
vim sftp://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 \
|
||||
~sdk/.bin/make_calendar.sh \
|
||||
~vorstand/private/Kalender/scripts/make_calendar.sh \
|
||||
|| true
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,46 +0,0 @@
|
||||
@-moz-document domain(old.reddit.com) {
|
||||
* {
|
||||
background-color: #181818 !important;
|
||||
color: #CCC !important;
|
||||
border-color: #555 !important;
|
||||
border-width: 0px !important;
|
||||
}
|
||||
.premium-banner-outer, .premium-banner {
|
||||
display: none !important;
|
||||
}
|
||||
#header-img.default-header, .side {
|
||||
display: none !important;
|
||||
}
|
||||
.link.promotedlink.promoted, .link.promotedlink.external {
|
||||
display: none !important;
|
||||
}
|
||||
.footer-parent {
|
||||
display: none !important;
|
||||
}
|
||||
.happening-now-wrap {
|
||||
display: none !important;
|
||||
}
|
||||
.stickied {
|
||||
display: none !important;
|
||||
}
|
||||
input, textarea, button {
|
||||
background-color: #282828 !important;
|
||||
}
|
||||
a {
|
||||
font-style: oblique !important;
|
||||
}
|
||||
.expando-button, .thumbnail, .rank, .midcol {
|
||||
display: none !important;
|
||||
}
|
||||
.top-matter, .top-matter > *, .top-matter > * > *, .top-matter > * > * > *, .top-matter > * > * > * > * {
|
||||
background-color: #222 !important;
|
||||
}
|
||||
.linkflairlabel, .linkflairlabel > * {
|
||||
background-color: #999 !important;
|
||||
color: #121212 !important;
|
||||
}
|
||||
.entry {
|
||||
border-left: 5px solid darkred !important;
|
||||
padding-left: 5px !important;
|
||||
}
|
||||
}
|
||||
@@ -33,3 +33,5 @@ color body green default "^\\+"
|
||||
color body green default "^\\+.*"
|
||||
color body green default "> \\+.*"
|
||||
|
||||
color 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;
|
||||
|
||||
# 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.spreadsheetml.sheet; ~/.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
|
||||
auto_view text/html text/enriched text/calendar
|
||||
|
||||
# Preview HTML
|
||||
macro pager,attach \cs "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/apply_patch.sh /tmp/muttpatch.diff<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>"
|
||||
# apply inline patch
|
||||
macro index,pager,attach \cs "| ~/.mutt/scripts/patch.sh patch<enter>"
|
||||
macro index,pager,attach \ca "| ~/.mutt/scripts/patch.sh git<enter>"
|
||||
|
||||
# pipe-message
|
||||
set pipe_decode_weed = no
|
||||
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 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 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
|
||||
@@ -321,4 +319,9 @@ set crypt_opportunistic_encrypt_strong_keys = yes # autoselect key with trust fu
|
||||
set autocrypt = no
|
||||
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
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/ksh -e
|
||||
|
||||
# needs converters/qprint
|
||||
# mutt: macro pager,attach \cs "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/apply_patch.sh /tmp/muttpatch.diff<enter>"
|
||||
|
||||
clear
|
||||
|
||||
printf '\n---------------------------------------------------------------------\n'
|
||||
grep -E 'Subject: |^Index|^RCS|^diff --git|^file +|^[-+]{3} ' "${1}"
|
||||
printf '---------------------------------------------------------------------\n\n'
|
||||
|
||||
printf "Base path for the patch?\n"
|
||||
printf "Example: /usr/ports or /usr/src\n"
|
||||
printf ": "
|
||||
read -r _path
|
||||
cd $_path
|
||||
|
||||
print "Using: $_path"
|
||||
|
||||
printf "Fix quoted-printable mangeled patch? [y/N]: "
|
||||
read -r _qprint
|
||||
|
||||
case ${_qprint} in
|
||||
[y|Y]) _catcmd="qprint -d"; ;;
|
||||
*) _catcmd="cat"; ;;
|
||||
esac
|
||||
|
||||
printf "Strip? [0]: "
|
||||
read -r _strip
|
||||
|
||||
echo "CMD: ${_catcmd} "${1}" | doas -u sdk patch -E -pp${_strip:=0} -d ${_path}"
|
||||
${_catcmd} "${1}" | doas -u sdk patch -E -N -p${_strip:=0} -d ${_path}
|
||||
echo ${_path} | xclip
|
||||
echo "done."
|
||||
read
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
strip=0
|
||||
|
||||
clear
|
||||
printf '\n---------------------------------------------------------------------\n'
|
||||
egrep '^Index|^RCS|^diff --git|^file +' "$1" | sed 's,/cvs,/usr,g'
|
||||
printf '---------------------------------------------------------------------\n\n'
|
||||
|
||||
printf "Path for patch [/usr/ports]? "
|
||||
read _path
|
||||
|
||||
[ -z "$_path" ] && _path=/usr/ports
|
||||
egrep -q '^diff --git a/' "$1" && strip=1
|
||||
|
||||
#print "Trying to apply patch"
|
||||
#qprint -d "$1" "$1.out"
|
||||
|
||||
doas patch -Ep"$strip" -d $_path < "$1"
|
||||
cd $_path && ksh
|
||||
68
.mutt/scripts/patch.sh
Executable file
68
.mutt/scripts/patch.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/ksh -e
|
||||
# needs converters/qprint
|
||||
|
||||
if [ -t 0 ] || [ -z "$1" ]
|
||||
then
|
||||
echo "usage: patch.sh [git|patch] < patchfile.diff"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "Shortcuts:"
|
||||
echo "ld - luakit-dev"
|
||||
echo "lt - luakit-test"
|
||||
echo "ltmp - luakit-tmp"
|
||||
echo "src - /usr/src"
|
||||
echo "sys - /usr/src/sys"
|
||||
echo "ports - /usr/ports"
|
||||
echo "www - /usr/www"
|
||||
echo
|
||||
printf "Path [$PWD]: "
|
||||
read _reply < /dev/tty
|
||||
|
||||
if [ -z "$_reply" ]
|
||||
then
|
||||
_path="$PWD"
|
||||
else
|
||||
_path="$_reply"
|
||||
fi
|
||||
|
||||
# shortcuts!!!
|
||||
case "$_path" in
|
||||
ld) _path="/home/sdk/src/luakit-dev" ;;
|
||||
lt) _path="/home/sdk/src/luakit-test" ;;
|
||||
ltmp) _path="/home/sdk/src/luakit-tmp" ;;
|
||||
src) _path="/usr/src" ;;
|
||||
sys) _path="/usr/src/sys" ;;
|
||||
ports) _path="/usr/ports" ;;
|
||||
esac
|
||||
|
||||
if [ ! -d "$_path" ]
|
||||
then
|
||||
_path="$(port-jump "$_path")"
|
||||
fi
|
||||
|
||||
print "Using: $_path"
|
||||
|
||||
if [ ! -d "$_path" ]
|
||||
then
|
||||
echo "Error with path: $_path"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
cd "$_path"
|
||||
if [ "$1" == "git" ]
|
||||
then
|
||||
cat /dev/stdin | git am
|
||||
fi
|
||||
|
||||
if [ "$1" == "patch" ]
|
||||
then
|
||||
printf "Strip [0]: "
|
||||
read _strip < /dev/tty
|
||||
_strip=${_strip:=0}
|
||||
|
||||
cat /dev/stdin | doas -u sdk patch -E -N -p$_strip -d "$_path"
|
||||
fi
|
||||
|
||||
echo "$_path" | xclip
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/ksh -e
|
||||
|
||||
# needs converters/qprint
|
||||
# mutt: macro pager,attach \cs "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/portpatch2.sh /tmp/muttpatch.diff<enter>"
|
||||
|
||||
clear
|
||||
|
||||
printf '\n---------------------------------------------------------------------\n'
|
||||
grep -E 'Subject: |^Index|^RCS|^diff --git|^file +|^[-+]{3} ' "${1}"
|
||||
printf '---------------------------------------------------------------------\n\n'
|
||||
|
||||
printf "Base path for the patch?\n"
|
||||
printf "Example: /usr/ports or /usr/src\n"
|
||||
printf ": "
|
||||
read -r _path
|
||||
cd $_path
|
||||
|
||||
print "Using: $_path"
|
||||
|
||||
printf "Fix quoted-printable mangeled patch? [y/N]: "
|
||||
read -r _qprint
|
||||
|
||||
case ${_qprint} in
|
||||
[y|Y]) _catcmd="qprint -d"; ;;
|
||||
*) _catcmd="cat"; ;;
|
||||
esac
|
||||
|
||||
printf "Strip? [0]: "
|
||||
read -r _strip
|
||||
|
||||
echo "CMD: ${_catcmd} "${1}" | doas -u sdk patch -E -pp${_strip:=0} -d ${_path}"
|
||||
${_catcmd} "${1}" | doas -u sdk patch -i -E -N -p${_strip:=0} -d ${_path}
|
||||
echo ${_path} | xclip
|
||||
echo "done.
|
||||
read
|
||||
@@ -53,6 +53,10 @@ Host home.codevoid.de
|
||||
Hostname home.codevoid.de
|
||||
User sdk
|
||||
|
||||
Host backup-fsn.codevoid.de
|
||||
User u475462-sub1
|
||||
Port 23
|
||||
|
||||
Host dalek
|
||||
Hostname dalek.home.codevoid.de
|
||||
User sdk
|
||||
|
||||
35
.vim/bin/findtagsdir
Executable file
35
.vim/bin/findtagsdir
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
gitdir() {
|
||||
_path="$PWD"
|
||||
while [ -n "$_path" ]
|
||||
do [ -d "$_path/.git" ] \
|
||||
&& echo "$_path" \
|
||||
&& break
|
||||
_path="${_path%/*}"
|
||||
done
|
||||
}
|
||||
|
||||
cvsdir() {
|
||||
_path="$PWD"
|
||||
while [ -n "$_path" ]
|
||||
do
|
||||
[ ! -d "$_path/../CVS" ] \
|
||||
&& echo "$_path" \
|
||||
&& break
|
||||
_path="${_path%/*}"
|
||||
done
|
||||
}
|
||||
|
||||
_gitdir="$(gitdir)"
|
||||
_cvsdir="$(cvsdir)"
|
||||
|
||||
if [ -n "$_gitdir" ]
|
||||
then
|
||||
echo "$_gitdir/.git"
|
||||
elif [ -n "$_cvsdir" ]
|
||||
then
|
||||
echo "$_cvsdir/.tags"
|
||||
else
|
||||
echo "$PWD/.tags"
|
||||
fi
|
||||
@@ -1,4 +0,0 @@
|
||||
GitHub Copilot is offered under the [GitHub Terms of
|
||||
Service](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features#github-copilot).
|
||||
|
||||
Copyright (C) 2023 GitHub, Inc. - All Rights Reserved.
|
||||
@@ -1,64 +0,0 @@
|
||||
# GitHub Copilot for Vim and Neovim
|
||||
|
||||
GitHub Copilot uses OpenAI Codex to suggest code and entire functions in
|
||||
real-time right from your editor. Trained on billions of lines of public
|
||||
code, GitHub Copilot turns natural language prompts including comments and
|
||||
method names into coding suggestions across dozens of languages.
|
||||
|
||||
Copilot.vim is a Vim/Neovim plugin for GitHub Copilot.
|
||||
|
||||
To learn more, visit
|
||||
[https://github.com/features/copilot](https://github.com/features/copilot).
|
||||
|
||||
## Subscription
|
||||
|
||||
GitHub Copilot requires a subscription. It is free for verified students and
|
||||
maintainers of popular open source projects on GitHub.
|
||||
|
||||
GitHub Copilot is subject to the [GitHub Additional Product
|
||||
Terms](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features).
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Install [Neovim][] or the latest patch of [Vim][] (9.0.0185 or newer).
|
||||
|
||||
2. Install [Node.js][].
|
||||
|
||||
3. Install `github/copilot.vim` using vim-plug, packer.nvim, or any other
|
||||
plugin manager. Or to install manually, run one of the following
|
||||
commands:
|
||||
|
||||
* Vim, Linux/macOS:
|
||||
|
||||
git clone https://github.com/github/copilot.vim.git \
|
||||
~/.vim/pack/github/start/copilot.vim
|
||||
|
||||
* Neovim, Linux/macOS:
|
||||
|
||||
git clone https://github.com/github/copilot.vim.git \
|
||||
~/.config/nvim/pack/github/start/copilot.vim
|
||||
|
||||
* Vim, Windows (PowerShell command):
|
||||
|
||||
git clone https://github.com/github/copilot.vim.git `
|
||||
$HOME/vimfiles/pack/github/start/copilot.vim
|
||||
|
||||
* Neovim, Windows (PowerShell command):
|
||||
|
||||
git clone https://github.com/github/copilot.vim.git `
|
||||
$HOME/AppData/Local/nvim/pack/github/start/copilot.vim
|
||||
|
||||
4. Start Vim/Neovim and invoke `:Copilot setup`.
|
||||
|
||||
[Node.js]: https://nodejs.org/en/download/
|
||||
[Neovim]: https://github.com/neovim/neovim/releases/latest
|
||||
[Vim]: https://github.com/vim/vim
|
||||
|
||||
Suggestions are displayed inline and can be accepted by pressing the tab key.
|
||||
See `:help copilot` for more information.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
We’d love to get your help in making GitHub Copilot better! If you have
|
||||
feedback or encounter any problems, please reach out on our [Feedback
|
||||
forum](https://github.com/orgs/community/discussions/categories/copilot).
|
||||
@@ -1,4 +0,0 @@
|
||||
If you discover a security issue in this repo, please submit it through the
|
||||
[GitHub Security Bug Bounty](https://hackerone.com/github).
|
||||
|
||||
Thanks for helping make GitHub Copilot safe for everyone.
|
||||
@@ -1,860 +0,0 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
let s:has_nvim_ghost_text = has('nvim-0.7') && exists('*nvim_buf_get_mark')
|
||||
let s:vim_minimum_version = '9.0.0185'
|
||||
let s:has_vim_ghost_text = has('patch-' . s:vim_minimum_version) && has('textprop')
|
||||
let s:has_ghost_text = s:has_nvim_ghost_text || s:has_vim_ghost_text
|
||||
|
||||
let s:hlgroup = 'CopilotSuggestion'
|
||||
let s:annot_hlgroup = 'CopilotAnnotation'
|
||||
|
||||
if s:has_vim_ghost_text && empty(prop_type_get(s:hlgroup))
|
||||
call prop_type_add(s:hlgroup, {'highlight': s:hlgroup})
|
||||
endif
|
||||
if s:has_vim_ghost_text && empty(prop_type_get(s:annot_hlgroup))
|
||||
call prop_type_add(s:annot_hlgroup, {'highlight': s:annot_hlgroup})
|
||||
endif
|
||||
|
||||
function! s:Echo(msg) abort
|
||||
if has('nvim') && &cmdheight == 0
|
||||
call v:lua.vim.notify(a:msg, v:null, {'title': 'GitHub Copilot'})
|
||||
else
|
||||
echo a:msg
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:EditorConfiguration() abort
|
||||
let filetypes = copy(s:filetype_defaults)
|
||||
if type(get(g:, 'copilot_filetypes')) == v:t_dict
|
||||
call extend(filetypes, g:copilot_filetypes)
|
||||
endif
|
||||
return {
|
||||
\ 'enableAutoCompletions': empty(get(g:, 'copilot_enabled', 1)) ? v:false : v:true,
|
||||
\ 'disabledLanguages': map(sort(keys(filter(filetypes, { k, v -> empty(v) }))), { _, v -> {'languageId': v}}),
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! copilot#Init(...) abort
|
||||
call copilot#util#Defer({ -> exists('s:client') || s:Start() })
|
||||
endfunction
|
||||
|
||||
function! s:Running() abort
|
||||
return exists('s:client.job') || exists('s:client.client_id')
|
||||
endfunction
|
||||
|
||||
function! s:Start() abort
|
||||
if s:Running() || exists('s:client.startup_error')
|
||||
return
|
||||
endif
|
||||
let s:client = copilot#client#New({'editorConfiguration' : s:EditorConfiguration()})
|
||||
endfunction
|
||||
|
||||
function! s:Stop() abort
|
||||
if exists('s:client')
|
||||
let client = remove(s:, 'client')
|
||||
call client.Close()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#Client() abort
|
||||
call s:Start()
|
||||
return s:client
|
||||
endfunction
|
||||
|
||||
function! copilot#RunningClient() abort
|
||||
if s:Running()
|
||||
return s:client
|
||||
else
|
||||
return v:null
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has('nvim-0.7') && !has(luaeval('vim.version().api_prerelease') ? 'nvim-0.8.1' : 'nvim-0.8.0')
|
||||
let s:editor_warning = 'Neovim 0.7 support is deprecated and will be dropped in a future release of copilot.vim.'
|
||||
endif
|
||||
if has('vim_starting') && exists('s:editor_warning')
|
||||
call copilot#logger#Warn(s:editor_warning)
|
||||
endif
|
||||
function! s:EditorVersionWarning() abort
|
||||
if exists('s:editor_warning')
|
||||
echohl WarningMsg
|
||||
echo 'Warning: ' . s:editor_warning
|
||||
echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#Request(method, params, ...) abort
|
||||
let client = copilot#Client()
|
||||
return call(client.Request, [a:method, a:params] + a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#Call(method, params, ...) abort
|
||||
let client = copilot#Client()
|
||||
return call(client.Call, [a:method, a:params] + a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#Notify(method, params, ...) abort
|
||||
let client = copilot#Client()
|
||||
return call(client.Notify, [a:method, a:params] + a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#NvimNs() abort
|
||||
return nvim_create_namespace('github-copilot')
|
||||
endfunction
|
||||
|
||||
function! copilot#Clear() abort
|
||||
if exists('g:_copilot_timer')
|
||||
call timer_stop(remove(g:, '_copilot_timer'))
|
||||
endif
|
||||
if exists('b:_copilot')
|
||||
call copilot#client#Cancel(get(b:_copilot, 'first', {}))
|
||||
call copilot#client#Cancel(get(b:_copilot, 'cycling', {}))
|
||||
endif
|
||||
call s:UpdatePreview()
|
||||
unlet! b:_copilot
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! copilot#Dismiss() abort
|
||||
call copilot#Clear()
|
||||
call s:UpdatePreview()
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
let s:filetype_defaults = {
|
||||
\ 'gitcommit': 0,
|
||||
\ 'gitrebase': 0,
|
||||
\ 'hgcommit': 0,
|
||||
\ 'svn': 0,
|
||||
\ 'cvs': 0,
|
||||
\ '.': 0}
|
||||
|
||||
function! s:BufferDisabled() abort
|
||||
if &buftype =~# '^\%(help\|prompt\|quickfix\|terminal\)$'
|
||||
return 5
|
||||
endif
|
||||
if exists('b:copilot_disabled')
|
||||
return empty(b:copilot_disabled) ? 0 : 3
|
||||
endif
|
||||
if exists('b:copilot_enabled')
|
||||
return empty(b:copilot_enabled) ? 4 : 0
|
||||
endif
|
||||
let short = empty(&l:filetype) ? '.' : split(&l:filetype, '\.', 1)[0]
|
||||
let config = {}
|
||||
if type(get(g:, 'copilot_filetypes')) == v:t_dict
|
||||
let config = g:copilot_filetypes
|
||||
endif
|
||||
if has_key(config, &l:filetype)
|
||||
return empty(config[&l:filetype])
|
||||
elseif has_key(config, short)
|
||||
return empty(config[short])
|
||||
elseif has_key(config, '*')
|
||||
return empty(config['*'])
|
||||
else
|
||||
return get(s:filetype_defaults, short, 1) == 0 ? 2 : 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#Enabled() abort
|
||||
return get(g:, 'copilot_enabled', 1)
|
||||
\ && empty(s:BufferDisabled())
|
||||
endfunction
|
||||
|
||||
let s:inline_invoked = 1
|
||||
let s:inline_automatic = 2
|
||||
|
||||
function! copilot#Complete(...) abort
|
||||
if exists('g:_copilot_timer')
|
||||
call timer_stop(remove(g:, '_copilot_timer'))
|
||||
endif
|
||||
let target = [bufnr(''), getbufvar('', 'changedtick'), line('.'), col('.')]
|
||||
if !exists('b:_copilot.target') || b:_copilot.target !=# target
|
||||
if exists('b:_copilot.first')
|
||||
call copilot#client#Cancel(b:_copilot.first)
|
||||
endif
|
||||
if exists('b:_copilot.cycling')
|
||||
call copilot#client#Cancel(b:_copilot.cycling)
|
||||
endif
|
||||
let params = {
|
||||
\ 'textDocument': {'uri': bufnr('')},
|
||||
\ 'position': copilot#util#AppendPosition(),
|
||||
\ 'formattingOptions': {'insertSpaces': &expandtab ? v:true : v:false, 'tabSize': shiftwidth()},
|
||||
\ 'context': {'triggerKind': s:inline_automatic}}
|
||||
let b:_copilot = {
|
||||
\ 'target': target,
|
||||
\ 'params': params,
|
||||
\ 'first': copilot#Request('textDocument/inlineCompletion', params)}
|
||||
let g:_copilot_last = b:_copilot
|
||||
endif
|
||||
let completion = b:_copilot.first
|
||||
if !a:0
|
||||
return completion.Await()
|
||||
else
|
||||
call copilot#client#Result(completion, function(a:1, [b:_copilot]))
|
||||
if a:0 > 1
|
||||
call copilot#client#Error(completion, function(a:2, [b:_copilot]))
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:HideDuringCompletion() abort
|
||||
return get(g:, 'copilot_hide_during_completion', 1)
|
||||
endfunction
|
||||
|
||||
function! s:SuggestionTextWithAdjustments() abort
|
||||
let empty = ['', 0, 0, {}]
|
||||
try
|
||||
if mode() !~# '^[iR]' || (s:HideDuringCompletion() && pumvisible()) || !exists('b:_copilot.suggestions')
|
||||
return empty
|
||||
endif
|
||||
let choice = get(b:_copilot.suggestions, b:_copilot.choice, {})
|
||||
if !has_key(choice, 'range') || choice.range.start.line != line('.') - 1 || type(choice.insertText) !=# v:t_string
|
||||
return empty
|
||||
endif
|
||||
let line = getline('.')
|
||||
let offset = col('.') - 1
|
||||
let choice_text = strpart(line, 0, copilot#util#UTF16ToByteIdx(line, choice.range.start.character)) . substitute(choice.insertText, "\n*$", '', '')
|
||||
let typed = strpart(line, 0, offset)
|
||||
let end_offset = copilot#util#UTF16ToByteIdx(line, choice.range.end.character)
|
||||
if end_offset < 0
|
||||
let end_offset = len(line)
|
||||
endif
|
||||
let delete = strpart(line, offset, end_offset - offset)
|
||||
if typed =~# '^\s*$'
|
||||
let leading = matchstr(choice_text, '^\s\+')
|
||||
let unindented = strpart(choice_text, len(leading))
|
||||
if strpart(typed, 0, len(leading)) == leading && unindented !=# delete
|
||||
return [unindented, len(typed) - len(leading), strchars(delete), choice]
|
||||
endif
|
||||
elseif typed ==# strpart(choice_text, 0, offset)
|
||||
return [strpart(choice_text, offset), 0, strchars(delete), choice]
|
||||
endif
|
||||
catch
|
||||
call copilot#logger#Exception()
|
||||
endtry
|
||||
return empty
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:Advance(count, context, ...) abort
|
||||
if a:context isnot# get(b:, '_copilot', {})
|
||||
return
|
||||
endif
|
||||
let a:context.choice += a:count
|
||||
if a:context.choice < 0
|
||||
let a:context.choice += len(a:context.suggestions)
|
||||
endif
|
||||
let a:context.choice %= len(a:context.suggestions)
|
||||
call s:UpdatePreview()
|
||||
endfunction
|
||||
|
||||
function! s:GetSuggestionsCyclingCallback(context, result) abort
|
||||
let callbacks = remove(a:context, 'cycling_callbacks')
|
||||
let seen = {}
|
||||
for suggestion in a:context.suggestions
|
||||
let seen[suggestion.insertText] = 1
|
||||
endfor
|
||||
for suggestion in get(a:result, 'items', [])
|
||||
if !has_key(seen, suggestion.insertText)
|
||||
call add(a:context.suggestions, suggestion)
|
||||
let seen[suggestion.insertText] = 1
|
||||
endif
|
||||
endfor
|
||||
for Callback in callbacks
|
||||
call Callback(a:context)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:GetSuggestionsCycling(callback) abort
|
||||
if exists('b:_copilot.cycling_callbacks')
|
||||
call add(b:_copilot.cycling_callbacks, a:callback)
|
||||
elseif exists('b:_copilot.cycling')
|
||||
call a:callback(b:_copilot)
|
||||
elseif exists('b:_copilot.suggestions')
|
||||
let params = deepcopy(b:_copilot.first.params)
|
||||
let params.context.triggerKind = s:inline_invoked
|
||||
let b:_copilot.cycling_callbacks = [a:callback]
|
||||
let b:_copilot.cycling = copilot#Request('textDocument/inlineCompletion',
|
||||
\ params,
|
||||
\ function('s:GetSuggestionsCyclingCallback', [b:_copilot]),
|
||||
\ function('s:GetSuggestionsCyclingCallback', [b:_copilot]),
|
||||
\ )
|
||||
call s:UpdatePreview()
|
||||
endif
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! copilot#Next() abort
|
||||
return s:GetSuggestionsCycling(function('s:Advance', [1]))
|
||||
endfunction
|
||||
|
||||
function! copilot#Previous() abort
|
||||
return s:GetSuggestionsCycling(function('s:Advance', [-1]))
|
||||
endfunction
|
||||
|
||||
function! copilot#GetDisplayedSuggestion() abort
|
||||
let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments()
|
||||
|
||||
return {
|
||||
\ 'item': item,
|
||||
\ 'text': text,
|
||||
\ 'outdentSize': outdent,
|
||||
\ 'deleteSize': delete}
|
||||
endfunction
|
||||
|
||||
function! s:ClearPreview() abort
|
||||
if s:has_nvim_ghost_text
|
||||
call nvim_buf_del_extmark(0, copilot#NvimNs(), 1)
|
||||
elseif s:has_vim_ghost_text
|
||||
call prop_remove({'type': s:hlgroup, 'all': v:true})
|
||||
call prop_remove({'type': s:annot_hlgroup, 'all': v:true})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:UpdatePreview() abort
|
||||
try
|
||||
let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments()
|
||||
let text = split(text, "\r\n\\=\\|\n", 1)
|
||||
if empty(text[-1])
|
||||
call remove(text, -1)
|
||||
endif
|
||||
if empty(text) || !s:has_ghost_text
|
||||
return s:ClearPreview()
|
||||
endif
|
||||
if exists('b:_copilot.cycling_callbacks')
|
||||
let annot = '(1/…)'
|
||||
elseif exists('b:_copilot.cycling')
|
||||
let annot = '(' . (b:_copilot.choice + 1) . '/' . len(b:_copilot.suggestions) . ')'
|
||||
else
|
||||
let annot = ''
|
||||
endif
|
||||
call s:ClearPreview()
|
||||
if s:has_nvim_ghost_text
|
||||
let data = {'id': 1}
|
||||
let data.virt_text_pos = 'overlay'
|
||||
let append = strpart(getline('.'), col('.') - 1 + delete)
|
||||
let data.virt_text = [[text[0] . append . repeat(' ', delete - len(text[0])), s:hlgroup]]
|
||||
if len(text) > 1
|
||||
let data.virt_lines = map(text[1:-1], { _, l -> [[l, s:hlgroup]] })
|
||||
if !empty(annot)
|
||||
let data.virt_lines[-1] += [[' '], [annot, s:annot_hlgroup]]
|
||||
endif
|
||||
elseif len(annot)
|
||||
let data.virt_text += [[' '], [annot, s:annot_hlgroup]]
|
||||
endif
|
||||
let data.hl_mode = 'combine'
|
||||
call nvim_buf_set_extmark(0, copilot#NvimNs(), line('.')-1, col('.')-1, data)
|
||||
elseif s:has_vim_ghost_text
|
||||
let new_suffix = text[0]
|
||||
let current_suffix = getline('.')[col('.') - 1 :]
|
||||
let inset = ''
|
||||
while delete > 0 && !empty(new_suffix)
|
||||
let last_char = matchstr(new_suffix, '.$')
|
||||
let new_suffix = matchstr(new_suffix, '^.\{-\}\ze.$')
|
||||
if last_char ==# matchstr(current_suffix, '.$')
|
||||
if !empty(inset)
|
||||
call prop_add(line('.'), col('.') + len(current_suffix), {'type': s:hlgroup, 'text': inset})
|
||||
let inset = ''
|
||||
endif
|
||||
let current_suffix = matchstr(current_suffix, '^.\{-\}\ze.$')
|
||||
let delete -= 1
|
||||
else
|
||||
let inset = last_char . inset
|
||||
endif
|
||||
endwhile
|
||||
if !empty(new_suffix . inset)
|
||||
call prop_add(line('.'), col('.'), {'type': s:hlgroup, 'text': new_suffix . inset})
|
||||
endif
|
||||
for line in text[1:]
|
||||
call prop_add(line('.'), 0, {'type': s:hlgroup, 'text_align': 'below', 'text': line})
|
||||
endfor
|
||||
if !empty(annot)
|
||||
call prop_add(line('.'), col('$'), {'type': s:annot_hlgroup, 'text': ' ' . annot})
|
||||
endif
|
||||
endif
|
||||
call copilot#Notify('textDocument/didShowCompletion', {'item': item})
|
||||
catch
|
||||
return copilot#logger#Exception()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:HandleTriggerResult(state, result) abort
|
||||
let a:state.suggestions = type(a:result) == type([]) ? a:result : get(empty(a:result) ? {} : a:result, 'items', [])
|
||||
let a:state.choice = 0
|
||||
if get(b:, '_copilot') is# a:state
|
||||
call s:UpdatePreview()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:HandleTriggerError(state, result) abort
|
||||
let a:state.suggestions = []
|
||||
let a:state.choice = 0
|
||||
let a:state.error = a:result
|
||||
if get(b:, '_copilot') is# a:state
|
||||
call s:UpdatePreview()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#Suggest() abort
|
||||
if !s:Running()
|
||||
return ''
|
||||
endif
|
||||
try
|
||||
call copilot#Complete(function('s:HandleTriggerResult'), function('s:HandleTriggerError'))
|
||||
catch
|
||||
call copilot#logger#Exception()
|
||||
endtry
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:Trigger(bufnr, timer) abort
|
||||
let timer = get(g:, '_copilot_timer', -1)
|
||||
if a:bufnr !=# bufnr('') || a:timer isnot# timer || mode() !=# 'i'
|
||||
return
|
||||
endif
|
||||
unlet! g:_copilot_timer
|
||||
return copilot#Suggest()
|
||||
endfunction
|
||||
|
||||
function! copilot#Schedule() abort
|
||||
if !s:has_ghost_text || !s:Running() || !copilot#Enabled()
|
||||
call copilot#Clear()
|
||||
return
|
||||
endif
|
||||
call s:UpdatePreview()
|
||||
let delay = get(g:, 'copilot_idle_delay', 45)
|
||||
call timer_stop(get(g:, '_copilot_timer', -1))
|
||||
let g:_copilot_timer = timer_start(delay, function('s:Trigger', [bufnr('')]))
|
||||
endfunction
|
||||
|
||||
function! s:Attach(bufnr, ...) abort
|
||||
try
|
||||
return copilot#Client().Attach(a:bufnr)
|
||||
catch
|
||||
call copilot#logger#Exception()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! copilot#OnFileType() abort
|
||||
if empty(s:BufferDisabled()) && &l:modifiable && &l:buflisted
|
||||
call copilot#util#Defer(function('s:Attach'), bufnr(''))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Focus(bufnr, ...) abort
|
||||
if s:Running() && copilot#Client().IsAttached(a:bufnr)
|
||||
call copilot#Client().Notify('textDocument/didFocus', {'textDocument': {'uri': copilot#Client().Attach(a:bufnr).uri}})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#OnBufEnter() abort
|
||||
let bufnr = bufnr('')
|
||||
call copilot#util#Defer(function('s:Focus'), bufnr)
|
||||
endfunction
|
||||
|
||||
function! copilot#OnInsertLeavePre() abort
|
||||
call copilot#Clear()
|
||||
call s:ClearPreview()
|
||||
endfunction
|
||||
|
||||
function! copilot#OnInsertEnter() abort
|
||||
return copilot#Schedule()
|
||||
endfunction
|
||||
|
||||
function! copilot#OnCompleteChanged() abort
|
||||
if s:HideDuringCompletion()
|
||||
return copilot#Clear()
|
||||
else
|
||||
return copilot#Schedule()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#OnCursorMovedI() abort
|
||||
return copilot#Schedule()
|
||||
endfunction
|
||||
|
||||
function! copilot#OnBufUnload() abort
|
||||
endfunction
|
||||
|
||||
function! copilot#OnVimLeavePre() abort
|
||||
endfunction
|
||||
|
||||
function! copilot#TextQueuedForInsertion() abort
|
||||
try
|
||||
return remove(s:, 'suggestion_text')
|
||||
catch
|
||||
return ''
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! copilot#Accept(...) abort
|
||||
let s = copilot#GetDisplayedSuggestion()
|
||||
if !empty(s.text)
|
||||
unlet! b:_copilot
|
||||
let text = ''
|
||||
if a:0 > 1
|
||||
let text = substitute(matchstr(s.text, "\n*" . '\%(' . a:2 .'\)'), "\n*$", '', '')
|
||||
endif
|
||||
if empty(text)
|
||||
let text = s.text
|
||||
endif
|
||||
if text ==# s.text && has_key(s.item, 'command')
|
||||
call copilot#Request('workspace/executeCommand', s.item.command)
|
||||
else
|
||||
let line_text = strpart(getline('.'), 0, col('.') - 1) . text
|
||||
call copilot#Notify('textDocument/didPartiallyAcceptCompletion', {
|
||||
\ 'item': s.item,
|
||||
\ 'acceptedLength': copilot#util#UTF16Width(line_text) - s.item.range.start.character})
|
||||
endif
|
||||
call s:ClearPreview()
|
||||
let s:suggestion_text = text
|
||||
let recall = text =~# "\n" ? "\<C-R>\<C-O>=" : "\<C-R>\<C-R>="
|
||||
return repeat("\<Left>\<Del>", s.outdentSize) . repeat("\<Del>", s.deleteSize) .
|
||||
\ recall . "copilot#TextQueuedForInsertion()\<CR>" . (a:0 > 1 ? '' : "\<End>")
|
||||
endif
|
||||
let default = get(g:, 'copilot_tab_fallback', pumvisible() ? "\<C-N>" : "\t")
|
||||
if !a:0
|
||||
return default
|
||||
elseif type(a:1) == v:t_string
|
||||
return a:1
|
||||
elseif type(a:1) == v:t_func
|
||||
try
|
||||
return call(a:1, [])
|
||||
catch
|
||||
return default
|
||||
endtry
|
||||
else
|
||||
return default
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#AcceptWord(...) abort
|
||||
return copilot#Accept(a:0 ? a:1 : '', '\%(\k\@!.\)*\k*')
|
||||
endfunction
|
||||
|
||||
function! copilot#AcceptLine(...) abort
|
||||
return copilot#Accept(a:0 ? a:1 : "\r", "[^\n]\\+")
|
||||
endfunction
|
||||
|
||||
function! s:BrowserCallback(into, code) abort
|
||||
let a:into.code = a:code
|
||||
endfunction
|
||||
|
||||
function! copilot#Browser() abort
|
||||
if type(get(g:, 'copilot_browser')) == v:t_list
|
||||
let cmd = copy(g:copilot_browser)
|
||||
elseif type(get(g:, 'open_command')) == v:t_list
|
||||
let cmd = copy(g:open_command)
|
||||
elseif has('win32')
|
||||
let cmd = ['rundll32', 'url.dll,FileProtocolHandler']
|
||||
elseif has('mac')
|
||||
let cmd = ['open']
|
||||
elseif executable('wslview')
|
||||
return ['wslview']
|
||||
elseif executable('xdg-open')
|
||||
return ['xdg-open']
|
||||
else
|
||||
return []
|
||||
endif
|
||||
if executable(get(cmd, 0, ''))
|
||||
return cmd
|
||||
else
|
||||
return []
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:commands = {}
|
||||
|
||||
function! s:EnabledStatusMessage() abort
|
||||
let buf_disabled = s:BufferDisabled()
|
||||
if !s:has_ghost_text
|
||||
if has('nvim')
|
||||
return "Neovim 0.6 required to support ghost text"
|
||||
else
|
||||
return "Vim " . s:vim_minimum_version . " required to support ghost text"
|
||||
endif
|
||||
elseif !get(g:, 'copilot_enabled', 1)
|
||||
return 'Disabled globally by :Copilot disable'
|
||||
elseif buf_disabled is# 5
|
||||
return 'Disabled for current buffer by buftype=' . &buftype
|
||||
elseif buf_disabled is# 4
|
||||
return 'Disabled for current buffer by b:copilot_enabled'
|
||||
elseif buf_disabled is# 3
|
||||
return 'Disabled for current buffer by b:copilot_disabled'
|
||||
elseif buf_disabled is# 2
|
||||
return 'Disabled for filetype=' . &filetype . ' by internal default'
|
||||
elseif buf_disabled
|
||||
return 'Disabled for filetype=' . &filetype . ' by g:copilot_filetypes'
|
||||
elseif !copilot#Enabled()
|
||||
return 'BUG: Something is wrong with enabling/disabling'
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:VerifySetup() abort
|
||||
let error = copilot#Client().StartupError()
|
||||
if !empty(error)
|
||||
echo 'Copilot: ' . error
|
||||
return
|
||||
endif
|
||||
|
||||
let status = copilot#Call('checkStatus', {})
|
||||
|
||||
if !has_key(status, 'user')
|
||||
echo 'Copilot: Not authenticated. Invoke :Copilot setup'
|
||||
return
|
||||
endif
|
||||
|
||||
if status.status ==# 'NoTelemetryConsent'
|
||||
echo 'Copilot: Telemetry terms not accepted. Invoke :Copilot setup'
|
||||
return
|
||||
endif
|
||||
|
||||
if status.status ==# 'NotAuthorized'
|
||||
echo "Copilot: You don't have access to GitHub Copilot. Sign up by visiting https://github.com/settings/copilot"
|
||||
return
|
||||
endif
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:commands.status(opts) abort
|
||||
if !s:VerifySetup()
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('s:client.status.status') && s:client.status.status =~# 'Warning\|Error'
|
||||
echo 'Copilot: ' . s:client.status.status
|
||||
if !empty(get(s:client.status, 'message', ''))
|
||||
echon ': ' . s:client.status.message
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
let status = s:EnabledStatusMessage()
|
||||
if !empty(status)
|
||||
echo 'Copilot: ' . status
|
||||
return
|
||||
endif
|
||||
|
||||
echo 'Copilot: Ready'
|
||||
call s:EditorVersionWarning()
|
||||
endfunction
|
||||
|
||||
function! s:commands.signout(opts) abort
|
||||
let status = copilot#Call('checkStatus', {'options': {'localChecksOnly': v:true}})
|
||||
if has_key(status, 'user')
|
||||
echo 'Copilot: Signed out as GitHub user ' . status.user
|
||||
else
|
||||
echo 'Copilot: Not signed in'
|
||||
endif
|
||||
call copilot#Call('signOut', {})
|
||||
endfunction
|
||||
|
||||
function! s:commands.setup(opts) abort
|
||||
let startup_error = copilot#Client().StartupError()
|
||||
if !empty(startup_error)
|
||||
echo 'Copilot: ' . startup_error
|
||||
return
|
||||
endif
|
||||
|
||||
let browser = copilot#Browser()
|
||||
|
||||
let status = copilot#Call('checkStatus', {})
|
||||
if has_key(status, 'user')
|
||||
let data = {'status': 'AlreadySignedIn', 'user': status.user}
|
||||
else
|
||||
let data = copilot#Call('signInInitiate', {})
|
||||
endif
|
||||
|
||||
if has_key(data, 'verificationUri')
|
||||
let uri = data.verificationUri
|
||||
if has('clipboard')
|
||||
try
|
||||
let @+ = data.userCode
|
||||
catch
|
||||
endtry
|
||||
try
|
||||
let @* = data.userCode
|
||||
catch
|
||||
endtry
|
||||
endif
|
||||
let codemsg = "First copy your one-time code: " . data.userCode . "\n"
|
||||
try
|
||||
if len(&mouse)
|
||||
let mouse = &mouse
|
||||
set mouse=
|
||||
endif
|
||||
if get(a:opts, 'bang')
|
||||
call s:Echo(codemsg . "In your browser, visit " . uri)
|
||||
elseif len(browser)
|
||||
call input(codemsg . "Press ENTER to open GitHub in your browser\n")
|
||||
let status = {}
|
||||
call copilot#job#Stream(browser + [uri], v:null, v:null, function('s:BrowserCallback', [status]))
|
||||
let time = reltime()
|
||||
while empty(status) && reltimefloat(reltime(time)) < 5
|
||||
sleep 10m
|
||||
endwhile
|
||||
if get(status, 'code', browser[0] !=# 'xdg-open') != 0
|
||||
call s:Echo("Failed to open browser. Visit " . uri)
|
||||
else
|
||||
call s:Echo("Opened " . uri)
|
||||
endif
|
||||
else
|
||||
call s:Echo(codemsg . "Could not find browser. Visit " . uri)
|
||||
endif
|
||||
call s:Echo("Waiting (could take up to 10 seconds)")
|
||||
let request = copilot#Request('signInConfirm', {'userCode': data.userCode}).Wait()
|
||||
finally
|
||||
if exists('mouse')
|
||||
let &mouse = mouse
|
||||
endif
|
||||
endtry
|
||||
if request.status ==# 'error'
|
||||
return 'echoerr ' . string('Copilot: Authentication failure: ' . request.error.message)
|
||||
else
|
||||
let status = request.result
|
||||
endif
|
||||
elseif get(data, 'status', '') isnot# 'AlreadySignedIn'
|
||||
return 'echoerr ' . string('Copilot: Something went wrong')
|
||||
endif
|
||||
|
||||
let user = get(status, 'user', '<unknown>')
|
||||
|
||||
echo 'Copilot: Authenticated as GitHub user ' . user
|
||||
endfunction
|
||||
|
||||
let s:commands.auth = s:commands.setup
|
||||
let s:commands.signin = s:commands.setup
|
||||
|
||||
function! s:commands.help(opts) abort
|
||||
return a:opts.mods . ' help ' . (len(a:opts.arg) ? ':Copilot_' . a:opts.arg : 'copilot')
|
||||
endfunction
|
||||
|
||||
function! s:commands.version(opts) abort
|
||||
echo 'copilot.vim ' .copilot#client#EditorPluginInfo().version
|
||||
let editorInfo = copilot#client#EditorInfo()
|
||||
echo editorInfo.name . ' ' . editorInfo.version
|
||||
if s:Running()
|
||||
let versions = s:client.Request('getVersion', {})
|
||||
if exists('s:client.serverInfo.version')
|
||||
echo s:client.serverInfo.name . ' ' . s:client.serverInfo.version
|
||||
else
|
||||
echo 'GitHub Copilot Language Server ' . versions.Await().version
|
||||
endif
|
||||
if exists('s:client.node_version')
|
||||
echo 'Node.js ' . s:client.node_version
|
||||
else
|
||||
echo 'Node.js ' . substitute(get(versions.Await(), 'runtimeVersion', '?'), '^node/', '', 'g')
|
||||
endif
|
||||
else
|
||||
echo 'Not running'
|
||||
if exists('s:client.node_version')
|
||||
echo 'Node.js ' . s:client.node_version
|
||||
endif
|
||||
endif
|
||||
if has('win32')
|
||||
echo 'Windows'
|
||||
elseif has('macunix')
|
||||
echo 'macOS'
|
||||
elseif !has('unix')
|
||||
echo 'Unknown OS'
|
||||
elseif isdirectory('/sys/kernel')
|
||||
echo 'Linux'
|
||||
else
|
||||
echo 'UNIX'
|
||||
endif
|
||||
call s:EditorVersionWarning()
|
||||
endfunction
|
||||
|
||||
function! s:UpdateEditorConfiguration() abort
|
||||
try
|
||||
if s:Running()
|
||||
call copilot#Notify('notifyChangeConfiguration', {'settings': s:EditorConfiguration()})
|
||||
endif
|
||||
catch
|
||||
call copilot#logger#Exception()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
let s:feedback_url = 'https://github.com/orgs/community/discussions/categories/copilot'
|
||||
function! s:commands.feedback(opts) abort
|
||||
echo s:feedback_url
|
||||
let browser = copilot#Browser()
|
||||
if len(browser)
|
||||
call copilot#job#Stream(browser + [s:feedback_url], v:null, v:null, v:null)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:commands.restart(opts) abort
|
||||
call s:Stop()
|
||||
echo 'Copilot: Restarting language server'
|
||||
call s:Start()
|
||||
endfunction
|
||||
|
||||
function! s:commands.disable(opts) abort
|
||||
let g:copilot_enabled = 0
|
||||
call s:UpdateEditorConfiguration()
|
||||
endfunction
|
||||
|
||||
function! s:commands.enable(opts) abort
|
||||
let g:copilot_enabled = 1
|
||||
call s:UpdateEditorConfiguration()
|
||||
endfunction
|
||||
|
||||
function! s:commands.panel(opts) abort
|
||||
if s:VerifySetup()
|
||||
return copilot#panel#Open(a:opts)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:commands.log(opts) abort
|
||||
return a:opts.mods . ' split +$ copilot:///log'
|
||||
endfunction
|
||||
|
||||
function! copilot#CommandComplete(arg, lead, pos) abort
|
||||
let args = matchstr(strpart(a:lead, 0, a:pos), 'C\%[opilot][! ] *\zs.*')
|
||||
if args !~# ' '
|
||||
return sort(filter(map(keys(s:commands), { k, v -> tr(v, '_', '-') }),
|
||||
\ { k, v -> strpart(v, 0, len(a:arg)) ==# a:arg }))
|
||||
else
|
||||
return []
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#Command(line1, line2, range, bang, mods, arg) abort
|
||||
let cmd = matchstr(a:arg, '^\%(\\.\|\S\)\+')
|
||||
let arg = matchstr(a:arg, '\s\zs\S.*')
|
||||
if !empty(cmd) && !has_key(s:commands, tr(cmd, '-', '_'))
|
||||
return 'echoerr ' . string('Copilot: unknown command ' . string(cmd))
|
||||
endif
|
||||
try
|
||||
if empty(cmd)
|
||||
if !s:Running()
|
||||
let cmd = 'restart'
|
||||
else
|
||||
try
|
||||
let opts = copilot#Call('checkStatus', {'options': {'localChecksOnly': v:true}})
|
||||
if opts.status !=# 'OK' && opts.status !=# 'MaybeOK'
|
||||
let cmd = 'setup'
|
||||
else
|
||||
let cmd = 'panel'
|
||||
endif
|
||||
catch
|
||||
call copilot#logger#Exception()
|
||||
let cmd = 'log'
|
||||
endtry
|
||||
endif
|
||||
endif
|
||||
let opts = {'line1': a:line1, 'line2': a:line2, 'range': a:range, 'bang': a:bang, 'mods': a:mods, 'arg': arg}
|
||||
let retval = s:commands[tr(cmd, '-', '_')](opts)
|
||||
if type(retval) == v:t_string
|
||||
return retval
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
catch /^Copilot:/
|
||||
return 'echoerr ' . string(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
@@ -1,764 +0,0 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
let s:plugin_version = copilot#version#String()
|
||||
|
||||
let s:error_canceled = {'code': -32800, 'message': 'Canceled'}
|
||||
let s:error_exit = {'code': -32097, 'message': 'Process exited'}
|
||||
let s:error_connection_inactive = {'code': -32096, 'message': 'Connection inactive'}
|
||||
|
||||
let s:root = expand('<sfile>:h:h:h')
|
||||
|
||||
if !exists('s:instances')
|
||||
let s:instances = {}
|
||||
endif
|
||||
|
||||
" allow sourcing this file to reload the Lua file too
|
||||
if has('nvim')
|
||||
lua package.loaded._copilot = nil
|
||||
endif
|
||||
|
||||
function! s:Warn(msg) abort
|
||||
if !empty(get(g:, 'copilot_no_startup_warnings'))
|
||||
return
|
||||
endif
|
||||
echohl WarningMsg
|
||||
echomsg 'Copilot: ' . a:msg
|
||||
echohl NONE
|
||||
endfunction
|
||||
|
||||
function! s:VimClose() dict abort
|
||||
if !has_key(self, 'job')
|
||||
return
|
||||
endif
|
||||
let job = self.job
|
||||
if has_key(self, 'kill')
|
||||
call job_stop(job, 'kill')
|
||||
call copilot#logger#Warn('Process forcefully terminated')
|
||||
return
|
||||
endif
|
||||
let self.kill = v:true
|
||||
let self.shutdown = self.Request('shutdown', {}, function(self.Notify, ['exit']))
|
||||
call timer_start(2000, { _ -> job_stop(job, 'kill') })
|
||||
call copilot#logger#Debug('Process shutdown initiated')
|
||||
endfunction
|
||||
|
||||
function! s:LogSend(request, line) abort
|
||||
return '--> ' . a:line
|
||||
endfunction
|
||||
|
||||
function! s:RejectRequest(request, error) abort
|
||||
if a:request.status !=# 'running'
|
||||
return
|
||||
endif
|
||||
let a:request.waiting = {}
|
||||
call remove(a:request, 'resolve')
|
||||
let reject = remove(a:request, 'reject')
|
||||
let a:request.status = 'error'
|
||||
let a:request.error = deepcopy(a:error)
|
||||
for Cb in reject
|
||||
let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', Cb]))] = 1
|
||||
endfor
|
||||
if index([s:error_canceled.code, s:error_connection_inactive.code], a:error.code) != -1
|
||||
return
|
||||
endif
|
||||
let msg = 'Method ' . a:request.method . ' errored with E' . a:error.code . ': ' . json_encode(a:error.message)
|
||||
if empty(reject)
|
||||
call copilot#logger#Error(msg)
|
||||
else
|
||||
call copilot#logger#Debug(msg)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:AfterInitialized(fn, ...) dict abort
|
||||
call add(self.after_initialized, function(a:fn, a:000))
|
||||
endfunction
|
||||
|
||||
function! s:Send(instance, request) abort
|
||||
if !has_key(a:instance, 'job')
|
||||
return v:false
|
||||
endif
|
||||
try
|
||||
call ch_sendexpr(a:instance.job, a:request)
|
||||
return v:true
|
||||
catch /^Vim\%((\a\+)\)\=:E906:/
|
||||
let a:instance.kill = v:true
|
||||
let job = remove(a:instance, 'job')
|
||||
call job_stop(job)
|
||||
call timer_start(2000, { _ -> job_stop(job, 'kill') })
|
||||
call copilot#logger#Warn('Terminating process after failed write')
|
||||
return v:false
|
||||
catch /^Vim\%((\a\+)\)\=:E631:/
|
||||
return v:false
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:VimNotify(method, params) dict abort
|
||||
let request = {'method': a:method, 'params': a:params}
|
||||
call self.AfterInitialized(function('s:Send', [self, request]))
|
||||
endfunction
|
||||
|
||||
function! s:RequestWait() dict abort
|
||||
while self.status ==# 'running'
|
||||
sleep 1m
|
||||
endwhile
|
||||
while !empty(get(self, 'waiting', {}))
|
||||
sleep 1m
|
||||
endwhile
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:RequestAwait() dict abort
|
||||
call self.Wait()
|
||||
if has_key(self, 'result')
|
||||
return self.result
|
||||
endif
|
||||
throw 'Copilot:E' . self.error.code . ': ' . self.error.message
|
||||
endfunction
|
||||
|
||||
function! s:RequestClient() dict abort
|
||||
return get(s:instances, self.client_id, v:null)
|
||||
endfunction
|
||||
|
||||
if !exists('s:id')
|
||||
let s:id = 0
|
||||
endif
|
||||
if !exists('s:progress_token_id')
|
||||
let s:progress_token_id = 0
|
||||
endif
|
||||
|
||||
function! s:SetUpRequest(instance, id, method, params, progress, ...) abort
|
||||
let request = {
|
||||
\ 'client_id': a:instance.id,
|
||||
\ 'id': a:id,
|
||||
\ 'method': a:method,
|
||||
\ 'params': a:params,
|
||||
\ 'Client': function('s:RequestClient'),
|
||||
\ 'Wait': function('s:RequestWait'),
|
||||
\ 'Await': function('s:RequestAwait'),
|
||||
\ 'Cancel': function('s:RequestCancel'),
|
||||
\ 'resolve': [],
|
||||
\ 'reject': [],
|
||||
\ 'progress': a:progress,
|
||||
\ 'status': 'running'}
|
||||
let args = a:000[2:-1]
|
||||
if len(args)
|
||||
if !empty(a:1)
|
||||
call add(request.resolve, { v -> call(a:1, [v] + args)})
|
||||
endif
|
||||
if !empty(a:2)
|
||||
call add(request.reject, { v -> call(a:2, [v] + args)})
|
||||
endif
|
||||
return request
|
||||
endif
|
||||
if a:0 && !empty(a:1)
|
||||
call add(request.resolve, a:1)
|
||||
endif
|
||||
if a:0 > 1 && !empty(a:2)
|
||||
call add(request.reject, a:2)
|
||||
endif
|
||||
return request
|
||||
endfunction
|
||||
|
||||
function! s:UrlEncode(str) abort
|
||||
return substitute(iconv(a:str, 'latin1', 'utf-8'),'[^A-Za-z0-9._~!$&''()*+,;=:@/-]','\="%".printf("%02X",char2nr(submatch(0)))','g')
|
||||
endfunction
|
||||
|
||||
let s:slash = exists('+shellslash') ? '\' : '/'
|
||||
function! s:UriFromBufnr(bufnr) abort
|
||||
let absolute = tr(bufname(a:bufnr), s:slash, '/')
|
||||
if absolute !~# '^\a\+:\|^/\|^$' && getbufvar(a:bufnr, 'buftype') =~# '^\%(nowrite\)\=$'
|
||||
let absolute = substitute(tr(getcwd(), s:slash, '/'), '/\=$', '/', '') . absolute
|
||||
endif
|
||||
return s:UriFromPath(absolute)
|
||||
endfunction
|
||||
|
||||
function! s:UriFromPath(absolute) abort
|
||||
let absolute = a:absolute
|
||||
if has('win32') && absolute =~# '^\a://\@!'
|
||||
return 'file:///' . strpart(absolute, 0, 2) . s:UrlEncode(strpart(absolute, 2))
|
||||
elseif absolute =~# '^/'
|
||||
return 'file://' . s:UrlEncode(absolute)
|
||||
elseif absolute =~# '^\a[[:alnum:].+-]*:\|^$'
|
||||
return absolute
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:BufferText(bufnr) abort
|
||||
return join(getbufline(a:bufnr, 1, '$'), "\n") . "\n"
|
||||
endfunction
|
||||
|
||||
let s:valid_request_key = '^\%(id\|method\|params\)$'
|
||||
function! s:SendRequest(instance, request, ...) abort
|
||||
if !has_key(a:instance, 'job') || get(a:instance, 'shutdown', a:request) isnot# a:request
|
||||
return s:RejectRequest(a:request, s:error_connection_inactive)
|
||||
endif
|
||||
let json = filter(copy(a:request), 'v:key =~# s:valid_request_key')
|
||||
if empty(s:Send(a:instance, json)) && has_key(a:request, 'id') && has_key(a:instance.requests, a:request.id)
|
||||
call s:RejectRequest(remove(a:instance.requests, a:request.id), {'code': -32099, 'message': 'Write failed'})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RegisterWorkspaceFolderForBuffer(instance, buf) abort
|
||||
let root = getbufvar(a:buf, 'workspace_folder')
|
||||
if type(root) != v:t_string
|
||||
return
|
||||
endif
|
||||
let root = s:UriFromPath(substitute(root, '[\/]$', '', ''))
|
||||
if empty(root) || has_key(a:instance.workspaceFolders, root)
|
||||
return
|
||||
endif
|
||||
let a:instance.workspaceFolders[root] = v:true
|
||||
call a:instance.Notify('workspace/didChangeWorkspaceFolders', {'event': {'added': [{'uri': root, 'name': fnamemodify(root, ':t')}], 'removed': []}})
|
||||
endfunction
|
||||
|
||||
function! s:PreprocessParams(instance, params) abort
|
||||
let bufnr = v:null
|
||||
for doc in filter([get(a:params, 'textDocument', {})], 'type(get(v:val, "uri", "")) == v:t_number')
|
||||
let bufnr = doc.uri
|
||||
call s:RegisterWorkspaceFolderForBuffer(a:instance, bufnr)
|
||||
call extend(doc, a:instance.Attach(bufnr))
|
||||
endfor
|
||||
let progress_tokens = []
|
||||
for key in keys(a:params)
|
||||
if key =~# 'Token$' && type(a:params[key]) == v:t_func
|
||||
let s:progress_token_id += 1
|
||||
let a:instance.progress[s:progress_token_id] = a:params[key]
|
||||
call add(progress_tokens, s:progress_token_id)
|
||||
let a:params[key] = s:progress_token_id
|
||||
endif
|
||||
endfor
|
||||
return [bufnr, progress_tokens]
|
||||
endfunction
|
||||
|
||||
function! s:VimAttach(bufnr) dict abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return {'uri': '', 'version': 0}
|
||||
endif
|
||||
let bufnr = a:bufnr
|
||||
let doc = {
|
||||
\ 'uri': s:UriFromBufnr(bufnr),
|
||||
\ 'version': getbufvar(bufnr, 'changedtick', 0),
|
||||
\ 'languageId': getbufvar(bufnr, '&filetype'),
|
||||
\ }
|
||||
if has_key(self.open_buffers, bufnr) && (
|
||||
\ self.open_buffers[bufnr].uri !=# doc.uri ||
|
||||
\ self.open_buffers[bufnr].languageId !=# doc.languageId)
|
||||
call self.Notify('textDocument/didClose', {'textDocument': {'uri': self.open_buffers[bufnr].uri}})
|
||||
call remove(self.open_buffers, bufnr)
|
||||
endif
|
||||
if !has_key(self.open_buffers, bufnr)
|
||||
call self.Notify('textDocument/didOpen', {'textDocument': extend({'text': s:BufferText(bufnr)}, doc)})
|
||||
let self.open_buffers[bufnr] = doc
|
||||
else
|
||||
call self.Notify('textDocument/didChange', {
|
||||
\ 'textDocument': {'uri': doc.uri, 'version': doc.version},
|
||||
\ 'contentChanges': [{'text': s:BufferText(bufnr)}]})
|
||||
let self.open_buffers[bufnr].version = doc.version
|
||||
endif
|
||||
return doc
|
||||
endfunction
|
||||
|
||||
function! s:VimIsAttached(bufnr) dict abort
|
||||
return bufloaded(a:bufnr) && has_key(self.open_buffers, a:bufnr) ? v:true : v:false
|
||||
endfunction
|
||||
|
||||
function! s:VimRequest(method, params, ...) dict abort
|
||||
let s:id += 1
|
||||
let params = deepcopy(a:params)
|
||||
let [_, progress] = s:PreprocessParams(self, params)
|
||||
let request = call('s:SetUpRequest', [self, s:id, a:method, params, progress] + a:000)
|
||||
call self.AfterInitialized(function('s:SendRequest', [self, request]))
|
||||
let self.requests[s:id] = request
|
||||
return request
|
||||
endfunction
|
||||
|
||||
function! s:Call(method, params, ...) dict abort
|
||||
let request = call(self.Request, [a:method, a:params] + a:000)
|
||||
if a:0
|
||||
return request
|
||||
endif
|
||||
return request.Await()
|
||||
endfunction
|
||||
|
||||
function! s:Cancel(request) dict abort
|
||||
if has_key(self.requests, get(a:request, 'id', ''))
|
||||
call self.Notify('$/cancelRequest', {'id': a:request.id})
|
||||
call s:RejectRequest(remove(self.requests, a:request.id), s:error_canceled)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RequestCancel() dict abort
|
||||
let instance = self.Client()
|
||||
if !empty(instance)
|
||||
call instance.Cancel(self)
|
||||
elseif get(self, 'status', '') ==# 'running'
|
||||
call s:RejectRequest(self, s:error_canceled)
|
||||
endif
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:DispatchMessage(instance, method, handler, id, params, ...) abort
|
||||
try
|
||||
let response = {'result': call(a:handler, [a:params, a:instance])}
|
||||
if response.result is# 0
|
||||
let response.result = v:null
|
||||
endif
|
||||
catch
|
||||
call copilot#logger#Exception('lsp.request.' . a:method)
|
||||
let response = {'error': {'code': -32000, 'message': v:exception}}
|
||||
endtry
|
||||
if a:id isnot# v:null
|
||||
call s:Send(a:instance, extend({'id': a:id}, response))
|
||||
endif
|
||||
if !has_key(s:notifications, a:method)
|
||||
return response
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnMessage(instance, body, ...) abort
|
||||
if !has_key(a:body, 'method')
|
||||
return s:OnResponse(a:instance, a:body)
|
||||
endif
|
||||
let request = a:body
|
||||
let id = get(request, 'id', v:null)
|
||||
let params = get(request, 'params', v:null)
|
||||
if has_key(a:instance.methods, request.method)
|
||||
return s:DispatchMessage(a:instance, request.method, a:instance.methods[request.method], id, params)
|
||||
elseif id isnot# v:null
|
||||
call s:Send(a:instance, {"id": id, "error": {"code": -32700, "message": "Method not found: " . request.method}})
|
||||
call copilot#logger#Debug('Unexpected request ' . request.method . ' called with ' . json_encode(params))
|
||||
elseif request.method !~# '^\$/'
|
||||
call copilot#logger#Debug('Unexpected notification ' . request.method . ' called with ' . json_encode(params))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnResponse(instance, response, ...) abort
|
||||
let response = a:response
|
||||
let id = get(a:response, 'id', v:null)
|
||||
if !has_key(a:instance.requests, id)
|
||||
return
|
||||
endif
|
||||
let request = remove(a:instance.requests, id)
|
||||
for progress_token in request.progress
|
||||
if has_key(a:instance.progress, progress_token)
|
||||
call remove(a:instance.progress, progress_token)
|
||||
endif
|
||||
endfor
|
||||
if request.status !=# 'running'
|
||||
return
|
||||
endif
|
||||
if has_key(response, 'result')
|
||||
let request.waiting = {}
|
||||
let resolve = remove(request, 'resolve')
|
||||
call remove(request, 'reject')
|
||||
let request.status = 'success'
|
||||
let request.result = response.result
|
||||
for Cb in resolve
|
||||
let request.waiting[timer_start(0, function('s:Callback', [request, 'result', Cb]))] = 1
|
||||
endfor
|
||||
else
|
||||
call s:RejectRequest(request, response.error)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnErr(instance, ch, line, ...) abort
|
||||
if !has_key(a:instance, 'serverInfo')
|
||||
call copilot#logger#Bare('<-! ' . a:line)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnExit(instance, code, ...) abort
|
||||
let a:instance.exit_status = a:code
|
||||
if has_key(a:instance, 'job')
|
||||
call remove(a:instance, 'job')
|
||||
endif
|
||||
if has_key(a:instance, 'client_id')
|
||||
call remove(a:instance, 'client_id')
|
||||
endif
|
||||
let message = 'Process exited with status ' . a:code
|
||||
if a:code >= 18 && a:code < 100
|
||||
let message = 'Node.js too old. ' .
|
||||
\ (get(a:instance.node, 0, 'node') ==# 'node' ? 'Upgrade' : 'Change g:copilot_node_command') .
|
||||
\ ' to ' . a:code . '.x or newer'
|
||||
endif
|
||||
if !has_key(a:instance, 'serverInfo') && !has_key(a:instance, 'startup_error')
|
||||
let a:instance.startup_error = message
|
||||
endif
|
||||
for id in sort(keys(a:instance.requests), { a, b -> +a > +b })
|
||||
call s:RejectRequest(remove(a:instance.requests, id), s:error_exit)
|
||||
endfor
|
||||
if has_key(a:instance, 'after_initialized')
|
||||
let a:instance.AfterInitialized = function('copilot#util#Defer')
|
||||
for Fn in remove(a:instance, 'after_initialized')
|
||||
call copilot#util#Defer(Fn)
|
||||
endfor
|
||||
endif
|
||||
call copilot#util#Defer({ -> get(s:instances, a:instance.id) is# a:instance ? remove(s:instances, a:instance.id) : {} })
|
||||
if a:code == 0
|
||||
call copilot#logger#Info(message)
|
||||
else
|
||||
call copilot#logger#Warn(message)
|
||||
if !has_key(a:instance, 'kill')
|
||||
call copilot#util#Defer(function('s:Warn'), message)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#client#LspInit(id, initialize_result) abort
|
||||
if !has_key(s:instances, a:id)
|
||||
return
|
||||
endif
|
||||
call s:PostInit(a:initialize_result, s:instances[a:id])
|
||||
endfunction
|
||||
|
||||
function! copilot#client#LspExit(id, code, signal) abort
|
||||
if !has_key(s:instances, a:id)
|
||||
return
|
||||
endif
|
||||
let instance = remove(s:instances, a:id)
|
||||
call s:OnExit(instance, a:code)
|
||||
endfunction
|
||||
|
||||
function! copilot#client#LspResponse(id, opts, ...) abort
|
||||
if !has_key(s:instances, a:id)
|
||||
return
|
||||
endif
|
||||
call s:OnResponse(s:instances[a:id], a:opts)
|
||||
endfunction
|
||||
|
||||
function! s:NvimAttach(bufnr) dict abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return {'uri': '', 'version': 0}
|
||||
endif
|
||||
call luaeval('pcall(vim.lsp.buf_attach_client, _A[1], _A[2])', [a:bufnr, self.id])
|
||||
return luaeval('{uri = vim.uri_from_bufnr(_A), version = vim.lsp.util.buf_versions[_A]}', a:bufnr)
|
||||
endfunction
|
||||
|
||||
function! s:NvimIsAttached(bufnr) dict abort
|
||||
return bufloaded(a:bufnr) ? luaeval('vim.lsp.buf_is_attached(_A[1], _A[2])', [a:bufnr, self.id]) : v:false
|
||||
endfunction
|
||||
|
||||
function! s:NvimRequest(method, params, ...) dict abort
|
||||
let params = deepcopy(a:params)
|
||||
let [bufnr, progress] = s:PreprocessParams(self, params)
|
||||
let request = call('s:SetUpRequest', [self, v:null, a:method, params, progress] + a:000)
|
||||
call self.AfterInitialized(function('s:NvimDoRequest', [self, request, bufnr]))
|
||||
return request
|
||||
endfunction
|
||||
|
||||
function! s:NvimDoRequest(client, request, bufnr) abort
|
||||
let request = a:request
|
||||
if has_key(a:client, 'client_id') && !has_key(a:client, 'kill')
|
||||
let request.id = eval("v:lua.require'_copilot'.lsp_request(a:client.id, a:request.method, a:request.params, a:bufnr)")
|
||||
endif
|
||||
if request.id isnot# v:null
|
||||
let a:client.requests[request.id] = request
|
||||
else
|
||||
if has_key(a:client, 'client_id')
|
||||
call copilot#client#LspExit(a:client.client_id, -1, -1)
|
||||
endif
|
||||
call copilot#util#Defer(function('s:RejectRequest'), request, s:error_connection_inactive)
|
||||
endif
|
||||
return request
|
||||
endfunction
|
||||
|
||||
function! s:NvimClose() dict abort
|
||||
if !has_key(self, 'client_id')
|
||||
return
|
||||
endif
|
||||
let self.kill = v:true
|
||||
return luaeval('vim.lsp.get_client_by_id(_A).stop()', self.client_id)
|
||||
endfunction
|
||||
|
||||
function! s:NvimNotify(method, params) dict abort
|
||||
call self.AfterInitialized(function('s:NvimDoNotify', [self.client_id, a:method, a:params]))
|
||||
endfunction
|
||||
|
||||
function! s:NvimDoNotify(client_id, method, params) abort
|
||||
return eval("v:lua.require'_copilot'.rpc_notify(a:client_id, a:method, a:params)")
|
||||
endfunction
|
||||
|
||||
function! copilot#client#LspHandle(id, request) abort
|
||||
if !has_key(s:instances, a:id)
|
||||
return
|
||||
endif
|
||||
return s:OnMessage(s:instances[a:id], a:request)
|
||||
endfunction
|
||||
|
||||
let s:script_name = 'dist/language-server.js'
|
||||
function! s:Command() abort
|
||||
if !has('nvim-0.7') && v:version < 900
|
||||
return [[], [], 'Vim version too old']
|
||||
endif
|
||||
let script = get(g:, 'copilot_command', '')
|
||||
if type(script) == type('')
|
||||
let script = [expand(script)]
|
||||
endif
|
||||
if empty(script) || !filereadable(script[0])
|
||||
let script = [s:root . '/' . s:script_name]
|
||||
if !filereadable(script[0])
|
||||
return [[], [], 'Could not find ' . s:script_name . ' (bad install?)']
|
||||
endif
|
||||
elseif script[0] !~# '\.js$'
|
||||
return [[], script + ['--stdio'], '']
|
||||
endif
|
||||
let node = get(g:, 'copilot_node_command', '')
|
||||
if empty(node)
|
||||
let node = ['node']
|
||||
elseif type(node) == type('')
|
||||
let node = [expand(node)]
|
||||
endif
|
||||
if !executable(get(node, 0, ''))
|
||||
if get(node, 0, '') ==# 'node'
|
||||
return [[], [], 'Node.js not found in PATH']
|
||||
else
|
||||
return [[], [], 'Node.js executable `' . get(node, 0, '') . "' not found"]
|
||||
endif
|
||||
endif
|
||||
return [node, script + ['--stdio'], '']
|
||||
endfunction
|
||||
|
||||
function! s:UrlDecode(str) abort
|
||||
return substitute(a:str, '%\(\x\x\)', '\=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")', 'g')
|
||||
endfunction
|
||||
|
||||
function! copilot#client#EditorInfo() abort
|
||||
if !exists('s:editor_version')
|
||||
if has('nvim')
|
||||
let s:editor_version = matchstr(execute('version'), 'NVIM v\zs[^[:space:]]\+')
|
||||
else
|
||||
let s:editor_version = (v:version / 100) . '.' . (v:version % 100) . (exists('v:versionlong') ? printf('.%04d', v:versionlong % 10000) : '')
|
||||
endif
|
||||
endif
|
||||
return {'name': has('nvim') ? 'Neovim': 'Vim', 'version': s:editor_version}
|
||||
endfunction
|
||||
|
||||
function! copilot#client#EditorPluginInfo() abort
|
||||
return {'name': 'copilot.vim', 'version': s:plugin_version}
|
||||
endfunction
|
||||
|
||||
function! copilot#client#Settings() abort
|
||||
let settings = {
|
||||
\ 'http': {
|
||||
\ 'proxy': get(g:, 'copilot_proxy', v:null),
|
||||
\ 'proxyStrictSSL': get(g:, 'copilot_proxy_strict_ssl', v:null)},
|
||||
\ 'github-enterprise': {'uri': get(g:, 'copilot_auth_provider_url', v:null)},
|
||||
\ }
|
||||
if type(settings.http.proxy) ==# v:t_string && settings.http.proxy =~# '^[^/]\+$'
|
||||
let settings.http.proxy = 'http://' . settings.http.proxy
|
||||
endif
|
||||
if type(get(g:, 'copilot_settings')) == v:t_dict
|
||||
call extend(settings, g:copilot_settings)
|
||||
endif
|
||||
return settings
|
||||
endfunction
|
||||
|
||||
function! s:PostInit(result, instance) abort
|
||||
let a:instance.serverInfo = get(a:result, 'serverInfo', {})
|
||||
if !has_key(a:instance, 'node_version') && has_key(a:result.serverInfo, 'nodeVersion')
|
||||
let a:instance.node_version = a:result.serverInfo.nodeVersion
|
||||
endif
|
||||
let a:instance.AfterInitialized = function('copilot#util#Defer')
|
||||
for Fn in remove(a:instance, 'after_initialized')
|
||||
call copilot#util#Defer(Fn)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:InitializeResult(result, instance) abort
|
||||
call s:Send(a:instance, {'method': 'initialized', 'params': {}})
|
||||
call s:PostInit(a:result, a:instance)
|
||||
endfunction
|
||||
|
||||
function! s:InitializeError(error, instance) abort
|
||||
if !has_key(a:instance, 'startup_error')
|
||||
let a:instance.startup_error = 'Unexpected error E' . a:error.code . ' initializing language server: ' . a:error.message
|
||||
call a:instance.Close()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:StartupError() dict abort
|
||||
while (has_key(self, 'job') || has_key(self, 'client_id')) && !has_key(self, 'startup_error') && !has_key(self, 'serverInfo')
|
||||
sleep 10m
|
||||
endwhile
|
||||
if has_key(self, 'serverInfo')
|
||||
return ''
|
||||
else
|
||||
return get(self, 'startup_error', 'Something unexpected went wrong spawning the language server')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:StatusNotification(params, instance) abort
|
||||
let a:instance.status = a:params
|
||||
endfunction
|
||||
|
||||
function! s:Nop(...) abort
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! s:False(...) abort
|
||||
return v:false
|
||||
endfunction
|
||||
|
||||
function! s:Progress(params, instance) abort
|
||||
if has_key(a:instance.progress, a:params.token)
|
||||
call a:instance.progress[a:params.token](a:params.value)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:notifications = {
|
||||
\ '$/progress': function('s:Progress'),
|
||||
\ 'featureFlagsNotification': function('s:Nop'),
|
||||
\ 'statusNotification': function('s:StatusNotification'),
|
||||
\ 'window/logMessage': function('copilot#handlers#window_logMessage'),
|
||||
\ }
|
||||
|
||||
let s:vim_handlers = {
|
||||
\ 'window/showMessageRequest': function('copilot#handlers#window_showMessageRequest'),
|
||||
\ 'window/showDocument': function('copilot#handlers#window_showDocument'),
|
||||
\ }
|
||||
|
||||
let s:vim_capabilities = {
|
||||
\ 'workspace': {'workspaceFolders': v:true},
|
||||
\ 'window': {'showDocument': {'support': v:true}},
|
||||
\ }
|
||||
|
||||
function! copilot#client#New(...) abort
|
||||
let opts = a:0 ? a:1 : {}
|
||||
let instance = {'requests': {},
|
||||
\ 'progress': {},
|
||||
\ 'workspaceFolders': {},
|
||||
\ 'after_initialized': [],
|
||||
\ 'status': {'status': 'Starting', 'message': ''},
|
||||
\ 'AfterInitialized': function('s:AfterInitialized'),
|
||||
\ 'Close': function('s:Nop'),
|
||||
\ 'Notify': function('s:False'),
|
||||
\ 'Request': function('s:VimRequest'),
|
||||
\ 'Attach': function('s:Nop'),
|
||||
\ 'IsAttached': function('s:False'),
|
||||
\ 'Call': function('s:Call'),
|
||||
\ 'Cancel': function('s:Cancel'),
|
||||
\ 'StartupError': function('s:StartupError'),
|
||||
\ }
|
||||
let instance.methods = copy(s:notifications)
|
||||
let [node, argv, command_error] = s:Command()
|
||||
if !empty(command_error)
|
||||
let instance.id = -1
|
||||
let instance.startup_error = command_error
|
||||
call copilot#logger#Error(command_error)
|
||||
return instance
|
||||
endif
|
||||
let instance.node = node
|
||||
let command = node + argv
|
||||
let opts = {}
|
||||
let opts.initializationOptions = {
|
||||
\ 'editorInfo': copilot#client#EditorInfo(),
|
||||
\ 'editorPluginInfo': copilot#client#EditorPluginInfo(),
|
||||
\ }
|
||||
let opts.workspaceFolders = []
|
||||
let settings = extend(copilot#client#Settings(), get(opts, 'editorConfiguration', {}))
|
||||
if type(get(g:, 'copilot_workspace_folders')) == v:t_list
|
||||
for folder in g:copilot_workspace_folders
|
||||
if type(folder) == v:t_string && !empty(folder) && folder !~# '\*\*\|^/$'
|
||||
for path in glob(folder . '/', 0, 1)
|
||||
let uri = s:UriFromPath(substitute(path, '[\/]*$', '', ''))
|
||||
call add(opts.workspaceFolders, {'uri': uri, 'name': fnamemodify(uri, ':t')})
|
||||
endfor
|
||||
elseif type(folder) == v:t_dict && has_key(v:t_dict, 'uri') && !empty(folder.uri) && has_key(folder, 'name')
|
||||
call add(opts.workspaceFolders, folder)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
for folder in opts.workspaceFolders
|
||||
let instance.workspaceFolders[folder.uri] = v:true
|
||||
endfor
|
||||
if has('nvim')
|
||||
call extend(instance, {
|
||||
\ 'Close': function('s:NvimClose'),
|
||||
\ 'Notify': function('s:NvimNotify'),
|
||||
\ 'Request': function('s:NvimRequest'),
|
||||
\ 'Attach': function('s:NvimAttach'),
|
||||
\ 'IsAttached': function('s:NvimIsAttached'),
|
||||
\ })
|
||||
let instance.client_id = eval("v:lua.require'_copilot'.lsp_start_client(command, keys(instance.methods), opts, settings)")
|
||||
let instance.id = instance.client_id
|
||||
else
|
||||
call extend(instance, {
|
||||
\ 'Close': function('s:VimClose'),
|
||||
\ 'Notify': function('s:VimNotify'),
|
||||
\ 'Attach': function('s:VimAttach'),
|
||||
\ 'IsAttached': function('s:VimIsAttached'),
|
||||
\ })
|
||||
let state = {'headers': {}, 'mode': 'headers', 'buffer': ''}
|
||||
let instance.open_buffers = {}
|
||||
let instance.methods = extend(s:vim_handlers, instance.methods)
|
||||
let instance.job = job_start(command, {
|
||||
\ 'cwd': copilot#job#Cwd(),
|
||||
\ 'noblock': 1,
|
||||
\ 'stoponexit': '',
|
||||
\ 'in_mode': 'lsp',
|
||||
\ 'out_mode': 'lsp',
|
||||
\ 'out_cb': { j, d -> copilot#util#Defer(function('s:OnMessage'), instance, d) },
|
||||
\ 'err_cb': function('s:OnErr', [instance]),
|
||||
\ 'exit_cb': { j, d -> copilot#util#Defer(function('s:OnExit'), instance, d) },
|
||||
\ })
|
||||
let instance.id = job_info(instance.job).process
|
||||
let opts.capabilities = s:vim_capabilities
|
||||
let opts.processId = getpid()
|
||||
let request = instance.Request('initialize', opts, function('s:InitializeResult'), function('s:InitializeError'), instance)
|
||||
call call(remove(instance.after_initialized, 0), [])
|
||||
call instance.Notify('workspace/didChangeConfiguration', {'settings': settings})
|
||||
endif
|
||||
let s:instances[instance.id] = instance
|
||||
return instance
|
||||
endfunction
|
||||
|
||||
function! copilot#client#Cancel(request) abort
|
||||
if type(a:request) == type({}) && has_key(a:request, 'Cancel')
|
||||
call a:request.Cancel()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Callback(request, type, callback, timer) abort
|
||||
call remove(a:request.waiting, a:timer)
|
||||
if has_key(a:request, a:type)
|
||||
call a:callback(a:request[a:type])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#client#Result(request, callback) abort
|
||||
if has_key(a:request, 'resolve')
|
||||
call add(a:request.resolve, a:callback)
|
||||
elseif has_key(a:request, 'result')
|
||||
let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'result', a:callback]))] = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#client#Error(request, callback) abort
|
||||
if has_key(a:request, 'reject')
|
||||
call add(a:request.reject, a:callback)
|
||||
elseif has_key(a:request, 'error')
|
||||
let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', a:callback]))] = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:CloseBuffer(bufnr) abort
|
||||
for instance in values(s:instances)
|
||||
try
|
||||
if has_key(instance, 'job') && has_key(instance.open_buffers, a:bufnr)
|
||||
let buffer = remove(instance.open_buffers, a:bufnr)
|
||||
call instance.Notify('textDocument/didClose', {'textDocument': {'uri': buffer.uri}})
|
||||
endif
|
||||
catch
|
||||
call copilot#logger#Exception()
|
||||
endtry
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
augroup copilot_close
|
||||
autocmd!
|
||||
if !has('nvim')
|
||||
autocmd BufUnload * call s:CloseBuffer(+expand('<abuf>'))
|
||||
endif
|
||||
augroup END
|
||||
@@ -1,31 +0,0 @@
|
||||
function! copilot#handlers#window_logMessage(params, ...) abort
|
||||
call copilot#logger#Raw(get(a:params, 'type', 6), get(a:params, 'message', ''))
|
||||
endfunction
|
||||
|
||||
function! copilot#handlers#window_showMessageRequest(params, ...) abort
|
||||
let choice = inputlist([a:params.message . "\n\nRequest Actions:"] +
|
||||
\ map(copy(get(a:params, 'actions', [])), { i, v -> (i + 1) . '. ' . v.title}))
|
||||
return choice > 0 ? get(a:params.actions, choice - 1, v:null) : v:null
|
||||
endfunction
|
||||
|
||||
function! s:BrowserCallback(into, code) abort
|
||||
let a:into.code = a:code
|
||||
endfunction
|
||||
|
||||
function! copilot#handlers#window_showDocument(params, ...) abort
|
||||
echo a:params.uri
|
||||
if empty(get(a:params, 'external'))
|
||||
return {'success': v:false}
|
||||
endif
|
||||
let browser = copilot#Browser()
|
||||
if empty(browser)
|
||||
return {'success': v:false}
|
||||
endif
|
||||
let status = {}
|
||||
call copilot#job#Stream(browser + [a:params.uri], v:null, v:null, function('s:BrowserCallback', [status]))
|
||||
let time = reltime()
|
||||
while empty(status) && reltimefloat(reltime(time)) < 1
|
||||
sleep 10m
|
||||
endwhile
|
||||
return {'success': get(status, 'code') ? v:false : v:true}
|
||||
endfunction
|
||||
@@ -1,106 +0,0 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
function! copilot#job#Nop(...) abort
|
||||
endfunction
|
||||
|
||||
function! s:Jobs(job_or_jobs) abort
|
||||
let jobs = type(a:job_or_jobs) == v:t_list ? copy(a:job_or_jobs) : [a:job_or_jobs]
|
||||
call map(jobs, { k, v -> type(v) == v:t_dict ? get(v, 'job', '') : v })
|
||||
call filter(jobs, { k, v -> type(v) !=# type('') })
|
||||
return jobs
|
||||
endfunction
|
||||
|
||||
let s:job_stop = exists('*job_stop') ? 'job_stop' : 'jobstop'
|
||||
function! copilot#job#Stop(job) abort
|
||||
for job in s:Jobs(a:job)
|
||||
call call(s:job_stop, [job])
|
||||
endfor
|
||||
return copilot#job#Wait(a:job)
|
||||
endfunction
|
||||
|
||||
let s:sleep = has('patch-8.2.2366') ? 'sleep! 1m' : 'sleep 1m'
|
||||
function! copilot#job#Wait(jobs) abort
|
||||
let jobs = s:Jobs(a:jobs)
|
||||
if exists('*jobwait')
|
||||
call jobwait(jobs)
|
||||
else
|
||||
for job in jobs
|
||||
while ch_status(job) !=# 'closed' || job_status(job) ==# 'run'
|
||||
exe s:sleep
|
||||
endwhile
|
||||
endfor
|
||||
endif
|
||||
return a:jobs
|
||||
endfunction
|
||||
|
||||
function! s:VimExitCallback(result, exit_cb, job, data) abort
|
||||
let a:result.exit_status = a:data
|
||||
if !has_key(a:result, 'closed')
|
||||
return
|
||||
endif
|
||||
call remove(a:result, 'closed')
|
||||
call a:exit_cb(a:result.exit_status)
|
||||
endfunction
|
||||
|
||||
function! s:VimCloseCallback(result, exit_cb, job) abort
|
||||
if !has_key(a:result, 'exit_status')
|
||||
let a:result.closed = v:true
|
||||
return
|
||||
endif
|
||||
call a:exit_cb(a:result.exit_status)
|
||||
endfunction
|
||||
|
||||
function! s:NvimCallback(cb, job, data, type) dict abort
|
||||
let self[a:type][0] .= remove(a:data, 0)
|
||||
call extend(self[a:type], a:data)
|
||||
while len(self[a:type]) > 1
|
||||
call a:cb(substitute(remove(self[a:type], 0), "\r$", '', ''))
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
function! s:NvimExitCallback(out_cb, err_cb, exit_cb, job, data, type) dict abort
|
||||
if len(self.stderr[0])
|
||||
call a:err_cb(substitute(self.stderr[0], "\r$", '', ''))
|
||||
endif
|
||||
call a:exit_cb(a:data)
|
||||
endfunction
|
||||
|
||||
function! copilot#job#Cwd() abort
|
||||
let home = expand("~")
|
||||
if !isdirectory(home) && isdirectory($VIM)
|
||||
return $VIM
|
||||
endif
|
||||
return home
|
||||
endfunction
|
||||
|
||||
function! copilot#job#Stream(argv, out_cb, err_cb, ...) abort
|
||||
let exit_status = []
|
||||
let ExitCb = function(a:0 && !empty(a:1) ? a:1 : { e -> add(exit_status, e) }, a:000[2:-1])
|
||||
let OutCb = function(empty(a:out_cb) ? 'copilot#job#Nop' : a:out_cb, a:000[2:-1])
|
||||
let ErrCb = function(empty(a:err_cb) ? 'copilot#job#Nop' : a:err_cb, a:000[2:-1])
|
||||
let state = {'headers': {}, 'mode': 'headers', 'buffer': ''}
|
||||
if exists('*job_start')
|
||||
let result = {}
|
||||
let job = job_start(a:argv, {
|
||||
\ 'cwd': copilot#job#Cwd(),
|
||||
\ 'out_mode': 'raw',
|
||||
\ 'out_cb': { j, d -> OutCb(d) },
|
||||
\ 'err_cb': { j, d -> ErrCb(d) },
|
||||
\ 'exit_cb': function('s:VimExitCallback', [result, ExitCb]),
|
||||
\ 'close_cb': function('s:VimCloseCallback', [result, ExitCb]),
|
||||
\ })
|
||||
else
|
||||
let jopts = {
|
||||
\ 'cwd': copilot#job#Cwd(),
|
||||
\ 'stderr': [''],
|
||||
\ 'on_stdout': { j, d, t -> OutCb(join(d, "\n")) },
|
||||
\ 'on_stderr': function('s:NvimCallback', [ErrCb]),
|
||||
\ 'on_exit': function('s:NvimExitCallback', [OutCb, ErrCb, ExitCb])}
|
||||
let job = jobstart(a:argv, jopts)
|
||||
endif
|
||||
if a:0
|
||||
return job
|
||||
endif
|
||||
call copilot#job#Wait(job)
|
||||
return exit_status[0]
|
||||
endfunction
|
||||
@@ -1,105 +0,0 @@
|
||||
if !exists('s:log_file')
|
||||
let s:log_file = tempname() . '-copilot.log'
|
||||
try
|
||||
call writefile([], s:log_file)
|
||||
catch
|
||||
endtry
|
||||
endif
|
||||
|
||||
let s:logs = []
|
||||
|
||||
function! copilot#logger#BufReadCmd() abort
|
||||
try
|
||||
setlocal modifiable noreadonly
|
||||
silent call deletebufline('', 1, '$')
|
||||
if !empty(s:logs)
|
||||
call setline(1, s:logs)
|
||||
endif
|
||||
finally
|
||||
setlocal buftype=nofile bufhidden=wipe nobuflisted nomodified nomodifiable
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
let s:level_prefixes = ['', '[ERROR] ', '[WARN] ', '[INFO] ', '[DEBUG] ', '[DEBUG] ']
|
||||
|
||||
function! copilot#logger#Raw(level, message) abort
|
||||
let lines = type(a:message) == v:t_list ? copy(a:message) : split(a:message, "\n", 1)
|
||||
let lines[0] = strftime('[%Y-%m-%d %H:%M:%S] ') . get(s:level_prefixes, a:level, '[UNKNOWN] ') . get(lines, 0, '')
|
||||
try
|
||||
if !filewritable(s:log_file)
|
||||
return
|
||||
endif
|
||||
call map(lines, { k, L -> type(L) == v:t_func ? call(L, []) : L })
|
||||
call extend(s:logs, lines)
|
||||
let overflow = len(s:logs) - get(g:, 'copilot_log_history', 10000)
|
||||
if overflow > 0
|
||||
call remove(s:logs, 0, overflow - 1)
|
||||
endif
|
||||
let bufnr = bufnr('copilot:///log')
|
||||
if bufnr > 0 && bufloaded(bufnr)
|
||||
call setbufvar(bufnr, '&modifiable', 1)
|
||||
call setbufline(bufnr, 1, s:logs)
|
||||
call setbufvar(bufnr, '&modifiable', 0)
|
||||
for winid in win_findbuf(bufnr)
|
||||
if has('nvim') && winid != win_getid()
|
||||
call nvim_win_set_cursor(winid, [len(s:logs), 0])
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
catch
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! copilot#logger#Debug(...) abort
|
||||
if empty(get(g:, 'copilot_debug'))
|
||||
return
|
||||
endif
|
||||
call copilot#logger#Raw(4, a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#logger#Info(...) abort
|
||||
call copilot#logger#Raw(3, a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#logger#Warn(...) abort
|
||||
call copilot#logger#Raw(2, a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#logger#Error(...) abort
|
||||
call copilot#logger#Raw(1, a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#logger#Bare(...) abort
|
||||
call copilot#logger#Raw(0, a:000)
|
||||
endfunction
|
||||
|
||||
function! copilot#logger#Exception(...) abort
|
||||
if !empty(v:exception) && v:exception !=# 'Vim:Interrupt'
|
||||
call copilot#logger#Error('Exception: ' . v:exception . ' @ ' . v:throwpoint)
|
||||
let client = copilot#RunningClient()
|
||||
if !empty(client)
|
||||
let [_, type, code, message; __] = matchlist(v:exception, '^\%(\(^[[:alnum:]_#]\+\)\%((\a\+)\)\=\%(\(:E-\=\d\+\)\)\=:\s*\)\=\(.*\)$')
|
||||
let stacklines = []
|
||||
for frame in split(substitute(v:throwpoint, ', \S\+ \(\d\+\)$', '[\1]', ''), '\.\@<!\.\.\.\@!')
|
||||
let fn_line = matchlist(frame, '^\%(function \)\=\(\S\+\)\[\(\d\+\)\]$')
|
||||
if !empty(fn_line)
|
||||
call add(stacklines, {'function': substitute(fn_line[1], '^<SNR>\d\+_', '<SID>', ''), 'lineno': +fn_line[2]})
|
||||
elseif frame =~# ' Autocmds for "\*"$'
|
||||
call add(stacklines, {'function': frame})
|
||||
elseif frame =~# ' Autocmds for ".*"$'
|
||||
call add(stacklines, {'function': substitute(frame, ' for ".*"$', ' for "[redacted]"', '')})
|
||||
else
|
||||
call add(stacklines, {'function': '[redacted]'})
|
||||
endif
|
||||
endfor
|
||||
return client.Request('telemetry/exception', {
|
||||
\ 'transaction': a:0 ? a:1 : '',
|
||||
\ 'platform': 'other',
|
||||
\ 'exception_detail': [{
|
||||
\ 'type': type . code,
|
||||
\ 'value': message,
|
||||
\ 'stacktrace': stacklines}]
|
||||
\ }, v:null, function('copilot#util#Nop'))
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
@@ -1,167 +0,0 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
if !exists('s:panel_id')
|
||||
let s:panel_id = 0
|
||||
endif
|
||||
|
||||
let s:separator = repeat('─', 72)
|
||||
|
||||
function! s:Render(state) abort
|
||||
let bufnr = bufnr('^' . a:state.panel . '$')
|
||||
let state = a:state
|
||||
if !bufloaded(bufnr)
|
||||
return
|
||||
endif
|
||||
let sorted = a:state.items
|
||||
if !empty(get(a:state, 'error'))
|
||||
let lines = ['Error: ' . a:state.error.message]
|
||||
let sorted = []
|
||||
elseif get(a:state, 'percentage') == 100
|
||||
let lines = ['Synthesized ' . (len(sorted) == 1 ? '1 completion' : len(sorted) . ' completions')]
|
||||
else
|
||||
let lines = [substitute('Synthesizing ' . matchstr(get(a:state, 'message', ''), '\d\+\%(/\d\+\)\=') . ' completions', ' \+', ' ', 'g')]
|
||||
endif
|
||||
if len(sorted)
|
||||
call add(lines, 'Press <CR> on a completion to accept')
|
||||
endif
|
||||
let leads = {}
|
||||
for item in sorted
|
||||
let insert = split(item.insertText, "\r\n\\=\\|\n", 1)
|
||||
let insert[0] = strpart(a:state.line, 0, copilot#util#UTF16ToByteIdx(a:state.line, item.range.start.character)) . insert[0]
|
||||
let lines += [s:separator] + insert
|
||||
if !has_key(leads, string(item.range.start))
|
||||
let match = insert[0 : a:state.position.line - item.range.start.line]
|
||||
let match[-1] = strpart(match[-1], 0, copilot#util#UTF16ToByteIdx(match[-1], a:state.position.character))
|
||||
call map(match, { k, v -> escape(v, '][^$.*\~') })
|
||||
let leads[string(item.range.start)] = join(match, '\n')
|
||||
endif
|
||||
endfor
|
||||
try
|
||||
call setbufvar(bufnr, '&modifiable', 1)
|
||||
call setbufvar(bufnr, '&readonly', 0)
|
||||
call setbufline(bufnr, 1, lines)
|
||||
finally
|
||||
call setbufvar(bufnr, '&modifiable', 0)
|
||||
endtry
|
||||
call clearmatches()
|
||||
call matchadd('CopilotSuggestion', '\C^' . s:separator . '\n\zs\%(' . join(sort(values(leads), { a, b -> len(b) - len(a) }), '\|') . '\)', 10, 4)
|
||||
endfunction
|
||||
|
||||
function! s:PartialResult(state, value) abort
|
||||
let items = type(a:value) == v:t_list ? a:value : a:value.items
|
||||
call extend(a:state.items, items)
|
||||
call s:Render(a:state)
|
||||
endfunction
|
||||
|
||||
function! s:WorkDone(state, value) abort
|
||||
if has_key(a:value, 'message')
|
||||
let a:state.message = a:value.message
|
||||
endif
|
||||
if has_key(a:value, 'percentage')
|
||||
let a:state.percentage = a:value.percentage
|
||||
call s:Render(a:state)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! copilot#panel#Accept(...) abort
|
||||
let state = get(b:, 'copilot_panel', {})
|
||||
if empty(state.items)
|
||||
return ''
|
||||
endif
|
||||
if !has_key(state, 'bufnr') || !bufloaded(get(state, 'bufnr', -1))
|
||||
return "echoerr 'Buffer was closed'"
|
||||
endif
|
||||
let at = a:0 ? a:1 : line('.')
|
||||
let index = 0
|
||||
for lnum in range(1, at)
|
||||
if getline(lnum) ==# s:separator
|
||||
let index += 1
|
||||
endif
|
||||
endfor
|
||||
if index > 0 && index <= len(state.items)
|
||||
let item = state.items[index - 1]
|
||||
let lnum = item.range.start.line + 1
|
||||
if getbufline(state.bufnr, lnum) !=# [state.line]
|
||||
return 'echoerr "Buffer has changed since synthesizing completion"'
|
||||
endif
|
||||
let lines = split(item.insertText, "\n", 1)
|
||||
let old_first = getbufline(state.bufnr, item.range.start.line + 1)[0]
|
||||
let lines[0] = strpart(old_first, 0, copilot#util#UTF16ToByteIdx(old_first, item.range.start.character)) . lines[0]
|
||||
let old_last = getbufline(state.bufnr, item.range.end.line + 1)[0]
|
||||
let lines[-1] .= strpart(old_last, copilot#util#UTF16ToByteIdx(old_last, item.range.end.character))
|
||||
call deletebufline(state.bufnr, item.range.start.line + 1, item.range.end.line + 1)
|
||||
call appendbufline(state.bufnr, item.range.start.line, lines)
|
||||
call copilot#Request('workspace/executeCommand', item.command)
|
||||
bwipeout
|
||||
let win = bufwinnr(state.bufnr)
|
||||
if win > 0
|
||||
exe win . 'wincmd w'
|
||||
exe item.range.start.line + len(lines)
|
||||
if state.was_insert
|
||||
startinsert!
|
||||
else
|
||||
normal! $
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:Initialize(state) abort
|
||||
let &l:filetype = 'copilot' . (empty(a:state.filetype) ? '' : '.' . a:state.filetype)
|
||||
let &l:tabstop = a:state.tabstop
|
||||
nmap <buffer><script> <CR> <Cmd>exe copilot#panel#Accept()<CR>
|
||||
nmap <buffer><script> [[ <Cmd>call search('^─\{9,}\n.', 'bWe')<CR>
|
||||
nmap <buffer><script> ]] <Cmd>call search('^─\{9,}\n.', 'We')<CR>
|
||||
endfunction
|
||||
|
||||
function! s:BufReadCmd() abort
|
||||
setlocal bufhidden=wipe buftype=nofile nobuflisted nomodifiable
|
||||
let state = get(b:, 'copilot_panel')
|
||||
if type(state) != v:t_dict
|
||||
return
|
||||
endif
|
||||
call s:Initialize(state)
|
||||
call s:Render(state)
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:Result(state, result) abort
|
||||
let a:state.percentage = 100
|
||||
call s:PartialResult(a:state, a:result)
|
||||
endfunction
|
||||
|
||||
function! s:Error(state, error) abort
|
||||
let a:state.error = a:error
|
||||
call s:Render(a:state)
|
||||
endfunction
|
||||
|
||||
function! copilot#panel#Open(opts) abort
|
||||
let s:panel_id += 1
|
||||
let state = {'items': [], 'filetype': &filetype, 'was_insert': mode() =~# '^[iR]', 'bufnr': bufnr(''), 'tabstop': &tabstop}
|
||||
let state.panel = 'copilot:///panel/' . s:panel_id
|
||||
if state.was_insert
|
||||
let state.position = copilot#util#AppendPosition()
|
||||
stopinsert
|
||||
else
|
||||
let state.position = {'line': a:opts.line1 >= 1 ? a:opts.line1 - 1 : 0, 'character': copilot#util#UTF16Width(getline('.'))}
|
||||
endif
|
||||
let state.line = getline(state.position.line + 1)
|
||||
let params = {
|
||||
\ 'textDocument': {'uri': state.bufnr},
|
||||
\ 'position': state.position,
|
||||
\ 'partialResultToken': function('s:PartialResult', [state]),
|
||||
\ 'workDoneToken': function('s:WorkDone', [state]),
|
||||
\ }
|
||||
let response = copilot#Request('textDocument/copilotPanelCompletion', params, function('s:Result', [state]), function('s:Error', [state]))
|
||||
exe substitute(a:opts.mods, '\C\<tab\>', '-tab', 'g') 'keepalt split' state.panel
|
||||
let b:copilot_panel = state
|
||||
call s:Initialize(state)
|
||||
call s:Render(state)
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
augroup github_copilot_panel
|
||||
autocmd!
|
||||
autocmd BufReadCmd copilot:///panel/* exe s:BufReadCmd()
|
||||
augroup END
|
||||
@@ -1,61 +0,0 @@
|
||||
let s:deferred = []
|
||||
|
||||
function! copilot#util#Nop(...) abort
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! copilot#util#Defer(fn, ...) abort
|
||||
call add(s:deferred, function(a:fn, a:000))
|
||||
return timer_start(0, function('s:RunDeferred'))
|
||||
endfunction
|
||||
|
||||
function! s:RunDeferred(...) abort
|
||||
if empty(s:deferred)
|
||||
return
|
||||
endif
|
||||
let Fn = remove(s:deferred, 0)
|
||||
call timer_start(0, function('s:RunDeferred'))
|
||||
call call(Fn, [])
|
||||
endfunction
|
||||
|
||||
function! copilot#util#UTF16Width(str) abort
|
||||
return strchars(substitute(a:str, "\\%#=2[^\u0001-\uffff]", " ", 'g'))
|
||||
endfunction
|
||||
|
||||
if exists('*utf16idx')
|
||||
|
||||
function! copilot#util#UTF16ToByteIdx(str, utf16_idx) abort
|
||||
return byteidx(a:str, a:utf16_idx, 1)
|
||||
endfunction
|
||||
|
||||
elseif has('nvim')
|
||||
|
||||
function! copilot#util#UTF16ToByteIdx(str, utf16_idx) abort
|
||||
try
|
||||
return v:lua.vim.str_byteindex(a:str, a:utf16_idx, 1)
|
||||
catch /^Vim(return):E5108:/
|
||||
return -1
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
else
|
||||
|
||||
function! copilot#util#UTF16ToByteIdx(str, utf16_idx) abort
|
||||
if copilot#util#UTF16Width(a:str) < a:utf16_idx
|
||||
return -1
|
||||
endif
|
||||
let end_offset = len(a:str)
|
||||
while copilot#util#UTF16Width(strpart(a:str, 0, end_offset)) > a:utf16_idx && end_offset > 0
|
||||
let end_offset -= 1
|
||||
endwhile
|
||||
return end_offset
|
||||
endfunction
|
||||
|
||||
endif
|
||||
|
||||
function! copilot#util#AppendPosition() abort
|
||||
let line = getline('.')
|
||||
let col_byte = col('.') - (mode() =~# '^[iR]' || empty(line))
|
||||
let col_utf16 = copilot#util#UTF16Width(strpart(line, 0, col_byte))
|
||||
return {'line': line('.') - 1, 'character': col_utf16}
|
||||
endfunction
|
||||
@@ -1,3 +0,0 @@
|
||||
function! copilot#version#String() abort
|
||||
return '1.41.0'
|
||||
endfunction
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.vim/pack/plugins/opt/vim-copilot/dist/crypt32.node
vendored
BIN
.vim/pack/plugins/opt/vim-copilot/dist/crypt32.node
vendored
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user