Function: ghostel-mode

ghostel-mode is an interactive and natively compiled function defined in ghostel.el.

Signature

(ghostel-mode)

Documentation

Major mode for Ghostel terminal emulator.

This mode runs the hook ghostel-mode-hook, as the final or penultimate step during initialization.

                ghostel-find-file-at-point
<XF86Copy> kill-ring-save
<XF86Paste> ghostel-yank
<down-mouse-1> ghostel-mouse-press-or-copy-mode
<down-mouse-2> ghostel-mouse-down-2-or-noop
<down-mouse-3> ghostel--mouse-press
<drag-mouse-1> ghostel-mouse-drag-or-set-region
<drag-mouse-2> ghostel--mouse-drag
<drag-mouse-3> ghostel--mouse-drag
<drag-n-drop> ghostel--drop
<mouse-1> ghostel-mouse-release-or-set-point
<mouse-2> ghostel-mouse-paste-primary-or-release
<mouse-3> ghostel--mouse-release
<xterm-paste> ghostel-xterm-paste
C-c C-\ ghostel-send-C-backslash
C-c C-c ghostel-send-C-c
C-c C-d ghostel-send-C-d
C-c C-e ghostel-emacs-mode
C-c C-j ghostel-semi-char-mode
C-c C-l ghostel-line-mode
C-c C-n ghostel-next-hyperlink
C-c C-p ghostel-previous-hyperlink
C-c C-q ghostel-send-next-key
C-c C-t ghostel-copy-mode
C-c C-y ghostel-paste
C-c C-z ghostel-send-C-z
C-c M-d ghostel-char-mode
C-c M-l ghostel-clear-scrollback
C-c M-n ghostel-next-prompt
C-c M-p ghostel-previous-prompt
C-c M-w ghostel-copy-all
C-g ghostel-send-C-g
C-x C-q ghostel-readonly-enter

Key Bindings

This command is not in any keymaps.

Source Code

;; Defined in /nix/store/1252krff0gb2kisjcpp45m50cpdskfrl-emacs-packages-deps/share/emacs/site-lisp/ghostel.el
(define-derived-mode ghostel-mode fundamental-mode "Ghostel"
  "Major mode for Ghostel terminal emulator."
  (hack-dir-local-variables)
  (when-let* ((cell (assq 'ghostel-environment dir-local-variables-alist))
              (value (cdr cell))
              ((ghostel--safe-environment-p value)))
    (setq-local ghostel-environment value))
  (buffer-disable-undo)
  (font-lock-mode -1)
  (face-remap-add-relative 'default 'ghostel-default)
  ;; `font-lock-mode' can still be re-enabled by user configuration that
  ;; forces `font-lock-defaults' globally (e.g. Doom Emacs).  When active,
  ;; JIT-lock calls `font-lock-unfontify-region' on every redraw, which
  ;; strips the per-cell `face' text-properties the native module writes.
  ;; Neutralise the unfontify pass so face props survive regardless of
  ;; whether font-lock ends up on.  `ghostel-mode' has no keywords, so
  ;; skipping unfontify has no other effect.
  (setq-local font-lock-unfontify-region-function #'ignore)
  ;; The terminal renderer owns the buffer contents.  Read-only until
  ;; a process spawn runs `ghostel--sync-read-only'.
  (setq buffer-read-only t)
  ;; Live terminal-input modes clear `buffer-read-only' and instead
  ;; intercept foreign edits here: insertions are forwarded to the PTY,
  ;; deletions repaired by a redraw; see `ghostel--sync-read-only'.
  ;; Depth 90 so other hook members still see an insertion before the
  ;; forwarding removes it.
  (add-hook 'after-change-functions
            #'ghostel--forward-inserts-after-change 90 t)
  (setq-local scroll-margin 0)
  (setq-local auto-hscroll-mode nil)
  (setq-local hscroll-margin 0)
  (setq-local truncate-lines t)
  (setq-local scroll-conservatively 101)
  (setq-local line-spacing ghostel-line-spacing)
  ;; Shield row geometry from a global `default-text-properties':
  ;; `line-spacing'/`line-height' properties supplied through its fallback
  ;; inflate rendered rows invisibly to the `window-screen-lines' sizing math.
  (setq-local default-text-properties nil)
  (setq-local filter-buffer-substring-function #'ghostel--filter-buffer-substring)
  ;; expose cwd to buffer-menu/ibuffer
  (setq-local list-buffers-directory (expand-file-name default-directory))
  (ghostel--buffer-identification-update)
  ;; bookmark this buffer's cwd (loads ghostel-bookmark.el lazily on use)
  (setq-local bookmark-make-record-function #'ghostel-bookmark-make-record)
  ;; X11 and pgtk deliver drops through `special-event-map' and the
  ;; `dnd-protocol-alist' machinery, so the `<drag-n-drop>' binding in
  ;; `ghostel-mode-map' is never consulted there; intercept file drops
  ;; buffer-locally instead.  NS and w32 bind `[drag-n-drop]' in the
  ;; global map, which the keymap binding shadows.
  (setq-local dnd-protocol-alist
              (append '(("^file:///" . ghostel--dnd-handle-file)
                        ("^file://"  . ghostel--dnd-handle-file)
                        ("^file:"    . ghostel--dnd-handle-file))
                      dnd-protocol-alist))
  ;; `yank-media' pastes a clipboard image or PDF as a temp-file path.
  (when (fboundp 'yank-media-handler)   ; Emacs 29+
    (yank-media-handler '("image/.*" application/pdf)
                        #'ghostel--yank-media-data))
  ;; Accept any image flavor and PDF: stock autoselect only prefers
  ;; png/jpeg, stranding e.g. TIFF-only clipboards (Qt apps on macOS).
  (when (boundp 'yank-media-preferred-types)  ; Emacs 31+
    (setq-local yank-media-preferred-types
                (append yank-media-preferred-types
                        (list (lambda (types)
                                (append
                                 (seq-filter
                                  (lambda (type)
                                    (string-prefix-p "image/"
                                                     (symbol-name type)))
                                  types)
                                 (and (memq 'application/pdf types)
                                      '(application/pdf))))))))
  ;; Save this buffer's dir + identity in the desktop file
  (setq-local desktop-save-buffer #'ghostel-desktop-save-buffer)
  (setq ghostel--input-mode 'semi-char)
  (setq ghostel--scroll-intercept-active t)
  ;; Let C-g reach the keymap instead of triggering keyboard-quit.
  ;; When inhibit-quit is non-nil, C-g sets quit-flag and delivers
  ;; the character through normal input dispatch.
  (setq-local inhibit-quit t)

  (add-function :after after-focus-change-function #'ghostel--frame-focus-flags)
  (add-function :after after-focus-change-function #'ghostel--focus-change)
  (add-hook 'window-selection-change-functions #'ghostel--focus-change)
  (add-hook 'window-buffer-change-functions #'ghostel--focus-change)
  (add-hook 'window-buffer-change-functions #'ghostel--window-buffer-change nil t)
  (add-hook 'window-buffer-change-functions #'ghostel--sync-tty-composition nil t)
  (add-hook 'window-buffer-change-functions #'ghostel--tty-esc-window-change nil t)
  (add-hook 'pre-redisplay-functions #'ghostel--pre-redisplay nil t)
  (add-hook 'window-size-change-functions #'ghostel--adjust-size nil t)
  (add-hook 'minibuffer-exit-hook #'ghostel--minibuffer-exit)
  (add-hook 'minibuffer-exit-hook #'ghostel--minibuffer-exit-maybe-leave)
  (add-hook 'activate-mark-hook #'ghostel--mark-activated nil t)
  (add-hook 'isearch-mode-end-hook #'ghostel-maybe-leave-input nil t)
  (add-hook 'kill-buffer-query-functions #'ghostel--kill-buffer-query nil t)
  (add-hook 'change-major-mode-hook #'ghostel--change-major-mode-guard nil t)
  ;; Eldoc link echo, thing-at-point providers, file-name-at-point.
  (ghostel-links-setup)
  ;; Lone-ESC decoding on the creating terminal
  ;; (later TTY frames are covered by `ghostel--tty-esc-window-change' above).
  (ghostel--tty-esc-init)

  ;; Set up the comint/shell completion plumbing once per buffer so
  ;; `ghostel-line-mode-complete-at-point' has the right
  ;; `comint-dynamic-complete-functions', `comint-file-name-chars',
  ;; etc. ready when the user enters line mode.  The plumbing is
  ;; cheap and harmless outside line mode (the capf is added to
  ;; `completion-at-point-functions' but no one calls it).
  (shell-completion-vars)

  (use-local-map ghostel-semi-char-mode-map)
  (ghostel--suppress-interfering-modes)
  (ghostel-imenu-setup))