Package: emacs;
Reported by: Jaehwang Jerry Jung <tomtomjhj <at> gmail.com>
Date: Sun, 9 Feb 2020 08:16:02 UTC
Severity: wishlist
Tags: patch
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Jaehwang Jerry Jung <tomtomjhj <at> gmail.com> To: 39517 <at> debbugs.gnu.org Cc: Jaehwang Jerry Jung <tomtomjhj <at> gmail.com> 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
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.