Function: ghostel--setup-remote-integration

ghostel--setup-remote-integration is a natively compiled function defined in ghostel-shell.el.

Signature

(ghostel--setup-remote-integration SHELL-TYPE)

Documentation

Set up shell integration on the remote host for SHELL-TYPE.

Reads the local integration script, writes it (with any necessary preamble) to a temporary file on the remote host. When the bundled terminfo is available locally, also pushes it to a remote temp dir over the same TRAMP connection and adds TERMINFO=... to the env. Returns a plist (:env :args :temp-files :temp-dirs) for ghostel--start-process. Returns nil on failure.

Source Code

;; Defined in /nix/store/1252krff0gb2kisjcpp45m50cpdskfrl-emacs-packages-deps/share/emacs/site-lisp/ghostel-shell.el
(defun ghostel--setup-remote-integration (shell-type)
  "Set up shell integration on the remote host for SHELL-TYPE.
Reads the local integration script, writes it (with any necessary
preamble) to a temporary file on the remote host.  When the bundled
terminfo is available locally, also pushes it to a remote temp dir
over the same TRAMP connection and adds `TERMINFO=...' to the env.
Returns a plist (:env :args :temp-files :temp-dirs) for
`ghostel--start-process'.
Returns nil on failure."
  (condition-case err
      (let* ((remote-prefix (file-remote-p default-directory))
             (ghostel-dir (ghostel--resource-root))
             (ext (symbol-name shell-type))
             (integration (ghostel--read-local-file
                           (expand-file-name
                            (format "etc/shell/ghostel.%s" ext) ghostel-dir)))
             (tinfo (and (ghostel--ssh-install-enabled-p)
                         (ghostel--push-remote-terminfo remote-prefix)))
             (base (pcase shell-type
                     ;; Bash: --rcfile replaces normal rc loading, so we source
                     ;; startup files explicitly before the integration.
                     ('bash
                      (let* ((temp (make-temp-file
                                    (concat remote-prefix "ghostel-") nil ".bash"))
                             (path (file-remote-p temp 'localname)))
                        (ghostel--write-remote-file
                         temp
                         (concat
                          "# Source standard startup files\n"
                          "if shopt -q login_shell 2>/dev/null; then\n"
                          "  [ -r /etc/profile ] && . /etc/profile\n"
                          "  for __gf in ~/.bash_profile ~/.bash_login ~/.profile; do\n"
                          "    [ -r \"$__gf\" ] && { . \"$__gf\"; break; }; done\n"
                          "  unset __gf\n"
                          "else\n"
                          "  for __gf in /etc/bash.bashrc /etc/bash/bashrc /etc/bashrc; do\n"
                          "    [ -r \"$__gf\" ] && { . \"$__gf\"; break; }; done\n"
                          "  unset __gf\n"
                          "  [ -r ~/.bashrc ] && . ~/.bashrc\n"
                          "fi\n"
                          integration))
                        (list :env nil :args (list "--rcfile" path)
                              :temp-files (list temp))))
                     ;; Zsh: ZDOTDIR replaces .zshenv search, so we restore it,
                     ;; source the user's .zshenv, then load integration.
                     ('zsh
                      (let* ((temp-dir (make-temp-file
                                        (concat remote-prefix "ghostel-") t))
                             (temp-zshenv (concat (file-name-as-directory temp-dir)
                                                  ".zshenv"))
                             (remote-dir (file-remote-p temp-dir 'localname)))
                        (ghostel--write-remote-file
                         temp-zshenv
                         (concat
                          "if [[ -n \"${GHOSTEL_ZSH_ZDOTDIR+X}\" ]]; then\n"
                          "    'builtin' 'export' ZDOTDIR=\"$GHOSTEL_ZSH_ZDOTDIR\"\n"
                          "    'builtin' 'unset' 'GHOSTEL_ZSH_ZDOTDIR'\n"
                          "else\n"
                          "    'builtin' 'unset' 'ZDOTDIR'\n"
                          "fi\n"
                          "{\n"
                          "    'builtin' 'typeset' _ghostel_file="
                          "\"${ZDOTDIR-$HOME}/.zshenv\"\n"
                          "    [[ ! -r \"$_ghostel_file\" ]] || "
                          "'builtin' 'source' '--' \"$_ghostel_file\"\n"
                          "} always {\n"
                          "    if [[ -o 'interactive' ]]; then\n"
                          integration "\n"
                          "    fi\n"
                          "    'builtin' 'unset' '_ghostel_file'\n"
                          "}\n"))
                        (list :env (list (format "ZDOTDIR=%s" remote-dir))
                              :args nil
                              :temp-dirs (list temp-dir))))
                     ;; Fish: -C runs after config, so just source the script.
                     ('fish
                      (let* ((temp (make-temp-file
                                    (concat remote-prefix "ghostel-") nil ".fish"))
                             (path (file-remote-p temp 'localname)))
                        (ghostel--write-remote-file temp integration)
                        (list :env nil
                              :args (list "-C" (format "source %s"
                                                       (shell-quote-argument path)))
                              :temp-files (list temp))))
                     ;; Nushell: --execute runs after config (like fish's -C).
                     ;; nushell `source' needs a parse-time-constant path, so the
                     ;; literal remote temp path is embedded in the --execute arg.
                     ('nu
                      (let* ((temp (make-temp-file
                                    (concat remote-prefix "ghostel-") nil ".nu"))
                             (path (file-remote-p temp 'localname)))
                        (ghostel--write-remote-file temp integration)
                        (list :env nil
                              :args (list "--execute"
                                          (format "source %s"
                                                  (shell-quote-argument path)))
                              :temp-files (list temp)))))))
        (if tinfo
            (ghostel--merge-integration-plists base tinfo)
          base))
    (error
     (message "ghostel: remote shell integration failed: %s"
              (error-message-string err))
     nil)))