That said, I am a huge fan of manual window management.
164 karma · joined September 26, 2025
email: piekvorst@outlook.com
That said, I am a huge fan of manual window management.
This is not to say that there's nothing to improve. Multiline editing experience suffers, and non-readline shells aren't supported. Those problems were solved by Plan 9 (at the cost of dropping xterm compatibility), but the mainstream hasn't yet adopted those solutions.
% echo test >'/tmp/hello world'
% cat /tmp/hello*
test
This is bash 5.3.9.Still, I couldn't agree more on limiting IFS. Personally, I set it only to <LF>.
In my scripts, I rely on the $(ls) idiom heavily. People I've talked to consider this an anti-pattern and suggest relying on -0, -z, --zero, --null, and -print0 flags instead. I don't deny that it's better than nothing when correctness is the goal, but I’d counter that shell is more about using a familiar interface (text representation) to solve new tasks, not about writing correct code (that’s the domain of other languages). An uncritical pursuit of correctness often results in convoluted code.
(I know that $(ls) is a subject to various expansions. I solve this problem by using a shell that doesn't do that [1].)
Another consideration is that /bin/ls and /bin/find are not the only sources of filenames. Sometimes the source is third-party or has to be user-friendly (and thus separated by traditional newlines).
Some typographical issues just can't be solved by a pursuit of mechanistic correctness. For another example, the \.txt$ idiom wouldn't work if spaces are allowed at the end of filenames. Those problems are not even shell-specific.
Those are just a few of my personal notes. Fortunately, there's a more systematic and comprehensive study of this issue [2].
[1]: https://9p.io/sys/doc/rc.html
[2]: https://dwheeler.com/essays/fixing-unix-linux-filenames.html
Relying on it even in limited scenarios can train an invisible habit that would backfire at the least expected moment.
Any assistance intended for immediate action should itself be immediate, not indirect.
. . . if you forget which commands deal with windows, just type @b[ESC-?]@t[window]@b[ESC].
This weird command is presented with such a benevolent innocence as if it's the simplest thing in the world.I think the better advice for command-line editing would be to set up the mouse.
I've never used the majority of these tricks for decades, except for brace expansion, process substitutions, and complex redirections.
, x/(.+\n)+/ .,+#0-#1 x/\n/ c/ /
, x/\n+/ c/\n/
(I haven’t tested it.)I’m glad that sam worked out for you. You can learn more from [1] and [2]. If you need any help, you’re always welcome to ask me.
[1]: https://ratfactor.com/papers/sam_tut.pdf
[2]: https://9p.io/sources/contrib/steve/other-docs/struct-regex....
I find the X command extremely powerful, and can't see any way to
have a streaming implementation that will look at multiple files
simultaneously.
> Is there a port to Apple silicon?plan9port works on it. It compiled without any errors on my Apple Silicon Mac.
[1]: https://9fans.github.io/plan9port/man/man1/ssam.html
[2]: https://9fans.github.io/plan9port
[3]: https://9fans.topicbox.com/groups/9fans/Tdf6095a105816f01-M3...
. The dot (".") never matches newlines, which keeps line-oriented idioms from accidentally spanning newlines [1]
. Changes must be sequential and non-overlapping (that's why I deleted the whole thing before processing in the third example).
. Sam matches only the original input, not past changes.
. Addresses (expressions before commands) select a single range, x commands select multiple ranges and loop over it.
[1]: https://p9f.org/sys/doc/sam/sam.html, Regular expressions
:loop N; s/\n[[:space:]]\+/ /g; t loop; p
In sam, the equivalent is: x/(.+\n)*/ x/\n */ c/ /
It reads like this: loop over paragraphs of non-empty lines, loop over newline followed by spaces, replace with a single space. It's surprisingly close to SQL in its eloquence.Another example:
N; h; s/\n/->/g ;p; g; D
In sam, an equivalent would be {
1,$-2 x/./ {
a/->/
/./ t .
}
$-1 d
}
Again, it's readable from top to bottom: from the first line to the second from the end, loop over each symbol, put "->" after it and copy the next symbol next to it; delete the last line.Let's see how far we can get. Another example:
N; h; s/\n/->/g; p; G; D
In sam, an equivalent would be: {
d
1,$-2 x/./ {
1,/./ x/.|\n/ {
g/./ t $
g/\n/ $ c/->/
}
$ c/\n/
}
}
It reads like this: delete the whole thing; from the first line to the second from the end, loop over each character; on each iteration, from the first line to the next character, run an inner loop over each character or newline; if it's a character, put it at the end; otherwise, put "->" at the end; once the inner loop is done, put a newline at the end.The final example from the post is too long to have it here (15 lines). Here's just the sam equivalent for it:
x/(.+\n)+|\n+/ {
g/./ x/\n/ c/ /
v/./ c/\n/
}
It reads like this: loop over paragraphs of non-empty lines or sequences of newline characters; if it has any symbol (that is, it's a paragraph), replace each newline symbol with a space; if it doesn't have a symbol (that is, it's a sequence of newline symbols), replace it with a single newline.What I have learned from this is that a tool with limited but well-chosen primitives is more convenient than a universal state machine.
(My examples may not be the exact same algorithms, since I do not understand (or need) sed concepts, but they do produce the same output.)
The only major problems are X.org dependency, lack of mouse warping in XWayland (essential for Acme), and slow text rendering on Raspberry Pi 5.
By making them comments, Go subtly signals that these are exceptional, making them less prominent and harder to abuse.
If you’re a U.S. citizen, it’s worth studying what this country’s foundational freedom means specifically, why and why not something else, such as consumer rights.
Edit: the same applies to diffs generated by /bin/diff. Most of the time, diff strings are unique enough to locate them by plain text searching.
In contrast, in Plumber [1], we have things like !98—this text opens pull request no. 98 by passing "!98" to the local server, which knows how to interpret it.
Both approaches go one step beyond plain text. However, Plumber’s approach, at least, doesn’t compromise the plain text itself by embedding invisible elements.
This eliminates an entire category of risks by design. With no hidden metadata, accidental clicks are less probable and social engineering attacks, such as UI deception, are impossible.
It steps back from the “customize everything” mantra, believing that approach leaves users with an underdeveloped essential system. But it still has two major APIs: one for window manipulation [2], the other for text-based integration with the surrounding system via plumber [3].
All textual CLI tools (that is, those without pseudographics) work by default and are the heart of its style.
I use Acme for everything except web browsing (although most links are still managed by Acme).
[1]: http://youtu.be/dP1xVpMPn8M
(At one moment, I used to work on a single desktop with around 20 windows, no dock, just windows, on my 14in MacBook with 125% DPI. Too much but possible. Now I keep only 6-7 windows.)
This is not to say that dynamic window management is worse. Far from it. But it excels at this: dynamic, rapidly changing environments, where at almost any given moment something is either opening, closing, or changing its dimensions. This is usually the case with specialized programs like web browsers or IDE, but not with the main system WM.
The main problem is that overlapping windows and automatic window management are incompatible. The former assumes that user sets the dimensions and is always right, which makes the latter powerless to follow any efficient algorithm. To give an example, if you manage your windows with a dock and “maximize” button, they’d break overlapping patterns.
> I either want one full screen windows or a few windows side by side.
You’re not wrong to work like this, but it may be a byproduct of modern hybrid systems making it harder to fully internalize the overlapping windows concept.
/s