Chrome omnibox keyword search broken

Update 2021-02-24: The Chrome developers have rolled back the change.

The latest stable Chrome (released February 4), breaks the way keywords can be used to invoke search engines from the omnibox (address bar). TLDR: typing space after the keyword no longer works, but tab does. Disabling the omnibox-keyword-search-button flag will revert to the old behaviour.

Prior to the upgrade I could type g foo directly in the omnibox, hit enter, and get Google search results for “foo”. After typing the space after the “g”, the keyword gets expanded to “Search Google” or similar, so in the case of “g foo”, you actually see something like “Search Google | foo”.

screenshot of omnibox with "g " expanded to "Search Google |"

This works because I configured Google search to use the “g” keyword, from the chrome://settings/searchEngines settings page, as documented by Google.

screenshot of Chrome search engine settings with Google using the "g" keyword

However, this stopped working in Chrome 88.0.4324.150. Instead of “g foo” invoking the search engine I’d configured with keyword “g”, it invoked the default search engine with the query “g foo”! This was extremely disconcerting since I’m very accustomed to using keyword prefixes to search different websites.

However, you can still get at the keyword search functionality by hitting tab after the keyword rather than space. So in the previous example, typing gtabfoo will search for “foo”. The tab key doesn’t work quite the same way that space used to: it moves focus to a button in the autocomplete list for the keyword search, but merely having focus is enough to activate the search when you continue typing.

screenshot of the "Search Google" button focused in the omnibox autocomplete list

The Chrome search engine shortcuts no longer auto-fill with space bug on the Chromium tracker explains that this is due to the new button, and that you can get space working again by opening the chrome://flags/#omnibox-keyword-search-button settings and disabling the omnibox-keyword-search-button flag.

Machine learning for climbing grades

Conventional assessment of route difficulty for rock climbing is a subjective process. A small number of people (often just one) assign a grade for a particular route, and there isn’t really a process for refining grades once they’ve been assigned (it’s just one opinion vs another). Most of the grading systems are on an ordinal scale, which means you can rank the grades in order but the difference or ratio between grades isn’t meaningful. Intentional biases are even part of climbing culture.

To address these shortcomings, I developed a statistical model for grading rock climbing routes. The difficulty of a climbing route and the performance of a climber on a particular day are described by numerical ratings. The difference in ratings between a climber and a route determines the probability the climber will ascend the route “successfully”. For modern sport climbing, success loosely means getting to the top without weighting a rope or other mechanical devices. The climbing model is based on a dynamic Bradley-Terry model, which is a common model for game and sports rating systems such as Elo and Glicko-2.

While the statistical model provides a theory for predicting ascent outcomes based on ratings parameters, it’s not useful in practice without a process for estimating the parameters (individual ratings for climbers and routes) and hyperparameters (generalizations that are independent of individual climbers or routes, e.g. how hard the “average” route is, and how quickly climbers can improve). So I implemented an algorithm for estimating the parameters, based on the Whole-History Rating (WHR) algorithm. WHR is a fast algorithm that uses second-order (Newton-Raphson) optimization for finding the ratings for climbers and routes that maximize the likelihood of observing a particular set of ascents (known as the maximum a posteriori estimates). I used machine learning methods to choose the hyperparameters. The implementation is available as a free, open-source software package at the Climbing Ratings project on GitHub.

Continue reading “Machine learning for climbing grades”

Ergodox coding layer layout

I’ve previously written about the Ergodox EZ and the difficulty of where to place all those pesky right-pinky keys that don’t fit, and how to make those symbols (many of which are frequently used for coding) convenient to access.

Before jumping into my solution, let’s review other popular ideas:

  • ZSA’s default Ergodox layout has square brackets on the bottom row of the base layer, and various parens/brackets on the left middle and index columns on a “symbols” layer. The symbols layer is activated with the pinkies. = is in heaps of places: top-right of the base layer, and in layer 1 next to the layer 1 toggles.
  • BEAKL 15 places various bracket-like symbols on the AltGr layer, using the ring and index fingers of both hands. = is on the right middle finger, home row. The AltGr key is on the right thumb.

My solution is a coding layer:

diagram of right-hand key assignments on an ergodox keyboard

The left thumb’s space key acts as a layer modifier for the coding layer while held. The coding layer adds a shift modifier to all the numbers (except 9 and 0, which become square brackets instead of parentheses), and also changes the right hand to have the following layout (where ()=⏎ are the home positions):

&*[]⌫
0{}\/
()=⏎-
!":>+

I think this works better for modern programming languages (C, C++, Java, Javascript, Python, Ruby, Swift) than the ZSA and BEAKL layouts. It optimizes frequent bigrams and trigrams by making them rollable without releasing the layer modifier. For example, ␣{⏎ is a single-direction roll, as are ():⏎ (think Python!), ␣=> (think Javascript arrow functions), ({, }), )⏎ and }⏎. The frequent trigram ␣=␣, while not a continuous roll, is all on home-positions. The layout also complements Dvorak’s left hand symbols: );⏎ can be timed as one stroke.

Subtly, these placements are meant to feel familiar to Dvorak users. I have short pinkies, so I type [0] on Dvorak by moving my whole hand slightly then hitting middle-index-ring with a single stroke; the same can be done with this layout. Similarly, I hit = on Dvorak with my ring finger; it’s still the same finger, but the home-row placement reflects the high frequency of “ = ” in code. Having \ and on the right pinky should also feel very familiar.

I think the layer modifier is also better placed (on the thumb rather than the pinkies) compared to ZSA’s layouts. This leaves all the other left hand fingers in relatively comfortable positions, and space is already covered by the right thumb. I take advantage of this by using the left-hand home positions for modifier keys.

diagram showing an ergodox keyboard layout for the left hand

Of course, my typing preferences aren’t the same as everyone else. This layout is certainly not “balanced” (it’s biased to typing characters with the right hand), and it really emphasizes the efficiency of strokes and rolls rather than penalizing finger movement. It doesn’t perform amazingly with conventional BEAKL penalties.

You can check out my QMK branch from github for the source code, or download the compiled firmware directly (it’s Oryx-compatible!).

Edit 2020-10-28: this is actually v2 of the coding layer, this post previously described a slightly different layout.