Listed below are the current commands, their documentation, and their source. Non-command based features are currently unlisted.
Commands
nyxt-init-time
Return the duration of Nyxt initialization.
(define-command nil
(echo "~,2f seconds" (slot-value *browser* 'init-time)))
load-init-file
Load or reload the init file.
(define-command (&key (init-file (expand-path *init-file-path*)))
(load-lisp init-file :package (find-package :nyxt-user)))
load-file
Load the prompted Lisp file.
(define-command nil
(let ((file-name-input
(prompt-minibuffer :input-prompt "Load file"
:hide-suggestion-count-p t)))
(load-lisp file-name-input)))
start-swank
Start a Swank server that can be connected to, for instance, in Emacs via SLIME. Warning: This allows Nyxt to be controlled remotely, that is, to execute arbitrary code with the privileges of the user running Nyxt. Make sure you understand the security risks associated with this before running this command.
(define-command (&optional (swank-port *swank-port*))
(swank:create-server :port swank-port :dont-close t)
(echo "Swank server started at port ~a" swank-port))
quit-after-clearing-session
Clear session then quit Nyxt.
(define-command nil
(uiop/filesystem:delete-file-if-exists
(expand-path (session-path (current-buffer))))
(quit))
quit
Quit Nyxt.
(define-command nil
(sera:run-hook (before-exit-hook *browser*))
(loop for window in (window-list)
do (ffi-window-delete window))
(ffi-kill-browser *browser*)
(when (socket-thread *browser*)
(ignore-errors (bordeaux-threads:destroy-thread (socket-thread *browser*)))
(let ((socket-path (expand-path *socket-path*)))
(when (uiop/filesystem:file-exists-p socket-path)
(log:info "Deleting socket ~s." socket-path)
(uiop/filesystem:delete-file-if-exists socket-path))))
(unless *keep-alive* (uiop/image:quit 0 nil)))
replace-session-by-name
Delete all the buffers of the current session and restore the one chosen by user.
(define-command nil
(let ((name
(prompt-minibuffer :input-prompt
"The name of the session to replace the current one"
:history
(minibuffer-session-restore-history *browser*)
:suggestion-function
#'session-name-suggestion-filter)))
(when name
(dolist (buffer (buffer-list)) (buffer-delete buffer))
(restore (data-profile (current-buffer))
(make-instance 'session-data-path :basename name :dirname
(dirname (session-path (current-buffer))))))))
restore-session-by-name
Restore the session data from the file named by user input.
(define-command nil
(let ((name
(prompt-minibuffer :input-prompt
"The name of the session to restore" :history
(minibuffer-session-restore-history *browser*)
:suggestion-function
#'session-name-suggestion-filter)))
(when name
(restore (data-profile (current-buffer))
(make-instance 'session-data-path :basename name :dirname
(dirname (session-path (current-buffer))))))))
store-session-by-name
Store the session data (i.e. all the opened buffers) in the file named by user input.
(define-command nil
(let ((name
(prompt-minibuffer :input-prompt "The name to store session with"
:history
(minibuffer-session-restore-history *browser*)
:suggestion-function
#'session-name-suggestion-filter)))
(when name
(store (data-profile (current-buffer))
(make-instance 'session-data-path :dirname
(dirname (session-path (current-buffer)))
:basename name)))))
about
Show the list of contributors.
(define-command nil
(with-current-html-buffer (buffer "*About*" 'base-mode)
(cl-markup:markup (:style (style buffer)) (:h1 "Contributors")
(:p
"Let us know if you've contributed to the development of
Nyxt and would like to be included on this list.")
(:ul (:li "Adom Hartell (@4t0m)")
(:li "Artyom Bologov (@aartaka)")
(:li "John Mercouris (@jmercouris)")
(:li "Pierre Neidhardt (@ambrevar)")
(:li "Solomon Bloch (@noogie13)")
(:li "Vincent Dardel (@vindarel)"))
(:h1 "Supporters")
(:p "Thank you to NLnet for supporting Nyxt!")
(:h1 "Crowdfunding backers")
(:p
"Thank you to all who have supported and made Nyxt possible!")
(:h2 "2018-11 campaign: *NIX Support")
(:h3 "Digital Omnipresence")
(:ul (:li "Alexander.Shendi") (:li "Ashish SHUKLA")
(:li "Christopher Nascone") (:li "dan.girsh")
(:li "Eric Monson") (:li "Jack Randall")
(:li "James Anderson") (:li "liweitian")
(:li "Marco Heisig") (:li "Oluwafemi Agbabiaka")
(:li "pjb") (:li "Robert Krahn") (:li "Robert Uhl")
(:li "1 anonymous"))
(:h3 "Digital Magma")
(:ul (:li "Daniel V") (:li "Jason Hamilton")
(:li "Magnus Nyberg") (:li "Marek Kochanowicz")
(:li "Rich Smith") (:li "Robert Uhl") (:li "simon")
(:li "slade") (:li "Steve Last") (:li "ulf.makestad")
(:li "1 anonymous"))
(:h3 "Digital Immortality")
(:ul (:li "Alexey Abramov") (:li "Are Jensen")
(:li "Joseph Mingrone") (:li "Nikita Poliakov")
(:li "pjb") (:li "Sainath Adapa")
(:li "Spencer Heywood") (:li "Sungjin Chun")
(:li "Tom Delord") (:li "2 anonymous"))
(:h3 "Others")
(:ul (:li "Nicholas Zivkovic") (:li "Pierre Neidhardt")
(:li "Simon Zugmeyer") (:li "vindarel")
(:li "5 anonymous"))
(:h2 "2019-10 campaign: v1.4.0")
(:h3 "Digital Immortality")
(:ul (:li "Tim Johann") (:li "Julien Rousé")
(:li "ebababi") (:li "Emil Oppeln-Bronikowski")
(:li "Fox Kiester") (:li "Stefan Husmann")
(:li "Nils Grunwald") (:li "Florian Adamsky")
(:li "Valentin Atanasov") (:li "Pranav Vats")
(:li "Jörn Gersdorf") (:li "Matt Skinner")
(:li "Jelle Dirk Licht") (:li "Minori Yamashita")
(:li "Hugh Daschbach") (:li "Niklas Carlsson")
(:li "mestelan") (:li "Camille Troillard")
(:li "mace nicolas") (:li "dan.girsh")
(:li "Michael Bruderer") (:li "Patrice Rault")
(:li "Cees de Groot") (:li "Sam Hedin")
(:li "rbarzic") (:li "Jake Waksbaum")
(:li "Lukas Jenks") (:li "Rodrigo Lazo")
(:li "Lucas Sifoni") (:li "Calle Helmertz")
(:li "Kristian Nygaard Jensen") (:li "Robert Uhl")
(:li "Francis Burstall") (:li "Arnaud BEAUD'HUIN")
(:li "Daniel V") (:li "Albin Heimerson")
(:li "Alexander ter Weele") (:li "Jeremy Firth")
(:li "aim") (:li "liweitian") (:li "Philipe Dallaire")
(:li "Travis Brown") (:li "Divan Santana")
(:li "John C Haprian") (:li "Pierrick Maillard")
(:li "Dardel Renaud") (:li "Dardel Renaud")
(:li "Nils Grunwald") (:li "hector")
(:li "Jean Morel") (:li "Jos van Bakel") (:li "slade")
(:li "dietrich ayala") (:li "bacon totem")
(:li "Pierre Neidhardt") (:li "18 anonymous")))))
dashboard
Print a dashboard. Usable as a buffer-fn for make-startup-function.
(define-command nil
(flet ((list-bookmarks (&key (separator " → "))
(loop for bookmark in (get-data (bookmarks-path (current-buffer)))
collect (cl-markup:markup
(:li (title bookmark) separator
(:a :href (object-string (url bookmark))
(object-display (url bookmark)))))))
(list-history (&key (separator " → ") (limit 20))
(let* ((path (history-path (current-buffer)))
(history
(when (get-data path)
(sort (alex:hash-table-values (get-data path))
#'local-time:timestamp> :key #'last-access))))
(loop for item in (sera:take limit history)
collect (cl-markup:markup
(:li (title item)
(unless (str:emptyp (title item)) separator)
(:a :href (object-string (url item))
(object-string (url item)))))))))
(let ((dashboard-style
(cl-css:css
'((body :margin-top 0 :margin-bottom 0) ("a" :color "gray")
("#title" :font-size "400%")
(.section :border-top "solid lightgray" :margin-top "10px"
:overflow "scroll" :min-height "150px")
(".section h3" :color "dimgray")
("#container" :display "flex" :flex-flow "column" :height
"100vh")
("ul" :list-style-type "circle")))))
(with-current-html-buffer (buffer "*Dashboard*" 'base-mode)
(cl-markup:markup (:style (style buffer)) (:style dashboard-style)
(:div :id "container"
(:div :style "height: 210px"
(:h1 :id "title" "Nyxt "
(:span :style "color: lightgray" "browser ☺"))
(:h3
(local-time:format-timestring nil
(local-time:now)
:format
local-time:+rfc-1123-format+))
(:a :class "button" :href
(lisp-url `(restore-session-by-name))
"🗁 Restore Session")
(:a :class "button" :href
(lisp-url `(execute-command))
"⚙ Execute Command")
(:a :class "button" :href (lisp-url `(manual))
"🕮 Manual")
(:a :class "button" :href
"https://nyxt.atlas.engineer/download"
"⇡ Update"))
(:div :class "section" :style "flex: 3"
(:h3 "🏷 " (:b "Bookmarks"))
(:ul (list-bookmarks)))
(:div :class "section" :style "flex: 5"
(:h3 "🗐 " (:b "Recent URLs"))
(:ul (list-history)))))))))
copy-system-information
Save system information into the clipboard.
(define-command nil
(let* ((*print-length* nil)
(nyxt-information
(format nil
(str:concat "Nyxt version: ~a ~%"
"Operating system kernel: ~a ~a~%"
"Lisp implementation: ~a ~a~%"
"Features: ~a~%")
+version+ (software-type) (software-version)
(lisp-implementation-type) (lisp-implementation-version)
*features*)))
(copy-to-clipboard nyxt-information)
(log:info nyxt-information)
(echo "System information copied to clipboard.")))
tutorial
Show the tutorial.
(define-command nil
(with-current-html-buffer (buffer "*Tutorial*" 'nyxt/help-mode:help-mode)
(str:concat
(cl-markup:markup (:style (style buffer)) (:h1 "Nyxt tutorial")
(:p
"The following tutorial introduces the core concepts and the
basic usage. For more details, especially regarding the configuration, see
the "
(:code (command-markup 'manual)) "."))
(tutorial-content))))
manual
Show the manual.
(define-command nil
(with-current-html-buffer (buffer "*Manual*" 'nyxt/help-mode:help-mode)
(str:concat (cl-markup:markup (:style (style buffer))) (manual-content))))
help
Print help information.
(define-command nil
(with-current-html-buffer (buffer "*Help*" 'nyxt/help-mode:help-mode)
(cl-markup:markup (:style (style buffer))
(:style
(cl-css:css
'((:h2 :font-weight 300 :padding-top "10px"))))
(:h1 "Welcome to Nyxt ☺")
(:p
"Attention: Nyxt is under active development. Feel free to "
(:a :href
"https://github.com/atlas-engineer/nyxt/issues"
"report")
" bugs, instabilities or feature wishes.")
(:p
"You can help with Nyxt development by supporting us in various ways:"
(:ul
(:li "Support continuous development on "
(:a :href "https://www.patreon.com/nyxt" "Patreon")
".")
(:li "Spread the word on social media and "
(:a :href "https://github.com/atlas-engineer/nyxt"
"star the project on GitHub")
".")))
(:hr) (:h2 "Quick configuration")
(:p
(:a :class "button" :href
(lisp-url `(common-settings)) "Common settings")
" Switch between Emacs/vi/CUA key bindings, set home page URL, and zoom level.")
(:h2 "Documentation")
(:p
(:a :class "button" :href
(lisp-url `(describe-bindings)) "List bindings")
" List all bindings for the current buffer.")
(:p
(:a :class "button" :href (lisp-url `(tutorial))
"Tutorial")
" An introduction to Nyxt core concepts.")
(:p
(:a :class "button" :href (lisp-url `(manual))
"Manual")
" Full documentation about Nyxt, how it works and how to configure it."))))
list-messages
Show the *Messages* buffer.
(define-command nil
(with-current-html-buffer (buffer "*Messages*"
'nyxt/message-mode:message-mode)
(cl-markup:markup (:style (style buffer)) (:h1 "Messages")
(:a :class "button" :href (lisp-url '(list-messages))
"Update")
(:a :class "button" :href
(lisp-url '(nyxt/message-mode:clear-messages)
'(list-messages))
"Clear")
(:ul
(loop for message in (reverse
(messages-content *browser*))
collect (cl-markup:markup (:li message)))))))
nyxt-version
Version number of this version of Nyxt. The version number is stored in the clipboard.
(define-command nil
(trivial-clipboard:text +version+)
(echo "Version ~a" +version+))
describe-key
Display binding of user-inputted keys.
(define-command nil
(setf (input-dispatcher (current-window)) #'describe-key-dispatch-input)
(echo "Press a key sequence to describe (cancel with 'escape escape'):"))
describe-bindings
Show a buffer with the list of all known bindings for the current buffer.
(define-command nil
(with-current-html-buffer (buffer "*Help-bindings"
'nyxt/help-mode:help-mode)
(cl-markup:markup (:style (style buffer)) (:h1 "Bindings")
(:p
(loop for keymap in (current-keymaps (current-buffer))
collect (cl-markup:markup
(:h3 (keymap:name keymap))
(:table
(loop for keyspec being the hash-keys in (keymap:keymap-with-parents->map
keymap) using (hash-value
bound-value)
collect (cl-markup:markup
(:tr (:td keyspec)
(:td
(string-downcase
bound-value))))))))))))
common-settings
Configure a set of frequently used settings.
(define-command nil
(with-current-html-buffer (buffer "*Settings*" 'nyxt/help-mode:help-mode)
(cl-markup:markup (:style (style buffer)) (:h1 "Common Settings")
(:p "Set the values for frequently configured
settings. Changes made will apply to newly created
buffers.")
(:h2 "Keybinding style")
(:p
(:a :class "button" :href
(lisp-url
`(configure-slot 'default-modes '(buffer web-buffer)
:value '%slot-default)
`(nyxt/emacs-mode:emacs-mode :activate nil)
`(nyxt/vi-mode:vi-normal-mode :activate nil))
"Use default (CUA)"))
(:p
(:a :class "button" :href
(lisp-url
`(configure-slot 'default-modes '(buffer web-buffer)
:value
'(append '(emacs-mode)
%slot-default))
`(nyxt/emacs-mode:emacs-mode :activate t)
`(nyxt/vi-mode:vi-normal-mode :activate nil))
"Use Emacs"))
(:p
(:a :class "button" :href
(lisp-url
`(configure-slot 'default-modes '(buffer web-buffer)
:value
'(append '(vi-normal-mode)
%slot-default))
`(nyxt/vi-mode:vi-normal-mode :activate t)
`(nyxt/emacs-mode:emacs-mode :activate nil))
"Use vi"))
(:h2 "Default new buffer URL")
(:a :class "button" :href
(lisp-url
`(configure-slot 'default-new-buffer-url 'web-buffer
:type 'string))
"Set default new buffer URL")
(:h2 "Default zoom ratio")
(:a :class "button" :href
(lisp-url
`(configure-slot 'current-zoom-ratio 'buffer))
"Set default zoom ratio"))))
describe-slot
Inspect a slot and show it in a help buffer.
(define-command nil
(let* ((input
(prompt-minibuffer :input-prompt "Describe slot"
:suggestion-function (slot-suggestion-filter))))
(with-current-html-buffer (buffer
(str:concat "*Help-"
(symbol-name (name input)) "*")
'nyxt/help-mode:help-mode)
(str:concat (cl-markup:markup (:style (style buffer)))
(describe-slot* (name input) (class-sym input)
:mention-class-p t)))))
describe-class
Inspect a class and show it in a help buffer.
(define-command nil
(let* ((input
(class-suggestion-name
(prompt-minibuffer :input-prompt "Describe class"
:suggestion-function
(class-suggestion-filter)))))
(with-current-html-buffer (buffer
(str:concat "*Help-" (symbol-name input) "*")
'nyxt/help-mode:help-mode)
(let* ((slots (class-public-slots input))
(slot-descs
(apply #'str:concat
(mapcar (alex:rcurry #'describe-slot* input) slots))))
(str:concat
(cl-markup:markup (:style (style buffer)) (:h1 (symbol-name input))
(:p (:pre (documentation input 'type)))
(:h2 "Slots:"))
slot-descs)))))
describe-command
Inspect a command and show it in a help buffer. A command is a special kind of function that can be called with `execute-command' and can be bound to a key.
(define-command nil
(let ((input
(prompt-minibuffer :input-prompt "Describe command"
:suggestion-function
(command-suggestion-filter))))
(describe-command* input)))
describe-function
Inspect a function and show it in a help buffer. For generic functions, describe all the methods.
(define-command nil
(let ((input
(prompt-minibuffer :input-prompt "Describe function"
:suggestion-function
(function-suggestion-filter))))
(setf input (function-suggestion-name input))
(flet ((method-desc (method)
(cl-markup:markup
(:h1 (symbol-name input) " "
(write-to-string (sb-mop:method-specializers method)))
(:pre (documentation method 't)) (:h2 "Argument list")
(:p (write-to-string (sb-mop:method-lambda-list method))))))
(with-current-html-buffer (buffer
(str:concat "*Help-" (symbol-name input)
"*")
'nyxt/help-mode:help-mode)
(if (typep (symbol-function input) 'generic-function)
(apply #'str:concat
(mapcar #'method-desc
(sb-mop:generic-function-methods
(symbol-function input))))
(str:concat
(cl-markup:markup (:style (style buffer))
(:h1 (format nil "~s" input)
(when (macro-function input) " (macro)"))
(:pre (documentation input 'function))
(:h2 "Argument list")
(:p
(write-to-string
(metabang.moptilities:function-arglist
input))))
(unless (macro-function input)
(cl-markup:markup (:h2 "Type")
(:p
(format nil "~s"
(sb-introspect:function-type
input)))))))))))
describe-variable
Inspect a variable and show it in a help buffer.
(define-command nil
(let* ((input
(variable-suggestion-name
(prompt-minibuffer :suggestion-function
(variable-suggestion-filter) :input-prompt
"Describe variable"))))
(with-current-html-buffer (buffer
(str:concat "*Help-" (symbol-name input) "*")
'nyxt/help-mode:help-mode)
(cl-markup:markup (:style (style buffer)) (:h1 (format nil "~s" input))
(:pre (documentation input 'variable))
(:h2 "Current Value:")
(:pre (object-display (symbol-value input)))))))
unzoom-page
Unzoom the page.
(define-command (&key (buffer (current-buffer))
(ratio (zoom-ratio-default (current-buffer))))
(pflet ((nyxt/web-mode::unzoom nil
(parenscript:lisp
(setf (current-zoom-ratio (current-buffer)) ratio))
(setf (parenscript:chain nyxt/web-mode::document
nyxt/web-mode::body style
nyxt/web-mode::zoom)
(parenscript:lisp ratio))))
(with-current-buffer buffer
(nyxt/web-mode::unzoom))))
zoom-out-page
Zoom out the current page.
(define-command (&key (buffer (current-buffer)))
(pflet ((nyxt/web-mode::zoom-out nil
(parenscript:lisp
(nyxt/web-mode::ensure-zoom-ratio-range #'- (current-buffer)))
(let ((style
(parenscript:chain nyxt/web-mode::document
nyxt/web-mode::body style)))
(setf (parenscript:@ style nyxt/web-mode::zoom)
(parenscript:lisp
(current-zoom-ratio (current-buffer)))))))
(with-current-buffer buffer
(nyxt/web-mode::zoom-out))))
zoom-in-page
Zoom in the current page.
(define-command (&key (buffer (current-buffer)))
(pflet ((nyxt/web-mode::zoom nil
(parenscript:lisp
(nyxt/web-mode::ensure-zoom-ratio-range #'+ (current-buffer)))
(let ((style
(parenscript:chain nyxt/web-mode::document
nyxt/web-mode::body style)))
(setf (parenscript:@ style nyxt/web-mode::zoom)
(parenscript:lisp
(current-zoom-ratio (current-buffer)))))))
(with-current-buffer buffer
(nyxt/web-mode::zoom))))
spell-check-suggest-word
Suggest a spelling for a given word.
(define-command (&key nyxt/web-mode::word)
(let ((nyxt/web-mode::selected-word
(prompt-minibuffer :input-buffer nyxt/web-mode::word :input-prompt
"Suggest spelling (3+ characters)"
:suggestion-function
'nyxt/web-mode::enchant-suggestion)))
(trivial-clipboard:text nyxt/web-mode::selected-word)
(echo "Word copied to clipboard.")))
spell-check-word-at-cursor
Spell check the word at cursor.
(define-command nil
(let* ((nyxt/web-mode::contents
(nyxt/input-edit-mode::active-input-area-content))
(nyxt/web-mode::cursor-position
(nyxt/input-edit-mode::active-input-area-cursor)))
(let ((nyxt/web-mode::text-buffer
(make-instance 'text-buffer:text-buffer))
(nyxt/web-mode::cursor (make-instance 'text-buffer:cursor)))
(cluffer:attach-cursor nyxt/web-mode::cursor
nyxt/web-mode::text-buffer)
(text-buffer::insert-string nyxt/web-mode::cursor
nyxt/web-mode::contents)
(setf (cluffer:cursor-position nyxt/web-mode::cursor)
(parse-integer nyxt/web-mode::cursor-position))
(nyxt/web-mode::spell-check-prompt
(text-buffer::word-at-cursor nyxt/web-mode::cursor)))))
spell-check-highlighted-word
Spell check a highlighted word. If a word is incorrectly spelled, pull up a prompt of suggestions.
(define-command nil
(let ((nyxt/web-mode::word (%copy)))
(nyxt/web-mode::spell-check-prompt nyxt/web-mode::word)))
spell-check-word
Spell check a word.
(define-command (&key (nyxt/web-mode::word nil nyxt/web-mode::word-supplied-p))
(if nyxt/web-mode::word-supplied-p
(enchant:with-dict (nyxt/web-mode::lang
(spell-check-language *browser*))
(enchant:dict-check nyxt/web-mode::lang nyxt/web-mode::word))
(let ((nyxt/web-mode::word
(prompt-minibuffer :input-prompt "Spell check word")))
(if (enchant:with-dict (nyxt/web-mode::lang
(spell-check-language *browser*))
(enchant:dict-check nyxt/web-mode::lang nyxt/web-mode::word))
(echo "~s spelled correctly." nyxt/web-mode::word)
(echo "~s is incorrect." nyxt/web-mode::word)))))
remove-search-hints
Remove all search hints.
(define-command nil
(nyxt/web-mode::%remove-search-hints))
search-buffers
Show a prompt in the minibuffer that allows to choose one or more buffers, and then start a search prompt that searches over the selected buffer(s).
(define-command (&key
(nyxt/web-mode::case-sensitive-p nil
nyxt/web-mode::explicit-case-p))
(let ((buffers
(prompt-minibuffer :input-prompt "Search buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(apply #'nyxt/web-mode::search-over-buffers buffers
(if nyxt/web-mode::explicit-case-p
`(:case-sensitive-p ,nyxt/web-mode::case-sensitive-p)
'nil))))
search-buffer
Start a search on the current buffer.
(define-command (&key
(nyxt/web-mode::case-sensitive-p nil
nyxt/web-mode::explicit-case-p))
(apply #'nyxt/web-mode::search-over-buffers (list (current-buffer))
(if nyxt/web-mode::explicit-case-p
`(:case-sensitive-p ,nyxt/web-mode::case-sensitive-p)
'nil)))
scroll-page-up
Scroll up by one page height.
(define-command nil
(pflet ((nyxt/web-mode:scroll-page-up nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
0
(*
(parenscript:lisp
(page-scroll-ratio
(current-buffer)))
(-
(parenscript:@
window
nyxt/web-mode::inner-height)))))))
(nyxt/web-mode:scroll-page-up)))
scroll-page-down
Scroll down by one page height.
(define-command nil
(pflet ((nyxt/web-mode:scroll-page-down nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
0
(*
(parenscript:lisp
(page-scroll-ratio
(current-buffer)))
(parenscript:@
window
nyxt/web-mode::inner-height))))))
(nyxt/web-mode:scroll-page-down)))
scroll-right
Scroll right the current page. The amount scrolled is determined by the buffer's `horizontal-scroll-distance'.
(define-command (&key
(horizontal-scroll-distance
(horizontal-scroll-distance (current-buffer))))
(pflet ((nyxt/web-mode:scroll-right nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
(parenscript:lisp
horizontal-scroll-distance)
0))))
(nyxt/web-mode:scroll-right)))
scroll-left
Scroll left the current page. The amount scrolled is determined by the buffer's `horizontal-scroll-distance'.
(define-command (&key
(horizontal-scroll-distance
(horizontal-scroll-distance (current-buffer))))
(pflet ((nyxt/web-mode:scroll-left nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
(parenscript:lisp
(-
horizontal-scroll-distance))
0))))
(nyxt/web-mode:scroll-left)))
scroll-up
Scroll up the current page. The amount scrolled is determined by the buffer's `scroll-distance'.
(define-command (&key (scroll-distance (scroll-distance (current-buffer))))
(pflet ((nyxt/web-mode:scroll-up nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
0
(parenscript:lisp
(-
scroll-distance))))))
(nyxt/web-mode:scroll-up)))
scroll-down
Scroll down the current page. The amount scrolled is determined by the buffer's `scroll-distance'.
(define-command (&key (scroll-distance (scroll-distance (current-buffer))))
(pflet ((nyxt/web-mode:scroll-down nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
0
(parenscript:lisp
scroll-distance)))))
(nyxt/web-mode:scroll-down)))
scroll-to-bottom
Scroll to the bottom of the current page.
(define-command nil
(pflet ((nyxt/web-mode:scroll-to-bottom nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
0
(parenscript:chain
nyxt/web-mode::document
nyxt/web-mode::document-element
nyxt/web-mode::scroll-height)))))
(nyxt/web-mode:scroll-to-bottom)))
scroll-to-top
Scroll to the top of the current page.
(define-command nil
(pflet ((nyxt/web-mode:scroll-to-top nil
(parenscript:chain window
(nyxt/web-mode::scroll-by
0
(-
(parenscript:chain
nyxt/web-mode::document
nyxt/web-mode::document-element
nyxt/web-mode::scroll-height))))))
(nyxt/web-mode:scroll-to-top)))
jump-to-heading
Jump to a particular heading, of type h1, h2, h3, h4, h5, or h6.
(define-command nil
(let* ((nyxt/web-mode::headings (nyxt/web-mode::get-headings))
(nyxt/web-mode::heading
(prompt-minibuffer :input-prompt "Jump to heading"
:suggestion-function
(lambda (minibuffer)
(fuzzy-match (input-buffer minibuffer)
(nyxt/web-mode::make-headings
(json:decode-json-from-string
nyxt/web-mode::headings)))))))
(nyxt/web-mode::paren-jump-to-heading :heading-inner-text
(nyxt/web-mode::inner-text
nyxt/web-mode::heading))))
select-previous-follow
Select previous entry in minibuffer and focus the referencing hint/match if there is one such.
(define-command (&optional (minibuffer (current-minibuffer)))
(nyxt/minibuffer-mode:select-previous minibuffer)
(nyxt/web-mode::update-selection-highlight-hint :follow t :scroll t))
select-next-follow
Select next entry in minibuffer and focus the referencing hint/match if there is one such.
(define-command (&optional (minibuffer (current-minibuffer)))
(nyxt/minibuffer-mode:select-next minibuffer)
(nyxt/web-mode::update-selection-highlight-hint :follow t :scroll t))
toggle-hints-transparency
Toggle the on-screen element hints transparency.
(define-command (&key (buffer (current-buffer)))
(pflet ((nyxt/minibuffer-mode::toggle-transparent nil
(defun nyxt/minibuffer-mode::qsa
(nyxt/minibuffer-mode::context
nyxt/minibuffer-mode::selector)
"Alias of document.querySelectorAll"
(parenscript:chain nyxt/minibuffer-mode::context
(nyxt/minibuffer-mode::query-selector-all
nyxt/minibuffer-mode::selector)))
(dolist
(nyxt/minibuffer-mode::element
(nyxt/minibuffer-mode::qsa nyxt/minibuffer-mode::document
".nyxt-hint"))
(if (or
(=
(parenscript:chain nyxt/minibuffer-mode::element style
nyxt/minibuffer-mode::opacity)
"1")
(=
(parenscript:chain nyxt/minibuffer-mode::element style
nyxt/minibuffer-mode::opacity)
""))
(setf (parenscript:chain nyxt/minibuffer-mode::element style
nyxt/minibuffer-mode::opacity)
"0.2")
(setf (parenscript:chain nyxt/minibuffer-mode::element style
nyxt/minibuffer-mode::opacity)
"1.0")))))
(with-current-buffer buffer
(nyxt/minibuffer-mode::toggle-transparent))))
element-hint-mode
Minibuffer mode for setting the tag of a bookmark.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command ELEMENT-HINT-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/minibuffer-mode:element-hint-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/minibuffer-mode:user-element-hint-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/minibuffer-mode:element-hint-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/minibuffer-mode:element-hint-mode))))
buffer)
download-hint-url
Download the file under the URL(s) hinted by the user.
(define-command (&key nyxt/web-mode::annotate-visible-only-p)
(nyxt/web-mode::query-hints "Download link URL"
(lambda (nyxt/web-mode::selected-links)
(loop nyxt/web-mode::for nyxt/web-mode::link nyxt/web-mode::in nyxt/web-mode::selected-links
do (download
(quri.uri:uri
(url nyxt/web-mode::link))) (sleep
0.25))
(list-downloads))
:multi-selection-p t :annotate-visible-only-p
nyxt/web-mode::annotate-visible-only-p))
bookmark-hint
Show link hints on screen, and allow the user to bookmark one
(define-command nil
(let* ((nyxt/web-mode::elements-json (nyxt/web-mode::add-element-hints))
(nyxt/web-mode::result
(prompt-minibuffer :input-prompt "Bookmark hint" :default-modes
'(nyxt/web-mode::element-hint-mode
nyxt/web-mode::minibuffer-mode)
:history nil :suggestion-function
(nyxt/web-mode::hint-suggestion-filter
(nyxt/web-mode::elements-from-json
nyxt/web-mode::elements-json))
:cleanup-function
(lambda ()
(nyxt/web-mode::remove-element-hints))))
(tags
(prompt-minibuffer :input-prompt "Space-separated tag(s)"
:default-modes
'(set-tag-mode nyxt/web-mode::minibuffer-mode)
:input-buffer
(url-bookmark-tags
(quri.uri:uri (url nyxt/web-mode::result)))
:suggestion-function (tag-suggestion-filter))))
(when nyxt/web-mode::result
(bookmark-add (quri.uri:uri (url nyxt/web-mode::result)) :tags tags))))
copy-hint-url
Show a set of element hints, and copy the URL of the user inputted one.
(define-command (&key nyxt/web-mode::annotate-visible-only-p)
(nyxt/web-mode::query-hints "Copy element URL"
'nyxt/web-mode::%copy-hint-url
:annotate-visible-only-p
nyxt/web-mode::annotate-visible-only-p))
follow-hint-new-buffer-focus
Show a set of element hints, and open the user inputted one in a new visible active buffer.
(define-command (&key nyxt/web-mode::annotate-visible-only-p)
(nyxt/web-mode::query-hints "Go to element in new buffer"
(lambda (nyxt/web-mode::result)
(nyxt/web-mode::%follow-hint-new-buffer-focus
(first nyxt/web-mode::result))
(mapcar
#'nyxt/web-mode::%follow-hint-new-buffer
(rest nyxt/web-mode::result)))
:multi-selection-p t :annotate-visible-only-p
nyxt/web-mode::annotate-visible-only-p))
follow-hint-new-buffer
Show a set of element hints, and open the user inputted one in a new buffer (not set to visible active buffer).
(define-command (&key nyxt/web-mode::annotate-visible-only-p)
(nyxt/web-mode::query-hints "Open element in new buffer"
(lambda (nyxt/web-mode::result)
(mapcar
#'nyxt/web-mode::%follow-hint-new-buffer
nyxt/web-mode::result))
:multi-selection-p t :annotate-visible-only-p
nyxt/web-mode::annotate-visible-only-p))
follow-hint
Show a set of element hints, and go to the user inputted one in the currently active buffer.
(define-command (&key nyxt/web-mode::annotate-visible-only-p)
(nyxt/web-mode::query-hints "Go to element" 'nyxt/web-mode::%follow-hint
:annotate-visible-only-p
nyxt/web-mode::annotate-visible-only-p))
input-edit-mode
Mode for editing input areas in HTML. Overrides many of the bindings in other modes, so you will have to disable/enable it as necessary.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command INPUT-EDIT-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/input-edit-mode:input-edit-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/input-edit-mode:user-input-edit-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/input-edit-mode:input-edit-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/input-edit-mode:input-edit-mode))))
buffer)
delete-forwards-word
Delete forwards a word.
(define-command nil
(nyxt/input-edit-mode::with-input-area (nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(nyxt/input-edit-mode::with-text-buffer (nyxt/input-edit-mode::text-buffer
nyxt/input-edit-mode::cursor
nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(text-buffer::delete-forward-word nyxt/input-edit-mode::cursor)
(nyxt/input-edit-mode::set-active-input-area-content
(text-buffer::string-representation nyxt/input-edit-mode::text-buffer))
(nyxt/input-edit-mode::set-active-input-area-cursor
(cluffer:cursor-position nyxt/input-edit-mode::cursor)
(cluffer:cursor-position nyxt/input-edit-mode::cursor)))))
delete-backwards-word
Delete backwards a word.
(define-command nil
(nyxt/input-edit-mode::with-input-area (nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(nyxt/input-edit-mode::with-text-buffer (nyxt/input-edit-mode::text-buffer
nyxt/input-edit-mode::cursor
nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(text-buffer::delete-backward-word nyxt/input-edit-mode::cursor)
(nyxt/input-edit-mode::set-active-input-area-content
(text-buffer::string-representation nyxt/input-edit-mode::text-buffer))
(nyxt/input-edit-mode::set-active-input-area-cursor
(cluffer:cursor-position nyxt/input-edit-mode::cursor)
(cluffer:cursor-position nyxt/input-edit-mode::cursor)))))
delete-backwards
Delete character before cursor.
(define-command nil
(nyxt/input-edit-mode::with-input-area (nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(nyxt/input-edit-mode::with-text-buffer (nyxt/input-edit-mode::text-buffer
nyxt/input-edit-mode::cursor
nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(text-buffer::delete-item-backward nyxt/input-edit-mode::cursor)
(nyxt/input-edit-mode::set-active-input-area-content
(text-buffer::string-representation nyxt/input-edit-mode::text-buffer))
(nyxt/input-edit-mode::set-active-input-area-cursor
(cluffer:cursor-position nyxt/input-edit-mode::cursor)
(cluffer:cursor-position nyxt/input-edit-mode::cursor)))))
delete-forwards
Delete character after cursor.
(define-command nil
(nyxt/input-edit-mode::with-input-area (nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(nyxt/input-edit-mode::with-text-buffer (nyxt/input-edit-mode::text-buffer
nyxt/input-edit-mode::cursor
nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(text-buffer::delete-item-forward nyxt/input-edit-mode::cursor)
(nyxt/input-edit-mode::set-active-input-area-content
(text-buffer::string-representation nyxt/input-edit-mode::text-buffer))
(nyxt/input-edit-mode::set-active-input-area-cursor
(cluffer:cursor-position nyxt/input-edit-mode::cursor)
(cluffer:cursor-position nyxt/input-edit-mode::cursor)))))
cursor-backwards-word
Move cursor backwards a word.
(define-command nil
(nyxt/input-edit-mode::with-input-area (nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(nyxt/input-edit-mode::with-text-buffer (nyxt/input-edit-mode::text-buffer
nyxt/input-edit-mode::cursor
nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(text-buffer::move-backward-word nyxt/input-edit-mode::cursor
:conservative-word-move
(conservative-word-move
(current-buffer)))
(nyxt/input-edit-mode::set-active-input-area-cursor
(cluffer:cursor-position nyxt/input-edit-mode::cursor)
(cluffer:cursor-position nyxt/input-edit-mode::cursor)))))
cursor-forwards-word
Move cursor forwards a word.
(define-command nil
(nyxt/input-edit-mode::with-input-area (nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(nyxt/input-edit-mode::with-text-buffer (nyxt/input-edit-mode::text-buffer
nyxt/input-edit-mode::cursor
nyxt/input-edit-mode::contents
nyxt/input-edit-mode::cursor-position)
(text-buffer::move-forward-word nyxt/input-edit-mode::cursor
:conservative-word-move
(conservative-word-move
(current-buffer)))
(nyxt/input-edit-mode::set-active-input-area-cursor
(cluffer:cursor-position nyxt/input-edit-mode::cursor)
(cluffer:cursor-position nyxt/input-edit-mode::cursor)))))
cursor-backwards
Move cursor backwards by one element.
(define-command nil
(let* ((nyxt/input-edit-mode::cursor-position
(nyxt/input-edit-mode::active-input-area-cursor)))
(let ((nyxt/input-edit-mode::new-position
(- (parse-integer nyxt/input-edit-mode::cursor-position) 1)))
(nyxt/input-edit-mode::set-active-input-area-cursor
nyxt/input-edit-mode::new-position
nyxt/input-edit-mode::new-position))))
cursor-forwards
Move cursor forward by one element.
(define-command nil
(let* ((nyxt/input-edit-mode::cursor-position
(nyxt/input-edit-mode::active-input-area-cursor)))
(let ((nyxt/input-edit-mode::new-position
(+ (parse-integer nyxt/input-edit-mode::cursor-position) 1)))
(nyxt/input-edit-mode::set-active-input-area-cursor
nyxt/input-edit-mode::new-position
nyxt/input-edit-mode::new-position))))
darken
Darken the page.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"javascript:document.querySelectorAll('*').forEach(e=>e.setAttribute('style','background-color:#222 !important;background-image:none !important;color:#'+(/^A|BU/.test(e.tagName)?'36c;text-decoration:underline;':'eee;')+e.getAttribute('style')))"))
invert-color
Invert the color of the web page.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(d=>{var css=`:root{background-color:#fefefe;filter:invert(100%)}*{background-color:inherit}img:not([src*=\".svg\"]),video{filter: invert(100%)}`,style,id=\"dark-theme-snippet\",ee=d.getElementById(id);if(null!=ee)ee.parentNode.removeChild(ee);else {style = d.createElement('style');style.type=\"text/css\";style.id=id;if(style.styleSheet)style.styleSheet.cssText=css;else style.appendChild(d.createTextNode(css));(d.head||d.querySelector('head')).appendChild(style)}})(document)"))
decrease-brightness
Decrease the brightness of the web page.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){function RGBtoHSL(RGBColor){with(Math){var R,G,B;var cMax,cMin;var sum,diff;var Rdelta,Gdelta,Bdelta;var H,L,S;R=RGBColor[0];G=RGBColor[1];B=RGBColor[2];cMax=max(max(R,G),B);cMin=min(min(R,G),B);sum=cMax+cMin;diff=cMax-cMin;L=sum/2;if(cMax==cMin){S=0;H=0;}else{if(L<=(1/2))S=diff/sum;else S=diff/(2-sum);Rdelta=R/6/diff;Gdelta=G/6/diff;Bdelta=B/6/diff;if(R==cMax)H=Gdelta-Bdelta;else if(G==cMax)H=(1/3)+Bdelta-Rdelta;else H=(2/3)+Rdelta-Gdelta;if(H<0)H+=1;if(H>1)H-=1;}return[H,S,L];}}function getRGBColor(node,prop){var rgb=getComputedStyle(node,null).getPropertyValue(prop);var r,g,b;if(/rgb((d+),s(d+),s(d+))/.exec(rgb)){r=parseInt(RegExp.$1,10);g=parseInt(RegExp.$2,10);b=parseInt(RegExp.$3,10);return[r/255,g/255,b/255];}return rgb;}function hslToCSS(hsl){return \"hsl(\"+Math.round(hsl[0]*360)+\", \"+Math.round(hsl[1]*100)+\"%, \"+Math.round(hsl[2]*100)+\"%)\";}var props=[\"color\",\"background-color\",\"border-left-color\",\"border-right-color\",\"border-top-color\",\"border-bottom-color\"];var props2=[\"color\",\"backgroundColor\",\"borderLeftColor\",\"borderRightColor\",\"borderTopColor\",\"borderBottomColor\"];if(typeof getRGBColor(document.documentElement,\"background-color\")==\"string\")document.documentElement.style.backgroundColor=\"white\";revl(document.documentElement);function revl(n){var i,x,color,hsl;if(n.nodeType==Node.ELEMENT_NODE){for(i=0;x=n.childNodes[i];++i)revl(x);for(i=0;x=props[i];++i){color=getRGBColor(n,x);if(typeof(color)!=\"string\"){hsl=RGBtoHSL(color);hsl[2] = Math.pow(hsl[2], 6/5);n.style[props2[i]]=hslToCSS(hsl);}}}}})()"))
increase-brightness
Increase the brightness of the web page.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){function RGBtoHSL(RGBColor){with(Math){var R,G,B;var cMax,cMin;var sum,diff;var Rdelta,Gdelta,Bdelta;var H,L,S;R=RGBColor[0];G=RGBColor[1];B=RGBColor[2];cMax=max(max(R,G),B);cMin=min(min(R,G),B);sum=cMax+cMin;diff=cMax-cMin;L=sum/2;if(cMax==cMin){S=0;H=0;}else{if(L<=(1/2))S=diff/sum;else S=diff/(2-sum);Rdelta=R/6/diff;Gdelta=G/6/diff;Bdelta=B/6/diff;if(R==cMax)H=Gdelta-Bdelta;else if(G==cMax)H=(1/3)+Bdelta-Rdelta;else H=(2/3)+Rdelta-Gdelta;if(H<0)H+=1;if(H>1)H-=1;}return[H,S,L];}}function getRGBColor(node,prop){var rgb=getComputedStyle(node,null).getPropertyValue(prop);var r,g,b;if(/rgb((d+),s(d+),s(d+))/.exec(rgb)){r=parseInt(RegExp.$1,10);g=parseInt(RegExp.$2,10);b=parseInt(RegExp.$3,10);return[r/255,g/255,b/255];}return rgb;}function hslToCSS(hsl){return \"hsl(\"+Math.round(hsl[0]*360)+\", \"+Math.round(hsl[1]*100)+\"%, \"+Math.round(hsl[2]*100)+\"%)\";}var props=[\"color\",\"background-color\",\"border-left-color\",\"border-right-color\",\"border-top-color\",\"border-bottom-color\"];var props2=[\"color\",\"backgroundColor\",\"borderLeftColor\",\"borderRightColor\",\"borderTopColor\",\"borderBottomColor\"];if(typeof getRGBColor(document.documentElement,\"background-color\")==\"string\")document.documentElement.style.backgroundColor=\"white\";revl(document.documentElement);function revl(n){var i,x,color,hsl;if(n.nodeType==Node.ELEMENT_NODE){for(i=0;x=n.childNodes[i];++i)revl(x);for(i=0;x=props[i];++i){color=getRGBColor(n,x);if(typeof(color)!=\"string\"){hsl=RGBtoHSL(color);hsl[2] = Math.pow(hsl[2], 5/6);n.style[props2[i]]=hslToCSS(hsl);}}}}})()"))
hue-shift-negative
Shift the colors of the web page with a negative hue.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){function RGBtoHSL(RGBColor){with(Math){var R,G,B;var cMax,cMin;var sum,diff;var Rdelta,Gdelta,Bdelta;var H,L,S;R=RGBColor[0];G=RGBColor[1];B=RGBColor[2];cMax=max(max(R,G),B);cMin=min(min(R,G),B);sum=cMax+cMin;diff=cMax-cMin;L=sum/2;if(cMax==cMin){S=0;H=0;}else{if(L<=(1/2))S=diff/sum;else S=diff/(2-sum);Rdelta=R/6/diff;Gdelta=G/6/diff;Bdelta=B/6/diff;if(R==cMax)H=Gdelta-Bdelta;else if(G==cMax)H=(1/3)+Bdelta-Rdelta;else H=(2/3)+Rdelta-Gdelta;if(H<0)H+=1;if(H>1)H-=1;}return[H,S,L];}}function getRGBColor(node,prop){var rgb=getComputedStyle(node,null).getPropertyValue(prop);var r,g,b;if(/rgb((d+),s(d+),s(d+))/.exec(rgb)){r=parseInt(RegExp.$1,10);g=parseInt(RegExp.$2,10);b=parseInt(RegExp.$3,10);return[r/255,g/255,b/255];}return rgb;}function hslToCSS(hsl){return \"hsl(\"+Math.round(hsl[0]*360)+\", \"+Math.round(hsl[1]*100)+\"%, \"+Math.round(hsl[2]*100)+\"%)\";}var props=[\"color\",\"background-color\",\"border-left-color\",\"border-right-color\",\"border-top-color\",\"border-bottom-color\"];var props2=[\"color\",\"backgroundColor\",\"borderLeftColor\",\"borderRightColor\",\"borderTopColor\",\"borderBottomColor\"];if(typeof getRGBColor(document.documentElement,\"background-color\")==\"string\")document.documentElement.style.backgroundColor=\"white\";revl(document.documentElement);function revl(n){var i,x,color,hsl;if(n.nodeType==Node.ELEMENT_NODE){for(i=0;x=n.childNodes[i];++i)revl(x);for(i=0;x=props[i];++i){color=getRGBColor(n,x);if(typeof(color)!=\"string\"){hsl=RGBtoHSL(color);hsl[0] = (hsl[0] + 23/24) % 1;n.style[props2[i]]=hslToCSS(hsl);}}}}})()"))
hue-shift-positive
Shift the colors of the web page with a positive hue.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){function RGBtoHSL(RGBColor){with(Math){var R,G,B;var cMax,cMin;var sum,diff;var Rdelta,Gdelta,Bdelta;var H,L,S;R=RGBColor[0];G=RGBColor[1];B=RGBColor[2];cMax=max(max(R,G),B);cMin=min(min(R,G),B);sum=cMax+cMin;diff=cMax-cMin;L=sum/2;if(cMax==cMin){S=0;H=0;}else{if(L<=(1/2))S=diff/sum;else S=diff/(2-sum);Rdelta=R/6/diff;Gdelta=G/6/diff;Bdelta=B/6/diff;if(R==cMax)H=Gdelta-Bdelta;else if(G==cMax)H=(1/3)+Bdelta-Rdelta;else H=(2/3)+Rdelta-Gdelta;if(H<0)H+=1;if(H>1)H-=1;}return[H,S,L];}}function getRGBColor(node,prop){var rgb=getComputedStyle(node,null).getPropertyValue(prop);var r,g,b;if(/rgb((d+),s(d+),s(d+))/.exec(rgb)){r=parseInt(RegExp.$1,10);g=parseInt(RegExp.$2,10);b=parseInt(RegExp.$3,10);return[r/255,g/255,b/255];}return rgb;}function hslToCSS(hsl){return \"hsl(\"+Math.round(hsl[0]*360)+\", \"+Math.round(hsl[1]*100)+\"%, \"+Math.round(hsl[2]*100)+\"%)\";}var props=[\"color\",\"background-color\",\"border-left-color\",\"border-right-color\",\"border-top-color\",\"border-bottom-color\"];var props2=[\"color\",\"backgroundColor\",\"borderLeftColor\",\"borderRightColor\",\"borderTopColor\",\"borderBottomColor\"];if(typeof getRGBColor(document.documentElement,\"background-color\")==\"string\")document.documentElement.style.backgroundColor=\"white\";revl(document.documentElement);function revl(n){var i,x,color,hsl;if(n.nodeType==Node.ELEMENT_NODE){for(i=0;x=n.childNodes[i];++i)revl(x);for(i=0;x=props[i];++i){color=getRGBColor(n,x);if(typeof(color)!=\"string\"){hsl=RGBtoHSL(color);hsl[0]=(hsl[0]+1/24)%1;n.style[props2[i]]=hslToCSS(hsl);}}}}})()"))
remove-images
Remove images from web pages.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){function toArray (c){var a, k;a=new Array;for (k=0; k < c.length; ++k)a[k]=c[k];return a;}var images, img, altText;images=toArray(document.images);for (var i=0; i < images.length; ++i){img=images[i];altText=document.createTextNode(img.alt);img.parentNode.replaceChild(altText, img)}})();"))
remove-color
Remove color from web pages.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var newSS, styles='* { background: white ! important; color: black !important } :link, :link * { color: #0000EE !important } :visited, :visited * { color: #551A8B !important }'; if(document.createStyleSheet) { document.createStyleSheet(\"javascript:'\"+styles+\"'\"); } else { newSS=document.createElement('link'); newSS.rel='stylesheet'; newSS.href='data:text/css,'+escape(styles); document.getElementsByTagName(\"head\")[0].appendChild(newSS); } })();"))
transpose-tables
Transpose all table row and columns.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var d=document,q=\"table\",i,j,k,y,r,c,t;for(i=0;t=d.getElementsByTagName(q)[i];++i){var w=0,N=t.cloneNode(0);N.width=\"\";N.height=\"\";N.border=1;for(j=0;r=t.rows[j];++j)for(y=k=0;c=r.cells[k];++k){var z,a=c.rowSpan,b=c.colSpan,v=c.cloneNode(1);v.rowSpan=b;v.colSpan=a;v.width=\"\";v.height=\"\";if(!v.bgColor)v.bgColor=r.bgColor;while(w<y+b)N.insertRow(w++).p=0;while(N.rows[y].p>j)++y;N.rows[y].appendChild(v);for(z=0;z<b;++z)N.rows[y+z].p+=a;y+=b;}t.parentNode.replaceChild(N,t);}})()"))
number-lines
Numberlines in plaintext documents and PRE tags.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var i,p,L,d,j,n; for(i=0; p=document.getElementsByTagName(\"pre\")[i]; ++i) { L=p.innerHTML.split(\"rn\"); d=\"\"+L.length; for(j=0;j<L.length;++j) { n = \"\"+(j+1)+\". \"; while(n.length<d.length+2) n=\"0\"+n; L[j] = n + L[j]; } p.innerHTML=L.join(\"<br>\");/*join with br for ie*/ } })()"))
number-table-rows
Add numbers to table rows.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){function has(par,ctag){for(var k=0;k<par.childNodes.length;++k)if(par.childNodes[k].tagName==ctag)return true;} function add(par,ctag,text){var c=document.createElement(ctag); c.appendChild(document.createTextNode(text)); par.insertBefore(c,par.childNodes[0]);} var i,ts=document.getElementsByTagName(\"TABLE\"); for(i=0;i<ts.length;++i) { var n=0,trs=ts[i].rows,j,tr; for(j=0;j<trs.length;++j) {tr=trs[j]; if(has(tr,\"TD\"))add(tr,\"TD\",++n); else if(has(tr,\"TH\"))add(tr,\"TH\",\"Row\");}}})()"))
sort-table
Sort a table alphabetically.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"function toArray (c){var a, k;a=new Array;for (k=0; k<c.length; ++k)a[k]=c[k];return a;}function insAtTop(par,child){if(par.childNodes.length) par.insertBefore(child, par.childNodes[0]);else par.appendChild(child);}function countCols(tab){var nCols, i;nCols=0;for(i=0;i<tab.rows.length;++i)if(tab.rows[i].cells.length>nCols)nCols=tab.rows[i].cells.length;return nCols;}function makeHeaderLink(tableNo, colNo, ord){var link;link=document.createElement('a');link.href='javascript:sortTable('+tableNo+','+colNo+','+ord+');';link.appendChild(document.createTextNode((ord>0)?'a':'d'));return link;}function makeHeader(tableNo,nCols){var header, headerCell, i;header=document.createElement('tr');for(i=0;i<nCols;++i){headerCell=document.createElement('td');headerCell.appendChild(makeHeaderLink(tableNo,i,1));headerCell.appendChild(document.createTextNode('/'));headerCell.appendChild(makeHeaderLink(tableNo,i,-1));header.appendChild(headerCell);}return header;}g_tables=toArray(document.getElementsByTagName('table'));if(!g_tables.length) alert(\"This page doesn't contain any tables.\");(function(){var j, thead;for(j=0;j<g_tables.length;++j){thead=g_tables[j].createTHead();insAtTop(thead, makeHeader(j,countCols(g_tables[j])))}}) ();function compareRows(a,b){if(a.sortKey==b.sortKey)return 0;return (a.sortKey < b.sortKey) ? g_order : -g_order;}function sortTable(tableNo, colNo, ord){var table, rows, nR, bs, i, j, temp;g_order=ord;g_colNo=colNo;table=g_tables[tableNo];rows=new Array();nR=0;bs=table.tBodies;for(i=0; i<bs.length; ++i)for(j=0; j<bs[i].rows.length; ++j){rows[nR]=bs[i].rows[j];temp=rows[nR].cells[g_colNo];if(temp) rows[nR].sortKey=temp.innerHTML;else rows[nR].sortKey=\"\";++nR;}rows.sort(compareRows);for (i=0; i < rows.length; ++i)insAtTop(table.tBodies[0], rows[i]);}"))
zoom-images-out
Zoom images out.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){ function zoomImage(image, amt) { if(image.initialHeight == null) { /* avoid accumulating integer-rounding error */ image.initialHeight=image.height; image.initialWidth=image.width; image.scalingFactor=1; } image.scalingFactor*=amt; image.width=image.scalingFactor*image.initialWidth; image.height=image.scalingFactor*image.initialHeight; } var i,L=document.images.length; for (i=0;i<L;++i) zoomImage(document.images[i],.5); if (!L) alert(\"This page contains no images.\"); })();"))
zoom-images-in
Zoom images in.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){ function zoomImage(image, amt) { if(image.initialHeight == null) { /* avoid accumulating integer-rounding error */ image.initialHeight=image.height; image.initialWidth=image.width; image.scalingFactor=1; } image.scalingFactor*=amt; image.width=image.scalingFactor*image.initialWidth; image.height=image.scalingFactor*image.initialHeight; } var i,L=document.images.length; for (i=0;i<L;++i) zoomImage(document.images[i], 2); if (!L) alert(\"This page contains no images.\"); })();"))
highlight-regexp
Highlights each match for a regular expression.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var count=0, text, regexp;text=prompt(\"Search regexp:\", \"\");if(text==null || text.length==0)return;try{regexp=new RegExp(\"(\" + text +\")\", \"i\");}catch(er){alert(\"Unable to create regular expression using text '\"+text+\"'.nn\"+er);return;}function searchWithinNode(node, re){var pos, skip, spannode, middlebit, endbit, middleclone;skip=0;if( node.nodeType==3 ){pos=node.data.search(re);if(pos>=0){spannode=document.createElement(\"SPAN\");spannode.style.backgroundColor=\"yellow\";middlebit=node.splitText(pos);endbit=middlebit.splitText(RegExp.$1.length);middleclone=middlebit.cloneNode(true);spannode.appendChild(middleclone);middlebit.parentNode.replaceChild(spannode,middlebit);++count;skip=1;}}else if( node.nodeType==1 && node.childNodes && node.tagName.toUpperCase()!=\"SCRIPT\" && node.tagName.toUpperCase!=\"STYLE\"){for (var child=0; child < node.childNodes.length; ++child){child=child+searchWithinNode(node.childNodes[child], re);}}return skip;}window.status=\"Searching for \"+regexp+\"...\";searchWithinNode(document.body, regexp);window.status=\"Found \"+count+\" match\"+(count==1?\"\":\"es\")+\" for \"+regexp+\".\";})();"))
show-textbox-character-count
Displays a running count of the characters in each textbox.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var D=document,i,f,j,e;for(i=0;f=D.forms[i];++i)for(j=0;e=f[j];++j)if(e.type==\"text\"||e.type==\"password\"||e.tagName.toLowerCase()==\"textarea\")S(e);function S(e){if(!e.N){var x=D.createElement(\"span\"),s=x.style;s.color=\"green\";s.background=\"white\";s.font=\"bold 10pt sans-serif\";s.verticalAlign=\"top\";e.parentNode.insertBefore(x,e.nextSibling);function u(){x.innerHTML=e.value.length;}u();e.onchange=u;e.onkeyup=u;e.oninput=u;e.N=x;}else{e.parentNode.removeChild(e.N);e.N=0;}}})()"))
enlarge-textareas
Increase height of all text areas by 5 vertical lines.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var i,x; for(i=0;x=document.getElementsByTagName(\"textarea\")[i];++i) x.rows += 5; })()"))
show-hidden-form-elements
Show hidden form elements.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var i,f,j,e,div,label,ne; for(i=0;f=document.forms[i];++i)for(j=0;e=f[j];++j)if(e.type==\"hidden\"){ D=document; function C(t){return D.createElement(t);} function A(a,b){a.appendChild(b);} div=C(\"div\"); label=C(\"label\"); A(div, label); A(label, D.createTextNode(e.name + \": \")); e.parentNode.insertBefore(div, e); e.parentNode.removeChild(e); ne=C(\"input\");/*for ie*/ ne.type=\"text\"; ne.value=e.value; A(label, ne); label.style.MozOpacity=\".6\"; --j;/*for moz*/}})()"))
view-password-field-contents
View passwords on page.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var s,F,j,f,i; s = \"\"; F = document.forms; for(j=0; j<F.length; ++j) { f = F[j]; for (i=0; i<f.length; ++i) { if (f[i].type.toLowerCase() == \"password\") s += f[i].value + \"n\"; } } if (s) alert(\"Passwords in forms on this page:nn\" + s); else alert(\"There are no passwords in forms on this page.\");})();"))
toggle-checkboxes
Toggle all checkboxes.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){ function toggle(box){ temp=box.onchange; box.onchange=null; box.checked=!box.checked; box.onchange=temp; } var x,k,f,j; x=document.forms; for (k=0; k<x.length; ++k) { f=x[k]; for (j=0;j<f.length;++j) if (f[j].type.toLowerCase() == \"checkbox\") toggle(f[j]); } })();"))
hide-visited-urls
Hide visited URLs.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var newSS, styles=':visited {display: none}'; if(document.createStyleSheet) { document.createStyleSheet(\"javascript:'\"+styles+\"'\"); } else { newSS=document.createElement('link'); newSS.rel='stylesheet'; newSS.href='data:text/css,'+escape(styles); document.getElementsByTagName(\"head\")[0].appendChild(newSS); } })();"))
urls-as-link-text
Changes the text of links to match their absolute URLs.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var i,c,x,h; for(i=0;x=document.links[i];++i) { h=x.href; x.title+=\" \" + x.innerHTML; while(c=x.firstChild)x.removeChild(c); x.appendChild(document.createTextNode(h)); } })()"))
color-internal-external-links
Color internal links red, external links blue, and in-page links orange.
(define-command (&optional (buffer (current-buffer)))
(ffi-buffer-evaluate-javascript-async buffer
"(function(){var i,x; for (i=0;x=document.links[i];++i)x.style.color=['blue','red','orange'][sim(x,location)]; function sim(a,b) { if (a.hostname!=b.hostname) return 0; if (fixPath(a.pathname)!=fixPath(b.pathname) || a.search!=b.search) return 1; return 2; } function fixPath(p){ p = (p.charAt(0)=='/' ? '' : '/') + p;/*many browsers*/ p=p.split('?')[0];/*opera*/ return p; } })()"))
delete-os-generations
Delete generations of selected profile.
(define-command nil
(assert-package-manager)
(let* ((profile
(prompt-minibuffer :suggestion-function
(os-profile-suggestion-filter :include-manager-p
t)
:input-prompt "Target profile"))
(generations
(prompt-minibuffer :suggestion-function
(os-generation-suggestion-filter profile)
:input-prompt "Delete generations"
:multi-selection-p t)))
(operate-os-package "Deleting generations..." #'ospama:delete-generations
profile generations)))
switch-os-generation
Switch generation of selected profile.
(define-command nil
(assert-package-manager)
(let* ((profile
(prompt-minibuffer :suggestion-function
(os-profile-suggestion-filter :include-manager-p
t)
:input-prompt "Target profile"))
(generation
(prompt-minibuffer :suggestion-function
(os-generation-suggestion-filter profile)
:input-prompt "Switch to generation")))
(operate-os-package "Switching to generation..." #'ospama:switch-generation
profile generation)))
describe-os-generation
Show the packages of a given profile generation.
(define-command nil
(assert-package-manager)
(let* ((profile
(prompt-minibuffer :suggestion-function
(os-profile-suggestion-filter :include-manager-p
t)
:input-prompt "Profile"))
(generation
(prompt-minibuffer :suggestion-function
(os-generation-suggestion-filter profile)
:input-prompt "Generation"))
(buffer
(or (find-buffer 'os-package-manager-mode)
(nyxt/os-package-manager-mode:os-package-manager-mode :activate t
:buffer
(make-internal-buffer
:title
"*OS packages*")))))
(echo "Loading package database...")
(html-set
(cl-markup:markup (:style (style buffer))
(:h2
(format nil "Packages for generation ~a"
(ospama:id generation)))
(:p "Profile " profile)
(:ul
(loop for package-output in (ospama:list-packages
(ospama:path generation))
for package = (ospama:parent-package
package-output)
collect (cl-markup:markup*
`(:li
(:a :class "button" :href
,(lisp-url
`(%describe-os-package
(or
(ospama:find-os-packages
,(ospama:name package) :version
,(ospama:version package))
(ospama:find-os-packages
,(ospama:name package)))))
,(object-string package-output))
" " ,(ospama:version package))))))
buffer)
(echo "")
(set-current-buffer buffer)
buffer))
edit-package-manifest
Edit select manifest.
(define-command nil
(assert-package-manager)
(let ((manifest
(prompt-minibuffer :suggestion-function
(os-manifest-suggestion-filter) :input-prompt
"Manifest")))
(echo "Opening ~s with ~a" manifest (external-editor-program *browser*))
(uiop/launch-program:launch-program
(list (external-editor-program *browser*) manifest))))
install-package-manifest
Install select manifest to a profile.
(define-command nil
(assert-package-manager)
(let* ((profile
(prompt-minibuffer :suggestion-function
(os-profile-suggestion-filter) :input-prompt
"Target profile"))
(manifest
(prompt-minibuffer :suggestion-function
(os-manifest-suggestion-filter) :input-prompt
"Manifest")))
(operate-os-package "Installing package manifest..."
#'ospama:install-manifest profile manifest)))
uninstall-os-package
Uninstall select packages.
(define-command nil
(assert-package-manager)
(let* ((profile
(prompt-minibuffer :suggestion-function
(os-profile-suggestion-filter) :input-prompt
"Target profile"))
(packages
(prompt-minibuffer :suggestion-function
(os-installed-package-suggestion-filter profile)
:input-prompt "Uninstall OS package(s)"
:multi-selection-p t)))
(operate-os-package "Uninstalling packages..." #'ospama:uninstall profile
packages)))
install-os-package
Install select packages.
(define-command nil
(assert-package-manager)
(let* ((profile
(prompt-minibuffer :suggestion-function
(os-profile-suggestion-filter) :input-prompt
"Target profile"))
(packages
(prompt-minibuffer :suggestion-function
(os-package-output-suggestion-filter)
:input-prompt "Install OS package(s)"
:multi-selection-p t)))
(operate-os-package "Installing packages..." #'ospama:install profile
packages)))
list-os-package-files
List files of select packages.
(define-command nil
(assert-package-manager)
(let* ((packages-or-outputs
(if (typep (ospama:manager) 'ospama:guix-manager)
(prompt-minibuffer :suggestion-function
(os-package-output-suggestion-filter)
:input-prompt
"List files of OS package outputs(s)"
:multi-selection-p t)
(prompt-minibuffer :suggestion-function
(os-package-suggestion-filter) :input-prompt
"List files of OS package(s)"
:multi-selection-p t)))
(buffer
(or (find-buffer 'os-package-manager-mode)
(nyxt/os-package-manager-mode:os-package-manager-mode :activate t
:buffer
(make-internal-buffer
:title
"*OS packages*")))))
(echo "Computing file list...")
(html-set
(cl-markup:markup (:style (style buffer)) (:h1 "Package files")
(:ul
(loop for package-or-output in packages-or-outputs
collect (cl-markup:markup*
`(:li ,(object-string package-or-output)
(:ul
,@(mapcar
(lambda (file)
`(:li
,(if (viewable-file-type-p
file)
`(:a :href ,file ,file)
file)))
(ospama:list-files
(list package-or-output)))))))))
buffer)
(echo "")
(set-current-buffer buffer)
buffer))
describe-os-package
Show description of select packages.
(define-command nil
(assert-package-manager)
(let* ((packages
(prompt-minibuffer :suggestion-function
(os-package-suggestion-filter) :input-prompt
"Describe OS package(s)" :multi-selection-p t)))
(%describe-os-package packages)))
cancel-package-operation
Terminate the package manager process in the current buffer.
(define-command nil
(sera:and-let* ((nyxt/os-package-manager-mode::process-info
(nyxt/os-package-manager-mode:current-process-info
(find-submode (current-buffer)
'nyxt/os-package-manager-mode:os-package-manager-mode))))
(uiop/launch-program:terminate-process
nyxt/os-package-manager-mode::process-info)
(ffi-buffer-evaluate-javascript-async (current-buffer)
(parenscript:ps
(parenscript:chain
nyxt/os-package-manager-mode::document
(write
(parenscript:lisp
(cl-markup:markup
(:p
"Operation cancelled.")))))))))
os-package-manager-mode
Mode for package management.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command OS-PACKAGE-MANAGER-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer
'nyxt/os-package-manager-mode:os-package-manager-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/os-package-manager-mode:user-os-package-manager-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled."
'nyxt/os-package-manager-mode:os-package-manager-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled."
'nyxt/os-package-manager-mode:os-package-manager-mode))))
buffer)
reduce-tracking-mode
Set specific settings in the web view in order to mitigate fingerprinting, (how third-party trackers attempt to indentify you.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command REDUCE-TRACKING-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/reduce-tracking-mode:reduce-tracking-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/reduce-tracking-mode:user-reduce-tracking-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled."
'nyxt/reduce-tracking-mode:reduce-tracking-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled."
'nyxt/reduce-tracking-mode:reduce-tracking-mode))))
buffer)
force-https-mode
Impose HTTPS on every queried URI. Use at your own risk -- it can break websites whose certificates are not known and websites that still don't have HTTPS version (shame on them!). To permanently bypass the "Unacceptable TLS Certificate" error: (setf nyxt/certificate-exception-mode:*default-certificate-exceptions* '("your.unacceptable.cert.website")) Example: (define-configuration buffer ((default-modes (append '(force-https-mode) %slot-default))))
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command FORCE-HTTPS-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/force-https-mode:force-https-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/force-https-mode:user-force-https-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/force-https-mode:force-https-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/force-https-mode:force-https-mode))))
buffer)
vcs-update-local-projects
Scan the project roots and update the list of existing repositories.
(define-command nil
(setf nyxt/vcs::*git-projects* (nyxt/vcs::parse-projects))
(echo "VCS projects updated."))
git-clone
Alias of `vcs-clone'.
(define-command nil
(vcs-clone))
vcs-clone
Clone the repository of the current URL to disk. Only Git is supported at the moment. Set the list of preferred destinations in the `*vcs-projects-roots*' variable. The default username can be set in `*vcs-username*' or `*vcs-username-alist*'.
(define-command nil
(let* ((uri (url (current-buffer)))
(root-name
(first (str:split "/" (quri.uri:uri-path uri) :omit-nulls t)))
(project-name
(second (str:split "/" (quri.uri:uri-path uri) :omit-nulls t)))
(clone-uri (quri:copy-uri uri))
(existing-repo (nyxt/vcs::find-project-directory project-name))
target-dir)
(cond ((not project-name) (echo "Could not find the project name."))
(existing-repo (echo "This repository exists in ~a" existing-repo))
((= 1 (length nyxt/vcs:*vcs-projects-roots*))
(setf target-dir (first nyxt/vcs:*vcs-projects-roots*))
(nyxt/vcs::clone project-name root-name target-dir clone-uri))
(t
(let ((target-dir
(prompt-minibuffer :input-prompt "Target directory"
:suggestion-function
#'nyxt/vcs::projects-roots-suggestion-filter)))
(nyxt/vcs::clone project-name root-name target-dir
clone-uri))))))
download-open-file
Open a downloaded file. See also `open-file'.
(define-command nil
(let ((filename
(prompt-minibuffer :input-prompt "Open file" :suggestion-function
(downloaded-files-suggestion-filter))))
(nyxt/file-manager-mode:open-file-function filename)))
download-url
Download the page or file of the current buffer.
(define-command nil
(download (url (current-buffer)))
(unless (find-buffer 'download-mode) (list-downloads)))
list-downloads
Display a buffer listing all downloads.
(define-command nil
(unless (download-watcher *browser*)
(setf (download-watcher *browser*)
(bordeaux-threads:make-thread #'download-watch)))
(set-current-buffer (download-refresh)))
download-mode
Display list of downloads.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command DOWNLOAD-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'download-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'user-download-mode :buffer buffer
args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'download-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'download-mode))))
buffer)
open-file
Open a file from the filesystem. The user is prompted with the minibuffer, files are browsable with fuzzy suggestion. The default directory is the one computed by `download-manager:default-download-directory' (usually `~/Downloads'). Press `Enter' to visit a file, `M-Left' or `C-l' to go one directory up, `M-Right' or `C-j' to browse the directory at point. By default, it uses the `xdg-open' command. The user can override the `nyxt:open-file-function' function, which takes the filename (or directory name) as parameter. The default keybinding is `C-x C-f'. Note: this feature is alpha, get in touch for more!
(define-command nil
(uiop/filesystem:with-current-directory ((uiop/os:getcwd))
(let ((nyxt/file-manager-mode::filename
(prompt-minibuffer :default-modes
'(nyxt/file-manager-mode:file-manager-mode
nyxt/minibuffer-mode:minibuffer-mode)
:input-prompt (namestring (uiop/os:getcwd))
:suggestion-function
#'nyxt/file-manager-mode:open-file-from-directory-suggestion-filter)))
(funcall nyxt/file-manager-mode:*open-file-function*
(namestring nyxt/file-manager-mode::filename)))))
enter-directory
If the suggestion at point is a directory, refresh the minibuffer suggestions with its list of files. Default keybindings: `M-Right' and `C-j'.
(define-command (&optional (minibuffer (current-minibuffer)))
(let ((nyxt/file-manager-mode::filename (get-suggestion minibuffer)))
(when
(and
(uiop/pathname:directory-pathname-p
nyxt/file-manager-mode::filename)
(uiop/filesystem:directory-exists-p
nyxt/file-manager-mode::filename))
(uiop/os:chdir nyxt/file-manager-mode::filename)
(erase-input minibuffer)
(update-display minibuffer))))
display-parent-directory
Get the parent directory and update the minibuffer. Default keybindings: `M-Left' and `C-l'.
(define-command (&optional (minibuffer (current-minibuffer)))
(uiop/os:chdir "..")
(erase-input minibuffer)
(update-display minibuffer))
file-manager-mode
Mode to open any file from the filesystem with fuzzy suggestion on the minibuffer. Specialize keybindings on this mode. See the command `open-file'.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command FILE-MANAGER-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/file-manager-mode:file-manager-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/file-manager-mode:user-file-manager-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/file-manager-mode:file-manager-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled."
'nyxt/file-manager-mode:file-manager-mode))))
buffer)
nowebgl-mode
Disable WebGL in current buffer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command NOWEBGL-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/nowebgl-mode:nowebgl-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/nowebgl-mode:user-nowebgl-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/nowebgl-mode:nowebgl-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/nowebgl-mode:nowebgl-mode))))
buffer)
noscript-mode
Disable Javascript in current buffer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command NOSCRIPT-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/noscript-mode:noscript-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/noscript-mode:user-noscript-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/noscript-mode:noscript-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/noscript-mode:noscript-mode))))
buffer)
nosound-mode
Disable sound in current buffer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command NOSOUND-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/nosound-mode:nosound-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/nosound-mode:user-nosound-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/nosound-mode:nosound-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/nosound-mode:nosound-mode))))
buffer)
noimage-mode
Disable images in current buffer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command NOIMAGE-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/noimage-mode:noimage-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/noimage-mode:user-noimage-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/noimage-mode:noimage-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/noimage-mode:noimage-mode))))
buffer)
proxy-mode
Enable forwarding of all network requests to a specific host. As for every mode, it only applies to the current buffer. If you want to enable a proxy for all buffers, add it to the list of default modes. Example to use Tor as a proxy both for browsing and downloading: (define-configuration nyxt/proxy-mode:proxy-mode ((nyxt/proxy-mode:proxy (make-instance 'proxy :server-address (quri:uri "socks5://localhost:9050") :allowlist '("localhost" "localhost:8080") :proxied-downloads-p t)))) (define-configuration buffer ((default-modes (append '(proxy-mode) %slot-default))))
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command PROXY-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/proxy-mode:proxy-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/proxy-mode:user-proxy-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/proxy-mode:proxy-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/proxy-mode:proxy-mode))))
buffer)
blocker-mode
Enable blocking of listed hosts. To customize the list of blocked hosts, set the `hostlists' slot. See the `hostlist' class documentation. Example: (defvar *my-blocked-hosts* (nyxt/blocker-mode:make-hostlist :hosts '("platform.twitter.com" "syndication.twitter.com" "m.media-amazon.com"))) (define-mode my-blocker-mode (nyxt/blocker-mode:blocker-mode) "Blocker mode with custom hosts from `*my-blocked-hosts*'." ((nyxt/blocker-mode:hostlists (list *my-blocked-hosts* nyxt/blocker-mode:*default-hostlist*)))) (define-configuration buffer ((default-modes (append '(my-blocker-mode) %slot-default))))
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command BLOCKER-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/blocker-mode:blocker-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/blocker-mode:user-blocker-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/blocker-mode:blocker-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/blocker-mode:blocker-mode))))
buffer)
vi-button1
Enable VI insert mode when focus is on an input element on the web page.
(define-command (&optional (buffer (current-buffer)))
(ffi-generate-input-event (current-window) (last-event buffer))
(let ((nyxt/vi-mode::response (nyxt/web-mode:%clicked-in-input?)))
(cond
((and (nyxt/web-mode:input-tag-p nyxt/vi-mode::response)
(find-submode buffer 'nyxt/vi-mode:vi-normal-mode))
(nyxt/vi-mode:vi-insert-mode))
((and (not (nyxt/web-mode:input-tag-p nyxt/vi-mode::response))
(find-submode buffer 'nyxt/vi-mode:vi-insert-mode))
(nyxt/vi-mode:vi-normal-mode)))))
vi-insert-mode
Enable VI-style modal bindings (insert mode). See `vi-normal-mode'.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command VI-INSERT-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/vi-mode:vi-insert-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/vi-mode:user-vi-insert-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/vi-mode:vi-insert-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/vi-mode:vi-insert-mode))))
buffer)
vi-normal-mode
Enable VI-style modal bindings (normal mode). To enable these bindings by default, add the mode to the list of default modes in your configuration file. Example: (define-configuration buffer ((default-modes (append '(vi-normal-mode) %slot-default))))
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command VI-NORMAL-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/vi-mode:vi-normal-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/vi-mode:user-vi-normal-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/vi-mode:vi-normal-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/vi-mode:vi-normal-mode))))
buffer)
emacs-mode
Enable Emacs-style bindings. To enable these bindings by default, add the mode to the list of default modes in your configuration file. Example: (define-configuration buffer ((default-modes (append '(emacs-mode) %slot-default))))
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command EMACS-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/emacs-mode:emacs-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/emacs-mode:user-emacs-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/emacs-mode:emacs-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/emacs-mode:emacs-mode))))
buffer)
add-domain-to-certificate-exceptions
Add the current hostname to the buffer's certificate exception list. This is only effective if `certificate-exception-mode' is enabled. To make this change permanent, you can customize `*default-certificate-exceptions*' in your init file: (setf nyxt/certificate-exception-mode:*default-certificate-exceptions* '("nyxt.atlas.engineer" "example.org"))
(define-command (&optional (buffer (current-buffer)))
(if (find-submode buffer
'nyxt/certificate-exception-mode:certificate-exception-mode)
(let ((nyxt/certificate-exception-mode::input
(prompt-minibuffer :input-prompt "URL host to exception list:"
:suggestion-function
(nyxt/certificate-exception-mode::previous-history-urls-suggestion-filter))))
(unless
(url-empty-p
(url
(history-tree:data nyxt/certificate-exception-mode::input)))
(let ((nyxt/certificate-exception-mode::host
(quri.uri:uri-host
(url
(history-tree:data
nyxt/certificate-exception-mode::input)))))
(echo "Added exception for ~s."
nyxt/certificate-exception-mode::host)
(pushnew nyxt/certificate-exception-mode::host
(certificate-exceptions buffer) :test #'string=))))
(echo "Enable certificate-exception-mode first.")))
certificate-exception-mode
Enable ignoring of certificate errors. This can apply to specific buffers. See the `add-domain-to-certificate-exceptions' command.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command CERTIFICATE-EXCEPTION-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer
'nyxt/certificate-exception-mode:certificate-exception-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/certificate-exception-mode:user-certificate-exception-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled."
'nyxt/certificate-exception-mode:certificate-exception-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled."
'nyxt/certificate-exception-mode:certificate-exception-mode))))
buffer)
dark-mode
Mode for styling documents.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command DARK-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/style-mode:dark-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/style-mode:user-dark-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/style-mode:dark-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/style-mode:dark-mode))))
buffer)
style-mode
Mode for styling documents.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command STYLE-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/style-mode:style-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/style-mode:user-style-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/style-mode:style-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/style-mode:style-mode))))
buffer)
reading-line-cursor-down
Move the reading line cursor down. If scrolling off screen, move the screen as well.
(define-command (&key (nyxt/reading-line-mode::step-size 20)
(buffer (current-buffer)))
(pflet ((nyxt/reading-line-mode::cursor-down nil
(let ((nyxt/reading-line-mode::original-position
(parenscript:chain
(nyxt/reading-line-mode::parse-int
(parenscript:@
(parenscript:chain nyxt/reading-line-mode::document
(nyxt/reading-line-mode::query-selector
"#reading-line-cursor"))
style nyxt/reading-line-mode::top)
10))))
(setf (parenscript:@
(parenscript:chain nyxt/reading-line-mode::document
(nyxt/reading-line-mode::query-selector
"#reading-line-cursor"))
style nyxt/reading-line-mode::top)
(+
(+ nyxt/reading-line-mode::original-position
(parenscript:lisp
nyxt/reading-line-mode::step-size))
"px")))))
(with-current-buffer buffer
(nyxt/reading-line-mode::cursor-down)))
(nyxt/reading-line-mode:jump-to-reading-line-cursor :buffer buffer))
reading-line-cursor-up
Move the reading line cursor up. If scrolling off screen, move the screen as well.
(define-command (&key (nyxt/reading-line-mode::step-size 20)
(buffer (current-buffer)))
(pflet ((nyxt/reading-line-mode::cursor-up nil
(let ((nyxt/reading-line-mode::original-position
(parenscript:chain
(nyxt/reading-line-mode::parse-int
(parenscript:@
(parenscript:chain nyxt/reading-line-mode::document
(nyxt/reading-line-mode::query-selector
"#reading-line-cursor"))
style nyxt/reading-line-mode::top)
10))))
(setf (parenscript:@
(parenscript:chain nyxt/reading-line-mode::document
(nyxt/reading-line-mode::query-selector
"#reading-line-cursor"))
style nyxt/reading-line-mode::top)
(+
(- nyxt/reading-line-mode::original-position
(parenscript:lisp
nyxt/reading-line-mode::step-size))
"px")))))
(with-current-buffer buffer
(nyxt/reading-line-mode::cursor-up)))
(nyxt/reading-line-mode:jump-to-reading-line-cursor :buffer buffer))
jump-to-reading-line-cursor
Move the view port to show the reading line cursor.
(define-command (&key (buffer (current-buffer)))
(pflet ((nyxt/reading-line-mode::jump-to-cursor nil
(parenscript:chain
(parenscript:chain nyxt/reading-line-mode::document
(nyxt/reading-line-mode::query-selector
"#reading-line-cursor"))
(nyxt/reading-line-mode::scroll-into-view-if-needed))))
(with-current-buffer buffer
(nyxt/reading-line-mode::jump-to-cursor))))
reading-line-mode
Mode for drawing a line on screen that you can use to keep track of your reading position. To use this mode, first enable this mode and then use the bindings for `reading-line-cursor-up' and `reading-line-cursor-down' to move the reading line cursor. If you navigate away from the reading line, you can always invoke the command `jump-to-reading-line-cursor' to jump back to your reading position. To remove the reading line from the screen, disable this mode.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command READING-LINE-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/reading-line-mode:reading-line-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/reading-line-mode:user-reading-line-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/reading-line-mode:reading-line-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled."
'nyxt/reading-line-mode:reading-line-mode))))
buffer)
autofill
Fill in a field with a value from a saved list.
(define-command nil
(let ((nyxt/web-mode::selected-fill
(prompt-minibuffer :input-prompt "Autofill" :suggestion-function
(lambda (minibuffer)
(fuzzy-match (input-buffer minibuffer)
(autofills *browser*))))))
(cond
((stringp (autofill-fill nyxt/web-mode::selected-fill))
(%paste :input-text (autofill-fill nyxt/web-mode::selected-fill)))
((functionp (autofill-fill nyxt/web-mode::selected-fill))
(%paste :input-text
(funcall (autofill-fill nyxt/web-mode::selected-fill)))))))
copy
Copy selected text to clipboard.
(define-command nil
(let ((nyxt/web-mode::input (%copy)))
(copy-to-clipboard nyxt/web-mode::input)
(echo "Text copied.")))
paste-from-ring
Show `*browser*' clipboard ring and paste selected entry.
(define-command nil
(let ((nyxt/web-mode::ring-item
(prompt-minibuffer :suggestion-function
(nyxt/web-mode::ring-suggestion-filter
(clipboard-ring *browser*)))))
(%paste :input-text nyxt/web-mode::ring-item)))
paste
Paste from clipboard into active-element.
(define-command nil
(%paste))
buffer-history-tree
Open a new buffer displaying the whole history tree.
(define-command (&optional (buffer (current-buffer)))
(labels ((nyxt/web-mode::traverse
(nyxt/web-mode::node nyxt/web-mode::current)
(when nyxt/web-mode::node
`(:li
(:a :href
,(object-string
(url (history-tree:data nyxt/web-mode::node)))
,(let ((title
(or
(match (title
(history-tree:data nyxt/web-mode::node))
((guard nyxt/web-mode::e
(not (str:emptyp nyxt/web-mode::e)))
nyxt/web-mode::e))
(object-display
(url (history-tree:data nyxt/web-mode::node))))))
(if (eq nyxt/web-mode::node nyxt/web-mode::current)
`(:b ,title)
title)))
,(match (mapcar
(lambda (nyxt/web-mode::n)
(nyxt/web-mode::traverse nyxt/web-mode::n
nyxt/web-mode::current))
(history-tree:children nyxt/web-mode::node))
((guard nyxt/web-mode::l nyxt/web-mode::l)
`(:ul ,@nyxt/web-mode::l)))))))
(let* ((nyxt/web-mode::buffer-name
(format nil "*History-~a*" (id buffer)))
(nyxt/web-mode::output-buffer
(or
(find-if
(lambda (nyxt/web-mode::b)
(string= nyxt/web-mode::buffer-name
(title nyxt/web-mode::b)))
(buffer-list))
(nyxt/help-mode:help-mode :activate t :buffer
(make-internal-buffer :title
nyxt/web-mode::buffer-name))))
(history (history (find-submode buffer 'nyxt/web-mode:web-mode)))
(nyxt/web-mode::tree
`(:ul
,(nyxt/web-mode::traverse (history-tree:root history)
(history-tree:current history))))
(nyxt/web-mode::tree-style
(cl-css:css
'((nyxt/web-mode::body :line-height "initial")
(* :margin 0 :padding 0 :list-style "none")
("ul li" :margin-left "15px" :position "relative"
:padding-left "5px")
("ul li::before" :content "' '" :position "absolute" :width
"1px" :background-color "#000" :top "5px" :bottom "-12px"
:left "-10px")
("body > ul > li:first-child::before" :top "12px")
("ul li:not(:first-child):last-child::before" :display "none")
("ul li:only-child::before" :display "list-item" :content
"' '" :position "absolute" :width "1px" :background-color
"#000" :top "5px" :bottom "7px" :height "7px" :left "-10px")
("ul li::after" :content "' '" :position "absolute" :left
"-10px" :width "10px" :height "1px" :background-color "#000"
:top "12px"))))
(nyxt/web-mode::content
(cl-markup:markup
(:body (:h1 "History")
(:style (style nyxt/web-mode::output-buffer))
(:style (cl-markup:raw nyxt/web-mode::tree-style))
(:div
(cl-markup:raw (cl-markup:markup* nyxt/web-mode::tree))))))
(nyxt/web-mode::insert-content
(parenscript:ps
(setf (parenscript:@ nyxt/web-mode::document
nyxt/web-mode::body nyxt/web-mode::|innerHTML|)
(parenscript:lisp nyxt/web-mode::content)))))
(ffi-buffer-evaluate-javascript-async nyxt/web-mode::output-buffer
nyxt/web-mode::insert-content)
(set-current-buffer nyxt/web-mode::output-buffer))))
history-all-query
Query URL to go to, from the whole history.
(define-command nil
(let ((nyxt/web-mode::input
(prompt-minibuffer :input-prompt "Navigate to" :suggestion-function
(nyxt/web-mode::history-all-suggestion-filter))))
(when nyxt/web-mode::input
(nyxt/web-mode::set-url-from-history nyxt/web-mode::input))))
history-forwards-all-query
Query URL to forward to, from all child branches.
(define-command nil
(let ((nyxt/web-mode::input
(prompt-minibuffer :input-prompt
"Navigate forwards to (all branches)"
:suggestion-function
(nyxt/web-mode::history-forwards-all-suggestion-filter))))
(when nyxt/web-mode::input
(nyxt/web-mode::set-url-from-history nyxt/web-mode::input))))
history-forwards-maybe-query
If current node has multiple chidren, query forward-URL to navigate to. Otherwise go forward to the only child.
(define-command (&optional
(nyxt/web-mode::mode
(find-submode (current-buffer) 'nyxt/web-mode:web-mode)))
(if (<= 2
(length
(history-tree:children-nodes (history nyxt/web-mode::mode))))
(nyxt/web-mode:history-forwards-all-query)
(nyxt/web-mode:history-forwards)))
history-forwards-query
Query forward-URL to navigate to.
(define-command nil
(let ((nyxt/web-mode::input
(prompt-minibuffer :input-prompt "Navigate forwards to"
:suggestion-function
(nyxt/web-mode::history-forwards-suggestion-filter))))
(when nyxt/web-mode::input
(nyxt/web-mode::set-url-from-history nyxt/web-mode::input))))
history-backwards-query
Query parent URL to navigate back to.
(define-command nil
(let ((nyxt/web-mode::input
(prompt-minibuffer :input-prompt "Navigate backwards to"
:suggestion-function
(nyxt/web-mode::history-backwards-suggestion-filter))))
(when nyxt/web-mode::input
(nyxt/web-mode::set-url-from-history nyxt/web-mode::input))))
history-forwards
Go to forward URL in history.
(define-command (&optional (buffer (current-buffer)))
(let* ((nyxt/web-mode::mode (find-submode buffer 'nyxt/web-mode:web-mode)))
(if (history-tree:children-nodes (history nyxt/web-mode::mode))
(progn
(history-tree:forward (history nyxt/web-mode::mode))
(match (history-tree:current (history nyxt/web-mode::mode))
((guard nyxt/web-mode::n nyxt/web-mode::n)
(buffer-load (url (history-tree:data nyxt/web-mode::n))))))
(echo "No forward history."))))
history-backwards
Go to parent URL in history.
(define-command (&optional (buffer (current-buffer)))
(let* ((nyxt/web-mode::mode (find-submode buffer 'nyxt/web-mode:web-mode)))
(if (eq (history-tree:root (history nyxt/web-mode::mode))
(history-tree:current (history nyxt/web-mode::mode)))
(echo "No backward history.")
(progn
(history-tree:back (history nyxt/web-mode::mode))
(match (history-tree:current (history nyxt/web-mode::mode))
((guard nyxt/web-mode::n nyxt/web-mode::n)
(buffer-load (url (history-tree:data nyxt/web-mode::n)))))))))
maybe-scroll-to-top
Scroll to top if no input element is active, forward event otherwise.
(define-command (&optional (buffer (current-buffer)))
(nyxt/web-mode::call-non-input-command-or-forward
#'nyxt/web-mode:scroll-to-top :buffer buffer))
maybe-scroll-to-bottom
Scroll to bottom if no input element is active, forward event otherwise.
(define-command (&optional (buffer (current-buffer)))
(nyxt/web-mode::call-non-input-command-or-forward
#'nyxt/web-mode:scroll-to-bottom :buffer buffer))
paste-or-set-url
Paste text if active element is an input tag, forward event otherwise.
(define-command (&optional (buffer (current-buffer)))
(let ((nyxt/web-mode::response (nyxt/web-mode:%clicked-in-input?)))
(let ((nyxt/web-mode::url-empty (url-empty-p (url-at-point buffer))))
(if (and (nyxt/web-mode:input-tag-p nyxt/web-mode::response)
nyxt/web-mode::url-empty)
(funcall-safely #'nyxt/web-mode:paste)
(unless nyxt/web-mode::url-empty
(make-buffer-focus :url (url-at-point buffer)))))))
web-mode
Base mode for interacting with documents.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command WEB-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/web-mode:web-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/web-mode:user-web-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/web-mode:web-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/web-mode:web-mode))))
buffer)
application-mode
Mode that forwards all keys to the renderer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command APPLICATION-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/application-mode:application-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/application-mode:user-application-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/application-mode:application-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/application-mode:application-mode))))
buffer)
clear-messages
Clear the *Messages* buffer.
(define-command nil
(setf (messages-content *browser*) 'nil)
(echo "Messages cleared."))
message-mode
Mode for log and message listing.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command MESSAGE-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/message-mode:message-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/message-mode:user-message-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/message-mode:message-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/message-mode:message-mode))))
buffer)
help-mode
Mode for displaying documentation.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command HELP-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/help-mode:help-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/help-mode:user-help-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/help-mode:help-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/help-mode:help-mode))))
buffer)
lisp-repl
Show Lisp REPL.
(define-command nil
(let* ((repl-buffer
(make-buffer :title "*Lisp REPL*" :modes
'(nyxt/repl-mode:repl-mode base-mode))))
(set-current-buffer repl-buffer)
repl-buffer))
self-insert-repl
Insert pressed key in the current REPL.
(define-command nil
(nyxt/minibuffer-mode:self-insert (nyxt/repl-mode::current-repl)))
return-input
Return inputted text.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(let ((nyxt/repl-mode::input
(str:replace-all " " " "
(text-buffer::string-representation
(input-buffer nyxt/repl-mode::repl)))))
(nyxt/repl-mode::add-object-to-evaluation-history nyxt/repl-mode::repl
(format nil "> ~a"
nyxt/repl-mode::input))
(dolist (nyxt/repl-mode::result (evaluate nyxt/repl-mode::input))
(nyxt/repl-mode::add-object-to-evaluation-history nyxt/repl-mode::repl
nyxt/repl-mode::result))
(text-buffer::kill-line (input-cursor nyxt/repl-mode::repl))
(update-display nyxt/repl-mode::repl)))
kill-line
Delete forwards a word.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::kill-forward-line (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
delete-forwards-word
Delete forwards a word.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::delete-forward-word (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
delete-backwards-word
Delete backwards a word.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::delete-backward-word (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
cursor-backwards-word
Move cursor backwards a word.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::move-backward-word (input-cursor nyxt/repl-mode::repl)
:conservative-word-move
(conservative-word-move (current-buffer)))
(update-input-buffer-display nyxt/repl-mode::repl))
cursor-forwards-word
Move cursor forwards a word.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::move-forward-word (input-cursor nyxt/repl-mode::repl)
:conservative-word-move
(conservative-word-move (current-buffer)))
(update-input-buffer-display nyxt/repl-mode::repl))
cursor-end
Move cursor to the end of the buffer.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(cluffer:end-of-line (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
cursor-beginning
Move cursor to the beginning of the buffer.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(cluffer:beginning-of-line (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
delete-backwards
Delete character before cursor.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::delete-item-backward (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
delete-forwards
Delete character after cursor.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(cluffer:delete-item (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
cursor-backwards
Move cursor backwards by one element.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::safe-backward (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
cursor-forwards
Move cursor forward by one element.
(define-command (&optional
(nyxt/repl-mode::repl (nyxt/repl-mode::current-repl)))
(text-buffer::safe-forward (input-cursor nyxt/repl-mode::repl))
(update-input-buffer-display nyxt/repl-mode::repl))
repl-mode
Mode for interacting with the REPL.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command REPL-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/repl-mode:repl-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/repl-mode:user-repl-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/repl-mode:repl-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/repl-mode:repl-mode))))
buffer)
list-buffers
Show the *Buffers* buffer.
(define-command (&key (cluster nil))
(labels ((cluster-buffers ()
"Return buffers as hash table, where each value is a cluster (list of documents)."
(let ((collection
(make-instance 'analysis::document-collection)))
(loop for buffer in (buffer-list)
unless (internal-buffer-p buffer)
do (with-current-buffer buffer
(analysis::add-document collection
(make-instance
'analysis::document-cluster
:source buffer
:string-contents
(document-get-paragraph-contents)))))
(analysis::tf-vectorize-documents collection)
(analysis::generate-document-distance-vectors collection)
(analysis::dbscan collection :minimum-points 3 :epsilon 0.065)
(analysis::clusters collection)))
(buffer-markup (buffer)
"Create the presentation for a buffer."
(cl-markup:markup
(:p
(:a :class "button" :href
(lisp-url `(delete-buffer :id ,(id buffer))) "✕")
(:a :class "button" :href
(lisp-url `(switch-buffer :id ,(id buffer))) "→")
(:span (title buffer) " - " (quri:render-uri (url buffer))))))
(cluster-markup (cluster-id cluster)
"Create the presentation for a cluster."
(cl-markup:markup
(:div (:h2 (format nil "Cluster ~a" cluster-id))
(loop for document in cluster
collect (buffer-markup (analysis::source document))))))
(internal-buffers-markup ()
"Create the presentation for the internal buffers."
(cl-markup:markup
(:div (:h2 "Internal Buffers")
(loop for buffer in (buffer-list)
when (internal-buffer-p buffer)
collect (buffer-markup buffer))))))
(with-current-html-buffer (buffer "*Buffers*"
'nyxt/buffer-listing-mode:buffer-listing-mode)
(cl-markup:markup (:style (style buffer)) (:h1 "Buffers")
(:a :class "button" :href (lisp-url '(list-buffers))
"Update")
(:br "")
(:div
(if cluster
(append (list (internal-buffers-markup))
(loop for cluster-key being the hash-key using (hash-value
cluster) of (cluster-buffers)
collect (cluster-markup
cluster-key cluster)))
(loop for buffer in (buffer-list)
collect (buffer-markup buffer))))))))
base-mode
Mode that does nothing but bind the general-purpose key bindings.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command BASE-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'base-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'user-base-mode :buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'base-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'base-mode))))
buffer)
buffer-listing-mode
Mode for buffer-listing.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command BUFFER-LISTING-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/buffer-listing-mode:buffer-listing-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/buffer-listing-mode:user-buffer-listing-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled."
'nyxt/buffer-listing-mode:buffer-listing-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled."
'nyxt/buffer-listing-mode:buffer-listing-mode))))
buffer)
add-distribution
Add a new Quicklisp distribution.
(define-command nil
(let ((url
(prompt-minibuffer :input-prompt "New distribution URL"
:must-match-p nil)))
(ql-dist:install-dist url :prompt nil)))
load-system
Load a system from Quicklisp.
(define-command nil
(let ((system
(prompt-minibuffer :input-prompt "Load system" :suggestion-function
(lambda (minibuffer)
(fuzzy-match (input-buffer minibuffer)
(mapcar
#'ql-dist:short-description
(quicklisp-client:system-list))))
:must-match-p t)))
(quicklisp-client:quickload system)))
list-systems
List systems available via Quicklisp.
(define-command nil
(with-current-html-buffer (buffer "*Systems*" 'base-mode)
(cl-markup:markup (:style (style buffer)) (:h1 "Systems")
(:p "Listing of all available Quicklisp systems.")
(:body
(loop for system in (quicklisp-client:system-list)
collect (let ((name
(ql-dist:short-description
system))
(size
(format nil "~a"
(ql-dist:archive-size
(ql-dist:preference-parent
system))))
(dependencies
(format nil "~a"
(ql-dist:required-systems
system))))
(cl-markup:markup
(:div (:h2 name) (:p "Size: " size)
(:p "Requires: " dependencies)
(:p
(:a :class "button" :href
(lisp-url
`(quicklisp-client:quickload
,name))
"Load"))
(:hr)))))))))
fill-input-from-external-editor
This command will open your editor specified by your VISUAL-EDITOR of the BROWSER class, if unset, it will default to your VISUAL environment variable. It will then capture whatever text you enter and save in your editor.
(define-command nil
(bordeaux-threads:make-thread
(lambda ()
(let ((text (get-text-from-external-editor)))
(ffi-within-renderer-thread *browser*
(lambda () (%paste :input-text text)))))))
save-exact-modes-for-future-visits
Store the exact list of enabled modes to auto-mode rules for all the future visits of this domain/host/URL/group of websites inferring the suitable matching condition by user input. Uses `url-infer-match', see its documentation for matching rules. For the storage format see the comment in the head of your `auto-mode-rules-data-path' file.
(define-command nil
(let ((url
(prompt-minibuffer :input-prompt "URL:" :input-buffer
(object-string (url (current-buffer)))
:suggestion-function
(history-suggestion-filter :prefix-urls
(list
(object-string
(url
(current-buffer)))))
:history (minibuffer-set-url-history *browser*)
:must-match-p nil)))
(when (typep url 'history-entry) (setf url (url url)))
(nyxt/auto-mode:add-modes-to-auto-mode-rules
(nyxt/auto-mode::url-infer-match url) :include (modes (current-buffer))
:exact-p t)))
save-non-default-modes-for-future-visits
Save the modes present in `default-modes' and not present in current modes as :excluded, and modes that are present in mode list but not in `default-modes' as :included, to one of auto-mode rules. Apply the resulting rule for all the future visits to this URL, inferring the matching condition with `url-infer-match'. For the storage format see the comment in the head of your `auto-mode-rules-data-path' file.
(define-command nil
(let ((url
(prompt-minibuffer :input-prompt "URL:" :input-buffer
(object-string (url (current-buffer)))
:suggestion-function
(history-suggestion-filter :prefix-urls
(list
(object-string
(url
(current-buffer)))))
:history (minibuffer-set-url-history *browser*)
:must-match-p nil)))
(when (typep url 'history-entry) (setf url (url url)))
(nyxt/auto-mode:add-modes-to-auto-mode-rules
(nyxt/auto-mode::url-infer-match url) :include
(set-difference (modes (current-buffer))
(default-modes (current-buffer)) :test
#'nyxt/auto-mode::mode-equal)
:exclude
(set-difference (default-modes (current-buffer))
(modes (current-buffer)) :test
#'nyxt/auto-mode::mode-equal))))
auto-mode
Remember the modes setup for given domain/host/URL and store it in an editable form. These modes will then be activated on every visit to this domain/host/URL.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command AUTO-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'nyxt/auto-mode:auto-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/auto-mode:user-auto-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/auto-mode:auto-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/auto-mode:auto-mode))))
buffer)
delete-history-entry
Delete queried history entries.
(define-command nil
(with-data-access (history (history-path (current-buffer)))
(let ((entries
(prompt-minibuffer :input-prompt "Delete entries"
:suggestion-function
(history-suggestion-filter) :history
(minibuffer-set-url-history *browser*)
:multi-selection-p t)))
(dolist (entry entries)
(remhash (object-string (url entry)) history)))))
import-bookmarks-from-html
Import bookmarks from an HTML file.
(define-command nil
(let ((html-file
(prompt-minibuffer :default-modes
'(nyxt/file-manager-mode:file-manager-mode
minibuffer-mode)
:input-prompt "Path to the HTML file"
:suggestion-function
#'nyxt/file-manager-mode:open-file-from-directory-suggestion-filter
:must-match-p nil)))
(if (and (uiop/filesystem:file-exists-p html-file)
(equal (pathname-type html-file) "html"))
(with-open-file (in-html html-file :external-format :utf-8)
(let ((a-tags
(plump-dom:get-elements-by-tag-name
(plump-parser:parse in-html) "a")))
(dolist (a-tag a-tags)
(let* ((url (plump-dom:attribute a-tag "href"))
(title (plump-dom:render-text a-tag))
(date (plump-dom:attribute a-tag "add_date"))
(tags (plump-dom:attribute a-tag "tags"))
(url-uri (quri.uri:uri url)))
(when (str:starts-with? "http" (quri.uri:uri-scheme url-uri))
(bookmark-add url-uri :title title :date
(ignore-errors
(local-time:unix-to-timestamp
(parse-integer date)))
:tags (when tags (str:split "," tags))))))))
(echo "The file doesn't exist or is not an HTML file."))))
set-url-from-bookmark-new-buffer
Open selected bookmarks in new buffers.
(define-command nil
(let ((entries
(prompt-minibuffer :input-prompt "Open bookmarks in new buffers"
:default-modes
'(minibuffer-tag-mode minibuffer-mode)
:suggestion-function (bookmark-suggestion-filter)
:multi-selection-p t)))
(dolist (entry (rest entries))
(make-buffer :url (object-string (url entry))))
(make-buffer-focus :url (url (first entries)))))
set-url-from-bookmark
Set the URL for the current buffer from a bookmark. With multiple selections, open the first bookmark in the current buffer, the rest in background buffers.
(define-command nil
(let ((entries
(prompt-minibuffer :input-prompt "Open bookmark(s)" :default-modes
'(minibuffer-tag-mode minibuffer-mode)
:suggestion-function (bookmark-suggestion-filter)
:multi-selection-p t)))
(dolist (entry (rest entries))
(make-buffer :url (object-string (url entry))))
(buffer-load (url (first entries)))))
minibuffer-tag-mode
Minibuffer mode for setting the bookmark and their tags.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command MINIBUFFER-TAG-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'minibuffer-tag-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'user-minibuffer-tag-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'minibuffer-tag-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'minibuffer-tag-mode))))
buffer)
insert-suggestion-or-tag
Paste selected suggestion or tag in input. If character before cursor is '+' or '-' complete against tag.
(define-command (&optional (minibuffer (current-minibuffer)))
(let* ((current-word
(text-buffer::word-at-cursor (input-cursor minibuffer)))
(operand?
(unless (str:emptyp current-word) (subseq current-word 0 1))))
(if (or (equal "-" operand?) (equal "+" operand?))
(let ((tag
(prompt-minibuffer :input-prompt "Tag" :input-buffer
(subseq current-word 1)
:suggestion-function
(tag-suggestion-filter))))
(when tag
(text-buffer::replace-word-at-cursor (input-cursor minibuffer)
(str:concat operand?
(tag-name
tag)))))
(nyxt/minibuffer-mode:insert-suggestion minibuffer))))
bookmark-delete
Delete bookmark(s).
(define-command nil
(with-data-access (bookmarks (bookmarks-path (current-buffer)))
(let ((entries
(prompt-minibuffer :input-prompt "Delete bookmark(s)"
:multi-selection-p t :default-modes
'(minibuffer-tag-mode minibuffer-mode)
:suggestion-function
(bookmark-suggestion-filter))))
(setf bookmarks (set-difference bookmarks entries :test #'equals)))))
bookmark-url
Allow the user to bookmark a URL via minibuffer input.
(define-command nil
(let ((url (prompt-minibuffer :input-prompt "Bookmark URL")))
(if (not (valid-url-p url))
(echo "Invalid URL")
(let* ((url (quri.uri:uri url))
(tags
(prompt-minibuffer :input-prompt "Space-separated tag(s)"
:default-modes
'(set-tag-mode minibuffer-mode)
:input-buffer (url-bookmark-tags url)
:suggestion-function
(tag-suggestion-filter))))
(bookmark-add url :tags tags)))))
bookmark-page
Bookmark the currently opened page(s) in the active buffer.
(define-command nil
(let ((buffers
(prompt-minibuffer :input-prompt "Bookmark URL from buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(mapc #'bookmark-current-page buffers)))
bookmark-current-page
Bookmark the URL of BUFFER.
(define-command (&optional (buffer (current-buffer)))
(flet ((extract-keywords (html limit)
(sera:take limit
(delete ""
(mapcar #'first
(analysis:keywords
(make-instance 'analysis:document
:string-contents
(plump-dom:text
(plump-parser:parse
html)))))
:test #'string=)))
(make-tags (name-list)
(mapcar
(lambda (name) (make-tag :name name :description "suggestion"))
name-list)))
(if (url-empty-p (url buffer))
(echo "Buffer has no URL.")
(let* ((body
(with-current-buffer buffer
(document-get-body)))
(tags
(prompt-minibuffer :input-prompt "Space-separated tag(s)"
:default-modes
'(set-tag-mode minibuffer-mode)
:input-buffer
(url-bookmark-tags (url buffer))
:suggestion-function
(tag-suggestion-filter :extra-tags
(make-tags
(extract-keywords
body 5))))))
(bookmark-add (url buffer) :title (title buffer) :tags tags)
(echo "Bookmarked ~a." (object-display (url buffer)))))))
list-bookmarks
List all bookmarks in a new buffer.
(define-command nil
(with-current-html-buffer (bookmarks-buffer "*Bookmarks*" 'base-mode)
(cl-markup:markup (:style (style bookmarks-buffer)) (:h1 "Bookmarks")
(:body
(loop for bookmark in (get-data
(bookmarks-path
(current-buffer)))
collect (let ((url-display
(object-display (url bookmark)))
(url-href
(object-string (url bookmark))))
(cl-markup:markup
(:div
(:p (:b "Title: ") (title bookmark))
(:p (:b "URL: ")
(:a :href url-href url-display))
(:p (:b "Tags: ")
(when (tags bookmark)
(format nil " (~{~a~^, ~})"
(tags bookmark))))
(:p
(:a :class "button" :href
(lisp-url
`(delete-bookmark ,url-href))
"Delete"))
(:hr "")))))))))
set-tag-mode
Minibuffer mode for setting the tag of a bookmark.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command SET-TAG-MODE called on non-buffer"))
(let ((#:existing-instance0 (find-mode buffer 'set-tag-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'user-set-tag-mode :buffer buffer
args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'set-tag-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'set-tag-mode))))
buffer)
insert-tag
Replace current word with selected tag.
(define-command (&optional (minibuffer (current-minibuffer)))
(let ((selection (get-suggestion minibuffer)))
(unless (uiop/utility:emptyp selection)
(text-buffer::replace-word-at-cursor (input-cursor minibuffer)
(str:concat selection " "))
(update-display minibuffer))))
copy-password
Copy chosen password from minibuffer.
(define-command nil
(password-debug-info)
(if (password-interface *browser*)
(with-password (password-interface *browser*)
(let ((password-name
(prompt-minibuffer :suggestion-function
(password-suggestion-filter
(password-interface *browser*)))))
(password:clip-password (password-interface *browser*) :password-name
password-name)
(echo "Password saved to clipboard for ~a seconds."
password:*sleep-timer*)))
(echo-warning "No password manager found.")))
copy-password-prompt-details
Copy password prompting for all the details without suggestion.
(define-command nil
(password-debug-info)
(if (password-interface *browser*)
(let* ((password-name
(prompt-minibuffer :input-prompt "Name of password"))
(service (prompt-minibuffer :input-prompt "Service")))
(handler-case
(password:clip-password (password-interface *browser*) :password-name
password-name :service service)
(error (c) (echo-warning "Error retrieving password: ~a" c))))
(echo-warning "No password manager found.")))
save-new-password
Save password to password interface.
(define-command nil
(password-debug-info)
(cond
((and (password-interface *browser*)
(has-method-p (password-interface *browser*)
#'password:save-password))
(let* ((password-name
(prompt-minibuffer :input-prompt "Name for new password"
:input-buffer
(or
(quri.domain:uri-domain (url (current-buffer)))
"")))
(new-password
(prompt-minibuffer :invisible-input-p t :input-prompt
"New password (leave empty to generate)")))
(password:save-password (password-interface *browser*) :password-name
password-name :password new-password)))
((null (password-interface *browser*))
(echo-warning "No password manager found."))
(t
(echo-warning "Password manager ~s does not support saving passwords."
(string-downcase
(class-name (class-of (password-interface *browser*))))))))
reopen-last-buffer
Open a new buffer with the URL of the most recently deleted buffer.
(define-command nil
(if (plusp (metabang.utilities:size (recent-buffers *browser*)))
(let ((buffer
(buffer-make *browser* :dead-buffer
(metabang.cl-containers:delete-first
(recent-buffers *browser*)))))
(reload-current-buffer buffer)
(when (focus-on-reopened-buffer-p *browser*)
(set-current-buffer buffer)))
(echo "There are no recently-deleted buffers.")))
reopen-buffer
Reopen queried deleted buffer(s).
(define-command nil
(let ((buffers
(prompt-minibuffer :input-prompt "Reopen buffer(s)"
:multi-selection-p t :suggestion-function
(recent-buffer-suggestion-filter))))
(dolist (buffer buffers)
(metabang.cl-containers:delete-item-if (recent-buffers *browser*)
(buffer-match-predicate buffer))
(reload-current-buffer (buffer-make *browser* :dead-buffer buffer))
(when
(and (eq buffer (first buffers))
(focus-on-reopened-buffer-p *browser*))
(set-current-buffer buffer)))))
enable-hook-handler
Remove handler(s) from a hook.
(define-command nil
(let* ((hook-desc
(prompt-minibuffer :input-prompt "Hook where to enable handler"
:suggestion-function (hook-suggestion-filter)))
(handler
(prompt-minibuffer :input-prompt
(format nil "Enable handler from ~a"
(name hook-desc))
:suggestion-function
(disabled-handler-suggestion-filter
(value hook-desc)))))
(hooks:enable-hook (value hook-desc) handler)))
disable-hook-handler
Remove handler(s) from a hook.
(define-command nil
(let* ((hook-desc
(prompt-minibuffer :input-prompt "Hook where to disable handler"
:suggestion-function (hook-suggestion-filter)))
(handler
(prompt-minibuffer :input-prompt
(format nil "Disable handler from ~a"
(name hook-desc))
:suggestion-function
(handler-suggestion-filter (value hook-desc)))))
(hooks:disable-hook (value hook-desc) handler)))
execute-extended-command
Execute a command by name, also supply required, optional, and keyword parameters.
(define-command nil
(let* ((command
(prompt-minibuffer :input-prompt "Execute extended command"
:suggestion-function
(command-suggestion-filter
(mapcar #'mode-name (modes (current-buffer))))
:hide-suggestion-count-p t))
(command-symbol (sym command))
(argument-list (swank/backend:arglist command-symbol))
(required-arguments
(nth-value 0 (alex:parse-ordinary-lambda-list argument-list)))
(optional-arguments
(nth-value 1 (alex:parse-ordinary-lambda-list argument-list)))
(key-arguments
(nth-value 3 (alex:parse-ordinary-lambda-list argument-list))))
(apply command-symbol
(append
(when required-arguments
(loop for argument in required-arguments
collect (read-from-string
(prompt-minibuffer :input-prompt argument))))
(when optional-arguments
(loop for argument in optional-arguments
collect (read-from-string
(prompt-minibuffer :input-prompt
(first argument)))))
(when key-arguments
(loop for argument in key-arguments
collect (first (car argument))
collect (read-from-string
(prompt-minibuffer :input-prompt
(second (car argument))))))))
(setf (access-time command) (get-internal-real-time))))
execute-command
Execute a command by name.
(define-command nil
(unless (active-minibuffers (current-window))
(let ((command
(prompt-minibuffer :input-prompt "Execute command"
:suggestion-function
(command-suggestion-filter
(mapcar #'mode-name (modes (current-buffer))))
:hide-suggestion-count-p t)))
(setf (access-time command) (get-internal-real-time))
(run-async command))))
minibuffer-toggle-mark-all
Toggle the mark over all visible suggestions. Only available if minibuffer `multi-selection-p' is non-nil.
(define-command (&optional (minibuffer (current-minibuffer)))
(when (multi-selection-p minibuffer)
(with-slots ((nyxt/minibuffer-mode::suggestions suggestions)
(nyxt/minibuffer-mode::marked-suggestions
marked-suggestions))
minibuffer
(cond
((subsetp nyxt/minibuffer-mode::marked-suggestions
nyxt/minibuffer-mode::suggestions)
(setf nyxt/minibuffer-mode::marked-suggestions
(set-difference nyxt/minibuffer-mode::suggestions
nyxt/minibuffer-mode::marked-suggestions)))
((subsetp nyxt/minibuffer-mode::suggestions
nyxt/minibuffer-mode::marked-suggestions)
(setf nyxt/minibuffer-mode::marked-suggestions
(set-difference nyxt/minibuffer-mode::marked-suggestions
nyxt/minibuffer-mode::suggestions)))
(t
(setf nyxt/minibuffer-mode::marked-suggestions
(union nyxt/minibuffer-mode::suggestions
nyxt/minibuffer-mode::marked-suggestions))))))
(state-changed minibuffer)
(update-display minibuffer))
minibuffer-unmark-all
Unmark all visible suggestions. Only available if minibuffer `multi-selection-p' is non-nil.
(define-command (&optional (minibuffer (current-minibuffer)))
(when (multi-selection-p minibuffer)
(with-slots (suggestions marked-suggestions)
minibuffer
(setf marked-suggestions
(set-difference marked-suggestions suggestions)))
(state-changed minibuffer)
(update-display minibuffer)))
minibuffer-mark-all
Mark all visible suggestions. Only available if minibuffer `multi-selection-p' is non-nil.
(define-command (&optional (minibuffer (current-minibuffer)))
(when (multi-selection-p minibuffer)
(with-slots (suggestions marked-suggestions)
minibuffer
(setf marked-suggestions (union suggestions marked-suggestions)))
(state-changed minibuffer)
(update-display minibuffer)))
minibuffer-toggle-mark-backwards
Toggle suggestion and select previous suggestion. See `minibuffer-toggle-mark'.
(define-command (&key (minibuffer (current-minibuffer)))
(nyxt/minibuffer-mode:minibuffer-toggle-mark :minibuffer minibuffer
:direction :previous))
minibuffer-toggle-mark
Toggle suggestion. Only available if minibuffer `multi-selection-p' is non-nil. DIRECTION can be :next or :previous and specifies which suggestion to select once done.
(define-command (&key (minibuffer (current-minibuffer))
(nyxt/minibuffer-mode::direction :next))
(when (multi-selection-p minibuffer)
(with-slots (suggestions suggestion-cursor marked-suggestions)
minibuffer
(let ((nyxt/minibuffer-mode::suggestion
(nth suggestion-cursor suggestions)))
(match (member nyxt/minibuffer-mode::suggestion marked-suggestions)
((guard nyxt/minibuffer-mode::n nyxt/minibuffer-mode::n)
(setf marked-suggestions
(delete nyxt/minibuffer-mode::suggestion
marked-suggestions)))
(nyxt/minibuffer-mode::_
(push nyxt/minibuffer-mode::suggestion marked-suggestions)))))
(state-changed minibuffer)
(update-display minibuffer)
(match nyxt/minibuffer-mode::direction
(:next (nyxt/minibuffer-mode:select-next minibuffer))
(:previous (nyxt/minibuffer-mode:select-previous minibuffer)))))
minibuffer-history
Choose a minibuffer input history entry to insert as input.
(define-command (&optional (minibuffer (current-minibuffer)))
(when (history minibuffer)
(let ((nyxt/minibuffer-mode::input
(object-string
(prompt-minibuffer :input-prompt "Input history" :history nil
:suggestion-function
(nyxt/minibuffer-mode::minibuffer-history-suggestion-filter
(history minibuffer))))))
(unless (str:empty? nyxt/minibuffer-mode::input)
(log:debug nyxt/minibuffer-mode::input minibuffer)
(text-buffer::kill-line (input-cursor minibuffer))
(insert minibuffer nyxt/minibuffer-mode::input)))))
insert-suggestion
Paste selected suggestion to input. As a special case, if the inserted suggestion is a URI, we decode it to make it readable.
(define-command (&optional (minibuffer (current-minibuffer)))
(let ((nyxt/minibuffer-mode::suggestion (get-suggestion minibuffer)))
(when nyxt/minibuffer-mode::suggestion
(nyxt/minibuffer-mode:kill-whole-line minibuffer)
(insert minibuffer
(if (valid-url-p nyxt/minibuffer-mode::suggestion)
(quri.decode:url-decode nyxt/minibuffer-mode::suggestion
:lenient t)
nyxt/minibuffer-mode::suggestion)))))
copy-suggestion
Copy suggestion to clipboard.
(define-command (&optional (minibuffer (current-minibuffer)))
(let ((nyxt/minibuffer-mode::suggestion
(if (and (multi-selection-p minibuffer)
(not (null (marked-suggestions minibuffer))))
(str:join (string #\Newline)
(get-marked-suggestions minibuffer))
(get-suggestion minibuffer))))
(unless (str:emptyp nyxt/minibuffer-mode::suggestion)
(trivial-clipboard:text nyxt/minibuffer-mode::suggestion))))
minibuffer-paste
Paste clipboard text to input.
(define-command (&optional (minibuffer (current-minibuffer)))
(bordeaux-threads:make-thread
(lambda ()
(trivial-clipboard:text
(or (ignore-errors (trivial-clipboard:text)) ""))
(ffi-within-renderer-thread *browser*
(lambda ()
(insert minibuffer
(ring-insert-clipboard
(clipboard-ring *browser*))))))))
select-previous
Select previous entry in minibuffer.
(define-command (&optional (minibuffer (current-minibuffer)))
(when (> (suggestion-cursor minibuffer) 0)
(decf (suggestion-cursor minibuffer))
(state-changed minibuffer)
(update-suggestions-display minibuffer)
(evaluate-script minibuffer
(parenscript:ps
(parenscript:chain
(parenscript:chain nyxt/minibuffer-mode::document
(nyxt/minibuffer-mode::get-element-by-id
"head"))
(nyxt/minibuffer-mode::scroll-into-view
nyxt/minibuffer-mode::false))))))
select-next
Select next entry in minibuffer.
(define-command (&optional (minibuffer (current-minibuffer)))
(when
(< (suggestion-cursor minibuffer)
(- (length (suggestions minibuffer)) 1))
(incf (suggestion-cursor minibuffer))
(state-changed minibuffer)
(update-suggestions-display minibuffer)
(evaluate-script minibuffer
(parenscript:ps
(parenscript:chain
(parenscript:chain nyxt/minibuffer-mode::document
(nyxt/minibuffer-mode::get-element-by-id
"selected"))
(nyxt/minibuffer-mode::scroll-into-view
nyxt/minibuffer-mode::false))))))
kill-whole-line
Delete all characters in the input.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::kill-line (input-cursor minibuffer))
(reset-suggestion-state minibuffer)
(state-changed minibuffer)
(update-display minibuffer))
kill-line
Delete all characters from cursor position until the end of the line.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::kill-forward-line (input-cursor minibuffer))
(reset-suggestion-state minibuffer)
(state-changed minibuffer)
(update-display minibuffer))
delete-backwards-word
Delete characters from cursor position until the beginning of the word at point.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::delete-backward-word (input-cursor minibuffer))
(reset-suggestion-state minibuffer)
(state-changed minibuffer)
(update-display minibuffer))
delete-forwards-word
Delete characters from cursor position until the end of the word at point.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::delete-forward-word (input-cursor minibuffer))
(reset-suggestion-state minibuffer)
(state-changed minibuffer)
(update-display minibuffer))
cursor-backwards-word
Move cursor to the beginning of the word at point.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::move-backward-word (input-cursor minibuffer)
:conservative-word-move
(conservative-word-move (current-buffer)))
(state-changed minibuffer)
(update-input-buffer-display minibuffer)
(cluffer:cursor-position (input-cursor minibuffer)))
cursor-forwards-word
Move cursor to the end of the word at point.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::move-forward-word (input-cursor minibuffer)
:conservative-word-move
(conservative-word-move (current-buffer)))
(state-changed minibuffer)
(update-input-buffer-display minibuffer)
(cluffer:cursor-position (input-cursor minibuffer)))
cursor-end
Move cursor to the end of the input area.
(define-command (&optional (minibuffer (current-minibuffer)))
(cluffer:end-of-line (input-cursor minibuffer))
(state-changed minibuffer)
(update-input-buffer-display minibuffer))
cursor-beginning
Move cursor to the beginning of the input area.
(define-command (&optional (minibuffer (current-minibuffer)))
(cluffer:beginning-of-line (input-cursor minibuffer))
(state-changed minibuffer)
(update-input-buffer-display minibuffer))
cursor-backwards
Move cursor backwards by one.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::safe-backward (input-cursor minibuffer))
(state-changed minibuffer)
(update-input-buffer-display minibuffer))
cursor-forwards
Move cursor forward by one.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::safe-forward (input-cursor minibuffer))
(state-changed minibuffer)
(update-input-buffer-display minibuffer))
delete-backwards
Delete character before cursor.
(define-command (&optional (minibuffer (current-minibuffer)))
(text-buffer::delete-item-backward (input-cursor minibuffer))
(reset-suggestion-state minibuffer)
(state-changed minibuffer)
(update-display minibuffer))
delete-forwards
Delete character after cursor.
(define-command (&optional (minibuffer (current-minibuffer)))
(cluffer:delete-item (input-cursor minibuffer))
(reset-suggestion-state minibuffer)
(state-changed minibuffer)
(update-display minibuffer))
self-insert
Insert last key from current window to the receiver.
(define-command (nyxt/minibuffer-mode::receiver)
(let ((nyxt/minibuffer-mode::key-string
(keymap:key-value (last-key (current-window))))
(nyxt/minibuffer-mode::translation-table
'(("hyphen" "-") ("space" " "))))
(setf nyxt/minibuffer-mode::key-string
(or
(cadr
(assoc nyxt/minibuffer-mode::key-string
nyxt/minibuffer-mode::translation-table :test
#'string=))
nyxt/minibuffer-mode::key-string))
(insert nyxt/minibuffer-mode::receiver nyxt/minibuffer-mode::key-string)))
self-insert-minibuffer
Self insert with the current minibuffer.
(define-command nil
(nyxt/minibuffer-mode:self-insert (current-minibuffer)))
cancel-input
Close the minibuffer query without further action.
(define-command (&optional (minibuffer (current-minibuffer)))
(calispel:! (interrupt-channel minibuffer) t)
(hide minibuffer))
return-input
Return with minibuffer input, ignoring the selection.
(define-command (&optional (minibuffer (current-minibuffer)))
(calispel:! (channel minibuffer) (input-buffer minibuffer))
(nyxt/minibuffer-mode::quit-minibuffer minibuffer))
return-selection
Return with minibuffer selection.
(define-command (&optional (minibuffer (current-minibuffer)))
(let ((nyxt/minibuffer-mode::result))
(with-slots (must-match-p suggestions suggestion-cursor invisible-input-p
multi-selection-p marked-suggestions)
minibuffer
(match (or marked-suggestions
(and suggestions (list (nth suggestion-cursor suggestions)))
(and (not must-match-p) (list (input-buffer minibuffer))))
((guard suggestions suggestions)
(setf suggestions
(mapcar
(lambda (nyxt/minibuffer-mode::suggestion)
(if (stringp nyxt/minibuffer-mode::suggestion)
(str:replace-all " " " "
nyxt/minibuffer-mode::suggestion)
nyxt/minibuffer-mode::suggestion))
suggestions))
(setf nyxt/minibuffer-mode::result
(if multi-selection-p
suggestions
(first suggestions))))
(nil
(when invisible-input-p
(setf nyxt/minibuffer-mode::result (input-buffer minibuffer))))))
(nyxt/minibuffer-mode::quit-minibuffer minibuffer)
(calispel:! (channel minibuffer) nyxt/minibuffer-mode::result)))
insert-suggestion-or-search-engine
Paste selected suggestion or search engine to input. If minibuffer input is not empty and the selection is on first position, complete against a search engine.
(define-command (&optional (minibuffer (current-minibuffer)))
(cond
((and (not (str:emptyp (input-buffer minibuffer)))
(zerop (suggestion-cursor minibuffer)))
(let* ((nyxt/minibuffer-mode::engines (search-engines (current-buffer)))
(nyxt/minibuffer-mode::matching-engines
(remove-if
(complement
(alex:curry #'str:starts-with-p (input-buffer minibuffer)))
nyxt/minibuffer-mode::engines :key #'shortcut)))
(match (length nyxt/minibuffer-mode::matching-engines)
(1 (nyxt/minibuffer-mode:kill-whole-line minibuffer)
(insert minibuffer
(str:concat
(shortcut (first nyxt/minibuffer-mode::matching-engines))
" ")))
(nyxt/minibuffer-mode::match-count
(let ((nyxt/minibuffer-mode::engine
(prompt-minibuffer :input-prompt "Search engine"
:input-buffer
(if (zerop
nyxt/minibuffer-mode::match-count)
""
(input-buffer minibuffer))
:suggestion-function
#'search-engine-suggestion-filter)))
(when nyxt/minibuffer-mode::engine
(nyxt/minibuffer-mode:kill-whole-line minibuffer)
(insert minibuffer
(str:concat (shortcut nyxt/minibuffer-mode::engine)
" "))))))))
(t (nyxt/minibuffer-mode:insert-suggestion minibuffer))))
set-url-mode
Minibuffer mode for setting the URL of a buffer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command SET-URL-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/minibuffer-mode:set-url-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance 'nyxt/minibuffer-mode:user-set-url-mode
:buffer buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/minibuffer-mode:set-url-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/minibuffer-mode:set-url-mode))))
buffer)
minibuffer-mode
Mode for the minibuffer.
(define-command (&rest args &key (buffer (current-buffer))
(activate t explicit?) &allow-other-keys)
(unless
(find 'buffer (metabang.moptilities:superclasses buffer) :key
#'class-name)
(error "Mode command MINIBUFFER-MODE called on non-buffer"))
(let ((#:existing-instance0
(find-mode buffer 'nyxt/minibuffer-mode:minibuffer-mode)))
(unless explicit? (setf activate (not #:existing-instance0)))
(if activate
(unless #:existing-instance0
(let ((#:new-mode1
(apply #'make-instance
'nyxt/minibuffer-mode:user-minibuffer-mode :buffer
buffer args)))
(when (constructor #:new-mode1)
(funcall-safely (constructor #:new-mode1) #:new-mode1))
(push #:new-mode1 (modes buffer))
(sera:run-hook (enable-hook #:new-mode1) #:new-mode1)
(sera:run-hook (enable-mode-hook buffer) #:new-mode1))
(print-status)
(log:debug "~a enabled." 'nyxt/minibuffer-mode:minibuffer-mode))
(when #:existing-instance0
(sera:run-hook (disable-hook #:existing-instance0)
#:existing-instance0)
(sera:run-hook (disable-mode-hook buffer) #:existing-instance0)
(when (destructor #:existing-instance0)
(funcall-safely (destructor #:existing-instance0)
#:existing-instance0))
(setf (modes buffer) (delete #:existing-instance0 (modes buffer)))
(print-status)
(log:debug "~a disabled." 'nyxt/minibuffer-mode:minibuffer-mode))))
buffer)
search-selection
Search selected text using the queried search engine.
(define-command nil
(let* ((selection (%copy))
(engine
(prompt-minibuffer :input-prompt "Search engine"
:suggestion-function
#'search-engine-suggestion-filter)))
(when engine
(buffer-load (generate-search-query selection (search-url engine))))))
toggle-toolbars
Toggle the visibility of the message and status buffer areas.
(define-command (&optional (window (current-window)))
(if (= 0 (ffi-window-get-status-buffer-height window)
(ffi-window-get-message-buffer-height window))
(unpresent-current-window window)
(present-current-window window)))
toggle-fullscreen
Fullscreen WINDOW, or the currently active window if unspecified.
(define-command (&optional (window (current-window)))
(if (fullscreen-p window)
(ffi-window-unfullscreen window)
(ffi-window-fullscreen window)))
make-window
Create a new window.
(define-command (&optional buffer)
(let ((window (window-make *browser*))
(buffer (or buffer (make-buffer :url :default))))
(window-set-active-buffer window buffer)
(values window buffer)))
delete-current-window
Delete WINDOW, or the currently active window if unspecified.
(define-command (&optional (window (current-window)))
(let ((window-count (hash-table-count (windows *browser*))))
(cond ((and window (> window-count 1)) (ffi-window-delete window))
(window (echo "Can't delete sole window.")))))
delete-window
Delete the queried window(s).
(define-command nil
(let ((windows
(prompt-minibuffer :input-prompt "Delete window(s)"
:multi-selection-p t :suggestion-function
(window-suggestion-filter))))
(mapcar #'delete-current-window windows)))
print-buffer
Print the current buffer.
(define-command nil
(%print-buffer))
open-inspector
Open the inspector, a graphical tool to inspect and change the content of the buffer.
(define-command nil
(ffi-inspector-show (current-buffer)))
enable-mode-for-buffer
Enable queried mode(s) for select buffer(s).
(define-command nil
(let ((buffers
(prompt-minibuffer :input-prompt "Enable mode(s) for buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(enable-mode-for-current-buffer :buffers buffers)))
enable-mode-for-current-buffer
Enable queried mode(s).
(define-command (&key (buffers (list (current-buffer))))
(let ((modes
(prompt-minibuffer :input-prompt "Enable mode(s)" :multi-selection-p
t :suggestion-function
(inactive-mode-suggestion-filter buffers))))
(dolist (buffer buffers) (enable-modes modes buffer))))
disable-mode-for-buffer
Disable queried mode(s) for select buffer(s).
(define-command nil
(let ((buffers
(prompt-minibuffer :input-prompt "Disable mode(s) for buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(disable-mode-for-current-buffer :buffers buffers)))
disable-mode-for-current-buffer
Disable queried mode(s).
(define-command (&key (buffers (list (current-buffer))))
(let ((modes
(prompt-minibuffer :input-prompt "Disable mode(s)"
:multi-selection-p t :suggestion-function
(active-mode-suggestion-filter buffers))))
(dolist (buffer buffers) (disable-modes modes buffer))))
switch-buffer-next
Switch to the oldest buffer in the list of buffers.
(define-command nil
(let* ((buffers (buffer-list :sort-by-time t))
(oldest-buffer (alex:last-elt buffers)))
(when (eq oldest-buffer (current-buffer))
(setf oldest-buffer (or (second (nreverse buffers)) oldest-buffer)))
(set-current-buffer oldest-buffer)))
switch-buffer-previous
Switch to the previous buffer in the list of buffers. That is to say, the one with the most recent access time after the current buffer. The current buffer access time is set to be the last so that if we keep calling this command it cycles through all buffers.
(define-command nil
(let* ((buffers (buffer-list :sort-by-time t))
(last-buffer (alex:last-elt buffers))
(current-buffer (current-buffer)))
(when (second buffers)
(set-current-buffer (second buffers))
(setf (last-access current-buffer)
(local-time:timestamp- (last-access last-buffer) 1 :sec)))))
reload-buffer
Reload queried buffer(s).
(define-command nil
(let ((buffers
(prompt-minibuffer :input-prompt "Reload buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(mapcar #'reload-current-buffer buffers)))
reload-current-buffer
Reload of BUFFER or current buffer if unspecified.
(define-command (&optional (buffer (current-buffer)))
(buffer-load (url buffer) :buffer buffer))
set-url-new-buffer
Prompt for a URL and set it in a new focused buffer.
(define-command nil
(set-url :new-buffer-p t))
set-url-from-current-url
Set the URL for the current buffer, pre-filling in the current URL.
(define-command nil
(set-url :prefill-current-url-p t))
set-url
Set the URL for the current buffer, completing with history.
(define-command (&key new-buffer-p prefill-current-url-p)
(let ((history (minibuffer-set-url-history *browser*)))
(when history
(metabang.cl-containers:insert-item history (url (current-buffer))))
(let ((url
(prompt-minibuffer :input-prompt
(format nil "Open URL in ~A buffer"
(if new-buffer-p
"new"
"current"))
:input-buffer
(if prefill-current-url-p
(object-string (url (current-buffer)))
"")
:default-modes '(set-url-mode minibuffer-mode)
:suggestion-function
(history-suggestion-filter :prefix-urls
(list
(object-string
(url
(current-buffer)))))
:history history :must-match-p nil)))
(when (typep url 'history-entry) (setf url (url url)))
(buffer-load url :buffer
(if new-buffer-p
(make-buffer-focus :url "")
(current-buffer))))))
delete-other-buffers
Delete all other buffers but `buffer` which if not explicitly set defaults to the currently active buffer.
(define-command (&optional (buffer (current-buffer)))
(let* ((all-buffers (buffer-list))
(buffers-to-delete (remove buffer all-buffers))
(count (list-length buffers-to-delete)))
(if-confirm ("Are you sure to delete ~a buffer~p?" count count)
(mapcar #'buffer-delete buffers-to-delete))))
delete-current-buffer
Delete the currently active buffer, and make the next buffer the visible buffer. If no other buffers exist, set the url of the current buffer to the start page.
(define-command (&optional (buffer (current-buffer)))
(buffer-delete buffer))
delete-all-buffers
Delete all buffers, with confirmation.
(define-command nil
(let ((count (length (buffer-list))))
(if-confirm ("Are you sure to delete ~a buffer~p?" count count)
(delete-buffers))))
reduce-to-buffer
Reduce the buffer(s) via minibuffer input and copy their titles/URLs to a single buffer, optionally delete them. This function is useful for archiving a set of useful URLs or preparing a list to send to a someone else.
(define-command (&key (delete t))
(let ((buffers
(prompt-minibuffer :input-prompt "Reduce buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(with-current-html-buffer (reduced-buffer "*Reduced Buffers*" 'base-mode)
(cl-markup:markup (:style (style reduced-buffer))
(:h1 "Reduced Buffers:")
(:div
(loop for buffer in buffers
collect (with-current-buffer buffer
(cl-markup:markup
(:div
(:p (:b "Title: ") (title buffer))
(:p (:b "URL: ")
(:a :href
(object-string (url buffer))
(object-string (url buffer))))
(:p
(:b
"Automatically generated summary: ")
(:ul
(loop for summary-bullet in (analysis:summarize-text
(document-get-paragraph-contents
:limit
10000))
collect (cl-markup:markup
(:li
(str:collapse-whitespaces
summary-bullet))))))
(:hr ""))))))))
(when delete (mapcar #'buffer-delete buffers))))
delete-buffer
Delete the buffer(s) via minibuffer input.
(define-command (&key id)
(if id
(buffer-delete (gethash id (slot-value *browser* 'buffers)))
(let ((buffers
(prompt-minibuffer :input-prompt "Delete buffer(s)"
:multi-selection-p t :suggestion-function
(buffer-suggestion-filter))))
(mapcar #'buffer-delete buffers))))
make-buffer-focus
Switch to a new buffer. See `make-buffer'.
(define-command (&key (url :default))
(let ((buffer (make-buffer :url url)))
(set-current-buffer buffer)
buffer))
switch-buffer-domain
Switch the active buffer in the current window from the current domain.
(define-command (&key domain (buffer (current-buffer)))
(let ((domain (or domain (quri.domain:uri-domain (url buffer)))))
(let ((buffer
(prompt-minibuffer :input-prompt
"Switch to buffer in current domain:"
:suggestion-function
(buffer-suggestion-filter :domain domain
:current-is-last-p
t))))
(set-current-buffer buffer))))
switch-buffer
Switch the active buffer in the current window.
(define-command (&key id)
(if id
(set-current-buffer (gethash id (slot-value *browser* 'buffers)))
(let ((buffer
(prompt-minibuffer :input-prompt "Switch to buffer"
:suggestion-function
(buffer-suggestion-filter :current-is-last-p
t))))
(set-current-buffer buffer))))
copy-title
Save current page title to clipboard.
(define-command nil
(copy-to-clipboard (title (current-buffer)))
(echo "~a copied to clipboard." (title (current-buffer))))
copy-url
Save current URL to clipboard.
(define-command nil
(copy-to-clipboard (object-string (url (current-buffer))))
(echo "~a copied to clipboard." (object-string (url (current-buffer)))))
make-internal-buffer
Create a new buffer. MODES is a list of mode symbols. If URL is `:default', use `default-new-buffer-url'.
(define-command (&key (title "") modes)
(buffer-make *browser* :title title :default-modes modes :internal-buffer-p
t))
make-buffer
Create a new buffer. MODES is a list of mode symbols. If URL is `:default', use `default-new-buffer-url'.
(define-command (&key (title "") modes (url ""))
(let* ((buffer (buffer-make *browser* :title title :default-modes modes))
(url
(if (eq url :default)
(default-new-buffer-url buffer)
url)))
(unless (url-empty-p url) (buffer-load url :buffer buffer))
buffer))
noop
A command that does nothing. This is useful to override bindings to do nothing.
(define-command nil
(values))