From: Eli Zaretskii <eliz@gnu.org>
To: emacs-devel@gnu.org
Subject: Adjust point to move it off zero-width characters
Date: Sat, 06 Aug 2011 17:47:44 +0300 [thread overview]
Message-ID: <83bow2wq9b.fsf@gnu.org> (raw)
Is the patch below a good idea? If so, is it okay to install it on
the trunk? It will allow us to set the glyphless-char-display of LRM,
RLM, and the other directional control characters to zero-width and
thus make them invisible without having the cursor get "stuck" on
them and without using invisible or intangible text properties.
=== modified file 'src/dispextern.h'
--- src/dispextern.h 2011-08-05 11:04:44 +0000
+++ src/dispextern.h 2011-08-06 14:39:22 +0000
@@ -3098,6 +3098,9 @@ extern int cursor_in_mouse_face_p (struc
extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *,
int, int, enum draw_glyphs_face);
+extern Lisp_Object Qzero_width;
+extern Lisp_Object glyphless_char_display_method (int, struct frame *);
+
/* Flags passed to try_window. */
#define TRY_WINDOW_CHECK_MARGINS (1 << 0)
#define TRY_WINDOW_IGNORE_FONTS_CHANGE (1 << 1)
@@ -3113,6 +3116,7 @@ void compute_fringe_widths (struct frame
void w32_init_fringe (struct redisplay_interface *);
void w32_reset_fringes (void);
#endif
+
/* Defined in image.c */
#ifdef HAVE_WINDOW_SYSTEM
=== modified file 'src/keyboard.c'
--- src/keyboard.c 2011-08-04 17:04:39 +0000
+++ src/keyboard.c 2011-08-06 14:39:31 +0000
@@ -1721,11 +1721,13 @@ adjust_point_for_property (EMACS_INT las
user can keep inserting another character at point or keep
deleting characters around point. */
int check_composition = ! modified, check_display = 1, check_invisible = 1;
+ int check_glyphless = !modified;
EMACS_INT orig_pt = PT;
/* FIXME: cycling is probably not necessary because these properties
can't be usefully combined anyway. */
- while (check_composition || check_display || check_invisible)
+ while (check_composition || check_display || check_invisible
+ || check_glyphless)
{
/* FIXME: check `intangible'. */
if (check_composition
@@ -1733,7 +1735,7 @@ adjust_point_for_property (EMACS_INT las
&& (beg = composition_adjust_point (last_pt, PT)) != PT)
{
SET_PT (beg);
- check_display = check_invisible = 1;
+ check_display = check_invisible = check_glyphless = 1;
}
check_composition = 0;
if (check_display
@@ -1752,7 +1754,7 @@ adjust_point_for_property (EMACS_INT las
SET_PT (PT < last_pt
? (STRINGP (val) && SCHARS (val) == 0 ? beg - 1 : beg)
: end);
- check_composition = check_invisible = 1;
+ check_composition = check_invisible = check_glyphless = 1;
}
check_display = 0;
if (check_invisible && PT > BEGV && PT < ZV)
@@ -1823,7 +1825,7 @@ adjust_point_for_property (EMACS_INT las
was already in the range: we don't get to choose
which end of the range we have to go to. */
: (PT < last_pt ? beg : end));
- check_composition = check_display = 1;
+ check_composition = check_display = check_glyphless = 1;
}
#if 0 /* This assertion isn't correct, because SET_PT may end up setting
the point to something other than its argument, due to
@@ -1836,9 +1838,11 @@ adjust_point_for_property (EMACS_INT las
if (!modified && !ellipsis && beg < end)
{
if (last_pt == beg && PT == end && end < ZV)
- (check_composition = check_display = 1, SET_PT (end + 1));
+ (check_composition = check_display = check_glyphless = 1,
+ SET_PT (end + 1));
else if (last_pt == end && PT == beg && beg > BEGV)
- (check_composition = check_display = 1, SET_PT (beg - 1));
+ (check_composition = check_display = check_glyphless = 1,
+ SET_PT (beg - 1));
else if (PT == ((PT < last_pt) ? beg : end))
/* We've already moved as far as we can. Trying to go
to the other end would mean moving backwards and thus
@@ -1851,11 +1855,30 @@ adjust_point_for_property (EMACS_INT las
(make_number (PT == beg ? end : beg),
Qinvisible, Qnil),
!TEXT_PROP_MEANS_INVISIBLE (val)))
- (check_composition = check_display = 1,
+ (check_composition = check_display = check_glyphless = 1,
SET_PT (PT == beg ? end : beg));
}
}
check_invisible = 0;
+ if (check_glyphless)
+ {
+ Lisp_Object glyphless_method;
+
+ check_glyphless = 0;
+ if (PT >= BEGV && PT < ZV)
+ {
+ glyphless_method =
+ glyphless_char_display_method (FETCH_CHAR (PT_BYTE),
+ XFRAME (selected_frame));
+
+ if (EQ (glyphless_method, Qzero_width))
+ {
+ SET_PT (PT > BEGV && PT < last_pt ? PT - 1 : PT + 1);
+ check_glyphless = 1;
+ check_composition = check_display = check_invisible = 1;
+ }
+ }
+ }
}
}
=== modified file 'src/xdisp.c'
--- src/xdisp.c 2011-08-06 11:49:35 +0000
+++ src/xdisp.c 2011-08-06 14:00:43 +0000
@@ -770,7 +770,8 @@ Lisp_Object Qglyphless_char;
static Lisp_Object Qglyphless_char_display;
/* Method symbols for Vglyphless_char_display. */
-static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
+static Lisp_Object Qhex_code, Qempty_box, Qthin_space;
+Lisp_Object Qzero_width;
/* Default pixel width of `thin-space' display method. */
#define THIN_SPACE_WIDTH 1
@@ -6019,16 +6020,11 @@ static int (* get_next_element[NUM_IT_ME
FACE_FROM_ID ((IT)->f, (IT)->face_id), \
(IT)->string)))
-
-/* Lookup the char-table Vglyphless_char_display for character C (-1
- if we want information for no-font case), and return the display
- method symbol. By side-effect, update it->what and
- it->glyphless_method. This function is called from
- get_next_display_element for each character element, and from
- x_produce_glyphs when no suitable font was found. */
-
+/* A subroutine of lookup_glyphless_char_display. Also called from
+ keyboard.c, to adjust point position when it is on a glyphless
+ character whose display uses the zero-width method. */
Lisp_Object
-lookup_glyphless_char_display (int c, struct it *it)
+glyphless_char_display_method (int c, struct frame *f)
{
Lisp_Object glyphless_method = Qnil;
@@ -6039,13 +6035,27 @@ lookup_glyphless_char_display (int c, st
{
glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
if (CONSP (glyphless_method))
- glyphless_method = FRAME_WINDOW_P (it->f)
+ glyphless_method = FRAME_WINDOW_P (f)
? XCAR (glyphless_method)
: XCDR (glyphless_method);
}
else
glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
}
+ return glyphless_method;
+}
+
+/* Lookup the char-table Vglyphless_char_display for character C (-1
+ if we want information for no-font case), and return the display
+ method symbol. By side-effect, update it->what and
+ it->glyphless_method. This function is called from
+ get_next_display_element for each character element, and from
+ x_produce_glyphs when no suitable font was found. */
+
+Lisp_Object
+lookup_glyphless_char_display (int c, struct it *it)
+{
+ Lisp_Object glyphless_method = glyphless_char_display_method (c, it->f);
retry:
if (NILP (glyphless_method))
next reply other threads:[~2011-08-06 14:47 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-06 14:47 Eli Zaretskii [this message]
2011-08-07 16:13 ` Adjust point to move it off zero-width characters Stefan Monnier
2011-08-07 16:39 ` Eli Zaretskii
2011-08-07 16:46 ` Eli Zaretskii
2011-08-07 17:10 ` Eli Zaretskii
2011-08-08 0:50 ` Stefan Monnier
2011-08-08 3:02 ` Eli Zaretskii
2011-08-08 4:12 ` Stefan Monnier
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=83bow2wq9b.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=emacs-devel@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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.