218 lines
9.4 KiB
EmacsLisp
218 lines
9.4 KiB
EmacsLisp
;;; Eshell patches.
|
|
|
|
;;; Fix 27407, expected in Emacs 26.1.
|
|
;;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=4ebdcc46ab345849332332d580bd1e3c2c9adb1e
|
|
;;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=37cdfec7c73205668498da9b27387f5f3ccfebee
|
|
;;; Test:
|
|
;;;
|
|
;; (insert "echo \"\e[33mhello\e[0m\"")
|
|
;; (insert "echo \"\e[33mhello\"")
|
|
|
|
(with-eval-after-load 'ansi-color
|
|
(defun ansi-color-make-extent (from to &optional object)
|
|
"Make an extent for the range [FROM, TO) in OBJECT.
|
|
|
|
OBJECT defaults to the current buffer. XEmacs uses `make-extent', Emacs
|
|
uses `make-overlay'. XEmacs can use a buffer or a string for OBJECT,
|
|
Emacs requires OBJECT to be a buffer."
|
|
(if (fboundp 'make-extent)
|
|
(make-extent from to object)
|
|
;; In Emacs, the overlay might end at the process-mark in comint
|
|
;; buffers. In that case, new text will be inserted before the
|
|
;; process-mark, ie. inside the overlay (using insert-before-marks).
|
|
;; In order to avoid this, we use the `insert-behind-hooks' overlay
|
|
;; property to make sure it works.
|
|
(let ((overlay (make-overlay from to object)))
|
|
(overlay-put overlay 'modification-hooks '(ansi-color-freeze-overlay))
|
|
(overlay-put overlay 'insert-behind-hooks '(ansi-color-freeze-overlay))
|
|
overlay))))
|
|
|
|
(with-eval-after-load "esh-mode"
|
|
(defun eshell-output-filter (process string)
|
|
"Send the output from PROCESS (STRING) to the interactive display.
|
|
This is done after all necessary filtering has been done."
|
|
(let ((oprocbuf (if process (process-buffer process)
|
|
(current-buffer)))
|
|
(inhibit-point-motion-hooks t)
|
|
(inhibit-modification-hooks t))
|
|
(let ((functions eshell-preoutput-filter-functions))
|
|
(while (and functions string)
|
|
(setq string (funcall (car functions) string))
|
|
(setq functions (cdr functions))))
|
|
(if (and string oprocbuf (buffer-name oprocbuf))
|
|
(let (opoint obeg oend)
|
|
(with-current-buffer oprocbuf
|
|
(setq opoint (point))
|
|
(setq obeg (point-min))
|
|
(setq oend (point-max))
|
|
(let ((buffer-read-only nil)
|
|
(nchars (length string))
|
|
(ostart nil))
|
|
(widen)
|
|
(goto-char eshell-last-output-end)
|
|
(setq ostart (point))
|
|
(if (<= (point) opoint)
|
|
(setq opoint (+ opoint nchars)))
|
|
(if (< (point) obeg)
|
|
(setq obeg (+ obeg nchars)))
|
|
(if (<= (point) oend)
|
|
(setq oend (+ oend nchars)))
|
|
;; Let the ansi-color overlay hooks run.
|
|
(let ((inhibit-modification-hooks nil))
|
|
(insert-before-markers string))
|
|
(if (= (window-start) (point))
|
|
(set-window-start (selected-window)
|
|
(- (point) nchars)))
|
|
(if (= (point) eshell-last-input-end)
|
|
(set-marker eshell-last-input-end
|
|
(- eshell-last-input-end nchars)))
|
|
(set-marker eshell-last-output-start ostart)
|
|
(set-marker eshell-last-output-end (point))
|
|
(force-mode-line-update))
|
|
(narrow-to-region obeg oend)
|
|
(goto-char opoint)
|
|
(eshell-run-output-filters)))))))
|
|
|
|
(with-eval-after-load 'em-prompt
|
|
(defun eshell-emit-prompt ()
|
|
"Emit a prompt if eshell is being used interactively."
|
|
(when (boundp 'ansi-color-context-region)
|
|
(setq ansi-color-context-region nil))
|
|
(run-hooks 'eshell-before-prompt-hook)
|
|
(if (not eshell-prompt-function)
|
|
(set-marker eshell-last-output-end (point))
|
|
(let ((prompt (funcall eshell-prompt-function)))
|
|
(and eshell-highlight-prompt
|
|
(add-text-properties 0 (length prompt)
|
|
'(read-only t
|
|
font-lock-face eshell-prompt
|
|
front-sticky (font-lock-face read-only)
|
|
rear-nonsticky (font-lock-face read-only))
|
|
prompt))
|
|
(eshell-interactive-print prompt)))
|
|
(run-hooks 'eshell-after-prompt-hook)))
|
|
|
|
;;; Fix 27405, expected in Emacs 26.1.
|
|
;;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27405
|
|
;;; Emacs' standard functions fail when output has empty lines.
|
|
;;; The following implementation is more reliable.
|
|
(with-eval-after-load 'em-prompt
|
|
(defun eshell-next-prompt (n)
|
|
"Move to end of Nth next prompt in the buffer.
|
|
See `eshell-prompt-regexp'."
|
|
(interactive "p")
|
|
(re-search-forward eshell-prompt-regexp nil t n)
|
|
(when eshell-highlight-prompt
|
|
(while (not (get-text-property (line-beginning-position) 'read-only) )
|
|
(re-search-forward eshell-prompt-regexp nil t n)))
|
|
(eshell-skip-prompt))
|
|
|
|
(defun eshell-previous-prompt (n)
|
|
"Move to end of Nth previous prompt in the buffer.
|
|
See `eshell-prompt-regexp'."
|
|
(interactive "p")
|
|
(backward-char)
|
|
(eshell-next-prompt (- n))))
|
|
|
|
;;; Fix bug#29157: 25.3; Eshell parsing fails sometimes [...]
|
|
(with-eval-after-load 'em-hist
|
|
(defun eshell-hist-initialize ()
|
|
"Initialize the history management code for one Eshell buffer."
|
|
;; PATCH: Disable the history references.
|
|
;; (add-hook 'eshell-expand-input-functions
|
|
;; 'eshell-expand-history-references nil t)
|
|
|
|
(when (eshell-using-module 'eshell-cmpl)
|
|
(add-hook 'pcomplete-try-first-hook
|
|
'eshell-complete-history-reference nil t))
|
|
|
|
(if (and (eshell-using-module 'eshell-rebind)
|
|
(not eshell-non-interactive-p))
|
|
(let ((rebind-alist eshell-rebind-keys-alist))
|
|
(make-local-variable 'eshell-rebind-keys-alist)
|
|
(setq eshell-rebind-keys-alist
|
|
(append rebind-alist eshell-hist-rebind-keys-alist))
|
|
(set (make-local-variable 'search-invisible) t)
|
|
(set (make-local-variable 'search-exit-option) t)
|
|
(add-hook 'isearch-mode-hook
|
|
(function
|
|
(lambda ()
|
|
(if (>= (point) eshell-last-output-end)
|
|
(setq overriding-terminal-local-map
|
|
eshell-isearch-map)))) nil t)
|
|
(add-hook 'isearch-mode-end-hook
|
|
(function
|
|
(lambda ()
|
|
(setq overriding-terminal-local-map nil))) nil t))
|
|
(define-key eshell-mode-map [up] 'eshell-previous-matching-input-from-input)
|
|
(define-key eshell-mode-map [down] 'eshell-next-matching-input-from-input)
|
|
(define-key eshell-mode-map [(control up)] 'eshell-previous-input)
|
|
(define-key eshell-mode-map [(control down)] 'eshell-next-input)
|
|
(define-key eshell-mode-map [(meta ?r)] 'eshell-previous-matching-input)
|
|
(define-key eshell-mode-map [(meta ?s)] 'eshell-next-matching-input)
|
|
(define-key eshell-command-map [(meta ?r)]
|
|
'eshell-previous-matching-input-from-input)
|
|
(define-key eshell-command-map [(meta ?s)]
|
|
'eshell-next-matching-input-from-input)
|
|
(if eshell-hist-match-partial
|
|
(progn
|
|
(define-key eshell-mode-map [(meta ?p)]
|
|
'eshell-previous-matching-input-from-input)
|
|
(define-key eshell-mode-map [(meta ?n)]
|
|
'eshell-next-matching-input-from-input)
|
|
(define-key eshell-command-map [(meta ?p)] 'eshell-previous-input)
|
|
(define-key eshell-command-map [(meta ?n)] 'eshell-next-input))
|
|
(define-key eshell-mode-map [(meta ?p)] 'eshell-previous-input)
|
|
(define-key eshell-mode-map [(meta ?n)] 'eshell-next-input)
|
|
(define-key eshell-command-map [(meta ?p)]
|
|
'eshell-previous-matching-input-from-input)
|
|
(define-key eshell-command-map [(meta ?n)]
|
|
'eshell-next-matching-input-from-input)))
|
|
|
|
(make-local-variable 'eshell-history-size)
|
|
(or eshell-history-size
|
|
(let ((hsize (getenv "HISTSIZE")))
|
|
(setq eshell-history-size
|
|
(if (and (stringp hsize)
|
|
(integerp (setq hsize (string-to-number hsize)))
|
|
(> hsize 0))
|
|
hsize
|
|
128))))
|
|
|
|
(make-local-variable 'eshell-history-file-name)
|
|
(or eshell-history-file-name
|
|
(setq eshell-history-file-name (getenv "HISTFILE")))
|
|
|
|
(make-local-variable 'eshell-history-index)
|
|
(make-local-variable 'eshell-save-history-index)
|
|
|
|
(if (minibuffer-window-active-p (selected-window))
|
|
(set (make-local-variable 'eshell-save-history-on-exit) nil)
|
|
(set (make-local-variable 'eshell-history-ring) nil)
|
|
(if eshell-history-file-name
|
|
(eshell-read-history nil t))
|
|
|
|
(add-hook 'eshell-exit-hook 'eshell-write-history nil t))
|
|
|
|
(unless eshell-history-ring
|
|
(setq eshell-history-ring (make-ring eshell-history-size)))
|
|
|
|
(add-hook 'eshell-exit-hook 'eshell-write-history nil t)
|
|
|
|
(add-hook 'kill-emacs-hook 'eshell-save-some-history)
|
|
|
|
(make-local-variable 'eshell-input-filter-functions)
|
|
(add-hook 'eshell-input-filter-functions 'eshell-add-to-history nil t)
|
|
|
|
(define-key eshell-command-map [(control ?l)] 'eshell-list-history)
|
|
(define-key eshell-command-map [(control ?x)] 'eshell-get-next-from-history)))
|
|
|
|
;;; Fix 29854, expected in Emacs 26.1?
|
|
(setq
|
|
ansi-color-apply-face-function
|
|
(lambda (beg end face)
|
|
(when face
|
|
(put-text-property beg end 'face face))))
|
|
|
|
(provide 'patch-eshell)
|