bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#39517: [PATCH] Add new option 'word-wrap-boundary'


From: Jaehwang Jerry Jung
Subject: bug#39517: [PATCH] Add new option 'word-wrap-boundary'
Date: Sun, 9 Feb 2020 16:43:34 +0900

* src/buffer.c (syms_of_buffer): Define buffer-local variable
word-wrap-boundary.
* src/buffer.h (struct buffer): Add word_wrap_boundary_.
* src/xdisp.c (IT_DISPLAYING_WORD_WRAP_BOUNDARY): replaces
IT_DISPLAYING_WHITESPACE.
---
 etc/NEWS     |  5 +++++
 src/buffer.c | 16 ++++++++++++++--
 src/buffer.h |  3 +++
 src/xdisp.c  | 43 ++++++++++++++++++++++---------------------
 4 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 7b358ff271..40f432e5bb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -70,6 +70,11 @@ specify cursor-type to be '(box . SIZE)', the cursor becomes 
a hollow
 box if the point is on an image larger than 'SIZE' pixels in any
 dimension.
 
+** New option 'word-wrap-boundary'.
+This defines the characters that can be used as a wrapping boundary
+when 'word-wrap' is on. It defaults to " \t", the characters that had
+been hard-coded in the previous versions of Emacs.
+
 
 * Editing Changes in Emacs 28.1
 
diff --git a/src/buffer.c b/src/buffer.c
index cc7d4e4817..fa48461b2f 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -369,6 +369,11 @@ bset_word_wrap (struct buffer *b, Lisp_Object val)
   b->word_wrap_ = val;
 }
 static void
+bset_word_wrap_boundary (struct buffer *b, Lisp_Object val)
+{
+  b->word_wrap_boundary_ = val;
+}
+static void
 bset_zv_marker (struct buffer *b, Lisp_Object val)
 {
   b->zv_marker_ = val;
@@ -5168,6 +5173,7 @@ init_buffer_once (void)
   /* Make this one a permanent local.  */
   buffer_permanent_local_flags[idx++] = 1;
   XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, word_wrap_boundary), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, ctl_arrow), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, fill_column), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, left_margin), idx); ++idx;
@@ -5265,6 +5271,7 @@ init_buffer_once (void)
   XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
   bset_truncate_lines (&buffer_defaults, Qnil);
   bset_word_wrap (&buffer_defaults, Qnil);
+  bset_word_wrap_boundary (&buffer_defaults, build_string (" \t"));
   bset_ctl_arrow (&buffer_defaults, Qt);
   bset_bidi_display_reordering (&buffer_defaults, Qt);
   bset_bidi_paragraph_direction (&buffer_defaults, Qnil);
@@ -5752,8 +5759,8 @@ syms_of_buffer (void)
 
   DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil,
                     doc: /* Non-nil means to use word-wrapping for 
continuation lines.
-When word-wrapping is on, continuation lines are wrapped at the space
-or tab character nearest to the right window edge.
+When word-wrapping is on, continuation lines are wrapped at the character
+defined in `word-wrap-boundary` nearest to the right window edge.
 If nil, continuation lines are wrapped at the right screen edge.
 
 This variable has no effect if long lines are truncated (see
@@ -5768,6 +5775,11 @@ syms_of_buffer (void)
 visual lines rather than logical lines.  See the documentation of
 `visual-line-mode'.  */);
 
+  DEFVAR_PER_BUFFER ("word-wrap-boundary",
+                    &BVAR (current_buffer, word_wrap_boundary), Qstringp,
+                    doc: /* Characters that may cause line wrapping when 
`word-wrap` is on.
+" \\t" initially. */);
+
   DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
                     Qstringp,
                     doc: /* Name of default directory of current buffer.
diff --git a/src/buffer.h b/src/buffer.h
index fd05fdd37d..69707c4020 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -394,6 +394,9 @@ #define BVAR(buf, field) ((buf)->field ## _)
   /* Non-nil means to use word wrapping when displaying continuation lines.  */
   Lisp_Object word_wrap_;
 
+  /* Characters that may cause word wrapping.  */
+  Lisp_Object word_wrap_boundary_;
+
   /* Non-nil means display ctl chars with uparrow.  */
   Lisp_Object ctl_arrow_;
 
diff --git a/src/xdisp.c b/src/xdisp.c
index e41ceaf0bb..7e3710230c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -412,11 +412,12 @@ #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) false
 #endif /* HAVE_WINDOW_SYSTEM */
 
 /* Test if the display element loaded in IT, or the underlying buffer
-   or string character, is a space or a TAB character.  This is used
-   to determine where word wrapping can occur.  */
+   or string character, is a word wrap boundary character.  */
 
-#define IT_DISPLAYING_WHITESPACE(it)                                   \
-  ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))       \
+#define IT_DISPLAYING_WORD_WRAP_BOUNDARY(it)                           \
+  ((it->what == IT_CHARACTER                                           \
+    && strchr ((char *) SDATA (BVAR (current_buffer, word_wrap_boundary)), \
+               it->c))                                                 \
    || ((STRINGP (it->string)                                           \
        && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' '           \
            || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t'))     \
@@ -9078,12 +9079,12 @@ #define IT_RESET_X_ASCENT_DESCENT(IT)                   
\
        {
          if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
            {
-             if (IT_DISPLAYING_WHITESPACE (it))
+             if (IT_DISPLAYING_WORD_WRAP_BOUNDARY (it))
                may_wrap = true;
              else if (may_wrap)
                {
                  /* We have reached a glyph that follows one or more
-                    whitespace characters.  If the position is
+                    boundary characters.  If the position is
                     already found, we are done.  */
                  if (atpos_it.sp >= 0)
                    {
@@ -9228,10 +9229,10 @@ #define IT_RESET_X_ASCENT_DESCENT(IT)                   
\
                            {
                              bool can_wrap = true;
 
-                             /* If we are at a whitespace character
+                             /* If we are at a boundary character
                                 that barely fits on this screen line,
                                 but the next character is also
-                                whitespace, we cannot wrap here.  */
+                                boundary, we cannot wrap here.  */
                              if (it->line_wrap == WORD_WRAP
                                  && wrap_it.sp >= 0
                                  && may_wrap
@@ -9243,13 +9244,13 @@ #define IT_RESET_X_ASCENT_DESCENT(IT)                   
\
                                  SAVE_IT (tem_it, *it, tem_data);
                                  set_iterator_to_next (it, true);
                                  if (get_next_display_element (it)
-                                     && IT_DISPLAYING_WHITESPACE (it))
+                                     && IT_DISPLAYING_WORD_WRAP_BOUNDARY (it))
                                    can_wrap = false;
                                  RESTORE_IT (it, &tem_it, tem_data);
                                }
                              if (it->line_wrap != WORD_WRAP
                                  || wrap_it.sp < 0
-                                 /* If we've just found whitespace
+                                 /* If we've just found boundary
                                     where we can wrap, effectively
                                     ignore the previous wrap point --
                                     it is no longer relevant, but we
@@ -9322,19 +9323,19 @@ #define IT_RESET_X_ASCENT_DESCENT(IT)                   
\
                  else
                    IT_RESET_X_ASCENT_DESCENT (it);
 
-                 /* If the screen line ends with whitespace, and we
+                 /* If the screen line ends with boundary, and we
                     are under word-wrap, don't use wrap_it: it is no
                     longer relevant, but we won't have an opportunity
                     to update it, since we are done with this screen
                     line.  */
                  if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
                      /* If the character after the one which set the
-                        may_wrap flag is also whitespace, we can't
+                        may_wrap flag is also boundary, we can't
                         wrap here, since the screen line cannot be
-                        wrapped in the middle of whitespace.
+                        wrapped in the middle of boundary.
                         Therefore, wrap_it _is_ relevant in that
                         case.  */
-                     && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
+                     && !(moved_forward && IT_DISPLAYING_WORD_WRAP_BOUNDARY 
(it)))
                    {
                      /* If we've found TO_X, go back there, as we now
                         know the last word fits on this screen line.  */
@@ -23163,7 +23164,7 @@ #define RECORD_MAX_MIN_POS(IT)                          
        \
 
          if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
            {
-             if (IT_DISPLAYING_WHITESPACE (it))
+             if (IT_DISPLAYING_WORD_WRAP_BOUNDARY (it))
                may_wrap = true;
              else if (may_wrap)
                {
@@ -23308,10 +23309,10 @@ #define RECORD_MAX_MIN_POS(IT)                        
                \
                              /* Even if there is a previous wrap
                                 point, continue the line here as
                                 usual, if (i) the previous character
-                                was a space or tab AND (ii) the
-                                current character is not.  */
+                                was a boundary AND (ii) the current
+                                character is not.  */
                              && (!may_wrap
-                                 || IT_DISPLAYING_WHITESPACE (it)))
+                                 || IT_DISPLAYING_WORD_WRAP_BOUNDARY (it)))
                            goto back_to_wrap;
 
                          /* Record the maximum and minimum buffer
@@ -23342,10 +23343,10 @@ #define RECORD_MAX_MIN_POS(IT)                        
                \
                                       /* Even if there is a previous wrap
                                          point, continue the line here as
                                          usual, if (i) the previous character
-                                         was a space or tab AND (ii) the
-                                         current character is not.  */
+                                         was a boundary AND (ii) the current
+                                         character is not.  */
                                       && (!may_wrap
-                                          || IT_DISPLAYING_WHITESPACE (it)))
+                                          || IT_DISPLAYING_WORD_WRAP_BOUNDARY 
(it)))
                                goto back_to_wrap;
 
                            }
-- 
2.17.1






reply via email to

[Prev in Thread] Current Thread [Next in Thread]