commit efd3e78258c4d5238b58b59d7fdbfe1f141bbfd2 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Fri May 20 14:46:45 2022 +0800 Fix NS port warnings with GCC 12 * src/nsterm.m (ns_draw_glyphless_glyph_string_foreground): Clear s->char2b after function returns. diff --git a/src/nsterm.m b/src/nsterm.m index a1cbbff1cc..7fbfcf8c6d 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4180,6 +4180,10 @@ Function modeled after x_draw_glyph_string_box (). YES, YES); x += glyph->pixel_width; } + + /* GCC 12 complains even though nothing ever uses s->char2b after + this function returns. */ + s->char2b = NULL; } static void commit 726969a4b4e3e0f298b95a04d23e7a131d7abec7 Author: Po Lu Date: Fri May 20 05:34:04 2022 +0000 Remove flickering when toggling between different fullscreen states on Haiku * src/haiku_support.cc (FrameMoved): Don't allow moving the frame along the "filled" axis when fullwidth or fullheight. (ClearFullscreen): New argument `mode'. Return the previous rect but don't revert the frame to it if the target mode is not NONE. (SetFullscreen): Use rect provided by ClearFullscreen instead. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 0b3ab4cf4a..3961d33e4d 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1042,6 +1042,20 @@ class EmacsWindow : public BWindow BRect frame, decorator_frame; struct child_frame *f; + if (fullscreen_mode == FULLSCREEN_MODE_WIDTH + && new_position.x != 0) + { + MoveTo (0, new_position.y); + return; + } + + if (fullscreen_mode == FULLSCREEN_MODE_HEIGHT + && new_position.y != 0) + { + MoveTo (new_position.x, 0); + return; + } + rq.window = this; rq.x = std::lrint (new_position.x); rq.y = std::lrint (new_position.y); @@ -1159,34 +1173,46 @@ class EmacsWindow : public BWindow child_frame_lock.Unlock (); } - void - ClearFullscreen (void) + BRect + ClearFullscreen (enum haiku_fullscreen_mode target_mode) { + BRect original_frame; + switch (fullscreen_mode) { case FULLSCREEN_MODE_MAXIMIZED: - BWindow::Zoom (pre_zoom_rect.LeftTop (), - BE_RECT_WIDTH (pre_zoom_rect) - 1, - BE_RECT_HEIGHT (pre_zoom_rect) - 1); + original_frame = pre_zoom_rect; + + if (target_mode == FULLSCREEN_MODE_NONE) + BWindow::Zoom (pre_zoom_rect.LeftTop (), + BE_RECT_WIDTH (pre_zoom_rect) - 1, + BE_RECT_HEIGHT (pre_zoom_rect) - 1); break; case FULLSCREEN_MODE_BOTH: case FULLSCREEN_MODE_HEIGHT: case FULLSCREEN_MODE_WIDTH: - MoveTo (pre_fullscreen_rect.LeftTop ()); - ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect) - 1, - BE_RECT_HEIGHT (pre_fullscreen_rect) - 1); - + original_frame = pre_fullscreen_rect; SetFlags (Flags () & ~(B_NOT_MOVABLE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE)); + + if (target_mode != FULLSCREEN_MODE_NONE) + goto out; + + MoveTo (pre_fullscreen_rect.LeftTop ()); + ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect) - 1, + BE_RECT_HEIGHT (pre_fullscreen_rect) - 1); break; case FULLSCREEN_MODE_NONE: + original_frame = Frame (); break; } + out: fullscreen_mode = FULLSCREEN_MODE_NONE; + return original_frame; } BRect @@ -1211,17 +1237,17 @@ class EmacsWindow : public BWindow void SetFullscreen (enum haiku_fullscreen_mode mode) { - BRect zoom_rect; + BRect zoom_rect, frame; if (fullscreen_mode == mode) return; - ClearFullscreen (); + frame = ClearFullscreen (mode); switch (mode) { case FULLSCREEN_MODE_MAXIMIZED: - pre_zoom_rect = Frame (); + pre_zoom_rect = frame; zoom_rect = CalculateZoomRect (); BWindow::Zoom (zoom_rect.LeftTop (), BE_RECT_WIDTH (zoom_rect) - 1, @@ -1235,12 +1261,11 @@ class EmacsWindow : public BWindow case FULLSCREEN_MODE_HEIGHT: case FULLSCREEN_MODE_WIDTH: SetFlags (Flags () | B_NOT_ZOOMABLE | B_NOT_RESIZABLE); - pre_fullscreen_rect = Frame (); + pre_fullscreen_rect = frame; zoom_rect = FullscreenRectForMode (mode); ResizeTo (BE_RECT_WIDTH (zoom_rect) - 1, BE_RECT_HEIGHT (zoom_rect) - 1); MoveTo (zoom_rect.left, zoom_rect.top); - break; case FULLSCREEN_MODE_NONE: commit 242a4b49cb8397ae4eae0a3d7941e9d5afa16cd7 Author: Po Lu Date: Fri May 20 11:21:47 2022 +0800 Minor cleanups to X drag-and-drop code * src/xterm.c (struct x_client_list_window): Write comments describing the meaning of each field. (XM_DRAG_PROTOCOL_VERSION, xm_setup_dnd_targets) (xm_setup_drag_info, xm_read_drag_receiver_info) (x_dnd_compute_toplevels): Don't hard-code the supported Motif protocol version. diff --git a/src/xterm.c b/src/xterm.c index a8745894eb..a3b7c4ac25 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1015,36 +1015,67 @@ static unsigned int x_dnd_keyboard_state; terminating DND as part of the display disconnect handler. */ static jmp_buf x_dnd_disconnect_handler; +/* Structure describing a single window that can be the target of + drag-and-drop operations. */ struct x_client_list_window { + /* The window itself. */ Window window; + + /* The display that window is on. */ Display *dpy; + + /* Its X and Y coordinates from the root window. */ int x, y; + + /* The width and height of the window. */ int width, height; + + /* Whether or not the window is mapped. */ bool mapped_p; + + /* The event mask for the window before Emacs selected for events on + it. */ long previous_event_mask; + + /* The window manager state of the window. */ unsigned long wm_state; + /* The next window in this list. */ struct x_client_list_window *next; + + /* The Motif protocol style of this window, if any. */ uint8_t xm_protocol_style; + /* The extents of the frame window in each direction. */ int frame_extents_left; int frame_extents_right; int frame_extents_top; int frame_extents_bottom; #ifdef HAVE_XSHAPE + /* The border width of this window. */ int border_width; + /* The rectangles making up the input shape. */ XRectangle *input_rects; + + /* The number of rectangles composing the input shape. */ int n_input_rects; + /* The rectangles making up the bounding shape. */ XRectangle *bounding_rects; + + /* The number of rectangles composing the bounding shape. */ int n_bounding_rects; #endif }; -static struct x_client_list_window *x_dnd_toplevels = NULL; +/* List of all toplevels in stacking order, from top to bottom. */ +static struct x_client_list_window *x_dnd_toplevels; + +/* Whether or not the window manager supports the required features + for `x_dnd_toplevels' to work. */ static bool x_dnd_use_toplevels; /* Motif drag-and-drop protocol support. */ @@ -1224,6 +1255,10 @@ typedef struct xm_top_level_leave_message /* #define XM_DROP_SITE_INVALID 2 */ #define XM_DROP_SITE_NONE 1 +/* The version of the Motif drag-and-drop protocols that Emacs + supports. */ +#define XM_DRAG_PROTOCOL_VERSION 0 + static uint8_t xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action) { @@ -1637,7 +1672,7 @@ xm_setup_dnd_targets (struct x_display_info *dpyinfo, if (!rc) { header.byte_order = XM_BYTE_ORDER_CUR_FIRST; - header.protocol = 0; + header.protocol = XM_DRAG_PROTOCOL_VERSION; header.target_list_count = 1; header.total_data_size = 8 + 2 + ntargets * 4; @@ -1682,7 +1717,7 @@ xm_setup_dnd_targets (struct x_display_info *dpyinfo, xfree (recs); header.byte_order = XM_BYTE_ORDER_CUR_FIRST; - header.protocol = 0; + header.protocol = XM_DRAG_PROTOCOL_VERSION; header.target_list_count = 1; header.total_data_size = 8 + 2 + ntargets * 4; @@ -1719,7 +1754,7 @@ xm_setup_dnd_targets (struct x_display_info *dpyinfo, data format. To avoid confusing Motif when that happens, set it back to 0. There will probably be no more updates to the protocol either. */ - header.protocol = 0; + header.protocol = XM_DRAG_PROTOCOL_VERSION; xm_write_targets_table (dpyinfo->display, drag_window, dpyinfo->Xatom_MOTIF_DRAG_TARGETS, &header, recs); @@ -1749,7 +1784,7 @@ xm_setup_drag_info (struct x_display_info *dpyinfo, if (idx != -1) { drag_initiator_info.byteorder = XM_BYTE_ORDER_CUR_FIRST; - drag_initiator_info.protocol = 0; + drag_initiator_info.protocol = XM_DRAG_PROTOCOL_VERSION; drag_initiator_info.table_index = idx; drag_initiator_info.selection = dpyinfo->Xatom_XdndSelection; @@ -1977,6 +2012,9 @@ xm_read_drag_receiver_info (struct x_display_info *dpyinfo, rec->byteorder = XM_BYTE_ORDER_CUR_FIRST; } + if (data[1] > XM_DRAG_PROTOCOL_VERSION) + rc = 0; + if (tmp_data) XFree (tmp_data); @@ -2359,7 +2397,9 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo) && xcb_get_property_value_length (xm_property_reply) >= 4) { xmdata = xcb_get_property_value (xm_property_reply); - tem->xm_protocol_style = xmdata[2]; + + if (xmdata[1] <= XM_DRAG_PROTOCOL_VERSION) + tem->xm_protocol_style = xmdata[2]; } #endif commit 8a7d8bb04b38ba9849b60d63c9fcfd36856eb424 Author: Po Lu Date: Fri May 20 02:27:06 2022 +0000 Implement `cross-disabled-images' on Haiku * src/haiku_draw_support.cc (be_draw_cross_on_pixmap_1) (be_draw_cross_on_pixmap): New functions. * src/haiku_support.h: Update prototypes. * src/image.c (image_pixmap_draw_cross, image_disable_image): Implement drawing cross on Haiku. diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc index 551af51d7c..f0cc084bb3 100644 --- a/src/haiku_draw_support.cc +++ b/src/haiku_draw_support.cc @@ -503,3 +503,40 @@ BView_InvertRect (void *view, int x, int y, int width, int height) vw->InvertRect (BRect (x, y, x + width - 1, y + height - 1)); } + +static void +be_draw_cross_on_pixmap_1 (BBitmap *bitmap, int x, int y, int width, + int height, uint32_t color) +{ + BBitmap dest (bitmap->Bounds (), + bitmap->ColorSpace (), + true, false); + BView view (bitmap->Bounds (), NULL, B_FOLLOW_NONE, 0); + rgb_color high_color; + + rgb32_to_rgb_color (color, &high_color); + dest.ImportBits (bitmap); + + if (!dest.Lock ()) + return; + + dest.AddChild (&view); + + view.SetHighColor (high_color); + view.StrokeLine (BPoint (x, y), + BPoint (x + width - 1, y + height - 1)); + view.StrokeLine (BPoint (x, y + height - 1), + BPoint (x + width - 1, y)); + view.RemoveSelf (); + bitmap->ImportBits (&dest); +} + +void +be_draw_cross_on_pixmap (void *bitmap, int x, int y, int width, + int height, uint32_t color) +{ + BBitmap *target = (BBitmap *) bitmap; + + be_draw_cross_on_pixmap_1 (target, x, y, width, height, + color); +} diff --git a/src/haiku_support.h b/src/haiku_support.h index 0bfd027c0d..b66486b1dc 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -484,6 +484,8 @@ extern void hsl_color_rgb (double, double, double, uint32_t *); extern void *BBitmap_new (int, int, int); extern void *BBitmap_data (void *); extern int BBitmap_convert (void *, void **); +extern void be_draw_cross_on_pixmap (void *, int, int, int, int, + uint32_t); extern void BBitmap_free (void *); diff --git a/src/image.c b/src/image.c index 18e9e72d83..058c175570 100644 --- a/src/image.c +++ b/src/image.c @@ -6307,7 +6307,7 @@ image_edge_detection (struct frame *f, struct image *img, } -#if defined HAVE_X_WINDOWS || defined USE_CAIRO +#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_HAIKU static void image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap, int x, int y, unsigned int width, unsigned int height, @@ -6341,9 +6341,11 @@ image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap, XDrawLine (dpy, pixmap, gc, x, y, x + width - 1, y + height - 1); XDrawLine (dpy, pixmap, gc, x, y + height - 1, x + width - 1, y); XFreeGC (dpy, gc); -#endif /* HAVE_X_WINDOWS */ +#elif HAVE_HAIKU + be_draw_cross_on_pixmap (pixmap, x, y, width, height, color); +#endif } -#endif /* HAVE_X_WINDOWS || USE_CAIRO */ +#endif /* HAVE_X_WINDOWS || USE_CAIRO || HAVE_HAIKU */ /* Transform image IMG on frame F so that it looks disabled. */ @@ -6385,25 +6387,23 @@ image_disable_image (struct frame *f, struct image *img) { #ifndef HAVE_NTGUI #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */ -#ifndef HAVE_HAIKU -#ifndef USE_CAIRO +#if !defined USE_CAIRO && !defined HAVE_HAIKU #define CrossForeground(f) BLACK_PIX_DEFAULT (f) #define MaskForeground(f) WHITE_PIX_DEFAULT (f) -#else /* USE_CAIRO */ +#else /* USE_CAIRO || HAVE_HAIKU */ #define CrossForeground(f) 0 #define MaskForeground(f) PIX_MASK_DRAW -#endif /* USE_CAIRO */ +#endif /* USE_CAIRO || HAVE_HAIKU */ -#ifndef USE_CAIRO +#if !defined USE_CAIRO && !defined HAVE_HAIKU image_sync_to_pixmaps (f, img); -#endif /* !USE_CAIRO */ +#endif /* !USE_CAIRO && !HAVE_HAIKU */ image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height, CrossForeground (f)); if (img->mask) image_pixmap_draw_cross (f, img->mask, 0, 0, img->width, img->height, MaskForeground (f)); -#endif /* !HAVE_HAIKU */ #endif /* !HAVE_NS */ #else HDC hdc, bmpdc; commit 9d557d4d4adf68ca15ca9aaa48470133544ede26 Author: Lars Ingebrigtsen Date: Fri May 20 04:23:32 2022 +0200 Rename compare-window-configurations and update doc * doc/lispref/windows.texi (Window Configurations): Update name. * lisp/strokes.el (strokes-window-configuration-changed-p): * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Update callers and references. * lisp/subr.el (compare-window-configurations): Make into obsolete alias. * src/window.c (Fwindow_configuration_equal_p): Rename (bug#14964). diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 0bb873f3a9..90551e6697 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -6141,11 +6141,10 @@ configuration on the current frame. This function returns @code{t} if @var{object} is a window configuration. @end defun -@defun compare-window-configurations config1 config2 -This function compares two window configurations as regards the -structure of windows, but ignores the values of point and the -saved scrolling positions---it can return @code{t} even if those -aspects differ. +@defun window-configuration-equal-p config1 config2 +This function says whether two window configurations have the same +window layout, but ignores the values of point and the saved scrolling +positions---it can return @code{t} even if those aspects differ. @end defun @defun window-configuration-frame config diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index d3d8405d06..69795f9c11 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1368,7 +1368,7 @@ See Info node `(elisp) Integer Basics'." buffer-substring byte-code-function-p capitalize car-less-than-car car cdr ceiling char-after char-before char-equal char-to-string char-width compare-strings - compare-window-configurations concat coordinates-in-window-p + window-configuration-equal-p concat coordinates-in-window-p copy-alist copy-sequence copy-marker copysign cos count-lines current-time-string current-time-zone decode-char diff --git a/lisp/strokes.el b/lisp/strokes.el index dc242d8f33..5402ebf1e1 100644 --- a/lisp/strokes.el +++ b/lisp/strokes.el @@ -1036,8 +1036,8 @@ o Strokes are a bit computer-dependent in that they depend somewhat on (defun strokes-window-configuration-changed-p () "Non-nil if the `strokes-window-configuration' frame properties changed. This is based on the last time `strokes-window-configuration' was updated." - (compare-window-configurations (current-window-configuration) - strokes-window-configuration)) + (window-configuration-equal-p (current-window-configuration) + strokes-window-configuration)) (defun strokes-update-window-configuration () "Ensure that `strokes-window-configuration' is up-to-date." diff --git a/lisp/subr.el b/lisp/subr.el index 945587db53..6538d79050 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1874,6 +1874,9 @@ This was used internally by quail.el and keyboard.c in Emacs 27. It does nothing in Emacs 28.") (make-obsolete-variable 'inhibit--record-char nil "28.1") +(define-obsolete-function-alias 'compare-window-configurations + #'window-configuration-equal-p "29.1") + ;; We can't actually make `values' obsolete, because that will result ;; in warnings when using `values' in let-bindings. ;;(make-obsolete-variable 'values "no longer used" "28.1") diff --git a/src/window.c b/src/window.c index a87b4834aa..d3e8afd68a 100644 --- a/src/window.c +++ b/src/window.c @@ -8121,11 +8121,11 @@ compare_window_configurations (Lisp_Object configuration1, return true; } -DEFUN ("compare-window-configurations", Fcompare_window_configurations, - Scompare_window_configurations, 2, 2, 0, - doc: /* Compare two window configurations as regards the structure of windows. -This function ignores details such as the values of point -and scrolling positions. */) +DEFUN ("window-configuration-equal-p", Fwindow_configuration_equal_p, + Swindow_configuration_equal_p, 2, 2, 0, + doc: /* Say whether two window configurations have the same window layout. +This function ignores details such as the values of point and +scrolling positions. */) (Lisp_Object x, Lisp_Object y) { if (compare_window_configurations (x, y)) @@ -8613,7 +8613,7 @@ displayed after a scrolling operation to be somewhat inaccurate. */); defsubr (&Swindow_scroll_bars); defsubr (&Swindow_vscroll); defsubr (&Sset_window_vscroll); - defsubr (&Scompare_window_configurations); + defsubr (&Swindow_configuration_equal_p); defsubr (&Swindow_bump_use_time); defsubr (&Swindow_list); defsubr (&Swindow_list_1); diff --git a/test/lisp/ffap-tests.el b/test/lisp/ffap-tests.el index 0fdc31e8b6..4b580b5af5 100644 --- a/test/lisp/ffap-tests.el +++ b/test/lisp/ffap-tests.el @@ -73,7 +73,7 @@ left alone when opening a URL in an external browser." (urls nil) (ffap-url-fetcher (lambda (url) (push url urls) nil))) (should-not (ffap-other-window "https://www.gnu.org")) - (should (compare-window-configurations (current-window-configuration) old)) + (should (window-configuration-equal-p (current-window-configuration) old)) (should (equal urls '("https://www.gnu.org"))))) (defun ffap-test-string (space string) commit 7e32904998db6bcaff78c9329efa1fcbc26cbd70 Author: Lars Ingebrigtsen Date: Fri May 20 03:59:03 2022 +0200 Don't have the tutorial ask to save if we haven't moved * lisp/tutorial.el (tutorial--save-on-kill): Don't ask if the user hasn't moved point (bug#37326). (help-with-tutorial): Set the start point. diff --git a/lisp/tutorial.el b/lisp/tutorial.el index 0f3a1506d6..2c787ae559 100644 --- a/lisp/tutorial.el +++ b/lisp/tutorial.el @@ -649,13 +649,15 @@ with some explanatory links." (unless (eq prop-val 'key-sequence) (delete-region prop-start prop-end)))))) +(defvar tutorial--starting-point) (defun tutorial--save-on-kill () "Query the user about saving the tutorial when killing Emacs." (when (buffer-live-p tutorial--buffer) (with-current-buffer tutorial--buffer - (if (y-or-n-p "Save your position in the tutorial? ") - (tutorial--save-tutorial-to (tutorial--saved-file)) - (message "Tutorial position not saved")))) + (unless (= (point) tutorial--starting-point) + (if (y-or-n-p "Save your position in the tutorial? ") + (tutorial--save-tutorial-to (tutorial--saved-file)) + (message "Tutorial position not saved"))))) t) (defun tutorial--save-tutorial () @@ -734,7 +736,6 @@ See `tutorial--save-tutorial' for more information." (message "Can't save tutorial: %s is not a directory" tutorial-dir))))) - ;;;###autoload (defun help-with-tutorial (&optional arg dont-ask-for-revert) "Select the Emacs learn-by-doing tutorial. @@ -914,6 +915,7 @@ Run the Viper tutorial? ")) (forward-line 1) (newline (- n (/ n 2))))) (goto-char (point-min))) + (setq-local tutorial--starting-point (point)) (setq buffer-undo-list nil) (set-buffer-modified-p nil))))) commit d2865bfa2ca933b712b34507fe294dbcc047cdf0 Author: Po Lu Date: Fri May 20 01:49:43 2022 +0000 Implement more data type conversions for Haiku selections * src/haikuselect.c (haiku_message_to_lisp): (lisp_to_type_code): (haiku_lisp_to_message): (Fhaiku_drag_message): Recognize `double' and `float' types. (syms_of_haikuselect): New defsyms. diff --git a/src/haikuselect.c b/src/haikuselect.c index 313b26f6ba..6d03d6eb68 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -295,6 +295,14 @@ haiku_message_to_lisp (void *message) t1 = make_int ((intmax_t) *(ssize_t *) buf); break; + case 'DBLE': + t1 = make_float (*(double *) buf); + break; + + case 'FLOT': + t1 = make_float (*(float *) buf); + break; + default: t1 = make_uninit_string (buf_size); memcpy (SDATA (t1), buf, buf_size); @@ -353,6 +361,14 @@ haiku_message_to_lisp (void *message) t2 = Qpoint; break; + case 'DBLE': + t2 = Qdouble; + break; + + case 'FLOT': + t2 = Qfloat; + break; + default: t2 = make_int (type_code); } @@ -398,6 +414,10 @@ lisp_to_type_code (Lisp_Object obj) return 'SSZT'; else if (EQ (obj, Qpoint)) return 'BPNT'; + else if (EQ (obj, Qfloat)) + return 'FLOT'; + else if (EQ (obj, Qdouble)) + return 'DBLE'; else return -1; } @@ -416,7 +436,8 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) ssize_t ssizet_data; intmax_t t4; uintmax_t t5; - float t6, t7; + float t6, t7, float_data; + double double_data; int rc; specpdl_ref ref; @@ -520,6 +541,30 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) signal_error ("Invalid point", data); break; + case 'FLOT': + CHECK_NUMBER (data); + float_data = XFLOATINT (data); + + rc = be_add_message_data (message, SSDATA (name), + type_code, &float_data, + sizeof float_data); + + if (rc) + signal_error ("Failed to add float", data); + break; + + case 'DBLE': + CHECK_NUMBER (data); + double_data = XFLOATINT (data); + + rc = be_add_message_data (message, SSDATA (name), + type_code, &double_data, + sizeof double_data); + + if (rc) + signal_error ("Failed to add double", data); + break; + case 'SHRT': if (!TYPE_RANGED_FIXNUMP (int16, data)) signal_error ("Invalid value", data); @@ -734,6 +779,10 @@ system. If TYPE is `ssize_t', then DATA is an integer that can hold values from -1 to the maximum value of the C data type `ssize_t' on the current system. If TYPE is `point', then DATA is a cons of float values describing the X and Y coordinates of an on-screen location. +If TYPE is `float', then DATA is a low-precision floating point +number, whose exact precision is not guaranteed. If TYPE is `double', +then DATA is a floating point number that can represent any value a +Lisp float can represent. If the field name is not a string but the symbol `type', then it associates to a 32-bit unsigned integer describing the type of the @@ -928,6 +977,8 @@ used to retrieve the current position of the mouse. */); DEFSYM (Qsize_t, "size_t"); DEFSYM (Qssize_t, "ssize_t"); DEFSYM (Qpoint, "point"); + DEFSYM (Qfloat, "float"); + DEFSYM (Qdouble, "double"); DEFSYM (Qalready_running, "already-running"); defsubr (&Shaiku_selection_data); commit de9dfb1939caba80fd4acc42789794f5c9273df8 Author: Lars Ingebrigtsen Date: Fri May 20 03:46:35 2022 +0200 Fix font-locking of (defun foo (function ...)) * lisp/emacs-lisp/lisp-mode.el (lisp--el-funcall-position-p): Don't colorize the `function' in (defun foo (function ...)) as a special form (bug#37074). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 5dd2f5162e..5b93f145e8 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -244,6 +244,9 @@ ('let (forward-sexp 1) (>= pos (point))) + ((or 'defun 'defmacro 'cl-defmethod 'cl-defun) + (forward-sexp 2) + (>= pos (point))) ('condition-case ;; If (cdr paren-posns), then we're in the BODY ;; of HANDLERS. commit 871f0f0a5de2b30944348ad9bf708cb8611b27fe Author: Lars Ingebrigtsen Date: Fri May 20 03:38:27 2022 +0200 Make diff--font-lock-prettify do less if we don't have a left fringe * lisp/vc/diff-mode.el (diff--font-lock-prettify): Don't remove insert/deletions from the buffer if we don't have a left fringe (bug#37019). diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 5c13c7fc38..0fd67422d5 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2600,19 +2600,21 @@ fixed, visit it in a buffer." (defun diff--font-lock-prettify (limit) (when diff-font-lock-prettify - (save-excursion - ;; FIXME: Include the first space for context-style hunks! - (while (re-search-forward "^[-+! ]" limit t) - (unless (eq (get-text-property (match-beginning 0) 'face) 'diff-header) - (let ((spec - (alist-get - (char-before) - '((?+ . (left-fringe diff-fringe-add diff-indicator-added)) - (?- . (left-fringe diff-fringe-del diff-indicator-removed)) - (?! . (left-fringe diff-fringe-rep diff-indicator-changed)) - (?\s . (left-fringe diff-fringe-nul fringe)))))) - (put-text-property (match-beginning 0) (match-end 0) - 'display spec))))) + (when (> (frame-parameter nil 'left-fringe) 0) + (save-excursion + ;; FIXME: Include the first space for context-style hunks! + (while (re-search-forward "^[-+! ]" limit t) + (unless (eq (get-text-property (match-beginning 0) 'face) + 'diff-header) + (put-text-property + (match-beginning 0) (match-end 0) + 'display + (alist-get + (char-before) + '((?+ . (left-fringe diff-fringe-add diff-indicator-added)) + (?- . (left-fringe diff-fringe-del diff-indicator-removed)) + (?! . (left-fringe diff-fringe-rep diff-indicator-changed)) + (?\s . (left-fringe diff-fringe-nul fringe))))))))) ;; Mimicks the output of Magit's diff. ;; FIXME: This has only been tested with Git's diff output. ;; FIXME: Add support for Git's "rename from/to"? commit 4d7390576b1fdc385e48ae9eab19f70c82643c0c Author: Lars Ingebrigtsen Date: Fri May 20 03:24:30 2022 +0200 Add a new command 'yank-in-context' * lisp/simple.el (escaped-string-quote): New variable. (yank-in-context): New command. (yank-in-context--transform): Helper function. * lisp/progmodes/sh-script.el (sh-mode): Set up an escaped-string-quote function. * lisp/progmodes/sql.el (sql-mode): Define escaped-string-quote. diff --git a/etc/NEWS b/etc/NEWS index 6185c6ff6a..26b9b19952 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2201,6 +2201,10 @@ the clipboard, and insert it into the buffer. ** New user option 'yank-transform-functions'. This function allows the user to alter the string to be inserted. +--- +** New command 'yank-in-context'. +This command tries to preserve string/comment syntax when yanking. + --- ** New function 'minibuffer-lazy-highlight-setup'. This function allows setting up the minibuffer so that lazy diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index e48fa0668b..8205218ce1 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1543,6 +1543,11 @@ with your script for an edit-interpret-debug cycle." (add-hook 'completion-at-point-functions #'sh-completion-at-point-function nil t) (setq-local outline-regexp "###") + (setq-local escaped-string-quote + (lambda (terminator) + (if (eq terminator ?') + "'\\'" + "\\"))) ;; Parse or insert magic number for exec, and set all variables depending ;; on the shell thus determined. (sh-set-shell diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 7bb4fef0c0..8d25986090 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -4159,6 +4159,7 @@ must tell Emacs. Here's how to do that in your init file: (setq-local abbrev-all-caps 1) ;; Contains the name of database objects (setq-local sql-contains-names t) + (setq-local escaped-string-quote "'") (setq-local syntax-propertize-function (syntax-propertize-rules ;; Handle escaped apostrophes within strings. diff --git a/lisp/simple.el b/lisp/simple.el index 66e1b94f0f..c80af7c37b 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -60,6 +60,24 @@ value of 1 means that nothing is amalgamated.") (defgroup paren-matching nil "Highlight (un)matching of parens and expressions." :group 'matching) + +(defvar-local escaped-string-quote "\\" + "String to insert before a string quote character in a string to escape it. +This is typically a backslash (in most languages): + + \\='foo\\\\='bar\\=' + \"foo\\\"bar\" + +But in SQL, for instance, it's \"\\='\": + + \\='foo\\='\\='bar\\=' + +This can also be a function, which is called with the string +terminator as the argument, and should return a string to be +used as the escape. + +This variable is used by the `yank-in-context' command.") + ;;; next-error support framework @@ -6013,6 +6031,9 @@ Properties listed in `yank-handled-properties' are processed, then those listed in `yank-excluded-properties' are discarded. STRING will be run through `yank-transform-functions'. +`yank-in-context' is a command that uses this mechanism to +provide a `yank' alternative that conveniently preserves +string/comment syntax. If STRING has a non-nil `yank-handler' property anywhere, the normal insert behavior is altered, and instead, for each contiguous @@ -6064,6 +6085,88 @@ With ARG, rotate that many kills forward (or backward, if negative)." (interactive "p") (current-kill arg)) +(defun yank-in-context (&optional arg) + "Insert the last stretch of killed text while preserving syntax. +In particular, if point is inside a string, any quote characters +in the killed text will be quoted, so that the string remains a +valid string. + +If point is inside a comment, ensure that the inserted text is +also marked as a comment. + +This command otherwise behaves as `yank'. See that command for +explanation of ARG. + +This function uses the `escaped-string-quote' buffer-local +variable to determine how strings should be escaped." + (interactive "*P") + (let ((yank-transform-functions (cons #'yank-in-context--transform + yank-transform-functions))) + (yank arg))) + +(defun yank-in-context--transform (string) + (let ((ppss (syntax-ppss))) + (cond + ;; We're in a string. + ((ppss-string-terminator ppss) + (string-replace + (string (ppss-string-terminator ppss)) + (concat (if (functionp escaped-string-quote) + (funcall escaped-string-quote + (ppss-string-terminator ppss)) + escaped-string-quote) + (string (ppss-string-terminator ppss))) + string)) + ;; We're in a comment. + ((or (ppss-comment-depth ppss) + (and (bolp) + (not (eobp)) + ;; If we're in the middle of a bunch of commented text, + ;; we probably want to be commented. This is quite DWIM. + (or (bobp) + (save-excursion + (forward-line -1) + (forward-char 1) + (ppss-comment-depth (syntax-ppss)))) + (ppss-comment-depth + (setq ppss (save-excursion + (forward-char 1) + (syntax-ppss)))))) + (cond + ((and (eq (ppss-comment-depth ppss) t) + (> (length comment-end) 0) + (string-search comment-end string)) + (user-error "Can't insert a string containing a comment terminator in a comment")) + ;; If this is a comment syntax that has an explicit end, then + ;; we can just insert as is. + ((> (length comment-end) 0) string) + ;; Line-based comment formats. + ((or (string-search "\n" string) + (bolp)) + (let ((mode major-mode) + (bolp (bolp)) + (eolp (eolp)) + (comment-style 'plain)) + (with-temp-buffer + (funcall mode) + (insert string) + (when (string-match-p "\n\\'" string) + (cond + ((not eolp) (delete-char -1)) + (bolp (insert "\n")))) + (comment-normalize-vars) + (comment-region-default-1 + (if bolp + (point-min) + (save-excursion + (goto-char (point-min)) + (forward-line 1) + (point))) + (point-max) nil t) + (buffer-string)))) + (t string))) + (t string)))) + (defvar read-from-kill-ring-history) (defun read-from-kill-ring (prompt) "Read a `kill-ring' entry using completion and minibuffer history. diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index dcab811bb5..437c62f61d 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -971,5 +971,39 @@ See Bug#21722." ;;(should (= (length (delq nil (undo-make-selective-list 5 9))) 0)) (should (= (length (delq nil (undo-make-selective-list 6 9))) 0)))) +(ert-deftest test-yank-in-context () + (should + (equal + (with-temp-buffer + (sh-mode) + (insert "echo \"foo\"") + (kill-new "\"bar\"") + (goto-char 8) + (yank-in-context) + (buffer-string)) + "echo \"f\\\"bar\\\"oo\"")) + + (should + (equal + (with-temp-buffer + (sh-mode) + (insert "echo \"foo\"") + (kill-new "'bar'") + (goto-char 8) + (yank-in-context) + (buffer-string)) + "echo \"f'bar'oo\"")) + + (should + (equal + (with-temp-buffer + (sh-mode) + (insert "echo 'foo'") + (kill-new "'bar'") + (goto-char 8) + (yank-in-context) + (buffer-string)) + "echo 'f'\\''bar'\\''oo'"))) + (provide 'simple-test) ;;; simple-tests.el ends here commit 10411697468ebfcae93ffb48ca773d5321c8a5ec Author: Po Lu Date: Fri May 20 09:11:38 2022 +0800 Fix session management detection of the first X display * src/xterm.c (x_term_init): Check that there is no other display in the chain instead of testing the terminal ID. diff --git a/src/xterm.c b/src/xterm.c index db3f41e688..a8745894eb 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -24719,7 +24719,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) /* Only do this for the very first display in the Emacs session. Ignore X session management when Emacs was first started on a tty or started as a daemon. */ - if (terminal->id == 1 && ! IS_DAEMON) + if (!dpyinfo->next && ! IS_DAEMON) x_session_initialize (dpyinfo); #endif commit 8f3e0ed2b99b9b2ad42693cab2b3c0c291e3c3d0 Author: Lars Ingebrigtsen Date: Fri May 20 02:09:43 2022 +0200 Clarify yank-transform-functions doc string * lisp/simple.el (yank-transform-functions): Clarify calling convention. diff --git a/lisp/simple.el b/lisp/simple.el index bed72457c3..66e1b94f0f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5932,7 +5932,11 @@ See also `yank-handled-properties'." "List of functions to run on strings to be yanked. Each function in this list will be called (in order) with the string to be yanked as the sole argument, and should return the (possibly) - transformed string." +transformed string. + +The functions will be called from the buffer the string will be +inserted, and with point at the place where the string is to be +inserted." :type '(repeat function) :version "29.1" :group 'killing) commit 9e338b7456f652259d944d9973fe1790079dbb13 Author: Lars Ingebrigtsen Date: Fri May 20 02:02:12 2022 +0200 Make completion in emacs-lisp-mode intern fewer symbols * lisp/progmodes/elisp-mode.el (elisp-completion-at-point): Don't intern the string before point just to check whether we're looking at `ignore-error' (bug#55491). diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 37fd4fdb3c..70826b4c3a 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -627,13 +627,13 @@ functions are annotated with \"\" via the ;; t if in function position. (funpos (eq (char-before beg) ?\()) (quoted (elisp--form-quoted-p beg)) - (fun-sym (condition-case nil - (save-excursion - (up-list -1) - (forward-char 1) - (and (memq (char-syntax (char-after)) '(?w ?_)) - (read (current-buffer)))) - (error nil)))) + (is-ignore-error + (condition-case nil + (save-excursion + (up-list -1) + (forward-char 1) + (looking-at-p "ignore-error\\>")) + (error nil)))) (when (and end (or (not (nth 8 (syntax-ppss))) (memq (char-before beg) '(?` ?‘)))) (let ((table-etc @@ -642,7 +642,7 @@ functions are annotated with \"\" via the ;; FIXME: We could look at the first element of ;; the current form and use it to provide a more ;; specific completion table in more cases. - ((eq fun-sym 'ignore-error) + (is-ignore-error (list t (elisp--completion-local-symbols) :predicate (lambda (sym) (get sym 'error-conditions)))) commit 1c737673032422e0eaf40427b2ec5124747b2f94 Author: Lars Ingebrigtsen Date: Fri May 20 01:35:58 2022 +0200 Make `&' in dired be more consistent wrt. user input * lisp/dired-aux.el (dired-do-async-shell-command): Mention that commands here don't accept input. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index d2bac5c467..a98425d129 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -819,7 +819,9 @@ are executed in the background on each file sequentially waiting for each command to terminate before running the next command. In shell syntax this means separating the individual commands with `;'. -The output appears in the buffer named by `shell-command-buffer-name-async'." +The output appears in the buffer named by `shell-command-buffer-name-async'. + +Commands that are run asynchronously do not accept user input." (interactive (let ((files (dired-get-marked-files t current-prefix-arg nil nil t))) (list @@ -997,7 +999,13 @@ Also see the `dired-confirm-shell-command' variable." (when (cdr file-list) (setq files (concat dired-mark-prefix files dired-mark-postfix))) (funcall stuff-it files)))) - (or (and in-background "&") "")))) + (or (and in-background + (if (not w32-shell) + ;; Work the same as the `on-each' case -- don't + ;; accept user input in the output buffer. + "&wait" + "&")) + "")))) ;; This is an extra function so that it can be redefined by ange-ftp. ;;;###autoload commit 7fe33b6ba0823d4794417ef205ee1f011c09db0b Author: Lars Ingebrigtsen Date: Fri May 20 01:17:02 2022 +0200 Add new command 'enriched-toggle-markup' * lisp/textmodes/enriched.el (enriched-toggle-markup): New command (bug#33855). diff --git a/etc/NEWS b/etc/NEWS index c3bc1f0f58..6185c6ff6a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -816,6 +816,13 @@ so automatically. * Changes in Specialized Modes and Packages in Emacs 29.1 +** Enriched Mode + +--- +*** New command 'enriched-toggle-markup'. +This allows you to see the markup in 'enriched-mode' buffers (e.g., +the HELLO file). + ** Shell Script Mode --- @@ -2190,6 +2197,7 @@ platforms. This command lets you examine all data in the current selection and the clipboard, and insert it into the buffer. ++++ ** New user option 'yank-transform-functions'. This function allows the user to alter the string to be inserted. diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el index 50ff668a9f..935be06812 100644 --- a/lisp/textmodes/enriched.el +++ b/lisp/textmodes/enriched.el @@ -539,6 +539,30 @@ the range of text to assign text property SYMBOL with value VALUE." (list start end 'display prop) (list start end 'display (list 'disable-eval prop))))) +(defvar enriched--markup-shown) +(defun enriched-toggle-markup () + "Toggle whether to see markup in the current buffer." + (interactive) + (save-excursion + (save-restriction + (widen) + (with-silent-modifications + (if (bound-and-true-p enriched--markup-shown) + (progn + (setq-local enriched--markup-shown nil) + ;; Remove any faces, because they will be decoded, too. + (goto-char (point-min)) + (let (match) + (while (setq match (text-property-search-forward 'face)) + (put-text-property (prop-match-beginning match) + (prop-match-end match) + 'face nil))) + (enriched-decode (point-min) (point-max)) + (enriched-mode 1)) + (setq-local enriched--markup-shown t) + (enriched-encode (point-min) (point-max) (current-buffer)) + (enriched-mode -1)))))) + (provide 'enriched) ;;; enriched.el ends here commit c9a8a47ba4b8cda05c48fff4259ce8f0bd079c87 Author: Lars Ingebrigtsen Date: Fri May 20 00:15:28 2022 +0200 Add new user option 'yank-transform-functions' * doc/lispref/text.texi (Yanking): Mention it. (Yanking): Document it. * lisp/simple.el (yank-transform-functions): New user option. (yank): Mention it. * lisp/subr.el (insert-for-yank): Use it. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index a1db715db6..8fd8a5fb97 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -1034,6 +1034,9 @@ text in @var{string} according to the @code{yank-handler} text property, as well as the variables @code{yank-handled-properties} and @code{yank-excluded-properties} (see below), before inserting the result into the current buffer. + +@var{string} will be run through @code{yank-transform-functions} (see +below) before inserting. @end defun @defun insert-buffer-substring-as-yank buf &optional start end @@ -1108,6 +1111,23 @@ or specifying key bindings. It takes effect after @code{yank-handled-properties}. @end defopt +@defopt yank-transform-functions +This variable is a list of functions. Each function is called (in +order) with the string to be yanked as the parameter, and should +return a (possibly transformed) string. This variable can be set +globally, but can also be used to create new commands that are +variations on @code{yank}. For instance, to create a command that +works like @code{yank}, but cleans up whitespace before inserting, you +could say something like: + +@lisp +(defun yank-with-clean-whitespace () + (interactive) + (let ((yank-transform-functions + '(string-clean-whitespace))) + (call-interactively #'yank))) +@end lisp +@end defopt @node Yank Commands @subsection Functions for Yanking diff --git a/etc/NEWS b/etc/NEWS index 4f6df48129..c3bc1f0f58 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2190,6 +2190,9 @@ platforms. This command lets you examine all data in the current selection and the clipboard, and insert it into the buffer. +** New user option 'yank-transform-functions'. +This function allows the user to alter the string to be inserted. + --- ** New function 'minibuffer-lazy-highlight-setup'. This function allows setting up the minibuffer so that lazy diff --git a/lisp/simple.el b/lisp/simple.el index cd7a82b7ac..bed72457c3 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5928,6 +5928,15 @@ See also `yank-handled-properties'." :group 'killing :version "24.3") +(defcustom yank-transform-functions nil + "List of functions to run on strings to be yanked. +Each function in this list will be called (in order) with the +string to be yanked as the sole argument, and should return the (possibly) + transformed string." + :type '(repeat function) + :version "29.1" + :group 'killing) + (defvar yank-window-start nil) (defvar yank-undo-function nil "If non-nil, function used by `yank-pop' to delete last stretch of yanked text. @@ -5999,6 +6008,8 @@ property, as described below. Properties listed in `yank-handled-properties' are processed, then those listed in `yank-excluded-properties' are discarded. +STRING will be run through `yank-transform-functions'. + If STRING has a non-nil `yank-handler' property anywhere, the normal insert behavior is altered, and instead, for each contiguous segment of STRING that has a given value of the `yank-handler' diff --git a/lisp/subr.el b/lisp/subr.el index d7f06bdcde..945587db53 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4070,7 +4070,12 @@ remove properties specified by `yank-excluded-properties'." This function is like `insert', except it honors the variables `yank-handled-properties' and `yank-excluded-properties', and the -`yank-handler' text property, in the way that `yank' does." +`yank-handler' text property, in the way that `yank' does. + +It also runs the string through `yank-transform-functions'." + ;; Allow altering the yank string. + (dolist (func yank-transform-functions) + (setq string (funcall func string))) (let (to) (while (setq to (next-single-property-change 0 'yank-handler string)) (insert-for-yank-1 (substring string 0 to)) commit fb752561eab92343683552a5780dd80406936d09 Author: Eli Zaretskii Date: Thu May 19 15:34:29 2022 +0300 ; * etc/NEWS: Announce renaming of "Oriya" to "Odia". (Bug#55493) diff --git a/etc/NEWS b/etc/NEWS index 8aa53e62e0..4f6df48129 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -783,6 +783,7 @@ Setting it to a non-nil value temporarily disables automatic composition of character sequences at point, and thus makes it easier to edit such sequences by allowing point to "enter" the sequence. +--- *** Support for many old scripts and writing systems. Emacs now supports and has language-environments and input methods for several dozens of old scripts that were used in the past for various @@ -800,6 +801,13 @@ corresponding language environments are: **** Syloti Nagri script and language environment **** Modi script and language environment +--- +*** The "Oriya" language environment was renamed to "Odia". +This is to follow the change in the official name of the script. The +'oriya' input method was also renamed to 'odia'. However, the old +name of the language environment and the input method are still +supported. + --- *** New Greek translation of the Emacs tutorial. Type 'C-u C-h t' to select it in case your language setup does not do commit 99be0cfcd92d7400d65fdbfd0142e1fc619e4f1f Author: Eli Zaretskii Date: Thu May 19 15:29:14 2022 +0300 Provide Oriya language-environment alongside Odia * lisp/language/indian.el ("Oriya"): Add another name for the Odia language-environment. (Bug#55493) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index fccf3c0c0a..a5563a3ff7 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -90,8 +90,19 @@ North Indian language Gujarati is supported in this language environment.")) (sample-text . "Odia (ଓଡ଼ିଆ) ନମସ୍କାର") (documentation . "\ Such languages using the Odia script as Odia, Khonti, and Santali -are supported in this language environment (formerly the Oriya -language environment).")) +are supported in this language environment. (This language +environment was formerly known as \"Oriya\").")) + '("Indian")) + +(set-language-info-alist + "Oriya" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "odia") + (sample-text . "Odia (ଓଡ଼ିଆ) ନମସ୍କାର") + (documentation . "\ +Such languages using the Odia script as Odia, Khonti, and Santali +are supported in this language environment.")) '("Indian")) (set-language-info-alist commit cfd7edb5a9048324ab2a714365ef155efd918cb0 Author: समीर सिंह Sameer Singh Date: Thu May 19 01:08:14 2022 +0530 Rename Oriya to Odia, and more Due to "The Orissa (Alteration of Name) Act, 2011" (https://legislative.gov.in/sites/default/files/A2011-15.pdf) Oriya has been renamed to Odia. * lisp/language/indian.el (set-language-info-alist): Rename Oriya to Odia. Improve Oriya composition rules. * lisp/leim/quail/indian.el ("odia"): New input method. * lisp/erc/erc-lang.el: Obsolete the iso-638-languages variable (which was a typo) and replace it with iso-639-1-languages. * etc/HELLO: Rename Oriya to Odia. Replace the old Odia greeting with the new one. Add a Hindi greeting separate from the Devanagari one. (Bug#55493) diff --git a/etc/HELLO b/etc/HELLO index ba7bd8e132..bcaedd80b2 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -11,7 +11,7 @@ Non-ASCII examples: Cześć!,latin-iso8859-2 Dobrý den,cyrillic-iso8859-5 Здравствуйте!,greek-iso8859-7 Γειά σας, გამარჯობა Africa: ethiopicሠላም Middle/Near East:hebrew-iso8859-8 שָׁלוֹם, السّلام عليكم - South Asia: નમસ્તે, नमस्ते, ನಮಸ್ಕಾರ, നമസ്കാരം, ଶୁଣିବେ, + South Asia: નમસ્તે, नमस्ते, ನಮಸ್ಕಾರ, നമസ്കാരം, ନମସ୍କାର, ආයුබෝවන්, வணக்கம், నమస్కారం,tibetan བཀྲ་ཤིས་བདེ་ལེགས༎ South East Asia: ជំរាបសួរ,lao ສະບາຍດີ, မင်္ဂလာပါ,thai-tis620 สวัสดีครับ,vietnamese-viscii-lower vietnamese-viscii-upperCvietnamese-viscii-lowerhào bạn East Asia:chinese-gb2312 你好,chinese-big5-1 早晨,japanese-jisx0208 こんにちは,korean-ksc5601 안녕하세요 @@ -56,6 +56,7 @@ Greek, ancient (ἑλληνική) Οὖλέ τε καὶ μέγα χαῖρε Gujarati (ગુજરાતી) નમસ્તે Gurmukhi (ਗੁਰਮੁਖੀ) ਸਤ ਸ੍ਰੀ ਅਕਾਲ Hebrew (עִבְרִית) שָׁלוֹם +Hindi (हिन्दी) प्रणाम / पाय लागू Hungarian (magyar) Szép jó napot! Inuktitut (ᐃᓄᒃᑎᑐᑦ) ᐊᐃ Italian (italiano) Ciao / Buon giorno @@ -74,7 +75,7 @@ Modi (𑘦𑘻𑘚𑘲) 𑘡𑘦𑘭𑘿𑘎𑘰𑘨 Mongolian (монгол хэл) Сайн байна уу? Northern Thai (ᨣᩣᩴᨾᩮᩬᩥᨦ / ᨽᩣᩈᩣᩃ᩶ᩣ᩠ᨶᨶᩣ) ᩈ᩠ᩅᩢᩔ᩠ᨯᩦᨣᩕᩢ᩠ᨸ Norwegian (norsk) Hei / God dag -Oriya (ଓଡ଼ିଆ) ନମସ୍କାର +Odia (ଓଡ଼ିଆ) ନମସ୍କାର Polish (język polski) Dzień dobry! / Cześć! Russian (русский) Здра́вствуйте! Sharada (𑆯𑆳𑆫𑆢𑆳) 𑆤𑆩𑆱𑇀𑆑𑆳𑆫 diff --git a/lisp/erc/erc-lang.el b/lisp/erc/erc-lang.el index b65f4dbf6a..d059caf5a3 100644 --- a/lisp/erc/erc-lang.el +++ b/lisp/erc/erc-lang.el @@ -32,10 +32,8 @@ (require 'erc) -;; FIXME: It's ISO 639-1, not ISO 638. ISO 638 is for paper, board and pulps. -;; The Lisp variable should be renamed. - -(defvar iso-638-languages +(define-obsolete-variable-alias 'iso-638-languages 'iso-639-1-languages "29.1") +(defvar iso-639-1-languages '(("aa" . "Afar") ("ab" . "Abkhazian") ("af" . "Afrikaans") @@ -197,12 +195,12 @@ Normungsinstitut (ON), Postfach 130, A-1021 Vienna, Austria.") (defun language (code) "Return the language name for the ISO CODE." (interactive (list (completing-read "ISO language code: " - iso-638-languages))) - (message "%s" (cdr (assoc code iso-638-languages)))) + iso-639-1-languages))) + (message "%s" (cdr (assoc code iso-639-1-languages)))) (defun erc-cmd-LANG (language) "Display the language name for the language code given by LANGUAGE." - (let ((lang (cdr (assoc language iso-638-languages)))) + (let ((lang (cdr (assoc language iso-639-1-languages)))) (erc-display-message nil 'notice 'active (or lang (concat language ": No such domain")))) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index 257ecc1617..fccf3c0c0a 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -83,14 +83,15 @@ North Indian language Gujarati is supported in this language environment.")) '("Indian")) (set-language-info-alist - "Oriya" '((charset unicode) - (coding-system utf-8) - (coding-priority utf-8) - (input-method . "oriya-itrans") - (sample-text . "Oriya (ଓଡ଼ିଆ) ନମସ୍କାର") - (documentation . "\ -Such languages using Oriya script as Oriya, Khonti, and Santali -are supported in this language environment.")) + "Odia" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "odia") + (sample-text . "Odia (ଓଡ଼ିଆ) ନମସ୍କାର") + (documentation . "\ +Such languages using the Odia script as Odia, Khonti, and Santali +are supported in this language environment (formerly the Oriya +language environment).")) '("Indian")) (set-language-info-alist @@ -339,7 +340,7 @@ in this language environment.")) '(("a" . "\u0B01") ; SIGN CANDRABINDU ("A" . "[\u0B02\u0B03]") ; SIGN ANUSVARA .. VISARGA ("V" . "[\u0B05-\u0B14\u0B60\u0B61]") ; independent vowel - ("C" . "[\u0B15-\u0B39\u0B5C\u0B5D\u0B71]") ; consonant + ("C" . "[\u0B15-\u0B39\u0B5C\u0B5D\u0B5F\u0B71]") ; consonant ("B" . "[\u0B15-\u0B17\u0B1B-\u0B1D\u0B1F-\u0B21\u0B23\u0B24\u0B27-\u0B30\u0B32-\u0B35\u0B38\u0B39]") ; consonant with below form ("R" . "\u0B30") ; RA ("n" . "\u0B3C") ; NUKTA diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index 95798a4477..b76cf9a80d 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -1449,4 +1449,120 @@ Full key sequences are listed below:") ("M" ?𑘽) ) +(quail-define-package + "odia" "Odia" "ଓ" t "Odia phonetic input method. + + `\\=`' is used to switch levels instead of Alt-Gr. +" nil t t t t nil nil nil nil nil t) + +(quail-define-rules +("``" ?₹) +("1" ?୧) +("`1" ?1) +("`!" ?୲) +("2" ?୨) +("`2" ?2) +("`@" ?୳) +("3" ?୩) +("`3" ?3) +("`#" ?୴) +("4" ?୪) +("`4" ?4) +("`$" ?୵) +("5" ?୫) +("`5" ?5) +("`%" ?୶) +("6" ?୬) +("`6" ?6) +("`^" ?୷) +("7" ?୭) +("`7" ?7) +("8" ?୮) +("`8" ?8) +("9" ?୯) +("`9" ?9) +("0" ?୦) +("`0" ?0) +("`\\" ?।) +("`|" ?॥) +("`" ?ଟ) +("q" ?ଟ) +("Q" ?ଠ) +("`q" ?୰) +("`Q" ?୕) +("w" ?ଡ) +("W" ?ଢ) +("`w" ?ଡ଼) +("`W" ?ଢ଼) +("e" ?େ) +("E" ?ୈ) +("`e" ?ଏ) +("`E" ?ଐ) +("r" ?ର) +("R" ?ୃ) +("`r" ?ଋ) +("t" ?ତ) +("T" ?ଥ) +("`t" ?ୖ) +("`T" ?ୗ) +("y" ?ଯ) +("Y" ?ୟ) +("u" ?ୁ) +("U" ?ୂ) +("`u" ?ଉ) +("`U" ?ଊ) +("i" ?ି) +("I" ?ୀ) +("`i" ?ଇ) +("`I" ?ଈ) +("o" ?ୋ) +("O" ?ୌ) +("`o" ?ଓ) +("`O" ?ଔ) +("p" ?ପ) +("P" ?ଫ) +("a" ?ା) +("A" ?ଆ) +("`a" ?ଅ) +("s" ?ସ) +("S" ?ଶ) +("d" ?ଦ) +("D" ?ଧ) +("f" ?୍) +("F" ?ୄ) +("`f" ?ୠ) +("g" ?ଗ) +("G" ?ଘ) +("h" ?ହ) +("H" ?ଃ) +("j" ?ଜ) +("J" ?ଝ) +("k" ?କ) +("K" ?ଖ) +("l" ?ଲ) +("L" ?ଳ) +("`l" ?ୢ) +("`L" ?ଌ) +("z" ?ଞ) +("Z" ?ଙ) +("`z" ?ୣ) +("`Z" ?ୡ) +("x" ?ଷ) +("X" ?଼) +("c" ?ଚ) +("C" ?ଛ) +("`c" #x200C) ; ZWNJ +("`C" #x200D) ; ZWJ +("v" ?ଵ) +("V" ?ୱ) +("b" ?ବ) +("B" ?ଭ) +("n" ?ନ) +("N" ?ଣ) +("m" ?ମ) +("M" ?ଂ) +("`m" ?ଁ) +("`M" ?ଽ) +) + ;;; indian.el ends here commit c15430997679fced7ef6adc23cbc59d0cfa3d625 Author: Po Lu Date: Thu May 19 20:10:19 2022 +0800 Whitelist some incorrectly labeled "color" fonts under Xft * etc/PROBLEMS: Document problem with fonts incorrectly labeled as color fonts under Xft. * src/ftfont.c (xft_color_font_whitelisted_p): New function. (ftfont_spec_pattern, ftfont_list): Respect whitelisting of "color" fonts under Xft. * src/xftfont.c (syms_of_xftfont): New variable `xft-color-font-whitelist'. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 3e0b73a4d5..4224171298 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -805,6 +805,22 @@ to take advantage of. * Runtime problems related to font handling +** Some fonts are detected but not usable under Xft. + +Some fonts might not be usable under Emacs even though they show up in +the font family list when Emacs is built with Xft. This is because +Emacs prevents fonts that have color glyphs (such as color Emoji) from +being used, since they typically cause Xft crashes. + +On some GNU/Linux systems, fonts (such as Source Code Pro) that do not +have color glyphs are reported as color fonts, causing them to be +unavailable when using Xft. This is known to happen under Fedora +GNU/Linux 36 or later, and possibly other distributions as well. + +If you encounter a such a font, you can enable it while ignoring other +fonts that actually have color glyphs by adding its family name to the +list `xft-color-font-whitelist'. + ** Characters are displayed as empty boxes or with wrong font under X. *** This may be due to your local fontconfig customization. diff --git a/src/ftfont.c b/src/ftfont.c index 5797300d23..301a145b7a 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -645,8 +645,29 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec) return spec; } +#if defined HAVE_XFT && defined FC_COLOR +static bool +xft_color_font_whitelisted_p (const char *family) +{ + Lisp_Object tem, name; + + tem = Vxft_color_font_whitelist; + + FOR_EACH_TAIL_SAFE (tem) + { + name = XCAR (tem); + + if (STRINGP (name) && !strcmp (family, SSDATA (name))) + return true; + } + + return false; +} +#endif + static FcPattern * -ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **otspec, const char **langname) +ftfont_spec_pattern (Lisp_Object spec, char *otlayout, + struct OpenTypeSpec **otspec, const char **langname) { Lisp_Object tmp, extra; FcPattern *pattern = NULL; @@ -785,6 +806,8 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots /* We really don't like color fonts, they cause Xft crashes. See Bug#30874. */ if (xft_ignore_color_fonts + && (NILP (AREF (spec, FONT_FAMILY_INDEX)) + || NILP (Vxft_color_font_whitelist)) && ! FcPatternAddBool (pattern, FC_COLOR, FcFalse)) goto err; #endif @@ -930,7 +953,12 @@ ftfont_list (struct frame *f, Lisp_Object spec) returns them even when it shouldn't really do so, so we need to manually skip them here (Bug#37786). */ FcBool b; + FcChar8 *str; + if (xft_ignore_color_fonts + && (FcPatternGetString (fontset->fonts[i], FC_FAMILY, + 0, &str) != FcResultMatch + || !xft_color_font_whitelisted_p ((char *) str)) && FcPatternGetBool (fontset->fonts[i], FC_COLOR, 0, &b) == FcResultMatch && b != FcFalse) continue; diff --git a/src/xftfont.c b/src/xftfont.c index 31fb877c35..6043ef9f94 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -797,6 +797,15 @@ syms_of_xftfont (void) This is needed with some fonts to correct vertical overlap of glyphs. */); xft_font_ascent_descent_override = 0; + DEFVAR_LISP ("xft-color-font-whitelist", Vxft_color_font_whitelist, + doc: /* List of "color" font families that don't actually have color glyphs. +Some fonts (such as Source Code Pro) are reported as color fonts, but +do not actually have glyphs with colors that can cause Xft crashes. + +The font families in this list will not be ignored when +`xft-ignore-color-fonts' is non-nil. */); + Vxft_color_font_whitelist = list1 (build_pure_c_string ("Source Code Pro")); + pdumper_do_now_and_after_load (syms_of_xftfont_for_pdumper); } commit 0a4d9f26ee9b24ecf0a8b1fb14d4b4bab5daa3ae Author: Po Lu Date: Thu May 19 17:36:24 2022 +0800 Fix tooltip buffer flipping inside popup menus * src/xterm.c (x_flip_and_flush): Don't ignore if `inhibit-redisplay' but F is a tooltip frame. (bug#55519) diff --git a/src/xterm.c b/src/xterm.c index 48329a2fca..db3f41e688 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5621,7 +5621,10 @@ x_flip_and_flush (struct frame *f) /* Flipping buffers requires a working connection to the X server, which isn't always present if `inhibit-redisplay' is t, since this can be called from the IO error handler. */ - if (!NILP (Vinhibit_redisplay)) + if (!NILP (Vinhibit_redisplay) + /* This has to work for tooltip frames, however, and redisplay + cannot happen when they are being flushed anyway. (bug#55519) */ + && !FRAME_TOOLTIP_P (f)) return; block_input (); commit b9f6ead9f563a1eff3bf3b93b2264a95baea2aaf Author: Po Lu Date: Thu May 19 17:02:38 2022 +0800 Fix error handling when allowing touch events * src/xterm.c (handle_one_xevent): Catch errors correctly when linking touch points. diff --git a/src/xterm.c b/src/xterm.c index 142c2f81ce..48329a2fca 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -19558,6 +19558,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!menu_bar_p && !tool_bar_p) { + x_catch_errors (dpyinfo->display); + if (f && device->direct_p) { *finish = X_EVENT_DROP; @@ -19586,6 +19588,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XIAllowTouchEvents (dpyinfo->display, xev->deviceid, xev->detail, xev->event, XIRejectTouch); #endif + x_uncatch_errors (); } else { commit 75c90c7c5197fb69630a5c908de26db162c60a71 Author: Stefan Kangas Date: Thu May 19 10:12:43 2022 +0200 ; * doc/misc/efaq.texi: Replace copyright years with ranges. diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index 081205e155..07f3669e16 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -9,10 +9,9 @@ @copying Copyright @copyright{} 2001--2022 Free Software Foundation, Inc.@* -Copyright @copyright{} 1994, 1995, 1996, 1997, 1998, 1999, 2000 -Reuven M. Lerner@* -Copyright @copyright{} 1992, 1993 Steven Byrnes@* -Copyright @copyright{} 1990, 1991, 1992 Joseph Brian Wells@* +Copyright @copyright{} 1994--2000 Reuven M. Lerner@* +Copyright @copyright{} 1992--1993 Steven Byrnes@* +Copyright @copyright{} 1990--1992 Joseph Brian Wells@* @quotation This list of frequently asked questions about GNU Emacs with answers commit 6308f0738d3b1c1e0add5cab87bf02097fb1a8d1 Author: Eli Zaretskii Date: Thu May 19 11:00:36 2022 +0300 Fix Flymake diagnostics reporting in non-UTF-8 locales * lisp/progmodes/elisp-mode.el (elisp-flymake-byte-compile) (elisp-flymake--batch-compile-for-flymake): Bind I/O encoding to UTF-8, instead of relying on the locale's defaults. This is needed because ELisp files use UTF-8 by default, but Flymake doesn't know about that, since it isn't specific to ELisp. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 1ae1cf7eb6..37fd4fdb3c 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -2088,7 +2088,9 @@ current buffer state and calls REPORT-FN when done." (when (process-live-p elisp-flymake--byte-compile-process) (kill-process elisp-flymake--byte-compile-process))) (let ((temp-file (make-temp-file "elisp-flymake-byte-compile")) - (source-buffer (current-buffer))) + (source-buffer (current-buffer)) + (coding-system-for-write 'utf-8-unix) + (coding-system-for-read 'utf-8)) (save-restriction (widen) (write-region (point-min) (point-max) temp-file nil 'nomessage)) @@ -2138,6 +2140,8 @@ Runs in a batch-mode Emacs. Interactively use variable (interactive (list buffer-file-name)) (let* ((file (or file (car command-line-args-left))) + (coding-system-for-read 'utf-8-unix) + (coding-system-for-write 'utf-8) (byte-compile-log-buffer (generate-new-buffer " *dummy-byte-compile-log-buffer*")) (byte-compile-dest-file-function #'ignore)