hlfw.ca

hlfw

Download patch

ref: e188b1827ba0fe8e639e340a84c1ab006c612253
parent: 901006d1e7695d182eea1c470c1a4bbe810afc19
author: Michael Misch <michaelmisch1985@gmail.com>
date: Sat Aug 24 03:31:53 PDT 2024

Add new blog post

--- /dev/null
+++ b/blog/2024-08-24-more-setup.md
@@ -1,0 +1,163 @@
+I feel like I am ready to go to task on 9front in earnest, as pieces are slowly moving in to place. In my [last setup post](https://hlfw.ca/blog/2023-07-26-setup.md) I started to really dial in on a key tenet of "flow" that I was after.  Walking up to a machine, entering some command, and having that system configure itself for me to do that thing, automatically. So what does that look like? Walk up, type `do math`. You probably want a notepad of some form, a calculator, and ~ChatGPT covering most of the window~a reference open if you are not particularily fluent in the type of math you are currently working on.
+
+I don't do much math. Or maths, if ya nasty. But I do hit a spark of inspiration, insight, or intrigue and fall into a state of, "I need to do this or that to project foo", constantly. I'll think of a fix for a bug, or a way to do something that I haven't ironed out yet. If it starts with an "i" and it hits, I want to be ready to go, while the iron is hot. 
+
+## 9fs
+
+So a really nice command is 9fs, it pulls in a remote file share and does some convenience wrapping to behave idempotently under different constraints in some cases, such as `9fs 9fat`. Now, there's no reason you couldn't create your own `9fs`.
+
+	#!/bin/rc
+	
+	# Your logic here, be sure to exit after
+	rfork e
+	switch($1){
+	case foo
+		[...]
+		exit
+	}
+	
+	# If we don't match anything, fall back to the system script
+	/rc/bin/9fs $*
+
+## Namespaces
+
+Truly the powerhouse on 9front, when combined with the network transparency behind 9p, namespaces allow the construction of very dynamic workflows without the need for special insight in the tooling. As a small, well worn example, pulling in the `/net` of a remote system creates an ersatz VPN between your client machine and the remote system. Perhaps more interesting to me, however, is that I can `bind`, `mount`, and `srv` a given namespace to put files right where scripts expect them to be. A naive example could be as follows:
+
+	# on a remote machine
+	srv tcp!filey!564 project
+	mount /srv/project /mnt/project /path/to/project
+	acme /mnt/project
+	
+	# on a local machine
+	bind -c /path/to/project /mnt/project
+	acme /mnt/project
+
+## Please Stifle Your Yawns In The Traditional, Victorian Style
+
+Now, this does effectively nothing. If we have a shared fs root, we don't need the binds at all, we can just run `acme` over the dir. But, when we start writing custom `9fs` commands, we can have that set `/mnt` for us. And use the project name to automate what, where, why, and how, we can get *fancy* with it if we ever wanted. Like binding together your code and other resources into one namespace at `/mnt/project`, so it's all in one convenient space. This is useful when you share resources across projects, for example.
+
+	# on a remote machine
+	srv tcp!filey!564 project
+	srv tcp!filey!564 resources
+	mount /srv/project /mnt/project
+	mount /srv/resources /mnt/resources
+	bind -a /mnt/resources /mnt/project
+
+	# on a local machine
+	bind -a /path/to/resources /path/to/project
+	bind /path/to/project /mnt/project
+
+This sort of gets me where I want to be. `9fs project`, for my purposes puts the files right where I need them. It is an aesthetic touch, but it does actually flow cleanly.
+
+	#!/bin/rc
+	
+	rfork e
+	
+	if(test -d /mnt/work -a -s /mnt/work)
+		unmount /mnt/work
+	
+	switch($1){
+	case altid
+		# Assumes a docs/ in alt, and a shared fs root
+		bind $home/src/alt /mnt/work
+		bind -a $home/docs/go /mnt/work/docs
+	case rc
+		bind $home/bin/rc /mnt/work
+	case drawcpu
+		# Assumes a docs/ in drawcpu, and a shared fs root
+		bind $home/src/drawcpu /mnt/work
+		bind -a $home/docs/kernel /mnt/work/docs
+		bind -a $home/docs/devdraw /mnt/work/docs
+	[...]
+	}
+	
+	# Exit if we've successfully mounted
+	if(ns | grep /mnt/work > /dev/null)
+		exit
+	
+	/rc/bin/9fs $*
+
+## Taking This Further
+
+There's rumblings about a coming file server that will enable tags for files, which plays right into this very cleanly. It's supposed to create a flat directory of files matching a tag query, which does mess with the hierarchy for the source code, which can benefit from directory structure - but for resources, and auxilliary data of any type it's actually quite perfect. Assuming you can tag a file with multiple tags, one could take the above, and only have to do a query for documents matching `drawcpu`. That would be deeply helpful to broadening the utility of this approach.
+
+Aside from the /mnt/work becoming your thrown-together workspace, we also have work*spaces* thanks to `riow`, and friends. You could have a script that tidily orchestrates putting things where you would want them for a project, leveraging your established namespaces via acme, mothra, a file explorer if you desire. I mosty use Sam for my editing, so for me having everything in `/mnt/work` has an interesting benefit using [phil9's fm](https://shithub.us/phil9/fm/HEAD/info.html) This allows me to fuzzy search for anything in that directory. It works *really* well with how I manage context switching, flow, just how my brain works.
+
+	#!/bin/rc
+	# Quickly search and open a project file
+	
+	walk /mnt/work | fm -p | plumb -i
+
+But it has a _fatal flaw_, in that even if the plumber runs inside of the namespace, the listening program likely is not inside of the namespace.
+
+## Escaping The Namespace
+
+Now, to make that generally useful it would be nice to be able to run that *generally* with what is in `/mnt/work`. It's not very likely I will be working with multiple projects in multiple namespces, so it's safe to post my `/mnt/work` to `/srv`. For this, we can use `srvfs`, and make our 9fs script a little bit neater.
+
+	#!/bin/rc
+	
+	rfork e
+	
+	if(test -d /mnt/work -a -s /mnt/work)
+		unmount /mnt/work
+	if(test -f /srv/work)
+		rm /srv/work
+
+	switch($1){
+	case altid
+		# Assumes a docs/ in alt, and a shared fs root
+		bind $home/src/alt /mnt/work
+		bind -a $home/docs/go /mnt/work/docs
+	case rc
+		bind $home/bin/rc /mnt/work
+	case drawcpu
+		# Assumes a docs/ in drawcpu, and a shared fs root
+		bind $home/src/drawcpu /mnt/work
+		bind -a $home/docs/kernel /mnt/work/docs
+		bind -a $home/docs/devdraw /mnt/work/docs
+	[...]
+	}
+	
+	# Exit if we've successfully mounted
+	if(ns | grep /mnt/work > /dev/null){
+		# Assure our plumber is alive in this namespace
+		plumber -p $home/lib/plumb/main
+		srvfs work /mnt/work
+		exit
+	}
+	
+	/rc/bin/9fs $*
+	
+Now, when we target things with plumb rules, we can make the `plumb	start	foo` command, run a variant that sets up our namespace if our `/srv/work` exists like the following:
+
+
+	#!/bin/rc
+	
+	# plumb start nssam
+	if(test -f /srv/work)
+		mount /srv/work /mnt/work
+	
+	exec /bin/sam $*
+
+This leaves our open script looking like the following:
+
+	#!/bin/rc
+	
+	# Don't do this if it already exists
+	if (ns | grep /mnt/work >/dev/null){}
+	if not {
+		mount /srv/work /mnt/work
+		# Start a plumber associated with this namespace,
+		plumber -p $home/lib/plumb/main
+	}
+	
+	res=`{walk -f /mnt/work | fm -p}
+	if(! ~ $#res 0)
+		plumb $res
+	
+	# If you are running this from riow hotkeys, it won't close itself
+	echo delete > /mnt/wsys/wctl
+
+## In Closing
+
+It's not ideal to have to have custom scripts inside your plumbing, but this is a decent compromise. `9fs rc` gets me my namespace, and then `open` gets me coding. I use a global menu with a patched `riow` so that I can open some programs from anywhere I want, so I could in theory try to wire `9fs rc` and `open` into that, which shifts the context of my whole session instead of just my open window. (I just tried it, it works pretty well! I probably will patch `riow` to run my `open` command on hotkey)