diff --git a/README.md b/README.md index c74e592..d80703a 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,29 @@ -# Shared shell profile +# Shared login profile -This repository owns the login environment and interactive commands intended -to be shared by Bourne-family shells. - -"Shared" means shells capable of reading POSIX-style `sh`, such as `sh`, Bash, -Dash and—with appropriate compatibility—Zsh. It does not mean that the same -file can be sourced directly by shells with different languages, such as Fish -or Nushell. +This repository owns the portable login environment. It is deliberately quiet, +shell-agnostic and independent of interactive shell configuration. ## Responsibilities - Install `~/.profile` as a symlink into this repository. - Define XDG locations and general editor/browser environment variables. -- Construct PATH idempotently for language and user-level executable paths. -- Load environment setup that is portable at login, such as Cargo's `env` file. -- Provide common aliases and small interactive functions that are useful - across supported Bourne-family shells. -- Isolate Arch Linux commands from otherwise portable shell configuration. +- Construct `PATH` idempotently for language and user-level executables. +- Load portable login environment setup, such as Cargo's `env` file. ## Boundaries -The `profile` file must remain quiet, idempotent and safe for a POSIX shell to -source during login. It must not print an alias catalogue, configure a prompt, -perform interactive terminal operations or start background work. +The `profile` file must remain safe for a POSIX shell to source during login. It +must not print output, configure a prompt, define interactive conveniences, +perform terminal operations or start background work. -Interactive shells should source `interactive.sh` from their own RC file. The -login profile deliberately does not source it, because login profiles may also -run in non-interactive sessions. - -Shell-specific prompt, history, completion and initialization belongs in the -corresponding shell repository, currently `bash`. User services and timers -belong in the separate `systemd` repository. +Aliases, interactive functions, reminders, command catalogues, completion, +history and prompt configuration belong to the relevant shell repository. User +services and timers belong in the separate `systemd` repository. ## Files -- `profile`: portable login environment and PATH construction. -- `interactive.sh`: POSIX loader and manually curated alias reminder. -- `aliases.sh`: common POSIX interactive aliases and helper functions. -- `commands.sh`: command-catalogue display and validation functions. -- `hosts.sh`: SSH destination listing function. -- `platform/arch.sh`: Arch Linux applications, GNU options and Pacman/systemd - integration, written with POSIX shell syntax. -- `commands.tsv`: curated command descriptions and reminder visibility. -- `commands.README.md`: format and maintenance instructions for `commands.tsv`. -- `memory.tsv`: selectively curated shell-memory questions and answers. -- `memory.README.md`: format, scope and daily-selection behavior for the memory - question bank. +- `profile`: portable login environment and `PATH` construction. - `install.sh`: installs the `~/.profile` symlink. -## Alias portability - -The shared interactive files use POSIX shell syntax. Bash-only compatibility -aliases—including names that are deliberately being retired—live in the Bash -repository's `aliases.bash` instead. - -External commands remain platform-specific by design: aliases for Pacman, -systemd, GNU utilities and local applications target this Arch Linux setup. -Syntax portability does not imply operating-system portability. - -The Arch `update` function runs the local `archnews_wrap` Pacman workflow and, -after a successful upgrade, requests a non-blocking refresh from the systemd -user service `package-status-refresh.service`. +Interactive Bash uses this environment through the conventional `~/.profile` +interface. This repository does not reference or load the Bash repository. diff --git a/aliases.sh b/aliases.sh deleted file mode 100644 index 046a397..0000000 --- a/aliases.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -# Common interactive aliases and helpers using POSIX shell syntax. - -alias venv='. ./venv/bin/activate' - -alias e='nvim' -alias er='nvim README.md' -alias et='nvim TODO.md' -alias en='nvim NOTES.md' -alias ens='nvim NEXT_STEPS.md' -alias ea='nvim .autonote.md' -alias ee='nvim .' - -debuglog() { - clear - : > debug.log - tail -f debug.log -} - -alias g='git status' - -gg() { - _gg_message=${*:-update} - if git add . && git commit -m "$_gg_message" && git push; then - unset _gg_message - return 0 - fi - - unset _gg_message - return 1 -} - -wget() { - printf 'wget wrapper: using HSTS file %s\n' "$XDG_DATA_HOME/wget-hsts" >&2 - command wget --hsts-file="$XDG_DATA_HOME/wget-hsts" "$@" -} - -alias bc='bc -q -l' - -alias ytdl='yt-dlp --write-info-json --write-description --no-playlist' -alias ytdlb='yt-dlp --write-info-json --write-description --no-playlist -a' -alias ytdl-mp3='yt-dlp -f bestaudio --extract-audio --audio-format mp3 --embed-thumbnail --add-metadata' - -# lf gets confused by TERMINFO when running in tmux. -# https://github.com/gokcehan/lf/issues/138#issuecomment-464477665 -if [ -n "${TERMINFO:-}" ]; then - alias lf='TERMINFO= lf -last-dir-path="$HOME/.cache/lf-last-dir"' -else - alias lf='lf -last-dir-path="$HOME/.cache/lf-last-dir"' -fi - -cdlf() { - [ -r "$HOME/.cache/lf-last-dir" ] || return 1 - IFS= read -r _cdlf_last_dir < "$HOME/.cache/lf-last-dir" - [ -n "$_cdlf_last_dir" ] || return 1 - - if cd "$_cdlf_last_dir"; then - unset _cdlf_last_dir - return 0 - fi - - unset _cdlf_last_dir - return 1 -} - -lfcd() { - lf -last-dir-path="$HOME/.cache/lf-last-dir" && cdlf -} - -mkcd() { - if [ "$#" -ne 1 ]; then - printf '%s\n' 'Usage: mkcd ' >&2 - return 2 - fi - - mkdir -p "$1" || return - cd "$1" || return -} diff --git a/commands.README.md b/commands.README.md deleted file mode 100644 index 7b94f5b..0000000 --- a/commands.README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Command reminders - -`commands.tsv` is the manually curated source for the shell's command reminder. -It is not an inventory of every installed executable. - -Each non-empty line contains three tab-separated fields: - -```text -reminder command description -``` - -- `reminder` must be `yes` or `no`. `yes` includes the command in the shell - reminder; `no` keeps it available only in the full listing. -- `command` is the name entered at the shell. -- `description` is a brief explanation displayed by `commands`. - -The data file deliberately has no header or comments. Blank lines are allowed; -put explanatory material in this README instead. Duplicate commands, unknown -reminder values and malformed rows are reported as errors. - -Run `commands` to display every entry. To add or remove something from the -shell reminder, edit only its `reminder` field; do not duplicate the command -list in shell configuration. diff --git a/commands.sh b/commands.sh deleted file mode 100644 index 9480250..0000000 --- a/commands.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh - -# Display and validate the curated command catalogue. - -commands() { - awk -F '\t' ' - NF == 0 { next } - NF != 3 || ($1 != "yes" && $1 != "no") || $2 == "" || $3 == "" { - printf "Invalid command reminder on line %d.\n", NR > "/dev/stderr" - invalid = 1 - next - } - seen[$2]++ { - printf "Duplicate command reminder for %s on line %d.\n", $2, NR > "/dev/stderr" - invalid = 1 - next - } - { - count++ - reminder[count] = $1 - command[count] = $2 - description[count] = $3 - if (length($2) > command_width) command_width = length($2) - if (length($3) > description_width) description_width = length($3) - } - END { - if (invalid) exit 1 - if (length("COMMAND") > command_width) command_width = length("COMMAND") - if (length("DESCRIPTION") > description_width) description_width = length("DESCRIPTION") - printf "%-*s %-*s %s\n", command_width, "COMMAND", description_width, "DESCRIPTION", "REMINDER" - for (row = 1; row <= count; row++) { - printf "%-*s %-*s %s\n", command_width, command[row], description_width, description[row], reminder[row] - } - } - ' "${XDG_CONFIG_HOME:-$HOME/.config}/profile/commands.tsv" -} - -_command_reminder() { - awk -F '\t' -v width="${COLUMNS:-80}" ' - NF == 0 { next } - NF != 3 || ($1 != "yes" && $1 != "no") || $2 == "" || $3 == "" { - printf "Invalid command reminder on line %d.\n", NR > "/dev/stderr" - invalid = 1 - next - } - seen[$2]++ { - printf "Duplicate command reminder for %s on line %d.\n", $2, NR > "/dev/stderr" - invalid = 1 - next - } - $1 == "yes" { command[++count] = $2 } - END { - if (invalid) exit 1 - if (width < 40) width = 80 - line = " " - for (row = 1; row <= count; row++) { - separator = (line == " " ? "" : " ") - if (length(line) + length(separator) + length(command[row]) > width) { - print line - line = " " command[row] - } else { - line = line separator command[row] - } - } - if (line != " ") print line - } - ' "${XDG_CONFIG_HOME:-$HOME/.config}/profile/commands.tsv" -} diff --git a/commands.tsv b/commands.tsv deleted file mode 100644 index d50c3c6..0000000 --- a/commands.tsv +++ /dev/null @@ -1,16 +0,0 @@ -yes nap snippet manager -yes hyprpicker Wayland colour picker -yes nmcli NetworkManager command-line client -yes lftp file-transfer client -yes lxc-wp create a local WordPress LXC project -yes qv4l2 Video4Linux control panel -no cheat command-line cheatsheets -no vimv batch rename files in Vim -yes rclone sync files with cloud storage -yes zathura document viewer -yes tesseract optical character recognition -yes remmina remote desktop client -yes wl-copy copy to the Wayland clipboard -yes wl-paste paste from the Wayland clipboard -yes hosts list SSH destinations -yes commands list remembered commands and descriptions diff --git a/hosts.sh b/hosts.sh deleted file mode 100644 index 93adca4..0000000 --- a/hosts.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -hosts() { - if [ ! -r "$HOME/.ssh/config.d/hosts.conf" ]; then - printf '%s\n' 'SSH host configuration is unavailable.' >&2 - return 1 - fi - - awk ' - tolower($1) == "host" { - for (field = 2; field <= NF; field++) { - if ($field !~ /[*?!]/) print $field - } - } - ' "$HOME/.ssh/config.d/hosts.conf" -} diff --git a/interactive.sh b/interactive.sh deleted file mode 100644 index c62f76e..0000000 --- a/interactive.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -# Shared interactive setup for POSIX-compatible shells. - -_profile_interactive_dir=${XDG_CONFIG_HOME:-$HOME/.config}/profile - -. "$_profile_interactive_dir/aliases.sh" -. "$_profile_interactive_dir/commands.sh" -. "$_profile_interactive_dir/hosts.sh" - -if [ -r /etc/arch-release ]; then - . "$_profile_interactive_dir/platform/arch.sh" -fi - -printf '%s\n' 'Remember aliases:' -printf '\033[1;37m%s\n' ' et en ens ee' -printf '%s\n' ' dusort debuglog mkcd' -printf '\033[0m\n\n' - -unset _profile_interactive_dir diff --git a/memory.README.md b/memory.README.md deleted file mode 100644 index ca7aba5..0000000 --- a/memory.README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Shell memory questions - -`memory.tsv` is a selectively curated question-and-answer bank for reinforcing -useful shell commands. It deliberately excludes internal functions, standard -command overrides and deprecated transition aliases. - -Each non-empty line contains three tab-separated fields: - -```text -name question answer -``` - -- `name` is a unique stable identifier, normally the command or alias name. -- `question` is displayed on shell startup. -- `answer` is displayed by running `answerpls` in that terminal. - -The file has no header or comments. Empty fields, duplicate names and malformed -rows are errors. - -Bash selects one entry deterministically from the local calendar date. Every -terminal opened on the same day therefore shows the same question without -requiring a state file. Editing the bank may change which question maps to a -given date. diff --git a/memory.tsv b/memory.tsv deleted file mode 100644 index 8617f4e..0000000 --- a/memory.tsv +++ /dev/null @@ -1,23 +0,0 @@ -nap What do you use as a snippet manager? nap -hyprpicker What do you use as a colour picker? hyprpicker -nmcli What manages NetworkManager from the terminal? nmcli -lftp What do you use for interactive file transfers? lftp -lxc-wp What creates a local WordPress LXC project? lxc-wp -qv4l2 What opens the Video4Linux control panel? qv4l2 -cheat What displays command-line cheatsheets? cheat -vimv What lets you batch rename files in Vim? vimv -rclone What synchronizes files with cloud storage? rclone -zathura What lightweight application opens documents? zathura -tesseract What performs optical character recognition? tesseract -remmina What opens remote desktop connections? remmina -wl-copy What copies text to the Wayland clipboard? wl-copy -wl-paste What pastes text from the Wayland clipboard? wl-paste -hosts What lists your configured SSH destinations? hosts -commands What lists remembered commands and their descriptions? commands -et What opens TODO.md for editing? et -en What opens NOTES.md for editing? en -ens What opens NEXT_STEPS.md for editing? ens -ee What opens the current directory in Neovim? ee -dusort What displays disk usage sorted by size? dusort [path] -debuglog What clears and follows debug.log? debuglog -mkcd What creates a directory and enters it? mkcd diff --git a/platform/arch.sh b/platform/arch.sh deleted file mode 100644 index ec51a32..0000000 --- a/platform/arch.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh - -# Interactive commands specific to this Arch Linux workstation. - -_ARCH_GREEN='\033[0;32m' -_ARCH_BLUE='\033[0;34m' -_ARCH_NC='\033[0m' - -alias backup='sudo borgmatic create --verbosity 1 --files' -alias cs='lxc list -c ns4b,user.comment:comment' - -pc() { - nohup pcmanfm . >/dev/null 2>&1 & -} - -# Expand aliases for commands following sudo. -alias sudo='sudo ' - -alias speak='/usr/local/src/kokora/speak' - -alias ls='LC_COLLATE=C ls --color=auto -h --group-directories-first --time-style=+"%d.%m.%Y %H:%M" -F' -alias cp='cp -irv' -alias mkdir='mkdir -vp' -alias mv='mv -iv' -alias rm='rm -dv' -alias grep='grep --colour=auto' - -dusort() { - if [ "$#" -gt 1 ]; then - printf '%s\n' 'Usage: dusort [path]' >&2 - return 2 - fi - - _dusort_path=${1:-.} - if [ ! -e "$_dusort_path" ]; then - printf 'dusort: path does not exist: %s\n' "$_dusort_path" >&2 - unset _dusort_path - return 1 - fi - - if sudo du -h -d 2 -- "$_dusort_path" | sort -h; then - unset _dusort_path - return 0 - fi - - unset _dusort_path - return 1 -} - -update() { - printf 'Executing "%bpacman -Syu%b" via "%barchnews_wrap%b" wrapper\n' \ - "$_ARCH_GREEN" "$_ARCH_NC" "$_ARCH_BLUE" "$_ARCH_NC" - - sudo "$HOME/.src/archnews/archnews_wrap" -Syu || return - systemctl --user start --no-block package-status-refresh.service >/dev/null 2>&1 || true -}