diff options
| author | Andrea Corallo | 2021-01-16 13:26:10 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2021-01-16 13:26:10 +0100 |
| commit | 0a7ac0b5504e75275699a3d8d2d5d94bcfda8708 (patch) | |
| tree | bb6158c8a9edeb1e716718abfc98dca16aef9e9e /src | |
| parent | f1efac1f9efbfa15b6434ebef507c00c1277633f (diff) | |
| parent | 0732fc31932c75c682c8b65b4dcb4376ca63e8fd (diff) | |
| download | emacs-0a7ac0b5504e75275699a3d8d2d5d94bcfda8708.tar.gz emacs-0a7ac0b5504e75275699a3d8d2d5d94bcfda8708.zip | |
Merge remote-tracking branch 'savannah/master' into native-comp
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 2 | ||||
| -rw-r--r-- | src/callproc.c | 33 | ||||
| -rw-r--r-- | src/data.c | 3 | ||||
| -rw-r--r-- | src/dispnew.c | 16 | ||||
| -rw-r--r-- | src/emacs.c | 4 | ||||
| -rw-r--r-- | src/eval.c | 26 | ||||
| -rw-r--r-- | src/fns.c | 85 | ||||
| -rw-r--r-- | src/keymap.c | 35 | ||||
| -rw-r--r-- | src/lisp.h | 8 | ||||
| -rw-r--r-- | src/lread.c | 29 | ||||
| -rw-r--r-- | src/minibuf.c | 211 | ||||
| -rw-r--r-- | src/pdumper.c | 2 | ||||
| -rw-r--r-- | src/process.c | 13 | ||||
| -rw-r--r-- | src/sysdep.c | 217 | ||||
| -rw-r--r-- | src/w32term.c | 3 | ||||
| -rw-r--r-- | src/window.c | 5 | ||||
| -rw-r--r-- | src/window.h | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 13 | ||||
| -rw-r--r-- | src/xfaces.c | 8 |
19 files changed, 619 insertions, 98 deletions
diff --git a/src/buffer.c b/src/buffer.c index 71ad5edd527..80c799e719b 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -4785,7 +4785,7 @@ mmap_init (void) | |||
| 4785 | if (mmap_fd <= 0) | 4785 | if (mmap_fd <= 0) |
| 4786 | { | 4786 | { |
| 4787 | /* No anonymous mmap -- we need the file descriptor. */ | 4787 | /* No anonymous mmap -- we need the file descriptor. */ |
| 4788 | mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); | 4788 | mmap_fd = emacs_open_noquit ("/dev/zero", O_RDONLY, 0); |
| 4789 | if (mmap_fd == -1) | 4789 | if (mmap_fd == -1) |
| 4790 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); | 4790 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); |
| 4791 | } | 4791 | } |
diff --git a/src/callproc.c b/src/callproc.c index 8d2a5619eb8..cb72b070b7b 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -314,6 +314,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 314 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 314 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 315 | char *tempfile = NULL; | 315 | char *tempfile = NULL; |
| 316 | #else | 316 | #else |
| 317 | sigset_t oldset; | ||
| 317 | pid_t pid = -1; | 318 | pid_t pid = -1; |
| 318 | #endif | 319 | #endif |
| 319 | int child_errno; | 320 | int child_errno; |
| @@ -601,9 +602,12 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 601 | 602 | ||
| 602 | #ifndef MSDOS | 603 | #ifndef MSDOS |
| 603 | 604 | ||
| 605 | block_input (); | ||
| 606 | block_child_signal (&oldset); | ||
| 607 | |||
| 604 | child_errno | 608 | child_errno |
| 605 | = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, | 609 | = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, |
| 606 | SSDATA (current_dir), NULL); | 610 | SSDATA (current_dir), NULL, &oldset); |
| 607 | eassert ((child_errno == 0) == (0 < pid)); | 611 | eassert ((child_errno == 0) == (0 < pid)); |
| 608 | 612 | ||
| 609 | if (pid > 0) | 613 | if (pid > 0) |
| @@ -624,6 +628,9 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 624 | } | 628 | } |
| 625 | } | 629 | } |
| 626 | 630 | ||
| 631 | unblock_child_signal (&oldset); | ||
| 632 | unblock_input (); | ||
| 633 | |||
| 627 | if (pid < 0) | 634 | if (pid < 0) |
| 628 | report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno); | 635 | report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno); |
| 629 | 636 | ||
| @@ -1227,17 +1234,21 @@ child_setup (int in, int out, int err, char **new_argv, char **env, | |||
| 1227 | process image file ARGV[0]. Use ENVP for the environment block for | 1234 | process image file ARGV[0]. Use ENVP for the environment block for |
| 1228 | the new process. Use CWD as working directory for the new process. | 1235 | the new process. Use CWD as working directory for the new process. |
| 1229 | If PTY is not NULL, it must be a pseudoterminal device. If PTY is | 1236 | If PTY is not NULL, it must be a pseudoterminal device. If PTY is |
| 1230 | NULL, don't perform any terminal setup. */ | 1237 | NULL, don't perform any terminal setup. OLDSET must be a pointer |
| 1238 | to a signal set initialized by `block_child_signal'. Before | ||
| 1239 | calling this function, call `block_input' and `block_child_signal'; | ||
| 1240 | afterwards, call `unblock_input' and `unblock_child_signal'. Be | ||
| 1241 | sure to call `unblock_child_signal' only after registering NEWPID | ||
| 1242 | in a list where `handle_child_signal' can find it! */ | ||
| 1231 | 1243 | ||
| 1232 | int | 1244 | int |
| 1233 | emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | 1245 | emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, |
| 1234 | char **argv, char **envp, const char *cwd, const char *pty) | 1246 | char **argv, char **envp, const char *cwd, |
| 1247 | const char *pty, const sigset_t *oldset) | ||
| 1235 | { | 1248 | { |
| 1236 | sigset_t oldset; | ||
| 1237 | int pid; | 1249 | int pid; |
| 1238 | 1250 | ||
| 1239 | block_input (); | 1251 | eassert (input_blocked_p ()); |
| 1240 | block_child_signal (&oldset); | ||
| 1241 | 1252 | ||
| 1242 | #ifndef WINDOWSNT | 1253 | #ifndef WINDOWSNT |
| 1243 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1254 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| @@ -1249,6 +1260,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1249 | int volatile stdout_volatile = std_out; | 1260 | int volatile stdout_volatile = std_out; |
| 1250 | int volatile stderr_volatile = std_err; | 1261 | int volatile stderr_volatile = std_err; |
| 1251 | char **volatile envp_volatile = envp; | 1262 | char **volatile envp_volatile = envp; |
| 1263 | const sigset_t *volatile oldset_volatile = oldset; | ||
| 1252 | 1264 | ||
| 1253 | #ifdef DARWIN_OS | 1265 | #ifdef DARWIN_OS |
| 1254 | /* Darwin doesn't let us run setsid after a vfork, so use fork when | 1266 | /* Darwin doesn't let us run setsid after a vfork, so use fork when |
| @@ -1270,6 +1282,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1270 | std_out = stdout_volatile; | 1282 | std_out = stdout_volatile; |
| 1271 | std_err = stderr_volatile; | 1283 | std_err = stderr_volatile; |
| 1272 | envp = envp_volatile; | 1284 | envp = envp_volatile; |
| 1285 | oldset = oldset_volatile; | ||
| 1273 | 1286 | ||
| 1274 | if (pid == 0) | 1287 | if (pid == 0) |
| 1275 | #endif /* not WINDOWSNT */ | 1288 | #endif /* not WINDOWSNT */ |
| @@ -1323,7 +1336,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1323 | would work? */ | 1336 | would work? */ |
| 1324 | if (std_in >= 0) | 1337 | if (std_in >= 0) |
| 1325 | emacs_close (std_in); | 1338 | emacs_close (std_in); |
| 1326 | std_out = std_in = emacs_open (pty, O_RDWR, 0); | 1339 | std_out = std_in = emacs_open_noquit (pty, O_RDWR, 0); |
| 1327 | 1340 | ||
| 1328 | if (std_in < 0) | 1341 | if (std_in < 0) |
| 1329 | { | 1342 | { |
| @@ -1364,7 +1377,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1364 | #endif | 1377 | #endif |
| 1365 | 1378 | ||
| 1366 | /* Stop blocking SIGCHLD in the child. */ | 1379 | /* Stop blocking SIGCHLD in the child. */ |
| 1367 | unblock_child_signal (&oldset); | 1380 | unblock_child_signal (oldset); |
| 1368 | 1381 | ||
| 1369 | if (pty_flag) | 1382 | if (pty_flag) |
| 1370 | child_setup_tty (std_out); | 1383 | child_setup_tty (std_out); |
| @@ -1382,10 +1395,6 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1382 | 1395 | ||
| 1383 | int vfork_error = pid < 0 ? errno : 0; | 1396 | int vfork_error = pid < 0 ? errno : 0; |
| 1384 | 1397 | ||
| 1385 | /* Stop blocking in the parent. */ | ||
| 1386 | unblock_child_signal (&oldset); | ||
| 1387 | unblock_input (); | ||
| 1388 | |||
| 1389 | if (pid < 0) | 1398 | if (pid < 0) |
| 1390 | { | 1399 | { |
| 1391 | eassert (0 < vfork_error); | 1400 | eassert (0 < vfork_error); |
diff --git a/src/data.c b/src/data.c index 3cf5bbbdd56..0dc21c8c2a1 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -3834,6 +3834,7 @@ syms_of_data (void) | |||
| 3834 | DEFSYM (Qbuffer_read_only, "buffer-read-only"); | 3834 | DEFSYM (Qbuffer_read_only, "buffer-read-only"); |
| 3835 | DEFSYM (Qtext_read_only, "text-read-only"); | 3835 | DEFSYM (Qtext_read_only, "text-read-only"); |
| 3836 | DEFSYM (Qmark_inactive, "mark-inactive"); | 3836 | DEFSYM (Qmark_inactive, "mark-inactive"); |
| 3837 | DEFSYM (Qinhibited_interaction, "inhibited-interaction"); | ||
| 3837 | 3838 | ||
| 3838 | DEFSYM (Qlistp, "listp"); | 3839 | DEFSYM (Qlistp, "listp"); |
| 3839 | DEFSYM (Qconsp, "consp"); | 3840 | DEFSYM (Qconsp, "consp"); |
| @@ -3918,6 +3919,8 @@ syms_of_data (void) | |||
| 3918 | PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only"); | 3919 | PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only"); |
| 3919 | PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail), | 3920 | PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail), |
| 3920 | "Text is read-only"); | 3921 | "Text is read-only"); |
| 3922 | PUT_ERROR (Qinhibited_interaction, error_tail, | ||
| 3923 | "User interaction while inhibited"); | ||
| 3921 | 3924 | ||
| 3922 | DEFSYM (Qrange_error, "range-error"); | 3925 | DEFSYM (Qrange_error, "range-error"); |
| 3923 | DEFSYM (Qdomain_error, "domain-error"); | 3926 | DEFSYM (Qdomain_error, "domain-error"); |
diff --git a/src/dispnew.c b/src/dispnew.c index 36a6dd8a091..e603c671363 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -6049,7 +6049,14 @@ additional wait period, in milliseconds; this is for backwards compatibility. | |||
| 6049 | READING is true if reading input. | 6049 | READING is true if reading input. |
| 6050 | If DISPLAY_OPTION is >0 display process output while waiting. | 6050 | If DISPLAY_OPTION is >0 display process output while waiting. |
| 6051 | If DISPLAY_OPTION is >1 perform an initial redisplay before waiting. | 6051 | If DISPLAY_OPTION is >1 perform an initial redisplay before waiting. |
| 6052 | */ | 6052 | |
| 6053 | Returns a boolean Qt if we waited the full time and returns Qnil if the | ||
| 6054 | wait was interrupted by incoming process output or keyboard events. | ||
| 6055 | |||
| 6056 | FIXME: When `wait_reading_process_output` returns early because of | ||
| 6057 | process output, instead of returning nil we should loop and wait some | ||
| 6058 | more (i.e. until either there's pending input events or the timeout | ||
| 6059 | expired). */ | ||
| 6053 | 6060 | ||
| 6054 | Lisp_Object | 6061 | Lisp_Object |
| 6055 | sit_for (Lisp_Object timeout, bool reading, int display_option) | 6062 | sit_for (Lisp_Object timeout, bool reading, int display_option) |
| @@ -6110,8 +6117,9 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) | |||
| 6110 | gobble_input (); | 6117 | gobble_input (); |
| 6111 | #endif | 6118 | #endif |
| 6112 | 6119 | ||
| 6113 | wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display, | 6120 | int nbytes |
| 6114 | Qnil, NULL, 0); | 6121 | = wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display, |
| 6122 | Qnil, NULL, 0); | ||
| 6115 | 6123 | ||
| 6116 | if (reading && curbuf_eq_winbuf) | 6124 | if (reading && curbuf_eq_winbuf) |
| 6117 | /* Timers and process filters/sentinels may have changed the selected | 6125 | /* Timers and process filters/sentinels may have changed the selected |
| @@ -6120,7 +6128,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) | |||
| 6120 | buffer to start with). */ | 6128 | buffer to start with). */ |
| 6121 | set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents)); | 6129 | set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents)); |
| 6122 | 6130 | ||
| 6123 | return detect_input_pending () ? Qnil : Qt; | 6131 | return (nbytes > 0 || detect_input_pending ()) ? Qnil : Qt; |
| 6124 | } | 6132 | } |
| 6125 | 6133 | ||
| 6126 | 6134 | ||
diff --git a/src/emacs.c b/src/emacs.c index 738ef12c98c..c6581bba37e 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1300,7 +1300,7 @@ main (int argc, char **argv) | |||
| 1300 | { | 1300 | { |
| 1301 | emacs_close (STDIN_FILENO); | 1301 | emacs_close (STDIN_FILENO); |
| 1302 | emacs_close (STDOUT_FILENO); | 1302 | emacs_close (STDOUT_FILENO); |
| 1303 | int result = emacs_open (term, O_RDWR, 0); | 1303 | int result = emacs_open_noquit (term, O_RDWR, 0); |
| 1304 | if (result != STDIN_FILENO | 1304 | if (result != STDIN_FILENO |
| 1305 | || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) | 1305 | || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) |
| 1306 | != STDOUT_FILENO)) | 1306 | != STDOUT_FILENO)) |
| @@ -2884,7 +2884,7 @@ from the parent process and its tty file descriptors. */) | |||
| 2884 | int nfd; | 2884 | int nfd; |
| 2885 | 2885 | ||
| 2886 | /* Get rid of stdin, stdout and stderr. */ | 2886 | /* Get rid of stdin, stdout and stderr. */ |
| 2887 | nfd = emacs_open ("/dev/null", O_RDWR, 0); | 2887 | nfd = emacs_open_noquit ("/dev/null", O_RDWR, 0); |
| 2888 | err |= nfd < 0; | 2888 | err |= nfd < 0; |
| 2889 | err |= dup2 (nfd, STDIN_FILENO) < 0; | 2889 | err |= dup2 (nfd, STDIN_FILENO) < 0; |
| 2890 | err |= dup2 (nfd, STDOUT_FILENO) < 0; | 2890 | err |= dup2 (nfd, STDOUT_FILENO) < 0; |
diff --git a/src/eval.c b/src/eval.c index f77f07e1711..cef9407dbfa 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1176,9 +1176,18 @@ Lisp_Object | |||
| 1176 | internal_catch (Lisp_Object tag, | 1176 | internal_catch (Lisp_Object tag, |
| 1177 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1177 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) |
| 1178 | { | 1178 | { |
| 1179 | /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by | ||
| 1180 | throwing t to tag `exit'. | ||
| 1181 | Value -1 means there is no (throw 'exit t) in progress; | ||
| 1182 | 0 means the `throw' wasn't done from an active minibuffer; | ||
| 1183 | N > 0 means the `throw' was done from the minibuffer at level N. */ | ||
| 1184 | static EMACS_INT minibuffer_quit_level = -1; | ||
| 1179 | /* This structure is made part of the chain `catchlist'. */ | 1185 | /* This structure is made part of the chain `catchlist'. */ |
| 1180 | struct handler *c = push_handler (tag, CATCHER); | 1186 | struct handler *c = push_handler (tag, CATCHER); |
| 1181 | 1187 | ||
| 1188 | if (EQ (tag, Qexit)) | ||
| 1189 | minibuffer_quit_level = -1; | ||
| 1190 | |||
| 1182 | /* Call FUNC. */ | 1191 | /* Call FUNC. */ |
| 1183 | if (! sys_setjmp (c->jmp)) | 1192 | if (! sys_setjmp (c->jmp)) |
| 1184 | { | 1193 | { |
| @@ -1192,6 +1201,23 @@ internal_catch (Lisp_Object tag, | |||
| 1192 | Lisp_Object val = handlerlist->val; | 1201 | Lisp_Object val = handlerlist->val; |
| 1193 | clobbered_eassert (handlerlist == c); | 1202 | clobbered_eassert (handlerlist == c); |
| 1194 | handlerlist = handlerlist->next; | 1203 | handlerlist = handlerlist->next; |
| 1204 | if (EQ (tag, Qexit) && EQ (val, Qt)) | ||
| 1205 | /* If we've thrown t to tag `exit' from within a minibuffer, we | ||
| 1206 | exit all minibuffers more deeply nested than the current | ||
| 1207 | one. */ | ||
| 1208 | { | ||
| 1209 | EMACS_INT mini_depth = this_minibuffer_depth (Qnil); | ||
| 1210 | if (mini_depth && mini_depth != minibuffer_quit_level) | ||
| 1211 | { | ||
| 1212 | if (minibuffer_quit_level == -1) | ||
| 1213 | minibuffer_quit_level = mini_depth; | ||
| 1214 | if (minibuffer_quit_level | ||
| 1215 | && (minibuf_level > minibuffer_quit_level)) | ||
| 1216 | Fthrow (Qexit, Qt); | ||
| 1217 | } | ||
| 1218 | else | ||
| 1219 | minibuffer_quit_level = -1; | ||
| 1220 | } | ||
| 1195 | return val; | 1221 | return val; |
| 1196 | } | 1222 | } |
| 1197 | } | 1223 | } |
| @@ -5548,6 +5548,90 @@ It should not be used for anything security-related. See | |||
| 5548 | return make_digest_string (digest, SHA1_DIGEST_SIZE); | 5548 | return make_digest_string (digest, SHA1_DIGEST_SIZE); |
| 5549 | } | 5549 | } |
| 5550 | 5550 | ||
| 5551 | DEFUN ("buffer-line-statistics", Fbuffer_line_statistics, | ||
| 5552 | Sbuffer_line_statistics, 0, 1, 0, | ||
| 5553 | doc: /* Return data about lines in BUFFER. | ||
| 5554 | The data is returned as a list, and the first element is the number of | ||
| 5555 | lines in the buffer, the second is the length of the longest line, and | ||
| 5556 | the third is the mean line length. The lengths returned are in bytes, not | ||
| 5557 | characters. */ ) | ||
| 5558 | (Lisp_Object buffer_or_name) | ||
| 5559 | { | ||
| 5560 | Lisp_Object buffer; | ||
| 5561 | ptrdiff_t lines = 0, longest = 0; | ||
| 5562 | double mean = 0; | ||
| 5563 | struct buffer *b; | ||
| 5564 | |||
| 5565 | if (NILP (buffer_or_name)) | ||
| 5566 | buffer = Fcurrent_buffer (); | ||
| 5567 | else | ||
| 5568 | buffer = Fget_buffer (buffer_or_name); | ||
| 5569 | if (NILP (buffer)) | ||
| 5570 | nsberror (buffer_or_name); | ||
| 5571 | |||
| 5572 | b = XBUFFER (buffer); | ||
| 5573 | |||
| 5574 | unsigned char *start = BUF_BEG_ADDR (b); | ||
| 5575 | ptrdiff_t area = BUF_GPT_BYTE (b) - BUF_BEG_BYTE (b), pre_gap = 0; | ||
| 5576 | |||
| 5577 | /* Process the first part of the buffer. */ | ||
| 5578 | while (area > 0) | ||
| 5579 | { | ||
| 5580 | unsigned char *n = memchr (start, '\n', area); | ||
| 5581 | |||
| 5582 | if (n) | ||
| 5583 | { | ||
| 5584 | ptrdiff_t this_line = n - start; | ||
| 5585 | if (this_line > longest) | ||
| 5586 | longest = this_line; | ||
| 5587 | lines++; | ||
| 5588 | /* Blame Knuth. */ | ||
| 5589 | mean = mean + (this_line - mean) / lines; | ||
| 5590 | area = area - this_line - 1; | ||
| 5591 | start += this_line + 1; | ||
| 5592 | } | ||
| 5593 | else | ||
| 5594 | { | ||
| 5595 | /* Didn't have a newline here, so save the rest for the | ||
| 5596 | post-gap calculation. */ | ||
| 5597 | pre_gap = area; | ||
| 5598 | area = 0; | ||
| 5599 | } | ||
| 5600 | } | ||
| 5601 | |||
| 5602 | /* If the gap is before the end of the buffer, process the last half | ||
| 5603 | of the buffer. */ | ||
| 5604 | if (BUF_GPT_BYTE (b) < BUF_Z_BYTE (b)) | ||
| 5605 | { | ||
| 5606 | start = BUF_GAP_END_ADDR (b); | ||
| 5607 | area = BUF_Z_ADDR (b) - BUF_GAP_END_ADDR (b); | ||
| 5608 | |||
| 5609 | while (area > 0) | ||
| 5610 | { | ||
| 5611 | unsigned char *n = memchr (start, '\n', area); | ||
| 5612 | ptrdiff_t this_line = n? n - start + pre_gap: area + pre_gap; | ||
| 5613 | |||
| 5614 | if (this_line > longest) | ||
| 5615 | longest = this_line; | ||
| 5616 | lines++; | ||
| 5617 | /* Blame Knuth again. */ | ||
| 5618 | mean = mean + (this_line - mean) / lines; | ||
| 5619 | area = area - this_line - 1; | ||
| 5620 | start += this_line + 1; | ||
| 5621 | pre_gap = 0; | ||
| 5622 | } | ||
| 5623 | } | ||
| 5624 | else if (pre_gap > 0) | ||
| 5625 | { | ||
| 5626 | if (pre_gap > longest) | ||
| 5627 | longest = pre_gap; | ||
| 5628 | lines++; | ||
| 5629 | mean = mean + (pre_gap - mean) / lines; | ||
| 5630 | } | ||
| 5631 | |||
| 5632 | return list3 (make_int (lines), make_int (longest), make_float (mean)); | ||
| 5633 | } | ||
| 5634 | |||
| 5551 | static bool | 5635 | static bool |
| 5552 | string_ascii_p (Lisp_Object string) | 5636 | string_ascii_p (Lisp_Object string) |
| 5553 | { | 5637 | { |
| @@ -5871,4 +5955,5 @@ this variable. */); | |||
| 5871 | defsubr (&Ssecure_hash); | 5955 | defsubr (&Ssecure_hash); |
| 5872 | defsubr (&Sbuffer_hash); | 5956 | defsubr (&Sbuffer_hash); |
| 5873 | defsubr (&Slocale_info); | 5957 | defsubr (&Slocale_info); |
| 5958 | defsubr (&Sbuffer_line_statistics); | ||
| 5874 | } | 5959 | } |
diff --git a/src/keymap.c b/src/keymap.c index 1197f6fd4a5..de9b2b58c5e 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1646,39 +1646,6 @@ specified buffer position instead of point are used. | |||
| 1646 | 1646 | ||
| 1647 | /* GC is possible in this function if it autoloads a keymap. */ | 1647 | /* GC is possible in this function if it autoloads a keymap. */ |
| 1648 | 1648 | ||
| 1649 | DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 2, 0, | ||
| 1650 | doc: /* Return the binding for command KEYS in current local keymap only. | ||
| 1651 | KEYS is a string or vector, a sequence of keystrokes. | ||
| 1652 | The binding is probably a symbol with a function definition. | ||
| 1653 | |||
| 1654 | If optional argument ACCEPT-DEFAULT is non-nil, recognize default | ||
| 1655 | bindings; see the description of `lookup-key' for more details about this. */) | ||
| 1656 | (Lisp_Object keys, Lisp_Object accept_default) | ||
| 1657 | { | ||
| 1658 | register Lisp_Object map = BVAR (current_buffer, keymap); | ||
| 1659 | if (NILP (map)) | ||
| 1660 | return Qnil; | ||
| 1661 | return Flookup_key (map, keys, accept_default); | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | /* GC is possible in this function if it autoloads a keymap. */ | ||
| 1665 | |||
| 1666 | DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 2, 0, | ||
| 1667 | doc: /* Return the binding for command KEYS in current global keymap only. | ||
| 1668 | KEYS is a string or vector, a sequence of keystrokes. | ||
| 1669 | The binding is probably a symbol with a function definition. | ||
| 1670 | This function's return values are the same as those of `lookup-key' | ||
| 1671 | \(which see). | ||
| 1672 | |||
| 1673 | If optional argument ACCEPT-DEFAULT is non-nil, recognize default | ||
| 1674 | bindings; see the description of `lookup-key' for more details about this. */) | ||
| 1675 | (Lisp_Object keys, Lisp_Object accept_default) | ||
| 1676 | { | ||
| 1677 | return Flookup_key (current_global_map, keys, accept_default); | ||
| 1678 | } | ||
| 1679 | |||
| 1680 | /* GC is possible in this function if it autoloads a keymap. */ | ||
| 1681 | |||
| 1682 | DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, | 1649 | DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, |
| 1683 | doc: /* Find the visible minor mode bindings of KEY. | 1650 | doc: /* Find the visible minor mode bindings of KEY. |
| 1684 | Return an alist of pairs (MODENAME . BINDING), where MODENAME is | 1651 | Return an alist of pairs (MODENAME . BINDING), where MODENAME is |
| @@ -3253,8 +3220,6 @@ be preferred. */); | |||
| 3253 | defsubr (&Scopy_keymap); | 3220 | defsubr (&Scopy_keymap); |
| 3254 | defsubr (&Scommand_remapping); | 3221 | defsubr (&Scommand_remapping); |
| 3255 | defsubr (&Skey_binding); | 3222 | defsubr (&Skey_binding); |
| 3256 | defsubr (&Slocal_key_binding); | ||
| 3257 | defsubr (&Sglobal_key_binding); | ||
| 3258 | defsubr (&Sminor_mode_key_binding); | 3223 | defsubr (&Sminor_mode_key_binding); |
| 3259 | defsubr (&Sdefine_key); | 3224 | defsubr (&Sdefine_key); |
| 3260 | defsubr (&Slookup_key); | 3225 | defsubr (&Slookup_key); |
diff --git a/src/lisp.h b/src/lisp.h index b6182c37eed..296f9af7337 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4368,9 +4368,12 @@ extern Lisp_Object Vminibuffer_list; | |||
| 4368 | extern Lisp_Object last_minibuf_string; | 4368 | extern Lisp_Object last_minibuf_string; |
| 4369 | extern void move_minibuffer_onto_frame (void); | 4369 | extern void move_minibuffer_onto_frame (void); |
| 4370 | extern bool is_minibuffer (EMACS_INT, Lisp_Object); | 4370 | extern bool is_minibuffer (EMACS_INT, Lisp_Object); |
| 4371 | extern EMACS_INT this_minibuffer_depth (Lisp_Object); | ||
| 4372 | extern EMACS_INT minibuf_level; | ||
| 4371 | extern Lisp_Object get_minibuffer (EMACS_INT); | 4373 | extern Lisp_Object get_minibuffer (EMACS_INT); |
| 4372 | extern void init_minibuf_once (void); | 4374 | extern void init_minibuf_once (void); |
| 4373 | extern void syms_of_minibuf (void); | 4375 | extern void syms_of_minibuf (void); |
| 4376 | extern void barf_if_interaction_inhibited (void); | ||
| 4374 | 4377 | ||
| 4375 | /* Defined in callint.c. */ | 4378 | /* Defined in callint.c. */ |
| 4376 | 4379 | ||
| @@ -4518,8 +4521,8 @@ extern void setup_process_coding_systems (Lisp_Object); | |||
| 4518 | # define CHILD_SETUP_ERROR_DESC "Doing vfork" | 4521 | # define CHILD_SETUP_ERROR_DESC "Doing vfork" |
| 4519 | #endif | 4522 | #endif |
| 4520 | 4523 | ||
| 4521 | extern int emacs_spawn (pid_t *, int, int, int, char **, char **, const char *, | 4524 | extern int emacs_spawn (pid_t *, int, int, int, char **, char **, |
| 4522 | const char *); | 4525 | const char *, const char *, const sigset_t *); |
| 4523 | extern char **make_environment_block (Lisp_Object); | 4526 | extern char **make_environment_block (Lisp_Object); |
| 4524 | extern void init_callproc_1 (void); | 4527 | extern void init_callproc_1 (void); |
| 4525 | extern void init_callproc (void); | 4528 | extern void init_callproc (void); |
| @@ -4598,6 +4601,7 @@ extern AVOID emacs_abort (void) NO_INLINE; | |||
| 4598 | extern int emacs_fstatat (int, char const *, void *, int); | 4601 | extern int emacs_fstatat (int, char const *, void *, int); |
| 4599 | extern int emacs_openat (int, char const *, int, int); | 4602 | extern int emacs_openat (int, char const *, int, int); |
| 4600 | extern int emacs_open (const char *, int, int); | 4603 | extern int emacs_open (const char *, int, int); |
| 4604 | extern int emacs_open_noquit (const char *, int, int); | ||
| 4601 | extern int emacs_pipe (int[2]); | 4605 | extern int emacs_pipe (int[2]); |
| 4602 | extern int emacs_close (int); | 4606 | extern int emacs_close (int); |
| 4603 | extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); | 4607 | extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); |
diff --git a/src/lread.c b/src/lread.c index e308fa88699..4cf4f8cde9b 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -767,11 +767,16 @@ is used for reading a character. | |||
| 767 | If the optional argument SECONDS is non-nil, it should be a number | 767 | If the optional argument SECONDS is non-nil, it should be a number |
| 768 | specifying the maximum number of seconds to wait for input. If no | 768 | specifying the maximum number of seconds to wait for input. If no |
| 769 | input arrives in that time, return nil. SECONDS may be a | 769 | input arrives in that time, return nil. SECONDS may be a |
| 770 | floating-point value. */) | 770 | floating-point value. |
| 771 | |||
| 772 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 773 | `inhibited-interaction' error. */) | ||
| 771 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | 774 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) |
| 772 | { | 775 | { |
| 773 | Lisp_Object val; | 776 | Lisp_Object val; |
| 774 | 777 | ||
| 778 | barf_if_interaction_inhibited (); | ||
| 779 | |||
| 775 | if (! NILP (prompt)) | 780 | if (! NILP (prompt)) |
| 776 | message_with_string ("%s", prompt, 0); | 781 | message_with_string ("%s", prompt, 0); |
| 777 | val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); | 782 | val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); |
| @@ -782,6 +787,12 @@ floating-point value. */) | |||
| 782 | 787 | ||
| 783 | DEFUN ("read-event", Fread_event, Sread_event, 0, 3, 0, | 788 | DEFUN ("read-event", Fread_event, Sread_event, 0, 3, 0, |
| 784 | doc: /* Read an event object from the input stream. | 789 | doc: /* Read an event object from the input stream. |
| 790 | |||
| 791 | If you want to read non-character events, consider calling `read-key' | ||
| 792 | instead. `read-key' will decode events via `input-decode-map' that | ||
| 793 | `read-event' will not. On a terminal this includes function keys such | ||
| 794 | as <F7> and <RIGHT>, or mouse events generated by `xterm-mouse-mode'. | ||
| 795 | |||
| 785 | If the optional argument PROMPT is non-nil, display that as a prompt. | 796 | If the optional argument PROMPT is non-nil, display that as a prompt. |
| 786 | If PROMPT is nil or the string \"\", the key sequence/events that led | 797 | If PROMPT is nil or the string \"\", the key sequence/events that led |
| 787 | to the current command is used as the prompt. | 798 | to the current command is used as the prompt. |
| @@ -793,9 +804,14 @@ is used for reading a character. | |||
| 793 | If the optional argument SECONDS is non-nil, it should be a number | 804 | If the optional argument SECONDS is non-nil, it should be a number |
| 794 | specifying the maximum number of seconds to wait for input. If no | 805 | specifying the maximum number of seconds to wait for input. If no |
| 795 | input arrives in that time, return nil. SECONDS may be a | 806 | input arrives in that time, return nil. SECONDS may be a |
| 796 | floating-point value. */) | 807 | floating-point value. |
| 808 | |||
| 809 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 810 | `inhibited-interaction' error. */) | ||
| 797 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | 811 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) |
| 798 | { | 812 | { |
| 813 | barf_if_interaction_inhibited (); | ||
| 814 | |||
| 799 | if (! NILP (prompt)) | 815 | if (! NILP (prompt)) |
| 800 | message_with_string ("%s", prompt, 0); | 816 | message_with_string ("%s", prompt, 0); |
| 801 | return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); | 817 | return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); |
| @@ -822,11 +838,16 @@ is used for reading a character. | |||
| 822 | If the optional argument SECONDS is non-nil, it should be a number | 838 | If the optional argument SECONDS is non-nil, it should be a number |
| 823 | specifying the maximum number of seconds to wait for input. If no | 839 | specifying the maximum number of seconds to wait for input. If no |
| 824 | input arrives in that time, return nil. SECONDS may be a | 840 | input arrives in that time, return nil. SECONDS may be a |
| 825 | floating-point value. */) | 841 | floating-point value. |
| 826 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | 842 | |
| 843 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 844 | `inhibited-interaction' error. */) | ||
| 845 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | ||
| 827 | { | 846 | { |
| 828 | Lisp_Object val; | 847 | Lisp_Object val; |
| 829 | 848 | ||
| 849 | barf_if_interaction_inhibited (); | ||
| 850 | |||
| 830 | if (! NILP (prompt)) | 851 | if (! NILP (prompt)) |
| 831 | message_with_string ("%s", prompt, 0); | 852 | message_with_string ("%s", prompt, 0); |
| 832 | 853 | ||
diff --git a/src/minibuf.c b/src/minibuf.c index 5ee440f6622..5df10453739 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -63,10 +63,31 @@ static Lisp_Object minibuf_prompt; | |||
| 63 | 63 | ||
| 64 | static ptrdiff_t minibuf_prompt_width; | 64 | static ptrdiff_t minibuf_prompt_width; |
| 65 | 65 | ||
| 66 | static Lisp_Object nth_minibuffer (EMACS_INT depth); | ||
| 67 | |||
| 66 | 68 | ||
| 69 | /* Return TRUE when a frame switch causes a minibuffer on the old | ||
| 70 | frame to move onto the new one. */ | ||
| 67 | static bool | 71 | static bool |
| 68 | minibuf_follows_frame (void) | 72 | minibuf_follows_frame (void) |
| 69 | { | 73 | { |
| 74 | return EQ (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame), | ||
| 75 | Qt); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Return TRUE when a minibuffer always remains on the frame where it | ||
| 79 | was first invoked. */ | ||
| 80 | static bool | ||
| 81 | minibuf_stays_put (void) | ||
| 82 | { | ||
| 83 | return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); | ||
| 84 | } | ||
| 85 | |||
| 86 | /* Return TRUE when opening a (recursive) minibuffer causes | ||
| 87 | minibuffers on other frames to move to the selected frame. */ | ||
| 88 | static bool | ||
| 89 | minibuf_moves_frame_when_opened (void) | ||
| 90 | { | ||
| 70 | return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); | 91 | return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); |
| 71 | } | 92 | } |
| 72 | 93 | ||
| @@ -90,7 +111,7 @@ choose_minibuf_frame (void) | |||
| 90 | minibuf_window = sf->minibuffer_window; | 111 | minibuf_window = sf->minibuffer_window; |
| 91 | /* If we've still got another minibuffer open, use its mini-window | 112 | /* If we've still got another minibuffer open, use its mini-window |
| 92 | instead. */ | 113 | instead. */ |
| 93 | if (minibuf_level && !minibuf_follows_frame ()) | 114 | if (minibuf_level > 1 && minibuf_stays_put ()) |
| 94 | { | 115 | { |
| 95 | Lisp_Object buffer = get_minibuffer (minibuf_level); | 116 | Lisp_Object buffer = get_minibuffer (minibuf_level); |
| 96 | Lisp_Object tail, frame; | 117 | Lisp_Object tail, frame; |
| @@ -105,26 +126,40 @@ choose_minibuf_frame (void) | |||
| 105 | } | 126 | } |
| 106 | } | 127 | } |
| 107 | 128 | ||
| 108 | if (minibuf_follows_frame ()) | 129 | if (minibuf_moves_frame_when_opened () |
| 130 | && FRAMEP (selected_frame) | ||
| 131 | && FRAME_LIVE_P (XFRAME (selected_frame))) | ||
| 109 | /* Make sure no other frame has a minibuffer as its selected window, | 132 | /* Make sure no other frame has a minibuffer as its selected window, |
| 110 | because the text would not be displayed in it, and that would be | 133 | because the text would not be displayed in it, and that would be |
| 111 | confusing. Only allow the selected frame to do this, | 134 | confusing. Only allow the selected frame to do this, |
| 112 | and that only if the minibuffer is active. */ | 135 | and that only if the minibuffer is active. */ |
| 113 | { | 136 | { |
| 114 | Lisp_Object tail, frame; | 137 | Lisp_Object tail, frame; |
| 115 | 138 | struct frame *of; | |
| 116 | FOR_EACH_FRAME (tail, frame) | 139 | |
| 117 | if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame)))) | 140 | FOR_EACH_FRAME (tail, frame) |
| 118 | && !(EQ (frame, selected_frame) | 141 | if (!EQ (frame, selected_frame) |
| 119 | && minibuf_level > 0)) | 142 | && minibuf_level > 1 |
| 120 | Fset_frame_selected_window (frame, Fframe_first_window (frame), | 143 | /* The frame's minibuffer can be on a different frame. */ |
| 121 | Qnil); | 144 | && ! EQ (XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame, |
| 122 | } | 145 | selected_frame)) |
| 146 | { | ||
| 147 | if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) | ||
| 148 | Fset_frame_selected_window (frame, Fframe_first_window (frame), | ||
| 149 | Qnil); | ||
| 150 | |||
| 151 | if (!EQ (XWINDOW (of->minibuffer_window)->contents, | ||
| 152 | nth_minibuffer (0))) | ||
| 153 | set_window_buffer (of->minibuffer_window, | ||
| 154 | nth_minibuffer (0), 0, 0); | ||
| 155 | } | ||
| 156 | } | ||
| 123 | } | 157 | } |
| 124 | 158 | ||
| 125 | /* If `minibuffer_follows_selected_frame' and we have a minibuffer, move it | 159 | /* If `minibuffer_follows_selected_frame' is t and we have a |
| 126 | from its current frame to the selected frame. This function is | 160 | minibuffer, move it from its current frame to the selected frame. |
| 127 | intended to be called from `do_switch_frame' in frame.c. */ | 161 | This function is intended to be called from `do_switch_frame' in |
| 162 | frame.c. */ | ||
| 128 | void move_minibuffer_onto_frame (void) | 163 | void move_minibuffer_onto_frame (void) |
| 129 | { | 164 | { |
| 130 | if (!minibuf_level) | 165 | if (!minibuf_level) |
| @@ -135,14 +170,18 @@ void move_minibuffer_onto_frame (void) | |||
| 135 | && FRAME_LIVE_P (XFRAME (selected_frame)) | 170 | && FRAME_LIVE_P (XFRAME (selected_frame)) |
| 136 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) | 171 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) |
| 137 | { | 172 | { |
| 173 | EMACS_INT i; | ||
| 138 | struct frame *sf = XFRAME (selected_frame); | 174 | struct frame *sf = XFRAME (selected_frame); |
| 139 | Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; | 175 | Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; |
| 140 | struct frame *of = XFRAME (old_frame); | 176 | struct frame *of = XFRAME (old_frame); |
| 141 | Lisp_Object buffer = XWINDOW (minibuf_window)->contents; | ||
| 142 | 177 | ||
| 143 | set_window_buffer (sf->minibuffer_window, buffer, 0, 0); | 178 | /* Stack up all the (recursively) open minibuffers on the selected |
| 179 | mini_window. */ | ||
| 180 | for (i = 1; i <= minibuf_level; i++) | ||
| 181 | set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0); | ||
| 144 | minibuf_window = sf->minibuffer_window; | 182 | minibuf_window = sf->minibuffer_window; |
| 145 | set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); | 183 | if (of != sf) |
| 184 | set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); | ||
| 146 | } | 185 | } |
| 147 | } | 186 | } |
| 148 | 187 | ||
| @@ -336,6 +375,63 @@ return t only if BUFFER is an active minibuffer. */) | |||
| 336 | ? Qt : Qnil; | 375 | ? Qt : Qnil; |
| 337 | } | 376 | } |
| 338 | 377 | ||
| 378 | DEFUN ("innermost-minibuffer-p", Finnermost_minibuffer_p, | ||
| 379 | Sinnermost_minibuffer_p, 0, 1, 0, | ||
| 380 | doc: /* Return t if BUFFER is the most nested active minibuffer. | ||
| 381 | No argument or nil as argument means use the current buffer as BUFFER. */) | ||
| 382 | (Lisp_Object buffer) | ||
| 383 | { | ||
| 384 | if (NILP (buffer)) | ||
| 385 | buffer = Fcurrent_buffer (); | ||
| 386 | return EQ (buffer, (Fcar (Fnthcdr (make_fixnum (minibuf_level), | ||
| 387 | Vminibuffer_list)))) | ||
| 388 | ? Qt | ||
| 389 | : Qnil; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* Return the nesting depth of the active minibuffer BUFFER, or 0 if | ||
| 393 | BUFFER isn't such a thing. If BUFFER is nil, this means use the current | ||
| 394 | buffer. */ | ||
| 395 | EMACS_INT | ||
| 396 | this_minibuffer_depth (Lisp_Object buffer) | ||
| 397 | { | ||
| 398 | EMACS_INT i; | ||
| 399 | Lisp_Object bufs; | ||
| 400 | |||
| 401 | if (NILP (buffer)) | ||
| 402 | buffer = Fcurrent_buffer (); | ||
| 403 | for (i = 1, bufs = Fcdr (Vminibuffer_list); | ||
| 404 | i <= minibuf_level; | ||
| 405 | i++, bufs = Fcdr (bufs)) | ||
| 406 | if (EQ (Fcar (bufs), buffer)) | ||
| 407 | return i; | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | DEFUN ("abort-minibuffers", Fabort_minibuffers, Sabort_minibuffers, 0, 0, "", | ||
| 412 | doc: /* Abort the current minibuffer. | ||
| 413 | If we are not currently in the innermost minibuffer, prompt the user to | ||
| 414 | confirm the aborting of the current minibuffer and all contained ones. */) | ||
| 415 | (void) | ||
| 416 | { | ||
| 417 | EMACS_INT minibuf_depth = this_minibuffer_depth (Qnil); | ||
| 418 | Lisp_Object array[2]; | ||
| 419 | AUTO_STRING (fmt, "Abort %s minibuffer levels? "); | ||
| 420 | |||
| 421 | if (!minibuf_depth) | ||
| 422 | error ("Not in a minibuffer"); | ||
| 423 | if (minibuf_depth < minibuf_level) | ||
| 424 | { | ||
| 425 | array[0] = fmt; | ||
| 426 | array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); | ||
| 427 | if (!NILP (Fyes_or_no_p (Fformat (2, array)))) | ||
| 428 | Fthrow (Qexit, Qt); | ||
| 429 | } | ||
| 430 | else | ||
| 431 | Fthrow (Qexit, Qt); | ||
| 432 | return Qnil; | ||
| 433 | } | ||
| 434 | |||
| 339 | DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, | 435 | DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, |
| 340 | Sminibuffer_prompt_end, 0, 0, 0, | 436 | Sminibuffer_prompt_end, 0, 0, 0, |
| 341 | doc: /* Return the buffer position of the end of the minibuffer prompt. | 437 | doc: /* Return the buffer position of the end of the minibuffer prompt. |
| @@ -411,6 +507,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 411 | Lisp_Object val; | 507 | Lisp_Object val; |
| 412 | ptrdiff_t count = SPECPDL_INDEX (); | 508 | ptrdiff_t count = SPECPDL_INDEX (); |
| 413 | Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; | 509 | Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; |
| 510 | Lisp_Object calling_frame = selected_frame; | ||
| 414 | Lisp_Object enable_multibyte; | 511 | Lisp_Object enable_multibyte; |
| 415 | EMACS_INT pos = 0; | 512 | EMACS_INT pos = 0; |
| 416 | /* String to add to the history. */ | 513 | /* String to add to the history. */ |
| @@ -648,6 +745,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 648 | } | 745 | } |
| 649 | } | 746 | } |
| 650 | 747 | ||
| 748 | if (minibuf_moves_frame_when_opened ()) | ||
| 749 | { | ||
| 750 | EMACS_INT i; | ||
| 751 | |||
| 752 | /* Stack up all the (recursively) open minibuffers on the selected | ||
| 753 | mini_window. */ | ||
| 754 | for (i = 1; i < minibuf_level; i++) | ||
| 755 | set_window_buffer (XFRAME (mini_frame)->minibuffer_window, | ||
| 756 | nth_minibuffer (i), 0, 0); | ||
| 757 | } | ||
| 758 | |||
| 651 | /* Display this minibuffer in the proper window. */ | 759 | /* Display this minibuffer in the proper window. */ |
| 652 | /* Use set_window_buffer instead of Fset_window_buffer (see | 760 | /* Use set_window_buffer instead of Fset_window_buffer (see |
| 653 | discussion of bug#11984, bug#12025, bug#12026). */ | 761 | discussion of bug#11984, bug#12025, bug#12026). */ |
| @@ -729,6 +837,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 729 | 837 | ||
| 730 | recursive_edit_1 (); | 838 | recursive_edit_1 (); |
| 731 | 839 | ||
| 840 | /* We've exited the recursive edit without an error, so switch the | ||
| 841 | current window away from the expired minibuffer window. */ | ||
| 842 | { | ||
| 843 | Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); | ||
| 844 | /* PREV can be on a different frame when we have a minibuffer only | ||
| 845 | frame, the other frame's minibuffer window is MINIBUF_WINDOW, | ||
| 846 | and its "focus window" is also MINIBUF_WINDOW. */ | ||
| 847 | while (!EQ (prev, minibuf_window) | ||
| 848 | && !EQ (selected_frame, WINDOW_FRAME (XWINDOW (prev)))) | ||
| 849 | prev = Fprevious_window (prev, Qnil, Qnil); | ||
| 850 | if (!EQ (prev, minibuf_window)) | ||
| 851 | Fset_frame_selected_window (selected_frame, prev, Qnil); | ||
| 852 | } | ||
| 853 | |||
| 732 | /* If cursor is on the minibuffer line, | 854 | /* If cursor is on the minibuffer line, |
| 733 | show the user we have exited by putting it in column 0. */ | 855 | show the user we have exited by putting it in column 0. */ |
| 734 | if (XWINDOW (minibuf_window)->cursor.vpos >= 0 | 856 | if (XWINDOW (minibuf_window)->cursor.vpos >= 0 |
| @@ -767,6 +889,12 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 767 | in set-window-configuration. */ | 889 | in set-window-configuration. */ |
| 768 | unbind_to (count, Qnil); | 890 | unbind_to (count, Qnil); |
| 769 | 891 | ||
| 892 | /* Switch the frame back to the calling frame. */ | ||
| 893 | if (!EQ (selected_frame, calling_frame) | ||
| 894 | && FRAMEP (calling_frame) | ||
| 895 | && FRAME_LIVE_P (XFRAME (calling_frame))) | ||
| 896 | call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); | ||
| 897 | |||
| 770 | /* Add the value to the appropriate history list, if any. This is | 898 | /* Add the value to the appropriate history list, if any. This is |
| 771 | done after the previous buffer has been made current again, in | 899 | done after the previous buffer has been made current again, in |
| 772 | case the history variable is buffer-local. */ | 900 | case the history variable is buffer-local. */ |
| @@ -790,6 +918,14 @@ is_minibuffer (EMACS_INT depth, Lisp_Object buf) | |||
| 790 | && EQ (Fcar (tail), buf); | 918 | && EQ (Fcar (tail), buf); |
| 791 | } | 919 | } |
| 792 | 920 | ||
| 921 | /* Return the DEPTHth minibuffer, or nil if such does not yet exist. */ | ||
| 922 | static Lisp_Object | ||
| 923 | nth_minibuffer (EMACS_INT depth) | ||
| 924 | { | ||
| 925 | Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list); | ||
| 926 | return XCAR (tail); | ||
| 927 | } | ||
| 928 | |||
| 793 | /* Return a buffer to be used as the minibuffer at depth `depth'. | 929 | /* Return a buffer to be used as the minibuffer at depth `depth'. |
| 794 | depth = 0 is the lowest allowed argument, and that is the value | 930 | depth = 0 is the lowest allowed argument, and that is the value |
| 795 | used for nonrecursive minibuffer invocations. */ | 931 | used for nonrecursive minibuffer invocations. */ |
| @@ -939,6 +1075,13 @@ read_minibuf_unwind (void) | |||
| 939 | } | 1075 | } |
| 940 | 1076 | ||
| 941 | 1077 | ||
| 1078 | void | ||
| 1079 | barf_if_interaction_inhibited (void) | ||
| 1080 | { | ||
| 1081 | if (inhibit_interaction) | ||
| 1082 | xsignal0 (Qinhibited_interaction); | ||
| 1083 | } | ||
| 1084 | |||
| 942 | DEFUN ("read-from-minibuffer", Fread_from_minibuffer, | 1085 | DEFUN ("read-from-minibuffer", Fread_from_minibuffer, |
| 943 | Sread_from_minibuffer, 1, 7, 0, | 1086 | Sread_from_minibuffer, 1, 7, 0, |
| 944 | doc: /* Read a string from the minibuffer, prompting with string PROMPT. | 1087 | doc: /* Read a string from the minibuffer, prompting with string PROMPT. |
| @@ -983,6 +1126,9 @@ If the variable `minibuffer-allow-text-properties' is non-nil, | |||
| 983 | then the string which is returned includes whatever text properties | 1126 | then the string which is returned includes whatever text properties |
| 984 | were present in the minibuffer. Otherwise the value has no text properties. | 1127 | were present in the minibuffer. Otherwise the value has no text properties. |
| 985 | 1128 | ||
| 1129 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 1130 | `inhibited-interaction' error. | ||
| 1131 | |||
| 986 | The remainder of this documentation string describes the | 1132 | The remainder of this documentation string describes the |
| 987 | INITIAL-CONTENTS argument in more detail. It is only relevant when | 1133 | INITIAL-CONTENTS argument in more detail. It is only relevant when |
| 988 | studying existing code, or when HIST is a cons. If non-nil, | 1134 | studying existing code, or when HIST is a cons. If non-nil, |
| @@ -998,6 +1144,8 @@ and some related functions, which use zero-indexing for POSITION. */) | |||
| 998 | { | 1144 | { |
| 999 | Lisp_Object histvar, histpos, val; | 1145 | Lisp_Object histvar, histpos, val; |
| 1000 | 1146 | ||
| 1147 | barf_if_interaction_inhibited (); | ||
| 1148 | |||
| 1001 | CHECK_STRING (prompt); | 1149 | CHECK_STRING (prompt); |
| 1002 | if (NILP (keymap)) | 1150 | if (NILP (keymap)) |
| 1003 | keymap = Vminibuffer_local_map; | 1151 | keymap = Vminibuffer_local_map; |
| @@ -1071,11 +1219,17 @@ point positioned at the end, so that SPACE will accept the input. | |||
| 1071 | \(Actually, INITIAL can also be a cons of a string and an integer. | 1219 | \(Actually, INITIAL can also be a cons of a string and an integer. |
| 1072 | Such values are treated as in `read-from-minibuffer', but are normally | 1220 | Such values are treated as in `read-from-minibuffer', but are normally |
| 1073 | not useful in this function.) | 1221 | not useful in this function.) |
| 1222 | |||
| 1074 | Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits | 1223 | Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits |
| 1075 | the current input method and the setting of`enable-multibyte-characters'. */) | 1224 | the current input method and the setting of`enable-multibyte-characters'. |
| 1225 | |||
| 1226 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 1227 | `inhibited-interaction' error. */) | ||
| 1076 | (Lisp_Object prompt, Lisp_Object initial, Lisp_Object inherit_input_method) | 1228 | (Lisp_Object prompt, Lisp_Object initial, Lisp_Object inherit_input_method) |
| 1077 | { | 1229 | { |
| 1078 | CHECK_STRING (prompt); | 1230 | CHECK_STRING (prompt); |
| 1231 | barf_if_interaction_inhibited (); | ||
| 1232 | |||
| 1079 | return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, | 1233 | return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, |
| 1080 | 0, Qminibuffer_history, make_fixnum (0), Qnil, 0, | 1234 | 0, Qminibuffer_history, make_fixnum (0), Qnil, 0, |
| 1081 | !NILP (inherit_input_method)); | 1235 | !NILP (inherit_input_method)); |
| @@ -2032,13 +2186,15 @@ For example, `eval-expression' uses this. */); | |||
| 2032 | The function is called with the arguments passed to `read-buffer'. */); | 2186 | The function is called with the arguments passed to `read-buffer'. */); |
| 2033 | Vread_buffer_function = Qnil; | 2187 | Vread_buffer_function = Qnil; |
| 2034 | 2188 | ||
| 2035 | DEFVAR_BOOL ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, | 2189 | DEFVAR_LISP ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, |
| 2036 | doc: /* Non-nil means the active minibuffer always displays on the selected frame. | 2190 | doc: /* t means the active minibuffer always displays on the selected frame. |
| 2037 | Nil means that a minibuffer will appear only in the frame which created it. | 2191 | Nil means that a minibuffer will appear only in the frame which created it. |
| 2192 | Any other value means the minibuffer will move onto another frame, but | ||
| 2193 | only when the user starts using a minibuffer there. | ||
| 2038 | 2194 | ||
| 2039 | Any buffer local or dynamic binding of this variable is ignored. Only the | 2195 | Any buffer local or dynamic binding of this variable is ignored. Only the |
| 2040 | default top level value is used. */); | 2196 | default top level value is used. */); |
| 2041 | minibuffer_follows_selected_frame = 1; | 2197 | minibuffer_follows_selected_frame = Qt; |
| 2042 | 2198 | ||
| 2043 | DEFVAR_BOOL ("read-buffer-completion-ignore-case", | 2199 | DEFVAR_BOOL ("read-buffer-completion-ignore-case", |
| 2044 | read_buffer_completion_ignore_case, | 2200 | read_buffer_completion_ignore_case, |
| @@ -2183,6 +2339,15 @@ This variable also overrides the default character that `read-passwd' | |||
| 2183 | uses to hide passwords. */); | 2339 | uses to hide passwords. */); |
| 2184 | Vread_hide_char = Qnil; | 2340 | Vread_hide_char = Qnil; |
| 2185 | 2341 | ||
| 2342 | DEFVAR_BOOL ("inhibit-interaction", | ||
| 2343 | inhibit_interaction, | ||
| 2344 | doc: /* Non-nil means any user interaction will signal an error. | ||
| 2345 | This variable can be bound when user interaction can't be performed, | ||
| 2346 | for instance when running a headless Emacs server. Functions like | ||
| 2347 | `read-from-minibuffer' (and the like) will signal `inhibited-interaction' | ||
| 2348 | instead. */); | ||
| 2349 | inhibit_interaction = 0; | ||
| 2350 | |||
| 2186 | defsubr (&Sactive_minibuffer_window); | 2351 | defsubr (&Sactive_minibuffer_window); |
| 2187 | defsubr (&Sset_minibuffer_window); | 2352 | defsubr (&Sset_minibuffer_window); |
| 2188 | defsubr (&Sread_from_minibuffer); | 2353 | defsubr (&Sread_from_minibuffer); |
| @@ -2196,6 +2361,8 @@ uses to hide passwords. */); | |||
| 2196 | defsubr (&Sminibuffer_prompt); | 2361 | defsubr (&Sminibuffer_prompt); |
| 2197 | 2362 | ||
| 2198 | defsubr (&Sminibufferp); | 2363 | defsubr (&Sminibufferp); |
| 2364 | defsubr (&Sinnermost_minibuffer_p); | ||
| 2365 | defsubr (&Sabort_minibuffers); | ||
| 2199 | defsubr (&Sminibuffer_prompt_end); | 2366 | defsubr (&Sminibuffer_prompt_end); |
| 2200 | defsubr (&Sminibuffer_contents); | 2367 | defsubr (&Sminibuffer_contents); |
| 2201 | defsubr (&Sminibuffer_contents_no_properties); | 2368 | defsubr (&Sminibuffer_contents_no_properties); |
diff --git a/src/pdumper.c b/src/pdumper.c index 7eefcc83fda..f0711078a5a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -5460,7 +5460,7 @@ pdumper_load (const char *dump_filename, char *argv0, char const *original_pwd) | |||
| 5460 | eassert (!dump_loaded_p ()); | 5460 | eassert (!dump_loaded_p ()); |
| 5461 | 5461 | ||
| 5462 | int err; | 5462 | int err; |
| 5463 | int dump_fd = emacs_open (dump_filename, O_RDONLY, 0); | 5463 | int dump_fd = emacs_open_noquit (dump_filename, O_RDONLY, 0); |
| 5464 | if (dump_fd < 0) | 5464 | if (dump_fd < 0) |
| 5465 | { | 5465 | { |
| 5466 | err = (errno == ENOENT || errno == ENOTDIR | 5466 | err = (errno == ENOENT || errno == ENOTDIR |
diff --git a/src/process.c b/src/process.c index 06d750d3368..dac7d0440fa 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -692,8 +692,7 @@ status_convert (int w) | |||
| 692 | if (WIFSTOPPED (w)) | 692 | if (WIFSTOPPED (w)) |
| 693 | return Fcons (Qstop, Fcons (make_fixnum (WSTOPSIG (w)), Qnil)); | 693 | return Fcons (Qstop, Fcons (make_fixnum (WSTOPSIG (w)), Qnil)); |
| 694 | else if (WIFEXITED (w)) | 694 | else if (WIFEXITED (w)) |
| 695 | return Fcons (Qexit, Fcons (make_fixnum (WEXITSTATUS (w)), | 695 | return Fcons (Qexit, Fcons (make_fixnum (WEXITSTATUS (w)), Qnil)); |
| 696 | WCOREDUMP (w) ? Qt : Qnil)); | ||
| 697 | else if (WIFSIGNALED (w)) | 696 | else if (WIFSIGNALED (w)) |
| 698 | return Fcons (Qsignal, Fcons (make_fixnum (WTERMSIG (w)), | 697 | return Fcons (Qsignal, Fcons (make_fixnum (WTERMSIG (w)), |
| 699 | WCOREDUMP (w) ? Qt : Qnil)); | 698 | WCOREDUMP (w) ? Qt : Qnil)); |
| @@ -2059,6 +2058,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2059 | bool pty_flag = 0; | 2058 | bool pty_flag = 0; |
| 2060 | char pty_name[PTY_NAME_SIZE]; | 2059 | char pty_name[PTY_NAME_SIZE]; |
| 2061 | Lisp_Object lisp_pty_name = Qnil; | 2060 | Lisp_Object lisp_pty_name = Qnil; |
| 2061 | sigset_t oldset; | ||
| 2062 | 2062 | ||
| 2063 | inchannel = outchannel = -1; | 2063 | inchannel = outchannel = -1; |
| 2064 | 2064 | ||
| @@ -2139,13 +2139,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2139 | setup_process_coding_systems (process); | 2139 | setup_process_coding_systems (process); |
| 2140 | char **env = make_environment_block (current_dir); | 2140 | char **env = make_environment_block (current_dir); |
| 2141 | 2141 | ||
| 2142 | block_input (); | ||
| 2143 | block_child_signal (&oldset); | ||
| 2144 | |||
| 2142 | pty_flag = p->pty_flag; | 2145 | pty_flag = p->pty_flag; |
| 2143 | eassert (pty_flag == ! NILP (lisp_pty_name)); | 2146 | eassert (pty_flag == ! NILP (lisp_pty_name)); |
| 2144 | 2147 | ||
| 2145 | vfork_errno | 2148 | vfork_errno |
| 2146 | = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, | 2149 | = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, |
| 2147 | SSDATA (current_dir), | 2150 | SSDATA (current_dir), |
| 2148 | pty_flag ? SSDATA (lisp_pty_name) : NULL); | 2151 | pty_flag ? SSDATA (lisp_pty_name) : NULL, &oldset); |
| 2149 | 2152 | ||
| 2150 | eassert ((vfork_errno == 0) == (0 < pid)); | 2153 | eassert ((vfork_errno == 0) == (0 < pid)); |
| 2151 | 2154 | ||
| @@ -2153,6 +2156,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2153 | if (pid >= 0) | 2156 | if (pid >= 0) |
| 2154 | p->alive = 1; | 2157 | p->alive = 1; |
| 2155 | 2158 | ||
| 2159 | /* Stop blocking in the parent. */ | ||
| 2160 | unblock_child_signal (&oldset); | ||
| 2161 | unblock_input (); | ||
| 2162 | |||
| 2156 | /* Environment block no longer needed. */ | 2163 | /* Environment block no longer needed. */ |
| 2157 | unbind_to (count, Qnil); | 2164 | unbind_to (count, Qnil); |
| 2158 | 2165 | ||
diff --git a/src/sysdep.c b/src/sysdep.c index 6ede06b1aa3..941b4e2fa24 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -53,6 +53,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 53 | # include <sys/sysctl.h> | 53 | # include <sys/sysctl.h> |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | #if defined __OpenBSD__ | ||
| 57 | # include <sys/proc.h> | ||
| 58 | #endif | ||
| 59 | |||
| 56 | #ifdef DARWIN_OS | 60 | #ifdef DARWIN_OS |
| 57 | # include <libproc.h> | 61 | # include <libproc.h> |
| 58 | #endif | 62 | #endif |
| @@ -2316,6 +2320,28 @@ emacs_open (char const *file, int oflags, int mode) | |||
| 2316 | return emacs_openat (AT_FDCWD, file, oflags, mode); | 2320 | return emacs_openat (AT_FDCWD, file, oflags, mode); |
| 2317 | } | 2321 | } |
| 2318 | 2322 | ||
| 2323 | /* Same as above, but doesn't allow the user to quit. */ | ||
| 2324 | |||
| 2325 | static int | ||
| 2326 | emacs_openat_noquit (int dirfd, const char *file, int oflags, | ||
| 2327 | int mode) | ||
| 2328 | { | ||
| 2329 | int fd; | ||
| 2330 | if (! (oflags & O_TEXT)) | ||
| 2331 | oflags |= O_BINARY; | ||
| 2332 | oflags |= O_CLOEXEC; | ||
| 2333 | do | ||
| 2334 | fd = openat (dirfd, file, oflags, mode); | ||
| 2335 | while (fd < 0 && errno == EINTR); | ||
| 2336 | return fd; | ||
| 2337 | } | ||
| 2338 | |||
| 2339 | int | ||
| 2340 | emacs_open_noquit (char const *file, int oflags, int mode) | ||
| 2341 | { | ||
| 2342 | return emacs_openat_noquit (AT_FDCWD, file, oflags, mode); | ||
| 2343 | } | ||
| 2344 | |||
| 2319 | /* Open FILE as a stream for Emacs use, with mode MODE. | 2345 | /* Open FILE as a stream for Emacs use, with mode MODE. |
| 2320 | Act like emacs_open with respect to threads, signals, and quits. */ | 2346 | Act like emacs_open with respect to threads, signals, and quits. */ |
| 2321 | 2347 | ||
| @@ -2972,6 +2998,14 @@ make_lisp_timeval (struct timeval t) | |||
| 2972 | return make_lisp_time (timeval_to_timespec (t)); | 2998 | return make_lisp_time (timeval_to_timespec (t)); |
| 2973 | } | 2999 | } |
| 2974 | 3000 | ||
| 3001 | #elif defined __OpenBSD__ | ||
| 3002 | |||
| 3003 | static Lisp_Object | ||
| 3004 | make_lisp_timeval (long sec, long usec) | ||
| 3005 | { | ||
| 3006 | return make_lisp_time(make_timespec(sec, usec * 1000)); | ||
| 3007 | } | ||
| 3008 | |||
| 2975 | #endif | 3009 | #endif |
| 2976 | 3010 | ||
| 2977 | #ifdef GNU_LINUX | 3011 | #ifdef GNU_LINUX |
| @@ -3661,6 +3695,189 @@ system_process_attributes (Lisp_Object pid) | |||
| 3661 | return attrs; | 3695 | return attrs; |
| 3662 | } | 3696 | } |
| 3663 | 3697 | ||
| 3698 | #elif defined __OpenBSD__ | ||
| 3699 | |||
| 3700 | Lisp_Object | ||
| 3701 | system_process_attributes (Lisp_Object pid) | ||
| 3702 | { | ||
| 3703 | int proc_id, nentries, fscale, i; | ||
| 3704 | int pagesize = getpagesize (); | ||
| 3705 | int mib[6]; | ||
| 3706 | size_t len; | ||
| 3707 | double pct; | ||
| 3708 | char *ttyname, args[ARG_MAX]; | ||
| 3709 | struct kinfo_proc proc; | ||
| 3710 | struct passwd *pw; | ||
| 3711 | struct group *gr; | ||
| 3712 | struct timespec t; | ||
| 3713 | struct uvmexp uvmexp; | ||
| 3714 | |||
| 3715 | Lisp_Object attrs = Qnil; | ||
| 3716 | Lisp_Object decoded_comm; | ||
| 3717 | |||
| 3718 | CHECK_NUMBER (pid); | ||
| 3719 | CONS_TO_INTEGER (pid, int, proc_id); | ||
| 3720 | |||
| 3721 | len = sizeof proc; | ||
| 3722 | mib[0] = CTL_KERN; | ||
| 3723 | mib[1] = KERN_PROC; | ||
| 3724 | mib[2] = KERN_PROC_PID; | ||
| 3725 | mib[3] = proc_id; | ||
| 3726 | mib[4] = len; | ||
| 3727 | mib[5] = 1; | ||
| 3728 | if (sysctl (mib, 6, &proc, &len, NULL, 0) != 0) | ||
| 3729 | return attrs; | ||
| 3730 | |||
| 3731 | attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.p_uid)), attrs); | ||
| 3732 | |||
| 3733 | block_input (); | ||
| 3734 | pw = getpwuid (proc.p_uid); | ||
| 3735 | unblock_input (); | ||
| 3736 | if (pw) | ||
| 3737 | attrs = Fcons (Fcons (Quser, build_string(pw->pw_name)), attrs); | ||
| 3738 | |||
| 3739 | attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER(proc.p_svgid)), attrs); | ||
| 3740 | |||
| 3741 | block_input (); | ||
| 3742 | gr = getgrgid (proc.p_svgid); | ||
| 3743 | unblock_input (); | ||
| 3744 | if (gr) | ||
| 3745 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | ||
| 3746 | |||
| 3747 | AUTO_STRING (comm, proc.p_comm); | ||
| 3748 | decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0); | ||
| 3749 | attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); | ||
| 3750 | |||
| 3751 | { | ||
| 3752 | char state[2] = {'\0', '\0'}; | ||
| 3753 | switch (proc.p_stat) { | ||
| 3754 | case SIDL: | ||
| 3755 | state[0] = 'I'; | ||
| 3756 | break; | ||
| 3757 | case SRUN: | ||
| 3758 | state[0] = 'R'; | ||
| 3759 | break; | ||
| 3760 | case SSLEEP: | ||
| 3761 | state[0] = 'S'; | ||
| 3762 | break; | ||
| 3763 | case SSTOP: | ||
| 3764 | state[0] = 'T'; | ||
| 3765 | break; | ||
| 3766 | case SZOMB: | ||
| 3767 | state[0] = 'Z'; | ||
| 3768 | break; | ||
| 3769 | case SDEAD: | ||
| 3770 | state[0] = 'D'; | ||
| 3771 | break; | ||
| 3772 | } | ||
| 3773 | attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); | ||
| 3774 | } | ||
| 3775 | |||
| 3776 | attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.p_ppid)), attrs); | ||
| 3777 | attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.p_gid)), attrs); | ||
| 3778 | attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.p_sid)), attrs); | ||
| 3779 | |||
| 3780 | block_input (); | ||
| 3781 | ttyname = proc.p_tdev == NODEV ? NULL : devname (proc.p_tdev, S_IFCHR); | ||
| 3782 | unblock_input (); | ||
| 3783 | if (ttyname) | ||
| 3784 | attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs); | ||
| 3785 | |||
| 3786 | attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.p_tpgid)), attrs); | ||
| 3787 | attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc.p_uru_minflt)), | ||
| 3788 | attrs); | ||
| 3789 | attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (proc.p_uru_majflt)), | ||
| 3790 | attrs); | ||
| 3791 | |||
| 3792 | /* FIXME: missing cminflt, cmajflt. */ | ||
| 3793 | |||
| 3794 | attrs = Fcons (Fcons (Qutime, make_lisp_timeval (proc.p_uutime_sec, | ||
| 3795 | proc.p_uutime_usec)), | ||
| 3796 | attrs); | ||
| 3797 | attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.p_ustime_sec, | ||
| 3798 | proc.p_ustime_usec)), | ||
| 3799 | attrs); | ||
| 3800 | t = timespec_add (make_timespec (proc.p_uutime_sec, | ||
| 3801 | proc.p_uutime_usec * 1000), | ||
| 3802 | make_timespec (proc.p_ustime_sec, | ||
| 3803 | proc.p_ustime_usec * 1000)); | ||
| 3804 | attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); | ||
| 3805 | |||
| 3806 | attrs = Fcons (Fcons (Qcutime, make_lisp_timeval (proc.p_uctime_sec, | ||
| 3807 | proc.p_uctime_usec)), | ||
| 3808 | attrs); | ||
| 3809 | |||
| 3810 | /* FIXME: missing cstime and thus ctime. */ | ||
| 3811 | |||
| 3812 | attrs = Fcons (Fcons (Qpri, make_fixnum (proc.p_priority)), attrs); | ||
| 3813 | attrs = Fcons (Fcons (Qnice, make_fixnum (proc.p_nice)), attrs); | ||
| 3814 | |||
| 3815 | /* FIXME: missing thcount (thread count) */ | ||
| 3816 | |||
| 3817 | attrs = Fcons (Fcons (Qstart, make_lisp_timeval (proc.p_ustart_sec, | ||
| 3818 | proc.p_ustart_usec)), | ||
| 3819 | attrs); | ||
| 3820 | |||
| 3821 | len = (proc.p_vm_tsize + proc.p_vm_dsize + proc.p_vm_ssize) * pagesize >> 10; | ||
| 3822 | attrs = Fcons (Fcons (Qvsize, make_fixnum (len)), attrs); | ||
| 3823 | |||
| 3824 | attrs = Fcons (Fcons (Qrss, make_fixnum (proc.p_vm_rssize * pagesize >> 10)), | ||
| 3825 | attrs); | ||
| 3826 | |||
| 3827 | t = make_timespec (proc.p_ustart_sec, | ||
| 3828 | proc.p_ustart_usec * 1000); | ||
| 3829 | t = timespec_sub (current_timespec (), t); | ||
| 3830 | attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); | ||
| 3831 | |||
| 3832 | len = sizeof (fscale); | ||
| 3833 | mib[0] = CTL_KERN; | ||
| 3834 | mib[1] = KERN_FSCALE; | ||
| 3835 | if (sysctl (mib, 2, &fscale, &len, NULL, 0) != -1) | ||
| 3836 | { | ||
| 3837 | pct = (double)proc.p_pctcpu / fscale * 100.0; | ||
| 3838 | attrs = Fcons (Fcons (Qpcpu, make_float (pct)), attrs); | ||
| 3839 | } | ||
| 3840 | |||
| 3841 | len = sizeof (uvmexp); | ||
| 3842 | mib[0] = CTL_VM; | ||
| 3843 | mib[1] = VM_UVMEXP; | ||
| 3844 | if (sysctl (mib, 2, &uvmexp, &len, NULL, 0) != -1) | ||
| 3845 | { | ||
| 3846 | pct = (100.0 * (double)proc.p_vm_rssize / uvmexp.npages); | ||
| 3847 | attrs = Fcons (Fcons (Qpmem, make_float (pct)), attrs); | ||
| 3848 | } | ||
| 3849 | |||
| 3850 | len = sizeof args; | ||
| 3851 | mib[0] = CTL_KERN; | ||
| 3852 | mib[1] = KERN_PROC_ARGS; | ||
| 3853 | mib[2] = proc_id; | ||
| 3854 | mib[3] = KERN_PROC_ARGV; | ||
| 3855 | if (sysctl (mib, 4, &args, &len, NULL, 0) == 0 && len != 0) | ||
| 3856 | { | ||
| 3857 | char **argv = (char**)args; | ||
| 3858 | |||
| 3859 | /* concatenate argv reusing the existing storage storage. | ||
| 3860 | sysctl(8) guarantees that "the buffer pointed to by oldp is | ||
| 3861 | filled with an array of char pointers followed by the strings | ||
| 3862 | themselves." */ | ||
| 3863 | for (i = 0; argv[i] != NULL; ++i) | ||
| 3864 | { | ||
| 3865 | if (argv[i+1] != NULL) | ||
| 3866 | { | ||
| 3867 | len = strlen (argv[i]); | ||
| 3868 | argv[i][len] = ' '; | ||
| 3869 | } | ||
| 3870 | } | ||
| 3871 | |||
| 3872 | AUTO_STRING (comm, *argv); | ||
| 3873 | decoded_comm = code_convert_string_norecord (comm, | ||
| 3874 | Vlocale_coding_system, 0); | ||
| 3875 | attrs = Fcons (Fcons (Qargs, decoded_comm), attrs); | ||
| 3876 | } | ||
| 3877 | |||
| 3878 | return attrs; | ||
| 3879 | } | ||
| 3880 | |||
| 3664 | #elif defined DARWIN_OS | 3881 | #elif defined DARWIN_OS |
| 3665 | 3882 | ||
| 3666 | Lisp_Object | 3883 | Lisp_Object |
diff --git a/src/w32term.c b/src/w32term.c index e5a8a823b48..109aa58d732 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -7507,7 +7507,8 @@ w32_initialize (void) | |||
| 7507 | } | 7507 | } |
| 7508 | 7508 | ||
| 7509 | #ifdef CYGWIN | 7509 | #ifdef CYGWIN |
| 7510 | if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1) | 7510 | if ((w32_message_fd = emacs_open_noquit ("/dev/windows", O_RDWR, 0)) |
| 7511 | == -1) | ||
| 7511 | fatal ("opening /dev/windows: %s", strerror (errno)); | 7512 | fatal ("opening /dev/windows: %s", strerror (errno)); |
| 7512 | #endif /* CYGWIN */ | 7513 | #endif /* CYGWIN */ |
| 7513 | 7514 | ||
diff --git a/src/window.c b/src/window.c index 5e78aa400b5..e025e0b0821 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -2663,12 +2663,15 @@ static void | |||
| 2663 | decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) | 2663 | decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) |
| 2664 | { | 2664 | { |
| 2665 | struct window *w = decode_live_window (*window); | 2665 | struct window *w = decode_live_window (*window); |
| 2666 | Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window; | ||
| 2666 | 2667 | ||
| 2667 | XSETWINDOW (*window, w); | 2668 | XSETWINDOW (*window, w); |
| 2668 | /* MINIBUF nil may or may not include minibuffers. Decide if it | 2669 | /* MINIBUF nil may or may not include minibuffers. Decide if it |
| 2669 | does. */ | 2670 | does. */ |
| 2670 | if (NILP (*minibuf)) | 2671 | if (NILP (*minibuf)) |
| 2671 | *minibuf = minibuf_level ? minibuf_window : Qlambda; | 2672 | *minibuf = this_minibuffer_depth (XWINDOW (miniwin)->contents) |
| 2673 | ? miniwin | ||
| 2674 | : Qlambda; | ||
| 2672 | else if (!EQ (*minibuf, Qt)) | 2675 | else if (!EQ (*minibuf, Qt)) |
| 2673 | *minibuf = Qlambda; | 2676 | *minibuf = Qlambda; |
| 2674 | 2677 | ||
diff --git a/src/window.h b/src/window.h index 332cb3091fd..79eb44e7a38 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -1124,10 +1124,6 @@ extern Lisp_Object echo_area_window; | |||
| 1124 | 1124 | ||
| 1125 | extern EMACS_INT command_loop_level; | 1125 | extern EMACS_INT command_loop_level; |
| 1126 | 1126 | ||
| 1127 | /* Depth in minibuffer invocations. */ | ||
| 1128 | |||
| 1129 | extern EMACS_INT minibuf_level; | ||
| 1130 | |||
| 1131 | /* Non-zero if we should redraw the mode lines on the next redisplay. | 1127 | /* Non-zero if we should redraw the mode lines on the next redisplay. |
| 1132 | Usually set to a unique small integer so we can track the main causes of | 1128 | Usually set to a unique small integer so we can track the main causes of |
| 1133 | full redisplays in `redisplay--mode-lines-cause'. */ | 1129 | full redisplays in `redisplay--mode-lines-cause'. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 6a4304d194b..ea67329cff1 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -9285,8 +9285,8 @@ move_it_in_display_line_to (struct it *it, | |||
| 9285 | if (may_wrap && char_can_wrap_before (it)) | 9285 | if (may_wrap && char_can_wrap_before (it)) |
| 9286 | { | 9286 | { |
| 9287 | /* We have reached a glyph that follows one or more | 9287 | /* We have reached a glyph that follows one or more |
| 9288 | whitespace characters or a character that allows | 9288 | whitespace characters or characters that allow |
| 9289 | wrapping after it. If this character allows | 9289 | wrapping after them. If this character allows |
| 9290 | wrapping before it, save this position as a | 9290 | wrapping before it, save this position as a |
| 9291 | wrapping point. */ | 9291 | wrapping point. */ |
| 9292 | if (atpos_it.sp >= 0) | 9292 | if (atpos_it.sp >= 0) |
| @@ -9303,7 +9303,6 @@ move_it_in_display_line_to (struct it *it, | |||
| 9303 | } | 9303 | } |
| 9304 | /* Otherwise, we can wrap here. */ | 9304 | /* Otherwise, we can wrap here. */ |
| 9305 | SAVE_IT (wrap_it, *it, wrap_data); | 9305 | SAVE_IT (wrap_it, *it, wrap_data); |
| 9306 | next_may_wrap = false; | ||
| 9307 | } | 9306 | } |
| 9308 | /* Update may_wrap for the next iteration. */ | 9307 | /* Update may_wrap for the next iteration. */ |
| 9309 | may_wrap = next_may_wrap; | 9308 | may_wrap = next_may_wrap; |
| @@ -10650,9 +10649,10 @@ include the height of both, if present, in the return value. */) | |||
| 10650 | bpos = BEGV_BYTE; | 10649 | bpos = BEGV_BYTE; |
| 10651 | while (bpos < ZV_BYTE) | 10650 | while (bpos < ZV_BYTE) |
| 10652 | { | 10651 | { |
| 10653 | c = fetch_char_advance (&start, &bpos); | 10652 | c = FETCH_BYTE (bpos); |
| 10654 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) | 10653 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) |
| 10655 | break; | 10654 | break; |
| 10655 | inc_both (&start, &bpos); | ||
| 10656 | } | 10656 | } |
| 10657 | while (bpos > BEGV_BYTE) | 10657 | while (bpos > BEGV_BYTE) |
| 10658 | { | 10658 | { |
| @@ -10681,7 +10681,10 @@ include the height of both, if present, in the return value. */) | |||
| 10681 | dec_both (&end, &bpos); | 10681 | dec_both (&end, &bpos); |
| 10682 | c = FETCH_BYTE (bpos); | 10682 | c = FETCH_BYTE (bpos); |
| 10683 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) | 10683 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) |
| 10684 | break; | 10684 | { |
| 10685 | inc_both (&end, &bpos); | ||
| 10686 | break; | ||
| 10687 | } | ||
| 10685 | } | 10688 | } |
| 10686 | while (bpos < ZV_BYTE) | 10689 | while (bpos < ZV_BYTE) |
| 10687 | { | 10690 | { |
diff --git a/src/xfaces.c b/src/xfaces.c index b3b19a9cb2e..258b365eda3 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -3293,7 +3293,8 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3293 | } | 3293 | } |
| 3294 | else if (EQ (k, QCstyle)) | 3294 | else if (EQ (k, QCstyle)) |
| 3295 | { | 3295 | { |
| 3296 | if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button)) | 3296 | if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button) |
| 3297 | && !EQ(v, Qflat_button)) | ||
| 3297 | break; | 3298 | break; |
| 3298 | } | 3299 | } |
| 3299 | else | 3300 | else |
| @@ -6031,6 +6032,10 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 6031 | face->box = FACE_RAISED_BOX; | 6032 | face->box = FACE_RAISED_BOX; |
| 6032 | else if (EQ (value, Qpressed_button)) | 6033 | else if (EQ (value, Qpressed_button)) |
| 6033 | face->box = FACE_SUNKEN_BOX; | 6034 | face->box = FACE_SUNKEN_BOX; |
| 6035 | else if (EQ (value, Qflat_button)) { | ||
| 6036 | face->box = FACE_SIMPLE_BOX; | ||
| 6037 | face->box_color = face->background; | ||
| 6038 | } | ||
| 6034 | } | 6039 | } |
| 6035 | } | 6040 | } |
| 6036 | } | 6041 | } |
| @@ -6919,6 +6924,7 @@ syms_of_xfaces (void) | |||
| 6919 | DEFSYM (Qwave, "wave"); | 6924 | DEFSYM (Qwave, "wave"); |
| 6920 | DEFSYM (Qreleased_button, "released-button"); | 6925 | DEFSYM (Qreleased_button, "released-button"); |
| 6921 | DEFSYM (Qpressed_button, "pressed-button"); | 6926 | DEFSYM (Qpressed_button, "pressed-button"); |
| 6927 | DEFSYM (Qflat_button, "flat-button"); | ||
| 6922 | DEFSYM (Qnormal, "normal"); | 6928 | DEFSYM (Qnormal, "normal"); |
| 6923 | DEFSYM (Qextra_light, "extra-light"); | 6929 | DEFSYM (Qextra_light, "extra-light"); |
| 6924 | DEFSYM (Qlight, "light"); | 6930 | DEFSYM (Qlight, "light"); |