diff options
| author | João Távora | 2018-06-09 15:49:04 +0100 |
|---|---|---|
| committer | João Távora | 2018-06-09 15:49:04 +0100 |
| commit | 16a7bce700f4b90bd6b2d7ab4bb860a3c29cb764 (patch) | |
| tree | 48b02e12d83195e21658476dfd56caa1af71c557 | |
| parent | 4aed7ee79cbea9963a84d5d925d39f7bc07aed98 (diff) | |
| parent | 38111b5e98380c518aeb1bb7be52b7972a248332 (diff) | |
| download | emacs-scratch/allow-custom-null-and-false-objects-in-jsonc.tar.gz emacs-scratch/allow-custom-null-and-false-objects-in-jsonc.zip | |
Merge branch 'master' into this scratch branchscratch/allow-custom-null-and-false-objects-in-jsonc
scratch/allow-custom-null-and-false-objects-in-jsonc
| -rw-r--r-- | doc/misc/flymake.texi | 8 | ||||
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | lisp/files.el | 55 | ||||
| -rw-r--r-- | lisp/isearch.el | 1 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 214 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 10 | ||||
| -rw-r--r-- | src/.gdbinit | 3 | ||||
| -rw-r--r-- | src/buffer.c | 2 | ||||
| -rw-r--r-- | src/bytecode.c | 3 | ||||
| -rw-r--r-- | src/dispextern.h | 9 | ||||
| -rw-r--r-- | src/dispnew.c | 3 | ||||
| -rw-r--r-- | src/editfns.c | 45 | ||||
| -rw-r--r-- | src/eval.c | 6 | ||||
| -rw-r--r-- | src/font.c | 4 | ||||
| -rw-r--r-- | src/fringe.c | 22 | ||||
| -rw-r--r-- | src/ftfont.c | 7 | ||||
| -rw-r--r-- | src/lisp.h | 46 | ||||
| -rw-r--r-- | src/lread.c | 6 | ||||
| -rw-r--r-- | src/msdos.c | 8 | ||||
| -rw-r--r-- | src/term.c | 8 | ||||
| -rw-r--r-- | src/window.c | 2 | ||||
| -rw-r--r-- | src/xdisp.c | 51 | ||||
| -rw-r--r-- | src/xfaces.c | 303 | ||||
| -rw-r--r-- | src/xwidget.c | 20 |
24 files changed, 575 insertions, 269 deletions
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index e7f4da75bb9..502d408f2b8 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi | |||
| @@ -84,6 +84,10 @@ Syntax check is done ``on-the-fly''. It is started whenever | |||
| 84 | @code{flymake-start-on-flymake-mode} is nil; | 84 | @code{flymake-start-on-flymake-mode} is nil; |
| 85 | 85 | ||
| 86 | @item | 86 | @item |
| 87 | the buffer is saved, unless @code{flymake-start-on-save-buffer} is | ||
| 88 | nil; | ||
| 89 | |||
| 90 | @item | ||
| 87 | a newline character is added to the buffer, unless | 91 | a newline character is added to the buffer, unless |
| 88 | @code{flymake-start-syntax-check-on-newline} is nil; | 92 | @code{flymake-start-syntax-check-on-newline} is nil; |
| 89 | 93 | ||
| @@ -220,6 +224,10 @@ after a newline character is inserted into the buffer. | |||
| 220 | A boolean flag indicating whether to start syntax check immediately | 224 | A boolean flag indicating whether to start syntax check immediately |
| 221 | after enabling @code{flymake-mode}. | 225 | after enabling @code{flymake-mode}. |
| 222 | 226 | ||
| 227 | @item flymake-start-on-save-buffer | ||
| 228 | A boolean flag indicating whether to start syntax check after saving | ||
| 229 | the buffer. | ||
| 230 | |||
| 223 | @item flymake-error | 231 | @item flymake-error |
| 224 | A custom face for highlighting regions for which an error has been | 232 | A custom face for highlighting regions for which an error has been |
| 225 | reported. | 233 | reported. |
| @@ -183,6 +183,9 @@ shown in the currently selected window. | |||
| 183 | You should instead set properties on known diagnostic symbols, like | 183 | You should instead set properties on known diagnostic symbols, like |
| 184 | ':error' and ':warning', as demonstrated in the Flymake manual. | 184 | ':error' and ':warning', as demonstrated in the Flymake manual. |
| 185 | 185 | ||
| 186 | *** New customizable variable 'flymake-start-on-save-buffer' | ||
| 187 | Control whether Flymake starts checking the buffer on save. | ||
| 188 | |||
| 186 | ** Package | 189 | ** Package |
| 187 | *** New 'package-quickstart' feature | 190 | *** New 'package-quickstart' feature |
| 188 | When 'package-quickstart' is non-nil, package.el precomputes a big autoloads | 191 | When 'package-quickstart' is non-nil, package.el precomputes a big autoloads |
| @@ -573,6 +576,11 @@ manual for more details. | |||
| 573 | * Lisp Changes in Emacs 27.1 | 576 | * Lisp Changes in Emacs 27.1 |
| 574 | 577 | ||
| 575 | +++ | 578 | +++ |
| 579 | ** Face specifications (of the kind used in `face-remapping-alist') | ||
| 580 | now support filters, allowing faces to vary between windows display | ||
| 581 | the same buffer. | ||
| 582 | |||
| 583 | +++ | ||
| 576 | ** New function assoc-delete-all. | 584 | ** New function assoc-delete-all. |
| 577 | 585 | ||
| 578 | +++ | 586 | +++ |
diff --git a/lisp/files.el b/lisp/files.el index dbe95bb6659..3921040fa9b 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -2014,17 +2014,47 @@ think it does, because \"free\" is pretty hard to define in practice." | |||
| 2014 | :version "25.1" | 2014 | :version "25.1" |
| 2015 | :type '(choice integer (const :tag "Never issue warning" nil))) | 2015 | :type '(choice integer (const :tag "Never issue warning" nil))) |
| 2016 | 2016 | ||
| 2017 | (defun abort-if-file-too-large (size op-type filename) | 2017 | (declare-function x-popup-dialog "menu.c" (position contents &optional header)) |
| 2018 | |||
| 2019 | (defun files--ask-user-about-large-file (size op-type filename offer-raw) | ||
| 2020 | (let ((prompt (format "File %s is large (%s), really %s?" | ||
| 2021 | (file-name-nondirectory filename) | ||
| 2022 | (file-size-human-readable size) op-type))) | ||
| 2023 | (if (not offer-raw) | ||
| 2024 | (if (y-or-n-p prompt) nil 'abort) | ||
| 2025 | (let* ((use-dialog (and (display-popup-menus-p) | ||
| 2026 | last-input-event | ||
| 2027 | (listp last-nonmenu-event) | ||
| 2028 | use-dialog-box)) | ||
| 2029 | (choice | ||
| 2030 | (if use-dialog | ||
| 2031 | (x-popup-dialog t `(,prompt | ||
| 2032 | ("Yes" . ?y) | ||
| 2033 | ("No" . ?n) | ||
| 2034 | ("Open in raw mode" . ?r))) | ||
| 2035 | (read-char-choice | ||
| 2036 | (concat prompt " (y)es or (n)o or (r)aw ") | ||
| 2037 | '(?y ?Y ?n ?N ?r ?R))))) | ||
| 2038 | (cond ((memq choice '(?y ?Y)) nil) | ||
| 2039 | ((memq choice '(?r ?R)) 'raw) | ||
| 2040 | (t 'abort)))))) | ||
| 2041 | |||
| 2042 | (defun abort-if-file-too-large (size op-type filename &optional offer-raw) | ||
| 2018 | "If file SIZE larger than `large-file-warning-threshold', allow user to abort. | 2043 | "If file SIZE larger than `large-file-warning-threshold', allow user to abort. |
| 2019 | OP-TYPE specifies the file operation being performed (for message to user)." | 2044 | OP-TYPE specifies the file operation being performed (for message |
| 2020 | (when (and large-file-warning-threshold size | 2045 | to user). If OFFER-RAW is true, give user the additional option |
| 2021 | (> size large-file-warning-threshold) | 2046 | to open the file in raw mode. If the user chooses this option, |
| 2022 | ;; No point in warning if we can't read it. | 2047 | `abort-if-file-too-large' returns the symbol `raw'. Otherwise, it |
| 2023 | (file-readable-p filename) | 2048 | returns nil or exits non-locally." |
| 2024 | (not (y-or-n-p (format "File %s is large (%s), really %s? " | 2049 | (let ((choice (and large-file-warning-threshold size |
| 2025 | (file-name-nondirectory filename) | 2050 | (> size large-file-warning-threshold) |
| 2026 | (file-size-human-readable size) op-type)))) | 2051 | ;; No point in warning if we can't read it. |
| 2027 | (user-error "Aborted"))) | 2052 | (file-readable-p filename) |
| 2053 | (files--ask-user-about-large-file | ||
| 2054 | size op-type filename offer-raw)))) | ||
| 2055 | (when (eq choice 'abort) | ||
| 2056 | (user-error "Aborted")) | ||
| 2057 | choice)) | ||
| 2028 | 2058 | ||
| 2029 | (defun warn-maybe-out-of-memory (size) | 2059 | (defun warn-maybe-out-of-memory (size) |
| 2030 | "Warn if an attempt to open file of SIZE bytes may run out of memory." | 2060 | "Warn if an attempt to open file of SIZE bytes may run out of memory." |
| @@ -2104,7 +2134,10 @@ the various files." | |||
| 2104 | (setq buf other)))) | 2134 | (setq buf other)))) |
| 2105 | ;; Check to see if the file looks uncommonly large. | 2135 | ;; Check to see if the file looks uncommonly large. |
| 2106 | (when (not (or buf nowarn)) | 2136 | (when (not (or buf nowarn)) |
| 2107 | (abort-if-file-too-large (nth 7 attributes) "open" filename) | 2137 | (when (eq (abort-if-file-too-large |
| 2138 | (nth 7 attributes) "open" filename t) | ||
| 2139 | 'raw) | ||
| 2140 | (setf rawfile t)) | ||
| 2108 | (warn-maybe-out-of-memory (nth 7 attributes))) | 2141 | (warn-maybe-out-of-memory (nth 7 attributes))) |
| 2109 | (if buf | 2142 | (if buf |
| 2110 | ;; We are using an existing buffer. | 2143 | ;; We are using an existing buffer. |
diff --git a/lisp/isearch.el b/lisp/isearch.el index feadf10e8b7..1e785a44c51 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el | |||
| @@ -2036,6 +2036,7 @@ If search string is empty, just beep." | |||
| 2036 | (defun isearch-yank-kill () | 2036 | (defun isearch-yank-kill () |
| 2037 | "Pull string from kill ring into search string." | 2037 | "Pull string from kill ring into search string." |
| 2038 | (interactive) | 2038 | (interactive) |
| 2039 | (unless isearch-mode (isearch-mode t)) | ||
| 2039 | (isearch-yank-string (current-kill 0))) | 2040 | (isearch-yank-string (current-kill 0))) |
| 2040 | 2041 | ||
| 2041 | (defun isearch-yank-pop () | 2042 | (defun isearch-yank-pop () |
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index a1411ad5ea2..e619fac43f2 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -1110,13 +1110,56 @@ Note that the style variables are always made local to the buffer." | |||
| 1110 | (goto-char start) | 1110 | (goto-char start) |
| 1111 | (while (progn | 1111 | (while (progn |
| 1112 | (parse-partial-sexp (point) end nil nil st-s 'syntax-table) | 1112 | (parse-partial-sexp (point) end nil nil st-s 'syntax-table) |
| 1113 | (c-clear-char-property (1- (point)) 'syntax-table) | 1113 | (unless (bobp) |
| 1114 | (c-clear-char-property (1- (point)) 'syntax-table)) | ||
| 1114 | (setq st-pos (point)) | 1115 | (setq st-pos (point)) |
| 1115 | (and (< (point) end) | 1116 | (and (< (point) end) |
| 1116 | (not (eq (char-before) ?\"))))) | 1117 | (not (eq (char-before) ?\"))))) |
| 1117 | (goto-char (min no-st-pos st-pos)) | 1118 | (goto-char (min no-st-pos st-pos)) |
| 1118 | nil)) | 1119 | nil)) |
| 1119 | 1120 | ||
| 1121 | (defun c-multiline-string-check-final-quote () | ||
| 1122 | ;; Check that the final quote in the buffer is correctly marked or not with | ||
| 1123 | ;; a string-fence syntax-table text propery. The return value has no | ||
| 1124 | ;; significance. | ||
| 1125 | (let (pos-ll pos-lt) | ||
| 1126 | (save-excursion | ||
| 1127 | (goto-char (point-max)) | ||
| 1128 | (skip-chars-backward "^\"") | ||
| 1129 | (while | ||
| 1130 | (and | ||
| 1131 | (not (bobp)) | ||
| 1132 | (cond | ||
| 1133 | ((progn | ||
| 1134 | (setq pos-ll (c-literal-limits) | ||
| 1135 | pos-lt (c-literal-type pos-ll)) | ||
| 1136 | (memq pos-lt '(c c++))) | ||
| 1137 | ;; In a comment. | ||
| 1138 | (goto-char (car pos-ll))) | ||
| 1139 | ((save-excursion | ||
| 1140 | (backward-char) ; over " | ||
| 1141 | (eq (logand (skip-chars-backward "\\\\") 1) 1)) | ||
| 1142 | ;; At an escaped string. | ||
| 1143 | (backward-char) | ||
| 1144 | t) | ||
| 1145 | (t | ||
| 1146 | ;; At a significant " | ||
| 1147 | (c-clear-char-property (1- (point)) 'syntax-table) | ||
| 1148 | (setq pos-ll (c-literal-limits) | ||
| 1149 | pos-lt (c-literal-type pos-ll)) | ||
| 1150 | nil))) | ||
| 1151 | (skip-chars-backward "^\"")) | ||
| 1152 | (cond | ||
| 1153 | ((bobp)) | ||
| 1154 | ((eq pos-lt 'string) | ||
| 1155 | (c-put-char-property (1- (point)) 'syntax-table '(15))) | ||
| 1156 | (t nil))))) | ||
| 1157 | |||
| 1158 | (defvar c-bc-changed-stringiness nil) | ||
| 1159 | ;; Non-nil when, in a before-change function, the deletion of a range of text | ||
| 1160 | ;; will change the "stringiness" of the subsequent text. Only used when | ||
| 1161 | ;; `c-multiline-sting-start-char' is a non-nil value which isn't a character. | ||
| 1162 | |||
| 1120 | (defun c-before-change-check-unbalanced-strings (beg end) | 1163 | (defun c-before-change-check-unbalanced-strings (beg end) |
| 1121 | ;; If BEG or END is inside an unbalanced string, remove the syntax-table | 1164 | ;; If BEG or END is inside an unbalanced string, remove the syntax-table |
| 1122 | ;; text property from respectively the start or end of the string. Also | 1165 | ;; text property from respectively the start or end of the string. Also |
| @@ -1175,6 +1218,18 @@ Note that the style variables are always made local to the buffer." | |||
| 1175 | (< (point) (point-max)))))) | 1218 | (< (point) (point-max)))))) |
| 1176 | (setq c-new-END (max (point) c-new-END))) | 1219 | (setq c-new-END (max (point) c-new-END))) |
| 1177 | 1220 | ||
| 1221 | (c-multiline-string-start-char | ||
| 1222 | (setq c-bc-changed-stringiness | ||
| 1223 | (not (eq (eq end-literal-type 'string) | ||
| 1224 | (eq beg-literal-type 'string)))) | ||
| 1225 | ;; Deal with deletion of backslashes before "s. | ||
| 1226 | (goto-char end) | ||
| 1227 | (if (and (looking-at "\\\\*\"") | ||
| 1228 | (eq (logand (skip-chars-backward "\\\\" beg) 1) 1)) | ||
| 1229 | (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) | ||
| 1230 | (if (eq beg-literal-type 'string) | ||
| 1231 | (setq c-new-BEG (min (car beg-limits) c-new-BEG)))) | ||
| 1232 | |||
| 1178 | ((< c-new-END (point-max)) | 1233 | ((< c-new-END (point-max)) |
| 1179 | (goto-char (1+ c-new-END)) ; might be a newline. | 1234 | (goto-char (1+ c-new-END)) ; might be a newline. |
| 1180 | ;; In the following regexp, the initial \n caters for a newline getting | 1235 | ;; In the following regexp, the initial \n caters for a newline getting |
| @@ -1183,7 +1238,6 @@ Note that the style variables are always made local to the buffer." | |||
| 1183 | nil t) | 1238 | nil t) |
| 1184 | ;; We're at an EOLL or point-max. | 1239 | ;; We're at an EOLL or point-max. |
| 1185 | (setq c-new-END (min (1+ (point)) (point-max))) | 1240 | (setq c-new-END (min (1+ (point)) (point-max))) |
| 1186 | ;; FIXME!!! Write a clever comment here. | ||
| 1187 | (goto-char c-new-END) | 1241 | (goto-char c-new-END) |
| 1188 | (if (equal (c-get-char-property (1- (point)) 'syntax-table) '(15)) | 1242 | (if (equal (c-get-char-property (1- (point)) 'syntax-table) '(15)) |
| 1189 | (if (memq (char-before) '(?\n ?\r)) | 1243 | (if (memq (char-before) '(?\n ?\r)) |
| @@ -1202,14 +1256,16 @@ Note that the style variables are always made local to the buffer." | |||
| 1202 | (if (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) | 1256 | (if (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) |
| 1203 | (c-clear-char-property (point) 'syntax-table)))) | 1257 | (c-clear-char-property (point) 'syntax-table)))) |
| 1204 | 1258 | ||
| 1205 | (when (eq end-literal-type 'string) | 1259 | (unless (and c-multiline-string-start-char |
| 1206 | (c-clear-char-property (1- (cdr end-limits)) 'syntax-table)) | 1260 | (not (c-characterp c-multiline-string-start-char))) |
| 1261 | (when (eq end-literal-type 'string) | ||
| 1262 | (c-clear-char-property (1- (cdr end-limits)) 'syntax-table)) | ||
| 1207 | 1263 | ||
| 1208 | (when (eq beg-literal-type 'string) | 1264 | (when (eq beg-literal-type 'string) |
| 1209 | (setq c-new-BEG (min c-new-BEG (car beg-limits))) | 1265 | (setq c-new-BEG (min c-new-BEG (car beg-limits))) |
| 1210 | (c-clear-char-property (car beg-limits) 'syntax-table)))) | 1266 | (c-clear-char-property (car beg-limits) 'syntax-table))))) |
| 1211 | 1267 | ||
| 1212 | (defun c-after-change-re-mark-unbalanced-strings (beg _end _old-len) | 1268 | (defun c-after-change-re-mark-unbalanced-strings (beg end _old-len) |
| 1213 | ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with | 1269 | ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with |
| 1214 | ;; string fence syntax-table text properties. | 1270 | ;; string fence syntax-table text properties. |
| 1215 | ;; | 1271 | ;; |
| @@ -1218,66 +1274,90 @@ Note that the style variables are always made local to the buffer." | |||
| 1218 | ;; | 1274 | ;; |
| 1219 | ;; This function is called exclusively as an after-change function via | 1275 | ;; This function is called exclusively as an after-change function via |
| 1220 | ;; `c-before-font-lock-functions'. | 1276 | ;; `c-before-font-lock-functions'. |
| 1221 | (c-save-buffer-state | 1277 | (if (and c-multiline-string-start-char |
| 1222 | ((cll (progn (goto-char c-new-BEG) | 1278 | (not (c-characterp c-multiline-string-start-char))) |
| 1223 | (c-literal-limits))) | 1279 | ;; Only the last " might need to be marked. |
| 1224 | (beg-literal-type (and cll (c-literal-type cll))) | 1280 | (c-save-buffer-state |
| 1225 | (beg-limits | 1281 | ((beg-literal-limits |
| 1226 | (cond | 1282 | (progn (goto-char beg) (c-literal-limits))) |
| 1227 | ((and (eq beg-literal-type 'string) | 1283 | (beg-literal-type (c-literal-type beg-literal-limits)) |
| 1228 | (c-unescaped-nls-in-string-p (car cll))) | 1284 | end-literal-limits end-literal-type) |
| 1229 | (cons | 1285 | (when (and (eq beg-literal-type 'string) |
| 1230 | (car cll) | 1286 | (c-get-char-property (car beg-literal-limits) 'syntax-table)) |
| 1287 | (c-clear-char-property (car beg-literal-limits) 'syntax-table) | ||
| 1288 | (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) | ||
| 1289 | (setq end-literal-limits (progn (goto-char end) (c-literal-limits)) | ||
| 1290 | end-literal-type (c-literal-type end-literal-limits)) | ||
| 1291 | ;; Deal with the insertion of backslashes before a ". | ||
| 1292 | (goto-char end) | ||
| 1293 | (if (and (looking-at "\\\\*\"") | ||
| 1294 | (eq (logand (skip-chars-backward "\\\\" beg) 1) 1)) | ||
| 1295 | (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) | ||
| 1296 | (when (eq (eq (eq beg-literal-type 'string) | ||
| 1297 | (eq end-literal-type 'string)) | ||
| 1298 | c-bc-changed-stringiness) | ||
| 1299 | (c-multiline-string-check-final-quote))) | ||
| 1300 | ;; There could be several "s needing marking. | ||
| 1301 | (c-save-buffer-state | ||
| 1302 | ((cll (progn (goto-char c-new-BEG) | ||
| 1303 | (c-literal-limits))) | ||
| 1304 | (beg-literal-type (and cll (c-literal-type cll))) | ||
| 1305 | (beg-limits | ||
| 1306 | (cond | ||
| 1307 | ((and (eq beg-literal-type 'string) | ||
| 1308 | (c-unescaped-nls-in-string-p (car cll))) | ||
| 1309 | (cons | ||
| 1310 | (car cll) | ||
| 1311 | (progn | ||
| 1312 | (goto-char (1+ (car cll))) | ||
| 1313 | (search-forward-regexp | ||
| 1314 | (cdr (assq (char-after (car cll)) c-string-innards-re-alist)) | ||
| 1315 | nil t) | ||
| 1316 | (min (1+ (point)) (point-max))))) | ||
| 1317 | ((and (null beg-literal-type) | ||
| 1318 | (goto-char beg) | ||
| 1319 | (eq (char-before) c-multiline-string-start-char) | ||
| 1320 | (memq (char-after) c-string-delims)) | ||
| 1321 | (cons (point) | ||
| 1322 | (progn | ||
| 1323 | (forward-char) | ||
| 1324 | (search-forward-regexp | ||
| 1325 | (cdr (assq (char-before) c-string-innards-re-alist)) nil t) | ||
| 1326 | (1+ (point))))) | ||
| 1327 | (cll))) | ||
| 1328 | s) | ||
| 1329 | (goto-char | ||
| 1330 | (cond ((null beg-literal-type) | ||
| 1331 | c-new-BEG) | ||
| 1332 | ((eq beg-literal-type 'string) | ||
| 1333 | (car beg-limits)) | ||
| 1334 | (t ; comment | ||
| 1335 | (cdr beg-limits)))) | ||
| 1336 | (while | ||
| 1337 | (and | ||
| 1338 | (< (point) c-new-END) | ||
| 1231 | (progn | 1339 | (progn |
| 1232 | (goto-char (1+ (car cll))) | 1340 | ;; Skip over any comments before the next string. |
| 1233 | (search-forward-regexp | 1341 | (while (progn |
| 1234 | (cdr (assq (char-after (car cll)) c-string-innards-re-alist)) | 1342 | (setq s (parse-partial-sexp (point) c-new-END nil |
| 1235 | nil t) | 1343 | nil s 'syntax-table)) |
| 1236 | (min (1+ (point)) (point-max))))) | 1344 | (and (not (nth 3 s)) |
| 1237 | ((and (null beg-literal-type) | 1345 | (< (point) c-new-END) |
| 1238 | (goto-char beg) | 1346 | (not (memq (char-before) c-string-delims))))) |
| 1239 | (eq (char-before) c-multiline-string-start-char) | 1347 | ;; We're at the start of a string. |
| 1240 | (memq (char-after) c-string-delims)) | 1348 | (memq (char-before) c-string-delims))) |
| 1241 | (cons (point) | 1349 | (if (c-unescaped-nls-in-string-p (1- (point))) |
| 1242 | (progn | 1350 | (looking-at "\\(\\\\\\(.\\|\n|\\\r\\)\\|[^\"]\\)*") |
| 1243 | (forward-char) | 1351 | (looking-at (cdr (assq (char-before) c-string-innards-re-alist)))) |
| 1244 | (search-forward-regexp | 1352 | (cond |
| 1245 | (cdr (assq (char-before) c-string-innards-re-alist)) nil t) | 1353 | ((memq (char-after (match-end 0)) '(?\n ?\r)) |
| 1246 | (1+ (point))))) | 1354 | (c-put-char-property (1- (point)) 'syntax-table '(15)) |
| 1247 | (cll))) | 1355 | (c-put-char-property (match-end 0) 'syntax-table '(15))) |
| 1248 | s) | 1356 | ((or (eq (match-end 0) (point-max)) |
| 1249 | (goto-char | 1357 | (eq (char-after (match-end 0)) ?\\)) ; \ at EOB |
| 1250 | (cond ((null beg-literal-type) | 1358 | (c-put-char-property (1- (point)) 'syntax-table '(15)))) |
| 1251 | c-new-BEG) | 1359 | (goto-char (min (1+ (match-end 0)) (point-max))) |
| 1252 | ((eq beg-literal-type 'string) | 1360 | (setq s nil))))) |
| 1253 | (car beg-limits)) | ||
| 1254 | (t ; comment | ||
| 1255 | (cdr beg-limits)))) | ||
| 1256 | (while | ||
| 1257 | (and | ||
| 1258 | (< (point) c-new-END) | ||
| 1259 | (progn | ||
| 1260 | ;; Skip over any comments before the next string. | ||
| 1261 | (while (progn | ||
| 1262 | (setq s (parse-partial-sexp (point) c-new-END nil | ||
| 1263 | nil s 'syntax-table)) | ||
| 1264 | (and (not (nth 3 s)) | ||
| 1265 | (< (point) c-new-END) | ||
| 1266 | (not (memq (char-before) c-string-delims))))) | ||
| 1267 | ;; We're at the start of a string. | ||
| 1268 | (memq (char-before) c-string-delims))) | ||
| 1269 | (if (c-unescaped-nls-in-string-p (1- (point))) | ||
| 1270 | (looking-at "[^\"]*") | ||
| 1271 | (looking-at (cdr (assq (char-before) c-string-innards-re-alist)))) | ||
| 1272 | (cond | ||
| 1273 | ((memq (char-after (match-end 0)) '(?\n ?\r)) | ||
| 1274 | (c-put-char-property (1- (point)) 'syntax-table '(15)) | ||
| 1275 | (c-put-char-property (match-end 0) 'syntax-table '(15))) | ||
| 1276 | ((or (eq (match-end 0) (point-max)) | ||
| 1277 | (eq (char-after (match-end 0)) ?\\)) ; \ at EOB | ||
| 1278 | (c-put-char-property (1- (point)) 'syntax-table '(15)))) | ||
| 1279 | (goto-char (min (1+ (match-end 0)) (point-max))) | ||
| 1280 | (setq s nil)))) | ||
| 1281 | 1361 | ||
| 1282 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 1362 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 1283 | ;; Parsing of quotes. | 1363 | ;; Parsing of quotes. |
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index d8959c8356a..fdb22ccaf34 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el | |||
| @@ -196,11 +196,17 @@ If nil, never start checking buffer automatically like this." | |||
| 196 | 'flymake-start-on-flymake-mode "26.1") | 196 | 'flymake-start-on-flymake-mode "26.1") |
| 197 | 197 | ||
| 198 | (defcustom flymake-start-on-flymake-mode t | 198 | (defcustom flymake-start-on-flymake-mode t |
| 199 | "Start syntax check when `flymake-mode' is enabled. | 199 | "If non-nil, start syntax check when `flymake-mode' is enabled. |
| 200 | Specifically, start it when the buffer is actually displayed." | 200 | Specifically, start it when the buffer is actually displayed." |
| 201 | :version "26.1" | 201 | :version "26.1" |
| 202 | :type 'boolean) | 202 | :type 'boolean) |
| 203 | 203 | ||
| 204 | (defcustom flymake-start-on-save-buffer t | ||
| 205 | "If non-nil start syntax check when a buffer is saved. | ||
| 206 | Specifically, start it when the saved buffer is actually displayed." | ||
| 207 | :version "27.1" | ||
| 208 | :type 'boolean) | ||
| 209 | |||
| 204 | (defcustom flymake-log-level -1 | 210 | (defcustom flymake-log-level -1 |
| 205 | "Obsolete and ignored variable." | 211 | "Obsolete and ignored variable." |
| 206 | :type 'integer) | 212 | :type 'integer) |
| @@ -962,7 +968,7 @@ Do it only if `flymake-no-changes-timeout' is non-nil." | |||
| 962 | (flymake--schedule-timer-maybe))) | 968 | (flymake--schedule-timer-maybe))) |
| 963 | 969 | ||
| 964 | (defun flymake-after-save-hook () | 970 | (defun flymake-after-save-hook () |
| 965 | (when flymake-mode | 971 | (when flymake-start-on-save-buffer |
| 966 | (flymake-log :debug "starting syntax check as buffer was saved") | 972 | (flymake-log :debug "starting syntax check as buffer was saved") |
| 967 | (flymake-start t))) | 973 | (flymake-start t))) |
| 968 | 974 | ||
diff --git a/src/.gdbinit b/src/.gdbinit index 7a0cf02ea13..67dcf718e3c 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -1020,9 +1020,6 @@ define xpr | |||
| 1020 | if $misc == Lisp_Misc_Overlay | 1020 | if $misc == Lisp_Misc_Overlay |
| 1021 | xoverlay | 1021 | xoverlay |
| 1022 | end | 1022 | end |
| 1023 | # if $misc == Lisp_Misc_Save_Value | ||
| 1024 | # xsavevalue | ||
| 1025 | # end | ||
| 1026 | end | 1023 | end |
| 1027 | if $type == Lisp_Vectorlike | 1024 | if $type == Lisp_Vectorlike |
| 1028 | set $size = ((struct Lisp_Vector *) $ptr)->header.size | 1025 | set $size = ((struct Lisp_Vector *) $ptr)->header.size |
diff --git a/src/buffer.c b/src/buffer.c index 14837372d34..244c1851fab 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1696,7 +1696,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1696 | { | 1696 | { |
| 1697 | ptrdiff_t count = SPECPDL_INDEX (); | 1697 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1698 | 1698 | ||
| 1699 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 1699 | record_unwind_protect_excursion (); |
| 1700 | set_buffer_internal (b); | 1700 | set_buffer_internal (b); |
| 1701 | 1701 | ||
| 1702 | /* First run the query functions; if any query is answered no, | 1702 | /* First run the query functions; if any query is answered no, |
diff --git a/src/bytecode.c b/src/bytecode.c index 55b193ffb2f..772cc982f9a 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -739,8 +739,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 739 | NEXT; | 739 | NEXT; |
| 740 | 740 | ||
| 741 | CASE (Bsave_excursion): | 741 | CASE (Bsave_excursion): |
| 742 | record_unwind_protect (save_excursion_restore, | 742 | record_unwind_protect_excursion (); |
| 743 | save_excursion_save ()); | ||
| 744 | NEXT; | 743 | NEXT; |
| 745 | 744 | ||
| 746 | CASE (Bsave_current_buffer): /* Obsolete since ??. */ | 745 | CASE (Bsave_current_buffer): /* Obsolete since ??. */ |
diff --git a/src/dispextern.h b/src/dispextern.h index bc2a76f1e02..2180c9ae63f 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3429,11 +3429,12 @@ char *choose_face_font (struct frame *, Lisp_Object *, Lisp_Object, | |||
| 3429 | #ifdef HAVE_WINDOW_SYSTEM | 3429 | #ifdef HAVE_WINDOW_SYSTEM |
| 3430 | void prepare_face_for_display (struct frame *, struct face *); | 3430 | void prepare_face_for_display (struct frame *, struct face *); |
| 3431 | #endif | 3431 | #endif |
| 3432 | int lookup_named_face (struct frame *, Lisp_Object, bool); | 3432 | int lookup_named_face (struct window *, struct frame *, Lisp_Object, bool); |
| 3433 | int lookup_basic_face (struct frame *, int); | 3433 | int lookup_basic_face (struct window *, struct frame *, int); |
| 3434 | int smaller_face (struct frame *, int, int); | 3434 | int smaller_face (struct frame *, int, int); |
| 3435 | int face_with_height (struct frame *, int, int); | 3435 | int face_with_height (struct frame *, int, int); |
| 3436 | int lookup_derived_face (struct frame *, Lisp_Object, int, bool); | 3436 | int lookup_derived_face (struct window *, struct frame *, |
| 3437 | Lisp_Object, int, bool); | ||
| 3437 | void init_frame_faces (struct frame *); | 3438 | void init_frame_faces (struct frame *); |
| 3438 | void free_frame_faces (struct frame *); | 3439 | void free_frame_faces (struct frame *); |
| 3439 | void recompute_basic_faces (struct frame *); | 3440 | void recompute_basic_faces (struct frame *); |
| @@ -3443,7 +3444,7 @@ int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, | |||
| 3443 | bool, Lisp_Object); | 3444 | bool, Lisp_Object); |
| 3444 | int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, | 3445 | int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 3445 | ptrdiff_t *, enum face_id, bool); | 3446 | ptrdiff_t *, enum face_id, bool); |
| 3446 | int merge_faces (struct frame *, Lisp_Object, int, int); | 3447 | int merge_faces (struct window *, Lisp_Object, int, int); |
| 3447 | int compute_char_face (struct frame *, int, Lisp_Object); | 3448 | int compute_char_face (struct frame *, int, Lisp_Object); |
| 3448 | void free_all_realized_faces (Lisp_Object); | 3449 | void free_all_realized_faces (Lisp_Object); |
| 3449 | extern char unspecified_fg[], unspecified_bg[]; | 3450 | extern char unspecified_fg[], unspecified_bg[]; |
diff --git a/src/dispnew.c b/src/dispnew.c index b854d179d51..46e0c83ef6a 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -2508,8 +2508,7 @@ spec_glyph_lookup_face (struct window *w, GLYPH *glyph) | |||
| 2508 | /* Convert the glyph's specified face to a realized (cache) face. */ | 2508 | /* Convert the glyph's specified face to a realized (cache) face. */ |
| 2509 | if (lface_id > 0) | 2509 | if (lface_id > 0) |
| 2510 | { | 2510 | { |
| 2511 | int face_id = merge_faces (XFRAME (w->frame), | 2511 | int face_id = merge_faces (w, Qt, lface_id, DEFAULT_FACE_ID); |
| 2512 | Qt, lface_id, DEFAULT_FACE_ID); | ||
| 2513 | SET_GLYPH_FACE (*glyph, face_id); | 2512 | SET_GLYPH_FACE (*glyph, face_id); |
| 2514 | } | 2513 | } |
| 2515 | } | 2514 | } |
diff --git a/src/editfns.c b/src/editfns.c index 608304c09ad..e672c0eb74d 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1016,37 +1016,30 @@ save_excursion_save (void) | |||
| 1016 | void | 1016 | void |
| 1017 | save_excursion_restore (Lisp_Object info) | 1017 | save_excursion_restore (Lisp_Object info) |
| 1018 | { | 1018 | { |
| 1019 | Lisp_Object tem, tem1; | 1019 | Lisp_Object marker = XSAVE_OBJECT (info, 0); |
| 1020 | 1020 | Lisp_Object window = XSAVE_OBJECT (info, 2); | |
| 1021 | tem = Fmarker_buffer (XSAVE_OBJECT (info, 0)); | 1021 | free_misc (info); |
| 1022 | Lisp_Object buffer = Fmarker_buffer (marker); | ||
| 1022 | /* If we're unwinding to top level, saved buffer may be deleted. This | 1023 | /* If we're unwinding to top level, saved buffer may be deleted. This |
| 1023 | means that all of its markers are unchained and so tem is nil. */ | 1024 | means that all of its markers are unchained and so BUFFER is nil. */ |
| 1024 | if (NILP (tem)) | 1025 | if (NILP (buffer)) |
| 1025 | goto out; | 1026 | return; |
| 1026 | 1027 | ||
| 1027 | Fset_buffer (tem); | 1028 | Fset_buffer (buffer); |
| 1028 | 1029 | ||
| 1029 | /* Point marker. */ | 1030 | Fgoto_char (marker); |
| 1030 | tem = XSAVE_OBJECT (info, 0); | 1031 | unchain_marker (XMARKER (marker)); |
| 1031 | Fgoto_char (tem); | ||
| 1032 | unchain_marker (XMARKER (tem)); | ||
| 1033 | 1032 | ||
| 1034 | /* If buffer was visible in a window, and a different window was | 1033 | /* If buffer was visible in a window, and a different window was |
| 1035 | selected, and the old selected window is still showing this | 1034 | selected, and the old selected window is still showing this |
| 1036 | buffer, restore point in that window. */ | 1035 | buffer, restore point in that window. */ |
| 1037 | tem = XSAVE_OBJECT (info, 2); | 1036 | if (WINDOWP (window) && !EQ (window, selected_window)) |
| 1038 | if (WINDOWP (tem) | 1037 | { |
| 1039 | && !EQ (tem, selected_window) | 1038 | /* Set window point if WINDOW is live and shows the current buffer. */ |
| 1040 | && (tem1 = XWINDOW (tem)->contents, | 1039 | Lisp_Object contents = XWINDOW (window)->contents; |
| 1041 | (/* Window is live... */ | 1040 | if (BUFFERP (contents) && XBUFFER (contents) == current_buffer) |
| 1042 | BUFFERP (tem1) | 1041 | Fset_window_point (window, make_number (PT)); |
| 1043 | /* ...and it shows the current buffer. */ | 1042 | } |
| 1044 | && XBUFFER (tem1) == current_buffer))) | ||
| 1045 | Fset_window_point (tem, make_number (PT)); | ||
| 1046 | |||
| 1047 | out: | ||
| 1048 | |||
| 1049 | free_misc (info); | ||
| 1050 | } | 1043 | } |
| 1051 | 1044 | ||
| 1052 | DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0, | 1045 | DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0, |
| @@ -1068,7 +1061,7 @@ usage: (save-excursion &rest BODY) */) | |||
| 1068 | register Lisp_Object val; | 1061 | register Lisp_Object val; |
| 1069 | ptrdiff_t count = SPECPDL_INDEX (); | 1062 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1070 | 1063 | ||
| 1071 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 1064 | record_unwind_protect_excursion (); |
| 1072 | 1065 | ||
| 1073 | val = Fprogn (args); | 1066 | val = Fprogn (args); |
| 1074 | return unbind_to (count, val); | 1067 | return unbind_to (count, val); |
| @@ -3242,7 +3235,7 @@ buffer stay intact. */) | |||
| 3242 | 3235 | ||
| 3243 | Fundo_boundary (); | 3236 | Fundo_boundary (); |
| 3244 | ptrdiff_t count = SPECPDL_INDEX (); | 3237 | ptrdiff_t count = SPECPDL_INDEX (); |
| 3245 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 3238 | record_unwind_protect_excursion (); |
| 3246 | 3239 | ||
| 3247 | ptrdiff_t i = size_a; | 3240 | ptrdiff_t i = size_a; |
| 3248 | ptrdiff_t j = size_b; | 3241 | ptrdiff_t j = size_b; |
diff --git a/src/eval.c b/src/eval.c index 90d8c335185..86011a234c0 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -3415,6 +3415,12 @@ record_unwind_protect_int (void (*function) (int), int arg) | |||
| 3415 | } | 3415 | } |
| 3416 | 3416 | ||
| 3417 | void | 3417 | void |
| 3418 | record_unwind_protect_excursion (void) | ||
| 3419 | { | ||
| 3420 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | ||
| 3421 | } | ||
| 3422 | |||
| 3423 | void | ||
| 3418 | record_unwind_protect_void (void (*function) (void)) | 3424 | record_unwind_protect_void (void (*function) (void)) |
| 3419 | { | 3425 | { |
| 3420 | specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID; | 3426 | specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID; |
diff --git a/src/font.c b/src/font.c index 305bb14576a..c886c299d19 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -3810,7 +3810,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, | |||
| 3810 | face_id = | 3810 | face_id = |
| 3811 | NILP (Vface_remapping_alist) | 3811 | NILP (Vface_remapping_alist) |
| 3812 | ? DEFAULT_FACE_ID | 3812 | ? DEFAULT_FACE_ID |
| 3813 | : lookup_basic_face (f, DEFAULT_FACE_ID); | 3813 | : lookup_basic_face (w, f, DEFAULT_FACE_ID); |
| 3814 | 3814 | ||
| 3815 | face_id = face_at_string_position (w, string, pos, 0, &ignore, | 3815 | face_id = face_at_string_position (w, string, pos, 0, &ignore, |
| 3816 | face_id, false); | 3816 | face_id, false); |
| @@ -4559,7 +4559,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, | |||
| 4559 | CHECK_CHARACTER (ch); | 4559 | CHECK_CHARACTER (ch); |
| 4560 | c = XINT (ch); | 4560 | c = XINT (ch); |
| 4561 | f = XFRAME (selected_frame); | 4561 | f = XFRAME (selected_frame); |
| 4562 | face_id = lookup_basic_face (f, DEFAULT_FACE_ID); | 4562 | face_id = lookup_basic_face (NULL, f, DEFAULT_FACE_ID); |
| 4563 | pos = -1; | 4563 | pos = -1; |
| 4564 | } | 4564 | } |
| 4565 | else | 4565 | else |
diff --git a/src/fringe.c b/src/fringe.c index 85aa14da727..60691846814 100644 --- a/src/fringe.c +++ b/src/fringe.c | |||
| @@ -587,8 +587,8 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o | |||
| 587 | if (face_id == DEFAULT_FACE_ID) | 587 | if (face_id == DEFAULT_FACE_ID) |
| 588 | { | 588 | { |
| 589 | Lisp_Object face = fringe_faces[which]; | 589 | Lisp_Object face = fringe_faces[which]; |
| 590 | face_id = NILP (face) ? lookup_named_face (f, Qfringe, false) | 590 | face_id = NILP (face) ? lookup_named_face (w, f, Qfringe, false) |
| 591 | : lookup_derived_face (f, face, FRINGE_FACE_ID, 0); | 591 | : lookup_derived_face (w, f, face, FRINGE_FACE_ID, 0); |
| 592 | if (face_id < 0) | 592 | if (face_id < 0) |
| 593 | face_id = FRINGE_FACE_ID; | 593 | face_id = FRINGE_FACE_ID; |
| 594 | } | 594 | } |
| @@ -1633,20 +1633,10 @@ If FACE is nil, reset face to default fringe face. */) | |||
| 1633 | if (!n) | 1633 | if (!n) |
| 1634 | error ("Undefined fringe bitmap"); | 1634 | error ("Undefined fringe bitmap"); |
| 1635 | 1635 | ||
| 1636 | /* The purpose of the following code is to signal an error if FACE | 1636 | /* We used to check, as a convenience to callers, for basic face |
| 1637 | is not a face. This is for the caller's convenience only; the | 1637 | validity here, but since validity can depend on the specific |
| 1638 | redisplay code should be able to fail gracefully. Skip the check | 1638 | _window_ in which this buffer is being displayed, defer the check |
| 1639 | if FRINGE_FACE_ID is unrealized (as in batch mode and during | 1639 | to redisplay, which can cope with bad face specifications. */ |
| 1640 | daemon startup). */ | ||
| 1641 | if (!NILP (face)) | ||
| 1642 | { | ||
| 1643 | struct frame *f = SELECTED_FRAME (); | ||
| 1644 | |||
| 1645 | if (FACE_FROM_ID_OR_NULL (f, FRINGE_FACE_ID) | ||
| 1646 | && lookup_derived_face (f, face, FRINGE_FACE_ID, 1) < 0) | ||
| 1647 | error ("No such face"); | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | fringe_faces[n] = face; | 1640 | fringe_faces[n] = face; |
| 1651 | return Qnil; | 1641 | return Qnil; |
| 1652 | } | 1642 | } |
diff --git a/src/ftfont.c b/src/ftfont.c index 9a8777ef078..a53467000f3 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -1131,16 +1131,19 @@ ftfont_open2 (struct frame *f, | |||
| 1131 | return Qnil; | 1131 | return Qnil; |
| 1132 | } | 1132 | } |
| 1133 | } | 1133 | } |
| 1134 | set_save_integer (val, 1, XSAVE_INTEGER (val, 1) + 1); | ||
| 1135 | size = XINT (AREF (entity, FONT_SIZE_INDEX)); | 1134 | size = XINT (AREF (entity, FONT_SIZE_INDEX)); |
| 1136 | if (size == 0) | 1135 | if (size == 0) |
| 1137 | size = pixel_size; | 1136 | size = pixel_size; |
| 1138 | if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) | 1137 | if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) |
| 1139 | { | 1138 | { |
| 1140 | if (XSAVE_INTEGER (val, 1) == 0) | 1139 | if (XSAVE_INTEGER (val, 1) == 0) |
| 1141 | FT_Done_Face (ft_face); | 1140 | { |
| 1141 | FT_Done_Face (ft_face); | ||
| 1142 | cache_data->ft_face = NULL; | ||
| 1143 | } | ||
| 1142 | return Qnil; | 1144 | return Qnil; |
| 1143 | } | 1145 | } |
| 1146 | set_save_integer (val, 1, XSAVE_INTEGER (val, 1) + 1); | ||
| 1144 | 1147 | ||
| 1145 | ASET (font_object, FONT_FILE_INDEX, filename); | 1148 | ASET (font_object, FONT_FILE_INDEX, filename); |
| 1146 | font = XFONT_OBJECT (font_object); | 1149 | font = XFONT_OBJECT (font_object); |
diff --git a/src/lisp.h b/src/lisp.h index ee2e72d32b7..293cf2783c3 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -228,8 +228,8 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; | |||
| 228 | 228 | ||
| 229 | USE_LSB_TAG not only requires the least 3 bits of pointers returned by | 229 | USE_LSB_TAG not only requires the least 3 bits of pointers returned by |
| 230 | malloc to be 0 but also needs to be able to impose a mult-of-8 alignment | 230 | malloc to be 0 but also needs to be able to impose a mult-of-8 alignment |
| 231 | on the few static Lisp_Objects used, all of which are aligned via | 231 | on some non-GC Lisp_Objects, all of which are aligned via |
| 232 | 'char alignas (GCALIGNMENT) gcaligned;' inside a union. */ | 232 | GCALIGNED_UNION at the end of a union. */ |
| 233 | 233 | ||
| 234 | enum Lisp_Bits | 234 | enum Lisp_Bits |
| 235 | { | 235 | { |
| @@ -277,6 +277,12 @@ DEFINE_GDB_SYMBOL_END (VALMASK) | |||
| 277 | error !; | 277 | error !; |
| 278 | #endif | 278 | #endif |
| 279 | 279 | ||
| 280 | #if USE_LSB_TAG | ||
| 281 | # define GCALIGNED_UNION char alignas (GCALIGNMENT) gcaligned; | ||
| 282 | #else | ||
| 283 | # define GCALIGNED_UNION | ||
| 284 | #endif | ||
| 285 | |||
| 280 | /* Lisp_Word is a scalar word suitable for holding a tagged pointer or | 286 | /* Lisp_Word is a scalar word suitable for holding a tagged pointer or |
| 281 | integer. Usually it is a pointer to a deliberately-incomplete type | 287 | integer. Usually it is a pointer to a deliberately-incomplete type |
| 282 | 'union Lisp_X'. However, it is EMACS_INT when Lisp_Objects and | 288 | 'union Lisp_X'. However, it is EMACS_INT when Lisp_Objects and |
| @@ -776,10 +782,10 @@ struct Lisp_Symbol | |||
| 776 | /* Next symbol in obarray bucket, if the symbol is interned. */ | 782 | /* Next symbol in obarray bucket, if the symbol is interned. */ |
| 777 | struct Lisp_Symbol *next; | 783 | struct Lisp_Symbol *next; |
| 778 | } s; | 784 | } s; |
| 779 | char alignas (GCALIGNMENT) gcaligned; | 785 | GCALIGNED_UNION |
| 780 | } u; | 786 | } u; |
| 781 | }; | 787 | }; |
| 782 | verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); | 788 | verify (!USE_LSB_TAG || alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); |
| 783 | 789 | ||
| 784 | /* Declare a Lisp-callable function. The MAXARGS parameter has the same | 790 | /* Declare a Lisp-callable function. The MAXARGS parameter has the same |
| 785 | meaning as in the DEFUN macro, and is used to construct a prototype. */ | 791 | meaning as in the DEFUN macro, and is used to construct a prototype. */ |
| @@ -890,9 +896,9 @@ union vectorlike_header | |||
| 890 | Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, | 896 | Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, |
| 891 | 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ | 897 | 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ |
| 892 | ptrdiff_t size; | 898 | ptrdiff_t size; |
| 893 | char alignas (GCALIGNMENT) gcaligned; | 899 | GCALIGNED_UNION |
| 894 | }; | 900 | }; |
| 895 | verify (alignof (union vectorlike_header) % GCALIGNMENT == 0); | 901 | verify (!USE_LSB_TAG || alignof (union vectorlike_header) % GCALIGNMENT == 0); |
| 896 | 902 | ||
| 897 | INLINE bool | 903 | INLINE bool |
| 898 | (SYMBOLP) (Lisp_Object x) | 904 | (SYMBOLP) (Lisp_Object x) |
| @@ -1250,10 +1256,10 @@ struct Lisp_Cons | |||
| 1250 | struct Lisp_Cons *chain; | 1256 | struct Lisp_Cons *chain; |
| 1251 | } u; | 1257 | } u; |
| 1252 | } s; | 1258 | } s; |
| 1253 | char alignas (GCALIGNMENT) gcaligned; | 1259 | GCALIGNED_UNION |
| 1254 | } u; | 1260 | } u; |
| 1255 | }; | 1261 | }; |
| 1256 | verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0); | 1262 | verify (!USE_LSB_TAG || alignof (struct Lisp_Cons) % GCALIGNMENT == 0); |
| 1257 | 1263 | ||
| 1258 | INLINE bool | 1264 | INLINE bool |
| 1259 | (NILP) (Lisp_Object x) | 1265 | (NILP) (Lisp_Object x) |
| @@ -1372,10 +1378,10 @@ struct Lisp_String | |||
| 1372 | unsigned char *data; | 1378 | unsigned char *data; |
| 1373 | } s; | 1379 | } s; |
| 1374 | struct Lisp_String *next; | 1380 | struct Lisp_String *next; |
| 1375 | char alignas (GCALIGNMENT) gcaligned; | 1381 | GCALIGNED_UNION |
| 1376 | } u; | 1382 | } u; |
| 1377 | }; | 1383 | }; |
| 1378 | verify (alignof (struct Lisp_String) % GCALIGNMENT == 0); | 1384 | verify (!USE_LSB_TAG || alignof (struct Lisp_String) % GCALIGNMENT == 0); |
| 1379 | 1385 | ||
| 1380 | INLINE bool | 1386 | INLINE bool |
| 1381 | STRINGP (Lisp_Object x) | 1387 | STRINGP (Lisp_Object x) |
| @@ -3977,6 +3983,7 @@ extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); | |||
| 3977 | extern void record_unwind_protect_ptr (void (*) (void *), void *); | 3983 | extern void record_unwind_protect_ptr (void (*) (void *), void *); |
| 3978 | extern void record_unwind_protect_int (void (*) (int), int); | 3984 | extern void record_unwind_protect_int (void (*) (int), int); |
| 3979 | extern void record_unwind_protect_void (void (*) (void)); | 3985 | extern void record_unwind_protect_void (void (*) (void)); |
| 3986 | extern void record_unwind_protect_excursion (void); | ||
| 3980 | extern void record_unwind_protect_nothing (void); | 3987 | extern void record_unwind_protect_nothing (void); |
| 3981 | extern void clear_unwind_protect (ptrdiff_t); | 3988 | extern void clear_unwind_protect (ptrdiff_t); |
| 3982 | extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object); | 3989 | extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object); |
| @@ -4680,13 +4687,14 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4680 | #define SAFE_ALLOCA_LISP(buf, nelt) SAFE_ALLOCA_LISP_EXTRA (buf, nelt, 0) | 4687 | #define SAFE_ALLOCA_LISP(buf, nelt) SAFE_ALLOCA_LISP_EXTRA (buf, nelt, 0) |
| 4681 | 4688 | ||
| 4682 | 4689 | ||
| 4683 | /* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate | 4690 | /* If USE_STACK_LISP_OBJECTS, define macros and functions that |
| 4684 | block-scoped conses and strings. These objects are not | 4691 | allocate some Lisp objects on the C stack. As the storage is not |
| 4685 | managed by the garbage collector, so they are dangerous: passing them | 4692 | managed by the garbage collector, these objects are dangerous: |
| 4686 | out of their scope (e.g., to user code) results in undefined behavior. | 4693 | passing them to user code could result in undefined behavior if the |
| 4687 | Conversely, they have better performance because GC is not involved. | 4694 | objects are in use after the C function returns. Conversely, these |
| 4695 | objects have better performance because GC is not involved. | ||
| 4688 | 4696 | ||
| 4689 | This feature is experimental and requires careful debugging. | 4697 | While debugging you may want to disable allocation on the C stack. |
| 4690 | Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */ | 4698 | Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */ |
| 4691 | 4699 | ||
| 4692 | #if (!defined USE_STACK_LISP_OBJECTS \ | 4700 | #if (!defined USE_STACK_LISP_OBJECTS \ |
| @@ -4751,7 +4759,8 @@ enum | |||
| 4751 | Take its unibyte value from the null-terminated string STR, | 4759 | Take its unibyte value from the null-terminated string STR, |
| 4752 | an expression that should not have side effects. | 4760 | an expression that should not have side effects. |
| 4753 | STR's value is not necessarily copied. The resulting Lisp string | 4761 | STR's value is not necessarily copied. The resulting Lisp string |
| 4754 | should not be modified or made visible to user code. */ | 4762 | should not be modified or given text properties or made visible to |
| 4763 | user code. */ | ||
| 4755 | 4764 | ||
| 4756 | #define AUTO_STRING(name, str) \ | 4765 | #define AUTO_STRING(name, str) \ |
| 4757 | AUTO_STRING_WITH_LEN (name, str, strlen (str)) | 4766 | AUTO_STRING_WITH_LEN (name, str, strlen (str)) |
| @@ -4760,7 +4769,8 @@ enum | |||
| 4760 | Take its unibyte value from the null-terminated string STR with length LEN. | 4769 | Take its unibyte value from the null-terminated string STR with length LEN. |
| 4761 | STR may have side effects and may contain null bytes. | 4770 | STR may have side effects and may contain null bytes. |
| 4762 | STR's value is not necessarily copied. The resulting Lisp string | 4771 | STR's value is not necessarily copied. The resulting Lisp string |
| 4763 | should not be modified or made visible to user code. */ | 4772 | should not be modified or given text properties or made visible to |
| 4773 | user code. */ | ||
| 4764 | 4774 | ||
| 4765 | #define AUTO_STRING_WITH_LEN(name, str, len) \ | 4775 | #define AUTO_STRING_WITH_LEN(name, str, len) \ |
| 4766 | Lisp_Object name = \ | 4776 | Lisp_Object name = \ |
diff --git a/src/lread.c b/src/lread.c index 239c66ccb85..d2c7eae20f9 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -1976,11 +1976,11 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1976 | if (!NILP (start)) | 1976 | if (!NILP (start)) |
| 1977 | { | 1977 | { |
| 1978 | /* Switch to the buffer we are reading from. */ | 1978 | /* Switch to the buffer we are reading from. */ |
| 1979 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 1979 | record_unwind_protect_excursion (); |
| 1980 | set_buffer_internal (b); | 1980 | set_buffer_internal (b); |
| 1981 | 1981 | ||
| 1982 | /* Save point in it. */ | 1982 | /* Save point in it. */ |
| 1983 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 1983 | record_unwind_protect_excursion (); |
| 1984 | /* Save ZV in it. */ | 1984 | /* Save ZV in it. */ |
| 1985 | record_unwind_protect (save_restriction_restore, save_restriction_save ()); | 1985 | record_unwind_protect (save_restriction_restore, save_restriction_save ()); |
| 1986 | /* Those get unbound after we read one expression. */ | 1986 | /* Those get unbound after we read one expression. */ |
| @@ -2137,7 +2137,7 @@ This function preserves the position of point. */) | |||
| 2137 | 2137 | ||
| 2138 | specbind (Qeval_buffer_list, Fcons (buf, Veval_buffer_list)); | 2138 | specbind (Qeval_buffer_list, Fcons (buf, Veval_buffer_list)); |
| 2139 | specbind (Qstandard_output, tem); | 2139 | specbind (Qstandard_output, tem); |
| 2140 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 2140 | record_unwind_protect_excursion (); |
| 2141 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); | 2141 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); |
| 2142 | specbind (Qlexical_binding, lisp_file_lexically_bound_p (buf) ? Qt : Qnil); | 2142 | specbind (Qlexical_binding, lisp_file_lexically_bound_p (buf) ? Qt : Qnil); |
| 2143 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); | 2143 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); |
diff --git a/src/msdos.c b/src/msdos.c index eedbf7b1a6c..6c0dfa0c46a 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -3063,15 +3063,15 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | |||
| 3063 | state = alloca (menu->panecount * sizeof (struct IT_menu_state)); | 3063 | state = alloca (menu->panecount * sizeof (struct IT_menu_state)); |
| 3064 | screensize = screen_size * 2; | 3064 | screensize = screen_size * 2; |
| 3065 | faces[0] | 3065 | faces[0] |
| 3066 | = lookup_derived_face (sf, intern ("msdos-menu-passive-face"), | 3066 | = lookup_derived_face (NULL, sf, intern ("msdos-menu-passive-face"), |
| 3067 | DEFAULT_FACE_ID, 1); | 3067 | DEFAULT_FACE_ID, 1); |
| 3068 | faces[1] | 3068 | faces[1] |
| 3069 | = lookup_derived_face (sf, intern ("msdos-menu-active-face"), | 3069 | = lookup_derived_face (NULL, sf, intern ("msdos-menu-active-face"), |
| 3070 | DEFAULT_FACE_ID, 1); | 3070 | DEFAULT_FACE_ID, 1); |
| 3071 | selectface = intern ("msdos-menu-select-face"); | 3071 | selectface = intern ("msdos-menu-select-face"); |
| 3072 | faces[2] = lookup_derived_face (sf, selectface, | 3072 | faces[2] = lookup_derived_face (NULL, sf, selectface, |
| 3073 | faces[0], 1); | 3073 | faces[0], 1); |
| 3074 | faces[3] = lookup_derived_face (sf, selectface, | 3074 | faces[3] = lookup_derived_face (NULL, sf, selectface, |
| 3075 | faces[1], 1); | 3075 | faces[1], 1); |
| 3076 | 3076 | ||
| 3077 | /* Make sure the menu title is always displayed with | 3077 | /* Make sure the menu title is always displayed with |
diff --git a/src/term.c b/src/term.c index 08d483f4fa0..bcd7dd82d6f 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -3132,15 +3132,15 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3132 | SAFE_NALLOCA (state, 1, menu->panecount); | 3132 | SAFE_NALLOCA (state, 1, menu->panecount); |
| 3133 | memset (state, 0, sizeof (*state)); | 3133 | memset (state, 0, sizeof (*state)); |
| 3134 | faces[0] | 3134 | faces[0] |
| 3135 | = lookup_derived_face (sf, intern ("tty-menu-disabled-face"), | 3135 | = lookup_derived_face (NULL, sf, intern ("tty-menu-disabled-face"), |
| 3136 | DEFAULT_FACE_ID, 1); | 3136 | DEFAULT_FACE_ID, 1); |
| 3137 | faces[1] | 3137 | faces[1] |
| 3138 | = lookup_derived_face (sf, intern ("tty-menu-enabled-face"), | 3138 | = lookup_derived_face (NULL, sf, intern ("tty-menu-enabled-face"), |
| 3139 | DEFAULT_FACE_ID, 1); | 3139 | DEFAULT_FACE_ID, 1); |
| 3140 | selectface = intern ("tty-menu-selected-face"); | 3140 | selectface = intern ("tty-menu-selected-face"); |
| 3141 | faces[2] = lookup_derived_face (sf, selectface, | 3141 | faces[2] = lookup_derived_face (NULL, sf, selectface, |
| 3142 | faces[0], 1); | 3142 | faces[0], 1); |
| 3143 | faces[3] = lookup_derived_face (sf, selectface, | 3143 | faces[3] = lookup_derived_face (NULL, sf, selectface, |
| 3144 | faces[1], 1); | 3144 | faces[1], 1); |
| 3145 | 3145 | ||
| 3146 | /* Make sure the menu title is always displayed with | 3146 | /* Make sure the menu title is always displayed with |
diff --git a/src/window.c b/src/window.c index f654d87e14a..2c6ff01ea43 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -5656,7 +5656,7 @@ scroll_command (Lisp_Object window, Lisp_Object n, int direction) | |||
| 5656 | the moment. But don't screw up if window_scroll gets an error. */ | 5656 | the moment. But don't screw up if window_scroll gets an error. */ |
| 5657 | if (XBUFFER (w->contents) != current_buffer) | 5657 | if (XBUFFER (w->contents) != current_buffer) |
| 5658 | { | 5658 | { |
| 5659 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 5659 | record_unwind_protect_excursion (); |
| 5660 | Fset_buffer (w->contents); | 5660 | Fset_buffer (w->contents); |
| 5661 | } | 5661 | } |
| 5662 | 5662 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index ad1c044557d..a2b6513e571 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2809,7 +2809,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2809 | /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */ | 2809 | /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */ |
| 2810 | if (! NILP (Vface_remapping_alist)) | 2810 | if (! NILP (Vface_remapping_alist)) |
| 2811 | remapped_base_face_id | 2811 | remapped_base_face_id |
| 2812 | = lookup_basic_face (XFRAME (w->frame), base_face_id); | 2812 | = lookup_basic_face (w, XFRAME (w->frame), base_face_id); |
| 2813 | 2813 | ||
| 2814 | /* Use one of the mode line rows of W's desired matrix if | 2814 | /* Use one of the mode line rows of W's desired matrix if |
| 2815 | appropriate. */ | 2815 | appropriate. */ |
| @@ -4060,7 +4060,7 @@ handle_face_prop (struct it *it) | |||
| 4060 | might be a big deal. */ | 4060 | might be a big deal. */ |
| 4061 | base_face_id = it->string_from_prefix_prop_p | 4061 | base_face_id = it->string_from_prefix_prop_p |
| 4062 | ? (!NILP (Vface_remapping_alist) | 4062 | ? (!NILP (Vface_remapping_alist) |
| 4063 | ? lookup_basic_face (it->f, DEFAULT_FACE_ID) | 4063 | ? lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID) |
| 4064 | : DEFAULT_FACE_ID) | 4064 | : DEFAULT_FACE_ID) |
| 4065 | : underlying_face_id (it); | 4065 | : underlying_face_id (it); |
| 4066 | } | 4066 | } |
| @@ -4988,7 +4988,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4988 | struct face *f; | 4988 | struct face *f; |
| 4989 | 4989 | ||
| 4990 | f = FACE_FROM_ID (it->f, | 4990 | f = FACE_FROM_ID (it->f, |
| 4991 | lookup_basic_face (it->f, DEFAULT_FACE_ID)); | 4991 | lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID)); |
| 4992 | new_height = (XFLOATINT (it->font_height) | 4992 | new_height = (XFLOATINT (it->font_height) |
| 4993 | * XINT (f->lface[LFACE_HEIGHT_INDEX])); | 4993 | * XINT (f->lface[LFACE_HEIGHT_INDEX])); |
| 4994 | } | 4994 | } |
| @@ -5175,12 +5175,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 5175 | 5175 | ||
| 5176 | if (it) | 5176 | if (it) |
| 5177 | { | 5177 | { |
| 5178 | int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID); | 5178 | int face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); |
| 5179 | 5179 | ||
| 5180 | if (CONSP (XCDR (XCDR (spec)))) | 5180 | if (CONSP (XCDR (XCDR (spec)))) |
| 5181 | { | 5181 | { |
| 5182 | Lisp_Object face_name = XCAR (XCDR (XCDR (spec))); | 5182 | Lisp_Object face_name = XCAR (XCDR (XCDR (spec))); |
| 5183 | int face_id2 = lookup_derived_face (it->f, face_name, | 5183 | int face_id2 = lookup_derived_face (it->w, it->f, face_name, |
| 5184 | FRINGE_FACE_ID, false); | 5184 | FRINGE_FACE_ID, false); |
| 5185 | if (face_id2 >= 0) | 5185 | if (face_id2 >= 0) |
| 5186 | face_id = face_id2; | 5186 | face_id = face_id2; |
| @@ -6985,7 +6985,7 @@ merge_escape_glyph_face (struct it *it) | |||
| 6985 | else | 6985 | else |
| 6986 | { | 6986 | { |
| 6987 | /* Merge the `escape-glyph' face into the current face. */ | 6987 | /* Merge the `escape-glyph' face into the current face. */ |
| 6988 | face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id); | 6988 | face_id = merge_faces (it->w, Qescape_glyph, 0, it->face_id); |
| 6989 | last_escape_glyph_frame = it->f; | 6989 | last_escape_glyph_frame = it->f; |
| 6990 | last_escape_glyph_face_id = it->face_id; | 6990 | last_escape_glyph_face_id = it->face_id; |
| 6991 | last_escape_glyph_merged_face_id = face_id; | 6991 | last_escape_glyph_merged_face_id = face_id; |
| @@ -7010,7 +7010,7 @@ merge_glyphless_glyph_face (struct it *it) | |||
| 7010 | else | 7010 | else |
| 7011 | { | 7011 | { |
| 7012 | /* Merge the `glyphless-char' face into the current face. */ | 7012 | /* Merge the `glyphless-char' face into the current face. */ |
| 7013 | face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id); | 7013 | face_id = merge_faces (it->w, Qglyphless_char, 0, it->face_id); |
| 7014 | last_glyphless_glyph_frame = it->f; | 7014 | last_glyphless_glyph_frame = it->f; |
| 7015 | last_glyphless_glyph_face_id = it->face_id; | 7015 | last_glyphless_glyph_face_id = it->face_id; |
| 7016 | last_glyphless_glyph_merged_face_id = face_id; | 7016 | last_glyphless_glyph_merged_face_id = face_id; |
| @@ -7184,7 +7184,7 @@ get_next_display_element (struct it *it) | |||
| 7184 | } | 7184 | } |
| 7185 | 7185 | ||
| 7186 | face_id = (lface_id | 7186 | face_id = (lface_id |
| 7187 | ? merge_faces (it->f, Qt, lface_id, it->face_id) | 7187 | ? merge_faces (it->w, Qt, lface_id, it->face_id) |
| 7188 | : merge_escape_glyph_face (it)); | 7188 | : merge_escape_glyph_face (it)); |
| 7189 | 7189 | ||
| 7190 | XSETINT (it->ctl_chars[0], g); | 7190 | XSETINT (it->ctl_chars[0], g); |
| @@ -7199,7 +7199,7 @@ get_next_display_element (struct it *it) | |||
| 7199 | if (nonascii_space_p && EQ (Vnobreak_char_display, Qt)) | 7199 | if (nonascii_space_p && EQ (Vnobreak_char_display, Qt)) |
| 7200 | { | 7200 | { |
| 7201 | /* Merge `nobreak-space' into the current face. */ | 7201 | /* Merge `nobreak-space' into the current face. */ |
| 7202 | face_id = merge_faces (it->f, Qnobreak_space, 0, | 7202 | face_id = merge_faces (it->w, Qnobreak_space, 0, |
| 7203 | it->face_id); | 7203 | it->face_id); |
| 7204 | XSETINT (it->ctl_chars[0], ' '); | 7204 | XSETINT (it->ctl_chars[0], ' '); |
| 7205 | ctl_len = 1; | 7205 | ctl_len = 1; |
| @@ -7212,7 +7212,7 @@ get_next_display_element (struct it *it) | |||
| 7212 | if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt)) | 7212 | if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt)) |
| 7213 | { | 7213 | { |
| 7214 | /* Merge `nobreak-space' into the current face. */ | 7214 | /* Merge `nobreak-space' into the current face. */ |
| 7215 | face_id = merge_faces (it->f, Qnobreak_hyphen, 0, | 7215 | face_id = merge_faces (it->w, Qnobreak_hyphen, 0, |
| 7216 | it->face_id); | 7216 | it->face_id); |
| 7217 | XSETINT (it->ctl_chars[0], '-'); | 7217 | XSETINT (it->ctl_chars[0], '-'); |
| 7218 | ctl_len = 1; | 7218 | ctl_len = 1; |
| @@ -7232,7 +7232,7 @@ get_next_display_element (struct it *it) | |||
| 7232 | } | 7232 | } |
| 7233 | 7233 | ||
| 7234 | face_id = (lface_id | 7234 | face_id = (lface_id |
| 7235 | ? merge_faces (it->f, Qt, lface_id, it->face_id) | 7235 | ? merge_faces (it->w, Qt, lface_id, it->face_id) |
| 7236 | : merge_escape_glyph_face (it)); | 7236 | : merge_escape_glyph_face (it)); |
| 7237 | 7237 | ||
| 7238 | /* Draw non-ASCII space/hyphen with escape glyph: */ | 7238 | /* Draw non-ASCII space/hyphen with escape glyph: */ |
| @@ -7860,7 +7860,7 @@ next_element_from_display_vector (struct it *it) | |||
| 7860 | { | 7860 | { |
| 7861 | int lface_id = GLYPH_CODE_FACE (gc); | 7861 | int lface_id = GLYPH_CODE_FACE (gc); |
| 7862 | if (lface_id > 0) | 7862 | if (lface_id > 0) |
| 7863 | it->face_id = merge_faces (it->f, Qt, lface_id, | 7863 | it->face_id = merge_faces (it->w, Qt, lface_id, |
| 7864 | it->saved_face_id); | 7864 | it->saved_face_id); |
| 7865 | } | 7865 | } |
| 7866 | 7866 | ||
| @@ -7889,7 +7889,7 @@ next_element_from_display_vector (struct it *it) | |||
| 7889 | GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]); | 7889 | GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]); |
| 7890 | 7890 | ||
| 7891 | if (lface_id > 0) | 7891 | if (lface_id > 0) |
| 7892 | next_face_id = merge_faces (it->f, Qt, lface_id, | 7892 | next_face_id = merge_faces (it->w, Qt, lface_id, |
| 7893 | it->saved_face_id); | 7893 | it->saved_face_id); |
| 7894 | } | 7894 | } |
| 7895 | } | 7895 | } |
| @@ -20084,7 +20084,7 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 20084 | /* If the default face was remapped, be sure to use the | 20084 | /* If the default face was remapped, be sure to use the |
| 20085 | remapped face for the appended newline. */ | 20085 | remapped face for the appended newline. */ |
| 20086 | if (default_face_p) | 20086 | if (default_face_p) |
| 20087 | it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID); | 20087 | it->face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); |
| 20088 | else if (it->face_before_selective_p) | 20088 | else if (it->face_before_selective_p) |
| 20089 | it->face_id = it->saved_face_id; | 20089 | it->face_id = it->saved_face_id; |
| 20090 | face = FACE_FROM_ID (it->f, it->face_id); | 20090 | face = FACE_FROM_ID (it->f, it->face_id); |
| @@ -20231,8 +20231,9 @@ extend_face_to_end_of_line (struct it *it) | |||
| 20231 | return; | 20231 | return; |
| 20232 | 20232 | ||
| 20233 | /* The default face, possibly remapped. */ | 20233 | /* The default face, possibly remapped. */ |
| 20234 | default_face = FACE_FROM_ID_OR_NULL (f, | 20234 | default_face = FACE_FROM_ID_OR_NULL ( |
| 20235 | lookup_basic_face (f, DEFAULT_FACE_ID)); | 20235 | f, |
| 20236 | lookup_basic_face (it->w, f, DEFAULT_FACE_ID)); | ||
| 20236 | 20237 | ||
| 20237 | /* Face extension extends the background and box of IT->face_id | 20238 | /* Face extension extends the background and box of IT->face_id |
| 20238 | to the end of the line. If the background equals the background | 20239 | to the end of the line. If the background equals the background |
| @@ -20486,11 +20487,12 @@ trailing_whitespace_p (ptrdiff_t charpos) | |||
| 20486 | } | 20487 | } |
| 20487 | 20488 | ||
| 20488 | 20489 | ||
| 20489 | /* Highlight trailing whitespace, if any, in ROW. */ | 20490 | /* Highlight trailing whitespace, if any, in row at IT. */ |
| 20490 | 20491 | ||
| 20491 | static void | 20492 | static void |
| 20492 | highlight_trailing_whitespace (struct frame *f, struct glyph_row *row) | 20493 | highlight_trailing_whitespace (struct it *it) |
| 20493 | { | 20494 | { |
| 20495 | struct glyph_row *row = it->glyph_row; | ||
| 20494 | int used = row->used[TEXT_AREA]; | 20496 | int used = row->used[TEXT_AREA]; |
| 20495 | 20497 | ||
| 20496 | if (used) | 20498 | if (used) |
| @@ -20535,7 +20537,7 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row) | |||
| 20535 | && glyph->u.ch == ' ')) | 20537 | && glyph->u.ch == ' ')) |
| 20536 | && trailing_whitespace_p (glyph->charpos)) | 20538 | && trailing_whitespace_p (glyph->charpos)) |
| 20537 | { | 20539 | { |
| 20538 | int face_id = lookup_named_face (f, Qtrailing_whitespace, false); | 20540 | int face_id = lookup_named_face (it->w, it->f, Qtrailing_whitespace, false); |
| 20539 | if (face_id < 0) | 20541 | if (face_id < 0) |
| 20540 | return; | 20542 | return; |
| 20541 | 20543 | ||
| @@ -21107,9 +21109,9 @@ maybe_produce_line_number (struct it *it) | |||
| 21107 | char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1]; | 21109 | char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1]; |
| 21108 | bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false; | 21110 | bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false; |
| 21109 | ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */ | 21111 | ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */ |
| 21110 | int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID); | 21112 | int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID); |
| 21111 | int current_lnum_face_id | 21113 | int current_lnum_face_id |
| 21112 | = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID); | 21114 | = merge_faces (it->w, Qline_number_current_line, 0, DEFAULT_FACE_ID); |
| 21113 | /* Compute point's line number if needed. */ | 21115 | /* Compute point's line number if needed. */ |
| 21114 | if ((EQ (Vdisplay_line_numbers, Qrelative) | 21116 | if ((EQ (Vdisplay_line_numbers, Qrelative) |
| 21115 | || EQ (Vdisplay_line_numbers, Qvisual) | 21117 | || EQ (Vdisplay_line_numbers, Qvisual) |
| @@ -21559,7 +21561,8 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21559 | portions of the screen will clear with the default face's | 21561 | portions of the screen will clear with the default face's |
| 21560 | background color. */ | 21562 | background color. */ |
| 21561 | if (row->reversed_p | 21563 | if (row->reversed_p |
| 21562 | || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID) | 21564 | || lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID) |
| 21565 | != DEFAULT_FACE_ID) | ||
| 21563 | extend_face_to_end_of_line (it); | 21566 | extend_face_to_end_of_line (it); |
| 21564 | break; | 21567 | break; |
| 21565 | } | 21568 | } |
| @@ -22192,7 +22195,7 @@ display_line (struct it *it, int cursor_vpos) | |||
| 22192 | 22195 | ||
| 22193 | /* Highlight trailing whitespace. */ | 22196 | /* Highlight trailing whitespace. */ |
| 22194 | if (!NILP (Vshow_trailing_whitespace)) | 22197 | if (!NILP (Vshow_trailing_whitespace)) |
| 22195 | highlight_trailing_whitespace (it->f, it->glyph_row); | 22198 | highlight_trailing_whitespace (it); |
| 22196 | 22199 | ||
| 22197 | /* Compute pixel dimensions of this line. */ | 22200 | /* Compute pixel dimensions of this line. */ |
| 22198 | compute_line_metrics (it); | 22201 | compute_line_metrics (it); |
| @@ -27862,7 +27865,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font, | |||
| 27862 | int face_id; | 27865 | int face_id; |
| 27863 | struct face *face; | 27866 | struct face *face; |
| 27864 | 27867 | ||
| 27865 | face_id = lookup_named_face (it->f, face_name, false); | 27868 | face_id = lookup_named_face (it->w, it->f, face_name, false); |
| 27866 | face = FACE_FROM_ID_OR_NULL (it->f, face_id); | 27869 | face = FACE_FROM_ID_OR_NULL (it->f, face_id); |
| 27867 | if (face == NULL || ((font = face->font) == NULL)) | 27870 | if (face == NULL || ((font = face->font) == NULL)) |
| 27868 | return make_number (-1); | 27871 | return make_number (-1); |
diff --git a/src/xfaces.c b/src/xfaces.c index a9c2f37e9f2..961bef7c9ce 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -350,7 +350,8 @@ static bool realize_default_face (struct frame *); | |||
| 350 | static void realize_named_face (struct frame *, Lisp_Object, int); | 350 | static void realize_named_face (struct frame *, Lisp_Object, int); |
| 351 | static struct face_cache *make_face_cache (struct frame *); | 351 | static struct face_cache *make_face_cache (struct frame *); |
| 352 | static void free_face_cache (struct face_cache *); | 352 | static void free_face_cache (struct face_cache *); |
| 353 | static bool merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *, | 353 | static bool merge_face_ref (struct window *w, |
| 354 | struct frame *, Lisp_Object, Lisp_Object *, | ||
| 354 | bool, struct named_merge_point *); | 355 | bool, struct named_merge_point *); |
| 355 | static int color_distance (XColor *x, XColor *y); | 356 | static int color_distance (XColor *x, XColor *y); |
| 356 | 357 | ||
| @@ -1551,7 +1552,7 @@ the WIDTH times as wide as FACE on FRAME. */) | |||
| 1551 | { | 1552 | { |
| 1552 | /* This is of limited utility since it works with character | 1553 | /* This is of limited utility since it works with character |
| 1553 | widths. Keep it for compatibility. --gerd. */ | 1554 | widths. Keep it for compatibility. --gerd. */ |
| 1554 | int face_id = lookup_named_face (f, face, false); | 1555 | int face_id = lookup_named_face (NULL, f, face, false); |
| 1555 | struct face *width_face = FACE_FROM_ID_OR_NULL (f, face_id); | 1556 | struct face *width_face = FACE_FROM_ID_OR_NULL (f, face_id); |
| 1556 | 1557 | ||
| 1557 | if (width_face && width_face->font) | 1558 | if (width_face && width_face->font) |
| @@ -1907,19 +1908,22 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, | |||
| 1907 | return !NILP (lface); | 1908 | return !NILP (lface); |
| 1908 | } | 1909 | } |
| 1909 | 1910 | ||
| 1910 | /* Get face attributes of face FACE_NAME from frame-local faces on frame | 1911 | /* Get face attributes of face FACE_NAME from frame-local faces on |
| 1911 | F. Store the resulting attributes in ATTRS which must point to a | 1912 | frame F. Store the resulting attributes in ATTRS which must point |
| 1912 | vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an | 1913 | to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. |
| 1913 | alias for another face, use that face's definition. | 1914 | If FACE_NAME is an alias for another face, use that face's |
| 1914 | If SIGNAL_P, signal an error if FACE_NAME does not name a face. | 1915 | definition. If SIGNAL_P, signal an error if FACE_NAME does not |
| 1915 | Otherwise, return true iff FACE_NAME is a face. */ | 1916 | name a face. Otherwise, return true iff FACE_NAME is a face. If W |
| 1916 | 1917 | is non-NULL, also consider remappings attached to the window. | |
| 1918 | */ | ||
| 1917 | static bool | 1919 | static bool |
| 1918 | get_lface_attributes (struct frame *f, Lisp_Object face_name, | 1920 | get_lface_attributes (struct window *w, |
| 1921 | struct frame *f, Lisp_Object face_name, | ||
| 1919 | Lisp_Object attrs[LFACE_VECTOR_SIZE], bool signal_p, | 1922 | Lisp_Object attrs[LFACE_VECTOR_SIZE], bool signal_p, |
| 1920 | struct named_merge_point *named_merge_points) | 1923 | struct named_merge_point *named_merge_points) |
| 1921 | { | 1924 | { |
| 1922 | Lisp_Object face_remapping; | 1925 | Lisp_Object face_remapping; |
| 1926 | eassert (w == NULL || WINDOW_XFRAME (w) == f); | ||
| 1923 | 1927 | ||
| 1924 | face_name = resolve_face_name (face_name, signal_p); | 1928 | face_name = resolve_face_name (face_name, signal_p); |
| 1925 | 1929 | ||
| @@ -1939,7 +1943,7 @@ get_lface_attributes (struct frame *f, Lisp_Object face_name, | |||
| 1939 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) | 1943 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
| 1940 | attrs[i] = Qunspecified; | 1944 | attrs[i] = Qunspecified; |
| 1941 | 1945 | ||
| 1942 | return merge_face_ref (f, XCDR (face_remapping), attrs, | 1946 | return merge_face_ref (w, f, XCDR (face_remapping), attrs, |
| 1943 | signal_p, named_merge_points); | 1947 | signal_p, named_merge_points); |
| 1944 | } | 1948 | } |
| 1945 | } | 1949 | } |
| @@ -2072,15 +2076,16 @@ merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid) | |||
| 2072 | 2076 | ||
| 2073 | /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and | 2077 | /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and |
| 2074 | store the resulting attributes in TO, which must be already be | 2078 | store the resulting attributes in TO, which must be already be |
| 2075 | completely specified and contain only absolute attributes. Every | 2079 | completely specified and contain only absolute attributes. |
| 2076 | specified attribute of FROM overrides the corresponding attribute of | 2080 | Every specified attribute of FROM overrides the corresponding |
| 2077 | TO; relative attributes in FROM are merged with the absolute value in | 2081 | attribute of TO; relative attributes in FROM are merged with the |
| 2078 | TO and replace it. NAMED_MERGE_POINTS is used internally to detect | 2082 | absolute value in TO and replace it. NAMED_MERGE_POINTS is used |
| 2079 | loops in face inheritance/remapping; it should be 0 when called from | 2083 | internally to detect loops in face inheritance/remapping; it should |
| 2080 | other places. */ | 2084 | be 0 when called from other places. If window W is non-NULL, use W |
| 2081 | 2085 | to interpret face specifications. */ | |
| 2082 | static void | 2086 | static void |
| 2083 | merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, | 2087 | merge_face_vectors (struct window *w, |
| 2088 | struct frame *f, Lisp_Object *from, Lisp_Object *to, | ||
| 2084 | struct named_merge_point *named_merge_points) | 2089 | struct named_merge_point *named_merge_points) |
| 2085 | { | 2090 | { |
| 2086 | int i; | 2091 | int i; |
| @@ -2093,7 +2098,8 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, | |||
| 2093 | other code uses `unspecified' as a generic value for face attributes. */ | 2098 | other code uses `unspecified' as a generic value for face attributes. */ |
| 2094 | if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) | 2099 | if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) |
| 2095 | && !NILP (from[LFACE_INHERIT_INDEX])) | 2100 | && !NILP (from[LFACE_INHERIT_INDEX])) |
| 2096 | merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, false, named_merge_points); | 2101 | merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], |
| 2102 | to, false, named_merge_points); | ||
| 2097 | 2103 | ||
| 2098 | if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) | 2104 | if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) |
| 2099 | { | 2105 | { |
| @@ -2153,10 +2159,12 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, | |||
| 2153 | /* Merge the named face FACE_NAME on frame F, into the vector of face | 2159 | /* Merge the named face FACE_NAME on frame F, into the vector of face |
| 2154 | attributes TO. Use NAMED_MERGE_POINTS to detect loops in face | 2160 | attributes TO. Use NAMED_MERGE_POINTS to detect loops in face |
| 2155 | inheritance. Return true if FACE_NAME is a valid face name and | 2161 | inheritance. Return true if FACE_NAME is a valid face name and |
| 2156 | merging succeeded. */ | 2162 | merging succeeded. Window W, if non-NULL, is used to filter face |
| 2163 | specifications. */ | ||
| 2157 | 2164 | ||
| 2158 | static bool | 2165 | static bool |
| 2159 | merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | 2166 | merge_named_face (struct window *w, |
| 2167 | struct frame *f, Lisp_Object face_name, Lisp_Object *to, | ||
| 2160 | struct named_merge_point *named_merge_points) | 2168 | struct named_merge_point *named_merge_points) |
| 2161 | { | 2169 | { |
| 2162 | struct named_merge_point named_merge_point; | 2170 | struct named_merge_point named_merge_point; |
| @@ -2166,11 +2174,11 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | |||
| 2166 | &named_merge_points)) | 2174 | &named_merge_points)) |
| 2167 | { | 2175 | { |
| 2168 | Lisp_Object from[LFACE_VECTOR_SIZE]; | 2176 | Lisp_Object from[LFACE_VECTOR_SIZE]; |
| 2169 | bool ok = get_lface_attributes (f, face_name, from, false, | 2177 | bool ok = get_lface_attributes (w, f, face_name, from, false, |
| 2170 | named_merge_points); | 2178 | named_merge_points); |
| 2171 | 2179 | ||
| 2172 | if (ok) | 2180 | if (ok) |
| 2173 | merge_face_vectors (f, from, to, named_merge_points); | 2181 | merge_face_vectors (w, f, from, to, named_merge_points); |
| 2174 | 2182 | ||
| 2175 | return ok; | 2183 | return ok; |
| 2176 | } | 2184 | } |
| @@ -2178,6 +2186,111 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | |||
| 2178 | return false; | 2186 | return false; |
| 2179 | } | 2187 | } |
| 2180 | 2188 | ||
| 2189 | /* Determine whether the face filter FILTER evaluated in window W | ||
| 2190 | matches. W can be NULL if the window context is unknown. | ||
| 2191 | |||
| 2192 | A face filter is either nil, which always matches, or a list | ||
| 2193 | (:window PARAMETER VALUE), which matches if the current window has | ||
| 2194 | a PARAMETER EQ to VALUE. | ||
| 2195 | |||
| 2196 | If the filter is invalid, set *OK to false and, if ERR_MSGS is | ||
| 2197 | true, log an error message. */ | ||
| 2198 | static bool | ||
| 2199 | evaluate_face_filter (Lisp_Object filter, struct window *w, | ||
| 2200 | bool *ok, bool err_msgs) | ||
| 2201 | { | ||
| 2202 | Lisp_Object orig_filter = filter; | ||
| 2203 | |||
| 2204 | { | ||
| 2205 | if (NILP (filter)) | ||
| 2206 | return true; | ||
| 2207 | |||
| 2208 | if (face_filters_always_match) | ||
| 2209 | return true; | ||
| 2210 | |||
| 2211 | if (!CONSP (filter)) | ||
| 2212 | goto err; | ||
| 2213 | |||
| 2214 | if (!EQ (XCAR (filter), Qwindow_kw)) | ||
| 2215 | goto err; | ||
| 2216 | filter = XCDR (filter); | ||
| 2217 | |||
| 2218 | Lisp_Object parameter = XCAR (filter); | ||
| 2219 | filter = XCDR (filter); | ||
| 2220 | if (!CONSP (filter)) | ||
| 2221 | goto err; | ||
| 2222 | |||
| 2223 | Lisp_Object value = XCAR (filter); | ||
| 2224 | filter = XCDR (filter); | ||
| 2225 | if (!NILP (filter)) | ||
| 2226 | goto err; | ||
| 2227 | |||
| 2228 | bool match = false; | ||
| 2229 | if (w) { | ||
| 2230 | Lisp_Object found = assq_no_quit (parameter, w->window_parameters); | ||
| 2231 | if (!NILP (found) && EQ (XCDR (found), value)) | ||
| 2232 | match = true; | ||
| 2233 | } | ||
| 2234 | |||
| 2235 | return match; | ||
| 2236 | } | ||
| 2237 | |||
| 2238 | err: | ||
| 2239 | if (err_msgs) | ||
| 2240 | add_to_log ("Invalid face filter %S", orig_filter); | ||
| 2241 | *ok = false; | ||
| 2242 | return false; | ||
| 2243 | } | ||
| 2244 | |||
| 2245 | /* Determine whether FACE_REF is a "filter" face specification (case | ||
| 2246 | #4 in merge_face_ref). If it is, evaluate the filter, and if the | ||
| 2247 | filter matches, return the filtered expression. Otherwise, return | ||
| 2248 | the original expression. | ||
| 2249 | |||
| 2250 | On error, set *OK to false, having logged an error message if | ||
| 2251 | ERR_MSGS is true, with return value unspecified. | ||
| 2252 | |||
| 2253 | W is either NULL or a window used to evaluate filters. If W is | ||
| 2254 | null, no window-based face specification filter matches. | ||
| 2255 | */ | ||
| 2256 | static Lisp_Object | ||
| 2257 | filter_face_ref (Lisp_Object face_ref, | ||
| 2258 | struct window *w, | ||
| 2259 | bool *ok, | ||
| 2260 | bool err_msgs) | ||
| 2261 | { | ||
| 2262 | Lisp_Object orig_face_ref = face_ref; | ||
| 2263 | if (!CONSP (face_ref)) | ||
| 2264 | return face_ref; | ||
| 2265 | |||
| 2266 | { | ||
| 2267 | if (!EQ (XCAR (face_ref), Qfiltered_kw)) | ||
| 2268 | return face_ref; | ||
| 2269 | face_ref = XCDR (face_ref); | ||
| 2270 | |||
| 2271 | if (!CONSP (face_ref)) | ||
| 2272 | goto err; | ||
| 2273 | Lisp_Object filter = XCAR (face_ref); | ||
| 2274 | face_ref = XCDR (face_ref); | ||
| 2275 | |||
| 2276 | if (!CONSP (face_ref)) | ||
| 2277 | goto err; | ||
| 2278 | Lisp_Object filtered_face_ref = XCAR (face_ref); | ||
| 2279 | face_ref = XCDR (face_ref); | ||
| 2280 | |||
| 2281 | if (!NILP (face_ref)) | ||
| 2282 | goto err; | ||
| 2283 | |||
| 2284 | return evaluate_face_filter (filter, w, ok, err_msgs) | ||
| 2285 | ? filtered_face_ref : Qnil; | ||
| 2286 | } | ||
| 2287 | |||
| 2288 | err: | ||
| 2289 | if (err_msgs) | ||
| 2290 | add_to_log ("Invalid face ref %S", orig_face_ref); | ||
| 2291 | *ok = false; | ||
| 2292 | return Qnil; | ||
| 2293 | } | ||
| 2181 | 2294 | ||
| 2182 | /* Merge face attributes from the lisp `face reference' FACE_REF on | 2295 | /* Merge face attributes from the lisp `face reference' FACE_REF on |
| 2183 | frame F into the face attribute vector TO. If ERR_MSGS, | 2296 | frame F into the face attribute vector TO. If ERR_MSGS, |
| @@ -2199,21 +2312,44 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | |||
| 2199 | (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is | 2312 | (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is |
| 2200 | for compatibility with 20.2. | 2313 | for compatibility with 20.2. |
| 2201 | 2314 | ||
| 2315 | 4. Conses of the form | ||
| 2316 | (:filter (:window PARAMETER VALUE) FACE-SPECIFICATION), | ||
| 2317 | which applies FACE-SPECIFICATION only if the | ||
| 2318 | given face attributes are being evaluated in the context of a | ||
| 2319 | window with a parameter named PARAMETER being EQ VALUE. | ||
| 2320 | |||
| 2321 | 5. nil, which means to merge nothing. | ||
| 2322 | |||
| 2202 | Face specifications earlier in lists take precedence over later | 2323 | Face specifications earlier in lists take precedence over later |
| 2203 | specifications. */ | 2324 | specifications. */ |
| 2204 | 2325 | ||
| 2205 | static bool | 2326 | static bool |
| 2206 | merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | 2327 | merge_face_ref (struct window *w, |
| 2328 | struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | ||
| 2207 | bool err_msgs, struct named_merge_point *named_merge_points) | 2329 | bool err_msgs, struct named_merge_point *named_merge_points) |
| 2208 | { | 2330 | { |
| 2209 | bool ok = true; /* Succeed without an error? */ | 2331 | bool ok = true; /* Succeed without an error? */ |
| 2332 | Lisp_Object filtered_face_ref; | ||
| 2333 | |||
| 2334 | filtered_face_ref = face_ref; | ||
| 2335 | do | ||
| 2336 | { | ||
| 2337 | face_ref = filtered_face_ref; | ||
| 2338 | filtered_face_ref = filter_face_ref (face_ref, w, &ok, err_msgs); | ||
| 2339 | } while (ok && !EQ (face_ref, filtered_face_ref)); | ||
| 2340 | |||
| 2341 | if (!ok) | ||
| 2342 | return false; | ||
| 2343 | |||
| 2344 | if (NILP (face_ref)) | ||
| 2345 | return true; | ||
| 2210 | 2346 | ||
| 2211 | if (CONSP (face_ref)) | 2347 | if (CONSP (face_ref)) |
| 2212 | { | 2348 | { |
| 2213 | Lisp_Object first = XCAR (face_ref); | 2349 | Lisp_Object first = XCAR (face_ref); |
| 2214 | 2350 | ||
| 2215 | if (EQ (first, Qforeground_color) | 2351 | if (EQ (first, Qforeground_color) |
| 2216 | || EQ (first, Qbackground_color)) | 2352 | || EQ (first, Qbackground_color)) |
| 2217 | { | 2353 | { |
| 2218 | /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR | 2354 | /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR |
| 2219 | . COLOR). COLOR must be a string. */ | 2355 | . COLOR). COLOR must be a string. */ |
| @@ -2400,7 +2536,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | |||
| 2400 | { | 2536 | { |
| 2401 | /* This is not really very useful; it's just like a | 2537 | /* This is not really very useful; it's just like a |
| 2402 | normal face reference. */ | 2538 | normal face reference. */ |
| 2403 | if (! merge_face_ref (f, value, to, | 2539 | if (! merge_face_ref (w, f, value, to, |
| 2404 | err_msgs, named_merge_points)) | 2540 | err_msgs, named_merge_points)) |
| 2405 | err = true; | 2541 | err = true; |
| 2406 | } | 2542 | } |
| @@ -2424,16 +2560,16 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | |||
| 2424 | Lisp_Object next = XCDR (face_ref); | 2560 | Lisp_Object next = XCDR (face_ref); |
| 2425 | 2561 | ||
| 2426 | if (! NILP (next)) | 2562 | if (! NILP (next)) |
| 2427 | ok = merge_face_ref (f, next, to, err_msgs, named_merge_points); | 2563 | ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); |
| 2428 | 2564 | ||
| 2429 | if (! merge_face_ref (f, first, to, err_msgs, named_merge_points)) | 2565 | if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) |
| 2430 | ok = false; | 2566 | ok = false; |
| 2431 | } | 2567 | } |
| 2432 | } | 2568 | } |
| 2433 | else | 2569 | else |
| 2434 | { | 2570 | { |
| 2435 | /* FACE_REF ought to be a face name. */ | 2571 | /* FACE_REF ought to be a face name. */ |
| 2436 | ok = merge_named_face (f, face_ref, to, named_merge_points); | 2572 | ok = merge_named_face (w, f, face_ref, to, named_merge_points); |
| 2437 | if (!ok && err_msgs) | 2573 | if (!ok && err_msgs) |
| 2438 | add_to_log ("Invalid face reference: %s", face_ref); | 2574 | add_to_log ("Invalid face reference: %s", face_ref); |
| 2439 | } | 2575 | } |
| @@ -3701,7 +3837,7 @@ Default face attributes override any local face attributes. */) | |||
| 3701 | /* Ensure that the face vector is fully specified by merging | 3837 | /* Ensure that the face vector is fully specified by merging |
| 3702 | the previously-cached vector. */ | 3838 | the previously-cached vector. */ |
| 3703 | memcpy (attrs, oldface->lface, sizeof attrs); | 3839 | memcpy (attrs, oldface->lface, sizeof attrs); |
| 3704 | merge_face_vectors (f, lvec, attrs, 0); | 3840 | merge_face_vectors (NULL, f, lvec, attrs, 0); |
| 3705 | vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE); | 3841 | vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE); |
| 3706 | newface = realize_face (c, lvec, DEFAULT_FACE_ID); | 3842 | newface = realize_face (c, lvec, DEFAULT_FACE_ID); |
| 3707 | 3843 | ||
| @@ -3774,7 +3910,7 @@ return the font name used for CHARACTER. */) | |||
| 3774 | else | 3910 | else |
| 3775 | { | 3911 | { |
| 3776 | struct frame *f = decode_live_frame (frame); | 3912 | struct frame *f = decode_live_frame (frame); |
| 3777 | int face_id = lookup_named_face (f, face, true); | 3913 | int face_id = lookup_named_face (NULL, f, face, true); |
| 3778 | struct face *fface = FACE_FROM_ID_OR_NULL (f, face_id); | 3914 | struct face *fface = FACE_FROM_ID_OR_NULL (f, face_id); |
| 3779 | 3915 | ||
| 3780 | if (! fface) | 3916 | if (! fface) |
| @@ -4432,10 +4568,12 @@ face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) | |||
| 4432 | /* Return the face id of the realized face for named face SYMBOL on | 4568 | /* Return the face id of the realized face for named face SYMBOL on |
| 4433 | frame F suitable for displaying ASCII characters. Value is -1 if | 4569 | frame F suitable for displaying ASCII characters. Value is -1 if |
| 4434 | the face couldn't be determined, which might happen if the default | 4570 | the face couldn't be determined, which might happen if the default |
| 4435 | face isn't realized and cannot be realized. */ | 4571 | face isn't realized and cannot be realized. If window W is given, |
| 4436 | 4572 | consider face remappings specified for W or for W's buffer. If W is | |
| 4573 | NULL, consider only frame-level face configuration. */ | ||
| 4437 | int | 4574 | int |
| 4438 | lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) | 4575 | lookup_named_face (struct window *w, struct frame *f, |
| 4576 | Lisp_Object symbol, bool signal_p) | ||
| 4439 | { | 4577 | { |
| 4440 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 4578 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 4441 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; | 4579 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; |
| @@ -4448,11 +4586,11 @@ lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) | |||
| 4448 | default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | 4586 | default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); |
| 4449 | } | 4587 | } |
| 4450 | 4588 | ||
| 4451 | if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0)) | 4589 | if (! get_lface_attributes (w, f, symbol, symbol_attrs, signal_p, 0)) |
| 4452 | return -1; | 4590 | return -1; |
| 4453 | 4591 | ||
| 4454 | memcpy (attrs, default_face->lface, sizeof attrs); | 4592 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 4455 | merge_face_vectors (f, symbol_attrs, attrs, 0); | 4593 | merge_face_vectors (w, f, symbol_attrs, attrs, 0); |
| 4456 | 4594 | ||
| 4457 | return lookup_face (f, attrs); | 4595 | return lookup_face (f, attrs); |
| 4458 | } | 4596 | } |
| @@ -4462,10 +4600,10 @@ lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) | |||
| 4462 | is FACE_ID. The return value will usually simply be FACE_ID, unless that | 4600 | is FACE_ID. The return value will usually simply be FACE_ID, unless that |
| 4463 | basic face has bee remapped via Vface_remapping_alist. This function is | 4601 | basic face has bee remapped via Vface_remapping_alist. This function is |
| 4464 | conservative: if something goes wrong, it will simply return FACE_ID | 4602 | conservative: if something goes wrong, it will simply return FACE_ID |
| 4465 | rather than signal an error. */ | 4603 | rather than signal an error. Window W, if non-NULL, is used to filter |
| 4466 | 4604 | face specifications for remapping. */ | |
| 4467 | int | 4605 | int |
| 4468 | lookup_basic_face (struct frame *f, int face_id) | 4606 | lookup_basic_face (struct window *w, struct frame *f, int face_id) |
| 4469 | { | 4607 | { |
| 4470 | Lisp_Object name, mapping; | 4608 | Lisp_Object name, mapping; |
| 4471 | int remapped_face_id; | 4609 | int remapped_face_id; |
| @@ -4505,7 +4643,7 @@ lookup_basic_face (struct frame *f, int face_id) | |||
| 4505 | 4643 | ||
| 4506 | /* If there is a remapping entry, lookup the face using NAME, which will | 4644 | /* If there is a remapping entry, lookup the face using NAME, which will |
| 4507 | handle the remapping too. */ | 4645 | handle the remapping too. */ |
| 4508 | remapped_face_id = lookup_named_face (f, name, false); | 4646 | remapped_face_id = lookup_named_face (w, f, name, false); |
| 4509 | if (remapped_face_id < 0) | 4647 | if (remapped_face_id < 0) |
| 4510 | return face_id; /* Give up. */ | 4648 | return face_id; /* Give up. */ |
| 4511 | 4649 | ||
| @@ -4603,22 +4741,23 @@ face_with_height (struct frame *f, int face_id, int height) | |||
| 4603 | attributes of the face FACE_ID for attributes that aren't | 4741 | attributes of the face FACE_ID for attributes that aren't |
| 4604 | completely specified by SYMBOL. This is like lookup_named_face, | 4742 | completely specified by SYMBOL. This is like lookup_named_face, |
| 4605 | except that the default attributes come from FACE_ID, not from the | 4743 | except that the default attributes come from FACE_ID, not from the |
| 4606 | default face. FACE_ID is assumed to be already realized. */ | 4744 | default face. FACE_ID is assumed to be already realized. |
| 4607 | 4745 | Window W, if non-NULL, filters face specifications. */ | |
| 4608 | int | 4746 | int |
| 4609 | lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id, | 4747 | lookup_derived_face (struct window *w, |
| 4748 | struct frame *f, Lisp_Object symbol, int face_id, | ||
| 4610 | bool signal_p) | 4749 | bool signal_p) |
| 4611 | { | 4750 | { |
| 4612 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 4751 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 4613 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; | 4752 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; |
| 4614 | struct face *default_face; | 4753 | struct face *default_face; |
| 4615 | 4754 | ||
| 4616 | if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0)) | 4755 | if (!get_lface_attributes (w, f, symbol, symbol_attrs, signal_p, 0)) |
| 4617 | return -1; | 4756 | return -1; |
| 4618 | 4757 | ||
| 4619 | default_face = FACE_FROM_ID (f, face_id); | 4758 | default_face = FACE_FROM_ID (f, face_id); |
| 4620 | memcpy (attrs, default_face->lface, sizeof attrs); | 4759 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 4621 | merge_face_vectors (f, symbol_attrs, attrs, 0); | 4760 | merge_face_vectors (w, f, symbol_attrs, attrs, 0); |
| 4622 | return lookup_face (f, attrs); | 4761 | return lookup_face (f, attrs); |
| 4623 | } | 4762 | } |
| 4624 | 4763 | ||
| @@ -4630,7 +4769,8 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector, | |||
| 4630 | Lisp_Object lface; | 4769 | Lisp_Object lface; |
| 4631 | lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE), | 4770 | lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE), |
| 4632 | Qunspecified); | 4771 | Qunspecified); |
| 4633 | merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents, | 4772 | merge_face_ref (NULL, XFRAME (selected_frame), |
| 4773 | plist, XVECTOR (lface)->contents, | ||
| 4634 | true, 0); | 4774 | true, 0); |
| 4635 | return lface; | 4775 | return lface; |
| 4636 | } | 4776 | } |
| @@ -4714,7 +4854,7 @@ x_supports_face_attributes_p (struct frame *f, | |||
| 4714 | 4854 | ||
| 4715 | memcpy (merged_attrs, def_attrs, sizeof merged_attrs); | 4855 | memcpy (merged_attrs, def_attrs, sizeof merged_attrs); |
| 4716 | 4856 | ||
| 4717 | merge_face_vectors (f, attrs, merged_attrs, 0); | 4857 | merge_face_vectors (NULL, f, attrs, merged_attrs, 0); |
| 4718 | 4858 | ||
| 4719 | face_id = lookup_face (f, merged_attrs); | 4859 | face_id = lookup_face (f, merged_attrs); |
| 4720 | face = FACE_FROM_ID_OR_NULL (f, face_id); | 4860 | face = FACE_FROM_ID_OR_NULL (f, face_id); |
| @@ -4985,7 +5125,7 @@ face for italic. */) | |||
| 4985 | 5125 | ||
| 4986 | for (i = 0; i < LFACE_VECTOR_SIZE; i++) | 5126 | for (i = 0; i < LFACE_VECTOR_SIZE; i++) |
| 4987 | attrs[i] = Qunspecified; | 5127 | attrs[i] = Qunspecified; |
| 4988 | merge_face_ref (f, attributes, attrs, true, 0); | 5128 | merge_face_ref (NULL, f, attributes, attrs, true, 0); |
| 4989 | 5129 | ||
| 4990 | def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); | 5130 | def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); |
| 4991 | if (def_face == NULL) | 5131 | if (def_face == NULL) |
| @@ -5354,7 +5494,7 @@ realize_named_face (struct frame *f, Lisp_Object symbol, int id) | |||
| 5354 | 5494 | ||
| 5355 | /* Merge SYMBOL's face with the default face. */ | 5495 | /* Merge SYMBOL's face with the default face. */ |
| 5356 | get_lface_attributes_no_remap (f, symbol, symbol_attrs, true); | 5496 | get_lface_attributes_no_remap (f, symbol, symbol_attrs, true); |
| 5357 | merge_face_vectors (f, symbol_attrs, attrs, 0); | 5497 | merge_face_vectors (NULL, f, symbol_attrs, attrs, 0); |
| 5358 | 5498 | ||
| 5359 | /* Realize the face. */ | 5499 | /* Realize the face. */ |
| 5360 | realize_face (c, attrs, id); | 5500 | realize_face (c, attrs, id); |
| @@ -5869,7 +6009,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) | |||
| 5869 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6009 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 5870 | struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | 6010 | struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); |
| 5871 | memcpy (attrs, default_face->lface, sizeof attrs); | 6011 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 5872 | merge_face_ref (f, prop, attrs, true, 0); | 6012 | merge_face_ref (NULL, f, prop, attrs, true, 0); |
| 5873 | face_id = lookup_face (f, attrs); | 6013 | face_id = lookup_face (f, attrs); |
| 5874 | } | 6014 | } |
| 5875 | 6015 | ||
| @@ -5948,7 +6088,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5948 | else if (NILP (Vface_remapping_alist)) | 6088 | else if (NILP (Vface_remapping_alist)) |
| 5949 | face_id = DEFAULT_FACE_ID; | 6089 | face_id = DEFAULT_FACE_ID; |
| 5950 | else | 6090 | else |
| 5951 | face_id = lookup_basic_face (f, DEFAULT_FACE_ID); | 6091 | face_id = lookup_basic_face (w, f, DEFAULT_FACE_ID); |
| 5952 | 6092 | ||
| 5953 | default_face = FACE_FROM_ID (f, face_id); | 6093 | default_face = FACE_FROM_ID (f, face_id); |
| 5954 | } | 6094 | } |
| @@ -5966,7 +6106,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5966 | 6106 | ||
| 5967 | /* Merge in attributes specified via text properties. */ | 6107 | /* Merge in attributes specified via text properties. */ |
| 5968 | if (!NILP (prop)) | 6108 | if (!NILP (prop)) |
| 5969 | merge_face_ref (f, prop, attrs, true, 0); | 6109 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 5970 | 6110 | ||
| 5971 | /* Now merge the overlay data. */ | 6111 | /* Now merge the overlay data. */ |
| 5972 | noverlays = sort_overlays (overlay_vec, noverlays, w); | 6112 | noverlays = sort_overlays (overlay_vec, noverlays, w); |
| @@ -5986,7 +6126,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5986 | so discard the mouse-face text property, if any, and | 6126 | so discard the mouse-face text property, if any, and |
| 5987 | use the overlay property instead. */ | 6127 | use the overlay property instead. */ |
| 5988 | memcpy (attrs, default_face->lface, sizeof attrs); | 6128 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 5989 | merge_face_ref (f, prop, attrs, true, 0); | 6129 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 5990 | } | 6130 | } |
| 5991 | 6131 | ||
| 5992 | oend = OVERLAY_END (overlay_vec[i]); | 6132 | oend = OVERLAY_END (overlay_vec[i]); |
| @@ -6004,7 +6144,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 6004 | 6144 | ||
| 6005 | prop = Foverlay_get (overlay_vec[i], propname); | 6145 | prop = Foverlay_get (overlay_vec[i], propname); |
| 6006 | if (!NILP (prop)) | 6146 | if (!NILP (prop)) |
| 6007 | merge_face_ref (f, prop, attrs, true, 0); | 6147 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 6008 | 6148 | ||
| 6009 | oend = OVERLAY_END (overlay_vec[i]); | 6149 | oend = OVERLAY_END (overlay_vec[i]); |
| 6010 | oendpos = OVERLAY_POSITION (oend); | 6150 | oendpos = OVERLAY_POSITION (oend); |
| @@ -6065,12 +6205,12 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, | |||
| 6065 | return DEFAULT_FACE_ID; | 6205 | return DEFAULT_FACE_ID; |
| 6066 | 6206 | ||
| 6067 | /* Begin with attributes from the default face. */ | 6207 | /* Begin with attributes from the default face. */ |
| 6068 | default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID)); | 6208 | default_face = FACE_FROM_ID (f, lookup_basic_face (w, f, DEFAULT_FACE_ID)); |
| 6069 | memcpy (attrs, default_face->lface, sizeof attrs); | 6209 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 6070 | 6210 | ||
| 6071 | /* Merge in attributes specified via text properties. */ | 6211 | /* Merge in attributes specified via text properties. */ |
| 6072 | if (!NILP (prop)) | 6212 | if (!NILP (prop)) |
| 6073 | merge_face_ref (f, prop, attrs, true, 0); | 6213 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 6074 | 6214 | ||
| 6075 | *endptr = endpos; | 6215 | *endptr = endpos; |
| 6076 | 6216 | ||
| @@ -6149,7 +6289,7 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6149 | 6289 | ||
| 6150 | /* Merge in attributes specified via text properties. */ | 6290 | /* Merge in attributes specified via text properties. */ |
| 6151 | if (!NILP (prop)) | 6291 | if (!NILP (prop)) |
| 6152 | merge_face_ref (f, prop, attrs, true, 0); | 6292 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 6153 | 6293 | ||
| 6154 | /* Look up a realized face with the given face attributes, | 6294 | /* Look up a realized face with the given face attributes, |
| 6155 | or realize a new one for ASCII characters. */ | 6295 | or realize a new one for ASCII characters. */ |
| @@ -6159,7 +6299,7 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6159 | 6299 | ||
| 6160 | /* Merge a face into a realized face. | 6300 | /* Merge a face into a realized face. |
| 6161 | 6301 | ||
| 6162 | F is frame where faces are (to be) realized. | 6302 | W is a window in the frame where faces are (to be) realized. |
| 6163 | 6303 | ||
| 6164 | FACE_NAME is named face to merge. | 6304 | FACE_NAME is named face to merge. |
| 6165 | 6305 | ||
| @@ -6173,9 +6313,10 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6173 | */ | 6313 | */ |
| 6174 | 6314 | ||
| 6175 | int | 6315 | int |
| 6176 | merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | 6316 | merge_faces (struct window *w, Lisp_Object face_name, int face_id, |
| 6177 | int base_face_id) | 6317 | int base_face_id) |
| 6178 | { | 6318 | { |
| 6319 | struct frame *f = WINDOW_XFRAME (w); | ||
| 6179 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6320 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 6180 | struct face *base_face; | 6321 | struct face *base_face; |
| 6181 | 6322 | ||
| @@ -6190,7 +6331,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | |||
| 6190 | face_name = lface_id_to_name[face_id]; | 6331 | face_name = lface_id_to_name[face_id]; |
| 6191 | /* When called during make-frame, lookup_derived_face may fail | 6332 | /* When called during make-frame, lookup_derived_face may fail |
| 6192 | if the faces are uninitialized. Don't signal an error. */ | 6333 | if the faces are uninitialized. Don't signal an error. */ |
| 6193 | face_id = lookup_derived_face (f, face_name, base_face_id, 0); | 6334 | face_id = lookup_derived_face (w, f, face_name, base_face_id, 0); |
| 6194 | return (face_id >= 0 ? face_id : base_face_id); | 6335 | return (face_id >= 0 ? face_id : base_face_id); |
| 6195 | } | 6336 | } |
| 6196 | 6337 | ||
| @@ -6199,7 +6340,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | |||
| 6199 | 6340 | ||
| 6200 | if (!NILP (face_name)) | 6341 | if (!NILP (face_name)) |
| 6201 | { | 6342 | { |
| 6202 | if (!merge_named_face (f, face_name, attrs, 0)) | 6343 | if (!merge_named_face (w, f, face_name, attrs, 0)) |
| 6203 | return base_face_id; | 6344 | return base_face_id; |
| 6204 | } | 6345 | } |
| 6205 | else | 6346 | else |
| @@ -6210,7 +6351,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | |||
| 6210 | face = FACE_FROM_ID_OR_NULL (f, face_id); | 6351 | face = FACE_FROM_ID_OR_NULL (f, face_id); |
| 6211 | if (!face) | 6352 | if (!face) |
| 6212 | return base_face_id; | 6353 | return base_face_id; |
| 6213 | merge_face_vectors (f, face->lface, attrs, 0); | 6354 | merge_face_vectors (w, f, face->lface, attrs, 0); |
| 6214 | } | 6355 | } |
| 6215 | 6356 | ||
| 6216 | /* Look up a realized face with the given face attributes, | 6357 | /* Look up a realized face with the given face attributes, |
| @@ -6421,6 +6562,11 @@ syms_of_xfaces (void) | |||
| 6421 | DEFSYM (Qunspecified, "unspecified"); | 6562 | DEFSYM (Qunspecified, "unspecified"); |
| 6422 | DEFSYM (QCignore_defface, ":ignore-defface"); | 6563 | DEFSYM (QCignore_defface, ":ignore-defface"); |
| 6423 | 6564 | ||
| 6565 | /* Used for limiting character attributes to windows with specific | ||
| 6566 | characteristics. */ | ||
| 6567 | DEFSYM (Qwindow_kw, ":window"); | ||
| 6568 | DEFSYM (Qfiltered_kw, ":filtered"); | ||
| 6569 | |||
| 6424 | /* The symbol `face-alias'. A symbol having that property is an | 6570 | /* The symbol `face-alias'. A symbol having that property is an |
| 6425 | alias for another face. Value of the property is the name of | 6571 | alias for another face. Value of the property is the name of |
| 6426 | the aliased face. */ | 6572 | the aliased face. */ |
| @@ -6496,6 +6642,10 @@ syms_of_xfaces (void) | |||
| 6496 | defsubr (&Sdump_colors); | 6642 | defsubr (&Sdump_colors); |
| 6497 | #endif | 6643 | #endif |
| 6498 | 6644 | ||
| 6645 | DEFVAR_BOOL ("face-filters-always-match", face_filters_always_match, | ||
| 6646 | doc: /* Non-nil means that face filters are always deemed to | ||
| 6647 | match. Use only when evaluating face attributes. */); | ||
| 6648 | |||
| 6499 | DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults, | 6649 | DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults, |
| 6500 | doc: /* List of global face definitions (for internal use only.) */); | 6650 | doc: /* List of global face definitions (for internal use only.) */); |
| 6501 | Vface_new_frame_defaults = Qnil; | 6651 | Vface_new_frame_defaults = Qnil; |
| @@ -6544,7 +6694,7 @@ REPLACEMENT is a face specification, i.e. one of the following: | |||
| 6544 | 6694 | ||
| 6545 | (1) a face name | 6695 | (1) a face name |
| 6546 | (2) a property list of attribute/value pairs, or | 6696 | (2) a property list of attribute/value pairs, or |
| 6547 | (3) a list in which each element has the form of (1) or (2). | 6697 | (3) a list in which each element has one of the above forms. |
| 6548 | 6698 | ||
| 6549 | List values for REPLACEMENT are merged to form the final face | 6699 | List values for REPLACEMENT are merged to form the final face |
| 6550 | specification, with earlier entries taking precedence, in the same way | 6700 | specification, with earlier entries taking precedence, in the same way |
| @@ -6564,13 +6714,32 @@ causes EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the | |||
| 6564 | existing definition of FACE. Note that this isn't necessary for the | 6714 | existing definition of FACE. Note that this isn't necessary for the |
| 6565 | default face, since every face inherits from the default face. | 6715 | default face, since every face inherits from the default face. |
| 6566 | 6716 | ||
| 6567 | If this variable is made buffer-local, the face remapping takes effect | 6717 | An entry in the list can also be a filtered face expression of the |
| 6568 | only in that buffer. For instance, the mode my-mode could define a | 6718 | form: |
| 6569 | face `my-mode-default', and then in the mode setup function, do: | 6719 | |
| 6720 | (:filtered FILTER FACE-SPECIFICATION) | ||
| 6721 | |||
| 6722 | This construct applies FACE-SPECIFICATION (which can have any of the | ||
| 6723 | forms allowed for face specifications generally) only if FILTER | ||
| 6724 | matches at the moment Emacs wants to draw text with the combined face. | ||
| 6725 | |||
| 6726 | The only filters currently defined are NIL (which always matches) and | ||
| 6727 | (:window PARAMETER VALUE), which matches only in the context of a | ||
| 6728 | window with a parameter EQ-equal to VALUE. | ||
| 6729 | |||
| 6730 | An entry in the face list can also be nil, which does nothing. | ||
| 6731 | |||
| 6732 | If `face-remapping-alist' is made buffer-local, the face remapping | ||
| 6733 | takes effect only in that buffer. For instance, the mode my-mode | ||
| 6734 | could define a face `my-mode-default', and then in the mode setup | ||
| 6735 | function, do: | ||
| 6570 | 6736 | ||
| 6571 | (set (make-local-variable \\='face-remapping-alist) | 6737 | (set (make-local-variable \\='face-remapping-alist) |
| 6572 | \\='((default my-mode-default)))). | 6738 | \\='((default my-mode-default)))). |
| 6573 | 6739 | ||
| 6740 | You probably want to use the face-remap package included in Emacs | ||
| 6741 | instead of manipulating face-remapping-alist directly. | ||
| 6742 | |||
| 6574 | Because Emacs normally only redraws screen areas when the underlying | 6743 | Because Emacs normally only redraws screen areas when the underlying |
| 6575 | buffer contents change, you may need to call `redraw-display' after | 6744 | buffer contents change, you may need to call `redraw-display' after |
| 6576 | changing this variable for it to take effect. */); | 6745 | changing this variable for it to take effect. */); |
diff --git a/src/xwidget.c b/src/xwidget.c index 32022abf341..5f2651214e3 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -749,8 +749,10 @@ argument procedure FUN.*/) | |||
| 749 | /* JavaScript execution happens asynchronously. If an elisp | 749 | /* JavaScript execution happens asynchronously. If an elisp |
| 750 | callback function is provided we pass it to the C callback | 750 | callback function is provided we pass it to the C callback |
| 751 | procedure that retrieves the return value. */ | 751 | procedure that retrieves the return value. */ |
| 752 | gchar *script_string | ||
| 753 | = XSAVE_POINTER (XCAR (AREF (xw->script_callbacks, idx)), 0); | ||
| 752 | webkit_web_view_run_javascript (WEBKIT_WEB_VIEW (xw->widget_osr), | 754 | webkit_web_view_run_javascript (WEBKIT_WEB_VIEW (xw->widget_osr), |
| 753 | XSAVE_POINTER (XCAR (AREF (xw->script_callbacks, idx)), 0), | 755 | script_string, |
| 754 | NULL, /* cancelable */ | 756 | NULL, /* cancelable */ |
| 755 | webkit_javascript_finished_cb, | 757 | webkit_javascript_finished_cb, |
| 756 | (gpointer) idx); | 758 | (gpointer) idx); |
| @@ -1221,15 +1223,13 @@ kill_buffer_xwidgets (Lisp_Object buffer) | |||
| 1221 | gtk_widget_destroy (xw->widgetwindow_osr); | 1223 | gtk_widget_destroy (xw->widgetwindow_osr); |
| 1222 | } | 1224 | } |
| 1223 | if (!NILP (xw->script_callbacks)) | 1225 | if (!NILP (xw->script_callbacks)) |
| 1224 | { | 1226 | for (ptrdiff_t idx = 0; idx < ASIZE (xw->script_callbacks); idx++) |
| 1225 | ptrdiff_t idx; | 1227 | { |
| 1226 | for (idx = 0; idx < ASIZE (xw->script_callbacks); idx++) | 1228 | Lisp_Object cb = AREF (xw->script_callbacks, idx); |
| 1227 | { | 1229 | if (!NILP (cb)) |
| 1228 | if (!NILP (AREF (xw->script_callbacks, idx))) | 1230 | xfree (XSAVE_POINTER (XCAR (cb), 0)); |
| 1229 | xfree (XSAVE_POINTER (XCAR (AREF (xw->script_callbacks, idx)), 0)); | 1231 | ASET (xw->script_callbacks, idx, Qnil); |
| 1230 | ASET (xw->script_callbacks, idx, Qnil); | 1232 | } |
| 1231 | } | ||
| 1232 | } | ||
| 1233 | } | 1233 | } |
| 1234 | } | 1234 | } |
| 1235 | } | 1235 | } |