Version 3.12.0
Nyxt manual
This manual first includes the tutorial, then covers the configuration of
Nyxt.
Commands are invoked by pressing specific keys or from
the
Keybindings are represented like this: 'C-x'. In this example, 'C' is a
shortcut for the modifier 'control', and 'x' represents the character 'x'. To
input the 'C-x' keybinding you would keep 'control' pressed and then hit 'x'.
Multiple key presses can be chained: in 'C-x C-s', you would have to press
'C-x', and then press 'C-s'. Modifier keys legend: Modifiers can be remapped, see the
Nyxt uses the concept of buffers instead of tabs. Unlike tabs, buffers
are fully separated, each buffer having its own behavior and settings. Each buffer has its own list of modes, ordered by priority. A mode is a
set of functions, hooks, keybindings and other facilities that may modify the
behavior of a buffer. For example, 'blocker-mode' can be used for domain-based
ad-blocking while 'no-script-mode' disables JavaScript. Each buffer has separate instances of modes, which means that altering
the settings of a mode in a buffer does not impact other buffers. Mode specific
functions/commands are only available when a mode is enabled for the current
buffer. Each mode has an associated
mode toggler which is a command
of the same name that toggles the mode for the current buffer. The prompt buffer is a menu that will appear when a command requests user
input. For example, when invoking the
Some commands support marks, for
instance
When at least one suggestion is marked, only the marked suggestions are processed
upon return. The suggestion under the cursor is not processed if not marked. The message area represents a space (typically at the bottom of a
window) where Nyxt outputs messages back to you. To view the history of all
messages, invoke the command
The status buffer is where information about the state of that buffer is
printed (typically at the bottom of a window). By default, this includes the
active modes, the URL, and the title of the current buffer. To move within a buffer, several commands are provided: When ambiguous URLs are inputted, Nyxt will attempt the best guess it
can. If you do not supply a protocol in a URL, HTTPS will be assumed. To
visit a site supporting only the less secure HTTP, you must explicitly type the
full URL including the 'http://' prefix. Unlike other web browsers, Nyxt provides powerful ways of copying
and pasting content via different commands. Starting from: Passing through webpage's data: Leveraging password managers: And more: History is represented as a tree that you can traverse: when you go back
in history, then follow a new URL, it effectively creates a new branch without
deleting the old path. The tree makes sure you never lose track of where you've
been. You can also view a full tree of the history for a given buffer by
invoking the command 'buffer-history-tree'. Nyxt's search is incremental, i.e. it begins as soon as you type
the first character of the search string. A single or multiple buffers can be
queried, and all results are displayed in the prompt buffer. This makes it easy to interact with results found in different URLs
from a unified interface. The bookmark file
Bookmark-related commands Annotations can have the following settings: Annotate-related commands The command
The command
Several commands are provided to spell check words. The default is
English but it is possible to change the slot
Select text without a mouse. Nyxt's
Visual mode provides the following commands: Commands designed to ease the use for CUA users (but available to all users): A note for
Nyxt has many facilities for automation. For instance, it is possible to
automate the reading experience: Symmetrically, it is possible to automate the filling of forms: In addition, it is possible to automate actions over time:
Core concepts
#
Keybindings and commands
#execute-command (Ctrl+space)
.
control
(
C
): Control keysuper
(
S
): Windows key, Command keymeta
(
M
): Alt key, Option keyshift
(
s
): Shift keymodifier-translator
slot of the
gtk-browser
class.
Quickstart keys
#
set-url (Ctrl+l)
:
Set the URL for the current buffer, completing with history.reload-current-buffer (f5)
:
Reload current buffer.set-url-new-buffer (Alt+l)
:
Prompt for a URL and set it in a new focused buffer.switch-buffer-previous (Ctrl+[)
:
Switch to the previous buffer in the buffer tree.history-backwards (unbound)
:
Go to parent URL of BUFFER in history.history-forwards (unbound)
:
Go forward one step/URL in BUFFER's history.follow-hint (unbound)
:
Follow the top element hint selection in the current buffer.follow-hint-new-buffer (unbound)
:
Like `follow-hint', but selection is handled in background buffers.quit (Ctrl+q)
:
Quit Nyxt.execute-command (Ctrl+space)
:
Execute a command by name.describe-bindings (f1 b)
:
Show a list of all available keybindings in the current buffer.
Buffers
#
Modes
#
Prompt buffer
#set-url
command, you must
supply the URL you would like to navigate to. The prompt buffer can provide
suggestions. The list of suggestions will automatically narrow down to those
matching your input as you type.
run-action-on-return (keypadenter)
: Validate the selected suggestion(s) or the current input if there is
no suggestion.set-action-on-return (Alt+keypadenter)
: Query the user for an action to run over the marked suggestion(s).delete-buffer
can delete all selected buffers at once.
When the input is changed and the suggestions are re-filtered, the marks are
not altered even if the marked suggestions aren't visible.
toggle-mark-forwards (Ctrl+keypadenter)
: Select or deselect the current suggestion.mark-all (Alt+a)
: Select all currently-displayed suggestions.unmark-all (Alt+u)
: Deselect all currently-displayed suggestions.toggle-mark-all (Alt+m)
: Toggle the mark of all currently-displayed suggestions.toggle-attributes-display (Ctrl+])
: Change which attributes are displayed in the suggestions list.
Message area
#list-messages (unbound)
.
Status buffer
#
Basic controls
#
Moving within a buffer
#
scroll-down (keypaddown)
:
Scroll down the current page.scroll-up (keypadup)
:
Scroll up the current page.scroll-page-down (keypadnext)
:
Scroll down by one page height.scroll-page-up (keypadpageup)
:
Scroll up by one page height.scroll-to-bottom (Ctrl+down)
:
Scroll to the bottom of the current page.scroll-to-top (Ctrl+up)
:
Scroll to the top of the current page.
Setting the URL
#
set-url (Ctrl+l)
:
Set the URL for the current buffer, completing with history.set-url-new-buffer (Alt+l)
:
Prompt for a URL and set it in a new focused buffer.make-buffer-focus (Ctrl+t)
:
Switch to a new buffer.
Switching buffers
#
switch-buffer (Alt+down)
:
Switch buffer using fuzzy completion.switch-buffer-next (Ctrl+])
:
Switch to the next buffer in the buffer tree.switch-buffer-previous (Ctrl+[)
:
Switch to the previous buffer in the buffer tree.
Copy and paste
#
copy (Ctrl+c)
:
Copy selected text to clipboard.paste (Ctrl+v)
:
Paste from clipboard into active element.
copy-url (Alt+c l)
:
Save current URL to clipboard.copy-title (Alt+c t)
:
Save current page title to clipboard.copy-placeholder (unbound)
:
Copy placeholder text to clipboard.copy-hint-url (unbound)
:
Save the element hint's URL to the clipboard.
copy-username (unbound)
:
Query username and save to clipboard.copy-password (unbound)
:
Query password and save to clipboard.copy-password-prompt-details (unbound)
:
Copy password prompting for all the details without suggestions.
paste-from-clipboard-ring (Alt+v)
:
Show `*browser*' clipboard ring and paste selected entry.show-system-information (unbound)
:
Display information about the currently running Nyxt system.
Using the buffer history
#
history-forwards (unbound)
:
Go forward one step/URL in BUFFER's history.history-backwards (unbound)
:
Go to parent URL of BUFFER in history.history-forwards-query (unbound)
:
Query forward-URL to navigate to.history-backwards-query (unbound)
:
Query parent URL to navigate back to.history-forwards-all-query (unbound)
:
Query URL to forward to, from all child branches.history-all-query (unbound)
:
Query URL to go to, from the whole history.
Incremental Search
#
search-buffer (unbound)
:
Search incrementally on the current buffer.search-buffers (unbound)
:
Search incrementally in multiple buffers.remove-search-marks (unbound)
:
Remove all search marks.
Bookmarks
# is made to be human readable and editable.
Bookmarks can have the following settings:
:url
: The URL of the bookmark.:title
: The title of the bookmark.:tags
: A list of strings. Useful to categorize and filter bookmarks.
bookmark-current-url (unbound)
:
Bookmark the URL of the current BUFFER.bookmark-buffer-url (unbound)
:
Bookmark the page(s) currently opened in the existing buffers.bookmark-url (unbound)
:
Prompt for a URL to bookmark.bookmark-hint (unbound)
:
Prompt for element hints and bookmark them.set-url-from-bookmark (unbound)
:
Set the URL for the current buffer from a bookmark.delete-bookmark (unbound)
:
Delete bookmark(s) matching the chosen URLS-OR-BOOKMARK-ENTRIES.list-bookmarks (unbound)
:
List all bookmarks in a new buffer.import-bookmarks-from-html (unbound)
:
Import bookmarks from an HTML-FILE with bookmarks from other browsers.bookmark-frequent-visits-mode (unbound)
:
Toggle `bookmark-frequent-visits-mode'.
Annotations
#
snippet
: The snippet which was highlighted by the user.url
: The URL of the annotation.page-title
: The title of the annotation.data
: The comment about the highlighted snippet or
the URL.tags
: A list of strings. Useful to categorize and filter annotations.
annotate-current-url (unbound)
:
Create an annotation of the URL of BUFFER.annotate-highlighted-text (unbound)
:
Create an annotation for the highlighted text of BUFFER.show-annotation (unbound)
:
Show prompted annotations.show-annotations (unbound)
:
Show all annotations.show-annotations-for-current-url (unbound)
:
Create a new buffer with the annotations of the current URL of BUFFER.
Passthrough mode
#passthrough-mode
forwards all keys to the
renderer. For instance, using the default binding of Nyxt (
web-cua-map
) the
keybinding
C-i
executes
autofill
. Suppose
a user is using their email client which also uses
C-i
for the italic command. Thus, after
executing
passthrough-mode
the
C-i
binding is associated
with the webpage's italic command instead of
autofill
. Finally, the
user can return to their configuration just by executing
passthrough-mode
again.
Enable, disable, and toggle multiple modes
#enable-modes (unbound)
allows the user to apply multiple
modes (such as
nosound-mode
and
dark-mode
) to
multiple buffers at once. Conversely, it is possible to revert this action by
executing
disable-modes (unbound)
while choosing exactly the same buffers and
modes previously selected. Finally,
toggle-mode
also allows
activation and deactivation of multiple modes, but only for the current
buffer.
Spelling check
#spell-check-language
for other languages:
spell-check-word (unbound)
:
Spell check a word.spell-check-word-at-cursor (unbound)
:
Spell check the word at the cursor.spell-check-suggest-word (unbound)
:
Suggest a spelling for a given word.spell-check-highlighted-word (unbound)
:
Spell check a highlighted word.spell-check-list-languages (unbound)
:
List all languages supported on your machine.spell-check-text-input (unbound)
:
Spell check full text input provided by the user.
Visual mode
#visual-mode
imitates Vim's visual mode (and comes with the
CUA and Emacs-like keybindings out of the box, too). Activate it with the
visual-mode (unbound)
command.
visual-mode (Ctrl+c)
: Quit visual mode.select-paragraph (unbound)
:
Add hints to text elements on the page and query them.toggle-mark (unbound)
:
Toggle the mark.forward-char (right)
:
Move caret forward by a character.backward-char (backspace)
:
Move caret backward by a character.forward-word (unbound)
:
Move caret forward by a word.backward-word (unbound)
:
Move caret backward by a word.forward-line (down)
:
Move caret forward by a line.backward-line (up)
:
Move caret backward by a line.beginning-line (keypadhome)
:
Move caret to the beginning of the line.end-line (keypadend)
:
Move caret to the end of the line.forward-sentence (unbound)
:
Move caret forward to next end of sentence.backward-sentence (unbound)
:
Move caret backward to start of sentence.
forward-char-with-selection (Shift+right)
:
Set mark and move caret forward by a character.backward-char-with-selection (Shift+left)
:
Set mark and move caret backward by a character.forward-line-with-selection (Shift+down)
:
Set mark and move caret forward by a line.backward-line-with-selection (Shift+up)
:
Set mark and move caret backward by a line.emacs-mode
users: unlike in Emacs, in Nyxt the command
toggle-mark (unbound)
is bound to Shift-space, as C-space is bound to 'execute-command,
overriding any mode keybinding. If you want to toggle mark with C-space,
you'll need to set your own override-map such that C-space is not bound.
An example:
(
define-configuration
input-buffer
((override-map
(let ((map (make-keymap
"override-map")))
(define-key
map "M-x" 'execute-command)))))
Automation
#
cruise-control-mode (unbound)
:
Toggle `cruise-control-mode'.
autofill (unbound)
:
Fill in a field with a value from a saved list.toggle-checkboxes (unbound)
:
Toggle all checkboxes.
watch-mode (unbound)
:
Toggle `watch-mode'.repeat-every (unbound)
:
Prompt for function to be run every seconds.
Or even automate actions based on conditions:
-
repeat-mode (unbound)
: Toggle `repeat-mode'. -
preview-mode (unbound)
: Toggle `preview-mode'.
Nyxt also offers a no-code interface to build automation via Common Lisp macros:
-
edit-macro (unbound)
: Edit a macro.
Lastly, the
process-mode
must be highlighted:
process-mode
is actually a building block
for other modes previously mentioned, such as
repeat-mode
.
The extension relationship goes further, since
cruise-control-mode
is in its turn an
extension and a composition of
repeat-mode
and
scroll-down (keypaddown)
. Further extensions and compositions can be
creatively tailor-made by users to automate their own use of Nyxt.
Miscellaneous
#
Miscellaneous
#-
zoom-page (Ctrl++)
: Zoom in the current page BUFFER. -
unzoom-page (Ctrl+button5)
: Zoom out the current page in BUFFER. -
reset-page-zoom (Ctrl+0)
: Reset the BUFFER zoom to the `zoom-ratio-default' or RATIO. -
autofill (unbound)
: Fill in a field with a value from a saved list. -
download-open-file (unbound)
: Open file in Nyxt or externally. -
edit-with-external-editor (Ctrl+u Ctrl+o)
: Edit the current input field using `external-editor-program'.
The Nyxt help system
#
The Nyxt help system
#Nyxt provides introspective and help capabilities. All commands, classes, slots, variables, functions and bindings can be inspected for definition and documentation.
-
tutorial (f1 t)
: Display Nyxt tutorial. -
describe-key (f1 k)
: Display binding of user-inputted keys. -
describe-bindings (f1 b)
: Show a list of all available keybindings in the current buffer. -
describe-command (f1 c)
: Inspect a command and show it in a help buffer. -
describe-function (f1 f)
: Inspect a function and show it in a help buffer. -
describe-variable (f1 v)
: Inspect a variable and show it in a help buffer. -
describe-class (f1 C)
: Inspect a class and show it in a help buffer. -
describe-slot (f1 s)
: Inspect a slot and show it in a help buffer. -
describe-any (f1 a)
: Inspect anything and show it in a help buffer.
A good starting point is to study the documentation of the classes
browser
,
window
,
buffer
and
prompt-buffer
.
Configuration
#
Configuration
#Nyxt is written in the Common Lisp programming language which offers a great perk: everything in the browser can be customized by the user, even while it's running!
To get started with Common Lisp, we recommend checking out our web page: Learn Lisp. It contains numerous pointers to other resources, including free books both for beginners and seasoned programmers.
Nyxt provides a mechanism for new users unfamiliar with Lisp to
customize Nyxt. Start by invoking the commands
describe-class (f1 C)
or
describe-slot (f1 s)
. You can press the button marked 'Configure' to
change the value of a setting. The settings will be applied immediately and
saved for future sessions. Please note that these settings will not alter
existing object instances.
Settings created by Nyxt are stored in
/home/doe/.config/nyxt/auto-config.3.lisp
.
Any settings can be overridden manually by
/home/doe/.config/nyxt/config.lisp
.
The following section assumes knowledge of basic Common Lisp or a similar programming language.
The user needs to manually create the Nyxt configuration file, and the parent folders if necessary.
Example:
(define-configuration
web-buffer
((default-modes
(pushnew
'nyxt/mode/no-script:no-script-mode %slot-value%
))))
The above turns on the 'no-script-mode' (disables JavaScript) by default for every buffer.
The
define-configuration
macro can be used to customize
the slots of classes like the browser, buffers, windows, etc. Refer to the
class and slot documentation for the individual details.
To find out about all modes known to Nyxt,
run
describe-command (f1 c)
and type 'mode'.
Slot configuration
#
Slot configuration
#Slot values can be queried and tweaked, enabling many customization
possibilities. For instance, slot
zoom-ratio-default
has the default value of
1.0
. Follow the steps
below to tweak it:
- Execute command
describe-slot (f1 s)
; - Type
zoom-ratio-default
to select the one fromdocument-buffer
; - Press the
Configure
button; - Type the desired value, for instance,
1.3
. - After restarting Nyxt, every page will be zoomed accordingly.
There are plenty of customizable slots and these can be discovered
by inspecting classes via
describe-class (f1 C)
.
Different types of buffers
#
Different types of buffers
#There are multiple buffer classes, such as
document-buffer
(for structured documents) and
input-buffer
(for buffers that can receive user input). A
web-buffer
class is used for web pages,
prompt-buffer
for, well, the prompt buffer. Some buffer classes may inherit from multiple other classes.
For instance
web-buffer
and
prompt-buffer
both inherit from
input-buffer
.
You can configure one of the parent
buffer
classes slots and the new
values will automatically cascade down as a new default for all child classes-
unless this slot is specialized by these child classes.
For instance if you configure the
override-map
slot in
input-buffer
, both
panel-buffer
and
web-buffer
classes will inherit from the new value.
Keybinding configuration
#
Keybinding configuration
#Nyxt supports multiple
bindings schemes such as CUA (the
default), Emacs or vi. Changing scheme is as simple as setting the
corresponding mode as default, e.g.
emacs-mode
. To make the change persistent across sessions,
add the following to your configuration:
- vi bindings:
(
define-configuration
buffer ((default-modes
(pushnew
'nyxt/mode/vi:vi-normal-mode%slot-value%
)))) - Emacs bindings:
(
define-configuration
buffer ((default-modes
(pushnew
'nyxt/mode/emacs:emacs-mode%slot-value%
))))
You can create new scheme names with
make-keyscheme
. Also see the
define-keyscheme-map macro
.
To extend the bindings of a specific mode, you can configure the mode with
define-configuration
and extend its
keyscheme-map
with
define-keyscheme-map
. For example:
(define-configuration
base-mode
"Note the :import part of the define-keyscheme-map
.
It re-uses the other keymap (in this case, the one that was slot value before
the configuration) and merely adds/modifies it."
((keyscheme-map
(define-keyscheme-map
"my-base" (list
:import %slot-value%
)
keyscheme:vi-normal
(list
"g b"
(lambda-command
switch-buffer*
nil
(switch-buffer
:current-is-last-p
t)))))))
The
override-map
is a keymap that has priority over
all other keymaps. By default, it has few bindings like the one
for
execute-command (Ctrl+space)
. You can use it to set keys globally:
(define-configuration
input-buffer
((override-map
(let ((map (make-keymap
"override-map")))
(define-key
map "M-x" 'execute-command "C-space" 'nothing)))))
The
nothing (unbound)
command is useful to override bindings to do
nothing. Note that it's possible to bind any command, including those of
disabled modes that are not listed in
execute-command (Ctrl+space)
. Binding to
nothing (unbound)
and binding to NIL means different things (see the documentation of
define-key
for details):
-
nothing (unbound)
- Binds the key to a command that does nothing. Still discovers the key and recognizes it as pressed.
- NIL
- Un-binds the key, removing all the bindings that it had in a given mode/keyscheme-map. If you press the un-bound key, the bindings that used to be there will not be found anymore, and the key will be forwarded to the renderer.
- Any other symbol/command
- Replaces the command that was there before, with the new one. When the key is pressed, the new command will fire instead of the old one.
In addition, a more flexible approach is to create your own mode with your custom keybindings. When this mode is added first to the buffer mode list, its keybindings have priorities over the other modes. Note that this kind of global keymaps also have priority over regular character insertion, so you should probably not bind anything without modifiers in such a keymap.
(defvar
*my-keymap* (make-keymap
"my-map"))
(define-key
*my-keymap* "C-f" 'nyxt/mode/history:history-forwards
"C-b" 'nyxt/mode/history:history-backwards)
(define-mode
my-mode
nil
"Dummy mode for the custom key bindings in *my-keymap*
."
((keyscheme-map
(nkeymaps/core:make-keyscheme-map
keyscheme:cua
*my-keymap*
keyscheme:emacs
*my-keymap*
keyscheme:vi-normal
*my-keymap*))))
(define-configuration
web-buffer
"Enable this mode by default."
((default-modes
(pushnew
'my-mode %slot-value%
))))
Bindings are subject to various translations as per
*translator*
. By default if it fails to find a binding it tries again with inverted
shifts. For instance if
C-x C-F
fails to match anything
C-x C-f
is tried.See the default value of
*translator*
to learn how to
customize it or set it to
nil
to disable all forms of
translation.
Search engines
#
Search engines
#See the
search-engines
buffer slot
documentation. Bookmarks can also be used as search engines, see the
corresponding section.
Nyxt comes with default search engines for
en.wikipedia.org, duckduckgo.com, search.atlas.engineer
. The following example shows one way to add new search engines.
(defvar
*my-search-engines*
(list
'("google" "https://google.com/search?q=~a" "https://google.com")
'("python3" "https://docs.python.org/3/search.html?q=~a"
"https://docs.python.org/3")
'("doi" "https://dx.doi.org/~a" "https://dx.doi.org/"))
"List of search engines.")
(define-configuration
context-buffer
"Go through the search engines above and make-search-engine
out of them."
((search-engines
(append
(mapcar
(lambda (engine) (apply 'make-search-engine
engine))
*my-search-engines*)
%slot-default%
))))
Note that the last search engine is the default one. For example, in order to make python3 the default, the above code can be slightly modified as follows.
(defvar
*my-search-engines*
(list
'("google" "https://google.com/search?q=~a" "https://google.com")
'("doi" "https://dx.doi.org/~a" "https://dx.doi.org/")
'("python3" "https://docs.python.org/3/search.html?q=~a"
"https://docs.python.org/3"))
"List of search engines.")
(define-configuration
context-buffer
"Go through the search engines above and make-search-engine
out of them."
((search-engines
(append
%slot-default%
(mapcar
(lambda (engine) (apply 'make-search-engine
engine))
*my-search-engines*)))))
If you don't want to use
make-search-engine
and want to try building the engines yourself, you can always make new
search-engine
and add it to
search-engines
list:
(define-configuration
context-buffer
"Add a single search engine manually."
((search-engines
(pushnew
(make-instance
'search-engine
:name "Reddit" :shortcut "r"
:search-url "https://reddit.com/search/?q=~a"
:fallback-url "https://reddit.com")
%slot-value%
))))
History
#
History
#Nyxt history model is a tree whose nodes are URLs. It branches out through all
the buffers. If you create a new buffer (via
follow-hint-new-buffer (unbound)
or
make-buffer (unbound)
), it becomes a new history branch originating
from the branch of the previous buffer.
History can be navigated with the arrow keys in the status buffer, or with
commands like
history-backwards (unbound)
and
history-forwards (unbound)
(which the arrows are bound to).
If the beyond-buffer-boundaries behavior sounds like too much to you, or you
prefer the behavior of Nyxt 2, where the history was still a tree, but was not
spilling across the buffers, then configure
global-history-p
to be NIL:
(define-configuration
:context-buffer
(global-history-p
nil))
history-backwards (unbound)
and
history-forwards (unbound)
) will only work inside the buffer history then.
Nyxt supra-buffer history has benefits, though: it optimizes browsing patterns
into more intuitive and productive structures. One particular pattern Nyxt
history optimizes is hub-and-spoke search, where you keep returning to a certain
hub to start your search/navigation from a familiar point. You can enable the
optimization (merely going back in history to the hub page, instead of creating
a new history node) for this strategy by configuring
backtrack-to-hubs-p
to T.
Another useful side to Nyxt tree-like history are braching-aware history
commands, like
history-forwards-query (unbound)
, allowing one to choose which branch of history they are going to visit, if
there are several. If there's only one branch, then this command behaves much
like regular
history-forwards (unbound)
.
There are commands that allow to move across all the history before or after the current node:
-
history-backwards-query (unbound)
: Query parent URL to navigate back to. -
history-forwards-all-query (unbound)
: Query URL to forward to, from all child branches. -
history-all-query (unbound)
: Query URL to go to, from the whole history.
If you need to know more: most of the optimizations and data structures are
in
history-tree
library, while most of the Nyxt-specific interface is in
nyxt/mode/history-tree
.
Downloads
#
Downloads
#See the
list-downloads (Ctrl+Shift+Y)
command and the
download-path
buffer slot documentation.
Proxy and Tor
#
Proxy and Tor
#See the
proxy-mode
documentation.
Blocker mode
#
Blocker mode
#This mode blocks access to websites related to specific hosts. To see
all hosts being blocked, execute command
describe-variable
, choose variable
NYXT/MODE/BLOCKER:*DEFAULT-HOSTLIST*
, and read data on
nyxt/mode/blocker:url-body
slot. To customize host blocking, read the
blocker-mode
documentation.
URL-dispatchers
#
URL-dispatchers
#You can configure which actions to take depending on the URL to be
loaded. For instance, you can configure which Torrent program to start to load
magnet links. See the
url-dispatching-handler
function
documentation.
Auto rules
#
Auto rules
#Auto-rules toggle modes when the URL satisfies the given conditions. URL-dispatchers can also be used for this, but it is simpler to use an auto-rule. Given that Nyxt's functionality is mode-based, the consequences are far reaching.
These can be used in the following ways:
- Manually, by calling:
-
save-non-default-modes-for-future-visits (unbound)
- which saves "unusual" modes - non-default modes that were toggled exclusively for a given URL.
-
save-exact-modes-for-future-visits (unbound)
- which saves the exact list of enabled modes for a given URL.
- Automatically, by setting
prompt-on-mode-toggle-p
to non-nil (refer to the configuration section for help).
All rules are stored at
/home/doe/.local/share/nyxt/auto-rules.lisp
, which
is
meant to be human-readable and human-writable. You can find instructions at the top of it.
The gist is that rules are mere Lisp lists which start with a condition that checks the
URL. When conditions are met, modes are toggled. Besides user-defined conditions, the
following are often useful:
By default,
apply-all-matching-auto-rules-p
is nil meaning that only the most specific rules are honored.
Auto-rules can also be defined for custom use-cases via
define-auto-rule
and un-defined with
undefine-auto-rule
.
Custom commands
#
Custom commands
#Creating your own invocable commands is similar to creating a Common
Lisp function, except the form is
define-command
instead of
defun
. If you want this command to be invocable outside of
the context of a mode, use
define-command-global
.
Example:
(define-command-global
my-bookmark-url
nil
"Query which URL to bookmark."
(let ((url
(prompt
:prompt "Bookmark URL" :sources
'prompter:raw-source)))
(nyxt/mode/bookmark:bookmark-add
url)))
See the
prompt-buffer
class documentation for how
to write custom prompt buffers.
You can also create your own context menu entries binding those to Lisp commands, using
ffi-add-context-menu-command
function. You can bind the
bookmark-url
like this:
(ffi-add-context-menu-command
'my-bookmark-url "Bookmark URL")
Currently, context menu commands don't have access to the renderer objects (and
shouldn't hope to). Commands you bind to context menu actions should deduce most
of the information from their surroundings, using JavaScript and Lisp functions
Nyxt provides. For example, one can use the
url-at-point
to get thep URL currently under pointer.
With this, one can improve the bookmarking using
url-at-point
:
(ffi-add-context-menu-command
(lambda ()
(nyxt/mode/bookmark:bookmark-add
(url-at-point
(current-buffer
))))
"Bookmark Link")
Custom URL schemes
#
Custom URL schemes
#If there's a scheme that Nyxt doesn't support, but you want it to, you can always define the handler for this scheme so that it's Nyxt-openable.
As a totally hypothetical example, you can define a nonsense scheme
bleep
to generate a page with random text:
(define-internal-scheme
"bleep"
(lambda (url buffer)
(values
(spinneret:with-html-string
(:h1 "Bleep bloop?")
(:p
(loop repeat (parse-integer
(quri.uri:uri-path
(url url))
:junk-allowed t)
collect (:li
(elt '("bleep" "bloop")
(random 2))))))
"text/html;charset=utf8"))
:local-p t)
What this piece of code does is
- Define a new scheme.
- Make a handler for it that takes the URL (as a string) and a buffer it's being opened in.
- Read the path (the part after the bleep:) of the URL and interpret it as a number.
- (Note that you need to wrap the URL into a
url
call so that it turns into auri
for the convenience of path (and other elements) fetching.) - Generate a random list of "bleep" and "bloop".
- Return it as a
text/html
content.
The next time you run Nyxt and open
bleep:20
, you'll see a list of twenty bleeps and bloops.
Internal schemes can return any type of content (both strings and arrays of
bytes are recognized), and they are capable of being
CORS-enabled
,
protected
, and are in general capable of whatever the renderer-provided schemes do.
nyxt: URLs and internal pages
#
nyxt: URLs and internal pages
#You can create pages out of Lisp commands, and make arbitrary computations for the content of those. More so: these pages can invoke Lisp commands on demand, be it on button click or on some page event. The macros and functions to look at are:
-
define-internal-page
to create new pages. -
buffer-load-internal-page-focus
to either get or create the buffer for the page. -
nyxt-url
to reference the internal pages by their name. -
define-internal-page-command
to generate a mode-specific command loading the internal page. -
define-internal-page-command-global
to generate a global command loading the internal page.
Using the facilities Nyxt provides, you can make a random number generator page:
(define-internal-page-command-global
random-number
(&key (max 1000000))
(buffer "*Random*")
"Generates a random number on every reload."
(spinneret:with-html-string
(:h1 (princ-to-string (random max)))
(:button.button :onclick
(parenscript:ps
(nyxt/parenscript:lisp-eval
(:title "re-load/re-generate the random number")
(reload-buffer buffer)))
:title "Re-generate the random number again" "New number")))
Several things to notice here:
- Internal page command is much like a regular command in being a Lisp function
that you can call either from the REPL or from the
execute-command (Ctrl+space)
menu. - With one important restriction: internal page commands should only have keyword
arguments. Other argument types are not supported. This is to make them
invocable through the URL they are assigned. For example, when you invoke the
random-number
command you've written, you'll see thenyxt:nyxt-user:random-number?max=%1B1000000
URL in the status buffer. The keyword argument is being seamlessly translated into a URL query parameter. - There's yet another important restriction: the values you provide to the internal page command should be serializable to URLs. Which restricts the arguments to numbers, symbols, and strings, for instance.
- Those commands should return the content of the page in their body, like internal schemes do.
- If you want to return HTML, then
with-html-string
is your best friend, but no one restricts you from producing HTML in any other way, including simply writing it by hand ;) -
nyxt/ps:lisp-eval
is a Parenscript macro to request Nyxt to run arbitrary code. The signature is:((&key (buffer '(nyxt:current-buffer)) title callback) &body form)
. You can bind it to a<button>
'sonClick
event, for example.
If you're making an extension, you might find other macros more useful.
define-internal-page-command
, for example, defines a command to only be visible when in the corresponding mode
is enabled. Useful to separate the context-specific commands from the
universally useful (
-global
) ones. If there's a page that you'd rather not have a command for, you can
still define it as:
(define-internal-page
not-a-command
nil
(:title "*Hello*" :page-mode 'base-mode)
"Hello there!")
and use as:
(buffer-load-internal-page-focus
'not-a-command)
See the slots and documentation of
internal-page
to understand what you can pass to
define-internal-page
.
Hooks
#
Hooks
#Hooks provide a powerful mechanism to tweak the behavior of various events that occur in the context of windows, buffers, modes, etc.
A hook holds a list of handlers. Handlers are named and typed functions. Each hook has a dedicated handler constructor.
Hooks can be 'run', that is, their handlers are run according to
the
combination
slot of the hook. This combination is a function
of the handlers. Depending on the combination, a hook can run the handlers
either in parallel, or in order until one fails, or even
compose them (pass the result of one as the input of the next). The handler types
specify which input and output values are expected.
To add or delete a hook, you only need to know a couple of functions:
-
handler
a class to wrap hook handlers in. -
add-hook
(also known ashooks:add-hook
) allows you to add a handler to a hook,for it to be invoked when the hook fires. -
nhooks:on
(also available ashooks:on
) as a shorthand for thenhooks:add-hook
. -
remove-hook
(also available ashooks:remove-hook
) that removes the handler from a certain hook. -
nhooks:once-on
(also available ashooks:once-on
) as a one-shot version ofnhooks:on
that removes the handler right after it's completed.
Many hooks are executed at different points in Nyxt, among others:
- Global hooks, such as
after-init-hook
orafter-startup-hook
. - Window- or buffer-related hooks.
-
window-make-hook
for when a new window is created. -
window-delete-hook
for when a window is deleted. -
window-set-buffer-hook
for when thecurrent-buffer
changes in the window. -
buffer-load-hook
for when there's a new page loading in the buffer. -
buffer-loaded-hook
for when this page is mostly done loading (some scripts/image/styles may not be fully loaded yet, so you may need to wait a bit after it fires.) -
request-resource-hook
for when a new request happens. Allows redirecting and blocking requests, and is a good place to do something conditioned on the links being loaded. -
prompt-buffer-ready-hook
fires when the prompt buffer is ready for user input. You may need to callall-ready-p
on the prompt to ensure all the sources it contains are ready too, and then you can safely set new inputs and select the necessary suggestions. - Commands :before and :after methods.
- Try, for example,
(defmethod set-url :after (&key (prefill-current-url-p t)) ...)
to do something after the set-url finishes executing. - Modes 'enable' and 'disable' methods and their :before, :after, and :around methods.
- Mode-specific hooks, like
before-download-hook
andafter-download-hook
fordownload
.
For instance, if you want to force 'old.reddit.com' over 'www.reddit.com', you can set a hook like the following in your configuration file:
(defun
old-reddit-handler (request-data)
(let ((url
(url
request-data)))
(setf (url
request-data)
(if
(search
"reddit.com" (quri.uri:uri-host
url))
(progn
(setf (quri.uri:uri-host
url) "old.reddit.com")
(log:info
"Switching to old Reddit: ~s"
(render-url
url))
url)
url)))
request-data)
(define-configuration
web-buffer
((request-resource-hook
(sera:add-hook
%slot-default%
'old-reddit-handler))))
(See
url-dispatching-handler
for a simpler way to achieve the same result.)
Or, if you want to set multiple handlers at once,
(define-configuration
web-buffer
((request-resource-hook
(reduce
#'sera:add-hook
'(old-reddit-handler auto-proxy-handler)
:initial-value %slot-default%
))))
Some hooks like the above example expect a return value, so it's
important to make sure we return
request-data
here. See the
documentation of the respective hooks for more details.
Data paths and data profiles
#
Data paths and data profiles
#Nyxt provides a uniform configuration interface for all data files
persisted to disk (bookmarks, cookies, etc.). To each file corresponds
a
nyxt-file
object. An
nyxt-profile
is a
customizable object that helps define general rules for data storage. Both
nyxt-file and nyxt-profile compose, so it's possible to define general rules
for all files (even for those not known in advance) while it's also
possible to specialize some data given an nyxt-profile.
The profile can be set from command line and from the
configuration file.You can list all known profiles (including the user-defined
profiles) with the
--list-profiles
command-line option.
The nyxt-files can be passed a hint from the
--with-file
command line option, but each nyxt-file and
profile rules are free to ignore it.
When a path ends with the
.gpg
extension, by default your
GnuPG key is used to decrypt and encrypt the file transparently. Refer to the
GnuPG documentation for how to set it up.
Note that the socket and the initialization nyxt-paths cannot be set in your configuration (the socket is used before the initialization file is loaded). Instead you can specify these paths from their respective command-line option. You can instantiate a unique, separate Nyxt instance when you provide a new socket path. This is particularly useful in combination with profiles, say to develop Nyxt or extensions.
Example to create a development profile that stores all data in
/tmp/nyxt
and stores bookmark in an encrypted file:
(define-class
dev-profile (nyxt-profile)
((files:name :initform "nyxt-dev"))
(:documentation "Development profile."))
(defmethod
files:resolve ((profile
dev-profile) (path nyxt-file))
"Expand all data paths inside a temporary directory."
(sera:path-join
(files:expand
(make-instance
'nyxt-temporary-directory
))
(uiop/pathname:relativize-pathname-directory
(call-next-method))))
(defmethod
files:resolve ((profile
dev-profile) (file history-file))
"Persist history to default location."
(files:resolve
(global-profile
) file))
(define-configuration
web-buffer
"Make new profile the default."
((profile
(make-instance
(or
(find-profile-class
(getf
*options*
:profile))
'dev-profile)))))
Then you can start a separate instance of Nyxt using this profile
with
nyxt --profile dev --socket /tmp/nyxt.socket
.
Password management
#
Password management
#Nyxt provides a uniform interface to some password managers including
KeepassXC and
Password Store. The supported installed password manager is automatically detected.See the
password-interface
buffer slot for customization.
You may use the
define-configuration
macro with
any of the password interfaces to configure them. Please make sure to
use the package prefixed class name/slot designators within
the
define-configuration
.
-
save-new-password (unbound)
: Query for name and new password to persist in the database. -
copy-password (unbound)
: Query password and save to clipboard.
KeePassXC support
#
KeePassXC support
#The interface for KeePassXC should cover most use-cases for KeePassXC, as it supports password database locking with
To configure KeePassXC interface, you might need to add something like this snippet to your config:
(defmethod
initialize-instance :after
((interface password:keepassxc-interface)
&key &allow-other-keys)
"It's obviously not recommended to set master password here,
as your config is likely unencrypted and can reveal your password to someone
peeking at the screen."
(setf (password:password-file
interface)
"/path/to/your/passwords.kdbx"
(password:key-file
interface) "/path/to/your/keyfile"
(password:yubikey-slot
interface) "1:1111"))
(define-configuration
nyxt/mode/password:password-mode
((nyxt/mode/password:password-interface
(make-instance
'password:keepassxc-interface
))))
(define-configuration
buffer
((default-modes
(append
(list
'nyxt/mode/password:password-mode) %slot-value%
))))
Appearance
#
Appearance
#Much of the visual style can be configured by the user. You can use the
facilities provided by
theme
and
browser theme slot
. The simplest option would be to use a built-in theme:
(define-configuration
browser
((theme
theme:+dark-theme+
:doc "Setting dark theme.
The default is theme:+light-theme+
.")))
There's also an option of creating a custom theme. For example, to set a theme to a midnight-like one, you can add this snippet to your configuration file:
(define-configuration
browser
((theme
(make-instance
'theme:theme
:background-color "black"
:action-color "#37a8e4" :primary-color "#808080"
:secondary-color "darkgray" :text-color
"lightgray" :contrast-text-color "black")
:doc
"You can omit the colors you like in default theme, and they will stay as they were.")))
This, on the next restart of Nyxt, will repaint all the interface elements into a dark-ish theme.
As a more involved theme example, here's how one can redefine most of the semantic colors Nyxt uses to be compliant with Solarized Light theme:
(define-configuration
browser
((theme
(make-instance
'theme:theme
:background-color "#eee8d5"
:action-color "#268bd2" :primary-color "#073642"
:secondary-color "#586e75" :success-color
"#2aa198" :warning-color "#dc322f"
:highlight-color "#d33682" :codeblock-color
"#6c71c4" :text-color "#002b36"
:contrast-text-color "#fdf6e3")
:doc
"Covers all the semantic groups (warning-color
, codeblock-color
etc.)
Note that you can also define more nuanced colors, like warning-color+
, so
that the interface gets even nicer. Otherwise Nyxt generates the missing colors
automatically, which should be good enough... for most cases.")))
As an alternative to the all-encompassing themes, you can alter the style of
every individual class controlling Nyxt interface elements. All such classes have a
style
slot that you can configure with your own CSS like this:
(define-configuration
nyxt/mode/style:dark-mode
((style
(theme:themed-css
(theme *browser*)
`(*
:background-color ,theme:background "!important"
:background-image none "!important" :color "red"
"!important")
`(a :background-color ,theme:background "!important"
:background-image none "!important" :color "#AAAAAA"
"!important"))))
:doc
"Notice the use of theme:themed-css
for convenient theme color injection.")
This snippet alters the
style
of Nyxt dark mode to have a more theme-compliant colors, using the
theme:themed-css
macro (making all the theme colors you've configured earlier available as
variables like
theme:on-primary
.)
Status buffer appearance
#
Status buffer appearance
#You can customize the layout and styling of
status-buffer
using the methods it uses for layout. These methods are:
-
format-status
- General layout of the status buffer, including the parts it consists of.
-
format-status-buttons
- The ("Back", "Forward", "Reload") buttons section.
-
format-status-url
- The current URL display section.
-
format-status-tabs
- Tab listing.
-
format-status-modes
- List of modes.
To complement the layout produced by these
format-*
functions, you might need to add more rules or replace the
style of status buffer
.
Scripting
#
Scripting
#You can evaluate code from the command line with
--eval
and
--load
. From a shell:
$ nyxt --no-config --eval '+version+'
--load my-lib.lisp --eval '(format t "Hello ~a!~&" (my-lib:my-world))'
You can evaluate multiple --eval and --load in a row, they are executed in the order they appear.
You can also evaluate a Lisp file from the Nyxt interface with
the
load-file (Ctrl+O)
command. For
convenience,
load-config-file (unbound)
(re)loads your initialization file.
You can even make scripts. Here is an example foo.lisp:
#!/bin/sh
#|
exec nyxt --script "$0"
|#
;; Your code follows:
(format t "~a~&" +version+)
--eval and --load can be commanded to operate over an existing instance instead of a separate instance that exits immediately.
The
remote-execution-p
of the remote instance must be non-nil:
(define-configuration
browser
((remote-execution-p
t)))
To let know a private instance of Nyxt to load a foo.lisp script and run its
foo
function:
nyxt --profile nosave --remote --load foo.lisp --eval '(foo)' --quit
Note that
--quit
at the end of each Nyxt CLI call here. If you don't provide
--quit
when dealing with a remote instance, it will go into a REPL mode, allowing an
immediate communication with an instance:
nyxt --remote
(echo "~s" (+ 1 2)) ;; Shows '3' in the message area of remote Nyxt
User scripts
#
User scripts
#User scripts are a conventional and lightweight way to run arbitrary JavaScript code on some set of pages/conditions. While not as powerful as either WebExtensions on Lisp-native extensions to Nyxt, those hook into the tenderer inner working and allow you to change the page and JavaScript objects associated to it.
As an example, you can remove navbars from all the pages you visit with this
small configuration snippet (note that you'd need to have
user-script-mode
in your
buffer default-modes
):
(define-configuration
web-buffer
"Enable user-script-mode, if you didn't already."
((default-modes
(pushnew
'nyxt/mode/user-script:user-script-mode %slot-value%
))))
(define-configuration
nyxt/mode/user-script:user-script-mode
((nyxt/mode/user-script:user-scripts
(list
(make-instance
'nyxt/mode/user-script:user-script
:code
"// ==UserScript==
// @name No navbars!
// @description A simple script to remove navbars
// @run-at document-end
// @include http://*/*
// @include https://*/*
// @noframes
// ==/UserScript==
var elem = document.querySelector(\"header\") || document.querySelector(\"nav\");
if (elem) {
elem.parentNode.removeChild(elem);
}"))
:doc "Alternatively, save the code to some file and use
:base-path #p\"/path/to/our/file.user.js\".
Or fetch a remote script with
url (quri:uri \"https://example.com/script.user.js\")")))
Greasemonkey documentation lists all the possible properties that a user script might have. To Nyxt implementation, only those are meaningful:
- @include and
include
- Sets the URL pattern to enable this script for. Follows the pattern
scheme://host/path
, where scheme is either a literal scheme or and asterisk (matching any scheme), and host and path are any valid characters plus asterisks (matching any set of characters) anywhere. - @match
- Same as @include.
- @exclude and
exclude
- Similar to @include, but rather disables the script for the matching pages.
- @noframes and
all-frames-p
- When present, disables the script for all the frames but toplevel ones. When
absent, injects the script everywhere. The Lisp-side
all-frames-p
works in an opposite way. - @run-at and
run-at
- When to run a script. Allowed values: document-start, document-end, document-idle (in Nyxt implementation, same as document-end).
- @require
- Allows including arbitrary JS files hosted on the Internet or loaded from the same place as the script itself. Neat for including some JS libraries, like jQuery.
Headless mode
#
Headless mode
#Similarly to Nyxt's scripting functionality, headless mode runs without a graphical user interface. Possible use-cases for this mode are web scraping, automations and web page analysis.
To enable headless mode, simply start Nyxt with the
--headless
CLI flag and provide a script file to serve as the configuration file:
nyxt --headless --config /path/to/your/headless-config.lisp
Note that you pass it a
configuration file—headless mode is only different from the regular Nyxt functions in that it has
no GUI, and is all the same otherwise, contrary to all the seeming similarities
to the
--script
flag usage.
The example below showcases frequent idioms that are found in the mode's configuration file:
#!/bin/sh
#|
exec nyxt --headless --no-auto-config --profile nosave --config "$0"
|#
(define-configuration
browser
"Disable session restoration to speed up startup and get more reproducible
behavior."
((restore-session-on-startup-p
nil)))
(define-configuration
browser
"Load the URL of Nyxt repository by default in all new buffers.
Alternatively, call buffer-load
in after-startup-hook
."
((default-new-buffer-url
(quri.uri:uri
"https://github.com/atlas-engineer/nyxt"))))
(hooks:on (after-startup-hook *browser*) (browser)
;; Once the page's done loading, do your thing.
(hooks:once-on (buffer-loaded-hook (current-buffer)) (buffer)
;; It's sometimes necessary to sleep, as `buffer-loaded-hook' fires when the
;; page is loaded, which does not mean that all the resources and scripts
;; are done loading yet. Give it some time there.
(sleep 0.5)
;; All the Nyxt reporting happens in headless mode, so you may want to log
;; it with `echo' and `echo-warning'.
(echo "Nyxt GitHub repo open.")
;; Updating the `document-model' so that it includes the most relevant
;; information about the page.
(nyxt:update-document-model)
;; Click the star button.
(nyxt/dom:click-element
(elt (clss:select "[aria-label=\"Star this repository\"]"
(document-model buffer))
0))
(echo "Clicked the star.")
;; It's good tone to `nyxt:quit' after you're done, but if you use nyxt
;; --no-socket, you don't have to. Just be ready for some RAM eating :)
(nyxt:quit)))
The contents of headless-config.lisp feature configuration forms that make Nyxt perform some actions to the opened pages and/or on certain hooks. Things you'd most probably want to put there are:
- Hook bindings, using the
nhooks
library and hooks provided by Nyxt. - Operations on the page. Check the
nyxt/dom
library and thedocument-model
method. - The
document-model
method has a reasonably fresh copy of the page DOM (Document Object Model, reflecting the dynamic structure of the page). It is aPlump
DOM, which means that allPlump
(andCLSS
) functions can be used on it. -
update-document-model
is a function to force DOM re-parsing for the cases when you consider the currentdocument-model
too outdated. -
select
is a CLSS function to find elements using CSS selectors (a terse notation for web page element description). -
clss:ordered-select
is the same asselect
, except it guarantees that all the elements are returned in a depth-first traversal order. -
click-element
to programmatically click a certain element (including the ones returned byselect
.) -
focus-select-element
to focus an input field, for example. -
check-element
to check a checkbox or a radio button. -
select-option-element
to select an option from the<select>
element options.
Additionally, headless mode gracefully interacts with other CLI toggles the Nyxt has:
-
--headless
itself! Notice that you can debug your script by omitting this CLI flag. When you're confident enough about it, put it back in. A good debugging tip, isn't it? -
--no-socket
flag allows starting as many Nyxt instances as your machine can handle. Useful to parallelize computations. -
--profile nosave
to not pollute your history and cache with the script-accessed pages.
Built-in REPL
#
Built-in REPL
#Nyxt has a built-in REPL, available with
repl (unbound)
command.The REPL can be used to try out some code snippets for automation or quickly
make some Lisp calculations. All the packages Nyxt depends on are available in
REPL with convenient nicknames, and all the code is evaluated in
nyxt-user
package.
Once the REPL is open, there's only one input cell visible. This cell, always
present at the bottom of the screen, adds new cells to the multi-pane interface
of Nyxt REPL. You can type in
(print "Hello, Nyxt!")
and press C-return to evaluate the cell. A new cell will appear at the top of the buffer, with
input area containing familiar code, with some
v332 = "Hello, Nyxt!"
variable assignment, and with a verbatim text outputted by your code:
Hello, Nyxt!
This cell-based code evaluation is the basis of the Nyxt REPL. For more features, see
REPL mode documentation
.
Extending the REPL
#
Extending the REPL
#Nyxt REPL is made to be extensible and allow to make custom cell types with their own display and functionality. The two cell types provided by default are:
-
lisp-cell
- and
shell-cell
Both of these serve as examples of cell extension, but it may be more illuminating to create one of a different type from the default ones. A commentary cell, for example—the type of cell one can use as an annotation to other cells.
First, define a new
cell
type:
(define-class
comment-cell (nyxt/mode/repl:cell)
((name "Commentary")) (:export-class-name-p t)
(:export-accessor-names-p t))
There are methods of
cell
that can be redefined for a better display:
-
evaluate
as a function to get results from the cell. -
suggest
for choosing the most intuitive content to paste into the cell. -
render-input
as the one rendering the input area for the cell. -
render-actions
, allowing to render a custom set of actions. - And
render-results
to show cell results (the immediate valuesevaluation
returns) and output (the text printed out whileevaluating
the cell). - And, in case none of those fits well,
render-cell
to override all the rendering code.
The easiest thing is
render-input
: it's already defined as an input field updating the cell
input
at every keypress. The only change to it that is needed for the commentary
cell is to render as a <pre> tag when marked
ready-p
:
(defmethod
nyxt/mode/repl:render-input ((cell comment-cell))
"Render as a pre tag when ready, render as default input otherwise."
(if
(nyxt/mode/repl:ready-p
cell)
(spinneret:with-html-string
(:pre (input cell)))
(call-next-method)))
render-results
is another method useless for comment cell. It can safely return the empty
string:
(defmethod
nyxt/mode/repl:render-results ((cell comment-cell))
(declare (ignore cell))
"")
render-actions
should stay as it is, because it produces an aesthetic set of buttons near the
input. No need to tweak it in this case.
Last but not least,
evaluate
. This method should produce the
results
and
output
of the cell. The REPL infrastructure sets
ready-p
to T when the evaluation ends, which enables the <pre> rendering. Given that
comment cells produce no result
evaluate
can stay empty:
(defmethod
nyxt/mode/repl:evaluate ((cell comment-cell))
(declare (ignore cell)))
After all of these methods are defined in the configuration file and Nyxt restarted,
invoking
repl (unbound)
and pressing the
Add a cell
button will allow to create a new comment cell.
Note that the display of the comment cell is not exactly concise. But making it better is left as an exercise to the reader.
Advanced configuration
#
Advanced configuration
#While
define-configuration
is convenient, it is mostly
restricted to class slot configuration. If you want to do anything else on
class instantiation, you'll have to specialize the
lower-level
customize-instance
generic function. Example:
All classes with metaclass
user-class
call
customize-instance
on instantiation,
after
initialize-instance
:after
. The primary method is reserved
to the user, however the
:after
method is reserved to the Nyxt
core to finalize the instance.
Extensions
#
Extensions
#To install an extension, copy inside the
*extensions-directory*
(default to
~/.local/share/nyxt/extensions
).
Extensions are regular Common Lisp systems.
A catalog of extensions is available in the
document/EXTENSIONS.org
file in the source repository.
Troubleshooting
#
Troubleshooting
#
Debugging and reporting errors
#
Debugging and reporting errors
#If you experience hangs or errors you can reproduce, you can use the
toggle-debug-on-error (unbound)
command to enable Nyxt-native debugger and see the reasons of these. Based on
this information, you can report a bug using
report-bug (unbound)
.
You can also try to start the browser with the
--failsafe
command line option and see if you can reproduce your issue then. If not,
then the issue is most likely due to your configuration, an extension, or some
corrupt data file like the history.
Note that often errors, hangs, and crashes happen on the side of renderer and thus are not visible to the Nyxt-native debugger and fixable on the side of Nyxt. See below.
Bwrap error on initialization (Ubuntu)
#
Bwrap error on initialization (Ubuntu)
#If Nyxt crashes on start due to
bwrap
, then disable or configure the
apparmor
service.
Playing videos
#
Playing videos
#Nyxt delegates video support to third-party plugins.
When using the WebKitGTK backends, GStreamer and its plugins are leveraged. Depending on the video, you will need to install some of the following packages:
- gst-libav
- gst-plugins-bad
- gst-plugins-base
- gst-plugins-good
- gst-plugins-ugly
On Debian-based systems, you might be looking for (adapt the version numbers):
- libgstreamer1.0-0
- gir1.2-gst-plugins-base-1.0
For systems from the Fedora family:
- gstreamer1-devel
- gstreamer1-plugins-base-devel
After the desired plugins have been installed, clear the GStreamer cache at
~/.cache/gstreamer-1.0
and restart Nyxt.
Website crashes
#
Website crashes
#If some websites systematically crash, try to install all the required GStreamer plugins as mentioned in the 'Playing videos' section.
Input method support (CJK, etc.)
#
Input method support (CJK, etc.)
#Depending on your setup, you might have to set some environment variables or run some commands before starting Nyxt, for instance
GTK_IM_MODULE=xim
XMODIFIERS=@im=ibus
ibus --daemonize --replace --xim
You can persist this change by saving the commands in
your
.xprofile
or similar.
HiDPI displays
#
HiDPI displays
#The entire UI may need to be scaled up on HiDPI displays.
When using the WebKitGTK renderer, export the environment
variable below before starting Nyxt. Note that
GDK_DPI_SCALE
(not
to be confused with
GDK_SCALE
) scales text only, so tweaking it
may be undesirable.
export GDK_SCALE=2
nyxt
StumpWM mouse scroll
#
StumpWM mouse scroll
#If the mouse scroll does not work for you, see the StumpWM FAQ for a fix.
Blank WebKitGTK views
#
Blank WebKitGTK views
#When experiencing rendering issues, try to disable compositing as below:
(setf (uiop/os:getenv
"WEBKIT_DISABLE_COMPOSITING_MODE") "1")
Missing cursor icons
#
Missing cursor icons
#If you are having issues with the cursor not changing when
hovering over buttons or links, it might be because Nyxt can't locate your cursor theme.
To fix that, try adding the following to your
.bash_profile
or similar:
export XCURSOR_PATH=${XCURSOR_PATH}:/usr/share/icons
export XCURSOR_PATH=${XCURSOR_PATH}:~/.local/share/icons