diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index e7bd06e..f7e0ebc 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1720,10 +1720,12 @@ would be visually distracting. You can change this by customizing the variable @code{visual-line-fringe-indicators}. @vindex word-wrap-chars +@findex word-wrap-chars-mode Word boundaries and hence points at which word wrap can occur are, by default, considered to occur on the space and tab characters. If you prefer word-wrap to be permissible at other characters, you can -change the value of the char-table @code{word-wrap-chars}. +change the value of the char-table @code{word-wrap-chars}, or use +@code{word-wrap-chars-mode}, which does this for you. @node Display Custom @section Customization of Display diff --git a/etc/NEWS b/etc/NEWS index a87eabc..918380b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -66,6 +66,13 @@ using the new `word-wrap-chars' char-table. If `word-wrap-chars' is nil (the default), then word-wrapping will occur only on the space or tab characters, as has been the case until now. +The most convenient way to change the characters at which wrap occurs +is customizing the new variable `word-wrap-type' and using the new +`word-wrap-chars-mode' minor mode, which sets `word-wrap-chars' based +on `word-wrap-type', for you. The options for `word-wrap-type' are +ascii-whitespace, unicode-whitespace and a customizable list of +character codes and character code ranges. + * Changes in Specialized Modes and Packages in Emacs 27.1 diff --git a/lisp/simple.el b/lisp/simple.el index 24ecf69..e97ee10 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -6879,6 +6879,117 @@ Mode' for details." visual-line-mode turn-on-visual-line-mode) +(defvar word-wrap-type) + +(defvar word-wrap-chars--saved nil) + +(define-minor-mode word-wrap-chars-mode + "Toggle wrapping using a look-up to `word-wrap-chars'. +The exact choice of characters on which wrapping occurs, depends +on the value of `word-wrap-type'. By default, `word-wrap-type' +is set to unicode-white-space, which allows word wrapping on all +breakable unicode whitespace, not only space and tap. + +For details of other customization options, see +`word-wrap-type'. + +This minor mode has no effect unless `visual-line-mode' is +enabled or `word-wrap' is set to t. + +To toggle wrapping using a look-up, globally, use +`global-word-wrap-chars-mode'." + :group 'visual-line + :lighter " wwc" + (if word-wrap-chars-mode + (progn + (if (local-variable-p 'word-wrap-chars) + (setq-local word-wrap-chars--saved + word-wrap-chars)) + (set-word-wrap-chars)) + (setq-local word-wrap-chars word-wrap-chars--saved))) + +(defun turn-on-word-wrap-chars-mode () + (visual-line-mode 1)) + +(define-globalized-minor-mode global-word-wrap-chars-mode + word-wrap-chars-mode turn-on-word-wrap-chars-mode) + +(defun update-word-wrap-chars () + "Update `word-wrap-chars' upon Customize of `word-wrap-type'. + +Only buffers which use the `word-wrap-chars-mode' are affected." + (mapcar #'(lambda (buf) + (with-current-buffer buf + (if word-wrap-chars-mode + (set-word-wrap-chars)))) + (buffer-list))) + +(defun set-word-wrap-chars () + "Set `word-wrap-chars' locally, based on `word-wrap-type'." + (cond + ((eq word-wrap-type 'ascii-whitespace) + (setq-local word-wrap-chars nil)) + ((eq word-wrap-type 'unicode-whitespace) + (set-word-wrap-chars-from-list + '(9 32 5760 (8192 . 8198) (8200 . 8203) 8287 12288))) + ((listp word-wrap-type) + (set-word-wrap-chars-from-list word-wrap-type)))) + +(defun set-word-wrap-chars-from-list (list) + "Set `word-wrap-chars' locally from a list. +Each element of the list can be a character code (code point) or +a cons of character codes, representing the two (inclusive) +endpoints of the range of characters." + (setq-local + word-wrap-chars + (let ((char-table (make-char-table nil nil))) + (dolist (range list char-table) + (set-char-table-range char-table range t))))) + +(defcustom word-wrap-type + 'unicode-whitespace + "Characters on which word-wrap occurs. +This variable controls the value of `word-wrap-chars' that is set +by `word-wrap-chars-mode`. `word-wrap-chars' determines on what +characters word-wrapping can occur, when `word-wrap' is t or +`visual-line-mode' is enabled. + +Possible values are ascii-whitespace, unicode-whitespace or a +custom list of characters and character ranges. + +If the value is `ascii-whitespace', word-wrap is only on space +and tab. If the value is `unicode-whitespace', word-wrap is on +all the Unicode whitespace characters that permit wrapping, +including but not limited to space and tab. + +If a custom list of characters and ranges is used, word wrap is +on these characters and character ranges. The ranges are +inclusive of both endpoints. + +When you change this without using customize, you need to call +`update-word-wrap-chars' to update the word wrap in current +buffers. For instance: + +(setq word-wrap-type \\='(9 32 ?_)) +(update-word-wrap-chars) + +will set the wrappable characters to space, tab and underscore, +in all buffers in `word-wrap-chars-mode' and using the default +value of `word-wrap-type'. +" + :type '(choice (const :tag "Space and tab" ascii-whitespace) + (const :tag "All unicode spaces" unicode-whitespace) + (repeat :tag "Custom characters or ranges" + :value (9 32) + (choice (character) + (cons :tag "Range" character character)))) + :set (lambda (symbol value) + (set-default symbol value) + (update-word-wrap-chars)) + :group 'visual-line + :version 27.1) + + (defun transpose-chars (arg) "Interchange characters around point, moving forward one character. With prefix arg ARG, effect is to take character before point diff --git a/src/buffer.c b/src/buffer.c index 3e260bb..662fc72 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5734,7 +5734,8 @@ visual lines rather than logical lines. See the documentation of If `word-wrap-chars' is non-nil and a char-table, continuation lines are wrapped on the characters in `word-wrap-chars' whose value is t, -rather than the space and tab characters. */); +rather than the space and tab characters. `word-wrap-chars-mode +provides a convenient interface for using this. */); DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), Qstringp, diff --git a/src/character.c b/src/character.c index fd1a9d3..ff3b6d3 100644 --- a/src/character.c +++ b/src/character.c @@ -1149,6 +1149,10 @@ See The Unicode Standard for the meaning of those values. */); DEFVAR_LISP ("word-wrap-chars", Vword_wrap_chars, doc: /* A char-table for characters at which word-wrap occurs. Such characters have value t in this table. If the char-table is nil, -word-wrap occurs only on space and tab. */); +word-wrap occurs only on space and tab. + +For a more user-friendly way of changing the characters at which +word-wrap can occur, consider using `word-wrap-chars-mode' and +customizing `word-wrap-type'. */); Vword_wrap_chars = Qnil; }