isaias-dias-machado

isaias-dias-machado

ExHelp - documentation fuzzy search and paging CLI tool for Elixir/Erlang

IEx’s h macro is great but it lacks a pager, so I built a small tool that caches documentation and lets you fuzzy search through it in your OS shell.

It follows the Unix philosophy - Internally pipes to fzf and your default $PAGER. The cache lives at ~/.cache/exh and builds up over time as you workon different projects (no duplicates).

It compiles your project, loads all the available modules, and encodes the documentation using ETF.

Performance-wise, it caches a vanilla Phoenix project in about 10 seconds on first run, 3 seconds on subsequent runs. Tested on my old T420.

The formatting of the docs matches IEx’s `h` macro since I borrowed some of that code.

Example usage:

$ exh fetch
$ exh

Originally tried making it IEx-native using Ports (check the less-in-iex branch), but, despite redirecting the group leader and waiting for the Port’s exit message, couldn’t find a way to make the BEAM fully yield terminal control - resulted in race conditions between the BEAM and the TUI. If anyone has insights on this, I’m all ears!

https://github.com/isaias-dias-machado/exhelp

Feedback welcome!

Most Liked

rhcarvalho

rhcarvalho

Interesting! How do you deal with versioning?

E.g., the help for a certain module/ function may change depending on the current branch/commit, in particular for “in development” state, not between tagged releases.

The cache invalidation problem :slight_smile:

rhcarvalho

rhcarvalho

I find myself consuming docs most of the time from hexdocs.pm or source code. When I do use h inside IEx, I’m typically inside tmux and can “scroll” back up with the keyboard.

So, speaking hypothetically, if exh clean nukes the whole cache, it would be too aggressive if I just want to refresh docs for a particular project. A refetch or fetch --force would be more targeted.

I still wonder how are you structuring the cache. Do you shard by package version? How do you treat Elixir and Erlang documentation?

This idea of centrally storing a deduplicated cache of packages reminds me of the Go Module Cache. In the Go ecosystem published modules have an immutable cryptographic checksum, and the multiple versions of a package are cached read-only in a single place. Separately, there’s also a build cache. How I’d translate that idea to Elixir is that published Hex packages could be cached by version, while “current project” needs special treatment as it can change anytime without a version change.

nikfp

nikfp

This solves a pain point I’ve been experiencing a lot, and never got a chance to dig in. (Too busy scrolling up after calling help!)

Looking forward to trying it out.

Last Post!

isaias-dias-machado

isaias-dias-machado

Hey! Make sure to pull and install the new changes:

exh fetch now updates stale cache. A module is considered stale when the documentation found in the current project/context is different than the documentation for the same module stored in cache.

exh fetch --prune will delete modules that are not found in the current context.

CRUD statistics on cached modules will be displayed after caching.

Bug fix: exh will correctly display functions and macros that have no @spec

Where Next?

Popular in Announcing Top

mischov
import Meeseeks.CSS html = HTTPoison.get!("https://news.ycombinator.com/").body for story <- Meeseeks.all(html, css("tr.athing")) do...
New
wmnnd
Hi there, for my project DBLSQD, I needed a file storage solution that is a bit more flexible than Arc. Because I thought others might f...
New
Azolo
Hey everyone, I just released WebSockex which is a Elixir WebSocket client. WebSockex strives to work as a OTP special process, be RFC6...
New
mspanc
I am pleased to announce an initial release of the Membrane Framework - an Elixir-based framework with special focus on processing multim...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 30486 241
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
fuelen
Hey folks! Want to present a toolkit for writing command-line user interfaces. It provides a convenient interface for colorizing text...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36820 110
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44265 214
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement