HNHacker News
TopNewBestAskShowJobs

JNRowe

7,427 karma · joined February 3, 2014

username at gmail.com ; Feel free to get in touch.

[ my public key: https://keybase.io/jnrowe; my proof: https://keybase.io/jnrowe/sigs/orH3nyNqAK4vkIpcxn2HRihHPV2HX80SyDwM9cR5xnw ]

submissionscomments
JNRowe··on Oh My Zsh
FWIW, that is also the default behaviour of zsh's standard completion subsystem for kill. You can try it yourself: "zsh -f" to get a shell without reading a fancy config, start compinit, "kill <Tab>".

You can even disable verbose mode via zstyle, should you be the type of person that likes a simple pid list like bash's completion project provides. To me this level of customization is the main feature zsh provides, but not everyone incessantly turns every knob they see.

JNRowe··on Oh My Zsh
Noting that you didn't solicit advice, but…

* Exporting shell variables such as HISTFILE isn't necessary, and can be unsafe. For example, if you decide to pop open unconfigured bash from within a zsh session it would intermingle its history on write.

* There is a smart keyboard subsystem that neatly manages terminal differences¹, making it much nicer compared to inserting {system,term}-specific escapes in to your config.

Hoping this comes across in the helpful spirit it was intended, not as nitpicky unwanted code review.

¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

JNRowe··on Oh My Zsh
As we're in a zsh story, I'll point out it comes with a clever file renaming interface out of the box¹. It allows full access to all the advanced glob operators zsh provides too².

¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

² https://zsh.sourceforge.io/Doc/Release/Expansion.html#Filena...

JNRowe··on Oh My Zsh
Like practically everything zsh, it can be configured. The select-word-style zle widget¹ ships with zsh, and has a bash compatible setting(among others). The interface is super powerful, and given that you can change it in individual zle widgets you can make it context aware if you wish too.

¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

JNRowe··on Use Midnight Commander like a pro (2015)
Well, you don't have to use the two pane mode if you don't want anyway. You can switch to single pane mode, use the second pane for file info, use the second pane as a directory tree in the manner of a "regular" single pane explorer, etc.

To perform your "copy, navigate, paste" task while in mc's single pane mode you could either:

a) tag files, pop open the second pane temporarily, navigate and copy.

b) tag files, swap the panes in the background, navigate and copy.

c) tag files, use the bindings to copy them to the inbuilt command line, navigate and copy. Using the "quick cd" dialog would probably speed this up.

d) any of the above with inverted target and source movement.

e) probably a thousand other more sensible ways than the three or cheat-y six I just thought of ;)

JNRowe··on Keeping a long shell history
zsh has a comprehensive hook system available for these types of tasks¹(zshaddhistory in this case). It gives you more options to control how/when the history is preserved, and allows you to be more selective in when it should be written.

Possibly worth noting for others that you'd want to think this through if you're using any of the history eliding options(hist_ignore_space² for example), as one history file may contain secrets when you're really expecting that it wouldn't.

There is also a better interface to work with hook functions through the add-zsh-hook mechanism³, which allows stacking multiple hook functions together.

¹ https://zsh.sourceforge.io/Doc/Release/Functions.html#index-...

² https://zsh.sourceforge.io/Doc/Release/Options.html#History

³ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

JNRowe··on Use Midnight Commander like a pro (2015)
Depends on the archive type and how the vfs/extfs code was implemented for it¹. It also depends on how the archive is treated if it is compressed container, which can be seen by looking at how a .tar and .tar.xz are handled for example. The zip handler is probably the easiest to understand, as it doesn't need to contend with external compression wrappers and is a simple perl script. (In some cases it would probably be nicer if it did extract the entire archive to tmpfs, such as when you independently pull a few files from a massive .deb for example)

Implementing your own extfs scripts to wrap a simple menu around some task can be really useful, far beyond basic archives. I wrote one so that I can shuffle my todo list priorities by moving fake "task files" in to different pseudo-directories.

¹ https://github.com/MidnightCommander/mc/tree/master/src/vfs/

JNRowe··on Use Midnight Commander like a pro (2015)
mc sets $MC_SID in the subshell, so you can query that in your prompt to mark prompts running under mc.

Another option might be to bind F10 to start mc, so that it acts as a toggle whether in mc or in a non-mc shell. You'd need to wrap a zle widget in zsh, or add a '$if Bash' guard to your inputrc with bash.

JNRowe··on Z – Jump around
My description above wasn't great. I meant completion would be an improvement in the sense that under zsh `~-<Tab>` can show not only the possible completion options, but also the value they expand to. For example, mine is set to display in the manner of a colorful version of the text below:

    $ cd ~-
    0 -- ~
    1 -- ~/Downloads
    2 -- ~/Desktop
The handling of tilde expansion under bash is a readline option, so users would configure it in their inputrc. It is pretty useful in general, because then it is also available to tools like imv¹ beyond just bash. Unfortunately, as it is handled separately from word completion you'd need to change the completion function to make it match the mark-directories behaviour you like.

If I wanted the text expanded for history use I'd probably expand it before writing using a zshaddhistory hook, but I don't think there is an equivalent in bash so changing the line buffer probably is the best option.

¹ https://www.nongnu.org/renameutils/

JNRowe··on Z – Jump around
Personally, I'd find the completion output from `~-<Tab>` a worthy improvement, although admittedly with zsh you can configure completion to display both name and value for `$c<Tab>` too I guess(can't recall if that is possible with bash).

User names should not begin with a hyphen¹, so it shouldn't interfere with home directory references.

The child process point is an interesting one, I feel like you could workaround it by using a chpwd hook to export $dirstack and set it at startup(or a precmd function and $DIRSTACK if using bash). Something like `export DIRSTACK=${(pj#:#)dirstack}` in the hook and `dirstack=(${(ps#:#)DIRSTACK})` in the startup file. I'll concede this point though, as while a fun thought experiment the end result would be ghastly ;)

¹ https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1...

JNRowe··on Z – Jump around
A slightly different take is available if you're a zsh user, as you can take advantage of named directories to replace the aliases. If you do this the directories you've added will show up in regular completions and be available as arguments to commands too. For example, `hash -d name=location` allows you to use `~name` for the path.

`run-help hash` for the basic interface, or zshexpn(1) for the gory details including fancy dynamic naming.

JNRowe··on Z – Jump around
pushd also gives you simple access via `~-n` in both bash and zsh out of the box. The bonus being that `~-[n]` is correctly handled when used as an argument to other commands too, so that `cp myfile ~-4/` does what you'd expect. The zsh completion for cd functions really nicely for this too, given that you can use zstyle to annotate your entries or group dynamic completions separately.

If you're using zsh you can implement the GPs idea by hooking chpwd, so that you don't need to change your muscle memory on cd. You can even combine them by enabling the auto_pushd option and just carrying on with regular cd whilst gaining access to `~-n` with no other changes.

JNRowe··on Statement about the EU Cyber Resilience Act
The vote result that led to this public statement received a lot of commentary yesterday¹, and the linked LWN article has a lot of interesting thoughts on the subject too.

¹ https://news.ycombinator.com/item?id=38787005

JNRowe··on Mblaze – Unix utilities to deal with Maildir
I'm so close to being a full-time mblaze user, it is truly excellent. There is something so smart about being able to use your standard shell tooling and interaction facilities to interact with mail. It is like everything that was a good idea with mh¹/nmh decades ago, just better all round and with a nicer message format.

Even if you don't like the idea of using command line tools as your MUA, you can easily make mblaze interactive with common tooling. For example, you could use mlist via fzf along with its --preview window as pretty awesome interactive client. Everything works as you'd expect, and you have all the power of every single tool you use to mangle that mail at any point.

I just seem to fall back in to mutt too easily in the end, I can't get over the final hump. I've even implemented a chunk of mimicry bindings so that I shouldn't even notice, but mutt pulls me back in for "that one tiny feature" every now and then. I've been doing this dance for at least a few years at this point², but I think it may be longer.

¹ https://en.wikipedia.org/wiki/MH_Message_Handling_System

² https://github.com/leahneukirchen/mblaze/commits?author=JNRo...

JNRowe··on Some Useful Bash Aliases (2022)
That seems potentially unpredictable versus building the string and calling cd once. For example, if you use direnv-type tools there may be side-effects along the route¹. zsh users could have state changing via the chpwd functions too, although that could be mitigated with "cd -q" at least.

Obviously, it might not be an issue for your use, but just noting a potential gotcha if I were to lift it for example.

[ Golf-y zsh, because vacation time and AoC has finished: ..() { cd ../${(pj:/:)${@/*/..}} } ]

¹ even just expensive setup/teardown delays would feel odd*

JNRowe··on Some Useful Bash Aliases (2022)
That is a GNU findutils extension, and modern means 2004 in this instance¹ ;) I spelunked because I thought "that always worked, didn't it?"

¹ https://git.savannah.gnu.org/cgit/findutils.git/tree/NEWS#n2...

JNRowe··on Some Useful Bash Aliases (2022)
There are few more general solutions to this interaction pattern(that also don't involve redundant history entries if you're OCD).

* bash has a glob-expand-word function which will perform inplace expansion of patterns, it is bound to C-x* out of the box. Using it will expand the pattern before point. Depending on the keymap you're using it is available via the same binding or the expand-word function in zsh too.

* C-xg (the glob-list-expansions function) will simply dump the expansion but retain the pattern in the command, if you'd prefer it didn't get added to history fully expanded for example. Again depending on keymap in zsh it is bound to the same key and calls the list-expand function.

* You can recall combinations of arguments from any line in history, so in your example 'rm !*' would recall all the args to previous command. The main reason this is useful is that you can also apply substitutions to fix incorrect results, and also because you can target other lines not just the previous one. You can even tack a modifier on to print the result without executing to double-double-check things, should you be feeling super careful(rm !*:p). zsh supports the same syntax, but has advanced more advanced modification options.

JNRowe··on Let the terminal bells ring out
One of the smart things with zsh is that the hooks¹ like precmd can be replaced with arrays of functions, so that you can cleanly have multiple hooks per hook point. It even provides a nice tool to work with the the arrays too², which makes editing/enabling/disabling far easier.

It makes life far easier when you see people post useful snippets(like wolfgang42's), but don't want to have to mangle them in to your already messy monolithic function.

¹ https://zsh.sourceforge.io/Doc/Release/Functions.html#Hook-F...

² https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

JNRowe··on Par: Paragraph reformatter, vaguely similar to fmt, but better
I've been using par for about twenty years, and 100% agree with its own apology: "Its only redeeming features are that it is extremely useful".

I literally have no clue what my $PAR* vars do, or what the odious string in my mutt config does. However, it works perfectly so I simply trust I won't have to figure it out again.

--

Oh, and check out his X-Advice¹ doc. It was a really great idea that sadly never caught on. Scanning a years worth of my own mail to write this comment tells me it is just me and one friend who use it, and only for "should read whenever" for messages between eachother :/

¹ http://www.nicemice.net/amc/advice-header/

JNRowe··on SymbOS Z80 multitasking operating system
What a time to be alive, 1980s pdf at your fingertip¹. The tool is described on page 84 of the linked doc.

¹ https://ia903206.us.archive.org/19/items/Your_Sinclair_003/Y...

JNRowe··on Rough.js: Create graphics with a hand-drawn, sketchy, appearance
I enjoy the general effect, but on your site the highlights are redefined as elements take focus which causes a bunch of off-putting flickering for me as I find the article I want to read. Perhaps, it is intended behaviour but I figured I'd report it in case it is not. (chrome/linux)
JNRowe··on Bit banging a 3.5" floppy drive
Thanks to the pluggable device layer, you could push that to 984kB or 1968kB with diskspare¹. The incredible thing, IMO, is that the implementation is only 5kB(seven times smaller than the formatted English docs).

¹ https://aminet.net/package/disk/misc/Diskspr3

JNRowe··on Let it snow in your terminal
[Because linking to cool zsh features seems to be a hobby of mine…]

If you're using zsh for this you can access terminfo directly¹, instead of hardcoding escapes(for example, "echoti cup $snowflakes[$i] $i"²) or shelling out to tput. You can also use zselect to replace sleep. Extra points for "echoti smcup" to use the secondary screen when available, instead of wiping the screen.

¹ https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#The-...

² To be fair it would need a minor change to array structure, as cup is zero-indexed.

³ https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#The-...

JNRowe··on Show HN: Spiderdash
I h a t e y o u s o m u c h r i g h t n o w.

Those leaves. I'm going outside to kick some nature, that'll teach it!

--

This feels like such a clever and sneaky improvement over the classic jezzball mechanic¹. It captures that "I can just make it"-aspect perfectly, and has an incredible level of polish.

It all feels perfect, standup75.

¹ https://mattdm.org/icebreaker/ - a nice clone available in Debian repos and elsewhere

JNRowe··on Philosophy of Biff
You can still relive a little of that joy with b1ff from talkfilters¹, with the caveat that a chunk of that package probably deserves a content warning for our times.

¹ https://github.com/hyperrealm/talkfilters

JNRowe··on Cdpath: Easily Navigate Directories in the Terminal
The article spends a little time talking about the drawbacks of using CDPATH because it will break scripts, but the better answer is simply not to export it. CDPATH is a shell variable, not an environment variable, and should be treated that way.

Simply use "CDPATH=here:there" without the export, get the same functionality and no additional breakage.

Plus, on zsh you can use the tied variable cdpath instead of CDPATH(see typeset -T¹). cdpath is an array that accepts all the regular array operations. For bonus points you can even declare it with -U to remove the need to consider duplicates in your config. Other common -- and useful -- tied variables include path/PATH and fpath/FPATH².

¹ https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Command...

² https://zsh.sourceforge.io/Doc/Release/Parameters.html#Param...

JNRowe··on Skyfield: Elegant Astronomy for Python
It is from the same author. He semi-retired pyephem with the release of this project¹: "The Skyfield astronomy library should be preferred over PyEphem for new projects. Its modern design encourages better Python code, and uses NumPy to accelerate its calculations."

I switched a few toys I'd written from pyephem to skyfield, and it felt like a large improvement. (Must note that they really were toys though, so the amount of work wasn't huge in my case).

¹ https://rhodesmill.org/pyephem/

JNRowe··on Turbo Pascal Turns 40
I was about to say there are a good few tools smaller than that on my system, but I was one hundred percent wrong.

    # zsh glob for regular files that are smaller
    print -l /usr/bin/*(.L-39731)  # Some ~500 results
    # Not interpreted or using system libraries
    file /usr/bin/*(.L-39731) | egrep -v '(script|dynamically)'  # 0 results
Turns out there are only smaller things if you accept big caveats.
JNRowe··on Fish – Update on the Rust port
Any reason to eschew short_loops in general that you're aware of? I ask because I'd probably use `for i ({0..9}) echo $i` in your for loop example. I've never managed to get my head around the necessity for a narrow short_repeat option when there is - for example - no short_select.

All of the zsh alternate forms feel far superior to me, in both interactive use and within scripts.

JNRowe notes the many off-by-one translations in other examples and tips hat to arp242

JNRowe··on The Five Meanings Of #. And What Does ${####} Mean?
There is a mid-level way to "fix" this under zsh, as it supports nesting parameter expressions¹. You can, for example, use ${#${#}} to disambiguate ${##}. It doesn't remedy any of overloading described in the article, but it does at least make it possible to understand the implied meaning(rainbow highlighting for brackets probably helps here too).

For the most part I'd prefer the syntax suggested in the posted document, but I'm pointing this out as it can be useful as a way to apply arbitrary zsh flags to simple strings to remove the need for external tools like sed(fex, ${(flags)${:-test}:flags}).

Final odd trivia note, you can make the syntax even worse with zsh as # is also an expansion flag when surrounded by braces. ${(#)#:-0x23} is valid -- and woefully unreadable -- syntax to count the length of the "#" string.

¹ https://zsh.sourceforge.io/Doc/Release/Expansion.html#Rules

← PreviousPage 3 of 21Next →