mirror of
https://github.com/larstvei/Focus.git
synced 2025-04-19 20:40:13 +00:00
147 lines
5.4 KiB
Org Mode
147 lines
5.4 KiB
Org Mode
[[https://melpa.org/#/focus][file:https://melpa.org/packages/focus-badge.svg]]
|
|
[[https://stable.melpa.org/#/focus][file:https://stable.melpa.org/packages/focus-badge.svg]]
|
|
|
|
* Focus
|
|
|
|
[[./focus-demo.gif]]
|
|
|
|
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 [[https://melpa.org/#/focus][MELPA]] and [[https://stable.melpa.org/#/focus][MELPA Stable]]:
|
|
|
|
#+BEGIN_EXAMPLE
|
|
M-x package-install focus
|
|
#+END_EXAMPLE
|
|
|
|
* 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 [[https://www.emacswiki.org/emacs/ThingAtPoint][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
|
|
|
|
#+BEGIN_EXAMPLE
|
|
'((prog-mode . defun) (text-mode . sentence))
|
|
#+END_EXAMPLE
|
|
|
|
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:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(add-to-list 'focus-mode-to-thing '(python-mode . paragraph))
|
|
#+END_SRC
|
|
|
|
changes ~python-mode~ to focus in on code-blocks with no blank lines rather
|
|
than the entire function.
|
|
|
|
According to [[https://www.reddit.com/r/emacs/comments/b1vrar/lsp_support_for_focusel_using_lspmode/][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~:
|
|
#+begin_src emacs-lisp
|
|
(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)
|
|
)
|
|
#+end_src
|
|
|
|
** 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~.
|