14 Commits

Author SHA1 Message Date
3e740b0a0b Minor manpage clean up; add some examples 2025-12-18 22:12:17 +01:00
a10715151a Add pick to the list of tools so that it gets installed 2025-12-18 22:11:03 +01:00
d5ba70db67 Fix command names in manpages 2025-12-12 14:20:37 +01:00
33adddf019 Cleanup makefile 2025-12-06 14:54:50 +01:00
6061556d39 Add shell expansion for output lines
Do shell expansion for output lines (|, @ and ?), so that it is possible to
evaluate arbitrary shell expressions.

Other fixes included:
- Don't assume ksh is in bin.
- Eval commands using the standard shell instead of ksh.
- Make sure we delete temp files; also avoid creating a temp file per line.
- Don't print ? output if return status is 0.
- Fix literal \? match when evaluating lines.
2025-11-28 22:42:48 +01:00
8afe36016a Don't override prefix if already provided 2025-11-22 17:59:35 +01:00
b3e848efe8 Delete rr script
Use instead `rr` in the `kshutils` repository.
2025-11-22 17:42:52 +01:00
61efff731f p - Don't ask for command when finished, exit directly 2024-07-05 17:01:11 +02:00
bd5a149cc0 Update Makefile 2024-06-17 12:11:51 +02:00
54217f9944 Accept commands with no arguments 2024-06-17 12:11:11 +02:00
66c1da49fb Send OSC escape sequences 2024-06-17 12:10:42 +02:00
9465227fe7 Plan 9's p pager
Useful for dumb terminals (e.g. `shell` under Emacs).
2024-06-17 12:06:09 +02:00
3e32f1b04e pick - Select one entry from stdin and/or argv
Pick will take stdin and all command line arguments and display a
ksh-like selection menu will all input lines/arguments.
2023-09-13 14:33:21 +02:00
34cfc3cf12 scmfmt - Use par instead of fmt and increase default width
The `-p` option is only available in OpenBSD. As there's no standard
way of ignoring lines by prefix, use `par`, which at least will be
installable almost everywhere.
2023-09-12 17:02:57 +02:00
21 changed files with 292 additions and 98 deletions

View File

@@ -1,8 +1,12 @@
prefix=$$HOME/opt/pkg/miscutils
target_bin=${prefix}/bin
target_man=${prefix}/share/man/man1
bin=bwrap hppt mkgmap newp rot rr scmfmt ts upcasetl unpage
prefix?=$$HOME/.local/cstow/miscutils
bindir=${prefix}/bin
mandir=${prefix}/share/man/man1
bins=bwrap hppt mkgmap newp osc p pick rot scmfmt ts upcasetl unpage
.PHONY: install clean
install:
install -d ${target_bin} ${target_man}
install -c ${bin} ${target_bin}
install -c ${bin:%=%.1} ${target_man}
install -d ${bindir} ${mandir}
install -c ${bins} ${bindir}
install -c ${bins:%=%.1} ${mandir}
clean:
rm -f *~

View File

@@ -1,27 +1,3 @@
# miscutils
Miscellaneous UNIX utilities.
## bwrap
Wrap text received in stdin as if it was a single line. Indicate breaks with the ":" charater at both ends.
## hppt
Reformat stdin as a horizontal paper tape.
## mkgmap
Generates a simple Gophermap in its standard output, listing all text files in the current directory
in reverse alphabetical order.
## newp
Creates a new ms phlog post. The file name will contain the current date and word separated by dashes.
## rot
Visually rotate stdin 90 degrees counter clockwise, swapping rows and columns.
## rr
Run a command repeteadly until it fails.
## scmfmt
Format stdin to use as a commit message
## ts
Runs the shell tests passed as arguments.
## unpage
Removes all page headers and footers from stdin, getting as result output that contains a single continuous page.
## upcasetl
Takes an ms troff document in stdin, and outputs to its stdout the same document
with all `.tl` and `.sh` converted to uppercase.

View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm bwrap
.Nd Wrap input text as a unit
.Nd wrap input text as a unit
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION

2
hppt.1
View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm hppt
.Nd Reformat stdin as a horizontal paper tape
.Nd reformat stdin as a horizontal paper tape
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION

View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm mkgmap
.Nd Create a simple Gophermap for the current directory
.Nd create a simple Gophermap for the current directory
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION

2
newp.1
View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm newp
.Nd Create a new phlog post
.Nd create a new phlog post
.Sh SYNOPSIS
.Nm
.Ar word ...

18
osc Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env ksh
(( $# < 1 )) && exit 64
[[ -v X_OSC_DISABLE || ! -t 1 ]] && exit 0
case $1 in
link)
[[ -z $2 ]] && exit 64
printf "\e]8;%s\e\\" "$2"
;;
pwd)
(( $# != 1 )) && exit 64
printf "\e]7;file://%s%s\e\\" "$HOSTNAME" "$PWD"
;;
title)
(( $# == 1 )) && exit 64
shift;
printf '\e]2;%s\e\\' "$*"
;;
esac

43
osc.1 Normal file
View File

@@ -0,0 +1,43 @@
.Dd Jun 11, 2024
.Dt OSC 1
.Os
.Sh NAME
.Nm osc
.Nd print OSC escape sequences
.Sh SYNOPSIS
.Nm
.Cm pwd
.Nm
.Cm link
.Ar URI
.Nm
.Cm title
.Ar word ...
.Sh DESCRIPTION
.Nm
prints an OSC escape sequence to stdout if connected to a tty.
If stdout is not a TTY, prints nothing.
.Pp
Three escape sequences are supported:
.Bl -tag -width Ds
.It Cm pwd
ESC 7, set current working directory.
.It Cm link
ESC 8, display an URI.
.It Cm title
ESC 2, set a title for the current window.
.El
.Pp
Whatever it is done with these escape sequences depends on the
terminal emulator. To avoid printing anything, even on ttys, define
.Ev X_OSC_DISABLE
with any value.
.Sh ENVIRONMENT
.Bl -tag -width X_OSC_DISABLE
.It Ev X_OSC_DISABLE
Don't do anything.
.El
.Sh EXIT STATUS
.Ex -std
.Sh AUTHORS
.An Adolfo Perez Alvarez Aq Mt adolfopa@sdf.org

49
p Executable file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env perl
use strict;
use warnings;
my $pagesize = $ENV{'LINES'} || 22;
open(my $tty, '<', '/dev/tty')
or die "$0: Cannot open /dev/tty for reading: $!";
sub evalcmd {
{
chomp($_ = <$tty>);
if (/^q$/) {
exit(0);
} elsif (/^!(.*)/) {
system($1);
redo;
}
}
}
sub printfile {
my ($fh) = @_;
my $lines = 0;
while (<$fh>) {
print;
&evalcmd unless ++$lines % $pagesize;
}
}
unshift(@ARGV, '-') unless @ARGV;
my $n = $#ARGV;
for (@ARGV) {
if (/^-$/) {
&printfile(\*STDIN);
&evalcmd if $n--;
} elsif (/^-(\d+)$/) {
$pagesize = $1;
} else {
open(my $fh, '<', $_) or die "$0: Cannot open $_ for reading: $!";
&printfile($fh);
&evalcmd if $n--;
close($fh);
}
}
close($tty);

48
p.1 Normal file
View File

@@ -0,0 +1,48 @@
.Dd May 17, 2024
.Dt P 1
.Os
.Sh NAME
.Nm p
.Nd paginate
.Sh SYNOPSIS
.Nm
.Op Fl number
.Ar
.Sh DESCRIPTION
.Nm
copies its standard input, or the named files if given,
to its standard output,
stopping at the end of every page and at the end of each file.
The special file name
.Pa -
can be used to refer explicitly to the standard input.
.Pp
Page size is defined by the
.Ev LINES
environment variable.
If not defined, a default page size of 22 will be used.
The page size can be overriden with the numeric option.
.Pp
While waiting for a newline,
.Nm
interprets the commands:
.Bl -tag
.It !
Run the rest of the line as a shell command.
.It q
Quit.
.El
Any other input will show the next input page.
.Sh ENVIRONMENT
.Bl -tag -width LINES
.It Ev LINES
Number of lines of the terminal.
.El
.Sh EXIT STATUS
.Ex -std
.Sh HISTORY
This is a reimplementation of Plan 9's
.Nm
pager.
.Sh AUTHORS
.An Adolfo Perez Alvarez Aq Mt adolfopa@sdf.org

35
pick Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env perl
use strict;
use warnings;
use Scalar::Util qw{looks_like_number};
my @choices;
for (@ARGV) {
if (/^--$/) {
push(@choices, <STDIN>);
} elsif (/^@(.+)$/) {
open(my $fh, '<', $1);
push(@choices, <$fh>);
close($fh);
} else {
push(@choices, "$_\n");
}
}
open(my $tty, '<', '/dev/tty');
my $sel;
until (looks_like_number($sel) && $sel > 0 && $sel <= @choices) {
while (my ($i, $c) = each @choices) {
print $i+1 . ') ' . $choices[$i];
}
print $ENV{'PS3'} || '#? ';
exit(1) unless defined($sel = <$tty>);
}
close($tty);
print $choices[$sel - 1];

44
pick.1 Normal file
View File

@@ -0,0 +1,44 @@
.Dd December 15, 2025
.Dt PICK 1
.Os
.Sh NAME
.Nm pick
.Nd choose interactively from a set of arguments and input lines
.Sh SYNOPSIS
.Nm
.Ar arg ...
.Sh DESCRIPTION
.Nm
will display a Korn shell style selection menu with any arguments as options.
The special argument
.Ar --
will read stdin and present each line as a choice.
.Pp
When a selection is made, the command will print its value to stdout;
If the selection is aborted, nothing will be printed.
.Sh ENVIRONMENT
.Bl -tag -width PS3
.It Ev PS3
Prompt string displayed to the user (default: #?).
.El
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
.Bd -literal -offset indent
$ pick 1 2 -- 3 4 <<.
> a
> b
> c
> .
1) 1
2) 2
3) a
4) b
5) c
6) 3
7) 4
#? 4
b
.Ed
.Sh AUTHORS
.An Adolfo Perez Alvarez Aq Mt adolfopa@sdf.org

2
rot.1
View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm rot
.Nd Rotate stdin 90 degrees
.Nd rotate stdin 90 degrees
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION

16
rr
View File

@@ -1,16 +0,0 @@
#!/bin/sh
[ $# -eq 1 ] && echo "usage: $0 command ..." && exit 64
tmp1=$(mktemp $0.XXXXXXXXXX)
tmp2=$(mktemp $0.XXXXXXXXXX)
trap "rm $tmp1 $tmp2; exit 0" 1 2 15
while "$@" >$tmp2
do
if ! diff $tmp1 $tmp2
then
cp $tmp2 $tmp1
else
echo -n "."
fi
sleep 2
done
rm $tmp1 $tmp2

30
rr.1
View File

@@ -1,30 +0,0 @@
.Dd Jun 10, 2022
.Dt RR 1
.Os
.Sh NAME
.Nm rr
.Nd Repeteadly run a command until it exits with a non zero status
.Sh SYNOPSIS
.Nm
.Ar cmd Op Ar arg ...
.Sh DESCRIPTION
Run command
.Ar cmd arg ...
repeteadly until it fails.
.Pp
In every run, compare its stdout with the one from the previous run.
If there has been any change, print a diff;
otherwise, display a dot to indicate progress.
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
.Bd -literal -offset indent
$ rr pgrep -f foo
0a1,2
> 6871
> 25428
\&...^C
$
.Ed
.Sh AUTHORS
.An Adolfo Perez Alvarez Aq Mt adolfopa@sdf.org

4
scmfmt
View File

@@ -21,9 +21,9 @@ i\
bl' |
sed -e '1s/^/./' -e 's/^ /./' |
fmt -p |
par -P=. |
awk '
BEGIN { LIMIT = 65 }
BEGIN { LIMIT = 72 }
NR == 1 || /^[^\.]/ || length($0) < LIMIT {
sub(/^\./, NR == 1 ? "" : " ");
print;

View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm scmfmt
.Nd Format a commit message
.Nd format a commit message
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION

43
ts
View File

@@ -1,18 +1,14 @@
#!/bin/ksh
#!/usr/bin/env ksh
function tsrun
{
typeset err out ret
typeset ret
err=$(mktemp /tmp/XXXXXXXXXX)
out=$(mktemp /tmp/XXXXXXXXXX)
trap "rm $err $out" EXIT
eval "$@" >$out 2>$err
sh -c "$@" >$out 2>$err
ret=$?
sed 's/^/| /' $out
sed 's/^/@ /' $err
print '? '$ret
(( ret != 0 )) && print "? $ret"
}
function tseval
@@ -26,15 +22,37 @@ function tseval
print "$ln"
tsrun "${ln#$}"
;;
!(?|@|\|))
!(\?|@|\|))
print "$ln"
;;
esac
done
}
function tsexpand
{
typeset ln
while read ln
do
case ${ln%% *}
in
\?|@|\|)
eval print \""$ln"\"
;;
*)
print "$ln"
;;
esac
done
}
(( $# == 0 )) && exit 64
err=$(mktemp /tmp/XXXXXXXXXX)
out=$(mktemp /tmp/XXXXXXXXXX)
trap "rm $err $out" HUP INT QUIT TERM
if [[ $1 = -b ]]
then
(( $# == 1 )) && exit 64
@@ -45,8 +63,13 @@ then
(rm $fn && tseval >$fn) <$fn
done
else
exp=$(mktemp /tmp/XXXXXXXXXX)
trap "rm $exp" HUP INT QUIT TERM
for fn
do
tseval <$fn | diff -u $fn -
tsexpand <$fn >$exp
tseval <$fn | diff -u $exp -
done
rm $exp
fi
rm $err $out

2
ts.1
View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm ts
.Nd Run shell tests
.Nd run shell tests
.Sh SYNOPSIS
.Nm
.Op Fl b

View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm unpage
.Nd Remove page headers and footers from text documents
.Nd remove page headers and footers from text documents
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION

View File

@@ -3,7 +3,7 @@
.Os
.Sh NAME
.Nm upcasetl
.Nd Upcase titles and section headers in an ms troff document
.Nd upcase titles and section headers in an ms troff document
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION