diff options
| author | Yuuki Harano | 2021-07-25 23:34:55 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2021-07-25 23:34:55 +0900 |
| commit | 13a9a5e836cbe6e64aadaba40fe1f7eb83320d08 (patch) | |
| tree | 242ac1f485cf6762680a904952747d63b295e198 /src | |
| parent | b242394f24b154f8e20f5abf4b2f826629e99ea6 (diff) | |
| parent | 41a55a330f518254da795719ac6e3085254d4110 (diff) | |
| download | emacs-13a9a5e836cbe6e64aadaba40fe1f7eb83320d08.tar.gz emacs-13a9a5e836cbe6e64aadaba40fe1f7eb83320d08.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 32 | ||||
| -rw-r--r-- | src/callint.c | 5 | ||||
| -rw-r--r-- | src/chartab.c | 104 | ||||
| -rw-r--r-- | src/coding.c | 2 | ||||
| -rw-r--r-- | src/data.c | 2 | ||||
| -rw-r--r-- | src/eval.c | 14 | ||||
| -rw-r--r-- | src/fileio.c | 109 | ||||
| -rw-r--r-- | src/filelock.c | 2 | ||||
| -rw-r--r-- | src/fns.c | 12 | ||||
| -rw-r--r-- | src/frame.c | 20 | ||||
| -rw-r--r-- | src/frame.h | 8 | ||||
| -rw-r--r-- | src/ftfont.c | 21 | ||||
| -rw-r--r-- | src/json.c | 25 | ||||
| -rw-r--r-- | src/keyboard.c | 82 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/macros.c | 2 | ||||
| -rw-r--r-- | src/minibuf.c | 2 | ||||
| -rw-r--r-- | src/xdisp.c | 86 | ||||
| -rw-r--r-- | src/xfaces.c | 83 | ||||
| -rw-r--r-- | src/xftfont.c | 6 |
20 files changed, 404 insertions, 217 deletions
diff --git a/src/buffer.c b/src/buffer.c index 02ca23eb2dd..b177c5eaa7f 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -781,15 +781,22 @@ fetch_buffer_markers (struct buffer *b) | |||
| 781 | 781 | ||
| 782 | 782 | ||
| 783 | DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer, | 783 | DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer, |
| 784 | 2, 3, | 784 | 2, 4, |
| 785 | "bMake indirect buffer (to buffer): \nBName of indirect buffer: ", | 785 | "bMake indirect buffer (to buffer): \nBName of indirect buffer: ", |
| 786 | doc: /* Create and return an indirect buffer for buffer BASE-BUFFER, named NAME. | 786 | doc: /* Create and return an indirect buffer for buffer BASE-BUFFER, named NAME. |
| 787 | BASE-BUFFER should be a live buffer, or the name of an existing buffer. | 787 | BASE-BUFFER should be a live buffer, or the name of an existing buffer. |
| 788 | |||
| 788 | NAME should be a string which is not the name of an existing buffer. | 789 | NAME should be a string which is not the name of an existing buffer. |
| 789 | Optional argument CLONE non-nil means preserve BASE-BUFFER's state, | 790 | Optional argument CLONE non-nil means preserve BASE-BUFFER's state, |
| 790 | such as major and minor modes, in the indirect buffer. | 791 | such as major and minor modes, in the indirect buffer. |
| 791 | CLONE nil means the indirect buffer's state is reset to default values. */) | 792 | |
| 792 | (Lisp_Object base_buffer, Lisp_Object name, Lisp_Object clone) | 793 | CLONE nil means the indirect buffer's state is reset to default values. |
| 794 | |||
| 795 | If optional argument INHIBIT-BUFFER-HOOKS is non-nil, the new buffer | ||
| 796 | does not run the hooks `kill-buffer-hook', | ||
| 797 | `kill-buffer-query-functions', and `buffer-list-update-hook'. */) | ||
| 798 | (Lisp_Object base_buffer, Lisp_Object name, Lisp_Object clone, | ||
| 799 | Lisp_Object inhibit_buffer_hooks) | ||
| 793 | { | 800 | { |
| 794 | Lisp_Object buf, tem; | 801 | Lisp_Object buf, tem; |
| 795 | struct buffer *b; | 802 | struct buffer *b; |
| @@ -834,6 +841,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 834 | b->pt_byte = b->base_buffer->pt_byte; | 841 | b->pt_byte = b->base_buffer->pt_byte; |
| 835 | b->begv_byte = b->base_buffer->begv_byte; | 842 | b->begv_byte = b->base_buffer->begv_byte; |
| 836 | b->zv_byte = b->base_buffer->zv_byte; | 843 | b->zv_byte = b->base_buffer->zv_byte; |
| 844 | b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks); | ||
| 837 | 845 | ||
| 838 | b->newline_cache = 0; | 846 | b->newline_cache = 0; |
| 839 | b->width_run_cache = 0; | 847 | b->width_run_cache = 0; |
| @@ -1076,12 +1084,12 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) | |||
| 1076 | for (newlist = Qnil; CONSP (list); list = XCDR (list)) | 1084 | for (newlist = Qnil; CONSP (list); list = XCDR (list)) |
| 1077 | { | 1085 | { |
| 1078 | Lisp_Object elt = XCAR (list); | 1086 | Lisp_Object elt = XCAR (list); |
| 1079 | /* Preserve element ELT if it's t, | 1087 | /* Preserve element ELT if it's t, or if it is a |
| 1080 | if it is a function with a `permanent-local-hook' property, | 1088 | function with a `permanent-local-hook' |
| 1081 | or if it's not a symbol. */ | 1089 | property. */ |
| 1082 | if (! SYMBOLP (elt) | 1090 | if (EQ (elt, Qt) |
| 1083 | || EQ (elt, Qt) | 1091 | || (SYMBOLP (elt) |
| 1084 | || !NILP (Fget (elt, Qpermanent_local_hook))) | 1092 | && !NILP (Fget (elt, Qpermanent_local_hook)))) |
| 1085 | newlist = Fcons (elt, newlist); | 1093 | newlist = Fcons (elt, newlist); |
| 1086 | } | 1094 | } |
| 1087 | newlist = Fnreverse (newlist); | 1095 | newlist = Fnreverse (newlist); |
| @@ -4214,7 +4222,11 @@ OVERLAY. */) | |||
| 4214 | 4222 | ||
| 4215 | DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 2, 0, | 4223 | DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 2, 0, |
| 4216 | doc: /* Return a list of the overlays that contain the character at POS. | 4224 | doc: /* Return a list of the overlays that contain the character at POS. |
| 4217 | If SORTED is non-nil, then sort them by decreasing priority. */) | 4225 | If SORTED is non-nil, then sort them by decreasing priority. |
| 4226 | |||
| 4227 | Zero-length overlays that start and stop at POS are not included in | ||
| 4228 | the return value. Instead use `overlays-in' if those overlays are of | ||
| 4229 | interest. */) | ||
| 4218 | (Lisp_Object pos, Lisp_Object sorted) | 4230 | (Lisp_Object pos, Lisp_Object sorted) |
| 4219 | { | 4231 | { |
| 4220 | ptrdiff_t len, noverlays; | 4232 | ptrdiff_t len, noverlays; |
diff --git a/src/callint.c b/src/callint.c index 18624637843..6f8a7f13f61 100644 --- a/src/callint.c +++ b/src/callint.c | |||
| @@ -892,7 +892,10 @@ behave as if the mark were still active. */); | |||
| 892 | Vmark_even_if_inactive = Qt; | 892 | Vmark_even_if_inactive = Qt; |
| 893 | 893 | ||
| 894 | DEFVAR_LISP ("mouse-leave-buffer-hook", Vmouse_leave_buffer_hook, | 894 | DEFVAR_LISP ("mouse-leave-buffer-hook", Vmouse_leave_buffer_hook, |
| 895 | doc: /* Hook to run when about to switch windows with a mouse command. | 895 | doc: /* Hook run when the user mouse-clicks in a window. |
| 896 | It can be run both before and after switching windows, or even when | ||
| 897 | not actually switching windows. | ||
| 898 | |||
| 896 | Its purpose is to give temporary modes such as Isearch mode | 899 | Its purpose is to give temporary modes such as Isearch mode |
| 897 | a way to turn themselves off when a mouse command switches windows. */); | 900 | a way to turn themselves off when a mouse command switches windows. */); |
| 898 | Vmouse_leave_buffer_hook = Qnil; | 901 | Vmouse_leave_buffer_hook = Qnil; |
diff --git a/src/chartab.c b/src/chartab.c index 331e8595ebe..6f0bc28f31b 100644 --- a/src/chartab.c +++ b/src/chartab.c | |||
| @@ -62,6 +62,9 @@ typedef Lisp_Object (*uniprop_encoder_t) (Lisp_Object, Lisp_Object); | |||
| 62 | 62 | ||
| 63 | static Lisp_Object uniprop_table_uncompress (Lisp_Object, int); | 63 | static Lisp_Object uniprop_table_uncompress (Lisp_Object, int); |
| 64 | static uniprop_decoder_t uniprop_get_decoder (Lisp_Object); | 64 | static uniprop_decoder_t uniprop_get_decoder (Lisp_Object); |
| 65 | static Lisp_Object | ||
| 66 | sub_char_table_ref_and_range (Lisp_Object, int, int *, int *, | ||
| 67 | Lisp_Object, bool); | ||
| 65 | 68 | ||
| 66 | /* 1 iff TABLE is a uniprop table. */ | 69 | /* 1 iff TABLE is a uniprop table. */ |
| 67 | #define UNIPROP_TABLE_P(TABLE) \ | 70 | #define UNIPROP_TABLE_P(TABLE) \ |
| @@ -247,6 +250,23 @@ char_table_ref (Lisp_Object table, int c) | |||
| 247 | return val; | 250 | return val; |
| 248 | } | 251 | } |
| 249 | 252 | ||
| 253 | static inline Lisp_Object | ||
| 254 | char_table_ref_simple (Lisp_Object table, int idx, int c, int *from, int *to, | ||
| 255 | Lisp_Object defalt, bool is_uniprop, bool is_subtable) | ||
| 256 | { | ||
| 257 | Lisp_Object val = is_subtable ? | ||
| 258 | XSUB_CHAR_TABLE (table)->contents[idx]: | ||
| 259 | XCHAR_TABLE (table)->contents[idx]; | ||
| 260 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val)) | ||
| 261 | val = uniprop_table_uncompress (table, idx); | ||
| 262 | if (SUB_CHAR_TABLE_P (val)) | ||
| 263 | val = sub_char_table_ref_and_range (val, c, from, to, | ||
| 264 | defalt, is_uniprop); | ||
| 265 | else if (NILP (val)) | ||
| 266 | val = defalt; | ||
| 267 | return val; | ||
| 268 | } | ||
| 269 | |||
| 250 | static Lisp_Object | 270 | static Lisp_Object |
| 251 | sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, | 271 | sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, |
| 252 | Lisp_Object defalt, bool is_uniprop) | 272 | Lisp_Object defalt, bool is_uniprop) |
| @@ -254,31 +274,18 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, | |||
| 254 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); | 274 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 255 | int depth = tbl->depth, min_char = tbl->min_char; | 275 | int depth = tbl->depth, min_char = tbl->min_char; |
| 256 | int chartab_idx = CHARTAB_IDX (c, depth, min_char), idx; | 276 | int chartab_idx = CHARTAB_IDX (c, depth, min_char), idx; |
| 257 | Lisp_Object val; | 277 | Lisp_Object val |
| 258 | 278 | = char_table_ref_simple (table, chartab_idx, c, from, to, | |
| 259 | val = tbl->contents[chartab_idx]; | 279 | defalt, is_uniprop, true); |
| 260 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val)) | ||
| 261 | val = uniprop_table_uncompress (table, chartab_idx); | ||
| 262 | if (SUB_CHAR_TABLE_P (val)) | ||
| 263 | val = sub_char_table_ref_and_range (val, c, from, to, defalt, is_uniprop); | ||
| 264 | else if (NILP (val)) | ||
| 265 | val = defalt; | ||
| 266 | 280 | ||
| 267 | idx = chartab_idx; | 281 | idx = chartab_idx; |
| 268 | while (idx > 0 && *from < min_char + idx * chartab_chars[depth]) | 282 | while (idx > 0 && *from < min_char + idx * chartab_chars[depth]) |
| 269 | { | 283 | { |
| 270 | Lisp_Object this_val; | ||
| 271 | |||
| 272 | c = min_char + idx * chartab_chars[depth] - 1; | 284 | c = min_char + idx * chartab_chars[depth] - 1; |
| 273 | idx--; | 285 | idx--; |
| 274 | this_val = tbl->contents[idx]; | 286 | Lisp_Object this_val |
| 275 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | 287 | = char_table_ref_simple (table, idx, c, from, to, |
| 276 | this_val = uniprop_table_uncompress (table, idx); | 288 | defalt, is_uniprop, true); |
| 277 | if (SUB_CHAR_TABLE_P (this_val)) | ||
| 278 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt, | ||
| 279 | is_uniprop); | ||
| 280 | else if (NILP (this_val)) | ||
| 281 | this_val = defalt; | ||
| 282 | 289 | ||
| 283 | if (! EQ (this_val, val)) | 290 | if (! EQ (this_val, val)) |
| 284 | { | 291 | { |
| @@ -290,17 +297,11 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, | |||
| 290 | < chartab_chars[depth - 1]) | 297 | < chartab_chars[depth - 1]) |
| 291 | && (c += min_char) <= *to) | 298 | && (c += min_char) <= *to) |
| 292 | { | 299 | { |
| 293 | Lisp_Object this_val; | ||
| 294 | |||
| 295 | chartab_idx++; | 300 | chartab_idx++; |
| 296 | this_val = tbl->contents[chartab_idx]; | 301 | Lisp_Object this_val |
| 297 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | 302 | = char_table_ref_simple (table, chartab_idx, c, from, to, |
| 298 | this_val = uniprop_table_uncompress (table, chartab_idx); | 303 | defalt, is_uniprop, true); |
| 299 | if (SUB_CHAR_TABLE_P (this_val)) | 304 | |
| 300 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt, | ||
| 301 | is_uniprop); | ||
| 302 | else if (NILP (this_val)) | ||
| 303 | this_val = defalt; | ||
| 304 | if (! EQ (this_val, val)) | 305 | if (! EQ (this_val, val)) |
| 305 | { | 306 | { |
| 306 | *to = c - 1; | 307 | *to = c - 1; |
| @@ -321,37 +322,26 @@ Lisp_Object | |||
| 321 | char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) | 322 | char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) |
| 322 | { | 323 | { |
| 323 | struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); | 324 | struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); |
| 324 | int chartab_idx = CHARTAB_IDX (c, 0, 0), idx; | 325 | int chartab_idx = CHARTAB_IDX (c, 0, 0); |
| 325 | Lisp_Object val; | ||
| 326 | bool is_uniprop = UNIPROP_TABLE_P (table); | 326 | bool is_uniprop = UNIPROP_TABLE_P (table); |
| 327 | 327 | ||
| 328 | val = tbl->contents[chartab_idx]; | ||
| 329 | if (*from < 0) | 328 | if (*from < 0) |
| 330 | *from = 0; | 329 | *from = 0; |
| 331 | if (*to < 0) | 330 | if (*to < 0) |
| 332 | *to = MAX_CHAR; | 331 | *to = MAX_CHAR; |
| 333 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val)) | 332 | |
| 334 | val = uniprop_table_uncompress (table, chartab_idx); | 333 | Lisp_Object val |
| 335 | if (SUB_CHAR_TABLE_P (val)) | 334 | = char_table_ref_simple (table, chartab_idx, c, from, to, |
| 336 | val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt, | 335 | tbl->defalt, is_uniprop, false); |
| 337 | is_uniprop); | 336 | |
| 338 | else if (NILP (val)) | 337 | int idx = chartab_idx; |
| 339 | val = tbl->defalt; | ||
| 340 | idx = chartab_idx; | ||
| 341 | while (*from < idx * chartab_chars[0]) | 338 | while (*from < idx * chartab_chars[0]) |
| 342 | { | 339 | { |
| 343 | Lisp_Object this_val; | ||
| 344 | |||
| 345 | c = idx * chartab_chars[0] - 1; | 340 | c = idx * chartab_chars[0] - 1; |
| 346 | idx--; | 341 | idx--; |
| 347 | this_val = tbl->contents[idx]; | 342 | Lisp_Object this_val |
| 348 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | 343 | = char_table_ref_simple (table, idx, c, from, to, |
| 349 | this_val = uniprop_table_uncompress (table, idx); | 344 | tbl->defalt, is_uniprop, false); |
| 350 | if (SUB_CHAR_TABLE_P (this_val)) | ||
| 351 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, | ||
| 352 | tbl->defalt, is_uniprop); | ||
| 353 | else if (NILP (this_val)) | ||
| 354 | this_val = tbl->defalt; | ||
| 355 | 345 | ||
| 356 | if (! EQ (this_val, val)) | 346 | if (! EQ (this_val, val)) |
| 357 | { | 347 | { |
| @@ -361,18 +351,12 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) | |||
| 361 | } | 351 | } |
| 362 | while (*to >= (chartab_idx + 1) * chartab_chars[0]) | 352 | while (*to >= (chartab_idx + 1) * chartab_chars[0]) |
| 363 | { | 353 | { |
| 364 | Lisp_Object this_val; | ||
| 365 | |||
| 366 | chartab_idx++; | 354 | chartab_idx++; |
| 367 | c = chartab_idx * chartab_chars[0]; | 355 | c = chartab_idx * chartab_chars[0]; |
| 368 | this_val = tbl->contents[chartab_idx]; | 356 | Lisp_Object this_val |
| 369 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | 357 | = char_table_ref_simple (table, chartab_idx, c, from, to, |
| 370 | this_val = uniprop_table_uncompress (table, chartab_idx); | 358 | tbl->defalt, is_uniprop, false); |
| 371 | if (SUB_CHAR_TABLE_P (this_val)) | 359 | |
| 372 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, | ||
| 373 | tbl->defalt, is_uniprop); | ||
| 374 | else if (NILP (this_val)) | ||
| 375 | this_val = tbl->defalt; | ||
| 376 | if (! EQ (this_val, val)) | 360 | if (! EQ (this_val, val)) |
| 377 | { | 361 | { |
| 378 | *to = c - 1; | 362 | *to = c - 1; |
diff --git a/src/coding.c b/src/coding.c index 46e7fca0f43..87b55aecc05 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -9476,7 +9476,7 @@ not fully specified.) */) | |||
| 9476 | } | 9476 | } |
| 9477 | 9477 | ||
| 9478 | /* Whether STRING only contains chars in the 0..127 range. */ | 9478 | /* Whether STRING only contains chars in the 0..127 range. */ |
| 9479 | static bool | 9479 | bool |
| 9480 | string_ascii_p (Lisp_Object string) | 9480 | string_ascii_p (Lisp_Object string) |
| 9481 | { | 9481 | { |
| 9482 | ptrdiff_t nbytes = SBYTES (string); | 9482 | ptrdiff_t nbytes = SBYTES (string); |
diff --git a/src/data.c b/src/data.c index 9adfafacaa5..ffca7e75355 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -3901,6 +3901,7 @@ syms_of_data (void) | |||
| 3901 | DEFSYM (Qerror, "error"); | 3901 | DEFSYM (Qerror, "error"); |
| 3902 | DEFSYM (Quser_error, "user-error"); | 3902 | DEFSYM (Quser_error, "user-error"); |
| 3903 | DEFSYM (Qquit, "quit"); | 3903 | DEFSYM (Qquit, "quit"); |
| 3904 | DEFSYM (Qminibuffer_quit, "minibuffer-quit"); | ||
| 3904 | DEFSYM (Qwrong_length_argument, "wrong-length-argument"); | 3905 | DEFSYM (Qwrong_length_argument, "wrong-length-argument"); |
| 3905 | DEFSYM (Qwrong_type_argument, "wrong-type-argument"); | 3906 | DEFSYM (Qwrong_type_argument, "wrong-type-argument"); |
| 3906 | DEFSYM (Qargs_out_of_range, "args-out-of-range"); | 3907 | DEFSYM (Qargs_out_of_range, "args-out-of-range"); |
| @@ -3973,6 +3974,7 @@ syms_of_data (void) | |||
| 3973 | Fput (sym, Qerror_message, build_pure_c_string (msg)) | 3974 | Fput (sym, Qerror_message, build_pure_c_string (msg)) |
| 3974 | 3975 | ||
| 3975 | PUT_ERROR (Qquit, Qnil, "Quit"); | 3976 | PUT_ERROR (Qquit, Qnil, "Quit"); |
| 3977 | PUT_ERROR (Qminibuffer_quit, pure_cons (Qquit, Qnil), "Quit"); | ||
| 3976 | 3978 | ||
| 3977 | PUT_ERROR (Quser_error, error_tail, ""); | 3979 | PUT_ERROR (Quser_error, error_tail, ""); |
| 3978 | PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument"); | 3980 | PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument"); |
diff --git a/src/eval.c b/src/eval.c index b76ced79d61..48104bd0f45 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2026,6 +2026,18 @@ skip_debugger (Lisp_Object conditions, Lisp_Object data) | |||
| 2026 | return 0; | 2026 | return 0; |
| 2027 | } | 2027 | } |
| 2028 | 2028 | ||
| 2029 | /* Say whether SIGNAL is a `quit' symbol (or inherits from it). */ | ||
| 2030 | bool | ||
| 2031 | signal_quit_p (Lisp_Object signal) | ||
| 2032 | { | ||
| 2033 | Lisp_Object list; | ||
| 2034 | |||
| 2035 | return EQ (signal, Qquit) | ||
| 2036 | || (!NILP (Fsymbolp (signal)) | ||
| 2037 | && CONSP (list = Fget (signal, Qerror_conditions)) | ||
| 2038 | && !NILP (Fmemq (Qquit, list))); | ||
| 2039 | } | ||
| 2040 | |||
| 2029 | /* Call the debugger if calling it is currently enabled for CONDITIONS. | 2041 | /* Call the debugger if calling it is currently enabled for CONDITIONS. |
| 2030 | SIG and DATA describe the signal. There are two ways to pass them: | 2042 | SIG and DATA describe the signal. There are two ways to pass them: |
| 2031 | = SIG is the error symbol, and DATA is the rest of the data. | 2043 | = SIG is the error symbol, and DATA is the rest of the data. |
| @@ -2044,7 +2056,7 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) | |||
| 2044 | ! input_blocked_p () | 2056 | ! input_blocked_p () |
| 2045 | && NILP (Vinhibit_debugger) | 2057 | && NILP (Vinhibit_debugger) |
| 2046 | /* Does user want to enter debugger for this kind of error? */ | 2058 | /* Does user want to enter debugger for this kind of error? */ |
| 2047 | && (EQ (sig, Qquit) | 2059 | && (signal_quit_p (sig) |
| 2048 | ? debug_on_quit | 2060 | ? debug_on_quit |
| 2049 | : wants_debugger (Vdebug_on_error, conditions)) | 2061 | : wants_debugger (Vdebug_on_error, conditions)) |
| 2050 | && ! skip_debugger (conditions, combined_data) | 2062 | && ! skip_debugger (conditions, combined_data) |
diff --git a/src/fileio.c b/src/fileio.c index 04c9d7d4af3..13c99bee109 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -749,6 +749,114 @@ For that reason, you should normally use `make-temp-file' instead. */) | |||
| 749 | empty_unibyte_string, Qnil); | 749 | empty_unibyte_string, Qnil); |
| 750 | } | 750 | } |
| 751 | 751 | ||
| 752 | DEFUN ("file-name-concat", Ffile_name_concat, Sfile_name_concat, 1, MANY, 0, | ||
| 753 | doc: /* Append COMPONENTS to DIRECTORY and return the resulting string. | ||
| 754 | Elements in COMPONENTS must be a string or nil. | ||
| 755 | DIRECTORY or the non-final elements in COMPONENTS may or may not end | ||
| 756 | with a slash -- if they don't end with a slash, a slash will be | ||
| 757 | inserted before contatenating. | ||
| 758 | usage: (record DIRECTORY &rest COMPONENTS) */) | ||
| 759 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 760 | { | ||
| 761 | ptrdiff_t chars = 0, bytes = 0, multibytes = 0, eargs = 0; | ||
| 762 | Lisp_Object *elements = args; | ||
| 763 | Lisp_Object result; | ||
| 764 | ptrdiff_t i; | ||
| 765 | |||
| 766 | /* First go through the list to check the types and see whether | ||
| 767 | they're all of the same multibytedness. */ | ||
| 768 | for (i = 0; i < nargs; i++) | ||
| 769 | { | ||
| 770 | Lisp_Object arg = args[i]; | ||
| 771 | /* Skip empty and nil elements. */ | ||
| 772 | if (NILP (arg)) | ||
| 773 | continue; | ||
| 774 | CHECK_STRING (arg); | ||
| 775 | if (SCHARS (arg) == 0) | ||
| 776 | continue; | ||
| 777 | eargs++; | ||
| 778 | /* Multibyte and non-ASCII. */ | ||
| 779 | if (STRING_MULTIBYTE (arg) && SCHARS (arg) != SBYTES (arg)) | ||
| 780 | multibytes++; | ||
| 781 | /* We're not adding a slash to the final part. */ | ||
| 782 | if (i == nargs - 1 | ||
| 783 | || IS_DIRECTORY_SEP (*(SSDATA (arg) + SBYTES (arg) - 1))) | ||
| 784 | { | ||
| 785 | bytes += SBYTES (arg); | ||
| 786 | chars += SCHARS (arg); | ||
| 787 | } | ||
| 788 | else | ||
| 789 | { | ||
| 790 | bytes += SBYTES (arg) + 1; | ||
| 791 | chars += SCHARS (arg) + 1; | ||
| 792 | } | ||
| 793 | } | ||
| 794 | |||
| 795 | /* Convert if needed. */ | ||
| 796 | if ((multibytes != 0 && multibytes != nargs) | ||
| 797 | || eargs != nargs) | ||
| 798 | { | ||
| 799 | int j = 0; | ||
| 800 | elements = xmalloc (eargs * sizeof *elements); | ||
| 801 | bytes = 0; | ||
| 802 | chars = 0; | ||
| 803 | |||
| 804 | /* Filter out nil/"". */ | ||
| 805 | for (i = 0; i < nargs; i++) | ||
| 806 | { | ||
| 807 | Lisp_Object arg = args[i]; | ||
| 808 | if (!NILP (arg) && SCHARS (arg) != 0) | ||
| 809 | elements[j++] = arg; | ||
| 810 | } | ||
| 811 | |||
| 812 | for (i = 0; i < eargs; i++) | ||
| 813 | { | ||
| 814 | Lisp_Object arg = elements[i]; | ||
| 815 | /* Use multibyte or all-ASCII strings as is. */ | ||
| 816 | if (!STRING_MULTIBYTE (arg) && !string_ascii_p (arg)) | ||
| 817 | elements[i] = Fstring_to_multibyte (arg); | ||
| 818 | arg = elements[i]; | ||
| 819 | /* We have to recompute the number of bytes. */ | ||
| 820 | if (i == eargs - 1 | ||
| 821 | || IS_DIRECTORY_SEP (*(SSDATA (arg) + SBYTES (arg) - 1))) | ||
| 822 | { | ||
| 823 | bytes += SBYTES (arg); | ||
| 824 | chars += SCHARS (arg); | ||
| 825 | } | ||
| 826 | else | ||
| 827 | { | ||
| 828 | bytes += SBYTES (arg) + 1; | ||
| 829 | chars += SCHARS (arg) + 1; | ||
| 830 | } | ||
| 831 | } | ||
| 832 | } | ||
| 833 | |||
| 834 | /* Allocate an empty string. */ | ||
| 835 | if (multibytes == 0) | ||
| 836 | result = make_uninit_string (chars); | ||
| 837 | else | ||
| 838 | result = make_uninit_multibyte_string (chars, bytes); | ||
| 839 | /* Null-terminate the string. */ | ||
| 840 | *(SSDATA (result) + SBYTES (result)) = 0; | ||
| 841 | |||
| 842 | /* Copy over the data. */ | ||
| 843 | char *p = SSDATA (result); | ||
| 844 | for (i = 0; i < eargs; i++) | ||
| 845 | { | ||
| 846 | Lisp_Object arg = elements[i]; | ||
| 847 | memcpy (p, SSDATA (arg), SBYTES (arg)); | ||
| 848 | p += SBYTES (arg); | ||
| 849 | /* The last element shouldn't have a slash added at the end. */ | ||
| 850 | if (i < eargs - 1 && !IS_DIRECTORY_SEP (*(p - 1))) | ||
| 851 | *p++ = DIRECTORY_SEP; | ||
| 852 | } | ||
| 853 | |||
| 854 | if (elements != args) | ||
| 855 | xfree (elements); | ||
| 856 | |||
| 857 | return result; | ||
| 858 | } | ||
| 859 | |||
| 752 | /* NAME must be a string. */ | 860 | /* NAME must be a string. */ |
| 753 | static bool | 861 | static bool |
| 754 | file_name_absolute_no_tilde_p (Lisp_Object name) | 862 | file_name_absolute_no_tilde_p (Lisp_Object name) |
| @@ -6488,6 +6596,7 @@ This includes interactive calls to `delete-file' and | |||
| 6488 | defsubr (&Sdirectory_file_name); | 6596 | defsubr (&Sdirectory_file_name); |
| 6489 | defsubr (&Smake_temp_file_internal); | 6597 | defsubr (&Smake_temp_file_internal); |
| 6490 | defsubr (&Smake_temp_name); | 6598 | defsubr (&Smake_temp_name); |
| 6599 | defsubr (&Sfile_name_concat); | ||
| 6491 | defsubr (&Sexpand_file_name); | 6600 | defsubr (&Sexpand_file_name); |
| 6492 | defsubr (&Ssubstitute_in_file_name); | 6601 | defsubr (&Ssubstitute_in_file_name); |
| 6493 | defsubr (&Scopy_file); | 6602 | defsubr (&Scopy_file); |
diff --git a/src/filelock.c b/src/filelock.c index 106633f5846..cc185d96cdf 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -673,7 +673,7 @@ lock_file (Lisp_Object fn) | |||
| 673 | Lisp_Object subject_buf = get_truename_buffer (fn); | 673 | Lisp_Object subject_buf = get_truename_buffer (fn); |
| 674 | if (!NILP (subject_buf) | 674 | if (!NILP (subject_buf) |
| 675 | && NILP (Fverify_visited_file_modtime (subject_buf)) | 675 | && NILP (Fverify_visited_file_modtime (subject_buf)) |
| 676 | && !NILP (Ffile_exists_p (lock_filename)) | 676 | && !NILP (Ffile_exists_p (fn)) |
| 677 | && current_lock_owner (NULL, lfname) != -2) | 677 | && current_lock_owner (NULL, lfname) != -2) |
| 678 | call1 (intern ("userlock--ask-user-about-supersession-threat"), fn); | 678 | call1 (intern ("userlock--ask-user-about-supersession-threat"), fn); |
| 679 | 679 | ||
| @@ -3955,7 +3955,7 @@ base64_decode_1 (const char *from, char *to, ptrdiff_t length, | |||
| 3955 | if (c == '=') | 3955 | if (c == '=') |
| 3956 | continue; | 3956 | continue; |
| 3957 | 3957 | ||
| 3958 | if (v1 < 0) | 3958 | if (v1 == 0) |
| 3959 | return -1; | 3959 | return -1; |
| 3960 | value += v1 - 1; | 3960 | value += v1 - 1; |
| 3961 | 3961 | ||
| @@ -5769,16 +5769,6 @@ characters. */ ) | |||
| 5769 | return list3 (make_int (lines), make_int (longest), make_float (mean)); | 5769 | return list3 (make_int (lines), make_int (longest), make_float (mean)); |
| 5770 | } | 5770 | } |
| 5771 | 5771 | ||
| 5772 | static bool | ||
| 5773 | string_ascii_p (Lisp_Object string) | ||
| 5774 | { | ||
| 5775 | ptrdiff_t nbytes = SBYTES (string); | ||
| 5776 | for (ptrdiff_t i = 0; i < nbytes; i++) | ||
| 5777 | if (SREF (string, i) > 127) | ||
| 5778 | return false; | ||
| 5779 | return true; | ||
| 5780 | } | ||
| 5781 | |||
| 5782 | DEFUN ("string-search", Fstring_search, Sstring_search, 2, 3, 0, | 5772 | DEFUN ("string-search", Fstring_search, Sstring_search, 2, 3, 0, |
| 5783 | doc: /* Search for the string NEEDLE in the string HAYSTACK. | 5773 | doc: /* Search for the string NEEDLE in the string HAYSTACK. |
| 5784 | The return value is the position of the first occurrence of NEEDLE in | 5774 | The return value is the position of the first occurrence of NEEDLE in |
diff --git a/src/frame.c b/src/frame.c index 3c7c4078cb0..94e0073e22a 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -1021,6 +1021,10 @@ make_frame (bool mini_p) | |||
| 1021 | rw->total_lines = FRAME_LINES (f) - (mini_p ? 1 : 0); | 1021 | rw->total_lines = FRAME_LINES (f) - (mini_p ? 1 : 0); |
| 1022 | rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f); | 1022 | rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f); |
| 1023 | 1023 | ||
| 1024 | fset_face_hash_table | ||
| 1025 | (f, make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, | ||
| 1026 | DEFAULT_REHASH_THRESHOLD, Qnil, false)); | ||
| 1027 | |||
| 1024 | if (mini_p) | 1028 | if (mini_p) |
| 1025 | { | 1029 | { |
| 1026 | mw->top_line = rw->total_lines; | 1030 | mw->top_line = rw->total_lines; |
| @@ -1329,7 +1333,7 @@ affects all frames on the same terminal device. */) | |||
| 1329 | { | 1333 | { |
| 1330 | struct frame *f; | 1334 | struct frame *f; |
| 1331 | struct terminal *t = NULL; | 1335 | struct terminal *t = NULL; |
| 1332 | Lisp_Object frame, tem; | 1336 | Lisp_Object frame; |
| 1333 | struct frame *sf = SELECTED_FRAME (); | 1337 | struct frame *sf = SELECTED_FRAME (); |
| 1334 | 1338 | ||
| 1335 | #ifdef MSDOS | 1339 | #ifdef MSDOS |
| @@ -1411,14 +1415,16 @@ affects all frames on the same terminal device. */) | |||
| 1411 | store_in_alist (&parms, Qminibuffer, Qt); | 1415 | store_in_alist (&parms, Qminibuffer, Qt); |
| 1412 | Fmodify_frame_parameters (frame, parms); | 1416 | Fmodify_frame_parameters (frame, parms); |
| 1413 | 1417 | ||
| 1414 | /* Make the frame face alist be frame-specific, so that each | 1418 | /* Make the frame face hash be frame-specific, so that each |
| 1415 | frame could change its face definitions independently. */ | 1419 | frame could change its face definitions independently. */ |
| 1416 | fset_face_alist (f, Fcopy_alist (sf->face_alist)); | 1420 | fset_face_hash_table (f, Fcopy_hash_table (sf->face_hash_table)); |
| 1417 | /* Simple Fcopy_alist isn't enough, because we need the contents of | 1421 | /* Simple copy_hash_table isn't enough, because we need the contents of |
| 1418 | the vectors which are the CDRs of associations in face_alist to | 1422 | the vectors which are the values in face_hash_table to |
| 1419 | be copied as well. */ | 1423 | be copied as well. */ |
| 1420 | for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem)) | 1424 | ptrdiff_t idx = 0; |
| 1421 | XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem)))); | 1425 | struct Lisp_Hash_Table *table = XHASH_TABLE (f->face_hash_table); |
| 1426 | for (idx = 0; idx < table->count; ++idx) | ||
| 1427 | set_hash_value_slot (table, idx, Fcopy_sequence (HASH_VALUE (table, idx))); | ||
| 1422 | 1428 | ||
| 1423 | f->can_set_window_size = true; | 1429 | f->can_set_window_size = true; |
| 1424 | f->after_make_frame = true; | 1430 | f->after_make_frame = true; |
diff --git a/src/frame.h b/src/frame.h index d3ae548ed3b..9856890c315 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -158,8 +158,8 @@ struct frame | |||
| 158 | There are four additional elements of nil at the end, to terminate. */ | 158 | There are four additional elements of nil at the end, to terminate. */ |
| 159 | Lisp_Object menu_bar_items; | 159 | Lisp_Object menu_bar_items; |
| 160 | 160 | ||
| 161 | /* Alist of elements (FACE-NAME . FACE-VECTOR-DATA). */ | 161 | /* Hash table of FACE-NAME keys and FACE-VECTOR-DATA values. */ |
| 162 | Lisp_Object face_alist; | 162 | Lisp_Object face_hash_table; |
| 163 | 163 | ||
| 164 | /* A vector that records the entire structure of this frame's menu bar. | 164 | /* A vector that records the entire structure of this frame's menu bar. |
| 165 | For the format of the data, see extensive comments in xmenu.c. | 165 | For the format of the data, see extensive comments in xmenu.c. |
| @@ -673,9 +673,9 @@ fset_condemned_scroll_bars (struct frame *f, Lisp_Object val) | |||
| 673 | f->condemned_scroll_bars = val; | 673 | f->condemned_scroll_bars = val; |
| 674 | } | 674 | } |
| 675 | INLINE void | 675 | INLINE void |
| 676 | fset_face_alist (struct frame *f, Lisp_Object val) | 676 | fset_face_hash_table (struct frame *f, Lisp_Object val) |
| 677 | { | 677 | { |
| 678 | f->face_alist = val; | 678 | f->face_hash_table = val; |
| 679 | } | 679 | } |
| 680 | #if defined (HAVE_WINDOW_SYSTEM) | 680 | #if defined (HAVE_WINDOW_SYSTEM) |
| 681 | INLINE void | 681 | INLINE void |
diff --git a/src/ftfont.c b/src/ftfont.c index 0603dd9ce68..12d0d72d276 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -2798,10 +2798,31 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, | |||
| 2798 | 2798 | ||
| 2799 | if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) | 2799 | if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) |
| 2800 | return Qnil; | 2800 | return Qnil; |
| 2801 | |||
| 2802 | /* mflt_run may fail to set g->g.to (which must be a valid index | ||
| 2803 | into lgstring) correctly if the font has an OTF table that is | ||
| 2804 | different from what the m17n library expects. */ | ||
| 2801 | for (i = 0; i < gstring.used; i++) | 2805 | for (i = 0; i < gstring.used; i++) |
| 2802 | { | 2806 | { |
| 2803 | MFLTGlyphFT *g = (MFLTGlyphFT *) (gstring.glyphs) + i; | 2807 | MFLTGlyphFT *g = (MFLTGlyphFT *) (gstring.glyphs) + i; |
| 2808 | if (g->g.to >= len) | ||
| 2809 | { | ||
| 2810 | /* Invalid g->g.to. */ | ||
| 2811 | g->g.to = len - 1; | ||
| 2812 | int from = g->g.from; | ||
| 2813 | /* Fix remaining glyphs. */ | ||
| 2814 | for (++i; i < gstring.used; i++) | ||
| 2815 | { | ||
| 2816 | g = (MFLTGlyphFT *) (gstring.glyphs) + i; | ||
| 2817 | g->g.from = from; | ||
| 2818 | g->g.to = len - 1; | ||
| 2819 | } | ||
| 2820 | } | ||
| 2821 | } | ||
| 2804 | 2822 | ||
| 2823 | for (i = 0; i < gstring.used; i++) | ||
| 2824 | { | ||
| 2825 | MFLTGlyphFT *g = (MFLTGlyphFT *) (gstring.glyphs) + i; | ||
| 2805 | g->g.from = LGLYPH_FROM (LGSTRING_GLYPH (lgstring, g->g.from)); | 2826 | g->g.from = LGLYPH_FROM (LGSTRING_GLYPH (lgstring, g->g.from)); |
| 2806 | g->g.to = LGLYPH_TO (LGSTRING_GLYPH (lgstring, g->g.to)); | 2827 | g->g.to = LGLYPH_TO (LGSTRING_GLYPH (lgstring, g->g.to)); |
| 2807 | } | 2828 | } |
diff --git a/src/json.c b/src/json.c index 3f1d27ad7fb..b0779b912a8 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -595,10 +595,8 @@ usage: (json-serialize OBJECT &rest ARGS) */) | |||
| 595 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | 595 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); |
| 596 | } | 596 | } |
| 597 | if (!json_initialized) | 597 | if (!json_initialized) |
| 598 | { | 598 | Fsignal (Qjson_unavailable, |
| 599 | message1 ("jansson library not found"); | 599 | list1 (build_unibyte_string ("jansson library not found"))); |
| 600 | return Qnil; | ||
| 601 | } | ||
| 602 | #endif | 600 | #endif |
| 603 | 601 | ||
| 604 | struct json_configuration conf = | 602 | struct json_configuration conf = |
| @@ -706,10 +704,8 @@ usage: (json-insert OBJECT &rest ARGS) */) | |||
| 706 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | 704 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); |
| 707 | } | 705 | } |
| 708 | if (!json_initialized) | 706 | if (!json_initialized) |
| 709 | { | 707 | Fsignal (Qjson_unavailable, |
| 710 | message1 ("jansson library not found"); | 708 | list1 (build_unibyte_string ("jansson library not found"))); |
| 711 | return Qnil; | ||
| 712 | } | ||
| 713 | #endif | 709 | #endif |
| 714 | 710 | ||
| 715 | struct json_configuration conf = | 711 | struct json_configuration conf = |
| @@ -965,10 +961,8 @@ usage: (json-parse-string STRING &rest ARGS) */) | |||
| 965 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | 961 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); |
| 966 | } | 962 | } |
| 967 | if (!json_initialized) | 963 | if (!json_initialized) |
| 968 | { | 964 | Fsignal (Qjson_unavailable, |
| 969 | message1 ("jansson library not found"); | 965 | list1 (build_unibyte_string ("jansson library not found"))); |
| 970 | return Qnil; | ||
| 971 | } | ||
| 972 | #endif | 966 | #endif |
| 973 | 967 | ||
| 974 | Lisp_Object string = args[0]; | 968 | Lisp_Object string = args[0]; |
| @@ -1064,10 +1058,8 @@ usage: (json-parse-buffer &rest args) */) | |||
| 1064 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | 1058 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); |
| 1065 | } | 1059 | } |
| 1066 | if (!json_initialized) | 1060 | if (!json_initialized) |
| 1067 | { | 1061 | Fsignal (Qjson_unavailable, |
| 1068 | message1 ("jansson library not found"); | 1062 | list1 (build_unibyte_string ("jansson library not found"))); |
| 1069 | return Qnil; | ||
| 1070 | } | ||
| 1071 | #endif | 1063 | #endif |
| 1072 | 1064 | ||
| 1073 | struct json_configuration conf = | 1065 | struct json_configuration conf = |
| @@ -1129,6 +1121,7 @@ syms_of_json (void) | |||
| 1129 | DEFSYM (Qjson_end_of_file, "json-end-of-file"); | 1121 | DEFSYM (Qjson_end_of_file, "json-end-of-file"); |
| 1130 | DEFSYM (Qjson_trailing_content, "json-trailing-content"); | 1122 | DEFSYM (Qjson_trailing_content, "json-trailing-content"); |
| 1131 | DEFSYM (Qjson_object_too_deep, "json-object-too-deep"); | 1123 | DEFSYM (Qjson_object_too_deep, "json-object-too-deep"); |
| 1124 | DEFSYM (Qjson_unavailable, "json-unavailable"); | ||
| 1132 | define_error (Qjson_error, "generic JSON error", Qerror); | 1125 | define_error (Qjson_error, "generic JSON error", Qerror); |
| 1133 | define_error (Qjson_out_of_memory, | 1126 | define_error (Qjson_out_of_memory, |
| 1134 | "not enough memory for creating JSON object", Qjson_error); | 1127 | "not enough memory for creating JSON object", Qjson_error); |
diff --git a/src/keyboard.c b/src/keyboard.c index 7d045648881..5b828ca60ff 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -725,6 +725,9 @@ recursive_edit_1 (void) | |||
| 725 | if (STRINGP (val)) | 725 | if (STRINGP (val)) |
| 726 | xsignal1 (Qerror, val); | 726 | xsignal1 (Qerror, val); |
| 727 | 727 | ||
| 728 | if (FUNCTIONP (val)) | ||
| 729 | call0 (val); | ||
| 730 | |||
| 728 | return unbind_to (count, Qnil); | 731 | return unbind_to (count, Qnil); |
| 729 | } | 732 | } |
| 730 | 733 | ||
| @@ -921,6 +924,7 @@ static Lisp_Object | |||
| 921 | cmd_error (Lisp_Object data) | 924 | cmd_error (Lisp_Object data) |
| 922 | { | 925 | { |
| 923 | Lisp_Object old_level, old_length; | 926 | Lisp_Object old_level, old_length; |
| 927 | Lisp_Object conditions; | ||
| 924 | char macroerror[sizeof "After..kbd macro iterations: " | 928 | char macroerror[sizeof "After..kbd macro iterations: " |
| 925 | + INT_STRLEN_BOUND (EMACS_INT)]; | 929 | + INT_STRLEN_BOUND (EMACS_INT)]; |
| 926 | 930 | ||
| @@ -940,10 +944,15 @@ cmd_error (Lisp_Object data) | |||
| 940 | else | 944 | else |
| 941 | *macroerror = 0; | 945 | *macroerror = 0; |
| 942 | 946 | ||
| 947 | conditions = Fget (XCAR (data), Qerror_conditions); | ||
| 948 | if (NILP (Fmemq (Qminibuffer_quit, conditions))) | ||
| 949 | { | ||
| 950 | Vexecuting_kbd_macro = Qnil; | ||
| 951 | executing_kbd_macro = Qnil; | ||
| 952 | } | ||
| 953 | |||
| 943 | Vstandard_output = Qt; | 954 | Vstandard_output = Qt; |
| 944 | Vstandard_input = Qt; | 955 | Vstandard_input = Qt; |
| 945 | Vexecuting_kbd_macro = Qnil; | ||
| 946 | executing_kbd_macro = Qnil; | ||
| 947 | kset_prefix_arg (current_kboard, Qnil); | 956 | kset_prefix_arg (current_kboard, Qnil); |
| 948 | kset_last_prefix_arg (current_kboard, Qnil); | 957 | kset_last_prefix_arg (current_kboard, Qnil); |
| 949 | cancel_echoing (); | 958 | cancel_echoing (); |
| @@ -976,7 +985,7 @@ cmd_error_internal (Lisp_Object data, const char *context) | |||
| 976 | { | 985 | { |
| 977 | /* The immediate context is not interesting for Quits, | 986 | /* The immediate context is not interesting for Quits, |
| 978 | since they are asynchronous. */ | 987 | since they are asynchronous. */ |
| 979 | if (EQ (XCAR (data), Qquit)) | 988 | if (signal_quit_p (XCAR (data))) |
| 980 | Vsignaling_function = Qnil; | 989 | Vsignaling_function = Qnil; |
| 981 | 990 | ||
| 982 | Vquit_flag = Qnil; | 991 | Vquit_flag = Qnil; |
| @@ -998,6 +1007,7 @@ Default value of `command-error-function'. */) | |||
| 998 | (Lisp_Object data, Lisp_Object context, Lisp_Object signal) | 1007 | (Lisp_Object data, Lisp_Object context, Lisp_Object signal) |
| 999 | { | 1008 | { |
| 1000 | struct frame *sf = SELECTED_FRAME (); | 1009 | struct frame *sf = SELECTED_FRAME (); |
| 1010 | Lisp_Object conditions; | ||
| 1001 | 1011 | ||
| 1002 | CHECK_STRING (context); | 1012 | CHECK_STRING (context); |
| 1003 | 1013 | ||
| @@ -1024,17 +1034,27 @@ Default value of `command-error-function'. */) | |||
| 1024 | } | 1034 | } |
| 1025 | else | 1035 | else |
| 1026 | { | 1036 | { |
| 1037 | conditions = Fget (XCAR (data), Qerror_conditions); | ||
| 1038 | |||
| 1027 | clear_message (1, 0); | 1039 | clear_message (1, 0); |
| 1028 | Fdiscard_input (); | ||
| 1029 | message_log_maybe_newline (); | 1040 | message_log_maybe_newline (); |
| 1030 | bitch_at_user (); | 1041 | |
| 1042 | if (!NILP (Fmemq (Qminibuffer_quit, conditions))) | ||
| 1043 | { | ||
| 1044 | Fding (Qt); | ||
| 1045 | } | ||
| 1046 | else | ||
| 1047 | { | ||
| 1048 | Fdiscard_input (); | ||
| 1049 | bitch_at_user (); | ||
| 1050 | } | ||
| 1031 | 1051 | ||
| 1032 | print_error_message (data, Qt, SSDATA (context), signal); | 1052 | print_error_message (data, Qt, SSDATA (context), signal); |
| 1033 | } | 1053 | } |
| 1034 | return Qnil; | 1054 | return Qnil; |
| 1035 | } | 1055 | } |
| 1036 | 1056 | ||
| 1037 | static Lisp_Object command_loop_2 (Lisp_Object); | 1057 | static Lisp_Object command_loop_1 (void); |
| 1038 | static Lisp_Object top_level_1 (Lisp_Object); | 1058 | static Lisp_Object top_level_1 (Lisp_Object); |
| 1039 | 1059 | ||
| 1040 | /* Entry to editor-command-loop. | 1060 | /* Entry to editor-command-loop. |
| @@ -1062,7 +1082,7 @@ command_loop (void) | |||
| 1062 | if (command_loop_level > 0 || minibuf_level > 0) | 1082 | if (command_loop_level > 0 || minibuf_level > 0) |
| 1063 | { | 1083 | { |
| 1064 | Lisp_Object val; | 1084 | Lisp_Object val; |
| 1065 | val = internal_catch (Qexit, command_loop_2, Qnil); | 1085 | val = internal_catch (Qexit, command_loop_2, Qerror); |
| 1066 | executing_kbd_macro = Qnil; | 1086 | executing_kbd_macro = Qnil; |
| 1067 | return val; | 1087 | return val; |
| 1068 | } | 1088 | } |
| @@ -1070,7 +1090,7 @@ command_loop (void) | |||
| 1070 | while (1) | 1090 | while (1) |
| 1071 | { | 1091 | { |
| 1072 | internal_catch (Qtop_level, top_level_1, Qnil); | 1092 | internal_catch (Qtop_level, top_level_1, Qnil); |
| 1073 | internal_catch (Qtop_level, command_loop_2, Qnil); | 1093 | internal_catch (Qtop_level, command_loop_2, Qerror); |
| 1074 | executing_kbd_macro = Qnil; | 1094 | executing_kbd_macro = Qnil; |
| 1075 | 1095 | ||
| 1076 | /* End of file in -batch run causes exit here. */ | 1096 | /* End of file in -batch run causes exit here. */ |
| @@ -1083,15 +1103,16 @@ command_loop (void) | |||
| 1083 | editing loop, and reenter the editing loop. | 1103 | editing loop, and reenter the editing loop. |
| 1084 | When there is an error, cmd_error runs and returns a non-nil | 1104 | When there is an error, cmd_error runs and returns a non-nil |
| 1085 | value to us. A value of nil means that command_loop_1 itself | 1105 | value to us. A value of nil means that command_loop_1 itself |
| 1086 | returned due to end of file (or end of kbd macro). */ | 1106 | returned due to end of file (or end of kbd macro). HANDLERS is a |
| 1107 | list of condition names, passed to internal_condition_case. */ | ||
| 1087 | 1108 | ||
| 1088 | static Lisp_Object | 1109 | Lisp_Object |
| 1089 | command_loop_2 (Lisp_Object ignore) | 1110 | command_loop_2 (Lisp_Object handlers) |
| 1090 | { | 1111 | { |
| 1091 | register Lisp_Object val; | 1112 | register Lisp_Object val; |
| 1092 | 1113 | ||
| 1093 | do | 1114 | do |
| 1094 | val = internal_condition_case (command_loop_1, Qerror, cmd_error); | 1115 | val = internal_condition_case (command_loop_1, handlers, cmd_error); |
| 1095 | while (!NILP (val)); | 1116 | while (!NILP (val)); |
| 1096 | 1117 | ||
| 1097 | return Qnil; | 1118 | return Qnil; |
| @@ -1234,7 +1255,7 @@ static int read_key_sequence (Lisp_Object *, Lisp_Object, | |||
| 1234 | bool, bool, bool, bool); | 1255 | bool, bool, bool, bool); |
| 1235 | static void adjust_point_for_property (ptrdiff_t, bool); | 1256 | static void adjust_point_for_property (ptrdiff_t, bool); |
| 1236 | 1257 | ||
| 1237 | Lisp_Object | 1258 | static Lisp_Object |
| 1238 | command_loop_1 (void) | 1259 | command_loop_1 (void) |
| 1239 | { | 1260 | { |
| 1240 | modiff_count prev_modiff = 0; | 1261 | modiff_count prev_modiff = 0; |
| @@ -6630,8 +6651,11 @@ DEFUN ("event-convert-list", Fevent_convert_list, Sevent_convert_list, 1, 1, 0, | |||
| 6630 | EVENT-DESC should contain one base event type (a character or symbol) | 6651 | EVENT-DESC should contain one base event type (a character or symbol) |
| 6631 | and zero or more modifier names (control, meta, hyper, super, shift, alt, | 6652 | and zero or more modifier names (control, meta, hyper, super, shift, alt, |
| 6632 | drag, down, double or triple). The base must be last. | 6653 | drag, down, double or triple). The base must be last. |
| 6633 | The return value is an event type (a character or symbol) which | 6654 | |
| 6634 | has the same base event type and all the specified modifiers. */) | 6655 | The return value is an event type (a character or symbol) which has |
| 6656 | essentially the same base event type and all the specified modifiers. | ||
| 6657 | (Some compatibility base types, like symbols that represent a | ||
| 6658 | character, are not returned verbatim.) */) | ||
| 6635 | (Lisp_Object event_desc) | 6659 | (Lisp_Object event_desc) |
| 6636 | { | 6660 | { |
| 6637 | Lisp_Object base = Qnil; | 6661 | Lisp_Object base = Qnil; |
| @@ -7618,7 +7642,7 @@ menu_item_eval_property_1 (Lisp_Object arg) | |||
| 7618 | { | 7642 | { |
| 7619 | /* If we got a quit from within the menu computation, | 7643 | /* If we got a quit from within the menu computation, |
| 7620 | quit all the way out of it. This takes care of C-] in the debugger. */ | 7644 | quit all the way out of it. This takes care of C-] in the debugger. */ |
| 7621 | if (CONSP (arg) && EQ (XCAR (arg), Qquit)) | 7645 | if (CONSP (arg) && signal_quit_p (XCAR (arg))) |
| 7622 | quit (); | 7646 | quit (); |
| 7623 | 7647 | ||
| 7624 | return Qnil; | 7648 | return Qnil; |
| @@ -9603,17 +9627,23 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt, | |||
| 9603 | (interrupted_kboard, | 9627 | (interrupted_kboard, |
| 9604 | Fcons (make_lispy_switch_frame (frame), | 9628 | Fcons (make_lispy_switch_frame (frame), |
| 9605 | KVAR (interrupted_kboard, kbd_queue))); | 9629 | KVAR (interrupted_kboard, kbd_queue))); |
| 9630 | mock_input = 0; | ||
| 9631 | } | ||
| 9632 | else | ||
| 9633 | { | ||
| 9634 | if (FIXNUMP (key) && XFIXNUM (key) != -2) | ||
| 9635 | { | ||
| 9636 | /* If interrupted while initializing terminal, we | ||
| 9637 | need to replay the interrupting key. See | ||
| 9638 | Bug#5095 and Bug#37782. */ | ||
| 9639 | mock_input = 1; | ||
| 9640 | keybuf[0] = key; | ||
| 9641 | } | ||
| 9642 | else | ||
| 9643 | { | ||
| 9644 | mock_input = 0; | ||
| 9645 | } | ||
| 9606 | } | 9646 | } |
| 9607 | if (FIXNUMP (key) && XFIXNUM (key) != -2) | ||
| 9608 | { | ||
| 9609 | /* If interrupted while initializing terminal, we | ||
| 9610 | need to replay the interrupting key. See | ||
| 9611 | Bug#5095 and Bug#37782. */ | ||
| 9612 | mock_input = 1; | ||
| 9613 | keybuf[0] = key; | ||
| 9614 | } | ||
| 9615 | else | ||
| 9616 | mock_input = 0; | ||
| 9617 | goto replay_entire_sequence; | 9647 | goto replay_entire_sequence; |
| 9618 | } | 9648 | } |
| 9619 | } | 9649 | } |
diff --git a/src/lisp.h b/src/lisp.h index 1795b9d811b..15a42a44562 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3586,6 +3586,7 @@ extern Lisp_Object detect_coding_system (const unsigned char *, ptrdiff_t, | |||
| 3586 | extern void init_coding (void); | 3586 | extern void init_coding (void); |
| 3587 | extern void init_coding_once (void); | 3587 | extern void init_coding_once (void); |
| 3588 | extern void syms_of_coding (void); | 3588 | extern void syms_of_coding (void); |
| 3589 | extern bool string_ascii_p (Lisp_Object); | ||
| 3589 | 3590 | ||
| 3590 | /* Defined in character.c. */ | 3591 | /* Defined in character.c. */ |
| 3591 | extern ptrdiff_t chars_in_text (const unsigned char *, ptrdiff_t); | 3592 | extern ptrdiff_t chars_in_text (const unsigned char *, ptrdiff_t); |
| @@ -4116,6 +4117,7 @@ extern Lisp_Object Vautoload_queue; | |||
| 4116 | extern Lisp_Object Vrun_hooks; | 4117 | extern Lisp_Object Vrun_hooks; |
| 4117 | extern Lisp_Object Vsignaling_function; | 4118 | extern Lisp_Object Vsignaling_function; |
| 4118 | extern Lisp_Object inhibit_lisp_code; | 4119 | extern Lisp_Object inhibit_lisp_code; |
| 4120 | extern bool signal_quit_p (Lisp_Object); | ||
| 4119 | 4121 | ||
| 4120 | /* To run a normal hook, use the appropriate function from the list below. | 4122 | /* To run a normal hook, use the appropriate function from the list below. |
| 4121 | The calling convention: | 4123 | The calling convention: |
| @@ -4417,7 +4419,7 @@ extern bool detect_input_pending_ignore_squeezables (void); | |||
| 4417 | extern bool detect_input_pending_run_timers (bool); | 4419 | extern bool detect_input_pending_run_timers (bool); |
| 4418 | extern void safe_run_hooks (Lisp_Object); | 4420 | extern void safe_run_hooks (Lisp_Object); |
| 4419 | extern void cmd_error_internal (Lisp_Object, const char *); | 4421 | extern void cmd_error_internal (Lisp_Object, const char *); |
| 4420 | extern Lisp_Object command_loop_1 (void); | 4422 | extern Lisp_Object command_loop_2 (Lisp_Object); |
| 4421 | extern Lisp_Object read_menu_command (void); | 4423 | extern Lisp_Object read_menu_command (void); |
| 4422 | extern Lisp_Object recursive_edit_1 (void); | 4424 | extern Lisp_Object recursive_edit_1 (void); |
| 4423 | extern void record_auto_save (void); | 4425 | extern void record_auto_save (void); |
diff --git a/src/macros.c b/src/macros.c index 60d0766a754..0752a5bb6f6 100644 --- a/src/macros.c +++ b/src/macros.c | |||
| @@ -324,7 +324,7 @@ buffer before the macro is executed. */) | |||
| 324 | break; | 324 | break; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | command_loop_1 (); | 327 | command_loop_2 (list1 (Qminibuffer_quit)); |
| 328 | 328 | ||
| 329 | executing_kbd_macro_iterations = ++success_count; | 329 | executing_kbd_macro_iterations = ++success_count; |
| 330 | 330 | ||
diff --git a/src/minibuf.c b/src/minibuf.c index 1b842b77211..0f4349e70b8 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -496,7 +496,7 @@ confirm the aborting of the current minibuffer and all contained ones. */) | |||
| 496 | } | 496 | } |
| 497 | } | 497 | } |
| 498 | else | 498 | else |
| 499 | Fthrow (Qexit, Qt); | 499 | CALLN (Ffuncall, intern ("minibuffer-quit-recursive-edit")); |
| 500 | return Qnil; | 500 | return Qnil; |
| 501 | } | 501 | } |
| 502 | 502 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 34e46407d99..b81b27469d0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -4557,11 +4557,13 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4557 | ptrdiff_t bufpos, charpos; | 4557 | ptrdiff_t bufpos, charpos; |
| 4558 | int base_face_id; | 4558 | int base_face_id; |
| 4559 | 4559 | ||
| 4560 | /* No face change past the end of the string (for the case | 4560 | /* No face change past the end of the string (for the case we |
| 4561 | we are padding with spaces). No face change before the | 4561 | are padding with spaces). No face change before the string |
| 4562 | string start. */ | 4562 | start. Ignore face changes before the first visible |
| 4563 | character on this display line. */ | ||
| 4563 | if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string) | 4564 | if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string) |
| 4564 | || (IT_STRING_CHARPOS (*it) == 0 && before_p)) | 4565 | || (IT_STRING_CHARPOS (*it) == 0 && before_p) |
| 4566 | || it->current_x <= it->first_visible_x) | ||
| 4565 | return it->face_id; | 4567 | return it->face_id; |
| 4566 | 4568 | ||
| 4567 | if (!it->bidi_p) | 4569 | if (!it->bidi_p) |
| @@ -4580,51 +4582,47 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4580 | } | 4582 | } |
| 4581 | else | 4583 | else |
| 4582 | { | 4584 | { |
| 4583 | if (before_p) | 4585 | /* With bidi iteration, the character before the current in |
| 4584 | { | 4586 | the visual order cannot be found by simple iteration, |
| 4585 | /* With bidi iteration, the character before the current | 4587 | because "reverse" reordering is not supported. Instead, |
| 4586 | in the visual order cannot be found by simple | 4588 | we need to start from the string beginning and go all the |
| 4587 | iteration, because "reverse" reordering is not | 4589 | way to the current string position, remembering the |
| 4588 | supported. Instead, we need to start from the string | 4590 | visually-previous position. We need to start from the |
| 4589 | beginning and go all the way to the current string | 4591 | string beginning for the character after the current as |
| 4590 | position, remembering the previous position. */ | 4592 | well, since the iterator state in IT may have been |
| 4591 | /* Ignore face changes before the first visible | 4593 | pushed, and the bidi cache is no longer coherent with the |
| 4592 | character on this display line. */ | 4594 | string's text. */ |
| 4593 | if (it->current_x <= it->first_visible_x) | 4595 | SAVE_IT (it_copy, *it, it_copy_data); |
| 4594 | return it->face_id; | 4596 | IT_STRING_CHARPOS (it_copy) = 0; |
| 4595 | SAVE_IT (it_copy, *it, it_copy_data); | 4597 | bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it); |
| 4596 | IT_STRING_CHARPOS (it_copy) = 0; | ||
| 4597 | bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it); | ||
| 4598 | |||
| 4599 | do | ||
| 4600 | { | ||
| 4601 | charpos = IT_STRING_CHARPOS (it_copy); | ||
| 4602 | if (charpos >= SCHARS (it->string)) | ||
| 4603 | break; | ||
| 4604 | bidi_move_to_visually_next (&it_copy.bidi_it); | ||
| 4605 | } | ||
| 4606 | while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it)); | ||
| 4607 | 4598 | ||
| 4608 | RESTORE_IT (it, it, it_copy_data); | 4599 | do |
| 4600 | { | ||
| 4601 | charpos = it_copy.bidi_it.charpos; | ||
| 4602 | if (charpos >= SCHARS (it->string)) | ||
| 4603 | break; | ||
| 4604 | bidi_move_to_visually_next (&it_copy.bidi_it); | ||
| 4609 | } | 4605 | } |
| 4610 | else | 4606 | while (it_copy.bidi_it.charpos != IT_STRING_CHARPOS (*it)); |
| 4607 | |||
| 4608 | if (!before_p) | ||
| 4611 | { | 4609 | { |
| 4612 | /* Set charpos to the string position of the character | 4610 | /* Set charpos to the string position of the character |
| 4613 | that comes after IT's current position in the visual | 4611 | that comes after IT's current position in the visual |
| 4614 | order. */ | 4612 | order. */ |
| 4615 | int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1); | 4613 | int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1); |
| 4616 | 4614 | /* If this is the first string character, | |
| 4617 | it_copy = *it; | ||
| 4618 | /* If this is the first display element, | ||
| 4619 | bidi_move_to_visually_next will deliver character at | 4615 | bidi_move_to_visually_next will deliver character at |
| 4620 | current position without moving, so we need to enlarge N. */ | 4616 | current position without moving, so we need to enlarge N. */ |
| 4621 | if (it->bidi_it.first_elt) | 4617 | if (it_copy.bidi_it.first_elt) |
| 4622 | n++; | 4618 | n++; |
| 4623 | while (n--) | 4619 | while (n--) |
| 4624 | bidi_move_to_visually_next (&it_copy.bidi_it); | 4620 | bidi_move_to_visually_next (&it_copy.bidi_it); |
| 4625 | 4621 | ||
| 4626 | charpos = it_copy.bidi_it.charpos; | 4622 | charpos = it_copy.bidi_it.charpos; |
| 4627 | } | 4623 | } |
| 4624 | |||
| 4625 | RESTORE_IT (it, it, it_copy_data); | ||
| 4628 | } | 4626 | } |
| 4629 | eassert (0 <= charpos && charpos <= SCHARS (it->string)); | 4627 | eassert (0 <= charpos && charpos <= SCHARS (it->string)); |
| 4630 | 4628 | ||
| @@ -22765,6 +22763,22 @@ get_it_property (struct it *it, Lisp_Object prop) | |||
| 22765 | return Fget_char_property (position, prop, object); | 22763 | return Fget_char_property (position, prop, object); |
| 22766 | } | 22764 | } |
| 22767 | 22765 | ||
| 22766 | /* Return the line-prefix/wrap-prefix property, checking both the | ||
| 22767 | current IT->OBJECT and the underlying buffer text. */ | ||
| 22768 | |||
| 22769 | static Lisp_Object | ||
| 22770 | get_line_prefix_it_property (struct it *it, Lisp_Object prop) | ||
| 22771 | { | ||
| 22772 | Lisp_Object prefix = get_it_property (it, prop); | ||
| 22773 | |||
| 22774 | /* If we are looking at a display or overlay string, check also the | ||
| 22775 | underlying buffer text. */ | ||
| 22776 | if (NILP (prefix) && it->sp > 0 && STRINGP (it->object)) | ||
| 22777 | return Fget_char_property (make_fixnum (IT_CHARPOS (*it)), prop, | ||
| 22778 | it->w->contents); | ||
| 22779 | return prefix; | ||
| 22780 | } | ||
| 22781 | |||
| 22768 | /* See if there's a line- or wrap-prefix, and if so, push it on IT. */ | 22782 | /* See if there's a line- or wrap-prefix, and if so, push it on IT. */ |
| 22769 | 22783 | ||
| 22770 | static void | 22784 | static void |
| @@ -22774,13 +22788,13 @@ handle_line_prefix (struct it *it) | |||
| 22774 | 22788 | ||
| 22775 | if (it->continuation_lines_width > 0) | 22789 | if (it->continuation_lines_width > 0) |
| 22776 | { | 22790 | { |
| 22777 | prefix = get_it_property (it, Qwrap_prefix); | 22791 | prefix = get_line_prefix_it_property (it, Qwrap_prefix); |
| 22778 | if (NILP (prefix)) | 22792 | if (NILP (prefix)) |
| 22779 | prefix = Vwrap_prefix; | 22793 | prefix = Vwrap_prefix; |
| 22780 | } | 22794 | } |
| 22781 | else | 22795 | else |
| 22782 | { | 22796 | { |
| 22783 | prefix = get_it_property (it, Qline_prefix); | 22797 | prefix = get_line_prefix_it_property (it, Qline_prefix); |
| 22784 | if (NILP (prefix)) | 22798 | if (NILP (prefix)) |
| 22785 | prefix = Vline_prefix; | 22799 | prefix = Vline_prefix; |
| 22786 | } | 22800 | } |
diff --git a/src/xfaces.c b/src/xfaces.c index 2bd2f4be4a9..37ad11b713c 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -95,9 +95,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 95 | with the symbol `face' in slot 0, and a slot for each of the face | 95 | with the symbol `face' in slot 0, and a slot for each of the face |
| 96 | attributes mentioned above. | 96 | attributes mentioned above. |
| 97 | 97 | ||
| 98 | There is also a global face alist `Vface_new_frame_defaults'. Face | 98 | There is also a global face map `Vface_new_frame_defaults', |
| 99 | definitions from this list are used to initialize faces of newly | 99 | containing conses of (FACE_ID . FACE_DEFINITION). Face definitions |
| 100 | created frames. | 100 | from this table are used to initialize faces of newly created |
| 101 | frames. | ||
| 101 | 102 | ||
| 102 | A face doesn't have to specify all attributes. Those not specified | 103 | A face doesn't have to specify all attributes. Those not specified |
| 103 | have a value of `unspecified'. Faces specifying all attributes but | 104 | have a value of `unspecified'. Faces specifying all attributes but |
| @@ -1989,13 +1990,11 @@ lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name, | |||
| 1989 | Lisp_Object lface; | 1990 | Lisp_Object lface; |
| 1990 | 1991 | ||
| 1991 | if (f) | 1992 | if (f) |
| 1992 | lface = assq_no_quit (face_name, f->face_alist); | 1993 | lface = Fgethash (face_name, f->face_hash_table, Qnil); |
| 1993 | else | 1994 | else |
| 1994 | lface = assq_no_quit (face_name, Vface_new_frame_defaults); | 1995 | lface = CDR (Fgethash (face_name, Vface_new_frame_defaults, Qnil)); |
| 1995 | 1996 | ||
| 1996 | if (CONSP (lface)) | 1997 | if (signal_p && NILP (lface)) |
| 1997 | lface = XCDR (lface); | ||
| 1998 | else if (signal_p) | ||
| 1999 | signal_error ("Invalid face", face_name); | 1998 | signal_error ("Invalid face", face_name); |
| 2000 | 1999 | ||
| 2001 | check_lface (lface); | 2000 | check_lface (lface); |
| @@ -2894,11 +2893,6 @@ Value is a vector of face attributes. */) | |||
| 2894 | /* Add a global definition if there is none. */ | 2893 | /* Add a global definition if there is none. */ |
| 2895 | if (NILP (global_lface)) | 2894 | if (NILP (global_lface)) |
| 2896 | { | 2895 | { |
| 2897 | global_lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); | ||
| 2898 | ASET (global_lface, 0, Qface); | ||
| 2899 | Vface_new_frame_defaults = Fcons (Fcons (face, global_lface), | ||
| 2900 | Vface_new_frame_defaults); | ||
| 2901 | |||
| 2902 | /* Assign the new Lisp face a unique ID. The mapping from Lisp | 2896 | /* Assign the new Lisp face a unique ID. The mapping from Lisp |
| 2903 | face id to Lisp face is given by the vector lface_id_to_name. | 2897 | face id to Lisp face is given by the vector lface_id_to_name. |
| 2904 | The mapping from Lisp face to Lisp face id is given by the | 2898 | The mapping from Lisp face to Lisp face id is given by the |
| @@ -2908,9 +2902,14 @@ Value is a vector of face attributes. */) | |||
| 2908 | xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, MAX_FACE_ID, | 2902 | xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, MAX_FACE_ID, |
| 2909 | sizeof *lface_id_to_name); | 2903 | sizeof *lface_id_to_name); |
| 2910 | 2904 | ||
| 2905 | Lisp_Object face_id = make_fixnum (next_lface_id); | ||
| 2911 | lface_id_to_name[next_lface_id] = face; | 2906 | lface_id_to_name[next_lface_id] = face; |
| 2912 | Fput (face, Qface, make_fixnum (next_lface_id)); | 2907 | Fput (face, Qface, face_id); |
| 2913 | ++next_lface_id; | 2908 | ++next_lface_id; |
| 2909 | |||
| 2910 | global_lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); | ||
| 2911 | ASET (global_lface, 0, Qface); | ||
| 2912 | Fputhash (face, Fcons (face_id, global_lface), Vface_new_frame_defaults); | ||
| 2914 | } | 2913 | } |
| 2915 | else if (f == NULL) | 2914 | else if (f == NULL) |
| 2916 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) | 2915 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
| @@ -2923,7 +2922,7 @@ Value is a vector of face attributes. */) | |||
| 2923 | { | 2922 | { |
| 2924 | lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); | 2923 | lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); |
| 2925 | ASET (lface, 0, Qface); | 2924 | ASET (lface, 0, Qface); |
| 2926 | fset_face_alist (f, Fcons (Fcons (face, lface), f->face_alist)); | 2925 | Fputhash (face, lface, f->face_hash_table); |
| 2927 | } | 2926 | } |
| 2928 | else | 2927 | else |
| 2929 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) | 2928 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
| @@ -3084,7 +3083,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3084 | f = NULL; | 3083 | f = NULL; |
| 3085 | lface = lface_from_face_name (NULL, face, true); | 3084 | lface = lface_from_face_name (NULL, face, true); |
| 3086 | 3085 | ||
| 3087 | /* When updating face-new-frame-defaults, we put :ignore-defface | 3086 | /* When updating face--new-frame-defaults, we put :ignore-defface |
| 3088 | where the caller wants `unspecified'. This forces the frame | 3087 | where the caller wants `unspecified'. This forces the frame |
| 3089 | defaults to ignore the defface value. Otherwise, the defface | 3088 | defaults to ignore the defface value. Otherwise, the defface |
| 3090 | will take effect, which is generally not what is intended. | 3089 | will take effect, which is generally not what is intended. |
| @@ -3669,7 +3668,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param, | |||
| 3669 | /* If there are no faces yet, give up. This is the case when called | 3668 | /* If there are no faces yet, give up. This is the case when called |
| 3670 | from Fx_create_frame, and we do the necessary things later in | 3669 | from Fx_create_frame, and we do the necessary things later in |
| 3671 | face-set-after-frame-defaults. */ | 3670 | face-set-after-frame-defaults. */ |
| 3672 | if (NILP (f->face_alist)) | 3671 | if (XFIXNAT (Fhash_table_count (f->face_hash_table)) == 0) |
| 3673 | return; | 3672 | return; |
| 3674 | 3673 | ||
| 3675 | if (EQ (param, Qforeground_color)) | 3674 | if (EQ (param, Qforeground_color)) |
| @@ -4335,14 +4334,13 @@ If FRAME is omitted or nil, use the selected frame. */) | |||
| 4335 | return i == LFACE_VECTOR_SIZE ? Qt : Qnil; | 4334 | return i == LFACE_VECTOR_SIZE ? Qt : Qnil; |
| 4336 | } | 4335 | } |
| 4337 | 4336 | ||
| 4338 | 4337 | DEFUN ("frame--face-hash-table", Fframe_face_hash_table, Sframe_face_hash_table, | |
| 4339 | DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, | ||
| 4340 | 0, 1, 0, | 4338 | 0, 1, 0, |
| 4341 | doc: /* Return an alist of frame-local faces defined on FRAME. | 4339 | doc: /* Return a hash table of frame-local faces defined on FRAME. |
| 4342 | For internal use only. */) | 4340 | For internal use only. */) |
| 4343 | (Lisp_Object frame) | 4341 | (Lisp_Object frame) |
| 4344 | { | 4342 | { |
| 4345 | return decode_live_frame (frame)->face_alist; | 4343 | return decode_live_frame (frame)->face_hash_table; |
| 4346 | } | 4344 | } |
| 4347 | 4345 | ||
| 4348 | 4346 | ||
| @@ -6859,30 +6857,32 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources, | |||
| 6859 | 6857 | ||
| 6860 | #ifdef HAVE_PDUMPER | 6858 | #ifdef HAVE_PDUMPER |
| 6861 | /* All the faces defined during loadup are recorded in | 6859 | /* All the faces defined during loadup are recorded in |
| 6862 | face-new-frame-defaults, with the last face first in the list. We | 6860 | face-new-frame-defaults. We need to set next_lface_id to the next |
| 6863 | need to set next_lface_id to the next face ID number, so that any | 6861 | face ID number, so that any new faces defined in this session will |
| 6864 | new faces defined in this session will have face IDs different from | 6862 | have face IDs different from those defined during loadup. We also |
| 6865 | those defined during loadup. We also need to set up the | 6863 | need to set up the lface_id_to_name[] array for the faces that were |
| 6866 | lface_id_to_name[] array for the faces that were defined during | 6864 | defined during loadup. */ |
| 6867 | loadup. */ | ||
| 6868 | void | 6865 | void |
| 6869 | init_xfaces (void) | 6866 | init_xfaces (void) |
| 6870 | { | 6867 | { |
| 6871 | if (CONSP (Vface_new_frame_defaults)) | 6868 | int nfaces = XFIXNAT (Fhash_table_count (Vface_new_frame_defaults)); |
| 6869 | if (nfaces > 0) | ||
| 6872 | { | 6870 | { |
| 6873 | /* Allocate the lface_id_to_name[] array. */ | 6871 | /* Allocate the lface_id_to_name[] array. */ |
| 6874 | lface_id_to_name_size = next_lface_id = | 6872 | lface_id_to_name_size = next_lface_id = nfaces; |
| 6875 | XFIXNAT (Flength (Vface_new_frame_defaults)); | ||
| 6876 | lface_id_to_name = xnmalloc (next_lface_id, sizeof *lface_id_to_name); | 6873 | lface_id_to_name = xnmalloc (next_lface_id, sizeof *lface_id_to_name); |
| 6877 | 6874 | ||
| 6878 | /* Store the faces. */ | 6875 | /* Store the faces. */ |
| 6879 | Lisp_Object tail; | 6876 | struct Lisp_Hash_Table* table = XHASH_TABLE (Vface_new_frame_defaults); |
| 6880 | int i = next_lface_id - 1; | 6877 | for (ptrdiff_t idx = 0; idx < nfaces; ++idx) |
| 6881 | for (tail = Vface_new_frame_defaults; CONSP (tail); tail = XCDR (tail)) | ||
| 6882 | { | 6878 | { |
| 6883 | Lisp_Object lface = XCAR (tail); | 6879 | Lisp_Object lface = HASH_KEY (table, idx); |
| 6884 | eassert (i >= 0); | 6880 | Lisp_Object face_id = CAR (HASH_VALUE (table, idx)); |
| 6885 | lface_id_to_name[i--] = XCAR (lface); | 6881 | if (FIXNATP (face_id)) { |
| 6882 | int id = XFIXNAT (face_id); | ||
| 6883 | eassert (id >= 0); | ||
| 6884 | lface_id_to_name[id] = lface; | ||
| 6885 | } | ||
| 6886 | } | 6886 | } |
| 6887 | } | 6887 | } |
| 6888 | face_attr_sym[0] = Qface; | 6888 | face_attr_sym[0] = Qface; |
| @@ -7038,7 +7038,7 @@ syms_of_xfaces (void) | |||
| 7038 | defsubr (&Sinternal_copy_lisp_face); | 7038 | defsubr (&Sinternal_copy_lisp_face); |
| 7039 | defsubr (&Sinternal_merge_in_global_face); | 7039 | defsubr (&Sinternal_merge_in_global_face); |
| 7040 | defsubr (&Sface_font); | 7040 | defsubr (&Sface_font); |
| 7041 | defsubr (&Sframe_face_alist); | 7041 | defsubr (&Sframe_face_hash_table); |
| 7042 | defsubr (&Sdisplay_supports_face_attributes_p); | 7042 | defsubr (&Sdisplay_supports_face_attributes_p); |
| 7043 | defsubr (&Scolor_distance); | 7043 | defsubr (&Scolor_distance); |
| 7044 | defsubr (&Sinternal_set_font_selection_order); | 7044 | defsubr (&Sinternal_set_font_selection_order); |
| @@ -7062,9 +7062,12 @@ This variable is intended for use only by code that evaluates | |||
| 7062 | the "specifity" of a face specification and should be let-bound | 7062 | the "specifity" of a face specification and should be let-bound |
| 7063 | only for this purpose. */); | 7063 | only for this purpose. */); |
| 7064 | 7064 | ||
| 7065 | DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults, | 7065 | DEFVAR_LISP ("face--new-frame-defaults", Vface_new_frame_defaults, |
| 7066 | doc: /* List of global face definitions (for internal use only.) */); | 7066 | doc: /* Hash table of global face definitions (for internal use only.) */); |
| 7067 | Vface_new_frame_defaults = Qnil; | 7067 | Vface_new_frame_defaults = |
| 7068 | /* 33 entries is enough to fit all basic faces */ | ||
| 7069 | make_hash_table (hashtest_eq, 33, DEFAULT_REHASH_SIZE, | ||
| 7070 | DEFAULT_REHASH_THRESHOLD, Qnil, false); | ||
| 7068 | 7071 | ||
| 7069 | DEFVAR_LISP ("face-default-stipple", Vface_default_stipple, | 7072 | DEFVAR_LISP ("face-default-stipple", Vface_default_stipple, |
| 7070 | doc: /* Default stipple pattern used on monochrome displays. | 7073 | doc: /* Default stipple pattern used on monochrome displays. |
diff --git a/src/xftfont.c b/src/xftfont.c index f7349316366..d8ad4035481 100644 --- a/src/xftfont.c +++ b/src/xftfont.c | |||
| @@ -33,6 +33,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 33 | #include "ftfont.h" | 33 | #include "ftfont.h" |
| 34 | #include "pdumper.h" | 34 | #include "pdumper.h" |
| 35 | 35 | ||
| 36 | #ifndef FC_LCD_FILTER | ||
| 37 | /* Older fontconfig versions don't have FC_LCD_FILTER. */ | ||
| 38 | # define FC_LCD_FILTER "lcdfilter" | ||
| 39 | #endif | ||
| 40 | |||
| 41 | |||
| 36 | /* Xft font driver. */ | 42 | /* Xft font driver. */ |
| 37 | 43 | ||
| 38 | /* Structure pointed by (struct face *)->extra */ | 44 | /* Structure pointed by (struct face *)->extra */ |