From bf7347380207d80183ce80ae6547ef08fa579c6a Mon Sep 17 00:00:00 2001 From: Polesznyák Márk Date: Sat, 29 Nov 2025 01:45:07 +0100 Subject: feat: add scripts, TARGET variable for Makefile --- .stow-local-ignore | 1 + .tmux-coreutils | 6 + .tmux-langs | 7 + .tmux.conf | 4 +- Makefile | 23 +- README.md | 6 +- scripts/bash-completor | 734 +++++++++++++++++++++++++++++++++++++++++++++++++ scripts/checktodo | 11 + scripts/cht.sh | 15 + scripts/fcopy | 8 + scripts/gitline | 6 + scripts/internet | 4 + scripts/origin | 12 + scripts/publicip | 3 + scripts/screenshot | 6 + scripts/tags | 3 + scripts/tmus | 30 ++ 17 files changed, 873 insertions(+), 6 deletions(-) create mode 100644 .tmux-coreutils create mode 100644 .tmux-langs create mode 100755 scripts/bash-completor create mode 100755 scripts/checktodo create mode 100755 scripts/cht.sh create mode 100755 scripts/fcopy create mode 100755 scripts/gitline create mode 100755 scripts/internet create mode 100755 scripts/origin create mode 100755 scripts/publicip create mode 100755 scripts/screenshot create mode 100755 scripts/tags create mode 100755 scripts/tmus diff --git a/.stow-local-ignore b/.stow-local-ignore index 1a7f152..7ef69fb 100644 --- a/.stow-local-ignore +++ b/.stow-local-ignore @@ -6,3 +6,4 @@ ^/README.* Makefile +scripts diff --git a/.tmux-coreutils b/.tmux-coreutils new file mode 100644 index 0000000..bafe029 --- /dev/null +++ b/.tmux-coreutils @@ -0,0 +1,6 @@ +awk +jq +find +ffmpeg +xargs +rsync diff --git a/.tmux-langs b/.tmux-langs new file mode 100644 index 0000000..3616951 --- /dev/null +++ b/.tmux-langs @@ -0,0 +1,7 @@ +lua +bash +c +rust +hare +haskell +elixir diff --git a/.tmux.conf b/.tmux.conf index f172bd2..f956f1a 100644 --- a/.tmux.conf +++ b/.tmux.conf @@ -14,7 +14,7 @@ bind v split-window -h -c "#{pane_current_path}" unbind '"' bind - split-window -v -c "#{pane_current_path}" -bind R source-file ~/.config/tmux/tmux.conf +bind R source-file ~/.tmux.conf bind -r j resize-pane -D 5 bind -r k resize-pane -U 5 @@ -38,7 +38,7 @@ bind-key -r C-c copy-mode bind-key -r i run-shell "tmux neww /usr/local/bin/cht.sh" bind-key -n C-f run-shell "tmux neww /usr/local/bin/tmus" -bind-key -n C-t run-shell "tmux neww /usr/local/bin/check_todo.sh" +bind-key -n C-t run-shell "tmux neww /usr/local/bin/checktodo" set -gq allow-passthrough on diff --git a/Makefile b/Makefile index e3d55ad..7beddbf 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,23 @@ +PREFIX = /usr/local +TARGET := $(HOME) +SCRIPTS := $(shell cd scripts && ls) + +default: + @echo "Current configuration:" + @echo " PREFIX: $(PREFIX)" + @echo " TARGET: $(TARGET)" + install: - stow . --target $(HOME) - git clone https://github.com/tmux-plugins/tpm $(HOME)/.tmux/plugins/tpm + stow . --target $(TARGET) + [ -d $(HOME)/.tmux/plugins/tpm ] || git clone https://github.com/tmux-plugins/tpm $(HOME)/.tmux/plugins/tpm + +install-scripts: + cd scripts && cp $(SCRIPTS) $(PREFIX)/bin/ uninstall: - stow -D . --target $(HOME) + stow -D . --target $(TARGET) + +uninstall-scripts: + cd $(PREFIX)/bin && rm -f $(SCRIPTS) + +.PHONY: default install install-scripts uninstall uninstall-scripts diff --git a/README.md b/README.md index 5ef4e06..b0731d7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,11 @@ This is my main dotfiles repo, though not all components are here. Namely: ## Usage -GNU Stow and Git are required. To install, simply run `make install`. To remove the created symlinks, run `make uninstall`. +GNU Stow and Git are required. To install, simply run `make install`. To remove the created symlinks, run `make uninstall`. A `TARGET` variable is supported, which defaults to the current user's home directory. + +For installation and later removal of custom scripts, run `make install-scripts` and `make uninstall-scripts`, respectively. A `PREFIX` variable is supported, which defaults to `/usr/local/`. + +You can check the current values by running `make`. ### tmux diff --git a/scripts/bash-completor b/scripts/bash-completor new file mode 100755 index 0000000..b013ec6 --- /dev/null +++ b/scripts/bash-completor @@ -0,0 +1,734 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail +set -o errtrace +(shopt -p inherit_errexit &>/dev/null) && shopt -s inherit_errexit + +readonly VERSION=v0.2.0 +readonly ARGS=$* +readonly SPACES_8=' ' +readonly SPACES_6=' ' +readonly SPACES_4=' ' +readonly SPACES_2=' ' + +declare -r RED="\\e[31m" +declare -r GREEN="\\e[32m" +declare -r YELLOW="\\e[33m" +declare -r CYAN="\\e[36m" +declare -r RESET_ALL="\\e[0m" + +debug() { + printf "%b[Debug] %s%b\n" "$CYAN" "$*" "$RESET_ALL" >/dev/tty +} + +warn() { + printf "%b[Warn] %s%b\n" "$YELLOW" "$*" "$RESET_ALL" >/dev/tty +} + +error() { + printf "%b[Error] %s%b\n" "$RED" "$*" "$RESET_ALL" >/dev/tty +} + +suggest() { + printf "%b[Suggest] %s%b\n" "$GREEN" "$*" "$RESET_ALL" >/dev/tty +} + +# Copy from https://github.com/adoyle-h/lobash/blob/develop/src/modules/is_array.bash +is_array() { + local attrs + # shellcheck disable=2207 + attrs=$(declare -p "$1" 2>/dev/null | sed -E "s/^declare -([-a-zA-Z]+) .+/\\1/" || true) + + # a: array + # A: associate array + if [[ ${attrs} =~ a|A ]]; then return 0; else return 1; fi +} + +is_func() { + declare -F "$1" &>/dev/null +} + +get_varname() { + local name=${1:-} + local encoded=${word_to_varname[$name]:-} + + if [[ -z ${encoded} ]]; then + encoded=${name//[^a-zA-Z_]/_} + fi + + echo "${encoded}" +} + +is_gnu_sed() { + local out + out=$(${1:-sed} --version 2>/dev/null) + [[ $out =~ 'GNU sed' ]] +} + +reply_words() { + local IFS=$'\n' + # shellcheck disable=2207 + COMPREPLY=( $(IFS=', ' compgen -W "$*" -- "${cur#=}") ) +} + +reply_list() { + local IFS=', ' + local array_list="" array_name + # shellcheck disable=2068 + for array_name in "$@"; do + array_list="$array_list \${${array_name}[*]}" + done + array_list="${array_list[*]:1}" + + IFS=$'\n'' ' + eval "COMPREPLY=( \$(compgen -W \"$array_list\" -- \"\$cur\") )" +} + +reply_files() { + local IFS=$'\n' + compopt -o nospace -o filenames + # shellcheck disable=2207 + COMPREPLY=( $(compgen -A file -- "$cur") ) +} + +reply_files_in_pattern() { + compopt -o nospace -o filenames + + local path + while read -r path; do + if [[ $path =~ $1 ]] || [[ -d $path ]]; then + COMPREPLY+=( "$path" ) + fi + done < <(compgen -A file -- "$cur") +} + +reply_dirs() { + local IFS=$'\n' + compopt -o nospace -o filenames + # shellcheck disable=2207 + COMPREPLY=( $(compgen -A directory -- "$cur") ) +} + + +make_get_varnames() { + echo "" + + declare -p word_to_varname | sed -e "s/word_to_varname/_${cmd}_comp_word_to_varname/" + + declare -f get_varname | sed -e "s/get_varname/_${cmd}_comp_util_get_varname/" -e 's/ *$//g' \ + -e "s/word_to_varname/_${cmd}_comp_word_to_varname/" +} + +make_dumped_variables() { + echo "" + local name + for name in $(compgen -A variable var_); do + declare -p "$name" | sed "s/^declare -.* var_/_${cmd}_comp_var_/" + done +} + +make_header() { + cat < 0 )); then + cat < 0 )); then + cat < 0)) && [[ ${func_arg[*]:0:1} != '@' ]]; then + printf -- "_%s_comp_reply_%s '%s'" "$cmd" "$func_name" "$func_arg" + else + printf -- '_%s_comp_reply_%s' "$cmd" "$func_name" + fi + else + error "Invalid '$position': The action '$var' is not defined." + + case $var in + @f*) suggest "Try '@files' instead of '$var'." ;; + @d*) suggest "Try '@dirs' instead of '$var'." ;; + @h*) suggest "Try '@hold' instead of '$var'." ;; + *) suggest "Try '@files', '@dirs', '@hold' or other reply functions. See https://github.com/adoyle-h/bash-completor/docs/syntax.md#reply-functions " ;; + esac + + exit 5 + fi + ;; + esac + else + if [[ -n "$var" ]]; then + printf -- "_%s_comp_reply_words '%s'" "$cmd" "$var" + else + printf ':' + fi + fi +} + +make_reply_action() { + local varname=$1 + local -n var=$varname + local reply + + if [[ -v "$varname" ]]; then + reply=$(parse_action "$var" "$varname=$var") + elif is_array "$varname"; then + reply="_${cmd}_comp_reply_list '${var}'" + else + reply="_${cmd}_comp_reply_files" + fi + + echo "$reply" +} + +make_reply_set() { + cat <> bash-debug.log +EOF + + local reply_args + + if $has_subcmds; then + cat < 1 )); then + # Enter the subcmd completion + local subcmd_varname + subcmd_varname="\$(_${cmd}_comp_util_get_varname "\${COMP_WORDS[1]}")" + if type "_${cmd}_completions_\$subcmd_varname" &>/dev/null; then + "_${cmd}_completions_\$subcmd_varname" + else + # If subcmd completion function not defined, use the fallback + "_${cmd}_completions__fallback" + fi + return 0 + fi +EOF + + reply_args="_${cmd}_comp_reply_list _${cmd}_comp_subcmds" + else + reply_args=$(make_reply_action cmd_args) + fi + + local reply_opts_fallback + if [[ -v cmd_opts_fallback ]]; then + reply_opts_fallback=$(make_reply_action cmd_opts_fallback) + else + reply_opts_fallback=$(make_reply_action cmd_args) + fi + + cat < "$output_path" + printf '%bGenerated file: %s%b\n' "${GREEN}" "$output_path" "$RESET_ALL" +} + +usage() { + cat < To generate Bash completion script based on configuration + -h|--help Print the usage + --version Print the version of bash-completor + +Description: Quickly generate Bash completion script based on configuration. + +Config Syntax: https://github.com/adoyle-h/bash-completor/docs/syntax.md + +Project: https://github.com/adoyle-h/bash-completor + +Version: $VERSION +EOF +} + +check_conf() { + local conf_path=$1 + + if [[ ! -f $conf_path ]]; then + echo "Not found config file at $conf_path" >&2 + exit 3 + fi + + # shellcheck disable=1090 + . "$conf_path" + + # Set default values of config options + cmd_name=$cmd + cmd=$(get_varname "$cmd_name") + cmd_args=${cmd_args:-@files} + subcmd_args__fallback=${subcmd_args__fallback:-@files} + + if (( ${#subcmds[@]} > 0 )); then + has_subcmds=true + fi +} + +main() { + if (( $# == 0 )); then usage; exit 0; fi + + case "$1" in + -c) + do_make "$2" + ;; + + -h|--help) + usage + ;; + + --version) + echo "$VERSION" + ;; + + *) + echo "Invalid option '$1'." >&2 + exit 2 + ;; + esac +} + +main "$@" diff --git a/scripts/checktodo b/scripts/checktodo new file mode 100755 index 0000000..e0c1eeb --- /dev/null +++ b/scripts/checktodo @@ -0,0 +1,11 @@ +#!/bin/bash + +if [ -f "./TODO.md" ]; then + FILE="./TODO.md" +elif [ -f "./TODO.txt" ]; then + FILE="./TODO.txt" +else + FILE="$HOME/TODO.md" +fi + +nvim $FILE diff --git a/scripts/cht.sh b/scripts/cht.sh new file mode 100755 index 0000000..6c27d29 --- /dev/null +++ b/scripts/cht.sh @@ -0,0 +1,15 @@ +#!/bin/sh +selected=`cat ~/.tmux-langs ~/.tmux-coreutils | fzf` +if [[ -z $selected ]]; then + exit 0 +fi + +read -p "Enter Query: " query + +if grep -qs "$selected" ~/.tmux-langs; then + query=`echo $query | tr ' ' '+'` + tmux neww bash -c "curl cht.sh/$selected/$query & while [ : ]; do sleep 1; done" +else + query=`echo $query | tr ' ' '+'` + tmux neww bash -c "curl cht.sh/$selected~$query & while [ : ]; do sleep 1; done" +fi diff --git a/scripts/fcopy b/scripts/fcopy new file mode 100755 index 0000000..d7eda81 --- /dev/null +++ b/scripts/fcopy @@ -0,0 +1,8 @@ +#!/bin/sh +if [[ "$1" == *.png ]]; then + xclip -selection clipboard -target image/png -i $1 +elif [[ "$1" == *.jpg ]] || [[ "$1" == *.jpeg ]]; then + xclip -selection clipboard -target image/jpeg -i $1 +else + bat "$1" | xclip -sel clip +fi diff --git a/scripts/gitline b/scripts/gitline new file mode 100755 index 0000000..0341f27 --- /dev/null +++ b/scripts/gitline @@ -0,0 +1,6 @@ +#!/bin/sh + +lineNumber=${1:-$(echo -n "" | dmenu -i -p "Line number:")} +file=${2:-$(echo -n "" | dmenu -i -p "Filename:")} + +git -C "$(dirname "$file")" log -L"$lineNumber",+1:"$file" diff --git a/scripts/internet b/scripts/internet new file mode 100755 index 0000000..dd9256b --- /dev/null +++ b/scripts/internet @@ -0,0 +1,4 @@ +#!/bin/sh +ip link set eth0 up +ip addr add 192.168.0.66/24 broadcast + dev eth0 +ip route add default via 192.168.0.1 dev eth0 diff --git a/scripts/origin b/scripts/origin new file mode 100755 index 0000000..ae67999 --- /dev/null +++ b/scripts/origin @@ -0,0 +1,12 @@ +#!/bin/sh +dir=${PWD##*/} +dir=${dir:-/} + +git remote add origin git@git.sr.ht:~pml68/"$dir" +echo "* text=auto eol=lf + +# Older git versions try to fix line endings on images, this prevents it. +*.png binary +*.jpg binary +*.ico binary" > .gitattributes +git config --add push.pushOption visibility="${1:-public}" diff --git a/scripts/publicip b/scripts/publicip new file mode 100755 index 0000000..af29bca --- /dev/null +++ b/scripts/publicip @@ -0,0 +1,3 @@ +#!/bin/sh + +dig +short myip.opendns.com @resolver1.opendns.com | xclip -sel clip diff --git a/scripts/screenshot b/scripts/screenshot new file mode 100755 index 0000000..45bf2f3 --- /dev/null +++ b/scripts/screenshot @@ -0,0 +1,6 @@ +#!/bin/sh +adb shell screencap /storage/emulated/0/Download/screen.png +adb pull /storage/emulated/0/Download/screen.png $HOME/Downloads/screenshots/ +adb shell rm /storage/emulated/0/Download/screen.png +xclip -selection clipboard -target image/png -i $HOME/Downloads/screenshots/screen.png +rm $HOME/Downloads/screenshots/screen.png diff --git a/scripts/tags b/scripts/tags new file mode 100755 index 0000000..89dcbc6 --- /dev/null +++ b/scripts/tags @@ -0,0 +1,3 @@ +#!/bin/sh +set -xe +ctags --sort=yes --format=2 --language-force=C --c-kinds=+pmftvux --fields=+afisS --extras=+q "$@" diff --git a/scripts/tmus b/scripts/tmus new file mode 100755 index 0000000..9bb9d5b --- /dev/null +++ b/scripts/tmus @@ -0,0 +1,30 @@ +#!/bin/sh + +if [ $# -eq 1 ]; then + selected="$1" + [ -d "$1" ] || mkdir -p "$1" +else + selected=$(find ~/projects/ ~/school/ ~/source/ ~/testing/ ~/git/ ~/QEMU/ ~/.config/ -mindepth 1 -maxdepth 1 -type d | fzf) +fi + +if [ -z "$selected" ]; then + exit 0 +fi + +selected_name=$(basename "$selected" | tr . _) +tmux_running=$(pgrep tmux) + +if [ -z "$TMUX" ] && [ -z "$tmux_running" ]; then + tmux new-session -s "$selected_name" -c "$selected" + exit 0 +fi + +if ! tmux has-session -t="$selected_name" 2> /dev/null; then + tmux new-session -ds "$selected_name" -c "$selected" +fi + +if tmux list-sessions | grep -qs attached; then + tmux switch-client -t "$selected_name" +else + tmux attach-session -t "$selected_name" +fi -- cgit v1.2.3