diff --git a/modules/editor/word-wrap/README.org b/modules/editor/word-wrap/README.org index 3e2199996..2ccc0952c 100644 --- a/modules/editor/word-wrap/README.org +++ b/modules/editor/word-wrap/README.org @@ -17,6 +17,7 @@ lines in the buffer without modifying the buffer content. ** Packages - [[doom-package:adaptive-wrap]] +- [[doom-package:visual-fill-column]] ** Hacks /No hacks documented for this module./ @@ -46,8 +47,8 @@ Word wrapping is not enabled by default. Wrapping can be toggled in the current buffer with ~M-x +word-wrap-mode~. The default doom bindings bind this to [[kbd:][SPC t w]] for ~evil~ users. -To enable wrapping in a specific mode, add it to the appropriate hook in your -~config.el~: +To enable wrapping in a specific mode, add it to the appropriate hook in +~$DOOMDIR/config.el~: #+begin_src emacs-lisp ;; enable word-wrap in C/C++/ObjC/Java (add-hook 'c-mode-common-hook #'+word-wrap-mode) @@ -55,9 +56,10 @@ To enable wrapping in a specific mode, add it to the appropriate hook in your To customize the behaviour in a specific mode: #+begin_src emacs-lisp -;; use a single indent in json-mode +;; use a single indent and wrap at fill-column in json-mode (add-hook! 'json-mode-hook - (setq-local +word-wrap-extra-indent 'single) + (setq-local +word-wrap-extra-indent 'single + +word-wrap-fill-style 'soft) (+word-wrap-mode +1)) #+end_src @@ -86,6 +88,13 @@ The ~+word-wrap-extra-indent~ variable supports the following values: - a negative integer: dedent by this fixed amount - ~nil~: no extra indent +Long lines are wrapped at the window margin by default, however soft-wrapping at +~fill-column~ is supported by setting ~+word-wrap-fill-style~. When set to +~auto~, if ~auto-fill-mode~ is enabled in the buffer, its behavior will not be +affected. This allows hard and soft wrapping methods to co-exist, with +hard-wrapping for new lines and soft-wrapping for existing lines. To disable +hard-wrapping entirely, set ~+word-wrap-fill-style~ to ~soft~. + This module also includes a global minor-mode ~+global-word-wrap-mode~ to automatically enable wrapping in most buffers. Wrapping will not be enabled in buffers whose major mode is marked "special", or are listed in diff --git a/modules/editor/word-wrap/autoload.el b/modules/editor/word-wrap/autoload.el index 6b382561a..de27b9aad 100644 --- a/modules/editor/word-wrap/autoload.el +++ b/modules/editor/word-wrap/autoload.el @@ -4,6 +4,8 @@ (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--enable-visual-fill-mode nil) +(defvar +word-wrap--disable-auto-fill-mode nil) (defvar +word-wrap--major-mode-indent-var nil) (defvar adaptive-wrap-extra-indent) @@ -15,7 +17,7 @@ (defun +word-wrap--calc-extra-indent (p) "Calculate extra word-wrap indentation at point." (if (not (or +word-wrap--major-mode-is-text - (sp-point-in-string-or-comment p))) + (doom-point-in-string-or-comment-p p))) (pcase +word-wrap-extra-indent ('double (* 2 (symbol-value +word-wrap--major-mode-indent-var))) @@ -30,33 +32,39 @@ (define-minor-mode +word-wrap-mode "Wrap long lines in the buffer with language-aware indentation. -This mode configures `adaptive-wrap' and `visual-line-mode' to wrap long lines -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. +This mode configures `adaptive-wrap', `visual-line-mode' and +`visual-fill-column-mode' to wrap long lines 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. 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'." +according to the configuration of `+word-wrap-extra-indent'. + +Long lines will wrap at the window margin by default, or can optionally be +wrapped at `fill-column' by configuring `+word-wrap-fill-style'." :init-value nil (if +word-wrap-mode (progn - (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--enable-adaptive-wrap-mode - (and (not (bound-and-true-p adaptive-wrap-prefix-mode)) - (not +word-wrap--major-mode-is-visual))) - - (setq-local +word-wrap--enable-visual-line-mode - (not (bound-and-true-p visual-line-mode))) + (setq-local + +word-wrap--major-mode-is-visual + (memq major-mode +word-wrap-visual-modes) + +word-wrap--major-mode-is-text + (memq major-mode +word-wrap-text-modes) + +word-wrap--enable-adaptive-wrap-mode + (and (not (bound-and-true-p adaptive-wrap-prefix-mode)) + (not +word-wrap--major-mode-is-visual)) + +word-wrap--enable-visual-line-mode + (not (bound-and-true-p visual-line-mode)) + +word-wrap--enable-visual-fill-mode + (and (not (bound-and-true-p visual-fill-column-mode)) + (memq +word-wrap-fill-style '(auto soft))) + +word-wrap--disable-auto-fill-mode + (and (bound-and-true-p auto-fill-function) + (eq +word-wrap-fill-style 'soft))) (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))) @@ -65,7 +73,11 @@ according to the configuration of `+word-wrap-extra-indent'." (when +word-wrap--enable-adaptive-wrap-mode (adaptive-wrap-prefix-mode +1)) (when +word-wrap--enable-visual-line-mode - (visual-line-mode +1))) + (visual-line-mode +1)) + (when +word-wrap--enable-visual-fill-mode + (visual-fill-column-mode +1)) + (when +word-wrap--disable-auto-fill-mode + (auto-fill-mode -1))) ;; disable +word-wrap-mode (unless +word-wrap--major-mode-is-visual @@ -74,7 +86,11 @@ according to the configuration of `+word-wrap-extra-indent'." (when +word-wrap--enable-adaptive-wrap-mode (adaptive-wrap-prefix-mode -1)) (when +word-wrap--enable-visual-line-mode - (visual-line-mode -1)))) + (visual-line-mode -1)) + (when +word-wrap--enable-visual-fill-mode + (visual-fill-column-mode -1)) + (when +word-wrap--disable-auto-fill-mode + (auto-fill-mode +1)))) (defun +word-wrap--enable-global-mode () "Enable `+word-wrap-mode' for `+word-wrap-global-mode'. diff --git a/modules/editor/word-wrap/config.el b/modules/editor/word-wrap/config.el index 968e71954..99e77ea35 100644 --- a/modules/editor/word-wrap/config.el +++ b/modules/editor/word-wrap/config.el @@ -10,6 +10,18 @@ When a negative integer, dedent by this fixed amount. Otherwise no extra indentation will be used.") +(defvar +word-wrap-fill-style nil + "How to handle `fill-column' in `+word-wrap-mode'. + +When 'auto, long lines will soft-wrap at `fill-column'. If `auto-fill-mode' is +enabled, its behaviour will not be affected. + +When 'soft, long lines will soft-wrap at `fill-column' and `auto-fill-mode' will +be forcibly disabled. + +Otherwise long lines will soft-wrap at the window margin and `auto-fill-mode' +will not be affected.") + (defvar +word-wrap-disabled-modes '(fundamental-mode so-long-mode) "Major-modes where `+global-word-wrap-mode' should not enable diff --git a/modules/editor/word-wrap/packages.el b/modules/editor/word-wrap/packages.el index dcafdd185..5e8637dfe 100644 --- a/modules/editor/word-wrap/packages.el +++ b/modules/editor/word-wrap/packages.el @@ -2,3 +2,4 @@ ;;; editor/word-wrap/packages.el (package! adaptive-wrap :pin "0d5b4a07de76d87dd64333a566a8a0a845f2b9f0") +(package! visual-fill-column :pin "453d698d7fc243a547665f8ba43c55eee574e0db")