From beeefb13a7eb1aab4bc9dc321f606f8ca8aad5ab Mon Sep 17 00:00:00 2001 From: daniel fusser Date: Sun, 21 Jun 2026 15:35:58 +0200 Subject: [PATCH] initial commit --- .gitignore | 17 +++ bin/tmx | 9 ++ dircolors/dir_colors | 252 +++++++++++++++++++++++++++++++++++++++++++ git/attributes | 3 + git/config | 53 +++++++++ git/ignore | 12 +++ hooks/post-checkout | 5 + hooks/post-commit | 5 + hooks/post-merge | 4 + install.sh | 5 + mksh/mkshrc | 211 ++++++++++++++++++++++++++++++++++++ mksh/notes.md | 149 +++++++++++++++++++++++++ tmux/tmux.conf | 176 ++++++++++++++++++++++++++++++ 13 files changed, 901 insertions(+) create mode 100644 .gitignore create mode 100755 bin/tmx create mode 100644 dircolors/dir_colors create mode 100644 git/attributes create mode 100644 git/config create mode 100644 git/ignore create mode 100755 hooks/post-checkout create mode 100755 hooks/post-commit create mode 100755 hooks/post-merge create mode 100755 install.sh create mode 100644 mksh/mkshrc create mode 100644 mksh/notes.md create mode 100644 tmux/tmux.conf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e6441a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# ignore everything by default — explicitly un-ignore what we track +* + +!.gitignore +!hooks/ +!hooks/* +!bin/ +!bin/* +!dircolors/ +!dircolors/* +!git/ +!git/* +git/local +!mksh/ +!mksh/* +!tmux/ +!tmux/* diff --git a/bin/tmx b/bin/tmx new file mode 100755 index 0000000..050f233 --- /dev/null +++ b/bin/tmx @@ -0,0 +1,9 @@ +#!/bin/sh + +[[ -z "$TMUX" ]] || exit #exec /bin/mksh +[[ -z $1 ]] && base_session="$(hostname)" || base_session="$1" +session_id="$base_session""_""`date +%M%S`" +tmux -u has-session -t $base_session || tmux -u new-session -s $base_session -d +tmux -u new-session -d -t $base_session -s $session_id +# \; new-window +tmux -u attach-session -t $session_id \; set-option -q destroy-unattached diff --git a/dircolors/dir_colors b/dircolors/dir_colors new file mode 100644 index 0000000..3325ebb --- /dev/null +++ b/dircolors/dir_colors @@ -0,0 +1,252 @@ +# Copyright (c) 2016-present Sven Greb +# This source code is licensed under the MIT license found in the license file. + +COLOR tty + +TERM alacritty +TERM alacritty-direct +TERM ansi +TERM *color* +TERM con[0-9]*x[0-9]* +TERM cons25 +TERM console +TERM cygwin +TERM dtterm +TERM dvtm +TERM dvtm-256color +TERM Eterm +TERM eterm-color +TERM fbterm +TERM gnome +TERM foot +TERM gnome-256color +TERM hurd +TERM jfbterm +TERM konsole +TERM konsole-256color +TERM kterm +TERM linux +TERM linux-c +TERM mlterm +TERM putty +TERM putty-256color +TERM rxvt* +TERM rxvt-unicode +TERM rxvt-256color +TERM rxvt-unicode256 +TERM screen* +TERM screen-256color +TERM st +TERM st-256color +TERM terminator +TERM tmux* +TERM tmux-256color +TERM vt100 +TERM xterm* +TERM xterm-color +TERM xterm-88color +TERM xterm-256color +TERM xterm-kitty + +#+-----------------+ +#+ Global Defaults + +#+-----------------+ +NORMAL 00 +RESET 0 + +FILE 00 +DIR 01;34 +LINK 36 +MULTIHARDLINK 04;36 + +FIFO 04;01;36 +SOCK 04;33 +DOOR 04;01;36 +BLK 01;33 +CHR 33 + +ORPHAN 31 +MISSING 01;37;41 + +EXEC 01;36 + +SETUID 01;04;37 +SETGID 01;04;37 +CAPABILITY 01;37 + +STICKY_OTHER_WRITABLE 01;37;44 +OTHER_WRITABLE 01;04;34 +STICKY 04;37;44 + +#+-------------------+ +#+ Extension Pattern + +#+-------------------+ +#+--- Archives ---+ +.7z 01;32 +.ace 01;32 +.alz 01;32 +.arc 01;32 +.arj 01;32 +.bz 01;32 +.bz2 01;32 +.cab 01;32 +.cpio 01;32 +.deb 01;32 +.dz 01;32 +.ear 01;32 +.gz 01;32 +.jar 01;32 +.lha 01;32 +.lrz 01;32 +.lz 01;32 +.lz4 01;32 +.lzh 01;32 +.lzma 01;32 +.lzo 01;32 +.rar 01;32 +.rpm 01;32 +.rz 01;32 +.sar 01;32 +.t7z 01;32 +.tar 01;32 +.taz 01;32 +.tbz 01;32 +.tbz2 01;32 +.tgz 01;32 +.tlz 01;32 +.txz 01;32 +.tz 01;32 +.tzo 01;32 +.tzst 01;32 +.war 01;32 +.xz 01;32 +.z 01;32 +.Z 01;32 +.zip 01;32 +.zoo 01;32 +.zst 01;32 + +#+--- Audio ---+ +.aac 32 +.au 32 +.flac 32 +.m4a 32 +.mid 32 +.midi 32 +.mka 32 +.mp3 32 +.mpa 32 +.mpeg 32 +.mpg 32 +.ogg 32 +.opus 32 +.ra 32 +.wav 32 + +#+--- Customs ---+ +.3des 01;35 +.aes 01;35 +.gpg 01;35 +.pgp 01;35 + +#+--- Documents ---+ +.doc 32 +.docx 32 +.dot 32 +.odg 32 +.odp 32 +.ods 32 +.odt 32 +.otg 32 +.otp 32 +.ots 32 +.ott 32 +.pdf 32 +.ppt 32 +.pptx 32 +.xls 32 +.xlsx 32 + +#+--- Executables ---+ +.app 01;36 +.bat 01;36 +.btm 01;36 +.cmd 01;36 +.com 01;36 +.exe 01;36 +.reg 01;36 + +#+--- Ignores ---+ +*~ 02;37 +.bak 02;37 +.BAK 02;37 +.log 02;37 +.log 02;37 +.old 02;37 +.OLD 02;37 +.orig 02;37 +.ORIG 02;37 +.swo 02;37 +.swp 02;37 + +#+--- Images ---+ +.bmp 32 +.cgm 32 +.dl 32 +.dvi 32 +.emf 32 +.eps 32 +.gif 32 +.jpeg 32 +.jpg 32 +.JPG 32 +.mng 32 +.pbm 32 +.pcx 32 +.pgm 32 +.png 32 +.PNG 32 +.ppm 32 +.pps 32 +.ppsx 32 +.ps 32 +.svg 32 +.svgz 32 +.tga 32 +.tif 32 +.tiff 32 +.xbm 32 +.xcf 32 +.xpm 32 +.xwd 32 +.xwd 32 +.yuv 32 + +#+--- Video ---+ +.anx 32 +.asf 32 +.avi 32 +.axv 32 +.flc 32 +.fli 32 +.flv 32 +.gl 32 +.m2v 32 +.m4v 32 +.mkv 32 +.mov 32 +.MOV 32 +.mp4 32 +.mpeg 32 +.mpg 32 +.nuv 32 +.ogm 32 +.ogv 32 +.ogx 32 +.qt 32 +.rm 32 +.rmvb 32 +.swf 32 +.vob 32 +.webm 32 +.wmv 32 diff --git a/git/attributes b/git/attributes new file mode 100644 index 0000000..cfa930d --- /dev/null +++ b/git/attributes @@ -0,0 +1,3 @@ +**/*.secret filter=ageencrypt +**/.env filter=ageencrypt +**/.key filter=ageencrypt diff --git a/git/config b/git/config new file mode 100644 index 0000000..7063e8e --- /dev/null +++ b/git/config @@ -0,0 +1,53 @@ +[core] + editor = nvim + whitespace = fix,-indent-with-non-tab,trailing-space,cr-at-eol + excludesfile = ~/.config/git/ignore + compression = 9 + preloadindex=true +[include] +path = ~/.config/git/local +[init] + defaultBranch = main +[push] + default = simple + autoSetupRemote = true +[status] + branch = true + showStash = true +[filter "ageencrypt"] + clean = age -r age14mg08panez45c6lj2cut2l8nqja0k5vm2vxmv5zvc4ufqgptgy2qcjfmuu -a - + smudge = age -d -i ~/.ssh/age.key - + required = true +[pull] + rebase = true + autoStash = true + missingCommitCheck = true +[interactive] + singlekey = true +[url "git@github.com:"] + insteadOf = "gh:" +[log] + abbrevCommit = true + graphColors = blue,yellow,cyan,magenta,green,red +[color "decorate"] + HEAD=red + branch=blue + tag=yellow + remoteBranch=magenta +[branch] + sort = -committerdate +[init] + defaultBranch = main +[alias] + i = ls-files --others --ignored --exclude-standard + s = status --short + ap = add --patch + l = log --graph --all --pretty=format:'%C(magenta)%h %C(white) %an %ar%C(auto) %D%n%s%n' + ll = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit + c = commit + ca = commit -a + cm = commit -m + cl = clone + d = diff + ls = ls-files + subinit = submodule update --init --recursive diff --git a/git/ignore b/git/ignore new file mode 100644 index 0000000..4123c80 --- /dev/null +++ b/git/ignore @@ -0,0 +1,12 @@ +node_modules +tmp +.env +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.test +*.out +go.work +go.work.sum diff --git a/hooks/post-checkout b/hooks/post-checkout new file mode 100755 index 0000000..ea51a5e --- /dev/null +++ b/hooks/post-checkout @@ -0,0 +1,5 @@ +#!/bin/sh +[ "$3" = "1" ] || exit 0 +DOTFILES=$(readlink -nf "$(dirname "$0")/..") +ln -sf "$DOTFILES/mksh/mkshrc" "$HOME/.mkshrc" +echo "dotfiles: linked ~/.mkshrc" diff --git a/hooks/post-commit b/hooks/post-commit new file mode 100755 index 0000000..2273f27 --- /dev/null +++ b/hooks/post-commit @@ -0,0 +1,5 @@ +#!/bin/sh +[ "$(git symbolic-ref --short HEAD 2>/dev/null)" = "main" ] || exit 0 +git rev-parse --verify gui >/dev/null 2>&1 || exit 0 +git merge-base --is-ancestor main gui 2>/dev/null && exit 0 +echo "dotfiles: gui branch is behind main — run: git rebase main gui" diff --git a/hooks/post-merge b/hooks/post-merge new file mode 100755 index 0000000..5724162 --- /dev/null +++ b/hooks/post-merge @@ -0,0 +1,4 @@ +#!/bin/sh +DOTFILES=$(readlink -nf "$(dirname "$0")/..") +ln -sf "$DOTFILES/mksh/mkshrc" "$HOME/.mkshrc" +echo "dotfiles: linked ~/.mkshrc" diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..96509ba --- /dev/null +++ b/install.sh @@ -0,0 +1,5 @@ +#!/bin/sh +DOTFILES=$(readlink -nf "$(dirname "$0")") +git -C "$DOTFILES" config core.hooksPath hooks +ln -sf "$DOTFILES/mksh/mkshrc" "$HOME/.mkshrc" +echo "dotfiles: linked ~/.mkshrc" diff --git a/mksh/mkshrc b/mksh/mkshrc new file mode 100644 index 0000000..e3ebeab --- /dev/null +++ b/mksh/mkshrc @@ -0,0 +1,211 @@ +export HISTFILESIZE=10000 +export HISTCONTROL=ignoredups +export HISTFILE=$HOME/.cache/mksh_history +export PAGER="less" +export FCEDIT=nvim +export EDITOR="nvim" +export WORDCHARS="*?_-.[]~=&!#$%^(){}<>" +export QUOTING_STYLE=literal + +ulimit -c unlimited +stty -ixon +bind '^l'=clear-screen +bind '^k'=kill-line +bind '^j'=kill-to-eol +bind '^e'=edit-line + +# alias dot='/usr/bin/git --work-tree=$DOTS --git-dir=$DOTS/.git' +\\builtin alias c='clear' q='exit' df='df -h' +\\builtin alias ..='cd ..' ...='cd ../..' +\\builtin alias cp='cp -r' scp='scp -r' rm='rm -r' +\\builtin alias rscp='rsync -aP --inplace --progress --human-readable' rsmv='rscp --remove-source-files --force' + +\: "${MKSH:=$(\\builtin whence -p mksh)}${MKSH:=/bin/mksh}" +\\builtin export MKSH +\\builtin export SHELL=$MKSH MANWIDTH=80 LESSHISTFILE=- +\\builtin alias cls='\\builtin print -n \\ec' +\: "${EDITOR:=/bin/ed}${TERM:=vt100}${USER:=$(\\builtin ulimit -c 0; id -un \ + 2>/dev/null)}${HOSTNAME:=$(\\builtin ulimit -c 0; hostname 2>/dev/null)}" +[[ $HOSTNAME = ?(?(ip6-)localhost?(6)) ]] && HOSTNAME=nil; +\\builtin export EDITOR HOSTNAME TERM USER="${USER:-?}" + +# paths +export PATH=$HOME/.config/bin:$PATH +export PATH=$HOME/.local/bin:$PATH +export PATH=$HOME/.local/bin/sh:$PATH +test -d $HOME/.local/share/nvim/mason/bin && export PATH=$HOME/.local/share/mason/bin:$PATH + +test -r ~/.config/local_paths && source ~/.config/local_paths + +# colors +txtblk="$(tput setaf 0 2>/dev/null || echo '\e[0;30m')" # Black +txtred="$(tput setaf 1 2>/dev/null || echo '\e[0;31m')" # Red +txtgrn="$(tput setaf 2 2>/dev/null || echo '\e[0;32m')" # Green +txtylw="$(tput setaf 3 2>/dev/null || echo '\e[0;33m')" # Yellow +txtblu="$(tput setaf 4 2>/dev/null || echo '\e[0;34m')" # Blue +txtpur="$(tput setaf 5 2>/dev/null || echo '\e[0;35m')" # Purple +txtcyn="$(tput setaf 6 2>/dev/null || echo '\e[0;36m')" # Cyan +txtwht="$(tput setaf 7 2>/dev/null || echo '\e[0;37m')" # White +txtgry="$(tput setaf 8 2>/dev/null || echo '\e[0;38m')" # Gray +# Bold +bld="$(tput bold 2>/dev/null || echo '\e[1m')" +# italics +ita="$(tput sitm 2>/dev/null || echo '\e[3m')" +# Underline +und="$(tput smul 2>/dev/null || echo '\e[4m')" +# Reset +rst="$(tput sgr 0 2>/dev/null || echo '\e[0m')" # Text Reset + +# rust +export PATH=$PATH:$HOME/.cargo/bin +# go +# export GOSRC=~/bin/go/src +export GOPATH=$HOME/.local/share/go +export CGO_CFLAGS="-g -O2 -Wno-return-local-addr" +export CGO_ENABLED=0 +export PATH=$PATH:$GOPATH/bin +# npm +# export NPM_PACKAGES="${HOME}/.cache/npm-packages" +# npm config set prefix "$NPM_PACKAGES" +export NPM_PACKAGES="${HOME}/.local/share/npm" +export PATH="$PATH:$NPM_PACKAGES/bin" +export PATH="$PATH:${HOME}/.npm-packages/bin" + +# ls TODO: $(dircolors ..) +export LS_COLORS='no=00:rs=0:fi=01;37:di=01;37;40:ln=01;36:mh=04;36:pi=03;31:so=04;33:do=04;01;36:bd=01;33:cd=33:or=31:mi=01;37;41:ex=01;33:su=01;04;37:sg=01;04;37:ca=01;37:tw=01;37;44:ow=01;04;34:st=04;37;44:*.c=01;32:*.h=01;35:*.sh=01;32:*.rc=01;32:*.md=01;35:*.txt=30:*~=30:*.bak=30:*.BAK=30:*.log=30:*.log=30:*.old=30:*.OLD=30:*.orig=30:*.ORIG=30:*.swo=30:*.swp=30:*.7z=01;31:*.ace=01;31:*.alz=01;31:*.arc=01;31:*.arj=01;31:*.bz=01;31:*.bz2=01;31:*.cab=01;31:*.cpio=01;31:*.deb=01;31:*.dz=01;31:*.ear=01;31:*.gz=01;31:*.jar=01;31:*.lha=01;31:*.lrz=01;31:*.lz=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.lzo=01;31:*.rar=01;31:*.rpm=01;31:*.rz=01;31:*.sar=01;31:*.t7z=01;31:*.tar=01;31:*.taz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tgz=01;31:*.tlz=01;31:*.txz=01;31:*.tz=01;31:*.tzo=01;31:*.tzst=01;31:*.war=01;31:*.xz=01;31:*.z=01;31:*.Z=01;31:*.zip=01;31:*.zoo=01;31:*.zst=01;31:*.aac=02;37:*.au=02;37:*.flac=02;37:*.m4a=02;37:*.mid=02;37:*.midi=02;37:*.mka=02;37:*.mp3=02;37:*.mpa=02;37:*.mpeg=02;37:*.mpg=02;37:*.ogg=02;37:*.opus=02;37:*.ra=02;37:*.wav=02;37:*.bmp=02;37:*.cgm=02;37:*.dl=02;37:*.dvi=02;37:*.emf=02;37:*.eps=02;37:*.gif=02;37:*.jpeg=02;37:*.jpg=02;37:*.JPG=02;37:*.mng=02;37:*.pbm=02;37:*.pcx=02;37:*.pgm=02;37:*.png=02;37:*.PNG=02;37:*.ppm=02;37:*.pps=02;37:*.ppsx=02;37:*.ps=02;37:*.svg=02;37:*.svgz=02;37:*.tga=02;37:*.tif=02;37:*.tiff=02;37:*.xbm=02;37:*.xcf=02;37:*.xpm=02;37:*.xwd=02;37:*.xwd=02;37:*.yuv=02;37:*.anx=02;37:*.asf=02;37:*.avi=02;37:*.axv=02;37:*.flc=02;37:*.fli=02;37:*.flv=02;37:*.gl=02;37:*.m2v=02;37:*.m4v=02;37:*.mkv=02;37:*.mov=02;37:*.MOV=02;37:*.mp4=02;37:*.mpeg=02;37:*.mpg=02;37:*.nuv=02;37:*.ogm=02;37:*.ogv=02;37:*.ogx=02;37:*.qt=02;37:*.rm=02;37:*.rmvb=02;37:*.swf=02;37:*.vob=02;37:*.webm=02;37:*.wmv=02;37:'; +test -r ~/.dir_colors && eval $(dircolors ~/.dir_colors) + +# -> eval $(dircolors "$XDG_CONFIG_HOME"/dircolors/dircolors) +\\builtin alias ls='ls --color=always --group-directories-first -h' l='ls ' la='l -a' ll='l -l' lo='l -alo' + +# less +export LESS="-Q -R -C -i -j4 -M -PM?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x..%t" +export LESSBINFMT='*u[%X]' +export LESS_TERMCAP_mb=$'\E[01;31m' +export LESS_TERMCAP_md=$'\E[01;31m' +export LESS_TERMCAP_me=$'\E[0m' +export LESS_TERMCAP_se=$'\E[0m' +export LESS_TERMCAP_so=$'\E[01;40;37m' +export LESS_TERMCAP_ue=$'\E[0m' +export LESS_TERMCAP_us=$'\E[01;32m' +export LESSHISTFILE=$HOME/.cache/lesshist + +# xdg dirs +export XDG_DATA_HOME=$HOME/.local/share +export XDG_CONFIG_HOME=$HOME/.config +export XDG_STATE_HOME=$HOME/.local/state +export XDG_CACHE_HOME=$HOME/.cache + +# xdg fixes +export DOCKER_CONFIG="$XDG_CONFIG_HOME"/docker +export GNUPGHOME="$XDG_DATA_HOME"/gnupg +export LESSHISTFILE="$XDG_STATE_HOME"/less/history +export RUSTUP_HOME="$XDG_DATA_HOME"/rustup +export SQLITE_HISTORY="$XDG_CACHE_HOME"/sqlite_history +export NPM_CONFIG_USERCONFIG=$XDG_CONFIG_HOME/npm/npmrc +export W3M_DIR="~/.cache/w3m" +alias w3m='w3m -config ~/.config/w3m/config' +alias docker='doas docker' + +# funcs + +fcd() { + d=$(fd . -t directory ~ | fzf) && cd "${d}" +} + +fapk() { + apk search -q "$@" | fzf -m | xargs -r apk add +} + +weechat() { + docker ps -a --format '{{.Names}}' | grep "weechat" | xargs -r -o docker attach +} + +dkr() { + if (( USER_ID )) ; then doas="doas" ; fi + cmd="docker $@" + [ -z "$@" ] && cmd="echo" # just echo containername if no subcommand is specified + $doas sh -c ". ~/.config/sh/fzf.sh ; docker ps -a --format 'table {{.Names}}\t{{.Status}}' | \ + grep -E -v '^NAMES' | \ + fzf -p -e -m | \ + cut -f1 -d' ' | \ + xargs -ro $cmd" +} + +loop() { while true ; do $@; sleep 1; done ;} + +# prompt + +_prompt_git(){ + # from polyglot.sh + GITREF="$(env git symbolic-ref --quiet HEAD 2> /dev/null)" + case $? in # See what the exit code is. + 0) ;; # $GITREF contains the name of a checked-out branch. + 128) return ;; # No Git repository here. + # Otherwise, see if HEAD is in a detached state. + *) GITREF="$(env git rev-parse --short HEAD 2> /dev/null)" || return ;; + esac + + if [ -n "$GITREF" ]; then + GITSTATUS=$(LC_ALL=C GIT_OPTIONAL_LOCKS=0 env git status -uno 2>&1) + GITSYMBOLS='' + + case $GITSTATUS in + *' have diverged,'*) GITSYMBOLS="${GITSYMBOLS}&*" ;; + esac + case $GITSTATUS in + *'Your branch is behind '*) GITSYMBOLS="${GITSYMBOLS}&" ;; + esac + case $GITSTATUS in + *'Your branch is ahead of '*) GITSYMBOLS="${GITSYMBOLS}*" ;; + esac + case $GITSTATUS in + *'new file: '*) GITSYMBOLS="${GITSYMBOLS}+" ;; + esac + case $GITSTATUS in + *'deleted: '*) GITSYMBOLS="${GITSYMBOLS}x" ;; + esac + case $GITSTATUS in + *'modified: '*) + GITSYMBOLS="${GITSYMBOLS}!" + ;; + esac + case $GITSTATUS in + *'renamed: '*) GITSYMBOLS="${GITSYMBOLS}>" ;; + esac + case $GITSTATUS in + *'Untracked files:'*) GITSYMBOLS="${GITSYMBOLS}?" ;; + esac + + [ -n "$GITSYMBOLS" ] && GITSYMBOLS="$GITSYMBOLS" + GITREF=${GITREF#refs/heads/main} # empty if main + + printf "  %s%s" "${GITREF#refs/heads/}" "$GITSYMBOLS" + fi + + unset GITREF GITSTATUS GITSYMBOLS +} + +# prompts - modified from /etc/mkshrc +PS4='[$EPOCHREALTIME] '; PS1='#'; (( USER_ID )) && PS1='→'; PS1=$'\001\r''${| + \\builtin typeset e=$? + + (( e )) && REPLY+="${txtred}$e${txtgry} " + { ( [[ -n $SSH_CLIENT ]] || [[ -n $SSH_TTY ]] ) && [[ -z $TMUX ]] } && REPLY+="${ita}${txtgry}${HOSTNAME} ${rst}" + # REPLY+=${USER}@${HOSTNAME%%.*}: + + \\builtin typeset d=${PWD:-?}/ p=~; [[ $p = ?(*/) ]] || d=${d/#$p\//\~/} + d=${d%/}; [[ -n $d ]] || d=/ + case $d in + "~"|/) ;; + "~/"*/*) d=…/${d##*/} ;; + "~/"*) ;; + *) d=…/${d##*/} ;; + esac + REPLY+=${ita}${txtgry}$d + REPLY+="$(_prompt_git)${rst}" + + print -n "\e]133;A\e\\" # foot sequence for ctrl+shift+x/z + + \\builtin return $e +} '"${txtylw}${bld}$PS1 ${rst}" diff --git a/mksh/notes.md b/mksh/notes.md new file mode 100644 index 0000000..55908fc --- /dev/null +++ b/mksh/notes.md @@ -0,0 +1,149 @@ +# mkshrc notes + +Checked `mkshrc` with: + +```sh +mksh -n mkshrc +``` + +Syntax check passes, but these issues/suspicious spots were found. + +## Issues + +1. **Mason PATH bug** + + ```sh + test -d $HOME/.local/share/nvim/mason/bin && export PATH=$HOME/.local/share/mason/bin:$PATH + ``` + + The test checks `~/.local/share/nvim/mason/bin`, but the exported path is `~/.local/share/mason/bin`. + On this machine the checked directory exists and the exported directory does not. + + Suggested fix: + + ```sh + test -d "$HOME/.local/share/nvim/mason/bin" && export PATH="$HOME/.local/share/nvim/mason/bin:$PATH" + ``` + +2. **`stty` / `bind` emit errors without a tty** + + Non-interactive sourcing produced errors like: + + ```text + stty: standard input: Not a tty + mksh: ./mkshrc[12]: bind: can't bind, not a tty + ``` + + Suggested guard: + + ```sh + [[ -t 0 ]] && stty -ixon + [[ -o interactive ]] && { + bind '^l'=clear-screen + bind '^k'=kill-line + bind '^j'=kill-to-eol + bind '^e'=edit-line + } + ``` + +3. **`HISTFILESIZE` and `HISTCONTROL` are bash-style** + + ```sh + export HISTFILESIZE=10000 + export HISTCONTROL=ignoredups + ``` + + These are likely ignored by mksh. mksh generally uses `HISTSIZE`/`HISTFILE`; `HISTCONTROL=ignoredups` is not a mksh feature. + +4. **`LESSHISTFILE` is set multiple times** + + ```sh + export SHELL=$MKSH MANWIDTH=80 LESSHISTFILE=- + export LESSHISTFILE=$HOME/.cache/lesshist + export LESSHISTFILE="$XDG_STATE_HOME"/less/history + ``` + + Final value wins. Also `~/.local/state/less` does not currently exist, so less may fail to write history unless created. + +5. **`W3M_DIR` contains literal `~`** + + ```sh + export W3M_DIR="~/.cache/w3m" + ``` + + Because `~` is quoted, it will not expand. + + Suggested fix: + + ```sh + export W3M_DIR="$HOME/.cache/w3m" + ``` + +6. **`dkr()` has a bug with multiple args** + + ```sh + [ -z "$@" ] && cmd="echo" + ``` + + With multiple arguments this can error in mksh. Use: + + ```sh + (( $# == 0 )) && cmd="echo" + ``` + + Also: + + ```sh + cmd="docker $@" + ``` + + loses argument quoting and can behave badly with spaces/shell metacharacters. + +7. **`loop()` should quote args** + + Current: + + ```sh + loop() { while true ; do $@; sleep 1; done ;} + ``` + + Safer: + + ```sh + loop() { while true; do "$@"; sleep 1; done; } + ``` + +8. **ANSI gray fallback is probably wrong** + + ```sh + txtgry="$(tput setaf 8 2>/dev/null || echo '\e[0;38m')" + ``` + + `38` normally expects extended color parameters. Better fallback: + + ```sh + echo '\e[0;90m' + ``` + +9. **PATH grows on repeated sourcing** + + Re-sourcing this file repeatedly prepends/appends duplicate PATH entries. Not fatal, but noticeable. + +10. **Dangerous aliases** + + These may be intentional, but are worth noting: + + ```sh + alias cp='cp -r' + alias rm='rm -r' + alias docker='doas docker' + ``` + + `rm -r` by default can make accidents worse. + +## Most important fixes + +- Fix Mason path line. +- Fix `W3M_DIR`. +- Fix `dkr()` argument check/quoting. +- Guard `stty`/`bind` for non-tty/non-interactive use. diff --git a/tmux/tmux.conf b/tmux/tmux.conf new file mode 100644 index 0000000..1e7e88c --- /dev/null +++ b/tmux/tmux.conf @@ -0,0 +1,176 @@ +# .tmuxrc +# set-option -g default-shell /bin/mksh +set-option -g focus-events on +set -s escape-time 0 +set -g detach-on-destroy off +set -g destroy-unattached off +# set -g default-terminal "screen-256color" +set -g default-terminal "tmux-256color" +set -g history-limit 50000 +set -g bell-action any +set -g base-index 0 +set -g set-titles on +set -g set-titles-string "#W #T" +set -g display-time 8000 +set -g status-interval 2 +# set -g set-remain-on-exit off +set -g terminal-overrides 'xterm*:smcup@:rmcup@' +set -g window-size latest +set-option -sa terminal-overrides ',screen-256color:RGB' +set-option -sa terminal-overrides ',st-256color:RGB' +set -g renumber-windows on +# set-window-option -g aggressive-resize on +set-window-option -g xterm-keys on +set-option -g focus-events +set-option -sa terminal-overrides ',foot:RGB' + +# foot +set-option -sa terminal-overrides ',foot:RGB' +# keybinds +unbind-key -a + +set -g default-terminal "xterm-256color" + +# set-option -ga terminal-overrides ',xterm-256color:Tc +set-option -sa terminal-features ',xterm-256color:RGB' + +# Undercurl +set-option -g default-terminal "tmux-256color" +set-option -ga terminal-features ",xterm-256color:usstyle" + +set-option -g prefix C-a +unbind-key C-a +bind-key C-a send-prefix +# set -g prefix ^A +# bind b send-prefix + +bind b set-option status +bind B set-option status +bind-key : command-prompt + +bind -n C-PPage copy-mode -u +# bind -t vi-copy -n C-PPage page-up +# bind -t vi-copy -n C-NPage page-down +bind p paste-buffer +bind P choose-buffer +bind V copy-mode +bind -n C-F11 switch-client -p +bind -n C-F12 switch-client -n +unbind Tab +bind Tab select-pane -D +unbind BTab +bind BTab select-pane -U +bind S choose-window "join-pane -v -s "%%"" +bind '"' choose-window +bind -n C-t new-window -c "#{pane_current_path}" +bind t new-window +bind T new-window -c "#{pane_current_path}" +# bind -n C-t new-window -c "#{pane_current_path}" +bind | split-window -h +bind & split-window +bind s split-window -c "#{pane_current_path}" +bind v split-window -h -c "#{pane_current_path}" +bind -n S-left swap-window -t -1 +bind -n S-right swap-window -t +1 +bind -n F11 prev +bind -n F12 next +bind ^C new-window +bind c new-window +bind C command-prompt "new-window -n %%" +bind V command-prompt "new-session -s %%" +bind l choose-window +bind ^P previous-window +bind p previous-window +bind ^N next-window +bind n next-window +bind " " last-window +bind b set-option status +bind / command-prompt -p "find" "find-window %%" +bind h new-window 'exec htop' +bind H split-window 'exec htop' + +# mouse +set -g mouse on +# bind -T root MouseDrag1Border resize-pane -M # default +# bind -T root MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= "#{pane_in_mode}" "copy-mode -M" "send-keys -M"' 'copy-mode -M' # default +# bind -T root MouseDown1Pane select-pane -t=\; send-keys -M # default +# bind -T root MouseDown3Pane select-pane -t= -m # default +# bind -T root MouseDown3Pane if -Ft= '#{pane_in_mode}' 'send-keys -M' 'select-pane -t= -m' +# unbind -T root WheelUpPane +# unbind -T root WheelDownPane +# bind -T root MouseDown1Status select-window -t= # default +# bind -T root MouseDown2Status kill-window + +# theme +set -g status-fg white +set -g status-bg default +set -g status-style bg=default +set -g status-left '' +set -g status-right ' #[fg=black]> #[fg=black]#H' +set -g status-justify right +setw -g window-status-format ' #[fg=black]#W' +setw -g window-status-current-format '#[fg=black]>#[fg=yellow]#W' + +# fix ncurses crash +set -as terminal-overrides ',st*:Ss@' +set-option -sa terminal-overrides ",xterm*:Tc" +# Undercurl +# set -g default-terminal '${TERM}' +set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm' # undercurl support +set -as terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m' # underscore colours - needs tmux-3.0 +set -as terminal-features ",foot*:RGB" + +# Move statusbar to the top +set-option -g status "on" +set-option -g status-position top + +# Use current directory as window title but allow manual renaming +set-option -g allow-rename on +set-option -g automatic-rename-format '#{b:pane_current_path}' + +# Monitoring +setw -g monitor-activity off +set -g visual-activity off +setw -g monitor-silence 0 + +# Start windows and panes at 1, not 0 +set -g base-index 1 +setw -g pane-base-index 1 +set-option -g renumber-windows on + +# frappe colors +COL_FG="#838ba7" +COL_BG_MEDIUM="#303446" +COL_BG_DARK="#292c3c" +COL_BG_VERY_DARK="#232634" +# new +COL_FG=color240 +COL_BG_MEDIUM=default +COL_BG_DARK=default +COL_BG_VERY_DARK=default + +set -g status-left-style "none" +set -g message-command-style "fg=$COL_FG,bg=$COL_BG_DARK" +set -g status-right-style "none" +set -g status-style "none,bg=$COL_BG_VERY_DARK" +set -g message-style "fg=$COL_FG,bg=$COL_BG_DARK" + +set-option -g status-style "none,fg=$COL_FG,bg=$COL_BG_VERY_DARK" +set-option -g status-justify "left" + +# window-status-activity-attr is reverse by default, which means bg and fg are switched +set-window-option -g window-status-activity-style none +set-window-option -g window-status-separator '' + +set -g status-left "#[fg=$COL_FG,bg=$COL_BG_DARK] #S #[fg=$COL_BG_DARK,bg=$COL_BG_VERY_DARK] " +set -g status-right "#[fg=color230] #h " + +activity_color="#{?window_activity_flag,colour1,$COL_FG}" +status_color="#{?window_silence_flag,colour3,${activity_color}}" + +set-window-option -g window-status-current-format "#[fg=$COL_BG_DARK] #{window_index} #[fg=color230]#{window_name} #[fg=$COL_BG_MEDIUM]" +set-window-option -g window-status-format "#[fg=$COL_BG_DARK,bg=$COL_BG_VERY_DARK]#[fg=${status_color},bg=$COL_BG_DARK] #{window_index} #{window_name} #[fg=$COL_BG_DARK,bg=$COL_BG_VERY_DARK]" + +set -g pane-active-border-style bg=default,fg=color240 +set -g pane-border-style fg=color240 +