Consult extension for searching on Hacker News
Alright, real talk time. Why are you here? Why do you need Hacker News in Emacs? What’s next, Tinder in Vim? Instagram in sed?
Listen, I get it - you’ve already got your email, calendar, therapist, and pizza delivery service running in Emacs. But at some point we need to draw the line.
Go outside! Touch grass! Read a book! Hug your loved ones - your partner, your kids, your dog, that suspicious potted plant that’s been eyeing you funny. Hell, go have a meaningful conversation with your toaster for all I care.
Please, for the love of Stallman’s beard, stop trying to consume the orange website from inside your text editor. Your productivity theatre has gone too far. The call is coming from inside the buffer!
(Who am I kidding, see you in the comments section in 5 minutes.)
Alright, alright, fine. So why does this package exist?
a) Because, why not?
b) I just needed to solve this weird itch for myself - very often I get a link to a blog post, a book or a video. And sometimes, I’m curious what HN comments say about that thing. Also, sometimes I’d like to find comments I posted myself long ago, just to get reassurance of how stupid I was back then and hopefully not getting any stupider now.
This is an Emacs extension that extends an extension. Because Emacs is extensible beyond imaginable limits, it allows you to extend what’s already been extended. So, in order to minimize confusion (or vice versa), we Emacsians do not call them “extensions”. We call them “packages”.
So, this is a package that packages some functionality for another (very popular and awesome) package called Consult. If you love Emacs, but not using Consult - stop hugging your toaster, close this page and go install it, asap!
This package searches through HN using public Algolia API.
You can install the package through your favorite Emacs package manager, it’s on MELPA, or you can recipe-it from GitHub directly, e.g., for Doom:
(package! hnreader :recipe (:host github :repo "agzam/consult-hn"))
Then you can just run (consult-hn-transient)
— UX-convenient option, or (more directly) — (consult-hn)
command.
Type a query and it will search for both comments and stories, by default sorting them with the latest first.
The format of the queries is the following: #SEARCH-TERM -- ADDITIONAL-PARAMETERS
Parameters and the search term are always separated by --
You can omit either parameters or the search-term. Parameters are key/value pairs of format: KEY=VALUE
You can use keys listed in the official API documentation
Here’s a YouTube video demoing it (7 minutes)
#Emacs
- will search for everything that contains “Emacs”
#Emacs -- tags=story
- articles with Emacs in the title
#"I hate Emacs" -- tags=comment
- comments matching the query
#-- tags=story,author_pg
- all the stories posted by Paul Graham
#-- tags=comment,author_pg
- all the comments of Paul Graham
#clojure -- restrictSearchableAttributes=url
- all stories containing matching URLs
Consult has narrowing feature, that’s why the prompt for consult-hn, typically starts with that hash-mark. So you can use it to narrow your results. e.g.
#Emacs#Vim
- finds everything on HN that contains “Emacs”, but then narrows the results to filter all the items that also contain Vim
#"I love Emacs" -- tags=comment #hate Vim
- fetch some comments and narrow
Once you find HN items you have multiple choices:
- preview (without closing the Consult buffer)
- browse (close the search buffer, open the item)
- push all the found items into Embark-Collect buffer. See Embark’s documentation for that.
You can customize
consult-hn-browse-fn
var, setting it to a function, here’s for example how to make it always open selected item in the browser.
(setopt consult-hn-browse-fn
(lambda (&rest args)
(browse-url (plist-get args :hn-object-url))))
Similarly, you can customize consult-hn-preview-fn
If you’re using hnreader, you may want to read the comments in its buffer - they show up in an Org-mode outline, it’s very nice:
(cl-defun consult-hn-reader (&key hn-object-url &allow-other-keys)
(hnreader-comment hn-object-url))
(setopt consult-hn-browse-fn #'consult-hn-reader
You can set consult-hn-initial-input-string
. For example, if you want to always see stories from the HN front page (whenever you open consult-hn), you can do (setq consult-hn-initial-input-string "-- tags=front_page")
. There’s however an important caveat I should mention. HN uses some proprietary algorithm to sort those stories, something that API doesn’t expose, so the sorted order of those stories will not be exactly as on the HN Front Page.
Or you may want to by default ignore stories that have fewer than a dozen of comments:
(setopt consult-hn-initial-input-string "-- numericFilters=num_comments>11")
Additionally, you can customize consult-hn-default-search-params
, like so:
(setopt consult-hn-default-search-params '((numericFilters "num_comments>11")))
Be careful though - these params quietly get translated into the query, and won’t even show up in the UI, for changing them, you will have to explicitly override them in the prompt. So, for the example above, unless you explicitly state: "-- numericFilters=num_comments>0"
, stories with fewer than 12 comments always be ignored. It might get confusing, so I suggest leaving this var unchanged.
The command, once receives a query, starts pulling the results exhaustively, until it fetches all the pages. Be mindful that you may encounter rate limiting due to Algolia API’s daily usage restrictions. To avoid this, try using more specific search terms and consider dropping into Embark Collect buffer to gather results sooner, rather than waiting for complete retrieval of all pages. I’ve been testing it pretty actively, and so far have not hit the rate-limiter.