Function: ghostel--update-directory

ghostel--update-directory is a natively compiled function defined in ghostel.el.

Signature

(ghostel--update-directory DIR)

Documentation

Update default-directory from terminal's OSC 7 report.

DIR may be a kitty-shell-cwd:// URL (raw, unencoded path), a file:// URL (path percent-decoded), or a plain path. When the hostname in a URL does not match the local machine, construct a TRAMP path.

Source Code

;; Defined in /nix/store/1252krff0gb2kisjcpp45m50cpdskfrl-emacs-packages-deps/share/emacs/site-lisp/ghostel.el
(defun ghostel--update-directory (dir)
  "Update `default-directory' from terminal's OSC 7 report.
DIR may be a kitty-shell-cwd:// URL (raw, unencoded path), a file://
URL (path percent-decoded), or a plain path.  When the hostname in a
URL does not match the local machine, construct a TRAMP path."
  (when (and dir (not (equal dir ghostel--last-directory)))
    (setq ghostel--last-directory dir)
    (let (host raw filename path)
      (cond
       ;; Split scheme://host/path by hand: `url-generic-parse-url' would treat
       ;; `#'/`?' in the path as fragment/query, but emitters that don't escape
       ;; them (kitty-shell-cwd verbatim contract, nushell) send them literally.
       ((string-match "\\`\\(kitty-shell-cwd\\|file\\)://" dir)
        (let* ((rest (substring dir (match-end 0)))
               (slash (string-search "/" rest)))
          (when slash
            ;; Downcased like `url-host' - a mixed-case hostname must
            ;; not fork the TRAMP connection identity.
            (setq host (downcase (substring rest 0 slash))
                  raw (substring rest slash)
                  filename
                  (if (equal (match-string 1 dir) "kitty-shell-cwd")
                      raw
                    ;; The encode step keeps `url-unhex-string' from
                    ;; mangling multibyte text that arrived unescaped;
                    ;; utf-8-unix stops eol detection from rewriting a
                    ;; %0D carriage return to LF.
                    (let ((decoded (decode-coding-string
                                    (url-unhex-string
                                     (encode-coding-string raw 'utf-8) t)
                                    'utf-8-unix)))
                      ;; %00 never names a real directory, and a NUL
                      ;; would make `file-directory-p' signal.
                      (if (string-match-p "\0" decoded) raw decoded))))
            ;; A Windows-style $PWD ("d:/...", no leading slash) glues
            ;; its drive spec onto the authority: scheme://HOSTd:/...
            ;; Only a local-host prefix disambiguates this from an RFC 3986
            ;; empty-port authority; a foreign host keeps its glued spelling.
            (if (and (string-match "\\`\\(.*\\)\\([a-z]:\\)\\'" host)
                     (ghostel--local-host-p (match-string 1 host)))
                (setq raw (concat (match-string 2 host) raw)
                      filename (concat (match-string 2 host) filename)
                      host (match-string 1 host))
              ;; Trailing colon for an empty port is not part of a hostname
              (when (string-suffix-p ":" host)
                (setq host (substring host 0 -1)))))))
       ;; A URI with an unrecognized scheme is not a plain path (OSC 9;9).
       ((string-match-p "\\`[[:alpha:]][[:alnum:]+.-]*://" dir)
        (message "ghostel: ignoring OSC 7 report with unknown scheme: %s"
                 (truncate-string-to-width dir 40)))
       (t (setq path dir)))
      (when filename
        (if (ghostel--local-host-p host)
            ;; Emitters that don't escape `%' (nushell) send `%XX' literally.
            ;; When only the raw spelling names a directory, it is the real one.
            (setq path (if (and raw
                                (not (file-directory-p filename))
                                (file-directory-p raw))
                           raw
                         filename))
          ;; Remote host - construct a TRAMP path.
          ;; Reuse the full remote prefix from default-directory
          ;; when available (preserves multi-hop, method, user).
          (let ((prefix (file-remote-p default-directory)))
            (setq path (if prefix
                           (concat prefix filename)
                         (format "/%s:%s:%s"
                                 (or ghostel-tramp-default-method
                                     tramp-default-method)
                                 host filename))))))
      (when (and path (not (string= path "")))
        (if (file-remote-p path)
            ;; Trust the shell's report; skip file-directory-p to avoid
            ;; synchronous TRAMP connections on every cd.
            (setq default-directory (file-name-as-directory path)
                  list-buffers-directory default-directory)
          (when (eq system-type 'windows-nt)
            (setq path (ghostel--windows-local-path path)))
          (when (file-directory-p path)
            (setq default-directory (file-name-as-directory path)
                  list-buffers-directory default-directory))))
      (when ghostel-buffer-name-function
        (ghostel--rename-managed
         (funcall ghostel-buffer-name-function ghostel-title)))
      (ghostel--buffer-identification-update))))