Search code examples
shellemacscontrol-characters

How to handle make-process output including control character


I want to handle make-process output including control character.

(setq proc
      (make-process
       :name "sh"
       :buffer (get-buffer-create "*proc*")
       :command '("hub" "clone" "emacs-mirror/emacs")
       :filter (lambda (proc string)
                 (when (buffer-live-p (process-buffer proc))
                   (with-current-buffer (process-buffer proc)
                     (let ((moving (= (point) (process-mark proc))))
                       (save-excursion
                         (goto-char (process-mark proc))
                         (insert string)
                         (set-marker (process-mark proc) (point)))
                       (if moving (goto-char (process-mark proc)))))))))

But, control character inserted as-is. How to handle it like shell?

enter image description here

Note: Maybe related manual page


Solution

  • Use Eshell internal output filter generates a good result.

    Needless whole Eshell (don't enter eshell-mode), setting some markers makes us able to use eshell-output-filter function.

    (with-current-buffer (get-buffer-create "*proc*")
      (set (make-local-variable 'eshell-last-input-start) (point-marker))
      (set (make-local-variable 'eshell-last-input-end) (point-marker))
      (set (make-local-variable 'eshell-last-output-start) (point-marker))
      (set (make-local-variable 'eshell-last-output-end) (point-marker))
      (set (make-local-variable 'eshell-last-output-block-begin) (point)))
    ;;=> 1
    
    (setq proc
          (make-process
           :name "sh"
           :buffer (get-buffer-create "*proc*")
           :command '("hub" "clone" "emacs-mirror/emacs")
           :filter (lambda (proc string)
                     (when (buffer-live-p (process-buffer proc))
                       (with-current-buffer (process-buffer proc)
                         (let ((moving (= (point) (process-mark proc))))
                           (save-excursion
                             (goto-char (process-mark proc))
                             (let ((inhibit-read-only t))
                               (eshell-output-filter proc string))
                             (set-marker (process-mark proc) (point)))
                           (if moving (goto-char (process-mark proc)))))))))
    ;;=> #<process sh>
    
    (delete-process proc)    ; kill the process when you want
    ;;=> nil