From: Jaehwang Jerry Jung <tomtomjhj@gmail.com>
To: 39517@debbugs.gnu.org
Cc: Jaehwang Jerry Jung <tomtomjhj@gmail.com>
Subject: bug#39517: [PATCH] Add new option 'word-wrap-boundary'
Date: Sun, 9 Feb 2020 16:43:34 +0900 [thread overview]
Message-ID: <20200209074334.16270-1-tomtomjhj@gmail.com> (raw)
* 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.
+
\f
* 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
next reply other threads:[~2020-02-09 7:43 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-09 7:43 Jaehwang Jerry Jung [this message]
2020-02-09 15:34 ` bug#39517: [PATCH] Add new option 'word-wrap-boundary' Eli Zaretskii
2020-02-10 15:36 ` Jaehwang Jerry Jung
2020-02-10 16:10 ` Eli Zaretskii
2020-02-11 15:43 ` Jaehwang Jerry Jung
2020-08-09 11:23 ` Lars Ingebrigtsen
2020-08-09 14:11 ` Eli Zaretskii
2020-08-09 15:23 ` Jaehwang Jerry Jung
2020-08-09 15:25 ` Lars Ingebrigtsen
2020-08-09 15:44 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200209074334.16270-1-tomtomjhj@gmail.com \
--to=tomtomjhj@gmail.com \
--cc=39517@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).