brhfl.com

decolletage.vim

The ‘screenshots’ in this post are just styled code blocks. There are likely some weird visual artifacts (like background colors not extending the whole width of the block), but the point is to show off the colors.

I’ve been using a hastily-thrown-together color scheme for vim, cleverly named ‘bcustom.vim’ for years now. It’s a dark scheme, peppered heavily with syntax highlighting. While slightly softer than most, it’s still a pretty typical, masculine scheme. I recently realized two things – I would like to use a more feminine, light scheme based on my general sense of pinkness1, and I actually find myself a lot more distracted by extensive syntax highlighting than I find myself aided by it. So I decided to start from the ground up, and build a minimalist, light pink colorscheme, ‘decolletage.vim’.

Again, part of the design decision was to keep the total number of colors used to a minimum. So, to start, here’s the basic scheme. You can see the line numbers, the basic scheme, a comment, an uncapitalized word (‘colors’), a misspelled word (‘matchTypo’), a fold, a search result (‘cterm’), an error (‘#123456’), a visual selection (‘Decolletage’), and matched parentheses:

193 194 195 “Adjust things re: markdown. colors only matchTypo if decolletage loads 196 if g:colors_name==“decolletage” 197 +— 5 lines: hi! link markdownBlockQuote CursorColumn―――――――――――――――――――――― 198 199 hi markdownBlockQuote ctermfg=none ctermbg=#123456 200 call DecolletageDiff(1)

It… looks a lot like this blog, I know. That truly wasn’t how I set out to do things, it’s just my aesthetic. Let’s examine a little -- More --, like that right there, which is how the more/mode message lines appear. Or these status lines:

2:~/.vim/colors/decolletage.vim [RO] [vim][utf-8] 74,1 71% 2:~/.vim/colors/decolletage.vim [RO] [vim][utf-8] 74,1 71% 2:~/.vim/colors/decolletage.vim [RO] [vim][utf-8] 74,1 71%

…Active, inactive, and insert, in that order. Yes, it may be weird, but I like having a blunt, obvious indication of which mode I’m in. And I associate blue with insertion, so that’s my choice for insert. This was a feature of my hacked-together ‘bcustom.vim’ as well – it’s pretty nice to have.

There are two variants for diffs in decolletage.vim. One is more traditional, very obvious with highlighted backgrounds and the like; and the other is fittingly minimal. Here’s the standard version (you also get to see a split line here; it’s predictable) (oh, and non-printing characters):

1 if this { │ 1 if this { 2 that │ 2 that 3 → the other↲ ---------------------------------- 4 print “goodbye” │ 3 print “goodbye” 5 → return true↲ │ 4 → return false↲ 6 } │ 5 }

…and here’s the more jarring, less obviously-a-diff minimal version:

1 if this { │ 1 if this { 2 that │ 2 that 3 → the other↲ --------------------------------- 4 print “goodbye” │ 3 print “goodbye” 5 → return true↲ │ 4 → return false↲ 6 } │ 5 }

I’m fully on board with the minimal version, but it doesn’t seem right to have as a default, so it isn’t. Add call DecolletageDiff(1) to your .vimrc to use it. Alternatively, you can choose it as a default, and call DecolletageDiff(0) for filetypes that seem to desire a more blatant diff.

:set cursorline in decolletage.vim looks like this:

254 255 this is the line that the cursor is on _ 256

I’m not a huge fan of cursorline, but I do see value in being able to quickly find the current line, so for a more subtle cursorline, we can call DecolletageNecklace(0):

254 255 this is the line that the cursor is on _ 256

Finally, there is an option to actually add some syntax highlighting, via call DecolletageFreckles(1). It’s rudimentary so far, and based on the default colors that vim would use in a 16-color terminal.

317 Constant 318 Identifier 319 Statement 320 PreProc 321 Type 322 Special 323 Number 324 Boolean

…this probably needs tweaking, but it is there if you want it. And again, implementing it as a function call means you can pop it on and off at will as you’re flipping through a file. So, that should be adjusted, I’d like to add some color for netrw, and I need to implement it as GUI colors as well2. But, for the time being (and particularly for my own specific needs), decolletage.vim looks pretty good, and is available for preliminary testing here.


  1. This is my meatspace aesthetic as well, my work desk has several pink tablets and pens with deep purple ink. ↩︎
  2. With the prevalence of termguicolors, not sure why I didn’t just start with GUI colors scraped from the 256-color list, but here we are. ↩︎

Examining 'my .vimrc'

I realized the other day that, as much as I’ve read through the vim documentation and sought out solutions to specific problems, I’m still constantly learning things about it almost accidentally as I stumble across how person x or y approached some specific task. It occurred to me that a lot of people post their .vimrc files online1, and flipping through a bunch of these could prove insightful. So I googled ‘my vimrc,’ I searched github, I poked around… a lot. It’s worth noting that some of my observations here are biased in that my vim use is primarily prose (generally in markdown), followed by HTML/CSS/JS, followed by recreational code. I don’t deal in major coding projects consisting of tens of thousands of SLOC for production systems. What works for me is almost certainly atypical.

Something that I’ve been meaning to write about is my aversion to things that make any given setup of mine less portable – and that includes things like keyboard mappings that simply give me muscle memory that only works on my configuration. I see a lot of this sort of stuff in the .vimrc files of others, and for the most part it’s just stuff where I’d rather take the efficiency hit but know how to do it in a portable way. For example, a lot of people map something to the ‘oh shit I forgot to sudo vim’ sequence, !sudo tee % > /dev/null. I fully understand how that sequence works, but to me it’s such an oddball use of tee that I feel like if I got too accustomed to not typing it, I might accidentally do something really weird on a system that isn’t my own2. Similarly, I see a lot of mappings like Ctrlh to jump left a window instead of Ctrlwh. This sort of thing saves you one keystroke, while completely demolishing one of the key points of using vim – that of context and modality. Ctrlw means ‘get ready to do some stuff to some windows’, be it moving, resizing, closing, whatever. It’s not a ‘mode’, per se, but it fits vim’s modal model.

I know there’s a huge community of vim plugin development, but I was still a little surprised to see so much reliance on plugins (and plugin managers3). There are a few plugins that I consider rather essential, like surround.vim, but again I largely try to do things the native way when possible, so I try not to extend vim too heavily.

I don’t strictly adhere to the aforementioned policy, particularly for things that I know I won’t forget how to do in a portable way (like autocd in the shell), or things that are purely conveniences (like mapping CtrlL such that it works in insert mode). One clever idea that I saw along these lines was remapping Enter to clear the search highlight before doing its thing. Which, I don’t think I’ll adopt, but it is a handy idea – those highlights can get a little distracting.

I see a lot of mappings of j to gj which again just feels so un-vimlike. Up/down movements corresponding to screen lines instead of content lines is something that actually bugs me in other editors. Worse, this mapping makes counts tricky to use in a . or macro situation, which is particularly weird when a lot of the same people use :set relativenumber. Another common mapping is to do gv after > or <, so that you can repeatedly hit it and have the same visual block selected. But… the vim way would be to use a count instead of mashing the button four or five times.

People remap <Leader> to , a lot, which to me feels even more awkward than \. I’ve seen weird insert-mode mappings to jump back to normal mode, like jj, which is fair – Esc is kind of a ways away. But the real trick to that is twofold: first, remap your useless Caps Lock to Ctrl system-wide, and then train yourself to use Ctrl[ instead of Esc.

Doug Black’s post about his .vimrc has two good pieces of advice: don’t add things to your .vimrc that you don’t understand, and don’t use the abbreviated forms of settings/commands4. I see a lot of files that don’t seem to conform to this rather basic advice. Things like hardcoding t_Co without performing any checks – at best it’s merely not portable, but it reads like ‘a thing that I did that solved a problem’ vs. a setting that the user actually understands.

I did have some positive takeaways from this little journey. While I don’t use macros much (I opt for :normal more often), I learned about :set lazyredraw which speeds up macro execution by waiting until the end to redraw the screen. I had somehow forgotten that vim supports encryption, and that it defaults to the laughable pkzip scheme, so :set cryptmethod=blowfish2 is making its way into my .vimrc. Someone added syntax for two spaces after a period, which is a smart idea – I would link that right to Error. It would be better (perhaps) to add that as a wrong/bad spell, but I think a highlight would work.

Curious to me was the number of people who put things in their .vimrc files that are specific to filetypes (etc.). This is stuff that I generally relegate to .vim/ftplugin/ and .vim/ftdetect/. For instance, I have some folding rules in place for markdown files used in my blog. I add the filetype hugo with a ftdetect script, and then lay out some syntax rules in .vim/ftplugin/hugo_folds.vim. I don’t know if my approach is better or worse – it definitely makes for a big pile of files. Is this more or less organized than just maintaining it in a tidy .vimrc? Something to think about.

This adventure down the dotfile rabbit hole taught me more than anything, I suppose, about how other vim users twist vim’s arm to make it less vimlike. Interestingly, I ran into a couple of files that were updated over the years, and the users seemingly adapted to more vimmy ways. I suspect a lot of these things come of a sort of feedback loop – a vim beginner sees a .vimrc file online with map <C-K> <C-W>k and thinks ‘why not shave off a keystroke?!’ They end up posting their .vimrc file a year down the road when they feel they’ve perfected it, and another novice stumbles across it, thinking ‘why not shave off…’ Regardless, it’s pretty neat just how many .vimrc files are floating around there, given how customizable and extensible vim is. Even approaches that are totally opposite one’s own likely have something previously unknown or unthought of.


  1. In no order, a handful of the .vimrc files that I looked at: amix, JeffreyWay, Chris Yeh, sts10 and sts10, Doug Black, vinchi777, Jake Gordon, Jay Pipes, MisoF, Taylor Hornby, Janis Miezitis, abbood, Isaac Sloan, Steve Francia ↩︎
  2. I guess this is a pretty out-there hypothetical, a system in which I’m on the sudoers list but cannot or have not swapped in my own .vimrc. Still, I’d rather just know how to do this vs. mapping it to a single keystroke. It really shouldn’t come up often enough that such convenience is necessary anyway. ↩︎
  3. I really don’t understand vim plugin managers. You have to use way too many plugins for this to even approach necessity, and even then… When people distribute vim plugins, they lay everything out in the appropriate structure to just drop in your .vim/ folders. ↩︎
  4. The weirdest is when people do something like :set scs "smartcase. Just… use the descriptive name instead of using the short name and a descriptive comment? ↩︎

Reversing Markdown

Most writing that I do, I do in vim using Markdown. Either for applications that support it natively (like Hugo, which powers this blog), via pandoc, or directly into Word via Writage. Going from Markdown is never really a problem, but trying to convert from pretty much any format to Markdown is pretty much always frustrating.

The reason for this is baked into the format — the format is designed to be flexible. It’s designed to be human-readable, and therefore most structural elements can be reached via several paths. For example, italics can be reached either by _this_ or *this*, and bold is achieved via either __this__ or **this**1. This allows a variety of personal styles. Since _this_ is a universal fallback for communications that don’t afford italics2, that is how I always do italics. And, on the rare chance that I use bold, I do it **this way** to readily set it off from the italics formatting. Ultimately, there are four combinations here, though, and software that is rendering to Markdown has to make its own style choices.

There are other decisions. Markdown, for some ungodly reason, promotes hard-wrapping (which I loathe). Markdown supports two different sorts of headers, one of which I find aesthetically pleasing, and then Setext-style. But again, a renderer has to either support a ton of options or make these decisions for you. Writage, for example, makes pretty much every decision opposite how I’d like it. Which is ok, but it means I spend a lot of time in vim reprocessing things.

I’ve been considering writing about this for months now, mostly to complain about Writage. But, this isn’t Writage’s fault. And I’d hesitate to call it a fault at all, it’s just a tradeoff that comes with a flexible markup language. I don’t think I would have made a lot of the decisions that Gruber made in establishing this format… But those decisions have led to it being a de facto standard for human-readable markup. Rich text would be worse off had this gone any other way.


  1. Textile gets this right, and Markdown gets it wrong, full stop. Major style guides refer to underline as an alternative to italic, and _underscore surround_ as an alternative to underline. I love Markdown, but I firmly believe this was a deeply flawed decision. ↩︎
  2. Even this is a poor example — when going to HTML, is _this_ <i> or <em>? <em> is likely preferable, but from a human-readable markup standpoint, is the aim style or structure? How does one reference the title of a book if _this_ is <em>? Textile distinguishes these as well. ↩︎

The delusion of accessibility checkers

There is a delusion that I deal with, professionally, day in and day out. That nearly any piece of authoring software, be it Microsoft Word or Adobe Acrobat, has some inbuilt mechanism for assessing the accessibility of a document. Before I get into the details, let me just come out and say that if you are not already an accessibility professional, these tools cannot help you. I understand the motivation, but in my experience, these things do more harm than good. They allow unversed consumers to gain a false sense of understanding about the output of their product. That sounds incredibly condescending, but that’s honestly how it should work when you’re talking about fields that require extensive training.

The ultimate problem is that accessibility comes down to human decision. Accessible tech is, thus far, ‘dumb’ — it almost exclusively responds to cues embedded by a human. Some day, I believe that AI will be good enough to largely make the decisions that currently necessitate a human. But we aren’t there yet. A good analogy, but one that only gets through to a select group, is that of a compiler throwing warnings and errors. I can’t just type make me a roguelike but where all you do is find cute clothes in treasure chests into gcc and get my game to come out — the computer is not that smart. I could program dresscrawler myself, and attempt to compile it. gcc might throw errors — these are just things that make it incapable of compiling. gcc might throw warnings — these are just things that it thinks could be problematic, or are outside of accepted style. gcc can’t stop me from making dresscrawler a game where the player can spawn inside an inescapable room with no exits. gcc can’t guarantee I even remembered to code dresses into dresscrawler. gcc can’t even ensure that I didn’t create some kind of stack overflow that would cause a fatal exception when I place my jeggings of holding inside my purse of holding.

Perhaps a faultier, but more lay explanation would be that of purchasing a meal. If I go to a local restaurant, and I order a veggie burger, and it’s awful… I don’t actually know why. I might have a vague idea, that it’s too sweet, say. But why? Did they add too much beet? Did they sweeten it to make up for something else? With what? Sugar? Glucose syrup? Some bizarre synthetic? I don’t have all the information; I cannot make accurate conclusions. All I can make are vague suggestions, and this is how accessibility checkers (and compilers) work.

If I knew how to make the perfect veggie burger, I’d just do it myself. If the computer was smart enough, it would program dresscrawler for me (and, oh, how I wish it would). And if the computer was smart enough, none of what I do for a living would even exist! This is a human job because, for the time being at least, it requires human decision-making based on human experience. I am very engaged with the accessibility community, the disabled community, as far as current best practices. But these are still judgment calls. Some things are explicitly laid out — WCAG 2.0 put forward mathematically acceptable contrast levels, for example. But a lot of accessibility work still boils down to human decision-making, based on ‘how would I want to experience this, if I was experiencing it differently?’

Universal digital accessibility is incredibly difficult to do right1. But it’s so detached from the reality of most abled people, that they trust relatively naïve algorithms will absolve them. I’ve tried to get customers to use JAWS or NVDA just to experience the misery of a poorly-structured document, and… they often don’t even last long enough to care. I honestly wish vendors would stop bundling these half-baked accessibility checkers into their authoring software. Come see me once your approach involves neural networks.


  1. I’m always willing to help queer creators make their content accessible pro bono. Just FYI. ↩︎

A few of my favorite: Slide rules

I link to photos hosted by the International Slide Rule Museum, a really great resource. Unfortunately, they don’t set IDs on their pages for specific rules, but luckily I only discuss two brands: Pickett and Faber-Castell.

I love slide rules nearly as much as I love HP calculators, and much like HP calculators, I have a humble collection of slide rules that is largely complete. While I keep them around more as beautiful engineering artifacts than anything, I do actually use them as well. These are a few of my favorites, from both a conceptual standpoint and from actual use.

Pickett 115 Basic Math Rule
This is, by far, the simplest rule that I own. It lacks the K1 scale that even the cheap, student 160-ES/T2 has. Aside from the L scale, it is functionally equivalent to a TI-108. But, to be fair, the TI-108 has two functions that nearly all slide rules lack: addition and subtraction. And, true to the name ‘Basic Math Rule,’ the Pickett 115 has two linear scales, X and Y, for doing addition and subtraction. Additionally, it has one scale-worth of Pickett’s ‘Decimal Keeper’ function, which aids the user in keeping track of how many decimal places their result is. All in all, it’s not a particularly impressive rule, but it is quite unique. Faber-Castell made a version of the Castell-Mentor 52/80 (unfortunately ISRM’s photo is not that version) with linear scales as well, and I probably prefer it in practice to the 115. The 115 just has a wonderful sort of pure simplicity about it that I appreciate, however.
Pickett N200-ES Trig
This is basically the next step up from the aforementioned 160-ES/T. The 160-ES/T is a simplex with K, A, B, C, CI, D, and L scales. The N200-ES/T is a duplex model that adds trig functions with a single set of S and T scales, and an ST scale. It’s a wee little pocket thing, the same size as the 160-ES/T, and it’s made of aluminum as opposed to plastic. It’s nothing fancy, but it handles a very useful number of functions in a very small package. The N600-ES/T does even more, but it becomes a little cluttery compared to the N200-ES/T’s lower information density. Good for playing with numbers in bed.
Faber-Castell 2/83N Novo-Duplex
The 2/83N is, in my opinion, the ultimate slide rule. It has 31 scales, conveniently organized, and with explanations on the right-hand side. Its braces have rubberized strips on them, and are thick enough that the rule can be used while sitting on a table. The ends of the slide extend out past the ends of the stator so it’s always easy to manipulate (I don’t have any Keuffel & Esser rules on this list, but they had a clever design that combatted this problem as well, with the braces being more L-shaped than C-shaped). The range of C (and therefore everything else, but this is the easiest way to explain) goes beyond 1-10, starting at around 0.85 and ending around 11.5. The plastic operates incredibly smoothly (granted, I bought mine NOS from Faber’s German store a few years ago, that had to have helped), and the whole thing is just beautiful. Truly the grail slide rule.
Faber-Castell 62/83N Novo-Duplex
This feels like a complete cop-out, because it is essentially identical to the 2/83N, except smashed into half of the width. You lose the nice braces, you get a slightly less-fancy cursor, and you lose precision when you condense the same scale down to half-width. But you end up with something ridiculously dense in functionality for a small package. Even though it’s essentially the same rule as the 2/83N, I think it deserves its own place on this list.
Pickett 108-ES
This was the piece I’d been looking for to essentially wrap up my collection. It is a circular, or dial, slide rule, and it is tiny – 8cm in diameter. It’s much harder to come by than the larger circular Picketts, particularly the older 101-C. Circular rules have some distinct advantages – notably their compact size (the 108-ES is the only rule I own that I would truly call pocketable, and it cradles nicely in the palm of my hand), and the infinite nature of a circular slide. The latter advantage means there’s no point in adding folded scales, nor is there ever a need to back up and start from the other end of the slide because your result is off the edge.
The 108-ES, by my understanding, was a fairly late model, manufactured in Japan. It is mostly plastic, and incredibly smooth to operate – moreso than non-circular Picketts that I’ve used. The obverse has L, CI, and C on the slide; D, A, and K on the stator. The reverse has no slide, and has D, TS, three scales of T, and two of S. I can’t help but hear “I’m the operator / with my pocket calculator” in my mind when I play with this thing. It really packs a lot of punch for something so diminutive. The larger 111-ES, of the same sort of manufacture, is also quite impressive with (among other things) the addition of log-log scales.


  1. If you’ve never used a slide rule before, the names of the scales won’t mean much. I’d suggest reading the ISRM’s Course on How to Use the Slide Rule and their Glossary for a full description of scales, but here are some basics: C and D are logarithmic scales used for multiplication. CF and DF are the same, but they start further down the line to effectively make the slide ‘longer’. CI and DI are the reciprocals of C and D, you can probably guess what CIF and DIF are. A and B are squares of C and D, K is cube. S and T refer to Sin and Tan, ST is a combined sin/tan scale for numbers low enough that they’re effectively the same. L is a linear scale for reversing the log. LL scales are log-log scales used for arbitrary exponentiation. ↩︎
  2. Pickett released yellow and white slide rules, largely standardized by the model number ending in ‘ES’ for ‘Eye-Saver’ yellow, or ’T’ for white. ↩︎