commit 5627693ce3f6ff7ef928a902bfab59731a63fbd4 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Wed Feb 9 15:01:36 2022 +0800 Explictly specify whether or not to respect alpha-background on Cairo * src/ftcrfont.c (ftcrfont_draw): Don't respect `alpha-background' if drawing cursor. (bug#53890) * src/xterm.c (x_set_cr_source_with_gc_foreground): (x_set_cr_source_with_gc_background): New parameters `respect_alpha_background'. All callers changed. * src/xterm.h: Update protoypes. diff --git a/src/ftcrfont.c b/src/ftcrfont.c index a0a3490c49..4d1ecee378 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -566,7 +566,7 @@ ftcrfont_draw (struct glyph_string *s, { #ifndef USE_BE_CAIRO #ifdef HAVE_X_WINDOWS - x_set_cr_source_with_gc_background (f, s->gc); + x_set_cr_source_with_gc_background (f, s->gc, s->hl != DRAW_CURSOR); #else pgtk_set_cr_source_with_color (f, s->xgcv.background, true); #endif @@ -595,7 +595,7 @@ ftcrfont_draw (struct glyph_string *s, } #ifndef USE_BE_CAIRO #ifdef HAVE_X_WINDOWS - x_set_cr_source_with_gc_foreground (f, s->gc); + x_set_cr_source_with_gc_foreground (f, s->gc, false); #else pgtk_set_cr_source_with_color (f, s->xgcv.foreground, false); #endif diff --git a/src/xterm.c b/src/xterm.c index 9b48006927..aed97fb37e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -875,20 +875,35 @@ x_end_cr_clip (struct frame *f) } void -x_set_cr_source_with_gc_foreground (struct frame *f, GC gc) +x_set_cr_source_with_gc_foreground (struct frame *f, GC gc, + bool respect_alpha_background) { XGCValues xgcv; XColor color; + unsigned int depth; XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv); color.pixel = xgcv.foreground; x_query_colors (f, &color, 1); - cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0, - color.green / 65535.0, color.blue / 65535.0); + depth = FRAME_DISPLAY_INFO (f)->n_planes; + + if (f->alpha_background < 1.0 && depth == 32 + && respect_alpha_background) + { + cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0, + color.green / 65535.0, color.blue / 65535.0, + f->alpha_background); + + cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE); + } + else + cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0, + color.green / 65535.0, color.blue / 65535.0); } void -x_set_cr_source_with_gc_background (struct frame *f, GC gc) +x_set_cr_source_with_gc_background (struct frame *f, GC gc, + bool respect_alpha_background) { XGCValues xgcv; XColor color; @@ -901,7 +916,8 @@ x_set_cr_source_with_gc_background (struct frame *f, GC gc) depth = FRAME_DISPLAY_INFO (f)->n_planes; - if (f->alpha_background < 1.0 && depth == 32) + if (f->alpha_background < 1.0 && depth == 32 + && respect_alpha_background) { cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0, @@ -912,7 +928,6 @@ x_set_cr_source_with_gc_background (struct frame *f, GC gc) else cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0); - } static const cairo_user_data_key_t xlib_surface_key, saved_drawable_key; @@ -1097,7 +1112,7 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image, cairo_rectangle (cr, dest_x, dest_y, width, height); else { - x_set_cr_source_with_gc_background (f, gc); + x_set_cr_source_with_gc_background (f, gc, false); cairo_rectangle (cr, dest_x, dest_y, width, height); cairo_fill_preserve (cr); } @@ -1114,7 +1129,7 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image, } else { - x_set_cr_source_with_gc_foreground (f, gc); + x_set_cr_source_with_gc_foreground (f, gc, false); cairo_clip (cr); cairo_mask (cr, image); } @@ -1325,7 +1340,7 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height, regarded as Pixmap of unspecified size filled with ones. */ || (xgcv.stipple & ((Pixmap) 7 << (sizeof (Pixmap) * CHAR_BIT - 3)))) { - x_set_cr_source_with_gc_foreground (f, gc); + x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background); cairo_rectangle (cr, x, y, width, height); cairo_fill (cr); } @@ -1333,14 +1348,14 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height, { eassert (xgcv.fill_style == FillOpaqueStippled); eassert (xgcv.stipple != None); - x_set_cr_source_with_gc_background (f, gc); + x_set_cr_source_with_gc_background (f, gc, respect_alpha_background); cairo_rectangle (cr, x, y, width, height); cairo_fill_preserve (cr); cairo_pattern_t *pattern = x_bitmap_stipple (f, xgcv.stipple); if (pattern) { - x_set_cr_source_with_gc_foreground (f, gc); + x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background); cairo_clip (cr); cairo_mask (cr, pattern); } @@ -1384,7 +1399,7 @@ x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height, cairo_t *cr; cr = x_begin_cr_clip (f, gc); - x_set_cr_source_with_gc_background (f, gc); + x_set_cr_source_with_gc_background (f, gc, respect_alpha_background); cairo_rectangle (cr, x, y, width, height); cairo_fill (cr); x_end_cr_clip (f); @@ -1430,7 +1445,7 @@ x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height) cairo_t *cr; cr = x_begin_cr_clip (f, gc); - x_set_cr_source_with_gc_foreground (f, gc); + x_set_cr_source_with_gc_foreground (f, gc, false); cairo_rectangle (cr, x + 0.5, y + 0.5, width, height); cairo_set_line_width (cr, 1); cairo_stroke (cr); @@ -1448,7 +1463,7 @@ x_clear_window (struct frame *f) cairo_t *cr; cr = x_begin_cr_clip (f, NULL); - x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc); + x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc, true); cairo_paint (cr); x_end_cr_clip (f); #else @@ -1471,7 +1486,7 @@ x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y, cairo_t *cr; cr = x_begin_cr_clip (f, gc); - x_set_cr_source_with_gc_foreground (f, gc); + x_set_cr_source_with_gc_foreground (f, gc, false); cairo_move_to (cr, top_p ? x : x + height, y); cairo_line_to (cr, x, y + height); cairo_line_to (cr, top_p ? x + width - height : x + width, y + height); @@ -1498,7 +1513,7 @@ x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y, int i; cr = x_begin_cr_clip (f, gc); - x_set_cr_source_with_gc_background (f, gc); + x_set_cr_source_with_gc_background (f, gc, false); for (i = 0; i < CORNER_LAST; i++) if (corners & (1 << i)) { @@ -1531,7 +1546,7 @@ x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y, int xoffset, n; cr = x_begin_cr_clip (f, gc); - x_set_cr_source_with_gc_foreground (f, gc); + x_set_cr_source_with_gc_foreground (f, gc, false); cairo_rectangle (cr, x, y, width, height); cairo_clip (cr); @@ -4840,7 +4855,8 @@ x_clear_area (struct frame *f, int x, int y, int width, int height) eassert (width > 0 && height > 0); cr = x_begin_cr_clip (f, NULL); - x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc); + x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc, + true); cairo_rectangle (cr, x, y, width, height); cairo_fill (cr); x_end_cr_clip (f); diff --git a/src/xterm.h b/src/xterm.h index 1ce3e7a6cf..435569943c 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1267,8 +1267,8 @@ extern void x_cr_destroy_frame_context (struct frame *); extern void x_cr_update_surface_desired_size (struct frame *, int, int); extern cairo_t *x_begin_cr_clip (struct frame *, GC); extern void x_end_cr_clip (struct frame *); -extern void x_set_cr_source_with_gc_foreground (struct frame *, GC); -extern void x_set_cr_source_with_gc_background (struct frame *, GC); +extern void x_set_cr_source_with_gc_foreground (struct frame *, GC, bool); +extern void x_set_cr_source_with_gc_background (struct frame *, GC, bool); extern void x_cr_draw_frame (cairo_t *, struct frame *); extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t); #endif commit 34772455261fc1508c3623ba549381976dcba258 Author: Tassilo Horn Date: Wed Feb 9 06:54:11 2022 +0100 Mention `overlay' show-paren-context-when-offscreen value in NEWS * etc/NEWS: Mention `overlay' value of show-paren-context-when-offscreen. diff --git a/etc/NEWS b/etc/NEWS index a8a270d57d..0f5e28b31a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -446,10 +446,10 @@ When non-nil, if the point is in a closing delimiter and the opening delimiter is offscreen, shows some context around the opening delimiter in the echo area. Default nil. -May also be set to the symbol 'child-frame' in which case the context -is shown in a child frame at the top left of the current window on -graphical frames. On non-graphical frames, the context is shown in -the echo area. +May also be set to the symbols 'overlay' or 'child-frame' in which +case the context is shown in an overlay or child-frame at the top-left +of the current window. The latter option requires a graphical frame. +On non-graphical frames, the context is shown in the echo area. ** Comint commit 9459399d580b3a712e895fdeb03fb1c196da96c7 Merge: 11ff76153e 82e74e4559 Author: Stefan Kangas Date: Wed Feb 9 06:30:54 2022 +0100 Merge from origin/emacs-28 82e74e4559 flymake: Ensure compatibility with older Emacsen commit 11ff76153e012cf76690568cf82b9a049c40e949 Author: Po Lu Date: Wed Feb 9 05:09:24 2022 +0000 Make haikufont_list_family actually work * haikufont.c (haikufont_list_family): Intern returned font families. diff --git a/src/haikufont.c b/src/haikufont.c index ebff619287..e9e788e8e8 100644 --- a/src/haikufont.c +++ b/src/haikufont.c @@ -1043,8 +1043,7 @@ haikufont_list_family (struct frame *f) for (idx = 0; idx < length; ++idx) { if (styles[idx][0]) - list = Fcons (build_string_from_utf8 ((char *) &styles[idx]), - list); + list = Fcons (intern ((char *) &styles[idx]), list); } free (styles); commit f96eee4e06001cbeb1f6b0caa0b138015858ce33 Author: Po Lu Date: Wed Feb 9 03:53:13 2022 +0000 Implement `list_family' for the haikufont driver * src/haiku_font_support.cc (be_list_font_families): New function. * src/haiku_support.h: Update prototypes. * src/haikufont.c (haikufont_list_family): New function. (haikufont_driver): Add `haikufont_list_family'. diff --git a/src/haiku_font_support.cc b/src/haiku_font_support.cc index e6d21c28fe..b92373b59e 100644 --- a/src/haiku_font_support.cc +++ b/src/haiku_font_support.cc @@ -615,3 +615,27 @@ BFont_string_width (void *font, const char *utf8) { return ((BFont *) font)->StringWidth (utf8); } + +haiku_font_family_or_style * +be_list_font_families (size_t *length) +{ + int32 families = count_font_families (); + haiku_font_family_or_style *array; + int32 idx; + uint32 flags; + + array = (haiku_font_family_or_style *) malloc (sizeof *array * families); + + if (!array) + return NULL; + + for (idx = 0; idx < families; ++idx) + { + if (get_font_family (idx, &array[idx], &flags) != B_OK) + array[idx][0] = '\0'; + } + + *length = families; + + return array; +} diff --git a/src/haiku_support.h b/src/haiku_support.h index ea34ccb435..369a4b6bb4 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -883,6 +883,9 @@ extern "C" extern void EmacsWindow_signal_menu_update_complete (void *window); + extern haiku_font_family_or_style * + be_list_font_families (size_t *length); + #ifdef __cplusplus extern void * find_appropriate_view_for_draw (void *vw); diff --git a/src/haikufont.c b/src/haikufont.c index 6cc984f316..ebff619287 100644 --- a/src/haikufont.c +++ b/src/haikufont.c @@ -29,6 +29,7 @@ along with GNU Emacs. If not, see . */ #include "fontset.h" #include "haikuterm.h" #include "character.h" +#include "coding.h" #include "font.h" #include "termchar.h" #include "pdumper.h" @@ -1023,6 +1024,35 @@ haikufont_draw (struct glyph_string *s, int from, int to, return 1; } +static Lisp_Object +haikufont_list_family (struct frame *f) +{ + Lisp_Object list = Qnil; + size_t length; + ptrdiff_t idx; + haiku_font_family_or_style *styles; + + block_input (); + styles = be_list_font_families (&length); + unblock_input (); + + if (!styles) + return list; + + block_input (); + for (idx = 0; idx < length; ++idx) + { + if (styles[idx][0]) + list = Fcons (build_string_from_utf8 ((char *) &styles[idx]), + list); + } + + free (styles); + unblock_input (); + + return list; +} + struct font_driver const haikufont_driver = { .type = LISPSYM_INITIALLY (Qhaiku), @@ -1036,7 +1066,8 @@ struct font_driver const haikufont_driver = .prepare_face = haikufont_prepare_face, .encode_char = haikufont_encode_char, .text_extents = haikufont_text_extents, - .shape = haikufont_shape + .shape = haikufont_shape, + .list_family = haikufont_list_family }; void commit d41a5e7e33067eb38b147ee2f8a1615f6faed7a4 Author: Po Lu Date: Wed Feb 9 11:26:47 2022 +0800 Improve selection of fonts available from `mouse-set-font' People get confused on a build without font dialogs (such as a Lucid build) if `menu-set-font' and `mouse-set-font' don't present them a list of the fonts actually available on their system. * lisp/mouse.el (mouse-generate-font-name-for-menu) (mouse-generate-font-menu): New functions. (mouse-select-font): Allow the user to select from all fonts available on the system. (mouse-set-font): Use `mouse-select-font' to display font menu. diff --git a/lisp/mouse.el b/lisp/mouse.el index 502683d3d1..acaf6611af 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -2755,18 +2755,72 @@ and selects that window." (declare-function generate-fontset-menu "fontset" ()) +(defun mouse-generate-font-name-for-menu (entity) + "Return a short name for font entity ENTITY. +The name should be used to describe ENTITY in the case that its +family is already known, such as in a pane generated by +`mouse-generate-font-menu'." + (let ((weight (font-get entity :weight)) + (slant (font-get entity :slant)) + (width (font-get entity :width)) + (size (font-get entity :size)) + (adstyle (font-get entity :adstyle)) + (name "")) + (when weight + (setq name (concat name (symbol-name weight) " "))) + (when (and slant + (not (eq slant 'normal))) + (setq name (concat name (symbol-name slant) " "))) + (when (and width (not (eq width 'normal))) + (setq name (concat name (symbol-name width) " "))) + (when (and size (not (zerop size))) + (setq name (concat name (number-to-string size) " "))) + (when adstyle + (setq name (concat name (if (symbolp adstyle) + (symbol-name adstyle) + (number-to-string adstyle)) + " "))) + (string-trim-right name))) + +(defun mouse-generate-font-menu () + "Return a list of menu panes for each font family." + (let ((families (font-family-list)) + (panes (list "Font families"))) + (dolist (family families) + (when family + (let* ((fonts (list-fonts (font-spec :family family))) + (pane (if fonts (list family) + (list family (cons family family))))) + (when fonts + (dolist (font fonts) + (setq pane + (nconc pane + (list (list (or (font-get font :name) + (mouse-generate-font-name-for-menu font)) + (font-xlfd-name font))))))) + (setq panes (nconc panes (list pane)))))) + panes)) + (defun mouse-select-font () "Prompt for a font name, using `x-popup-menu', and return it." (interactive) (unless (display-multi-font-p) (error "Cannot change fonts on this display")) - (car - (x-popup-menu - (if (listp last-nonmenu-event) - last-nonmenu-event - (list '(0 0) (selected-window))) - (append x-fixed-font-alist - (list (generate-fontset-menu)))))) + (let ((result (car + (x-popup-menu + (if (listp last-nonmenu-event) + last-nonmenu-event + (list '(0 0) (selected-window))) + (append x-fixed-font-alist + (list (generate-fontset-menu)) + '(("More Fonts" ("By Family" more)))))))) + (if (eq result 'more) + (car (x-popup-menu + (if (listp last-nonmenu-event) + last-nonmenu-event + (list '(0 0) (selected-window))) + (mouse-generate-font-menu))) + result))) (declare-function text-scale-mode "face-remap") @@ -2780,12 +2834,7 @@ choose a font." (interactive (progn (unless (display-multi-font-p) (error "Cannot change fonts on this display")) - (x-popup-menu - (if (listp last-nonmenu-event) - last-nonmenu-event - (list '(0 0) (selected-window))) - ;; Append list of fontsets currently defined. - (append x-fixed-font-alist (list (generate-fontset-menu)))))) + (list (mouse-select-font)))) (if fonts (let (font) (while fonts commit 59ff15e3502e44d7ae7ea23cd882fc18a766d989 Author: Po Lu Date: Wed Feb 9 02:10:36 2022 +0000 Make sure the cursor can't move on top of a tooltip on Haiku * src/haikuterm.c (haiku_read_socket): Work around leave notification events not being sent on tooltip frames. diff --git a/src/haikuterm.c b/src/haikuterm.c index 0c7e08585e..117d8df2e5 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -2730,9 +2730,21 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) struct frame *f = haiku_window_to_frame (b->window); Mouse_HLInfo *hlinfo = &x_display_list->mouse_highlight; - if (!f || FRAME_TOOLTIP_P (f)) + if (!f) continue; + if (FRAME_TOOLTIP_P (f)) + { + /* Dismiss the tooltip if the mouse moves onto a + tooltip frame. FIXME: for some reason we don't get + leave notification events for this. */ + + if (any_help_event_p) + do_help = -1; + + break; + } + Lisp_Object frame; XSETFRAME (frame, f); commit 882cf2d0cdf01e67634a3ddd4744e931f41d473d Author: Po Lu Date: Wed Feb 9 09:10:50 2022 +0800 Fix creation of tooltip frames with a stippled background * src/xfns.c (x_create_tip_frame): Init faces after creating the drawable, since that's needed for loading stipple files. diff --git a/src/xfns.c b/src/xfns.c index 2fd9ad6b05..79df70e73c 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -7285,19 +7285,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) gui_default_parameter (f, parms, Qno_special_glyphs, Qnil, NULL, NULL, RES_TYPE_BOOLEAN); - /* Init faces before gui_default_parameter is called for the - scroll-bar-width parameter because otherwise we end up in - init_iterator with a null face cache, which should not happen. */ - init_frame_faces (f); - - f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; - - gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil, - "inhibitDoubleBuffering", "InhibitDoubleBuffering", - RES_TYPE_BOOLEAN); - - gui_figure_window_size (f, parms, false, false); - { #ifndef USE_XCB XSetWindowAttributes attrs; @@ -7389,6 +7376,19 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) #endif } + /* Init faces before gui_default_parameter is called for the + scroll-bar-width parameter because otherwise we end up in + init_iterator with a null face cache, which should not happen. */ + init_frame_faces (f); + + gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil, + "inhibitDoubleBuffering", "InhibitDoubleBuffering", + RES_TYPE_BOOLEAN); + + gui_figure_window_size (f, parms, false, false); + + f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; + x_make_gc (f); gui_default_parameter (f, parms, Qauto_raise, Qnil, commit 2755e6bba0f9dbb4030f51ea3bc258ee23bb41c5 Author: Tassilo Horn Date: Tue Feb 8 21:54:56 2022 +0100 Allow showing show-paren context in an overlay * lisp/paren.el (show-paren-context-when-offscreen): Add new possibility `overlay'. (show-paren--context-overlay): New defvar. (show-paren--delete-context-overlay): New function. (show-paren--show-context-in-overlay): New function. (show-paren-function): Handle the new `overlay' case. * lisp/emacs-lisp/eldoc.el (eldoc-display-message-no-interference-p): There's no interference if `show-paren-context-when-offscreen' is overlay or child-frame. diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 74a20b8a8b..73713a3dec 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -387,6 +387,10 @@ Also store it in `eldoc-last-message' and return that value." ;; conflicts with eldoc. (and (boundp 'show-paren-context-when-offscreen) show-paren-context-when-offscreen + ;; There's no conflict with the child-frame and + ;; overlay versions. + (not (memq show-paren-context-when-offscreen + '(child-frame overlay))) (not (pos-visible-in-window-p (overlay-end show-paren--overlay))))))) diff --git a/lisp/paren.el b/lisp/paren.el index 221cad3f05..8d45987e90 100644 --- a/lisp/paren.el +++ b/lisp/paren.el @@ -96,14 +96,18 @@ context includes the previous nonblank line. By default, the context is shown in the echo area. +If set to the symbol `overlay', the context is shown in an +overlay at the top-left of the window. + If set to the symbol `child-frame', the context is shown in a -child frame at the top left of the window. You might want to +child frame at the top-left of the window. You might want to customize the `child-frame-border' face (especially the background color) to give the child frame a distinguished border. On non-graphical frames, the context is shown in the echo area." :type '(choice (const :tag "Off" nil) (const :tag "In echo area" t) - (const :tag "Child frame" child-frame)) + (const :tag "In overlay" overlay) + (const :tag "In child-frame" child-frame)) :version "29.1") (defvar show-paren--idle-timer nil) @@ -368,6 +372,32 @@ It is the default value of `show-paren-data-function'." (add-hook 'post-command-hook #'show-paren--delete-context-child-frame)))) +(defvar-local show-paren--context-overlay nil) + +(defun show-paren--delete-context-overlay () + (when show-paren--context-overlay + (delete-overlay show-paren--context-overlay) + (setq show-paren--context-overlay nil)) + (remove-hook 'post-command-hook #'show-paren--delete-overlays + 'local)) + +(defun show-paren--show-context-in-overlay (text) + "Show TEXT in an overlay at the top-left of the current window." + (setq text (replace-regexp-in-string "\n" " " text)) + (show-paren--delete-context-overlay) + (let* ((beg (window-start)) + (end (save-excursion + (goto-char beg) + (line-end-position)))) + (setq show-paren--context-overlay (make-overlay beg end))) + (overlay-put show-paren--context-overlay 'display text) + (overlay-put show-paren--context-overlay + 'face `(:box + ( :line-width (1 . -1) + :color ,(face-attribute 'shadow :foreground)))) + (add-hook 'post-command-hook #'show-paren--delete-context-overlay + nil 'local)) + (defun show-paren-function () "Highlight the parentheses until the next input arrives." (let ((data (and show-paren-mode (funcall show-paren-data-function)))) @@ -435,15 +465,18 @@ It is the default value of `show-paren-data-function'." (if (and show-paren-context-when-offscreen (< there-beg here-beg) (not (pos-visible-in-window-p openparen))) - (let ((open-paren-line-string - (blink-paren-open-paren-line-string openparen)) + (let ((context (blink-paren-open-paren-line-string + openparen)) (message-log-max nil)) - (if (and (eq show-paren-context-when-offscreen - 'child-frame) - (display-graphic-p)) - (show-paren--show-context-in-child-frame - open-paren-line-string) - (minibuffer-message "Matches %s" open-paren-line-string))))) + (cond + ((and + (eq show-paren-context-when-offscreen 'child-frame) + (display-graphic-p)) + (show-paren--show-context-in-child-frame context)) + ((eq show-paren-context-when-offscreen 'overlay) + (show-paren--show-context-in-overlay context)) + (show-paren-context-when-offscreen + (minibuffer-message "Matches %s" context)))))) ;; Always set the overlay face, since it varies. (overlay-put show-paren--overlay 'priority show-paren-priority) (overlay-put show-paren--overlay 'face face)))))) commit f7d16d93fded6ccdfef3c537c1841b7322010f12 Author: Juri Linkov Date: Tue Feb 8 21:35:12 2022 +0200 * lisp/replace.el (perform-replace): Allow using isearch in recursive-edit. Let-bind isearch-filter-predicate to the default value before calling recursive-edit to allow using isearch in a recursive edit (bug#53758). diff --git a/lisp/replace.el b/lisp/replace.el index 23e6483809..06be597855 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -3233,7 +3233,13 @@ characters." (last-command 'recenter-top-bottom)) (recenter-top-bottom))) ((eq def 'edit) - (let ((opos (point-marker))) + (let ((opos (point-marker)) + ;; Restore original isearch filter to allow + ;; using isearch in a recursive edit even + ;; when perform-replace was started from + ;; `xref--query-replace-1' that let-binds + ;; `isearch-filter-predicate' (bug#53758). + (isearch-filter-predicate #'isearch-filter-visible)) (setq real-match-data (replace-match-data nil real-match-data real-match-data)) commit 8bc4004519ae8dffa08b6692eba5c95f9e171348 Author: Eli Zaretskii Date: Tue Feb 8 18:53:40 2022 +0200 ; * etc/PROBLEMS: Fix typos and improve wording. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index b0692899e8..7c8c364c56 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1719,13 +1719,13 @@ remove anything that looks like this: From your X defaults file. Your X server might also provide a different visual class that will do what you want. You can experiment -with `TrueColor-8', by placing: +with `TrueColor-8', by placing this: Emacs.visualClass: TrueColor-8 -In your ~/.Xresources, and loading that file. +in your ~/.Xresources, and loading that file. -*** Colors messed up on Cairo builds or GTK builds. +*** Colors messed up on Cairo or GTK builds. If your display defaults to a visual where pixel values cannot be directly converted to their corresponding real colors, a build with @@ -1739,7 +1739,7 @@ not colormapped. Try the following in your ~/.Xresources: Emacs.visualClass: TrueColor-N -Where "N" is the bit depth of the visual your X server defaults to. +where "N" is the bit depth of the visual your X server defaults to. If that does not work, you lose. Configure Emacs '--without-cairo' and '--with-x-toolkit=lucid' instead. @@ -1764,9 +1764,9 @@ proprietary, it has many other disadvantages, such as not supporting most recent hardware and most modern extensions to the X protocol. Consider switching to a free X server, such as X.Org. -If GTK complains about not being built with support for debugging -options, then there is nothing you can do, except for switching to a -free X server. +If setting GDK_DEBUG causes GTK to complain about not being built with +support for debugging options, then there is nothing you can do, +except switch to a free X server. * Runtime problems on character terminals commit 1ea2993e83ad43bb9e93eb95fe858d2d90011a9e Author: Robert Pluim Date: Tue Feb 1 12:01:14 2022 +0100 Improve make-frame-on-display initial values * doc/emacs/frames.texi (Multiple Displays): Add index entry for 'display server'. * lisp/frame.el (make-frame-on-display): Specify sensible initial values when reading display name. * lisp/menu-bar.el (menu-bar-file-menu): Use 'display server' rather than 'display' to avoid monitor<->display confusion. diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index 29edbe9863..e3cfe5f844 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi @@ -949,6 +949,7 @@ Speedbar,,speedbar, Speedbar Manual}. @node Multiple Displays @section Multiple Displays @cindex multiple displays +@cindex display server A single Emacs can talk to more than one X display. Initially, Emacs uses just one display---the one specified with the @env{DISPLAY} diff --git a/lisp/frame.el b/lisp/frame.el index e9c88adc7c..b681a971aa 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -702,7 +702,9 @@ Return nil if we don't know how to interpret DISPLAY." The optional argument PARAMETERS specifies additional frame parameters." (interactive (if (fboundp 'x-display-list) (list (completing-read "Make frame on display: " - (x-display-list))) + (x-display-list) nil + nil (car (x-display-list)) + nil (car (x-display-list)))) (user-error "This Emacs build does not support X displays"))) (make-frame (cons (cons 'display display) parameters))) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 7678b1ece6..e26355293f 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -131,9 +131,9 @@ :visible (fboundp 'make-frame-on-monitor) :help "Open a new frame on another monitor")) (bindings--define-key menu [make-frame-on-display] - '(menu-item "New Frame on Display..." make-frame-on-display + '(menu-item "New Frame on Display Server..." make-frame-on-display :visible (fboundp 'make-frame-on-display) - :help "Open a new frame on another display")) + :help "Open a new frame on a display server")) (bindings--define-key menu [make-frame] '(menu-item "New Frame" make-frame-command :visible (fboundp 'make-frame-command) commit 57df45749259e2b6fd5f629107a868f0df9725cb Author: Robert Pluim Date: Tue Feb 1 11:59:42 2022 +0100 Improve thing-at-point-url-at-point docstring * lisp/thingatpt.el (thing-at-point-url-at-point): Correct description of BOUNDS argument. diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index 045264528f..5f9ccc094a 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -508,14 +508,14 @@ If no URL is found, return nil. If optional argument LAX is non-nil, look for URLs that are not well-formed, such as foo@bar or . -If optional arguments BOUNDS are non-nil, it should be a cons +If optional argument BOUNDS is non-nil, it should be a cons cell of the form (START . END), containing the beginning and end positions of the URI. Otherwise, these positions are detected automatically from the text around point. If the scheme component is absent, either because a URI delimited with lacks one, or because an ill-formed URI was found -with LAX or BEG and END, try to add a scheme in the returned URI. +with LAX or BOUNDS, try to add a scheme in the returned URI. The scheme is chosen heuristically: \"mailto:\" if the address looks like an email address, \"ftp://\" if it starts with \"ftp\", etc." commit 6058d3ebb4170fb70ebb78b42c0bc1e12fb96134 Author: Michael Albinus Date: Tue Feb 8 16:23:05 2022 +0100 Respect customization nature of `connection-local-*' user options * lisp/files-x.el (connection-local-set-profiles) (connection-local-set-profile-variables): Set user options via `customize-set-variable'. diff --git a/lisp/files-x.el b/lisp/files-x.el index 773339d748..319bfe0565 100644 --- a/lisp/files-x.el +++ b/lisp/files-x.el @@ -668,7 +668,9 @@ variables for a connection profile are defined using (setcdr slot (delete-dups (append (cdr slot) profiles))) (setq connection-local-criteria-alist (cons (cons criteria (delete-dups profiles)) - connection-local-criteria-alist))))) + connection-local-criteria-alist)))) + (customize-set-variable + 'connection-local-criteria-alist connection-local-criteria-alist)) (defsubst connection-local-get-profile-variables (profile) "Return the connection-local variable list for PROFILE." @@ -687,7 +689,9 @@ connection profile using `connection-local-set-profiles'. Then variables are set in the server's process buffer according to the VARIABLES list of the connection profile. The list is processed in order." - (setf (alist-get profile connection-local-profile-alist) variables)) + (setf (alist-get profile connection-local-profile-alist) variables) + (customize-set-variable + 'connection-local-profile-alist connection-local-profile-alist)) (defun hack-connection-local-variables (criteria) "Read connection-local variables according to CRITERIA. commit fe37e49a970b590f6643228899234628f5671a22 Author: Michael Albinus Date: Tue Feb 8 15:45:09 2022 +0100 Fix processes on remote default-directory with special characters * lisp/net/tramp.el (tramp-handle-make-process): Quote `localname'. * test/lisp/net/tramp-tests.el (tramp--test-check-files): Test also remote `default-directory' for processes. (Bug#53846) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 6d8f267ddf..05a80e1dcf 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4292,7 +4292,9 @@ substitution. SPEC-LIST is a list of char/value pairs used for (command (mapconcat #'tramp-shell-quote-argument command " ")) ;; Set cwd and environment variables. (command - (append `("cd" ,localname "&&" "(" "env") env `(,command ")")))) + (append + `("cd" ,(tramp-shell-quote-argument localname) "&&" "(" "env") + env `(,command ")")))) ;; Check for `tramp-sh-file-name-handler', because something ;; is different between tramp-sh.el, and tramp-adb.el or diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index a4f2fe9e0e..d78e8815b2 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -6475,6 +6475,23 @@ This requires restrictions of file name syntax." (delete-file file3) (should-not (file-exists-p file3)))) + ;; Check, that a process runs on a remote + ;; `default-directory' with special characters. See + ;; Bug#53846. + (when (and (tramp--test-expensive-test-p) + (tramp--test-supports-processes-p)) + (let ((default-directory file1)) + (dolist (this-shell-command + (append + ;; Synchronously. + '(shell-command) + ;; Asynchronously. + (and (tramp--test-asynchronous-processes-p) + '(tramp--test-async-shell-command)))) + (with-temp-buffer + (funcall this-shell-command "cat -- *" (current-buffer)) + (should (string-equal elt (buffer-string))))))) + (delete-file file2) (should-not (file-exists-p file2)) (delete-directory file1) commit 9966d9574bc729fdc3abe3e581ba877820247461 Author: Po Lu Date: Tue Feb 8 21:36:51 2022 +0800 * src/pgtkterm.c (map_event): Fix last change. diff --git a/src/pgtkterm.c b/src/pgtkterm.c index e9fd5f83b7..8faffe94d4 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -5552,7 +5552,7 @@ configure_event (GtkWidget *widget, if (f->win_gravity == NorthWestGravity) gtk_window_get_position (GTK_WINDOW (widget), - &f->top_pos, &f->left_pos); + &f->left_pos, &f->top_pos); else { f->top_pos = event->configure.y; commit b76da7e7a580cfae2827baadf5c15c91a3135b1d Author: Po Lu Date: Tue Feb 8 21:32:07 2022 +0800 Document some problems found during testing on various X servers * etc/PROBLEMS (General X problems): Document some problems found during testing on various X servers. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 2358203c3d..b0692899e8 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1709,6 +1709,65 @@ actual version of libXi installed does not. The solution is to upgrade your libXi binaries to libXi 1.8.0 or later, to correspond with your XInput headers. +*** Requesting a private colormap makes Emacs hang. + +The part of Xlib that provides this feature is broken in modern +incarnations of Xlib, so it cannot possibly work. The solution is to +remove anything that looks like this: + + Emacs.privateColormap: on + +From your X defaults file. Your X server might also provide a +different visual class that will do what you want. You can experiment +with `TrueColor-8', by placing: + + Emacs.visualClass: TrueColor-8 + +In your ~/.Xresources, and loading that file. + +*** Colors messed up on Cairo builds or GTK builds. + +If your display defaults to a visual where pixel values cannot be +directly converted to their corresponding real colors, a build with +Cairo drawing or GTK will display colors incorrectly. This is because +Cairo and GTK foolishly assume that all RGB values can be converted +directly from their individual components, without asking the X server +to allocate the color. + +Your X server might have a different visual which is decomposed and +not colormapped. Try the following in your ~/.Xresources: + + Emacs.visualClass: TrueColor-N + +Where "N" is the bit depth of the visual your X server defaults to. +If that does not work, you lose. Configure Emacs '--without-cairo' +and '--with-x-toolkit=lucid' instead. + +*** GUI widgets don't display on GTK builds, except for scrollbars. + +This can happen if your visual does not have a decomposed colormap, +and your X server has the X rendering extension. + +To solve the problem, disable the X rendering extension on your X +server, or rebuild Emacs without GTK+. + +*** On Accelerated X, the GTK 3 menu bar does not select items. + +The solution is to run Emacs with the environment variable 'GDK_DEBUG' +set to "nograbs", like this (where "..." stands for the other +command-line arguments you intend to pass to Emacs): + + GDK_DEBUG=nograbs emacs ... + +Accelerated X is a proprietary X server. Aside from being +proprietary, it has many other disadvantages, such as not supporting +most recent hardware and most modern extensions to the X protocol. +Consider switching to a free X server, such as X.Org. + +If GTK complains about not being built with support for debugging +options, then there is nothing you can do, except for switching to a +free X server. + * Runtime problems on character terminals *** With X forwarding, mouse highlighting can make Emacs slow. commit e37ffc379e66d45745e037b3a483460d25609e62 Author: Po Lu Date: Tue Feb 8 12:20:47 2022 +0000 Improve robustness of override-redirect on Haiku * src/haiku_support.cc (class EmacsWindow): New field `override_redirect_p'. (BWindow_change_decoration, BWindow_set_override_redirect): Set and restore from the saved pre-override redirect state fields if appropriate. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 0aeff104da..71aa323b07 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -433,7 +433,8 @@ class EmacsWindow : public BWindow int shown_flag = 0; volatile int was_shown_p = 0; bool menu_bar_active_p = false; - window_look pre_override_redirect_style; + bool override_redirect_p = false; + window_look pre_override_redirect_look; window_feel pre_override_redirect_feel; uint32 pre_override_redirect_workspaces; pthread_mutex_t menu_update_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -2305,13 +2306,24 @@ BView_convert_from_screen (void *view, int *x, int *y) void BWindow_change_decoration (void *window, int decorate_p) { - BWindow *w = (BWindow *) window; + EmacsWindow *w = (EmacsWindow *) window; if (!w->LockLooper ()) gui_abort ("Failed to lock window while changing its decorations"); - if (decorate_p) - w->SetLook (B_TITLED_WINDOW_LOOK); + + if (!w->override_redirect_p) + { + if (decorate_p) + w->SetLook (B_TITLED_WINDOW_LOOK); + else + w->SetLook (B_NO_BORDER_WINDOW_LOOK); + } else - w->SetLook (B_NO_BORDER_WINDOW_LOOK); + { + if (decorate_p) + w->pre_override_redirect_look = B_TITLED_WINDOW_LOOK; + else + w->pre_override_redirect_look = B_NO_BORDER_WINDOW_LOOK; + } w->UnlockLooper (); } @@ -3339,9 +3351,6 @@ be_use_subpixel_antialiasing (void) return current_subpixel_antialiasing; } -/* This isn't implemented very properly (for example: what if - decorations are changed while the window is under override - redirect?) but it works well enough for most use cases. */ void BWindow_set_override_redirect (void *window, bool override_redirect_p) { @@ -3349,19 +3358,21 @@ BWindow_set_override_redirect (void *window, bool override_redirect_p) if (w->LockLooper ()) { - if (override_redirect_p) + if (override_redirect_p && !w->override_redirect_p) { + w->override_redirect_p = true; w->pre_override_redirect_feel = w->Feel (); - w->pre_override_redirect_style = w->Look (); + w->pre_override_redirect_look = w->Look (); w->SetFeel (kMenuWindowFeel); w->SetLook (B_NO_BORDER_WINDOW_LOOK); w->pre_override_redirect_workspaces = w->Workspaces (); w->SetWorkspaces (B_ALL_WORKSPACES); } - else + else if (w->override_redirect_p) { + w->override_redirect_p = false; w->SetFeel (w->pre_override_redirect_feel); - w->SetLook (w->pre_override_redirect_style); + w->SetLook (w->pre_override_redirect_look); w->SetWorkspaces (w->pre_override_redirect_workspaces); } commit 855928082b31e7cf7872d389905972bce4c3d82c Author: Po Lu Date: Tue Feb 8 19:57:01 2022 +0800 Fix frame offset reporting on PGTK * src/pgtkterm.c (configure_event): Handle changes in window position. (bug#52697) diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 9d15b671dd..e9fd5f83b7 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -5536,6 +5536,7 @@ configure_event (GtkWidget *widget, gpointer *user_data) { struct frame *f = pgtk_any_window_to_frame (event->configure.window); + if (f && widget == FRAME_GTK_OUTER_WIDGET (f)) { if (any_help_event_p) @@ -5548,6 +5549,15 @@ configure_event (GtkWidget *widget, help_echo_string = Qnil; gen_help_event (Qnil, frame, Qnil, Qnil, 0); } + + if (f->win_gravity == NorthWestGravity) + gtk_window_get_position (GTK_WINDOW (widget), + &f->top_pos, &f->left_pos); + else + { + f->top_pos = event->configure.y; + f->left_pos = event->configure.x; + } } return FALSE; } commit 996daa00ae3cab514a0f9fca0ee8b108f220677e Author: Po Lu Date: Tue Feb 8 19:14:52 2022 +0800 Implement frame resize synchronization on GTK 3 * src/xterm.c (XTframe_up_to_date): (handle_one_xevent): Use the GTK frame clock to implement frame resize synchronization. * src/xterm.h (struct x_output): New variable `xg_sync_end_pending_p'. diff --git a/src/xterm.c b/src/xterm.c index 8bdb3c9ea1..9b48006927 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1848,10 +1848,14 @@ x_update_end (struct frame *f) static void XTframe_up_to_date (struct frame *f) { -#ifdef HAVE_XSYNC +#if defined HAVE_XSYNC && !defined HAVE_GTK3 XSyncValue add; XSyncValue current; Bool overflow_p; +#elif defined HAVE_XSYNC + GtkWidget *widget; + GdkWindow *window; + GdkFrameClock *clock; #endif eassert (FRAME_X_P (f)); @@ -1861,6 +1865,7 @@ XTframe_up_to_date (struct frame *f) show_back_buffer (f); #ifdef HAVE_XSYNC +#ifndef HAVE_GTK3 if (FRAME_X_OUTPUT (f)->sync_end_pending_p && FRAME_X_BASIC_COUNTER (f) != None) { @@ -1892,6 +1897,20 @@ XTframe_up_to_date (struct frame *f) FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false; } +#else + if (FRAME_X_OUTPUT (f)->xg_sync_end_pending_p) + { + widget = FRAME_GTK_OUTER_WIDGET (f); + window = gtk_widget_get_window (widget); + eassert (window); + clock = gdk_window_get_frame_clock (window); + eassert (clock); + + gdk_frame_clock_request_phase (clock, + GDK_FRAME_CLOCK_PHASE_AFTER_PAINT); + FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = false; + } +#endif #endif unblock_input (); } @@ -9130,7 +9149,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto done; } -#if defined HAVE_XSYNC && !defined HAVE_GTK3 +#if defined HAVE_XSYNC if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request && event->xclient.format == 32 && dpyinfo->xsync_supported_p) @@ -9138,9 +9157,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, struct frame *f = x_top_window_to_frame (dpyinfo, event->xclient.window); +#if defined HAVE_GTK3 + GtkWidget *widget; + GdkWindow *window; + GdkFrameClock *frame_clock; +#endif if (f) { +#ifndef HAVE_GTK3 if (event->xclient.data.l[4] == 0) { XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value, @@ -9155,6 +9180,22 @@ handle_one_xevent (struct x_display_info *dpyinfo, } *finish = X_EVENT_DROP; +#else + widget = FRAME_GTK_OUTER_WIDGET (f); + + if (widget && !FRAME_X_OUTPUT (f)->xg_sync_end_pending_p) + { + window = gtk_widget_get_window (widget); + eassert (window); + frame_clock = gdk_window_get_frame_clock (window); + eassert (frame_clock); + + gdk_frame_clock_request_phase (frame_clock, + GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT); + + FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = true; + } +#endif goto done; } } diff --git a/src/xterm.h b/src/xterm.h index 854d87c83c..1ce3e7a6cf 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -822,6 +822,9 @@ struct x_output bool_bf sync_end_pending_p : 1; bool_bf ext_sync_end_pending_p : 1; +#ifdef HAVE_GTK3 + bool_bf xg_sync_end_pending_p : 1; +#endif #endif /* Relief GCs, colors etc. */ commit f788bb33e5ac4d4a482e88dedd89e5a64dd1f7d5 Author: Lars Ingebrigtsen Date: Tue Feb 8 11:10:03 2022 +0100 Extend find-lisp-object-file-name * lisp/help-fns.el (find-lisp-object-file-name): Add optional parameter to always look in the DOC file (bug#17685). diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 5da575aa8d..80d7d5cb02 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -396,7 +396,7 @@ if the variable `help-downcase-arguments' is non-nil." ;; `describe-face' (instead of `describe-simplify-lib-file-name'). ;;;###autoload -(defun find-lisp-object-file-name (object type) +(defun find-lisp-object-file-name (object type &optional also-c-source) "Guess the file that defined the Lisp object OBJECT, of type TYPE. OBJECT should be a symbol associated with a function, variable, or face; alternatively, it can be a function definition. @@ -407,8 +407,13 @@ If TYPE is not a symbol, search for a function definition. The return value is the absolute name of a readable file where OBJECT is defined. If several such files exist, preference is given to a file found via `load-path'. The return value can also be `C-source', which -means that OBJECT is a function or variable defined in C. If no -suitable file is found, return nil." +means that OBJECT is a function or variable defined in C, but +it's currently unknown where. If no suitable file is found, +return nil. + +If ALSO-C-SOURCE is non-nil, instead of returning `C-source', +this function will attempt to locate the definition of OBJECT in +the C sources, too." (let* ((autoloaded (autoloadp type)) (file-name (or (and autoloaded (nth 1 type)) (symbol-file @@ -445,14 +450,18 @@ suitable file is found, return nil." (cond ((and (not file-name) (subrp type)) ;; A built-in function. The form is from `describe-function-1'. - (if (get-buffer " *DOC*") + (if (or (get-buffer " *DOC*") + (and also-c-source + (get-buffer-create " *DOC*"))) (help-C-file-name type 'subr) 'C-source)) ((and (not file-name) (symbolp object) (eq type 'defvar) (integerp (get object 'variable-documentation))) ;; A variable defined in C. The form is from `describe-variable'. - (if (get-buffer " *DOC*") + (if (or (get-buffer " *DOC*") + (and also-c-source + (get-buffer-create " *DOC*"))) (help-C-file-name object 'var) 'C-source)) ((not (stringp file-name)) commit 82e74e4559b8becd44f3e7ac0134e2baddd69921 (refs/remotes/origin/emacs-28) Author: Brian Leung Date: Tue Feb 8 07:16:25 2022 +0100 flymake: Ensure compatibility with older Emacsen * lisp/progmodes/flymake.el (flymake--log-1): Use replace-regexp-in-string instead of Emacs 28's string-replace (bug#53853). diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 0c16ddedcb..e369cb1f21 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -267,8 +267,8 @@ If set to nil, don't suppress any zero counters." (format " [%s %s]" (or sublog 'flymake) ;; Handle file names with "%" correctly. (Bug#51549) - (string-replace "%" "%%" - (buffer-name (current-buffer)))))) + (replace-regexp-in-string "%" "%%" + (buffer-name (current-buffer)))))) (display-warning (list 'flymake sublog) (apply #'format-message msg args) (if (numberp level)