diff options
| author | Dmitry Gutov | 2022-08-15 02:22:59 +0300 |
|---|---|---|
| committer | Dmitry Gutov | 2022-08-15 02:22:59 +0300 |
| commit | ee3a674c7c9e39fe7ff296ce1f9830fc45520de8 (patch) | |
| tree | e8ba1e7be54314f208454e80e3d31044c913f3eb /lisp/eshell | |
| parent | fe0e53d963899a16e0dd1bbc1ba10a6b59f7989e (diff) | |
| parent | 0a8e88fd83db5398d36064a7f87cff5b57da7284 (diff) | |
| download | emacs-scratch/font_lock_large_files.tar.gz emacs-scratch/font_lock_large_files.zip | |
Merge branch 'master' into scratch/font_lock_large_filesscratch/font_lock_large_files
Diffstat (limited to 'lisp/eshell')
| -rw-r--r-- | lisp/eshell/em-alias.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/esh-cmd.el | 85 | ||||
| -rw-r--r-- | lisp/eshell/esh-io.el | 50 | ||||
| -rw-r--r-- | lisp/eshell/esh-proc.el | 68 |
4 files changed, 106 insertions, 99 deletions
diff --git a/lisp/eshell/em-alias.el b/lisp/eshell/em-alias.el index 5d3aaf7c81c..9ad218d5988 100644 --- a/lisp/eshell/em-alias.el +++ b/lisp/eshell/em-alias.el | |||
| @@ -206,7 +206,7 @@ file named by `eshell-aliases-file'.") | |||
| 206 | (let ((eshell-current-handles | 206 | (let ((eshell-current-handles |
| 207 | (eshell-create-handles eshell-aliases-file 'overwrite))) | 207 | (eshell-create-handles eshell-aliases-file 'overwrite))) |
| 208 | (eshell/alias) | 208 | (eshell/alias) |
| 209 | (eshell-close-handles 0)))) | 209 | (eshell-close-handles 0 'nil)))) |
| 210 | 210 | ||
| 211 | (defsubst eshell-lookup-alias (name) | 211 | (defsubst eshell-lookup-alias (name) |
| 212 | "Check whether NAME is aliased. Return the alias if there is one." | 212 | "Check whether NAME is aliased. Return the alias if there is one." |
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 775e4c1057e..62c95056fd2 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el | |||
| @@ -133,6 +133,10 @@ There are several different kinds of commands, however." | |||
| 133 | Such arguments will be passed to `read', and then evaluated." | 133 | Such arguments will be passed to `read', and then evaluated." |
| 134 | :type 'regexp) | 134 | :type 'regexp) |
| 135 | 135 | ||
| 136 | (defcustom eshell-lisp-form-nil-is-failure t | ||
| 137 | "If non-nil, Lisp forms like (COMMAND ARGS) treat a nil result as failure." | ||
| 138 | :type 'boolean) | ||
| 139 | |||
| 136 | (defcustom eshell-pre-command-hook nil | 140 | (defcustom eshell-pre-command-hook nil |
| 137 | "A hook run before each interactive command is invoked." | 141 | "A hook run before each interactive command is invoked." |
| 138 | :type 'hook) | 142 | :type 'hook) |
| @@ -541,9 +545,7 @@ implemented via rewriting, rather than as a function." | |||
| 541 | ,(eshell-invokify-arg body t))) | 545 | ,(eshell-invokify-arg body t))) |
| 542 | (setcar for-items (cadr for-items)) | 546 | (setcar for-items (cadr for-items)) |
| 543 | (setcdr for-items (cddr for-items))) | 547 | (setcdr for-items (cddr for-items))) |
| 544 | (eshell-close-handles | 548 | (eshell-close-handles))))) |
| 545 | eshell-last-command-status | ||
| 546 | (list 'quote eshell-last-command-result)))))) | ||
| 547 | 549 | ||
| 548 | (defun eshell-structure-basic-command (func names keyword test body | 550 | (defun eshell-structure-basic-command (func names keyword test body |
| 549 | &optional else) | 551 | &optional else) |
| @@ -551,10 +553,11 @@ implemented via rewriting, rather than as a function." | |||
| 551 | The first of NAMES should be the positive form, and the second the | 553 | The first of NAMES should be the positive form, and the second the |
| 552 | negative. It's not likely that users should ever need to call this | 554 | negative. It's not likely that users should ever need to call this |
| 553 | function." | 555 | function." |
| 554 | ;; If the test form begins with `eshell-convert', it means | 556 | ;; If the test form begins with `eshell-convert' or |
| 555 | ;; something data-wise will be returned, and we should let | 557 | ;; `eshell-escape-arg', it means something data-wise will be |
| 556 | ;; that determine the truth of the statement. | 558 | ;; returned, and we should let that determine the truth of the |
| 557 | (unless (eq (car test) 'eshell-convert) | 559 | ;; statement. |
| 560 | (unless (memq (car test) '(eshell-convert eshell-escape-arg)) | ||
| 558 | (setq test | 561 | (setq test |
| 559 | `(progn ,test | 562 | `(progn ,test |
| 560 | (eshell-exit-success-p)))) | 563 | (eshell-exit-success-p)))) |
| @@ -574,9 +577,7 @@ function." | |||
| 574 | `(let ((eshell-command-body '(nil)) | 577 | `(let ((eshell-command-body '(nil)) |
| 575 | (eshell-test-body '(nil))) | 578 | (eshell-test-body '(nil))) |
| 576 | (,func ,test ,body ,else) | 579 | (,func ,test ,body ,else) |
| 577 | (eshell-close-handles | 580 | (eshell-close-handles))) |
| 578 | eshell-last-command-status | ||
| 579 | (list 'quote eshell-last-command-result)))) | ||
| 580 | 581 | ||
| 581 | (defun eshell-rewrite-while-command (terms) | 582 | (defun eshell-rewrite-while-command (terms) |
| 582 | "Rewrite a `while' command into its equivalent Eshell command form. | 583 | "Rewrite a `while' command into its equivalent Eshell command form. |
| @@ -1415,43 +1416,53 @@ via `eshell-errorn'." | |||
| 1415 | (defun eshell-lisp-command (object &optional args) | 1416 | (defun eshell-lisp-command (object &optional args) |
| 1416 | "Insert Lisp OBJECT, using ARGS if a function." | 1417 | "Insert Lisp OBJECT, using ARGS if a function." |
| 1417 | (catch 'eshell-external ; deferred to an external command | 1418 | (catch 'eshell-external ; deferred to an external command |
| 1419 | (setq eshell-last-command-status 0 | ||
| 1420 | eshell-last-arguments args) | ||
| 1418 | (let* ((eshell-ensure-newline-p (eshell-interactive-output-p)) | 1421 | (let* ((eshell-ensure-newline-p (eshell-interactive-output-p)) |
| 1422 | (command-form-p (functionp object)) | ||
| 1419 | (result | 1423 | (result |
| 1420 | (if (functionp object) | 1424 | (if command-form-p |
| 1421 | (progn | 1425 | (let ((numeric (not (get object |
| 1422 | (setq eshell-last-arguments args | 1426 | 'eshell-no-numeric-conversions))) |
| 1423 | eshell-last-command-name | 1427 | (fname-args (get object 'eshell-filename-arguments))) |
| 1428 | (when (or numeric fname-args) | ||
| 1429 | (while args | ||
| 1430 | (let ((arg (car args))) | ||
| 1431 | (cond | ||
| 1432 | ((and numeric (stringp arg) (> (length arg) 0) | ||
| 1433 | (text-property-any 0 (length arg) | ||
| 1434 | 'number t arg)) | ||
| 1435 | ;; If any of the arguments are flagged as | ||
| 1436 | ;; numbers waiting for conversion, convert | ||
| 1437 | ;; them now. | ||
| 1438 | (setcar args (string-to-number arg))) | ||
| 1439 | ((and fname-args (stringp arg) | ||
| 1440 | (string-equal arg "~")) | ||
| 1441 | ;; If any of the arguments match "~", | ||
| 1442 | ;; prepend "./" to treat it as a regular | ||
| 1443 | ;; file name. | ||
| 1444 | (setcar args (concat "./" arg))))) | ||
| 1445 | (setq args (cdr args)))) | ||
| 1446 | (setq eshell-last-command-name | ||
| 1424 | (concat "#<function " (symbol-name object) ">")) | 1447 | (concat "#<function " (symbol-name object) ">")) |
| 1425 | (let ((numeric (not (get object | ||
| 1426 | 'eshell-no-numeric-conversions))) | ||
| 1427 | (fname-args (get object 'eshell-filename-arguments))) | ||
| 1428 | (when (or numeric fname-args) | ||
| 1429 | (while args | ||
| 1430 | (let ((arg (car args))) | ||
| 1431 | (cond ((and numeric (stringp arg) (> (length arg) 0) | ||
| 1432 | (text-property-any 0 (length arg) | ||
| 1433 | 'number t arg)) | ||
| 1434 | ;; If any of the arguments are | ||
| 1435 | ;; flagged as numbers waiting for | ||
| 1436 | ;; conversion, convert them now. | ||
| 1437 | (setcar args (string-to-number arg))) | ||
| 1438 | ((and fname-args (stringp arg) | ||
| 1439 | (string-equal arg "~")) | ||
| 1440 | ;; If any of the arguments match "~", | ||
| 1441 | ;; prepend "./" to treat it as a | ||
| 1442 | ;; regular file name. | ||
| 1443 | (setcar args (concat "./" arg))))) | ||
| 1444 | (setq args (cdr args))))) | ||
| 1445 | (eshell-apply object eshell-last-arguments)) | 1448 | (eshell-apply object eshell-last-arguments)) |
| 1446 | (setq eshell-last-arguments args | 1449 | (setq eshell-last-command-name "#<Lisp object>") |
| 1447 | eshell-last-command-name "#<Lisp object>") | ||
| 1448 | (eshell-eval object)))) | 1450 | (eshell-eval object)))) |
| 1449 | (if (and eshell-ensure-newline-p | 1451 | (if (and eshell-ensure-newline-p |
| 1450 | (save-excursion | 1452 | (save-excursion |
| 1451 | (goto-char eshell-last-output-end) | 1453 | (goto-char eshell-last-output-end) |
| 1452 | (not (bolp)))) | 1454 | (not (bolp)))) |
| 1453 | (eshell-print "\n")) | 1455 | (eshell-print "\n")) |
| 1454 | (eshell-close-handles 0 (list 'quote result))))) | 1456 | (eshell-close-handles |
| 1457 | ;; If `eshell-lisp-form-nil-is-failure' is non-nil, Lisp forms | ||
| 1458 | ;; that succeeded but have a nil result should have an exit | ||
| 1459 | ;; status of 2. | ||
| 1460 | (when (and eshell-lisp-form-nil-is-failure | ||
| 1461 | (not command-form-p) | ||
| 1462 | (= eshell-last-command-status 0) | ||
| 1463 | (not result)) | ||
| 1464 | 2) | ||
| 1465 | (list 'quote result))))) | ||
| 1455 | 1466 | ||
| 1456 | (defalias 'eshell-lisp-command* #'eshell-lisp-command) | 1467 | (defalias 'eshell-lisp-command* #'eshell-lisp-command) |
| 1457 | 1468 | ||
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index 68e52a2c9c8..27703976f6d 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el | |||
| @@ -254,6 +254,30 @@ a nil value of mode defaults to `insert'." | |||
| 254 | (setq idx (1+ idx)))) | 254 | (setq idx (1+ idx)))) |
| 255 | handles) | 255 | handles) |
| 256 | 256 | ||
| 257 | (defun eshell-close-handles (&optional exit-code result handles) | ||
| 258 | "Close all of the current HANDLES, taking refcounts into account. | ||
| 259 | If HANDLES is nil, use `eshell-current-handles'. | ||
| 260 | |||
| 261 | EXIT-CODE is the process exit code (zero, if the command | ||
| 262 | completed successfully). If nil, then use the exit code already | ||
| 263 | set in `eshell-last-command-status'. | ||
| 264 | |||
| 265 | RESULT is the quoted value of the last command. If nil, then use | ||
| 266 | the value already set in `eshell-last-command-result'." | ||
| 267 | (when exit-code | ||
| 268 | (setq eshell-last-command-status exit-code)) | ||
| 269 | (when result | ||
| 270 | (cl-assert (eq (car result) 'quote)) | ||
| 271 | (setq eshell-last-command-result (cadr result))) | ||
| 272 | (let ((handles (or handles eshell-current-handles))) | ||
| 273 | (dotimes (idx eshell-number-of-handles) | ||
| 274 | (when-let ((handle (aref handles idx))) | ||
| 275 | (setcdr handle (1- (cdr handle))) | ||
| 276 | (when (= (cdr handle) 0) | ||
| 277 | (dolist (target (ensure-list (car (aref handles idx)))) | ||
| 278 | (eshell-close-target target (= eshell-last-command-status 0))) | ||
| 279 | (setcar handle nil)))))) | ||
| 280 | |||
| 257 | (defun eshell-close-target (target status) | 281 | (defun eshell-close-target (target status) |
| 258 | "Close an output TARGET, passing STATUS as the result. | 282 | "Close an output TARGET, passing STATUS as the result. |
| 259 | STATUS should be non-nil on successful termination of the output." | 283 | STATUS should be non-nil on successful termination of the output." |
| @@ -305,32 +329,6 @@ STATUS should be non-nil on successful termination of the output." | |||
| 305 | ((consp target) | 329 | ((consp target) |
| 306 | (apply (car target) status (cdr target))))) | 330 | (apply (car target) status (cdr target))))) |
| 307 | 331 | ||
| 308 | (defun eshell-close-handles (exit-code &optional result handles) | ||
| 309 | "Close all of the current handles, taking refcounts into account. | ||
| 310 | EXIT-CODE is the process exit code; mainly, it is zero, if the command | ||
| 311 | completed successfully. RESULT is the quoted value of the last | ||
| 312 | command. If nil, then the meta variables for keeping track of the | ||
| 313 | last execution result should not be changed." | ||
| 314 | (let ((idx 0)) | ||
| 315 | (cl-assert (or (not result) (eq (car result) 'quote))) | ||
| 316 | (setq eshell-last-command-status exit-code | ||
| 317 | eshell-last-command-result (cadr result)) | ||
| 318 | (while (< idx eshell-number-of-handles) | ||
| 319 | (let ((handles (or handles eshell-current-handles))) | ||
| 320 | (when (aref handles idx) | ||
| 321 | (setcdr (aref handles idx) | ||
| 322 | (1- (cdr (aref handles idx)))) | ||
| 323 | (when (= (cdr (aref handles idx)) 0) | ||
| 324 | (let ((target (car (aref handles idx)))) | ||
| 325 | (if (not (listp target)) | ||
| 326 | (eshell-close-target target (= exit-code 0)) | ||
| 327 | (while target | ||
| 328 | (eshell-close-target (car target) (= exit-code 0)) | ||
| 329 | (setq target (cdr target))))) | ||
| 330 | (setcar (aref handles idx) nil)))) | ||
| 331 | (setq idx (1+ idx))) | ||
| 332 | nil)) | ||
| 333 | |||
| 334 | (defun eshell-kill-append (string) | 332 | (defun eshell-kill-append (string) |
| 335 | "Call `kill-append' with STRING, if it is indeed a string." | 333 | "Call `kill-append' with STRING, if it is indeed a string." |
| 336 | (if (stringp string) | 334 | (if (stringp string) |
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 99b43661f2c..c367b5cd643 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el | |||
| @@ -346,7 +346,9 @@ Used only on systems which do not support async subprocesses.") | |||
| 346 | (defvar eshell-last-output-end) ;Defined in esh-mode.el. | 346 | (defvar eshell-last-output-end) ;Defined in esh-mode.el. |
| 347 | (eshell-update-markers eshell-last-output-end) | 347 | (eshell-update-markers eshell-last-output-end) |
| 348 | ;; Simulate the effect of eshell-sentinel. | 348 | ;; Simulate the effect of eshell-sentinel. |
| 349 | (eshell-close-handles (if (numberp exit-status) exit-status -1)) | 349 | (eshell-close-handles |
| 350 | (if (numberp exit-status) exit-status -1) | ||
| 351 | (list 'quote (and (numberp exit-status) (= exit-status 0)))) | ||
| 350 | (eshell-kill-process-function command exit-status) | 352 | (eshell-kill-process-function command exit-status) |
| 351 | (or (bound-and-true-p eshell-in-pipeline-p) | 353 | (or (bound-and-true-p eshell-in-pipeline-p) |
| 352 | (setq eshell-last-sync-output-start nil)) | 354 | (setq eshell-last-sync-output-start nil)) |
| @@ -398,40 +400,36 @@ PROC is the process that's exiting. STRING is the exit message." | |||
| 398 | (when (buffer-live-p (process-buffer proc)) | 400 | (when (buffer-live-p (process-buffer proc)) |
| 399 | (with-current-buffer (process-buffer proc) | 401 | (with-current-buffer (process-buffer proc) |
| 400 | (unwind-protect | 402 | (unwind-protect |
| 401 | (let ((entry (assq proc eshell-process-list))) | 403 | (when-let ((entry (assq proc eshell-process-list))) |
| 402 | ; (if (not entry) | 404 | (unwind-protect |
| 403 | ; (error "Sentinel called for unowned process `%s'" | 405 | (unless (string= string "run") |
| 404 | ; (process-name proc)) | 406 | ;; Write the exit message if the status is |
| 405 | (when entry | 407 | ;; abnormal and the process is already writing |
| 406 | (unwind-protect | 408 | ;; to the terminal. |
| 407 | (progn | 409 | (when (and (eq proc (eshell-tail-process)) |
| 408 | (unless (string= string "run") | 410 | (not (string-match "^\\(finished\\|exited\\)" |
| 409 | ;; Write the exit message if the status is | 411 | string))) |
| 410 | ;; abnormal and the process is already writing | 412 | (funcall (process-filter proc) proc string)) |
| 411 | ;; to the terminal. | 413 | (let ((handles (nth 1 entry)) |
| 412 | (when (and (eq proc (eshell-tail-process)) | 414 | (str (prog1 (nth 3 entry) |
| 413 | (not (string-match "^\\(finished\\|exited\\)" | 415 | (setf (nth 3 entry) nil))) |
| 414 | string))) | 416 | (status (process-exit-status proc))) |
| 415 | (funcall (process-filter proc) proc string)) | 417 | ;; If we're in the middle of handling output |
| 416 | (let ((handles (nth 1 entry)) | 418 | ;; from this process then schedule the EOF for |
| 417 | (str (prog1 (nth 3 entry) | 419 | ;; later. |
| 418 | (setf (nth 3 entry) nil))) | 420 | (letrec ((finish-io |
| 419 | (status (process-exit-status proc))) | 421 | (lambda () |
| 420 | ;; If we're in the middle of handling output | 422 | (if (nth 4 entry) |
| 421 | ;; from this process then schedule the EOF for | 423 | (run-at-time 0 nil finish-io) |
| 422 | ;; later. | 424 | (when str |
| 423 | (letrec ((finish-io | 425 | (ignore-error 'eshell-pipe-broken |
| 424 | (lambda () | 426 | (eshell-output-object |
| 425 | (if (nth 4 entry) | 427 | str nil handles))) |
| 426 | (run-at-time 0 nil finish-io) | 428 | (eshell-close-handles |
| 427 | (when str | 429 | status (list 'quote (= status 0)) |
| 428 | (ignore-error 'eshell-pipe-broken | 430 | handles))))) |
| 429 | (eshell-output-object | 431 | (funcall finish-io)))) |
| 430 | str nil handles))) | 432 | (eshell-remove-process-entry entry))) |
| 431 | (eshell-close-handles | ||
| 432 | status 'nil handles))))) | ||
| 433 | (funcall finish-io))))) | ||
| 434 | (eshell-remove-process-entry entry)))) | ||
| 435 | (eshell-kill-process-function proc string))))) | 433 | (eshell-kill-process-function proc string))))) |
| 436 | 434 | ||
| 437 | (defun eshell-process-interact (func &optional all query) | 435 | (defun eshell-process-interact (func &optional all query) |