commit cc67d6ef36a07f26364d63e524fcba6fe9cb2112 (HEAD, refs/remotes/origin/master) Author: Mark Oteiza Date: Fri May 10 20:55:04 2019 -0400 Generate some repetitive WordStar code with macros * lisp/obsolete/ws-mode.el (ws-set-marker-0, ws-set-marker-1): (ws-set-marker-2, ws-set-marker-3, ws-set-marker-4, ws-set-marker-5): (ws-set-marker-6, ws-set-marker-7, ws-set-marker-8, ws-set-marker-9): (ws-find-marker-0, ws-find-marker-1, ws-find-marker-2, ws-find-marker-3): (ws-find-marker-4, ws-find-marker-5, ws-find-marker-6, ws-find-marker-7): (ws-find-marker-8, ws-find-marker-9): Remove. (ws-set-marker, ws-find-marker): New macros. Use them. diff --git a/lisp/obsolete/ws-mode.el b/lisp/obsolete/ws-mode.el index 3d2e968b1d..1615610671 100644 --- a/lisp/obsolete/ws-mode.el +++ b/lisp/obsolete/ws-mode.el @@ -289,66 +289,6 @@ with C-q w." (setq ws-last-errormessage string) (error string)) -(defun ws-set-marker-0 () - "In WordStar mode: Set marker 0 to current cursor position." - (interactive) - (setq ws-marker-0 (point-marker)) - (message "Marker 0 set")) - -(defun ws-set-marker-1 () - "In WordStar mode: Set marker 1 to current cursor position." - (interactive) - (setq ws-marker-1 (point-marker)) - (message "Marker 1 set")) - -(defun ws-set-marker-2 () - "In WordStar mode: Set marker 2 to current cursor position." - (interactive) - (setq ws-marker-2 (point-marker)) - (message "Marker 2 set")) - -(defun ws-set-marker-3 () - "In WordStar mode: Set marker 3 to current cursor position." - (interactive) - (setq ws-marker-3 (point-marker)) - (message "Marker 3 set")) - -(defun ws-set-marker-4 () - "In WordStar mode: Set marker 4 to current cursor position." - (interactive) - (setq ws-marker-4 (point-marker)) - (message "Marker 4 set")) - -(defun ws-set-marker-5 () - "In WordStar mode: Set marker 5 to current cursor position." - (interactive) - (setq ws-marker-5 (point-marker)) - (message "Marker 5 set")) - -(defun ws-set-marker-6 () - "In WordStar mode: Set marker 6 to current cursor position." - (interactive) - (setq ws-marker-6 (point-marker)) - (message "Marker 6 set")) - -(defun ws-set-marker-7 () - "In WordStar mode: Set marker 7 to current cursor position." - (interactive) - (setq ws-marker-7 (point-marker)) - (message "Marker 7 set")) - -(defun ws-set-marker-8 () - "In WordStar mode: Set marker 8 to current cursor position." - (interactive) - (setq ws-marker-8 (point-marker)) - (message "Marker 8 set")) - -(defun ws-set-marker-9 () - "In WordStar mode: Set marker 9 to current cursor position." - (interactive) - (setq ws-marker-9 (point-marker)) - (message "Marker 9 set")) - (defun ws-begin-block () "In WordStar mode: Set block begin marker to current cursor position." (interactive) @@ -447,96 +387,6 @@ with C-q w." (ws-block-end-marker "Block begin marker not set") (t "Block markers not set"))))) -(defun ws-find-marker-0 () - "In WordStar mode: Go to marker 0." - (interactive) - (if ws-marker-0 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-0)) - (ws-error "Marker 0 not set"))) - -(defun ws-find-marker-1 () - "In WordStar mode: Go to marker 1." - (interactive) - (if ws-marker-1 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-1)) - (ws-error "Marker 1 not set"))) - -(defun ws-find-marker-2 () - "In WordStar mode: Go to marker 2." - (interactive) - (if ws-marker-2 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-2)) - (ws-error "Marker 2 not set"))) - -(defun ws-find-marker-3 () - "In WordStar mode: Go to marker 3." - (interactive) - (if ws-marker-3 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-3)) - (ws-error "Marker 3 not set"))) - -(defun ws-find-marker-4 () - "In WordStar mode: Go to marker 4." - (interactive) - (if ws-marker-4 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-4)) - (ws-error "Marker 4 not set"))) - -(defun ws-find-marker-5 () - "In WordStar mode: Go to marker 5." - (interactive) - (if ws-marker-5 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-5)) - (ws-error "Marker 5 not set"))) - -(defun ws-find-marker-6 () - "In WordStar mode: Go to marker 6." - (interactive) - (if ws-marker-6 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-6)) - (ws-error "Marker 6 not set"))) - -(defun ws-find-marker-7 () - "In WordStar mode: Go to marker 7." - (interactive) - (if ws-marker-7 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-7)) - (ws-error "Marker 7 not set"))) - -(defun ws-find-marker-8 () - "In WordStar mode: Go to marker 8." - (interactive) - (if ws-marker-8 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-8)) - (ws-error "Marker 8 not set"))) - -(defun ws-find-marker-9 () - "In WordStar mode: Go to marker 9." - (interactive) - (if ws-marker-9 - (progn - (setq ws-last-cursorposition (point-marker)) - (goto-char ws-marker-9)) - (ws-error "Marker 9 not set"))) - (defun ws-goto-block-begin () "In WordStar mode: Go to block begin marker." (interactive) @@ -654,6 +504,36 @@ sWith: " ) (ws-block-end-marker "Block begin marker not set") (t "Block markers not set"))))) +(defmacro ws-set-marker (&rest indices) + (let (n forms) + (while indices + (setq n (pop indices)) + (push `(defun ,(intern (format "ws-set-marker-%d" n)) () + ,(format "In WordStar mode: Set marker %d to current cursor position" n) + (interactive) + (setq ,(intern (format "ws-marker-%d" n)) (point-marker)) + (message ,(format "Marker %d set" n))) + forms)) + `(progn ,@(nreverse forms)))) + +(ws-set-marker 0 1 2 3 4 5 6 7 8 9) + +(defmacro ws-find-marker (&rest indices) + (let (n forms) + (while indices + (setq n (pop indices)) + (push `(defun ,(intern (format "ws-find-marker-%d" n)) () + ,(format "In WordStar mode: Go to marker %d." n) + (interactive) + (if ,(intern (format "ws-marker-%d" n)) + (progn (setq ws-last-cursorposition (point-marker)) + (goto-char ,(intern (format "ws-marker-%d" n)))) + (ws-error ,(format "Marker %d not set" n)))) + forms)) + `(progn ,@(nreverse forms)))) + +(ws-find-marker 0 1 2 3 4 5 6 7 8 9) + (provide 'ws-mode) ;;; ws-mode.el ends here commit 616ce44ac53f08bf447cbc032f4bb10cd65c0b70 Author: Alexander Gramiak Date: Thu May 9 09:37:50 2019 -0600 Convert Free_Pixmap macro into terminal hook * src/termhooks.h (terminal) [HAVE_WINDOW_SYSTEM]: New terminal hook free_pixmap. * src/image.c: Replace Free_Pixmap with free_pixmap. * src/msdos.h (FRAME_X_DISPLAY): * src/nsgui.h (Display): * src/nsterm.h (FRAME_NS_DISPLAY, FRAME_X_DISPLAY, FRAME_X_SCREEN) (FRAME_X_VISUAL): * src/w32term.h (FRAME_X_DISPLAY): Remove unused X-compatibility macros and typedefs. * src/nsterm.m: * src/w32term.c: * src/xterm.c: Implement and set free_pixmap hook. diff --git a/src/image.c b/src/image.c index e8cb434177..0779594989 100644 --- a/src/image.c +++ b/src/image.c @@ -1221,26 +1221,6 @@ four_corners_best (XImagePtr_or_DC ximg, int *corners, return best; } -/* Portability macros */ - -#ifdef HAVE_NTGUI - -#define Free_Pixmap(display, pixmap) \ - DeleteObject (pixmap) - -#elif defined (HAVE_NS) - -#define Free_Pixmap(display, pixmap) \ - ns_release_object (pixmap) - -#else - -#define Free_Pixmap(display, pixmap) \ - XFreePixmap (display, pixmap) - -#endif /* !HAVE_NTGUI && !HAVE_NS */ - - /* Return the `background' field of IMG. If IMG doesn't have one yet, it is guessed heuristically. If non-zero, XIMG is an existing XImage object (or device context with the image selected on W32) to @@ -1328,7 +1308,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags) { if (img->pixmap) { - Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap); + FRAME_TERMINAL (f)->free_pixmap (f, img->pixmap); img->pixmap = NO_PIXMAP; /* NOTE (HAVE_NS): background color is NOT an indexed color! */ img->background_valid = 0; @@ -1347,7 +1327,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags) { if (img->mask) { - Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); + FRAME_TERMINAL (f)->free_pixmap (f, img->mask); img->mask = NO_PIXMAP; img->background_transparent_valid = 0; } diff --git a/src/msdos.h b/src/msdos.h index 0d15df7a33..90ceea8e3d 100644 --- a/src/msdos.h +++ b/src/msdos.h @@ -95,7 +95,6 @@ typedef struct tty_display_info Display_Info; extern struct tty_display_info the_only_display_info; extern struct tty_output the_only_tty_output; -#define FRAME_X_DISPLAY(f) ((Display *) 0) #define FRAME_FONT(f) ((f)->output_data.tty->font) #define FRAME_DISPLAY_INFO(f) (&the_only_display_info) diff --git a/src/nsgui.h b/src/nsgui.h index c147f4dec4..ab6cdff1e5 100644 --- a/src/nsgui.h +++ b/src/nsgui.h @@ -115,7 +115,6 @@ typedef NSColor * Color; typedef void * Color; #endif typedef int Window; -typedef int Display; /* Some sort of attempt to normalize rectangle handling. Seems a bit diff --git a/src/nsterm.h b/src/nsterm.h index 683f2dd934..ffaf809785 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -997,12 +997,6 @@ struct x_output #define FRAME_NS_WINDOW(f) ((f)->output_data.ns->window_desc) #define FRAME_NATIVE_WINDOW(f) FRAME_NS_WINDOW (f) -/* This is the `Display *' which frame F is on. */ -#define FRAME_NS_DISPLAY(f) (0) -#define FRAME_X_DISPLAY(f) (0) -#define FRAME_X_SCREEN(f) (0) -#define FRAME_X_VISUAL(f) FRAME_DISPLAY_INFO(f)->visual - #define FRAME_FOREGROUND_COLOR(f) ((f)->output_data.ns->foreground_color) #define FRAME_BACKGROUND_COLOR(f) ((f)->output_data.ns->background_color) diff --git a/src/nsterm.m b/src/nsterm.m index ffb7b7692b..d688aceca5 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2515,8 +2515,7 @@ so some key presses (TAB) are swallowed by the system. */ /* Clear the mouse-moved flag for every frame on this display. */ FOR_EACH_FRAME (tail, frame) - if (FRAME_NS_P (XFRAME (frame)) - && FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp)) + if (FRAME_NS_P (XFRAME (frame))) XFRAME (frame)->mouse_moved = 0; dpyinfo->last_mouse_scroll_bar = nil; @@ -4966,6 +4965,18 @@ in certain situations (rapid incoming events). [eview updateFrameSize: NO]; } +/* ========================================================================== + + Image Hooks + + ========================================================================== */ + +static void +ns_free_pixmap (struct frame *_f, Pixmap pixmap) +{ + ns_release_object (pixmap); +} + /* ========================================================================== Initialization @@ -5196,6 +5207,7 @@ static Lisp_Object ns_new_font (struct frame *f, Lisp_Object font_object, terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar; terminal->judge_scroll_bars_hook = ns_judge_scroll_bars; terminal->get_string_resource_hook = ns_get_string_resource; + terminal->free_pixmap = ns_free_pixmap; terminal->delete_frame_hook = ns_destroy_window; terminal->delete_terminal_hook = ns_delete_terminal; /* Other hooks are NULL by default. */ diff --git a/src/termhooks.h b/src/termhooks.h index 54f09e0303..0962add081 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -741,6 +741,15 @@ struct terminal const char *name, const char *class); + /* Image hooks */ +#ifdef HAVE_WINDOW_SYSTEM + /* Free the pixmap PIXMAP on F. */ + void (*free_pixmap) (struct frame *f, Pixmap pixmap); + +#endif + + /* Deletion hooks */ + /* Called to delete the device-specific portions of a frame that is on this terminal device. */ void (*delete_frame_hook) (struct frame *); diff --git a/src/w32term.c b/src/w32term.c index 0abec3d92a..435455e1a6 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -6869,6 +6869,7 @@ w32_wm_set_size_hint (struct frame *f, long flags, bool user_position) leave_crit (); } + /*********************************************************************** Fonts ***********************************************************************/ @@ -6940,6 +6941,18 @@ w32_toggle_invisible_pointer (struct frame *f, bool invisible) unblock_input (); } + +/*********************************************************************** + Image Hooks + ***********************************************************************/ + +static void +w32_free_pixmap (struct frame *_f, Pixmap pixmap) +{ + DeleteObject (pixmap); +} + + /*********************************************************************** Initialization ***********************************************************************/ @@ -7119,6 +7132,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo) terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; terminal->judge_scroll_bars_hook = w32_judge_scroll_bars; terminal->get_string_resource_hook = w32_get_string_resource; + terminal->free_pixmap = w32_free_pixmap; terminal->delete_frame_hook = w32_destroy_window; terminal->delete_terminal_hook = w32_delete_terminal; /* Other hooks are NULL by default. */ diff --git a/src/w32term.h b/src/w32term.h index de372d7e5d..a03b9fd331 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -420,9 +420,6 @@ extern struct w32_output w32term_display; /* This gives the w32_display_info structure for the display F is on. */ #define FRAME_DISPLAY_INFO(f) ((void) (f), (&one_w32_display_info)) -/* This is the `Display *' which frame F is on. */ -#define FRAME_X_DISPLAY(f) (0) - #define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement) #define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode) diff --git a/src/xterm.c b/src/xterm.c index bd69e6c7a8..9371d47c95 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12181,6 +12181,17 @@ x_check_font (struct frame *f, struct font *font) #endif /* GLYPH_DEBUG */ +/*********************************************************************** + Image Hooks + ***********************************************************************/ + +static void +x_free_pixmap (struct frame *f, Pixmap pixmap) +{ + XFreePixmap (FRAME_X_DISPLAY (f), pixmap); +} + + /*********************************************************************** Initialization ***********************************************************************/ @@ -13257,6 +13268,7 @@ x_create_terminal (struct x_display_info *dpyinfo) terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar; terminal->judge_scroll_bars_hook = XTjudge_scroll_bars; terminal->get_string_resource_hook = x_get_string_resource; + terminal->free_pixmap = x_free_pixmap; terminal->delete_frame_hook = x_destroy_window; terminal->delete_terminal_hook = x_delete_terminal; /* Other hooks are NULL by default. */ commit 6bfc5fc6c4dfbed4b07528b64414fb04675cdf79 Author: Alexander Gramiak Date: Wed May 8 21:40:24 2019 -0600 Remove display member of glyph_string This member has little value even on X, and it leaks internal backend details to the glyph_string struct. * src/dispextern.h (glyph_string): Remove X display member. * src/xdisp.c (init_glyph_string): Remove initialization of display. * src/xfont.c (xfont_draw): * src/xterm.c: Use FRAME_X_DISPLAY (s->f) instead of display member. diff --git a/src/dispextern.h b/src/dispextern.h index bb981f83fc..619f4c0767 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1281,9 +1281,6 @@ struct glyph_string /* The window on which the glyph string is drawn. */ struct window *w; - /* X display and window for convenience. */ - Display *display; - /* The glyph row for which this string was built. It determines the y-origin and height of the string. */ struct glyph_row *row; diff --git a/src/xdisp.c b/src/xdisp.c index d380645c84..1aa677fcc7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25953,7 +25953,6 @@ init_glyph_string (struct glyph_string *s, #ifdef HAVE_NTGUI s->hdc = hdc; #endif - s->display = FRAME_X_DISPLAY (s->f); s->char2b = char2b; s->hl = hl; s->row = row; diff --git a/src/xfont.c b/src/xfont.c index 5ecbd6de33..ff80df407d 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -1000,6 +1000,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, bool with_background) { XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont; + Display *display = FRAME_X_DISPLAY (s->f); int len = to - from; GC gc = s->gc; int i; @@ -1007,7 +1008,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, if (s->gc != s->face->gc) { block_input (); - XSetFont (s->display, gc, xfont->fid); + XSetFont (display, gc, xfont->fid); unblock_input (); } @@ -1022,20 +1023,20 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, { if (s->padding_p) for (i = 0; i < len; i++) - XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawImageString (display, FRAME_X_DRAWABLE (s->f), gc, x + i, y, str + i, 1); else - XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawImageString (display, FRAME_X_DRAWABLE (s->f), gc, x, y, str, len); } else { if (s->padding_p) for (i = 0; i < len; i++) - XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawString (display, FRAME_X_DRAWABLE (s->f), gc, x + i, y, str + i, 1); else - XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawString (display, FRAME_X_DRAWABLE (s->f), gc, x, y, str, len); } unblock_input (); @@ -1048,20 +1049,20 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, { if (s->padding_p) for (i = 0; i < len; i++) - XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f), gc, x + i, y, s->char2b + from + i, 1); else - XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f), gc, x, y, s->char2b + from, len); } else { if (s->padding_p) for (i = 0; i < len; i++) - XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawString16 (display, FRAME_X_DRAWABLE (s->f), gc, x + i, y, s->char2b + from + i, 1); else - XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawString16 (display, FRAME_X_DRAWABLE (s->f), gc, x, y, s->char2b + from, len); } unblock_input (); diff --git a/src/xterm.c b/src/xterm.c index 26f74cde91..bd69e6c7a8 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1454,6 +1454,7 @@ x_set_cursor_gc (struct glyph_string *s) /* Cursor on non-default face: must merge. */ XGCValues xgcv; unsigned long mask; + Display *display = FRAME_X_DISPLAY (s->f); xgcv.background = s->f->output_data.x->cursor_pixel; xgcv.foreground = s->face->background; @@ -1479,11 +1480,11 @@ x_set_cursor_gc (struct glyph_string *s) mask = GCForeground | GCBackground | GCGraphicsExposures; if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc) - XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc, + XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc, mask, &xgcv); else FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc - = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv); + = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv); s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc; } @@ -1519,6 +1520,7 @@ x_set_mouse_face_gc (struct glyph_string *s) except for FONT. */ XGCValues xgcv; unsigned long mask; + Display *display = FRAME_X_DISPLAY (s->f); xgcv.background = s->face->background; xgcv.foreground = s->face->foreground; @@ -1526,11 +1528,11 @@ x_set_mouse_face_gc (struct glyph_string *s) mask = GCForeground | GCBackground | GCGraphicsExposures; if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc) - XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc, + XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc, mask, &xgcv); else FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc - = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv); + = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv); s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc; @@ -1672,11 +1674,12 @@ x_compute_glyph_string_overhangs (struct glyph_string *s) static void x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h) { + Display *display = FRAME_X_DISPLAY (s->f); XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv); - XSetForeground (s->display, s->gc, xgcv.background); + XGetGCValues (display, s->gc, GCForeground | GCBackground, &xgcv); + XSetForeground (display, s->gc, xgcv.background); x_fill_rectangle (s->f, s->gc, x, y, w, h); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); } @@ -1697,13 +1700,15 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p) if (s->stippled_p) { + Display *display = FRAME_X_DISPLAY (s->f); + /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); + XSetFillStyle (display, s->gc, FillOpaqueStippled); x_fill_rectangle (s->f, s->gc, s->x, s->y + box_line_width, s->background_width, s->height - 2 * box_line_width); - XSetFillStyle (s->display, s->gc, FillSolid); + XSetFillStyle (display, s->gc, FillSolid); s->background_filled_p = true; } else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width @@ -2591,7 +2596,7 @@ x_setup_relief_colors (struct glyph_string *s) XGCValues xgcv; /* Get the background color of the face. */ - XGetGCValues (s->display, s->gc, GCBackground, &xgcv); + XGetGCValues (FRAME_X_DISPLAY (s->f), s->gc, GCBackground, &xgcv); color = xgcv.background; } @@ -2801,10 +2806,11 @@ x_draw_box_rect (struct glyph_string *s, int left_x, int top_y, int right_x, int bottom_y, int width, bool left_p, bool right_p, XRectangle *clip_rect) { + Display *display = FRAME_X_DISPLAY (s->f); XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground, &xgcv); - XSetForeground (s->display, s->gc, s->face->box_color); + XGetGCValues (display, s->gc, GCForeground, &xgcv); + XSetForeground (display, s->gc, s->face->box_color); x_set_clip_rectangles (s->f, s->gc, clip_rect, 1); /* Top. */ @@ -2825,7 +2831,7 @@ x_draw_box_rect (struct glyph_string *s, x_fill_rectangle (s->f, s->gc, right_x - width + 1, top_y, width, bottom_y - top_y + 1); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); x_reset_clip_rectangles (s->f, s->gc); } @@ -2888,6 +2894,7 @@ x_composite_image (struct glyph_string *s, Pixmap dest, int srcX, int srcY, int dstX, int dstY, int width, int height) { + Display *display = FRAME_X_DISPLAY (s->f); #ifdef HAVE_XRENDER if (s->img->picture) { @@ -2897,27 +2904,27 @@ x_composite_image (struct glyph_string *s, Pixmap dest, /* FIXME: Should we do this each time or would it make sense to store destination in the frame struct? */ - default_format = XRenderFindVisualFormat (s->display, - DefaultVisual (s->display, 0)); - destination = XRenderCreatePicture (s->display, dest, + default_format = XRenderFindVisualFormat (display, + DefaultVisual (display, 0)); + destination = XRenderCreatePicture (display, dest, default_format, 0, &attr); /* FIXME: It may make sense to use PictOpSrc instead of PictOpOver, as I don't know if we care about alpha values too much here. */ - XRenderComposite (s->display, PictOpOver, + XRenderComposite (display, PictOpOver, s->img->picture, s->img->mask_picture, destination, srcX, srcY, srcX, srcY, dstX, dstY, width, height); - XRenderFreePicture (s->display, destination); + XRenderFreePicture (display, destination); return; } #endif - XCopyArea (s->display, s->img->pixmap, + XCopyArea (display, s->img->pixmap, dest, s->gc, srcX, srcY, width, height, dstX, dstY); @@ -2992,7 +2999,7 @@ x_draw_image_foreground (struct glyph_string *s) xgcv.clip_x_origin = x; xgcv.clip_y_origin = y; xgcv.function = GXcopy; - XChangeGC (s->display, s->gc, mask, &xgcv); + XChangeGC (FRAME_X_DISPLAY (s->f), s->gc, mask, &xgcv); get_glyph_string_clip_rect (s, &clip_rect); image_rect.x = x; @@ -3141,6 +3148,8 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap) if (s->img->pixmap) { + Display *display = FRAME_X_DISPLAY (s->f); + if (s->img->mask) { /* We can't set both a clip mask and use XSetClipRectangles @@ -3156,16 +3165,16 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap) xgcv.clip_x_origin = x - s->slice.x; xgcv.clip_y_origin = y - s->slice.y; xgcv.function = GXcopy; - XChangeGC (s->display, s->gc, mask, &xgcv); + XChangeGC (display, s->gc, mask, &xgcv); - XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, + XCopyArea (display, s->img->pixmap, pixmap, s->gc, s->slice.x, s->slice.y, s->slice.width, s->slice.height, x, y); - XSetClipMask (s->display, s->gc, None); + XSetClipMask (display, s->gc, None); } else { - XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, + XCopyArea (display, s->img->pixmap, pixmap, s->gc, s->slice.x, s->slice.y, s->slice.width, s->slice.height, x, y); @@ -3200,10 +3209,12 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { if (s->stippled_p) { + Display *display = FRAME_X_DISPLAY (s->f); + /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); + XSetFillStyle (display, s->gc, FillOpaqueStippled); x_fill_rectangle (s->f, s->gc, x, y, w, h); - XSetFillStyle (s->display, s->gc, FillSolid); + XSetFillStyle (display, s->gc, FillSolid); } else x_clear_glyph_string_rect (s, x, y, w, h); @@ -3231,6 +3242,7 @@ x_draw_image_glyph_string (struct glyph_string *s) int box_line_vwidth = max (s->face->box_line_width, 0); int height; #ifndef USE_CAIRO + Display *display = FRAME_X_DISPLAY (s->f); Pixmap pixmap = None; #endif @@ -3261,34 +3273,34 @@ x_draw_image_glyph_string (struct glyph_string *s) int depth = DefaultDepthOfScreen (screen); /* Create a pixmap as large as the glyph string. */ - pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f), + pixmap = XCreatePixmap (display, FRAME_X_DRAWABLE (s->f), s->background_width, s->height, depth); /* Don't clip in the following because we're working on the pixmap. */ - XSetClipMask (s->display, s->gc, None); + XSetClipMask (display, s->gc, None); /* Fill the pixmap with the background color/stipple. */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XSetTSOrigin (s->display, s->gc, - s->x, - s->y); - XFillRectangle (s->display, pixmap, s->gc, + XSetFillStyle (display, s->gc, FillOpaqueStippled); + XSetTSOrigin (display, s->gc, - s->x, - s->y); + XFillRectangle (display, pixmap, s->gc, 0, 0, s->background_width, s->height); - XSetFillStyle (s->display, s->gc, FillSolid); - XSetTSOrigin (s->display, s->gc, 0, 0); + XSetFillStyle (display, s->gc, FillSolid); + XSetTSOrigin (display, s->gc, 0, 0); } else { XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground | GCBackground, + XGetGCValues (display, s->gc, GCForeground | GCBackground, &xgcv); - XSetForeground (s->display, s->gc, xgcv.background); - XFillRectangle (s->display, pixmap, s->gc, + XSetForeground (display, s->gc, xgcv.background); + XFillRectangle (display, pixmap, s->gc, 0, 0, s->background_width, s->height); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); } } else @@ -3320,9 +3332,9 @@ x_draw_image_glyph_string (struct glyph_string *s) { x_draw_image_foreground_1 (s, pixmap); x_set_glyph_string_clipping (s); - XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc, + XCopyArea (display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc, 0, 0, s->background_width, s->height, s->x, s->y); - XFreePixmap (s->display, pixmap); + XFreePixmap (display, pixmap); } else #endif /* ! USE_CAIRO */ @@ -3383,6 +3395,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s) { int y = s->y; int w = background_width - width, h = s->height; + Display *display = FRAME_X_DISPLAY (s->f); XRectangle r; GC gc; @@ -3405,17 +3418,17 @@ x_draw_stretch_glyph_string (struct glyph_string *s) if (s->face->stipple) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, gc, FillOpaqueStippled); + XSetFillStyle (display, gc, FillOpaqueStippled); x_fill_rectangle (s->f, gc, x, y, w, h); - XSetFillStyle (s->display, gc, FillSolid); + XSetFillStyle (display, gc, FillSolid); } else { XGCValues xgcv; - XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv); - XSetForeground (s->display, gc, xgcv.background); + XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv); + XSetForeground (display, gc, xgcv.background); x_fill_rectangle (s->f, gc, x, y, w, h); - XSetForeground (s->display, gc, xgcv.foreground); + XSetForeground (display, gc, xgcv.foreground); } x_reset_clip_rectangles (s->f, gc); @@ -3470,10 +3483,12 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y) static void x_draw_underwave (struct glyph_string *s) { + Display *display = FRAME_X_DISPLAY (s->f); + /* Adjust for scale/HiDPI. */ int scale_x, scale_y; - x_get_scale_factor (s->display, &scale_x, &scale_y); + x_get_scale_factor (display, &scale_x, &scale_y); int wave_height = 3 * scale_y, wave_length = 2 * scale_x; @@ -3503,7 +3518,7 @@ x_draw_underwave (struct glyph_string *s) if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip)) return; - XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted); + XSetClipRectangles (display, s->gc, 0, 0, &final_clip, 1, Unsorted); /* Draw the waves */ @@ -3522,16 +3537,16 @@ x_draw_underwave (struct glyph_string *s) while (x1 <= xmax) { - XSetLineAttributes (s->display, s->gc, thickness, LineSolid, CapButt, + XSetLineAttributes (display, s->gc, thickness, LineSolid, CapButt, JoinRound); - XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2); + XDrawLine (display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2); x1 = x2, y1 = y2; x2 += dx, y2 = y0 + odd*dy; odd = !odd; } /* Restore previous clipping rectangle(s) */ - XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted); + XSetClipRectangles (display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted); #endif /* not USE_CAIRO */ } @@ -3648,11 +3663,12 @@ x_draw_glyph_string (struct glyph_string *s) x_draw_underwave (s); else { + Display *display = FRAME_X_DISPLAY (s->f); XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground, &xgcv); - XSetForeground (s->display, s->gc, s->face->underline_color); + XGetGCValues (display, s->gc, GCForeground, &xgcv); + XSetForeground (display, s->gc, s->face->underline_color); x_draw_underwave (s); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); } } else if (s->face->underline_type == FACE_UNDER_LINE) @@ -3732,12 +3748,13 @@ x_draw_glyph_string (struct glyph_string *s) s->x, y, s->width, thickness); else { + Display *display = FRAME_X_DISPLAY (s->f); XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground, &xgcv); - XSetForeground (s->display, s->gc, s->face->underline_color); + XGetGCValues (display, s->gc, GCForeground, &xgcv); + XSetForeground (display, s->gc, s->face->underline_color); x_fill_rectangle (s->f, s->gc, s->x, y, s->width, thickness); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); } } } @@ -3751,12 +3768,13 @@ x_draw_glyph_string (struct glyph_string *s) s->width, h); else { + Display *display = FRAME_X_DISPLAY (s->f); XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground, &xgcv); - XSetForeground (s->display, s->gc, s->face->overline_color); + XGetGCValues (display, s->gc, GCForeground, &xgcv); + XSetForeground (display, s->gc, s->face->overline_color); x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, s->width, h); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); } } @@ -3780,12 +3798,13 @@ x_draw_glyph_string (struct glyph_string *s) s->width, h); else { + Display *display = FRAME_X_DISPLAY (s->f); XGCValues xgcv; - XGetGCValues (s->display, s->gc, GCForeground, &xgcv); - XSetForeground (s->display, s->gc, s->face->strike_through_color); + XGetGCValues (display, s->gc, GCForeground, &xgcv); + XSetForeground (display, s->gc, s->face->strike_through_color); x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy, s->width, h); - XSetForeground (s->display, s->gc, xgcv.foreground); + XSetForeground (display, s->gc, xgcv.foreground); } } commit 655634808ad3b324ab844c53006e648b45713364 Author: Stefan Monnier Date: Fri May 10 08:49:03 2019 -0400 * lisp/help.el (help--read-key-sequence): Handle `switch-frame' events If you do `C-h k ... mouse-1 in other frame` (at least if you have a focus that follows the mouse), then additionally to the down-mouse-1 and mouse-1 events, a `switch-frame` event (and `select-window` event as well sometimes) is generated. When `read-key-sequence` is called with nil for `can-return-switch-frame`, this event is not returned but kept for later, which causes a subsequent `sit-for` to return nil immediately. This interfered without our "wait for double-click" which in turn prevented us from stopping after the mouse-1 click, getting stuck waiting for something else instead. (help--read-key-sequence): Pass a non-nil `can-return-switch-frame`, so the subsequent `sit-for` returns more trustworthy information. diff --git a/lisp/help.el b/lisp/help.el index 2b7eca9363..42ff375565 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -745,6 +745,7 @@ If NO-MOUSE-MOVEMENT is non-nil, ignore key sequences starting with `mouse-movement' events." (let ((enable-disabled-menus-and-buttons t) (cursor-in-echo-area t) + (side-event nil) saved-yank-menu) (unwind-protect (let (last-modifiers key-list) @@ -763,7 +764,8 @@ with `mouse-movement' events." (and (memq 'click last-modifiers) (not (sit-for (/ double-click-time 1000.0) t)))) (let* ((seq (read-key-sequence "\ -Describe the following key, mouse click, or menu item: ")) +Describe the following key, mouse click, or menu item: " + nil nil 'can-return-switch-frame)) (raw-seq (this-single-command-raw-keys)) (keyn (when (> (length seq) 0) (aref seq (1- (length seq))))) @@ -772,11 +774,18 @@ Describe the following key, mouse click, or menu item: ")) (cond ((zerop (length seq))) ;FIXME: Can this happen? ((and no-mouse-movement (eq base 'mouse-movement)) nil) + ((memq base '(mouse-movement switch-frame select-window)) + ;; Mostly ignore these events since it's sometimes difficult to + ;; generate the event you care about without also generating + ;; these side-events along the way. + (setq side-event (cons seq raw-seq))) ((eq base 'help-echo) nil) (t (setq last-modifiers modifiers) (push (cons seq raw-seq) key-list))))) - (nreverse key-list)) + (if side-event + (cons side-event (nreverse key-list)) + (nreverse key-list))) ;; Put yank-menu back as it was, if we changed it. (when saved-yank-menu (setq yank-menu (copy-sequence saved-yank-menu)) commit e8709e790006c75e1c91dbf0d50d5dbc816329f6 Author: Michael Albinus Date: Fri May 10 14:48:07 2019 +0200 Handle subdomains in Tramp ad-hoc proxies * lisp/net/tramp-sh.el (tramp-compute-multi-hops): Add proper regexps to `tramp-default-proxies-alist'. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index b9df403309..95fa61af98 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4622,21 +4622,19 @@ Goes through the list `tramp-inline-compress-commands'." ;; Ad-hoc proxy definitions. (dolist (proxy (reverse (split-string hops tramp-postfix-hop-regexp 'omit))) - (let ((user-domain (tramp-file-name-user-domain item)) - (host-port (tramp-file-name-host-port item)) - (proxy (concat - tramp-prefix-format proxy tramp-postfix-host-format))) - (tramp-message - vec 5 "Add proxy (\"%s\" \"%s\" \"%s\")" - (and (stringp host-port) (regexp-quote host-port)) - (and (stringp user-domain) (regexp-quote user-domain)) - proxy) + (let* ((host-port (tramp-file-name-host-port item)) + (user-domain (tramp-file-name-user-domain item)) + (proxy (concat + tramp-prefix-format proxy tramp-postfix-host-format)) + (entry + (list (and (stringp host-port) + (concat "^" (regexp-quote host-port) "$")) + (and (stringp user-domain) + (concat "^" (regexp-quote user-domain) "$")) + (propertize proxy 'tramp-ad-hoc t)))) + (tramp-message vec 5 "Add %S to `tramp-default-proxies-alist'" entry) ;; Add the hop. - (add-to-list - 'tramp-default-proxies-alist - (list (and (stringp host-port) (regexp-quote host-port)) - (and (stringp user-domain) (regexp-quote user-domain)) - (propertize proxy 'tramp-ad-hoc t))) + (add-to-list 'tramp-default-proxies-alist entry) (setq item (tramp-dissect-file-name proxy)))) ;; Save the new value. (when (and hops tramp-save-ad-hoc-proxies) commit 510aa7505fc14e0ebc6a0d220160397f068c5c04 Author: Noam Postavsky Date: Tue May 7 08:18:49 2019 -0400 Stop using message-default-charset (Bug#35370) In 2016-02-14 "Remove compat code for older Emacsen", message-default-charset was obsoleted, and a couple of uses were removed, but others were left behind. * lisp/gnus/message.el (message-send-mail) (message-send-news, message-do-fcc) (message-encode-message-body): * lisp/gnus/mml.el (mml-to-mime): Stop using message-default-charset. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index c8b6f0ee68..2c2122d89a 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -4588,8 +4588,7 @@ This function could be useful in `message-setup-hook'." (message-generate-headers '(Lines))) ;; Remove some headers. (message-remove-header message-ignored-mail-headers t) - (let ((mail-parse-charset message-default-charset)) - (mail-encode-encoded-word-buffer))) + (mail-encode-encoded-word-buffer)) (goto-char (point-max)) ;; require one newline at the end. (or (= (preceding-char) ?\n) @@ -4962,8 +4961,7 @@ Otherwise, generate and save a value for `canlock-password' first." (message-generate-headers '(Lines))) ;; Remove some headers. (message-remove-header message-ignored-news-headers t) - (let ((mail-parse-charset message-default-charset)) - (mail-encode-encoded-word-buffer))) + (mail-encode-encoded-word-buffer)) (goto-char (point-max)) ;; require one newline at the end. (or (= (preceding-char) ?\n) @@ -5441,8 +5439,7 @@ The result is a fixnum." (while (setq file (message-fetch-field "fcc" t)) (push file list) (message-remove-header "fcc" nil t)) - (let ((mail-parse-charset message-default-charset) - (rfc2047-header-encoding-alist + (let ((rfc2047-header-encoding-alist (cons '("Newsgroups" . default) rfc2047-header-encoding-alist))) (mail-encode-encoded-word-buffer))) @@ -8101,9 +8098,7 @@ regexp VARSTR." (defun message-encode-message-body () (unless message-inhibit-body-encoding - (let ((mail-parse-charset (or mail-parse-charset - message-default-charset)) - (case-fold-search t) + (let ((case-fold-search t) lines content-type-p) (message-goto-body) (save-restriction diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index f6d358dfc0..7a99a0dc46 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -48,7 +48,6 @@ (defvar gnus-article-mime-handles) (defvar gnus-newsrc-hashtb) -(defvar message-default-charset) (defvar message-deletable-headers) (defvar message-options) (defvar message-posting-charset) @@ -1015,8 +1014,7 @@ If HANDLES is non-nil, use it instead reparsing the buffer." ;; Skip past any From_ headers. (while (looking-at "From ") (forward-line 1)) - (let ((mail-parse-charset message-default-charset)) - (mail-encode-encoded-word-buffer))) + (mail-encode-encoded-word-buffer)) (message-encode-message-body)) (defun mml-insert-mime (handle &optional no-markup) commit 8ce5e37ce8f3274f0b8dddec723e2c71fbe87ea0 Author: Alan Mackenzie Date: Fri May 10 10:21:09 2019 +0000 Optimize CC Mode a bit for repetitive insertion and replace-regexp This is mainly by enhancing a parse-partial-sexp cache to retain recently calculated values. Also, there are several miscellaneous optimizations and bug fixes. * lisp/progmodes/cc-engine.el (c-state-semi-nonlit-near-cache): New buffer local variable. (c-state-semi-trim-near-cache, c-state-semi-get-near-cache-entry) (c-state-semi-put-near-cache-entry, c-state-semi-trim-cache): New functions. (c-state-semi-pp-to-literal, c-state-full-pp-to-literal): Use the new "near" cache. (c-parse-ps-state-below): Use the new function c-state-semi-trim-cache. (c-before-change-check-<>-operators): Check simply for < or > in the neighbourhood before doing more expensive processing. (c-maybe-re-mark-raw-string): Give a backward search limit to an operation which was needlessly lacking one. * lisp/progmodes/cc-mode.el (c-doc-fl-decl-start, c-doc-fl-decl-end): Check a certain regexp is valid before performing the (somewhat expensive) actions of these functions. (c-fl-decl-start): In the search for a C++ lambda capture list, replace (slow) calculation of c-parse-state by a (less slow) c-go-up-list-backward. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index a2762ca209..a25d059553 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -2526,6 +2526,25 @@ comment at the start of cc-engine.el for more info." ;; reduced by buffer changes, and increased by invocations of ;; `c-state-literal-at'. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; We also maintain a less simple cache of positions which aren't in a +;; literal, disregarding macros. +;; +;; This cache is in two parts: the "near" cache, which is an association list +;; of a small number (currently six) of positions and the parser states there; +;; the "far" cache (also known as "the cache"), a list of compressed parser +;; states going back to the beginning of the buffer, one entry every 3000 +;; characters. +;; +;; When searching this cache, `c-state-semi-pp-to-literal' first seeks an +;; exact match, then a "close" match from the near cache. If neither of these +;; succeed, the nearest entry in the far cache is used. +;; +;; Because either sub-cache can raise `c-state-semi-nonlit-pos-cache-limit', +;; both of them are "trimmed" together after a buffer change to ensure +;; consistency. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (defvar c-state-semi-nonlit-pos-cache nil) (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache) ;; A list of elements which are either buffer positions (when such positions @@ -2539,12 +2558,62 @@ comment at the start of cc-engine.el for more info." ;; is reduced by buffer changes, and increased by invocations of ;; `c-parse-ps-state-below'. +(defvar c-state-semi-nonlit-near-cache nil) +(make-variable-buffer-local 'c-state-semi-nonlit-near-cache) +;; A list of up to six recent results from `c-state-semi-pp-to-literal'. Each +;; element is a cons of the buffer position and the `parse-partial-sexp' state +;; at that position. + (defsubst c-truncate-semi-nonlit-pos-cache (pos) ;; Truncate the upper bound of the cache `c-state-semi-nonlit-pos-cache' to ;; POS, if it is higher than that position. (setq c-state-semi-nonlit-pos-cache-limit (min c-state-semi-nonlit-pos-cache-limit pos))) +(defun c-state-semi-trim-near-cache () + ;; Remove stale entries in `c-state-semi-nonlit-near-cache', i.e. those + ;; whose positions are above `c-state-semi-nonlit-pos-cache-limit'. + (let ((nc-list c-state-semi-nonlit-near-cache)) + (while nc-list + (if (> (caar nc-list) c-state-semi-nonlit-pos-cache-limit) + (setq c-state-semi-nonlit-near-cache + (delq (car nc-list) c-state-semi-nonlit-near-cache) + nc-list c-state-semi-nonlit-near-cache) ; start again in case + ; of list breakage. + (setq nc-list (cdr nc-list)))))) + +(defun c-state-semi-get-near-cache-entry (here) + ;; Return the near cache entry at the highest postion before HERE, if any, + ;; or nil. The near cache entry is of the form (POSITION . STATE), where + ;; STATE has the form of a result of `parse-partial-sexp'. + (let ((nc-pos-state + (or (assq here c-state-semi-nonlit-near-cache) + (let ((nc-list c-state-semi-nonlit-near-cache) + pos (nc-pos 0) cand-pos-state) + (while nc-list + (setq pos (caar nc-list)) + (when (and (<= pos here) + (> pos nc-pos)) + (setq nc-pos pos + cand-pos-state (car nc-list))) + (setq nc-list (cdr nc-list))) + cand-pos-state)))) + (when (and nc-pos-state + (not (eq nc-pos-state (car c-state-semi-nonlit-near-cache)))) + ;; Move the found cache entry to the front of the list. + (setq c-state-semi-nonlit-near-cache + (delq nc-pos-state c-state-semi-nonlit-near-cache)) + (push nc-pos-state c-state-semi-nonlit-near-cache)) + nc-pos-state)) + +(defun c-state-semi-put-near-cache-entry (here state) + ;; Put a new near cache entry into the near cache. + (while (>= (length c-state-semi-nonlit-near-cache) 6) + (setq c-state-semi-nonlit-near-cache + (delq (car (last c-state-semi-nonlit-near-cache)) + c-state-semi-nonlit-near-cache))) + (push (cons here state) c-state-semi-nonlit-near-cache)) + (defun c-state-semi-pp-to-literal (here &optional not-in-delimiter) ;; Do a parse-partial-sexp from a position in the buffer before HERE which ;; isn't in a literal, and return information about HERE, either: @@ -2564,12 +2633,28 @@ comment at the start of cc-engine.el for more info." (save-excursion (save-restriction (widen) + (c-state-semi-trim-cache) + (c-state-semi-trim-near-cache) + (setq c-state-semi-nonlit-pos-cache-limit here) (save-match-data - (let* ((base-and-state (c-parse-ps-state-below here)) + (let* ((base-and-state (c-state-semi-get-near-cache-entry here)) (base (car base-and-state)) + (near-base base) (s (cdr base-and-state)) - (s (parse-partial-sexp base here nil nil s)) - ty) + far-base-and-state far-base far-s ty) + (if (or (not base) + (< base (- here 100))) + (progn + (setq far-base-and-state (c-parse-ps-state-below here) + far-base (car far-base-and-state) + far-s (cdr far-base-and-state)) + (when (or (not base) (> far-base base)) + (setq base far-base + s far-s)))) + (when (> here base) + (setq s (parse-partial-sexp base here nil nil s))) + (when (not (eq near-base here)) + (c-state-semi-put-near-cache-entry here s)) (cond ((or (nth 3 s) (and (nth 4 s) @@ -2612,12 +2697,28 @@ comment at the start of cc-engine.el for more info." (save-excursion (save-restriction (widen) + (c-state-semi-trim-cache) + (c-state-semi-trim-near-cache) + (setq c-state-semi-nonlit-pos-cache-limit here) (save-match-data - (let* ((base-and-state (c-parse-ps-state-below here)) + (let* ((base-and-state (c-state-semi-get-near-cache-entry here)) (base (car base-and-state)) + (near-base base) (s (cdr base-and-state)) - (s (parse-partial-sexp base here nil nil s)) - ty start) + far-base-and-state far-base far-s ty start) + (if (or (not base) + (< base (- here 100))) + (progn + (setq far-base-and-state (c-parse-ps-state-below here) + far-base (car far-base-and-state) + far-s (cdr far-base-and-state)) + (when (or (not base) (> far-base base)) + (setq base far-base + s far-s)))) + (when (> here base) + (setq s (parse-partial-sexp base here nil nil s))) + (when (not (eq near-base here)) + (c-state-semi-put-near-cache-entry here s)) (cond ((or (nth 3 s) (and (nth 4 s) @@ -2812,6 +2913,14 @@ comment at the start of cc-engine.el for more info." elt (car elt))) +(defun c-state-semi-trim-cache () + ;; Trim the `c-state-semi-nonlit-pos-cache' to take account of buffer + ;; changes, indicated by `c-state-semi-nonlit-pos-cache-limit'. + (while (and c-state-semi-nonlit-pos-cache + (> (c-ps-state-cache-pos (car c-state-semi-nonlit-pos-cache)) + c-state-semi-nonlit-pos-cache-limit)) + (setq c-state-semi-nonlit-pos-cache (cdr c-state-semi-nonlit-pos-cache)))) + (defun c-parse-ps-state-below (here) ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where ;; CACHE-POS is a position not very far before HERE for which the @@ -2822,14 +2931,9 @@ comment at the start of cc-engine.el for more info." (save-excursion (save-restriction (widen) + (c-state-semi-trim-cache) (let ((c c-state-semi-nonlit-pos-cache) elt state npos high-elt) - ;; Trim the cache to take account of buffer changes. - (while (and c (> (c-ps-state-cache-pos (car c)) - c-state-semi-nonlit-pos-cache-limit)) - (setq c (cdr c))) - (setq c-state-semi-nonlit-pos-cache c) - (while (and c (> (c-ps-state-cache-pos (car c)) here)) (setq high-elt (car c)) (setq c (cdr c))) @@ -5617,7 +5721,7 @@ comment at the start of cc-engine.el for more info." (when (not high-elt) (setq stack (cdr elt)) (while - ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration. + ;; Add an element to `c-bs-cache' each iteration. (<= (setq npos (+ pos c-bs-interval)) here) (setq elt (c-update-brace-stack stack pos npos)) (setq npos (car elt)) @@ -6469,44 +6573,52 @@ comment at the start of cc-engine.el for more info." ;; ;; FIXME!!! This routine ignores the possibility of macros entirely. ;; 2010-01-29. - (save-excursion - (c-save-buffer-state - ((beg-lit-start (progn (goto-char beg) (c-literal-start))) - (end-lit-limits (progn (goto-char end) (c-literal-limits))) - new-beg new-end beg-limit end-limit) - ;; Locate the earliest < after the barrier before the changed region, - ;; which isn't already marked as a paren. - (goto-char (or beg-lit-start beg)) - (setq beg-limit (c-determine-limit 512)) - - ;; Remove the syntax-table/category properties from each pertinent <...> - ;; pair. Firstly, the ones with the < before beg and > after beg.... - (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit) - (eq (char-before) ?<)) - (c-backward-token-2) - (when (eq (char-after) ?<) - (c-clear-<-pair-props-if-match-after beg) - (setq new-beg (point)))) - (c-forward-syntactic-ws) + (when (and (> end beg) + (or + (progn + (goto-char beg) + (search-backward "<" (max (- (point) 1024) (point-min)) t)) + (progn + (goto-char end) + (search-forward ">" (min (+ (point) 1024) (point-max)) t)))) + (save-excursion + (c-save-buffer-state + ((beg-lit-start (progn (goto-char beg) (c-literal-start))) + (end-lit-limits (progn (goto-char end) (c-literal-limits))) + new-beg new-end beg-limit end-limit) + ;; Locate the earliest < after the barrier before the changed region, + ;; which isn't already marked as a paren. + (goto-char (or beg-lit-start beg)) + (setq beg-limit (c-determine-limit 512)) + + ;; Remove the syntax-table/category properties from each pertinent <...> + ;; pair. Firstly, the ones with the < before beg and > after beg.... + (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit) + (eq (char-before) ?<)) + (c-backward-token-2) + (when (eq (char-after) ?<) + (c-clear-<-pair-props-if-match-after beg) + (setq new-beg (point)))) + (c-forward-syntactic-ws) - ;; ...Then the ones with < before end and > after end. - (goto-char (if end-lit-limits (cdr end-lit-limits) end)) - (setq end-limit (c-determine-+ve-limit 512)) - (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end) - (eq (char-before) ?>)) - (c-end-of-current-token) - (when (eq (char-before) ?>) - (c-clear->-pair-props-if-match-before end (1- (point))) - (setq new-end (point)))) - (c-backward-syntactic-ws) - - ;; Extend the fontification region, if needed. - (and new-beg - (< new-beg c-new-BEG) - (setq c-new-BEG new-beg)) - (and new-end - (> new-end c-new-END) - (setq c-new-END new-end))))) + ;; ...Then the ones with < before end and > after end. + (goto-char (if end-lit-limits (cdr end-lit-limits) end)) + (setq end-limit (c-determine-+ve-limit 512)) + (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end) + (eq (char-before) ?>)) + (c-end-of-current-token) + (when (eq (char-before) ?>) + (c-clear->-pair-props-if-match-before end (1- (point))) + (setq new-end (point)))) + (c-backward-syntactic-ws) + + ;; Extend the fontification region, if needed. + (and new-beg + (< new-beg c-new-BEG) + (setq c-new-BEG new-beg)) + (and new-end + (> new-end c-new-END) + (setq c-new-END new-end)))))) (defun c-after-change-check-<>-operators (beg end) ;; This is called from `after-change-functions' when @@ -7123,7 +7235,8 @@ comment at the start of cc-engine.el for more info." t) ((save-excursion (and - (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\=" nil t) + (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\=" + (c-point 'bol) t) (setq id (match-string-no-properties 1)) (let* ((quoted-id (regexp-quote id)) (quoted-id-depth (regexp-opt-depth quoted-id))) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index ea865e0b0f..bd62fc754a 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1825,28 +1825,30 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".") ;; by `c-doc-line-join-re'), return the position of the first line of the ;; sequence. Otherwise, return nil. Point has no significance at entry to ;; and exit from this function. - (goto-char pos) - (back-to-indentation) - (and (or (looking-at c-comment-start-regexp) - (memq (c-literal-type (c-literal-limits)) '(c c++))) - (progn - (end-of-line) - (let ((here (point))) - (while (re-search-backward c-doc-line-join-re (c-point 'bopl) t)) - (and (not (eq (point) here)) - (c-point 'bol)))))) + (when (not (equal c-doc-line-join-re "a\\`")) + (goto-char pos) + (back-to-indentation) + (and (or (looking-at c-comment-start-regexp) + (memq (c-literal-type (c-literal-limits)) '(c c++))) + (progn + (end-of-line) + (let ((here (point))) + (while (re-search-backward c-doc-line-join-re (c-point 'bopl) t)) + (and (not (eq (point) here)) + (c-point 'bol))))))) (defun c-doc-fl-decl-end (pos) ;; If the line containing POS is continued by a doc comment continuation ;; marker (as defined by `c-doc-line-join-re), return the position of ;; the BOL at the end of the sequence. Otherwise, return nil. Point has no ;; significance at entry to and exit from this function. - (goto-char pos) - (back-to-indentation) - (let ((here (point))) - (while (re-search-forward c-doc-line-join-re (c-point 'eonl) t)) - (and (not (eq (point) here)) - (c-point 'bonl)))) + (when (not (equal c-doc-line-join-re "a\\`")) + (goto-char pos) + (back-to-indentation) + (let ((here (point))) + (while (re-search-forward c-doc-line-join-re (c-point 'eonl) t)) + (and (not (eq (point) here)) + (c-point 'bonl))))) (defun c-fl-decl-start (pos) ;; If the beginning of the line containing POS is in the middle of a "local" @@ -1874,13 +1876,10 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".") ;; In C++ Mode, first check if we are within a (possibly nested) lambda ;; form capture list. (when (c-major-mode-is 'c++-mode) - (let ((paren-state (c-parse-state)) - opener) - (save-excursion - (while (setq opener (c-pull-open-brace paren-state)) - (goto-char opener) - (if (c-looking-at-c++-lambda-capture-list) - (setq capture-opener (point))))))) + (save-excursion + (while (and (c-go-up-list-backward nil bod-lim) + (c-looking-at-c++-lambda-capture-list)) + (setq capture-opener (point))))) (while ;; Go to a less nested declaration each time round this loop.