Thursday, October 27

This one has always meant a lot to me.

p1k3 / 2016 / 10 / 27

Tuesday, October 25

I’ve been getting back into the exciting world of desktop Linux cat vacuuming yak shaving lately. (I never completely leave, but I guess the intensity of my presence varies.)

I’m not exactly sure when I crossed this threshold, but a while back I became the sort of person who cultivates dotfiles in earnest. I suppose what it amounts to is that I’ve been using a lot of the same software for years (and maybe decades by now). The customizations pile up.

I used to flit around all over the place, soaking up the novelty and variation, fascinated by all sorts of weird little evolutionary niches in interface and capability. I used to jump between DOS and Windows and Debian and Actual Antiquated Unix and Apple’s System (7|8|9) and whatever whacky demo you could boot off a floppy. The thing I miss most about old-school Debian is how there was just a menu for switching to a different window manager mid-session, which for some reason I spent hours doing.

Now: the first mention of XMonad on this blog is 2009; Vim is 1999. I’ve probably been on IRC for the majority of the time since 1996. If my software habits were human, some of them could be voting against Donald Trump in a presidential election.

Anyway, in keeping with all those yak clippings and my recent fixation on note-taking, I started a tiny project this evening: commandlog will be a handful of tools for accumulating command-line history with context, grouping them, and making notes about them. My hope is that eventually I can turn all my haphazard, undocumented shell time into a cumulative, re-usable log of different tasks and techniques. It seems to me like there should be a natural flow from doing some set of operations in the shell to building a reusable script.

My first couple of gestures at this were a lot simpler: I set the length of shell history to something ridiculously long, and added a comment command that was just a no-op for sticking things in history, so I could say:

$ frobnicate /dev/intangentializer
$ man frobnicate
$ apropos frobnicate
$ man frob
$ frob -i /dev/intangentializer
$ comment "trying to figure out frobnication of external devices"

…and then later grep for that sort of thing. (It is probably worth noting that these are made up commands.) It works ok as far as it goes, but it’s often lacking the context you’d want. (I can’t for the life of me remember why I didn’t just use # for comments, but I feel like there was some reason.)

commandlog is a touch heavier: It drops the command, along with context data like working directory, host, user, time, and current shell, into an SQLite database.

It probably isn’t ready for general use yet, but it won’t take much to get it there. I think the interesting pieces will probably come from search, grouping or tagging commands, and a notes system.

tags: topics/commandlog, topics/debian, topics/linux, topics/notes, topics/perl, topics/technical, topics/warelogging, topics/xmonad

p1k3 / 2016 / 10 / 25

Saturday, October 22


(photos redacted)

It’s hot and windy. 80-something in the sun, at least. It is not a perfect day for a bike ride, but it will work, and I haven’t ridden anywhere in months, so I become determined. Lacking any special destination, I head for Hygiene.

There’s a stand selling honey at the turn onto 75th, so I buy some. I’ve been thinking about the idea that eating locally-produced honey will somehow innoculate you against allergens. It’s probably nonsense, but it’s the kind of folk-medicine thing you hear from people for long enough and it starts to sound plausible. It’s probably worth a try.

I sit around with the locals at the farm (it’s an ever-rotating cast) and talk nonsense over a joint and a pickle jar full of water, buy a deli sandwich at the market by the intersection, and head west on Hygiene Road with a stop along the way for more bullshitting.


If you ever want a good sense of how people driving cars feel about sharing road space with bikes, Hygiene Rd is a useful exercise. With the exception of a few bridges and pullouts, there’s no paved shoulder — just a white line where pavement turns into dirt and goathead thorns.

I learn over and over that the safest thing to do on roads like this one is usually to take and hold the unambiguous center of the lane, which seems to force some mental switch for drivers that gets them to cross the line and take the other lane. Or maybe even wait to pass if there’s oncoming traffic.

I waver, though — the other thing that taking the lane does is make people angry. Honking, yelling out windows. Every time I do it, I remember the drivers I ride with (usually good people, my friends, etc.) who will gesture extravagantly and yell “GET OFF THE ROAD” in situations where the rules of the road clearly allow (or require!) bikers to be where they are. There’s a psychological tide pulling you ever closer to hugging the edge. You get to feeling that maybe meek conformity to expected norms will keep you alive longer than asserting your presence. Or you feel that way until a couple tons of metal tear past at 50 or 60 mph a few inches off your left elbow.

A home truth about cycling in America is that, whatever the statistics are on fatalities per passenger mile traveled, it’s pretty dangerous to bike on a large subset of roads. I suppose conformity to expected norms by way of not being on a bike is the major outcome of realizing that, for most people.


I don’t mean to get all adversarial about this, as hostile as things sometimes get in practice. I drive a lot on roads that are popular with the local road bike community, and I live in fear of the day I see somebody die because he (it’s just about always he) decides it’s well within his rights to ride three abreast out into the lane on a curvy, 60mph two lane highway full of tourist drivers already overwhelmed by the presence of mountains. Some of the standard-issue bike pieties wear kind of thin after a while, right along with some of the standard-issue bike behaviors.

Maybe there’s just a big experiential impedance mismatch between big metal boxes that feel slow at 40 miles an hour and skinny little metal frames that feel fast at 25. It’s probably best to remember that, however things should be, there’s an actual, material conflict of interests and modalities between different classes of vehicle. I piss off the drivers because I’m in their way. The drivers piss me off because there’s a decent chance they’ll kill me. So it goes.


All the same: Riding bikes is one of the better things.

tags: topics/bikes, topics/gallery

p1k3 / 2016 / 10 / 22

thursday, october 20

                         the data is   a program the program is a machine
         is a program the program is   a machine                   the data
   machine                       the   data is a program the program is a
   machine                  the data   is a program the program is a
       data is a program the program   is a machine                     the
       is a program the program is a   machine                     the data
                       the data is a   program the program is a machine
           the data is a program the   program is a machine
   is a machine                        the data is a program the program
               the data is a program   the program is a machine

(courtesy ptx(1))

p1k3 / 2016 / 10 / 20

wednesday, october 19

the data is a program
the program is a machine

p1k3 / 2016 / 10 / 19

monday, october 17

(nobody wants another meditation on mortality
some days it's just hard to write any other thing

nobody wants to rake the leaves, most of the
time, but they keep falling)

i was carefully arranging textfiles
and stacks of paper the other day
and i got to wondering
what am i doing this for?
what posterity etc. is waiting this
particular, deliberate tedium?

i got to thinking just now about
my great-grandfather keeping a journal
of his travels northwest of kansas,
some several lifetimes before i was born

in an age when i suppose half the
dying shape of the older continent
before what his people made of it
was yet within living memory

his journal's in my closet, in a box,
inside a plastic bag
i've thought now of transcribing it
for something like half my life

it wouldn't come to many words, or
i suppose convey much new information, but
i may yet put on cotton gloves and carefully
photograph those brittle pages

(there is probaby no true reckoning with the past, if we
are honest; no logic that can operate over the
accumulated data and balance the losses half-traced therein)

tags: topics/kansas, topics/poem

p1k3 / 2016 / 10 / 17

Sunday, October 16

finding an obscure vim plugin bug

I filed this against vim-fugitive a bit over a month ago and just remembered it: Autocommands do not fire for files named index:

I have an autocommand to do some stuff. I noticed that it fails on files named index, I think because fugitive.vim has its own autocommand for index{,.lock} that triggers BufReadIndex(), which in turn does something to prevent further processing of the event. I’m kind of hazy on how.

Tracking this down to its source was tricky, and I feel like I should document a couple of the small things I learned in the process.

For background, this is from the Vim help for :autocommand:

:au[tocmd] [group] {event} {pat} [nested] {cmd}
        Add {cmd} to the list of commands that Vim will
        execute automatically on {event} for a file matching
        {pat} |autocmd-patterns|.
        Vim always adds the {cmd} after existing autocommands,
        so that the autocommands execute in the order in which
        they were given.  See |autocmd-nested| for [nested].

The {event} is something like BufNewFile, which triggers when a buffer is opened with a new file. There are a bunch of these. I was trying to get something like the following autocommand to fire:

" this calls a function to treat blog entries as markdown
au BufReadPost,BufNewFile */p1k3/*[0123456789]* call BPB_PikeHighlight()

…and I couldn’t understand why the pattern */p1k3/*[0123456789]* wasn’t matching on a path like /home/brennen/p1k3/archives/2016/10/16/index, even though it worked for other files in that tree.

At first I thought something was wrong with the pattern, so I rewrote the function called by the command to this:

au BufReadPost,BufNewFile * call BPB_FiletypeOverrides()

" set custom filetypes for some things
function! BPB_FiletypeOverrides()
  " make sure NERDTree windows don't get messed up
  if bufname("%") =~ "NERD_tree"

  echom 'testing for p1k3 match'

  " using expand('%:p') instead of bufname("%") for full path, per:
  " the initial slash in the regex seems to be necessary to make \v work
  if expand('%:p') =~ "\\vp1k3\/archives.*([0-9]|[a-z])+$"
    echom 'p1k3 match - setting filetype to markdown'
    set filetype=markdown

That didn’t get any results, but since the echom debug messages didn’t trigger at all, it finally dawned on me that the autocommand wasn’t firing regardless of pattern. Then I got to thinking about how index is a special filename for things besides my blog. Git, for example.

In order to confirm my new suspicions, I wanted to see if some plugin was registering an autocommand that might be overriding mine. You can use :autocmd to list the existing ones. It gives many pages of output like this:

--- Auto-Commands ---
fugitive_status  BufDelete
    term://*  call fugitive#reload_status()
fugitive_commit  BufDelete
              execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE')
filetypedetect  BufEnter
    *.xpm     if getline(1) =~ "XPM2" |   setf xpm2 | else |   setf xpm | endif
    *.xpm2    setf xpm2

Since this was stupidly long and hard to jump around in, I went looking for a way to capture the output of a command. This actually turns out to be pretty easy:

:redir @a
:redir END

This puts the output of :autocmd into the register a, which can then be pasted into a buffer by typing "ap.

Sure enough, buried in there is this:

fugitive_files  BufReadCmd
              if fugitive#is_git_dir(expand('<amatch>:p:h')) |   exe s:BufReadIndex() | elseif filereadable(expand('<amatch>')) |   read <amatch> |   1delete | endif

I stopped there and filed a bug report, since it’s a trivial bug and it had already cost me more time than the thing I was trying to fix is likely to save me in a lifetime, but maybe one of these days I’ll get around to figuring out what is actually happening and write a patch.

As a final meta-level thought on this: I’ve invested an embarrassing amount of time in configuring my text editor over the years, but it’s only recently that I’ve hit the point where most of my deliberate changes to this setup land me firmly in the Turing tar-pit.

Perhaps not coincidentally, this is right about where I realize that shifting my preferences to another editor would be a matter not just of relearning interface elements, but of porting a small but growing body of somewhat tricky code. Every change increases the incentive to make future changes to the existing environment instead of paying the cost of switching environments.

Path dependence explains a lot of things in life.

It also remains true that Vim is an astonishing achievement, both powerful and feature rich in ways that most systems rarely attain. One might wish for an underlying syntactic and conceptual simplicity, for a language composable and manipulable without an entire vocabulary of dirty hacks — but one isn’t exactly surprised by reality.

Addendum: It turns out this is not the first time I have learned the :redir trick.

A further addendum, February 2019: I eventually revisited this and discovered that it’s a product of the BufReadCmd blocking further autocommands altogether. After some back and forth with Tim Pope about this and a related bug, I eventually got a fix merged.

tags: topics/technical

p1k3 / 2016 / 10 / 16

Friday, October 14

It’s the middle of the night, and I should be sleeping. Because I had a run in with a plate of Oskar Blues chicken enchiladas and one to four pilsners (who’s counting, really?), I am not.

In between festivals, weddings, and conferences, I’ve been thinking about a project.

Back in 2013, I started writing userland: a book about the command line for humans. It’s not really finished,1 but I got it to a readable state in the fall of 2014, right about when the main project in my life was coming apart at the seams.2

After I left SparkFun, userland set a tone for the next couple years in my working life. Or at least after that, I started to get paid for technical writing, and wound up with a full-time job writing sysadmin docs.

It wasn’t the way I’d imagined being a writer when I was young, but I could still say with a straight face that I was a professional. And with it, I learned that I could in fact stare down a blank editor window and make functional text happen, even on topics that held little personal interest. (More people read my disposable, obsolete-at-publication tutorial on hosting an ill-advised mobile app framework in a single week than will ever read any of my poems.)

And then somewhere in there I burned out pretty hard. In fact, although I can handle the mechanics of writing, I am terrible at life as a content monkey. Unable to farm clicks with the necessary ruthlessness and keep any peace of mind.

It’s not that “content marketing” is automatically a degrading way to sell things. In fact it might be one of the more honest propositions in the business, at least when what you mean by it is “documentation on how to use useful things”. It’s just that the idea of “content” as a kind of generic liquid substance remains grotesque and distorting, and despite the baseline assumptions of marketing culture, it continues to matter what you sell.

When I quit writing for DigitalOcean, I started thinking about writing for my own reasons, and about how I could take that seriously as a practical task. Since then I’ve been hovering around a set of ideas that seem to have accumulated, pecking at them here and there, working up to that moment when the engine might turn over again:

  • Forget the contempt I held for highschool / college platitudes about notes: Notes are essential to so much code, systems, prose.
  • I’ve been taking notes since some time in the late 90s. They’re just scattered, unindexed, unsorted.
  • What if I had random access into my life’s entire catalog of meta-memory?
  • Why don’t I keep a database?
  • In an age of ever-more-thoroughgoing surveillance, why can’t I ask basic questions about my own life and experiences in a rigorous way? Why does the panopticon’s model of my existence seem more developed than my own?
  • Why does so much of my history on the command-line go unrecorded, un-annotated, un-repeatable past the narrow time horizons of my working memory?
  • Why don’t I publish photos any more?
  • Some of the tools I use are pretty good. Others would be pretty good if I was tough-minded and serious about developing the underlying ideas.
  • If I spend so much time customizing my computer environment, why aren’t my tools better?

I know that I want to write something like a book, but these aren’t exactly the topics I want to write it about. It’s more that I intend to use them as a way to discover the book I do want to write, or the thing that isn’t quite a book but will satisfy the same basic impulse.

1 Being a sketchy outline of the book it ought to be, and having emerged from a moment when a kind of optimism about computing seemed to me, somehow, appropriate and sustainable.

2 It had a little help.

tags: topics/cli, topics/databases, topics/digitalocean, topics/notes, topics/sparkfun, topics/userland, topics/writing

p1k3 / 2016 / 10 / 14