5.4 KiB
Focus
This is Focus, a package that dims surrounding text. It works with any theme and can be configured to focus in on different regions like sentences, paragraphs or code-blocks.
Installation
It's available on MELPA and MELPA Stable:
M-x package-install focus
Usage
Enable focus-mode
with M-x focus-mode
.
A few interactive functions are provided:
Function | Description |
---|---|
focus-change-thing |
Adjust the narrowness of the focused section for the current buffer |
focus-pin |
Pin the focused section to its current location or the region, if active |
focus-unpin |
Unpin the focused section |
focus-next-thing |
Move the point to the middle of the Nth next thing |
focus-prev-thing |
Move the point to the middle of the Nth previous thing |
Focus relies on Thing At Point, which can retrieve a thing surrounding the
point. These things may be a symbol, list, S-expression (sexp), function
definition (defun), sentence, line, page and others. Calling M-x
focus-change-thing
allows you to interactively change the kind of region
which should be in focus.
Focus read-only mode
Enable focus-read-only-mode
with M-x focus-read-only-mode
. It inhibits
changes in a buffer, hides the cursor and provides bindings for moving
between things.
Some bindings for simple navigation and exiting `focus-read-only-mode` are provided.
Keybinding | Description |
---|---|
n |
Jump to next thing |
SPC |
Jump to next thing |
p |
Jump to previous thing |
S-SPC |
Jump to previous thing |
i |
Exit focus-read-only-mode |
q |
Exit focus-read-only-mode |
Customization
The choice of what thing is suitable for a mode may be configured by
setting the variable focus-mode-to-thing
. The default is
'((prog-mode . defun) (text-mode . sentence))
For modes inheriting prog-mode
(which are most programming modes), the
default is the function-body, and for modes inheriting text-mode
, the
default is a sentence.
For instance, adding the following to your .emacs
-file:
(add-to-list 'focus-mode-to-thing '(python-mode . paragraph))
changes python-mode
to focus in on code-blocks with no blank lines rather
than the entire function.
According to this reddit post, Focus plays nice with lsp-mode
.
Focus also works well with the built-in tree-sitter library which comes with
Emacs 29 or above. Below is an example configuration of using Focus with
pyton-ts-mode
:
(use-package focus
:config
(add-to-list 'focus-mode-to-thing '(python-ts-mode . py-thing))
)
(use-package treesit
;; Remember to run `treesit-install-language-grammar' to install the grammar
;; for each designated language.
:when
(and (fboundp 'treesit-available-p) (treesit-available-p))
:custom
(major-mode-remap-alist
(python-mode . python-ts-mode)
))
:config
;; define `py-thing' for `thing-at-point' so that the `focus-mode' can focus
;; on such python things.
(defvar py-thing--thing nil
"Store the thing at point. `thing-at-point' moves to the end of
the thing first. We should not re-run `py-thing' after that."
)
(defvar py-things-to-focus
'("class_definition"
"function_definition"
"try_statement"
"except_clause"
"if_statement"
"else_clause"
"for_statement"
"while_statement"
"module")
"Node types considered as python thing.")
(defun py-thing-begin ()
(when-let ((thing (or py-thing--thing (py-thing))))
(goto-char (treesit-node-start thing))))
(defun py-thing-end ()
(when-let ((thing (py-thing)))
(setq py-thing--thing thing)
(goto-char (treesit-node-end thing))))
(defun py-thing ()
(treesit-parent-until
(treesit-node-at (point))
(lambda (parent) (member (treesit-node-type parent) py-things-to-focus))))
(put 'py-thing 'beginning-op 'py-thing-begin)
(put 'py-thing 'end-op 'py-thing-end)
)
Faces
Focus offers two faces, one for the focused- and unfocused area. By default,
the focus-focused
is the empty face, meaning there is no change, and
focus-unfocused
inherits the comment face (which is usually subtle). The
faces can easily be customized via M-x list-faces-display
.