aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/eshell
diff options
context:
space:
mode:
authorDmitry Gutov2022-08-15 02:22:59 +0300
committerDmitry Gutov2022-08-15 02:22:59 +0300
commitee3a674c7c9e39fe7ff296ce1f9830fc45520de8 (patch)
treee8ba1e7be54314f208454e80e3d31044c913f3eb /lisp/eshell
parentfe0e53d963899a16e0dd1bbc1ba10a6b59f7989e (diff)
parent0a8e88fd83db5398d36064a7f87cff5b57da7284 (diff)
downloademacs-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.el2
-rw-r--r--lisp/eshell/esh-cmd.el85
-rw-r--r--lisp/eshell/esh-io.el50
-rw-r--r--lisp/eshell/esh-proc.el68
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."
133Such arguments will be passed to `read', and then evaluated." 133Such 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."
551The first of NAMES should be the positive form, and the second the 553The first of NAMES should be the positive form, and the second the
552negative. It's not likely that users should ever need to call this 554negative. It's not likely that users should ever need to call this
553function." 555function."
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.
259If HANDLES is nil, use `eshell-current-handles'.
260
261EXIT-CODE is the process exit code (zero, if the command
262completed successfully). If nil, then use the exit code already
263set in `eshell-last-command-status'.
264
265RESULT is the quoted value of the last command. If nil, then use
266the 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.
259STATUS should be non-nil on successful termination of the output." 283STATUS 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.
310EXIT-CODE is the process exit code; mainly, it is zero, if the command
311completed successfully. RESULT is the quoted value of the last
312command. If nil, then the meta variables for keeping track of the
313last 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)