Function: ghostel-bookmark-handler

ghostel-bookmark-handler is an autoloaded and natively compiled function defined in ghostel-bookmark.el.

Signature

(ghostel-bookmark-handler BMK)

Documentation

Restore the ghostel bookmark BMK.

Reuse a live ghostel buffer: slot identities match whole, command records match a live buffer running the recorded command, other records match by name (title tracking may have renamed the buffer). Otherwise create one in the bookmarked directory, respawning the recorded command or starting a shell. Respawned buffers are plain ghostel-exec buffers; kind-specific setup (e.g. eshell's visual-command exit behavior) is not restored. When a reused shell's directory differs and ghostel-bookmark-check-dir is non-nil, a cd is typed into it, but only while the shell is idle
(see ghostel-bookmark--shell-idle-p); command buffers are left alone.

Aliases

ghostel--bookmark-handler (obsolete since 0.51.0)

Source Code

;; Defined in /nix/store/1252krff0gb2kisjcpp45m50cpdskfrl-emacs-packages-deps/share/emacs/site-lisp/ghostel-bookmark.el
;;;###autoload
(defun ghostel-bookmark-handler (bmk)
  "Restore the ghostel bookmark BMK.
Reuse a live ghostel buffer: slot identities match whole, command
records match a live buffer running the recorded command, other
records match by name (title tracking may have renamed the buffer).
Otherwise create one in the bookmarked directory, respawning the
recorded `command' or starting a shell.  Respawned buffers are plain
`ghostel-exec' buffers; kind-specific setup (e.g. eshell's
visual-command exit behavior) is not restored.
When a reused shell's directory differs and `ghostel-bookmark-check-dir'
is non-nil, a `cd' is typed into it, but only while the shell is idle
\(see `ghostel-bookmark--shell-idle-p'); command buffers are left alone."
  (ghostel--load-module t)
  (let* ((dir (bookmark-prop-get bmk 'location))
         (buf-name (bookmark-prop-get bmk 'buf-name))
         ;; Bookmark files are external data; treat a non-alist identity
         ;; as absent.
         (identity (let ((id (bookmark-prop-get bmk 'identity)))
                     (and (consp id) id)))
         (command (alist-get 'command identity))
         (live-p (lambda (b)
                   (let ((p (and b (buffer-local-value 'ghostel--process b))))
                     (and p (process-live-p p) b))))
         ;; Retained dead-shell buffers may share the identity; reuse only
         ;; a live one.  Slot identities (with an `instance') are unique;
         ;; command records reattach to a live buffer running the same
         ;; command (its name may have been uniquified); the rest reuse
         ;; by name.
         (buf (cond
               ((alist-get 'instance identity)
                (ghostel--find-buffer-by-identity identity live-p))
               (command
                (let ((match-p
                       (lambda (b)
                         (and (with-current-buffer b
                                (and (derived-mode-p 'ghostel-mode)
                                     (ghostel-identity-match-p
                                      `((command . ,command))
                                      ghostel-identity)))
                              (funcall live-p b)))))
                  ;; Prefer the recorded name so several buffers running
                  ;; the same command each reattach to their own bookmark.
                  (or (when-let* ((b (get-buffer buf-name)))
                        (funcall match-p b))
                      (seq-find match-p (buffer-list)))))
               (t
                (let ((b (get-buffer buf-name)))
                  (and b
                       (eq (buffer-local-value 'major-mode b) 'ghostel-mode)
                       (funcall live-p b)))))))
    ;; Create branch: the program starts directly in DIR (no `cd').
    (unless buf
      (let ((default-directory (if ghostel-bookmark-check-dir
                                   dir
                                 default-directory)))
        (if command
            (condition-case err
                (progn
                  (setq buf (generate-new-buffer buf-name))
                  (ghostel-exec buf (car command) (cdr command) identity))
              ((error quit)
               (when (buffer-live-p buf) (kill-buffer buf))
               (signal (car err) (cdr err))))
          (setq buf (ghostel-create buf-name nil identity)))))
    ;; Reuse branch: `cd' if the live shell has wandered elsewhere.  A
    ;; typed `cd' only makes sense in a shell, not in a command buffer.
    (with-current-buffer buf
      (when (and ghostel-bookmark-check-dir
                 ghostel--term
                 (not (alist-get 'command ghostel-identity))
                 (not (or (string-equal default-directory dir)
                          (and (not (file-remote-p dir))
                               (file-equal-p default-directory dir)))))
        (if (not (ghostel-bookmark--shell-idle-p))
            (message "Ghostel: %s is busy, staying in %s"
                     (buffer-name) default-directory)
          (when (memq ghostel--input-mode '(copy emacs))
            (ghostel-readonly-exit))
          ;; We record remote dirs as TRAMP paths, so strip the TRAMP prefix
          ;; with `file-local-name', and quote so paths with spaces survive.
          (ghostel-send-string
           (concat "cd " (shell-quote-argument (file-local-name dir))))
          (ghostel-send-key "return"))))
    (set-buffer buf)))