Frage

My intention is to use bm.el Visible Bookmarks for each prompt as I press RET. I have managed to achieve this to a some degree.. Please comment on my code, below, if it is missing some important issue: eg. I have no idea if I need to handle the args beyond just passing them on to the default function.

When I press RET on an empty command line, I do not want to bookmark that line. How can I intercept the command line content before passing contol on to the default function eshell-send-input?

(defun eshell-send-input-zAp (&optional use-region queue-p no-newline)
  "eshell-send-input, customized to add bm-bookmark to prompt line"
 (interactive)
  (bm-bookmark-add)
  (eshell-send-input use-region queue-p no-newline))

(add-hook 'eshell-mode-hook
          #'(lambda ()
              (define-key eshell-mode-map
                [return]
                'eshell-send-input-zAp)))
War es hilfreich?

Lösung

Your code looks decent. If you read the code of eshell-send-input, you'll see how to get the current input.

Also read up on interactive arguments. "P" is required to pass the user-region on to eshell-send-input.

(defun eshell-send-input-zAp (&optional use-region queue-p no-newline)
  "eshell-send-input, customized to add bm-bookmark to prompt line"
  (interactive "*P")
  (unless (string-equal (eshell-get-old-input use-region) "")
    (bm-bookmark-add))
  (eshell-send-input use-region queue-p no-newline))

Andere Tipps

esh-mode defines a variable eshell-last-output-end which it updates each time the output is printed. So, you can grab the string which is to be sent to the shell by doing something like (buffer-substring eshell-last-output-end (point-max)) I believe.

EDIT: quote from the documentation on eshel-send-input:

"Send the input received to Eshell for parsing and processing. After eshell-last-output-end, sends all text from that marker to point as input. Before that marker, calls `eshell-get-old-input' to retrieve old input, copies it to the end of the buffer, and sends it.

If USE-REGION is non-nil, the current region (between point and mark) will be used as input.

If QUEUE-P is non-nil, input will be queued until the next prompt, rather than sent to the currently active process. If no process, the input is processed immediately.

If NO-NEWLINE is non-nil, the input is sent without an implied final newline."

Accent is mine. And if you look into the source of eshel-send-input, you may get the idea of how it is used.

To reflect on event_jr's answer - you don't necessarily need to pass universal argument to this function if your own function has no such option... Obviously, so far you have no use for that, that's sort of unnecessary.

(Answering my own question)... I realized that eshell is at its core just an emacs buffer, So, with that in mind, I've come up with this method, which does work, but perhaps could be done better. Maybe there is something about it which I'm yet unaware of, so I'm still open to suggestions.

(defun eshell-send-input-zAp (&optional use-region queue-p no-newline)
  "A customized `eshell-send-input`, to add bm-bookmark to prompt line" 
  (interactive)
  (let ((line (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
    (if (string-match eshell-prompt-regexp line)
        (if (> (length (substring line (match-end 0))) 0)
            (bm-bookmark-add))))
  (eshell-send-input use-region queue-p no-newline))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top