2021-05-12, updated: 2024-03-12

Tested with Nyxt 2 Pre-release 7.

Tags: feature.

Prompt buffer: an overpowered user experience

Prompt buffer: an overpowered user experience

By Pierre Neidhardt

Have you ever felt frustrated using a popular browser when you couldn't do something as simple as "close all Wikipedia tabs" or "download all pictures on this page"?

This frustration is behind one of the fundamental ideas that gave birth to Nyxt: provide the user with a powerful, non-limiting interactive experience. The UI (user interface) should never get in the way. Quite the opposite, actually, it should empower the user by allowing them to quickly search, filter and process anything, from web page content to UI elements.

With this in mind, we've decided to put interactivity at the center of Nyxt. This is how the prompt buffer came to fruition:

We didn't want to repeat Emacs' mistake: its original "prompt" is so limited that it couldn't contain the frustration of its power users. This gave birth to a flock of alternative prompts, from Helm to Ivy. Because of this, the Emacs community is now split between various interfaces, with loads of extensions that only work with one but not the other.

By providing an original framework that strives at being as powerful and flexible as possible, we hope to satisfy all possible needs and keep the community stuck together with a consistent user experience.

What is the prompt buffer?

The prompt buffer is a universal input area for Nyxt. You can think of it like an 'omnibox', but with more features and power beyond simply setting the URL.

Our prompt buffer is heavily inspired by Emacs helm, but without the technical debt. Indeed, much of the logic is contained in a small cleanly separated prompter library. (For the technically minded, the library is short of 1500 lines of Lisp code.)

Features

Let's review what makes the prompt buffer special.

Live narrowing and fuzzy-searching.

Let's walk through an example of setting the URL:

Run set-url (bound to C-l by default, or click on the URL in the status area).

When you begin typing, you'll instantly note that suggestions update in real time.

Suggestions are filtered and sorted by fuzzy (non-exact) matching. There are several phases one can customize to filter/modify/redisplay suggestions to one's liking.

When you see the suggestion you like, select it (for instance with the up/down arrow keys) and press return.

Multiple sources

So far so good, we've seen something similar to what the URL bar in many browser does.

That's where the familiarity ends and where the special side of the prompt buffer starts to shine!

Let's start with a simple frustration: why does the bar search known URLs only in the history instead of collecting all the known URLs from various sources? Why should I use a different bar to search my bookmarks for instance?

Well, the prompt buffer addresses this!

Notice how set-url suggestions are split by sources, such as "New URL or search query" or "Global history". You can jump between sources with C-pagedown and C-pageup.

One of the most powerful design aspects of the prompt buffer is that sources can be reused in any prompt. Not only is it elegant from a programming perspective, but it's also beneficial to the end users since it allows them to easily customize what suggestions will be listed in any prompt.

For instance, you could easily customize the set-url prompt to remove the bookmark source, and add it to another prompt.

More on this in the Prompt buffer customization article.

Multiple actions

Say you call set-url and select a URL, but only then you decide to rather open it in a new buffer. With a regular prompt, you'd be forced to quit it, run the right UI element or command, find and select the URL again. This can quickly get cumbersome.

No problem with the prompt buffer: By pressing M-return after selecting the desired URL, you're a prompted with a list of possible actions you can run!

Another benefit of actions is that it composes features. For instance, if we didn't have multiple-action support and if we wanted all the N URL-opening commands to have a way to open the result in a new buffer, we would need to define N more commands that would do the same as the original ones, only to open the result in a new buffer.

Without loss of generality, this means that for P actions common to N commands, we need N*(P-1) additional commands.

With support for multiple actions, the original N commands are enough!

Each source has its own set of actions. Technically, an action is any Lisp function run against the selection. More on this in the Prompt buffer customization article.

Multiple selections

In the introduction, I hinted at the frustration of not being able to "delete all Wikipedia buffers". So how do we solve this problem? The answer is simple: by marking the filtered suggestions.

Run delete-buffer for instance.

Notice that the prompt is followed by [2/3], with 3 being the number of suggestions, and 2 the number of current marks. This means that you can "mark" (in other words, "select") multiple suggestions with C-space by default.

Conveniently, marking automatically moves to the next suggestion, so you can keep C-space pressed to mark multiple elements in a row (press shift-space to mark backwards).

To list all marking keys, press f1 b and type mark.

The mark commands are togglers, so marking an already marked suggestion removes the mark.

Upon pressing return, all the marks are deleted.

Note that if you've marked at least one suggestion and if the current selection is not on a mark, it will not be applied in the resulting action. (In this particular example, it won't be deleted.)

Press M-a to mark all suggestions of a source. M-u to unmark all. If you want to apply an action on all elements save a few ones, it's more efficient to mark all elements first, then type some input to match the elements you want to unmark.

Let's answer our original question: to delete all Wikipedia buffers, run delete-buffer, type Wikipedia, press M-a to select all suggestions, make sure you remove non-Wikipedia mismatches and confirm the deletion with return!

Suggestion attributes and togglable column display

The URL bar in popular browser display the URL and its associated title, but often that's it. What if you wanted to know more details about the URLs, such as the last time you accessed it? What about other pieces of data, such as bookmarks with their tags?

The prompt buffer tackles this problem by offering an extensible tabular display.

When you run execute-command you'll notice that it displays multiple attribute columns by default. You can customize which attributes to display with toggle-attributes-display (C-] by default).

Only visible columns are matched against the user input. Thus, hiding some columns is an easy way to match against a specific one.

"Follow mode"

Some sources have a "follow action", that is, an action that's run on the selection when it's changed, without closing the prompt.

This is convenient to run actions that may act as a preview or perform some other preprocessing.

For instance, switch-buffer has a default follow action which temporarily switches the current buffer to the one that's selected. Upon quit, the original buffer is restored.

Resumable prompts

Each prompt session is automatically recorded and can be resumed with resume-prompt.

This is particularly useful, say, to resume a search.

Conclusion

We hope you enjoy these new features, and that they help make you more productive.

Thanks for reading :-)


Did you enjoy this article? Register for our newsletter to receive the latest hacker news from the world of Lisp and browsers!