diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-09-06 15:27:01 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-09-06 15:27:01 +1200 |
commit | b1bedf82010e14f74c680b63654652096e4fa1cc (patch) | |
tree | 4fa1cfeedd3559254330b9e50ca8693d3da86062 | |
parent | Merge branch 'master' into openbsd (diff) | |
parent | Tidy .inputrc bc section (diff) | |
download | dotfiles-b1bedf82010e14f74c680b63654652096e4fa1cc.tar.gz dotfiles-b1bedf82010e14f74c680b63654652096e4fa1cc.zip |
Merge branch 'master' into openbsd
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | ISSUES.markdown | 4 | ||||
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | README.markdown | 152 | ||||
-rw-r--r-- | bash/bash_completion.d/find.bash | 89 | ||||
-rw-r--r-- | bash/bash_completion.d/kill.bash | 15 | ||||
-rw-r--r-- | bash/bash_completion.d/make.bash | 1 | ||||
-rw-r--r-- | bash/bashrc.d/completion.bash | 13 | ||||
-rw-r--r-- | bash/bashrc.d/prompt.bash | 57 | ||||
-rwxr-xr-x | bin/bl | 11 | ||||
-rwxr-xr-x | bin/cf | 32 | ||||
-rwxr-xr-x | bin/cfr | 13 | ||||
-rw-r--r-- | bin/mftl.awk | 38 | ||||
-rwxr-xr-x | bin/rmrej | 3 | ||||
-rwxr-xr-x | bin/tl | 22 | ||||
-rwxr-xr-x | bin/umake | 11 | ||||
-rwxr-xr-x | bin/xgo | 16 | ||||
-rw-r--r-- | man/man1/bl.1df | 16 | ||||
-rw-r--r-- | man/man1/cf.1df | 10 | ||||
-rw-r--r-- | man/man1/cfr.1df | 9 | ||||
-rw-r--r-- | man/man1/mftl.1df | 30 | ||||
-rw-r--r-- | man/man1/rmrej.1df | 17 | ||||
-rw-r--r-- | man/man1/umake.1df | 15 | ||||
-rw-r--r-- | man/man6/rndn.6df | 6 | ||||
-rw-r--r-- | mutt/muttrc.m4 | 38 | ||||
-rw-r--r-- | readline/inputrc | 10 |
26 files changed, 469 insertions, 172 deletions
@@ -1,6 +1,7 @@ bin/han bin/mean bin/med +bin/mftl bin/mode bin/rfct bin/rndi @@ -15,5 +16,6 @@ games/zs git/gitconfig gnupg/gpg.conf man/man7/dotfiles.7df +mutt/muttrc tmux/tmux.conf urxvt/ext/select diff --git a/ISSUES.markdown b/ISSUES.markdown index f58d7572..22cca775 100644 --- a/ISSUES.markdown +++ b/ISSUES.markdown @@ -30,6 +30,4 @@ Known issues * sxhkd(1) might be nicer than xbindkeys; it's in Debian Testing now * Maybe I should port some of the prompt functions to POSIX sh so I don't have to maintain parallel versions for bash, pdksh, and zsh -* The Mutt configuration is not very standalone; relies quite a lot on - Debian's /etc/Muttrc and /etc/Muttrc.d, most of which can probably be - included in my own configuration files. +* PID completion for `kill` builtin @@ -64,11 +64,12 @@ NAME := Tom Ryder EMAIL := tom@sanctum.geek.nz KEY := 0xC14286EA77BB8872 -SENDMAIL := /usr/bin/msmtp +SENDMAIL := msmtp all : bin/han \ bin/mean \ bin/med \ + bin/mftl \ bin/mode \ bin/rfct \ bin/rndi \ @@ -78,14 +79,14 @@ all : bin/han \ bin/tot \ bin/unf \ git/gitconfig \ - gnupg/gpg.conf \ - urxvt/ext/select + gnupg/gpg.conf clean distclean : rm -f \ bin/han \ bin/mean \ bin/med \ + bin/mftl \ bin/mode \ bin/rfct \ bin/rndi \ @@ -177,8 +178,8 @@ install-bash-completion : install-bash install -pm 0644 -- bash/bash_completion "$(HOME)"/.config/bash_completion install -pm 0644 -- bash/bash_completion.d/* "$(HOME)"/.bash_completion.d -install-bin : bin/han bin/sd2u bin/su2d bin/mean bin/med bin/mode \ - bin/tot bin/unf check-bin install-bin-man +install-bin : bin/han bin/mean bin/med bin/mftl bin/mode bin/rfct \ + bin/rndi bin/sd2u bin/slsf bin/su2d bin/tot bin/unf install-bin-man install -m 0755 -d -- "$(HOME)"/.local/bin for name in bin/* ; do \ [ -x "$$name" ] || continue ; \ diff --git a/README.markdown b/README.markdown index 9717cae3..27bdfccb 100644 --- a/README.markdown +++ b/README.markdown @@ -42,8 +42,8 @@ Configuration is included for: * [Bash](https://www.gnu.org/software/bash/) -- GNU Bourne-Again Shell, including a `~/.profile` configured to work with most Bourne-compatible shells -* [cURL](https://curl.haxx.se/) -- Command-line tool for transferring data with - URL syntax +* [cURL](https://curl.haxx.se/) -- Command-line tool for transferring data + with URL syntax * [Dunst](http://knopwob.org/dunst/) -- A lightweight X11 notification daemon that works with `libnotify` * `finger(1)` -- User information lookup program @@ -62,49 +62,48 @@ Configuration is included for: of the Korn shell * [`psql(1)`](http://linux.die.net/man/1/psql) -- Command-line PostgreSQL client -* [Perl::Critic](http://perlcritic.com/) -- static source code analysis engine - for Perl +* [Perl::Critic](http://perlcritic.com/) -- static source code analysis + engine for Perl * [Perl::Tidy](http://perltidy.sourceforge.net/) -- Perl indenter and reformatter * [Readline](https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) -- GNU library for user input used by Bash, MySQL, and others * [rxvt-unicode](http://software.schmorp.de/pkg/rxvt-unicode.html) -- Fork of the rxvt terminal emulator with Unicode support -* [Subversion](https://subversion.apache.org/) -- Apache Subversion, a version - control system +* [Subversion](https://subversion.apache.org/) -- Apache Subversion, a + version control system * [tmux](https://tmux.github.io/) -- Terminal multiplexer similar to GNU Screen * [Vim](http://www.vim.org/) -- Vi IMproved, a text editor * [Wyrd](https://packages.debian.org/sid/wyrd) -- a `curses` calendar frontend for [Remind](https://www.roaringpenguin.com/products/remind) -* [X11](https://www.x.org/wiki/) -- Windowing system with network transparency - for Unix +* [X11](https://www.x.org/wiki/) -- Windowing system with network + transparency for Unix * [Yash](https://yash.osdn.jp/index.html.en) -- Yet another shell; just enough configuration to make it read the portable POSIX stuff * [Zsh](https://www.zsh.org/) -- Bourne-style shell designed for interactive use -The configurations for Bash, GnuPG, Mutt, tmux, and Vim are the most expansive -and most likely to be of interest. The i3 configuration is mostly changed to -make window switching behave like Vim windows and tmux panes do, and there's a -fair few resources defined for rxvt-unicode. Otherwise, the rest of the -configuration isn't too distant from the defaults. +The configurations for shells, GnuPG, Mutt, tmux, and Vim are the most +expansive, and most likely to be of interest. The i3 configuration is mostly +changed to make window switching behave like Vim windows and tmux panes do, and +there's a fair few resources defined for rxvt-unicode. ### Shell My `.profile` and other files in `sh` are written in POSIX shell script, so they should work in most `sh(1)` implementations. Individual scripts called by `.profile` are saved in `.profile.d` and iterated on login for ease of -management. All of these boil down to exporting variables appropriate to the +management. Most of these boil down to exporting variables appropriate to the system and the software it has available. -I make an effort to target POSIX for my functions and scripts where I can, but -Bash is my interactive shell of choice. +Configuration that should be sourced for all POSIX-fearing shells is kept in +`~/.shrc`, with subscripts read from `~/.shrc.d`. -My `.bash_profile` calls `.profile`, and then `.bashrc`, which only applies for -interactive shells. Subscripts for `.bashrc` are loaded from `.bashrc.d`. The -contents of the `*.d` directories changes depending on the host, so only -specific scripts in it are versioned. +I make an effort to target POSIX for my functions and scripts where I can, but +Bash is my interactive shell of choice. My `.bash_profile` calls `.profile`, +and then `.bashrc`, which only applies for interactive shells. Subscripts for +`.bashrc` are loaded from `.bashrc.d`. As I occasionally have work on very old internal systems, my Bash is written to work with [any version 2.05a or @@ -124,9 +123,6 @@ after testing `BASH_VERSINFO` appropriately. #### Prompt -When I use any other Bourne-compatible shell, I'm generally happy to accept its -defaults for interactive behavior. - A terminal session with my prompt looks something like this: ~$ ssh remote @@ -141,8 +137,9 @@ A terminal session with my prompt looks something like this: [1] 28937 tom@remote:~/.dotfiles(master+!){1}$ -The username and hostname are skipped if not connected via SSH. The right side -of the prompt expands based on context to include these elements in this order: +The username and hostname are elided if not connected via SSH. The working +directory is always shown. The rest of the prompt expands based on context to +include these elements in this order: * Whether in a Git repository if applicable, and punctuation to show repository status including reference to upstreams at a glance. Subversion @@ -223,14 +220,15 @@ There are a few other little tricks defined for other shells, mostly in #### Completion I find the `bash-completion` package a bit too heavy for my tastes, and turn it -off using a stub file installed in `.config/bash_completion`. The majority of +off using a stub file installed in `~/.config/bash_completion`. The majority of the time I just want to complete paths anyway, and this makes for a quicker startup without a lot of junk functions in my Bash namespace. I do make some exceptions with completions defined in `.bash_completion.d` -files for things I really do get tired of typing repeatedly: +files, for things I really do get tired of typing repeatedly: -* Builtins, commands, help topics, shell options, and variables +* Bash builtins: commands, help topics, shell options, variables, etc. +* `find(1)`'s more portable options * `ftp(1)` hostnames from `~/.netrc` * `git(1)` branch names * `gpg(1)` long options @@ -251,6 +249,10 @@ Bash ones. They're tested on OpenBSD and FreeBSD pdksh implementations, but the former is the primary system for which I'm maintaining them, and there are some feature differences. +#### Yash + +Just enough configuration to coax it into reading `~/.profile` and `~/.shrc`. + #### Zsh These are experimental; I do not like Zsh much at the moment. The files started @@ -273,7 +275,7 @@ most unfiltered mail is sent. I use [MSMTP](http://msmtp.sourceforge.net/); the configurations for these are not included here. I sign whenever I have some indication that the recipient might be using a PGP implementation, and I encrypt whenever I have a public key -available for them. The GnuPG interfacing is done with +available for them. The GnuPG and S/MIME interfacing is done with [GPGme](https://www.gnupg.org/related_software/gpgme/), rather than defining commands for each crypto operation. I wrote [an article about this setup](https://sanctum.geek.nz/arabesque/linux-crypto-email/) if it sounds @@ -315,6 +317,9 @@ The configuration for Bash includes a `tmux` function designed to make `attach` into the default command if no arguments are given and sessions do already exist. The default command is normally `new-session`. +My `~/.inputrc` file binds Alt+M to attach to or create a `tmux` session, and +Tmux in turn binds the same key combination to detach. + ### Vim The majority of the `.vimrc` file is just setting options, with a few mappings. @@ -329,20 +334,19 @@ Scripts ------- Where practical, I make short scripts into POSIX (but not Bourne) `sh(1)`, -`awk(1)`, or `sed(1)` scripts in `~/.local/bin`. A few of them still have -Bashisms for various reasons. I try to use shell functions only when I actually -need to, which tends to be when I need to tinker with the namespace of the -user's current shell. +`awk(1)`, or `sed(1)` scripts in `~/.local/bin`. I try to use shell functions +only when I actually need to, which tends to be when I need to tinker with the +namespace of the user's current shell. Installed by the `install-bin` target: * Three SSH-related scripts: * `sls(1df)` prints hostnames read from a `ssh_config(5)` file. It uses `slsf(1df)` to read each one. - * `sra(1df)` runs a command on multiple hosts read from `sls(1df)` and prints - output. - * `sta(1df)` runs a command on multiple hosts read from `sls(1df)` and prints - the hostname if the command returns zero. + * `sra(1df)` runs a command on multiple hosts read from `sls(1df)` and + prints output. + * `sta(1df)` runs a command on multiple hosts read from `sls(1df)` and + prints the hostname if the command returns zero. * Five URL-related shortcut scripts: * `hurl(1df)` extracts values of `href` attributes of `<a>` tags, sorts them uniquely, and writes them to `stdout`; it requires @@ -370,41 +374,51 @@ Installed by the `install-bin` target: * Four file formatting scripts: * `d2u(1df)` converts DOS line endings in files to UNIX ones. * `u2d(1df)` converts UNIX line endings in files to DOS ones. - * `stbl(1df)` strips a trailing blank line from the files in its arguments. - * `stws(1df)` strips trailing spaces from the ends of lines of the files in - its arguments. + * `stbl(1df)` strips a trailing blank line from the files in its + arguments. + * `stws(1df)` strips trailing spaces from the ends of lines of the files + in its arguments. * Five stream formatting scripts: * `sd2u(1df)` converts DOS line endings in streams to UNIX ones. * `su2d(1df)` converts UNIX line endings in streams to DOS ones. - * `tl(1df)` tags input lines with a prefix or suffix, basically a `sed(1)` - shortcut. - * `tlcs(1df)` executes a command and uses `tl(1df)` to tag stdout and stderr - lines, and color them if you want. - * `unf(1df)` joins lines with leading spaces to the previous line. Intended - for unfolding HTTP headers, but it should work for most RFC 822 - formats. + * `tl(1df)` tags input lines with a prefix or suffix, basically a + `sed(1)` shortcut. + * `tlcs(1df)` executes a command and uses `tl(1df)` to tag stdout and + stderr lines, and color them if you want. + * `unf(1df)` joins lines with leading spaces to the previous line. + Intended for unfolding HTTP headers, but it should work for most RFC + 822 formats. +* Four simple aggregators for integer data: + * `mean(1df)` prints the mean. + * `med(1df)` prints the median. + * `mode(1df)` prints the first encountered mode. + * `tot(1df)` totals the set. * `apf(1df)` prepends arguments to a command with ones read from a file, intended as a framework for shell wrappers or functions. * `ax(1df)` evaluates an awk expression given on the command line; this is intended as a quick way to test how Awk would interpret a given expression. * `bel(1df)` prints a terminal bell character. +* `bl(1df)` generates a given number of blank lines. * `br(1df)` launches `$BROWSER`, or a more suitable application for an URL if it knows of one. * `ca(1df)` prints a count of its given arguments. * `cf(1df)` prints a count of entries in a given directory. -* `cfr(1df)` does the same as `cf(1df)`, but recurses into subdirectories as well. +* `cfr(1df)` does the same as `cf(1df)`, but recurses into subdirectories as + well. * `clrd(1df)` sets up a per-line file read, clearing the screen first. -* `clwr(1df)` sets up a per-line file write, clearing the screen before each line -* `dmp(1df)` copies a pass(1) entry selected by `dmenu(1)` to the X CLIPBOARD. +* `clwr(1df)` sets up a per-line file write, clearing the screen before each + line +* `dmp(1df)` copies a pass(1) entry selected by `dmenu(1)` to the X + CLIPBOARD. * `dub(1df)` lists the biggest entries in a directory. * `edda(1df)` provides a means to run `ed(1)` over a set of files preserving any options, mostly useful for scripts. * `eds(1df)` edits executable script files in `EDSPATH`, defaulting to `~/.local/bin`, for personal scripting snippets. -* `fgscr(1df)` finds Git repositories in a directory root and scrubs them with - `gscr(1df)`. -* `fnl(1df)` runs a command and saves its output and error into temporary files, - printing their paths and line counts +* `fgscr(1df)` finds Git repositories in a directory root and scrubs them + with `gscr(1df)`. +* `fnl(1df)` runs a command and saves its output and error into temporary + files, printing their paths and line counts * `gms(1df)` runs a set of `getmailrc` files; does much the same thing as the script `getmails` in the `getmail` suite, but runs the requests in parallel and does up to three silent retries using `try(1df)`. @@ -418,23 +432,22 @@ Installed by the `install-bin` target: * `isgr(1df)` quietly tests whether the given directory appears to be a Git repository. * `jfc(1df)` adds and commits lazily to a Git repository. -* `jfcd(1df)` watches a directory for changes and runs `jfc(1df)` if it sees any. -* `maybe(1df)` is like `true(1)` or `false(1)`; given a probability of success, +* `jfcd(1df)` watches a directory for changes and runs `jfc(1df)` if it sees + any. +* `maybe(1df)` is like `true(1)` or `false(1)`; given a probability of + success, it exits with success or failure. Good for quick tests. -* `mean(1df)` prints the mean of a list of integers. -* `med(1df)` prints the median of a list of integers. -* `mode(1df)` prints the first encountered mode of a list of integers. +* `mftl(1df)` finds usable-looking targets in Makefiles. * `mkcp(1df)` creates a directory and copies preceding arguments into it. * `mkmv(1df)` creates a directory and moves preceding arguments into it. * `motd(1df)` shows the system MOTD. * `pa(1df)` prints its arguments, one per line. * `paz(1df)` print its arguments terminated by NULL chars. -* `pit(1df)` runs its input through a pager if its standard output looks like a - terminal. +* `pit(1df)` runs its input through a pager if its standard output looks like + a terminal. * `plmu(1df)` retrieves a list of installed modules from [`plenv`](https://github.com/tokuhirom/plenv), filters out any modules in `~/.plenv/non-cpan-modules`, and updates them all. -* `rmrej(1df)` deletes rejected hunks from a failed `patch(1)` run. * `shb(1df)` attempts to build shebang lines for scripts from `$PATH`. * `spr(1df)` posts its input to the sprunge.us pastebin. * `sshi(1df)` prints human-readable SSH connection details. @@ -442,12 +455,13 @@ Installed by the `install-bin` target: * `sue(8df)` execs `sudoedit(8)` as the owner of all the file arguments given, perhaps in cases where you may not necessarily have `root` `sudo(8)` privileges. -* `td(1df)` manages a to-do file for you with `$EDITOR` and `git(1)`; I used to - use Taskwarrior, but found it too complex and buggy. -* `tot(1df)` adds up a list of integers. -* `try(1df)` repeats a command up to a given number of times until it succeeds, - only printing error output if all three attempts failed. Good for +* `td(1df)` manages a to-do file for you with `$EDITOR` and `git(1)`; I used + to use Taskwarrior, but found it too complex and buggy. +* `try(1df)` repeats a command up to a given number of times until it + succeeds, only printing error output if all three attempts failed. Good for tolerating blips or temporary failures in `cron(8)` scripts. +* `umake(1df)` iterates upwards through the directory tree from `$PWD` until + it finds a Makefile for which to run `make(1)` with the given arguments. There's some silly stuff in `install-games`: @@ -466,12 +480,12 @@ Manuals The `install-bin` and `install-games` targets install manuals for each script they install. There's also an `install-dotfiles-man` target that uses -`pandoc(1)` to reformat this document as a manual page for section 7df +`pandoc(1)` to reformat this document as a manual page for section 7 (`dotfiles(7df)`) if you want that. I haven't made that install by default, because `pandoc(1)` is a bit heavy. If you want to use the manuals, you may need to add `~/.local/share/man` to -your `/etc/manpath` configuration, depending on your system. +your `~/.manpath` or `/etc/manpath` configuration, depending on your system. Testing ------- diff --git a/bash/bash_completion.d/find.bash b/bash/bash_completion.d/find.bash new file mode 100644 index 00000000..74dc17ad --- /dev/null +++ b/bash/bash_completion.d/find.bash @@ -0,0 +1,89 @@ +# compopt requires Bash >=4.0, and I don't think it's worth making a compatible +# version +((BASH_VERSINFO[0] >= 4)) || return + +# Semi-intelligent completion for find(1); nothing too crazy +_find() { + + # Backtrack through words so far; if none of them look like options, we're + # still completing directory names + local -i opts + for ((i = COMP_CWORD; i >= 0; i--)) ; do + case ${COMP_WORDS[i]} in + -*) + opts=1 + break + ;; + esac + done + if ! ((opts)) ; then + compopt -o dirnames + return + fi + + # For the rest of this, if we end up with an empty COMPREPLY, we should + # just do what Bash would normally do + compopt -o bashdefault -o default + + # Iterate through whatever the subshell gives us; don't add blank items, though + while read -r item ; do + [[ -n $item ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$item + done < <( + + # If the word being completed starts with a dash, just complete it as + # an option; crude, but simple, and will be right the vast majority of + # the time + case ${COMP_WORDS[COMP_CWORD]} in + (-*) + compgen -W ' + -atime + -ctime + -depth + -exec + -group + -links + -mtime + -name + -newer + -nogroup + -nouser + -ok + -perm + -print + -prune + -size + -type + -user + -xdev + ' -- "${COMP_WORDS[COMP_CWORD]}" + ;; + esac + + # Otherwise, look at the word *before* this one to figure out what to + # complete + case "${COMP_WORDS[COMP_CWORD-1]}" in + + # Args to -exec and -execdir should be commands + (-exec|-execdir) + compgen -A command -- "${COMP_WORDS[COMP_CWORD]}" + ;; + + # Args to -group should complete group names + (-group) + compgen -A group -- "${COMP_WORDS[COMP_CWORD]}" + ;; + + # Legal POSIX flags for -type + (-type) + compgen -W 'b c d f l p s' -- "${COMP_WORDS[COMP_CWORD]}" + ;; + + # Args to -user should complete usernames + (-user) + compgen -A user -- "${COMP_WORDS[COMP_CWORD]}" + ;; + esac + ) +} +complete -F _find find diff --git a/bash/bash_completion.d/kill.bash b/bash/bash_completion.d/kill.bash new file mode 100644 index 00000000..0aca041f --- /dev/null +++ b/bash/bash_completion.d/kill.bash @@ -0,0 +1,15 @@ +# Complete kill builtin with jobspecs (prefixed with % so it will accept them) +# and this user's PIDs (requires pgrep(1)) +_kill() { + while read -r pid ; do + case $pid in + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$pid + ;; + esac + done < <( { + compgen -A job -P% + pgrep -u "$USER" . + } 2>/dev/null ) +} +complete -F _kill kill diff --git a/bash/bash_completion.d/make.bash b/bash/bash_completion.d/make.bash index bf4ed268..c157bdc1 100644 --- a/bash/bash_completion.d/make.bash +++ b/bash/bash_completion.d/make.bash @@ -9,6 +9,7 @@ _make() { case $line in # We're looking for targets but not variable assignments + \#*) ;; $'\t'*) ;; *:=*) ;; *:*) diff --git a/bash/bashrc.d/completion.bash b/bash/bashrc.d/completion.bash index 0ddb1b55..3e1c7bac 100644 --- a/bash/bashrc.d/completion.bash +++ b/bash/bashrc.d/completion.bash @@ -8,18 +8,22 @@ # Bash builtins complete -A builtin builtin +complete -A enabled disable +complete -A disabled enable # Bash options complete -A setopt set # Commands -complete -A command command complete coproc exec hash type +complete -A command command complete compopt coproc exec if hash time type until while # Directories complete -A directory cd pushd mkdir rmdir -# Functions +# Functions and variables complete -A function function +complete -A function -A variable declare export local readonly typeset unset +complete -A variable for getopts let read select # Help topics complete -A helptopic help @@ -37,11 +41,8 @@ complete -A shopt shopt # Signal names complete -A signal trap -# Both functions and variables -complete -A function -A variable declare export readonly typeset unset - # The `mapfile` builtin in Bash >= 4.0 -((BASH_VERSINFO[0] >= 4)) && complete -A arrayvar mapfile +((BASH_VERSINFO[0] >= 4)) && complete -A arrayvar mapfile readarray # If we have dynamic completion loading (Bash>=4.0), use it if ((BASH_VERSINFO[0] >= 4)) ; then diff --git a/bash/bashrc.d/prompt.bash b/bash/bashrc.d/prompt.bash index 55c33282..3b99cc12 100644 --- a/bash/bashrc.d/prompt.bash +++ b/bash/bashrc.d/prompt.bash @@ -45,37 +45,32 @@ prompt() { # Decide prompt color formatting based on color availability local format - case $colors in - - # Check if we have non-bold bright green available - 256) - format=$( { - : "${PROMPT_COLOR:=10}" - tput setaf "$PROMPT_COLOR" || - tput setaf "$PROMPT_COLOR" 0 0 || - tput AF "$PROMPT_COLOR" || - tput AF "$PROMPT_COLOR" 0 0 - } 2>/dev/null ) - ;; - - # If we have only eight colors, use bold green - 8) - format=$( { - : "${PROMPT_COLOR:=2}" - tput setaf "$PROMPT_COLOR" || - tput AF "$PROMPT_COLOR" - tput bold || tput md - } 2>/dev/null ) - ;; - - # For all other terminals, we assume non-color (!), and we just - # use bold - *) - format=$( { - tput bold || tput md - } 2>/dev/null ) - ;; - esac + + # Check if we have non-bold bright green available + if ((colors >= 16)) ; then + format=$( { + : "${PROMPT_COLOR:=10}" + tput setaf "$PROMPT_COLOR" || + tput setaf "$PROMPT_COLOR" 0 0 || + tput AF "$PROMPT_COLOR" || + tput AF "$PROMPT_COLOR" 0 0 + } 2>/dev/null ) + + # If we have only eight colors, use bold green + elif ((colors >= 8)) ; then + format=$( { + : "${PROMPT_COLOR:=2}" + tput setaf "$PROMPT_COLOR" || + tput AF "$PROMPT_COLOR" + tput bold || tput md + } 2>/dev/null ) + + # Otherwise, we just try bold + else + format=$( { + tput bold || tput md + } 2>/dev/null ) + fi # String it all together PS1='\['"$format"'\]'"$PS1"'\['"$reset"'\] ' @@ -0,0 +1,11 @@ +#!/bin/sh +# Generate blank lines +if [ "$#" -ne 1 ] || [ "$1" -lt 0 ] ; then + printf >&2 'bl: Non-negative line count needed as sole argument\n' + exit 2 +fi +n=0 +while [ "$n" -lt "${1:-0}" ] ; do + printf '\n' + n=$((n+1)) +done @@ -1,10 +1,32 @@ #!/bin/sh # Count entries in a given set of directories +self=cf + +# Parse options out +while getopts 'o' opt ; do + case $opt in + + # Print only the count, not the filename + o) only=1 ;; + + # Unknown option + \?) + printf >&2 '%s: Unknown option %s\n' \ + "$self" "$opt" + exit 2 + ;; + esac +done +shift "$((OPTIND-1))" + +# Iterate over remaining non-option arguments (directories); default to current +# directory if none given for dir in "${@:-.}" ; do # Warn if a non-directory was given, flag errors, but continue if ! [ -d "$dir" ] ; then - printf >&2 'cf: %s: not a directory\n' "$dir" + printf >&2 '%s: %s: not a directory\n' \ + "$self" "$dir" ex=1 continue fi @@ -21,8 +43,12 @@ for dir in "${@:-.}" ; do [ "$1" = "$dir"/. ] && shift [ "$1" = "$dir"/.. ] && shift - # Print number of parameters - printf '%u\t%s\n' "$#" "$dir" + # Print either just the count, or the count and the dirname + if [ -n "$only" ] ; then + printf '%u\n' "$#" + else + printf '%u\t%s\n' "$#" "$dir" + fi done # Exit non-zero if a non-directory was given as an argument @@ -1,8 +1,13 @@ #!/bin/sh # Count all descendants of given directories; don't follow symlinks for dir in "${@:-.}" ; do - tot=$(find "$dir" -type d \ - -exec sh -c 'cd -- "$1" && cf' _ {} \; | - cut -f1 | tot) - printf '%u\t%s\n' "$tot" "$dir" + if ! [ -d "$dir" ] ; then + printf >&2 'cfr: %s: Not a directory\n' "$dir" + ex=1 + continue + fi + printf '%u\t%s\n' \ + "$(find "$dir" -type d -exec cf -o -- {} \; | tot)" \ + "$dir" done +exit "${ex:-0}" diff --git a/bin/mftl.awk b/bin/mftl.awk new file mode 100644 index 00000000..ee6ff022 --- /dev/null +++ b/bin/mftl.awk @@ -0,0 +1,38 @@ +# Try to find the targets in a Makefile that look like they're targets the user +# could be reasonably expected to call directly + +# Separators are space, tab, or colon +BEGIN { + FS = "[ \t:]" +} + +# Skip comments +/^#/ { next } + +# Join backslash-broken lines +/\\$/ { + sub(/\\$/, "") + line = line $0 + next +} +{ + $0 = line $0 + line = "" +} + +# Check lines matching expected "targets:dependencies" format +/^[a-zA-Z0-9][a-zA-Z0-9 \t_-]+:([^=]|$)/ { + + # Iterate through the targets that don't look like substitutions or + # inference rules and stack them up into an array's keys to keep them + # unique; this probably needs refinement + for (i = 1; i < NF; i++) + if ($i ~ /^[a-zA-Z0-9][a-zA-Z0-9./_-]*$/) + ats[$i] +} + +# Print unique determined targets, sorted +END { + for (t in ats) + print t | "sort" +} diff --git a/bin/rmrej b/bin/rmrej deleted file mode 100755 index 8ecbd2c1..00000000 --- a/bin/rmrej +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# Delete all rejected hunks from patch(1) -find "${1:-.}" -type f -name \*.rej -print -exec rm -- {} \; @@ -1,17 +1,21 @@ #!/bin/sh -# Tag lines from files or stdin with a string prefix or suffix. +# Tag lines from files or stdin with a string prefix or suffix +self=tl -# Parse options out, give help if necessary +# Parse options out while getopts 'p:s:' opt ; do case $opt in - p) - pref=$OPTARG - ;; - s) - suff=$OPTARG - ;; + + # Prefix + p) pref=$OPTARG ;; + + # Suffix + s) suff=$OPTARG ;; + + # Unknown option \?) - usage >&2 + printf >&2 '%s: Unknown option %s\n' \ + "$self" "$opt" exit 2 ;; esac diff --git a/bin/umake b/bin/umake new file mode 100755 index 00000000..8c8d4850 --- /dev/null +++ b/bin/umake @@ -0,0 +1,11 @@ +#!/bin/sh +# Keep going up the tree until we find a Makefile, and then run make(1) with +# any given args +while [ "$PWD" != / ] ; do + if [ -f Makefile ] ; then + exec make "$@" || exit + fi + cd .. || exit +done +printf >&2 'umake: No Makefile found in ancestors\n' +exit 1 @@ -12,12 +12,18 @@ for url ; do ( # If it's a YouTube video without a given start time, load it in mpv(1) case $url in - # If it's a GitHub link, swap "blob" for "raw" to get the actual file - *://github.com/*/blob/*) + # If this is a GitHub or GitLab link, swap "blob" for "raw" to get the actual file + *://github.com/*/blob/*|*://gitlab.com/*/blob/*) url=$(printf '%s\n' "$url" | sed 's_/blob/_/raw/_') ;; - # If it's a not-direct imgur link and not to an album, swap URL + # Dig out the plain text for pastebin.com links + *://pastebin.com/*) + # shellcheck disable=SC2016 + url=$(printf '%s\n' "$url" | sed 's_/[A-Za-z0-9][A-Za-z0-9]*$_/raw&_') + ;; + + # If this is a not-direct imgur link and not to an album, swap URL # elements to get to the actual file (it may not actually be a JPEG; # the MIME type will tell us) *://imgur.com/a/*) ;; @@ -25,7 +31,7 @@ for url ; do ( url=$(printf '%s\n' "$url" | sed 's_imgur\.com_i.imgur.com_;s/$/.jpg/') ;; - # If it's a YouTube video without a given start time, load it in mpv(1) + # If this is a YouTube video without a given start time, load it in mpv(1) *[/.]youtube.com/watch*[?\&]t=) ;; *[/.]youtube.com/watch*) mpv -- "$url" && exit @@ -38,7 +44,7 @@ for url ; do ( # Switch on media type case $mt in - # Open PDFs in xpdf(1); download them first as xpdf(1) doesn't seem to + # Open PDFs in xpdf(1); download them first as xpdf(1) does not seem to # have a way to handle stdin files application/pdf) ( diff --git a/man/man1/bl.1df b/man/man1/bl.1df new file mode 100644 index 00000000..2edaec38 --- /dev/null +++ b/man/man1/bl.1df @@ -0,0 +1,16 @@ +.TH BL 1df "July 2016" "Manual page for bl" +.SH NAME +.B bl +\- generate the given number of blank lines +.SH SYNOPSIS +.B bl +10 +.B bl +0 +.B bl +237481728 +.SH DESCRIPTION +.B bl +generates the given number of blank lines and prints them to stdout. +.SH AUTHOR +Tom Ryder <tom@sanctum.geek.nz> diff --git a/man/man1/cf.1df b/man/man1/cf.1df index ab1338ba..9ced3c20 100644 --- a/man/man1/cf.1df +++ b/man/man1/cf.1df @@ -10,10 +10,20 @@ .br .B cf dir1 dir2 +.br +.B cf +-o dir1 dir2 .SH DESCRIPTION .B cf counts all the entries in the given directories using glob expansion and prints the count. It defaults to the current directory. +.P +Giving the -o option omits printing the directory name (i.e., prints only the +count); this is intended for use in scripts such as cfr(1df). +.P +It uses globs to do the counting, so it will give you unexpected results if +you're counting a directory that has more than ARG_MAX entries in it. You'll +have to resort to find(1) loops in that case. .SH SEE ALSO cfr(1df) .SH AUTHOR diff --git a/man/man1/cfr.1df b/man/man1/cfr.1df index 2ec636bf..37dac2ad 100644 --- a/man/man1/cfr.1df +++ b/man/man1/cfr.1df @@ -14,15 +14,16 @@ dir1 dir2 .B cf counts all the entries in the directory trees rooted at the given arguments, and prints the total. It defaults to the current directory. It should correctly -handle corner cases like files with newlines in them. It will count but will -not follow symbolic links. +handle corner cases like filenames with newlines in them. It will count but +will not follow symbolic links. .SH NOTES You might think this would be better; it's certainly faster: .P - $ find . | wc -l + $ find . -mindepth 1 -print | wc -l .P However, it's subtly wrong; it will double-count anything with a path that -contains a newline! +contains a newline! You could use -print0 and count null characters instead, +but then you've broken POSIX already. .P cfr(1df) and cf(1df) are POSIX-fearing as far as I can tell (please correct me), but there are faster but less compatible ways to do this, while still diff --git a/man/man1/mftl.1df b/man/man1/mftl.1df new file mode 100644 index 00000000..efb2b486 --- /dev/null +++ b/man/man1/mftl.1df @@ -0,0 +1,30 @@ +.TH MFTL 1df "September 2016" "Manual page for mftl" +.SH NAME +.B mftl +\- find and list usable-looking targets in Makefiles +.SH SYNOPSIS +.B +mftl +Makefile +.br +.B +mftl +Makefile1 Makefile2 +.br +grep -v foo Makefile | +.B +mftl +.SH DESCRIPTION +.B mftl +searches for targets in a Makefile specified as either targets or dependencies. +Any targets it finds that are simple strings or filenames that look like they +should be referenced by the user, are printed uniquely sorted to stdout. +.P +This is not 100% accurate (and probably can't be); GNU Make's heresies make it +particularly complicated. For simple POSIX-ish Makefiles, it should work well. +The idea is to get an overview of what's accessible in a Makefile without +having to page through the whole thing. +.SH SEE ALSO +make(1) +.SH AUTHOR +Tom Ryder <tom@sanctum.geek.nz> diff --git a/man/man1/rmrej.1df b/man/man1/rmrej.1df deleted file mode 100644 index 9af77837..00000000 --- a/man/man1/rmrej.1df +++ /dev/null @@ -1,17 +0,0 @@ -.TH RMREJ 1df "August 2016" "Manual page for rmrej" -.SH NAME -.B rmrej -\- delete all rejected hunks from a failed patch(1) -.SH SYNOPSIS -.B rmrej -.br -.B rmrej -dir -.SH DESCRIPTION -.B rmrej -uses find(1) to find rejected patch hunks (.rej) in the given directory -(defaulting to the current directory), print their names, and delete them. -.SH SEE ALSO -patch(1) -.SH AUTHOR -Tom Ryder <tom@sanctum.geek.nz> diff --git a/man/man1/umake.1df b/man/man1/umake.1df new file mode 100644 index 00000000..247ea50e --- /dev/null +++ b/man/man1/umake.1df @@ -0,0 +1,15 @@ +.TH UMAKE 1df "September 2016" "Manual page for umake" +.SH NAME +.B umake +\- run make(1) with the closest Makefile in current working directory ancestry +.SH USAGE +.B umake +.br +.B umake +prefix=/foo/bar install +.SH DESCRIPTION +Iterate up through the directory tree starting with the current directory, +looking for a Makefile, and run make(1) with the given arguments as soon as one +is found. +.SH AUTHOR +Tom Ryder <tom@sanctum.geek.nz> diff --git a/man/man6/rndn.6df b/man/man6/rndn.6df index 97fbe30a..25a30513 100644 --- a/man/man6/rndn.6df +++ b/man/man6/rndn.6df @@ -6,14 +6,14 @@ .B rndn .br .B rndn --s 381290 +381290 .br business-critical-process -t "$(\fBrndn\fR)" .SH DESCRIPTION .B rndn uses an advanced but somewhat esoteric algorithm derived by Adams (2001) to -return a random number. The seed can be derived internally or specified with -the -s option. +return a random number. The seed can be derived internally or specified as an +argument. .P While rndn(6df) has proven robust in the author's production usage, its algorithm has not been formally verified. diff --git a/mutt/muttrc.m4 b/mutt/muttrc.m4 index 44883c32..6211fb85 100644 --- a/mutt/muttrc.m4 +++ b/mutt/muttrc.m4 @@ -26,14 +26,28 @@ set query_command = 'abook --mutt-query %s' # Alerts set beep_new = yes +# Attachments +attachments +A */.* +attachments -A text/x-vcard application/pgp.* +attachments -A application/x-pkcs7-.* +attachments +I text/plain +attachments -A message/external-body +attachments -I message/external-body + # Caching set header_cache = '~/.cache/mutt/headers' # Colors -color indicator black white -color normal default default -color status white color22 -color tree default default +color attachment brightyellow default +color hdrdefault cyan default +color indicator black white +color markers brightred default +color normal default default +color quoted green default +color signature cyan default +color status default color22 +color tilde blue default +color tree default default # Completion bind editor <Tab> complete-query @@ -47,7 +61,9 @@ set move = no set mark_old = no # Headers -hdr_order Date From To Cc +ignore * +unignore Date From: To Cc Subject +hdr_order Date From: To Cc Subject set edit_headers = yes # Index @@ -68,6 +84,9 @@ set confirmcreate = yes # Menus set menu_context = 1 +# MIME +mime_lookup application/octet-stream + # Pager set pager_context = 1 set pager_format = '%4C %Z %[!%b %e at %I:%M %p] %.20n %s%* -- (%P)' @@ -81,6 +100,9 @@ set tilde = yes alternative_order text/plain text/html * auto_view text/html +# Quoting +set quote_regexp = '^(>[ \t]*)+' + # Responses set fast_reply = yes set forward_format = 'Fw: %s' @@ -93,6 +115,9 @@ set sort_aux = 'last-date-received' set strict_threads = yes set thorough_search = yes +# SSH +set time_inc=250 + # Encryption settings set crypt_replysign = yes set crypt_replyencrypt = yes @@ -113,6 +138,9 @@ bind index,pager \Cd half-down bind generic,index,browser,pager \Cf next-page bind generic,index,browser,pager \Cb previous-page +# Turn off annoying mailbox lock feature +bind index '%' noop + # Jump to mailboxes macro generic,index,browser,pager gi '<change-folder>=inbox<enter>' 'Change to inbox folder' macro generic,index,browser,pager gs '<change-folder>=sent<enter>' 'Change to sent folder' diff --git a/readline/inputrc b/readline/inputrc index dd284f0b..3f98c08d 100644 --- a/readline/inputrc +++ b/readline/inputrc @@ -8,9 +8,6 @@ set bell-style none # Let readline do stuff like word killing, not stty(1) set bind-tty-special-chars off -# Jump to the matching parenthesis briefly when closing one -set blink-matching-paren on - # Ignore case when matching and completing paths set completion-ignore-case on @@ -85,7 +82,10 @@ $if Bash $endif -# Don't let bc complete filenames (!?) +# bc macros $if bc - Tab: + + # Don't let bc complete filenames (!?) + Tab: + $endif |