diff --git a/modules/editor/word-wrap/README.org b/modules/editor/word-wrap/README.org index 2b6f37187..1f21da495 100644 --- a/modules/editor/word-wrap/README.org +++ b/modules/editor/word-wrap/README.org @@ -12,10 +12,10 @@ This module adds a minor-mode ~+word-wrap-mode~, which intelligently wraps long lines in the buffer without modifying the buffer content. -Wrapped lines will be indented to match the preceding line. Lines which are not -inside a comment will have extra indentation as determined by -~+word-wrap-extra-indent~. The default is to increase the indent by twice the -major-mode indent. +Wrapped lines will be indented to match the preceding line. In code buffers, +lines which are not inside a string or comment will have extra indentation as +determined by ~+word-wrap-extra-indent~. The default is to increase the indent +by twice the major-mode indent. The ~+word-wrap-extra-indent~ variable supports the following values: - ~double~: indent by twice the major-mode indentation @@ -29,6 +29,14 @@ automatically enable wrapping in most buffers. Wrapping will not be enabled in buffers whose major mode is marked "special", or are listed in ~+word-wrap-disabled-modes~. +The ~+word-wrap-text-modes~ variable lists modes which shouldn't have any extra +indentation, regardless of the ~+word-wrap-extra-indent~ setting. This is useful +for modes which are primarily text, such as ~text-mode~ and ~markdown-mode~. + +The ~+word-wrap-visual-modes~ variable lists modes which should only enable +~visual-line-mode~ and not provide any prefix indentation. This is useful for +modes like ~org-mode~ which handle prefix indentation themselves. + ** Module Flags This module provides no flags. @@ -49,12 +57,12 @@ To enable wrapping in a specific mode, add it to the appropriate hook in your (add-hook 'c-mode-common-hook #'+word-wrap-mode) #+END_SRC -To customize the extra indent for a specific mode: +To customize the behaviour in a specific mode: #+BEGIN_SRC emacs-lisp -;; enable word-wrap with fixed extra 2 spaces in org-mode -(add-hook! 'org-mode-hook - (setq-local +word-wrap-extra-indent 2) +;; use a single indent in json-mode +(add-hook! 'json-mode-hook + (setq-local +word-wrap-extra-indent 'single) (+word-wrap-mode +1)) #+END_SRC diff --git a/modules/editor/word-wrap/autoload.el b/modules/editor/word-wrap/autoload.el index f024dd6a0..53bec3372 100644 --- a/modules/editor/word-wrap/autoload.el +++ b/modules/editor/word-wrap/autoload.el @@ -1,7 +1,9 @@ ;;; editor/word-wrap/autoload.el -*- lexical-binding: t; -*- -(defvar +word-wrap--prev-adaptive-wrap-mode nil) -(defvar +word-wrap--prev-visual-line-mode nil) +(defvar +word-wrap--major-mode-is-visual nil) +(defvar +word-wrap--major-mode-is-text nil) +(defvar +word-wrap--enable-adaptive-wrap-mode nil) +(defvar +word-wrap--enable-visual-line-mode nil) (defvar +word-wrap--major-mode-indent-var nil) (defun +word-wrap--adjust-extra-indent-a (orig-fn beg end) @@ -11,7 +13,8 @@ (defun +word-wrap--calc-extra-indent (p) "Calculate extra word-wrap indentation at point." - (if (not (sp-point-in-comment p)) + (if (not (or +word-wrap--major-mode-is-text + (sp-point-in-string-or-comment p))) (pcase +word-wrap-extra-indent ('double (* 2 (symbol-value +word-wrap--major-mode-indent-var))) @@ -31,34 +34,45 @@ without modifying the buffer content. This is useful when dealing with legacy code which contains gratuitously long lines, or running emacs on your wrist-phone. -Wrapped lines will be indented to match the preceding line. Lines which are not -inside a comment will have additional indentation according to the configuration -of `+word-wrap-extra-indent'." +Wrapped lines will be indented to match the preceding line. In code buffers, +lines which are not inside a string or comment will have additional indentation +according to the configuration of `+word-wrap-extra-indent'." :init-value nil (if +word-wrap-mode (progn - (require 'adaptive-wrap) - (require 'dtrt-indent) ; for dtrt-indent--search-hook-mapping - (require 'smartparens) ; for sp-point-in-string-or-comment + (setq-local +word-wrap--major-mode-is-visual + (memq major-mode +word-wrap-visual-modes)) + (setq-local +word-wrap--major-mode-is-text + (memq major-mode +word-wrap-text-modes)) - (setq-local +word-wrap--prev-adaptive-wrap-mode adaptive-wrap-prefix-mode) - (setq-local +word-wrap--prev-visual-line-mode visual-line-mode) - (setq-local +word-wrap--major-mode-indent-var - (caddr (dtrt-indent--search-hook-mapping major-mode))) + (setq-local +word-wrap--enable-adaptive-wrap-mode + (and (not (bound-and-true-p adaptive-wrap-prefix-mode)) + (not +word-wrap--major-mode-is-visual))) - (advice-add #'adaptive-wrap-fill-context-prefix :around #'+word-wrap--adjust-extra-indent-a) + (setq-local +word-wrap--enable-visual-line-mode + (not (bound-and-true-p visual-line-mode))) - (unless +word-wrap--prev-adaptive-wrap-mode + (unless +word-wrap--major-mode-is-visual + (require 'dtrt-indent) ; for dtrt-indent--search-hook-mapping + (require 'smartparens) ; for sp-point-in-string-or-comment + + (setq-local +word-wrap--major-mode-indent-var + (caddr (dtrt-indent--search-hook-mapping major-mode))) + + (advice-add #'adaptive-wrap-fill-context-prefix :around #'+word-wrap--adjust-extra-indent-a)) + + (when +word-wrap--enable-adaptive-wrap-mode (adaptive-wrap-prefix-mode +1)) - (unless +word-wrap--prev-visual-line-mode + (when +word-wrap--enable-visual-line-mode (visual-line-mode +1))) ;; disable +word-wrap-mode - (advice-remove #'adaptive-wrap-fill-context-prefix #'+word-wrap--adjust-extra-indent-a) + (unless +word-wrap--major-mode-is-visual + (advice-remove #'adaptive-wrap-fill-context-prefix #'+word-wrap--adjust-extra-indent-a)) - (unless +word-wrap--prev-adaptive-wrap-mode + (when +word-wrap--enable-adaptive-wrap-mode (adaptive-wrap-prefix-mode -1)) - (unless +word-wrap--prev-visual-line-mode + (when +word-wrap--enable-visual-line-mode (visual-line-mode -1)))) (defun +word-wrap--enable-global-mode () diff --git a/modules/editor/word-wrap/config.el b/modules/editor/word-wrap/config.el index f45faa88b..2a6af06c7 100644 --- a/modules/editor/word-wrap/config.el +++ b/modules/editor/word-wrap/config.el @@ -1,15 +1,26 @@ ;;; editor/word-wrap/config.el -*- lexical-binding: t; -*- (defvar +word-wrap-extra-indent 'double - "The amount of extra indentation for wrapped non-comment lines. + "The amount of extra indentation for wrapped code lines. When 'double, indent by twice the major-mode indentation. When 'single, indent by the major-mode indentation. When a positive integer, indent by this fixed amount. When a negative integer, dedent by this fixed amount. + Otherwise no extra indentation will be used.") (defvar +word-wrap-disabled-modes '(fundamental-mode so-long-mode) "Major-modes where `+global-word-wrap-mode' should not enable - `+word-wrap-mode'.") +`+word-wrap-mode'.") + +(defvar +word-wrap-visual-modes + '(org-mode) + "Major-modes where `+word-wrap-mode' should not use +`adaptive-wrap-prefix-mode'.") + +(defvar +word-wrap-text-modes + '(text-mode markdown-mode markdown-view-mode gfm-mode gfm-view-mode rst-mode + latex-mode LaTeX-mode) + "Major-modes where `+word-wrap-mode' should not provide extra indentation.")