| focus-demo.gif | ||
| focus.el | ||
| README.org | ||
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.