Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,16 @@ $(DOC_DEPS_STAMP):
--eval "(package-install 'htmlize)"
@touch $@

# Export README.org to a themed single-page site (ReadTheOrg) for GitHub
# Pages. The explicit output filename sidesteps `#+export_file_name:
# ghostel.texi' (which would otherwise make ox-html write ghostel.html).
# Needs network access for the ReadTheOrg `#+SETUPFILE'.
# Export README.org to a themed single-page site (ReadTheOrg, vendored under
# docs/org-html-themes/) for GitHub Pages. The explicit output filename
# sidesteps `#+export_file_name: ghostel.texi' (which would otherwise make
# ox-html write ghostel.html). The theme's src/ tree goes into public/ so its
# relative HTML_HEAD links resolve.
DOC_THEME_FILES := $(shell find docs/org-html-themes -type f)

html: public/index.html

public/index.html: README.org $(DOC_DEPS_STAMP)
public/index.html: README.org $(DOC_DEPS_STAMP) $(DOC_THEME_FILES)
@mkdir -p public
$(EMACS) --batch $(EMACSFLAGS) -Q \
--eval "(setq package-user-dir \"$(DOC_ELPA_DIR)\")" \
Expand All @@ -253,11 +256,10 @@ public/index.html: README.org $(DOC_DEPS_STAMP)
--eval "(setq make-backup-files nil \
org-html-validation-link nil \
org-export-with-broken-links 'mark \
org-html-htmlize-output-type 'css \
org-resource-download-policy 'safe \
org-safe-remote-resources '(\"\\\\\`https://fniessen\\\\.github\\\\.io/\"))" \
org-html-htmlize-output-type 'css)" \
--eval "(with-current-buffer (find-file-noselect \"README.org\") \
(org-export-to-file 'html \"public/index.html\"))"
cp -R docs/org-html-themes/src public/

clean:
rm -f ghostel-module.dylib ghostel-module.so ghostel-module.dll ghostel-module.version
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ or custom functions that interact with the Ghostel buffer.
:map ghostel-semi-char-mode-map
("C-s" . consult-line)
("C-k" . my/ghostel-send-C-k-and-kill)
;; ;; I'm used to go up/down the shell history with M-n/p from eshell
;; ;; Simulate this behavior in ghostel by sending C-p and C-n
;; I'm used to go up/down the shell history with M-n/p from eshell
;; Simulate this behavior in ghostel by sending C-p and C-n
("M-p" . (lambda () (interactive) (ghostel-send-key "p" "ctrl")))
("M-n" . (lambda () (interactive) (ghostel-send-key "n" "ctrl")))
:map project-prefix-map
Expand Down
20 changes: 11 additions & 9 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
#+texinfo_dir_title: Ghostel: (ghostel).
#+texinfo_dir_desc: Terminal emulator for Emacs powered by libghostty-vt.

# HTML export theme (ReadTheOrg). HTML-only; does not affect the Texinfo/Info export.
#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/setup/html-theme-readtheorg.setup
# Upstream ReadTheOrg references search.css by a relative path that 404s; load
# it from its absolute URL so the sidebar search box is styled correctly.
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://fniessen.github.io/org-html-themes/src/readtheorg/css/search.css"/>
# HTML export theme (ReadTheOrg, vendored under docs/org-html-themes/).
# HTML-only; does not affect the Texinfo/Info export.
#+SETUPFILE: docs/org-html-themes/org/setup/html-theme-readtheorg-local.setup

#+html: <a href="https://melpa.org/#/ghostel"><img alt="MELPA" src="https://melpa.org/packages/ghostel-badge.svg"/></a>
#+html: <a href="https://stable.melpa.org/#/ghostel"><img alt="MELPA Stable" src="https://stable.melpa.org/packages/ghostel-badge.svg"/></a>
Expand Down Expand Up @@ -1912,9 +1910,6 @@ while ghostel and vterm trade a compile step for a C/Zig engine.

| Feature | ghostel | vterm | eat |
|-------------------------------+---------+----------+----------|
| Native module required | ✅ | ✅ | ❌ |
| Auto-download module | ✅ | ❌ | n/a |
|-------------------------------+---------+----------+----------|
| True color (24-bit) | ✅ | ✅ | ✅ |
| OSC 4/10/11 color queries | ✅ | ❌ | partial |
| Bold / italic | ✅ | ✅ | ✅ |
Expand Down Expand Up @@ -1954,6 +1949,10 @@ while ghostel and vterm trade a compile step for a C/Zig engine.
| Drag-and-drop (file paths) | ✅ | ❌ | ❌ |
| Password prompt detection | ✅ | ❌ | manual |
|-------------------------------+---------+----------+----------|
| Native Windows support | ✅ | ❌ | ❌ |
| No native module needed | ❌ | ❌ | ✅ |
| Auto-download module | ✅ | ❌ | n/a |
|-------------------------------+---------+----------+----------|
| Scrollback default | 5 MB | 1,000 ln | 128 KB |
| Default redraw rate | ~30 fps | ~10 fps | adaptive |
| Throughput, plain ASCII | 75 MB/s | 18 MB/s | 6.2 MB/s |
Expand Down Expand Up @@ -1982,7 +1981,10 @@ Lisp: nothing to compile or download, so it runs anywhere Emacs does - including
hosts where you cannot build a native module. Ghostel downloads a prebuilt
module on first use (or builds it with [[https://ziglang.org/][Zig]]); vterm compiles its single C
dependency with CMake on first load. The native engines are what buy ghostel and
vterm their large throughput margin over eat.
vterm their large throughput margin over eat. Ghostel is also the only one of
the three that runs on native Windows Emacs (via ConPTY, see [[#windows-platform-notes][Platform notes]]):
vterm does not support Windows, and eat needs a real PTY, which Windows Emacs
does not provide.

*Graphics.* Inline images work in ghostel via the Kitty graphics protocol and in
eat via Sixel; vterm has neither. The two protocols are not interchangeable - a
Expand Down
9 changes: 9 additions & 0 deletions docs/org-html-themes/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Vendored subset of the ReadTheOrg HTML export theme, GPL-3.0 (same as this
repo, see LICENSE at the repo root).

Upstream: https://github.com/fniessen/org-html-themes
Commit: 8a87654701ab24d1bab984524a011bc57f94803b

Verbatim upstream copies; to update, re-copy the same paths from a newer
checkout and bump the commit above. The Google Fonts and Font Awesome CDN
imports in readtheorg.css are intentionally left remote.
33 changes: 33 additions & 0 deletions docs/org-html-themes/org/setup/html-theme-readtheorg-local.setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- mode: org; -*-

#+OPTIONS: html-style:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="src/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="src/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="src/readtheorg/css/code-copy.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="src/readtheorg/css/search.css"/>

#+HTML_HEAD: <script type="text/javascript" src="src/vendor/jquery/jquery.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="src/vendor/bootstrap/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="src/vendor/stickytableheaders/jquery.stickytableheaders.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="src/readtheorg/js/search.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="src/readtheorg/js/readtheorg.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="src/readtheorg/js/code-copy.js"></script>

#+MACRO: enable-search #+HTML_HEAD: <script type="text/javascript">enableSearch();</script>
#+MACRO: disable-search #+HTML_HEAD: <script type="text/javascript">disableSearch();</script>
#+MACRO: set-search-limit #+HTML_HEAD: <script type="text/javascript">setSearchLimit($1);</script>

* Search Configuration (v1.12) :noexport:

Usage: Optionally place these macros after including this file, before your content.

- {{{enable-search}}} :: Enable search bar (default)
- {{{disable-search}}} :: Disable search bar
- {{{set-search-limit(N)}}} :: Limit results to N (default: 0 for no limit)

Example:

#+begin_src org
{{{enable-search}}}
{{{set-search-limit(10)}}}
#+end_src
88 changes: 88 additions & 0 deletions docs/org-html-themes/src/readtheorg/css/code-copy.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* Code Copy Button Styles
* Styling for copy buttons on code blocks
*/

/* Container positioning */
.org-src-container {
position: relative;
}

pre.src {
position: relative;
padding-top: 30px; /* Make room for the button */
}

/* Copy button styling */
.copy-code-button {
position: absolute;
top: 5px;
right: 5px;
padding: 4px 10px;
font-size: 12px;
font-weight: 500;
line-height: 1.4;
color: #333;
background-color: #f5f5f5;
border: 1px solid #d1d1d1;
border-radius: 3px;
cursor: pointer;
opacity: 0.8;
transition: all 0.2s ease;
z-index: 10;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* Hover state */
.copy-code-button:hover {
opacity: 1;
background-color: #e8e8e8;
border-color: #b1b1b1;
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* Active/click state */
.copy-code-button:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}

/* Success state */
.copy-code-button.copied {
background-color: #28a745;
color: white;
border-color: #28a745;
}

.copy-code-button.copied:hover {
background-color: #218838;
border-color: #1e7e34;
}

/* Failed state */
.copy-code-button.failed {
background-color: #dc3545;
color: white;
border-color: #dc3545;
}

/* Focus state for accessibility */
.copy-code-button:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
}

/* Dark theme support (if applicable) */
@media (prefers-color-scheme: dark) {
.copy-code-button {
color: #e0e0e0;
background-color: #3a3a3a;
border-color: #555;
}

.copy-code-button:hover {
background-color: #4a4a4a;
border-color: #666;
}
}
145 changes: 145 additions & 0 deletions docs/org-html-themes/src/readtheorg/css/htmlize.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
.org-bold { /* bold */ font-weight: bold; }
.org-bold-italic { /* bold-italic */ font-weight: bold; font-style: italic; }
.org-buffer-menu-buffer { /* buffer-menu-buffer */ font-weight: bold; }
.org-builtin { /* font-lock-builtin-face */ color: #7a378b; }
.org-button { /* button */ text-decoration: underline; }
.org-calendar-today { /* calendar-today */ text-decoration: underline; }
.org-change-log-acknowledgement { /* change-log-acknowledgement */ color: #b22222; }
.org-change-log-conditionals { /* change-log-conditionals */ color: #a0522d; }
.org-change-log-date { /* change-log-date */ color: #8b2252; }
.org-change-log-email { /* change-log-email */ color: #a0522d; }
.org-change-log-file { /* change-log-file */ color: #0000ff; }
.org-change-log-function { /* change-log-function */ color: #a0522d; }
.org-change-log-list { /* change-log-list */ color: #a020f0; }
.org-change-log-name { /* change-log-name */ color: #008b8b; }
.org-comint-highlight-input { /* comint-highlight-input */ font-weight: bold; }
.org-comint-highlight-prompt { /* comint-highlight-prompt */ color: #00008b; }
.org-comment { /* font-lock-comment-face */ color: #999988; font-style: italic; }
.org-comment-delimiter { /* font-lock-comment-delimiter-face */ color: #999988; font-style: italic; }
.org-completions-annotations { /* completions-annotations */ font-style: italic; }
.org-completions-common-part { /* completions-common-part */ color: #000000; background-color: #ffffff; }
.org-completions-first-difference { /* completions-first-difference */ font-weight: bold; }
.org-constant { /* font-lock-constant-face */ color: #008b8b; }
.org-diary { /* diary */ color: #ff0000; }
.org-diff-context { /* diff-context */ color: #7f7f7f; }
.org-diff-file-header { /* diff-file-header */ background-color: #b3b3b3; font-weight: bold; }
.org-diff-function { /* diff-function */ background-color: #cccccc; }
.org-diff-header { /* diff-header */ background-color: #cccccc; }
.org-diff-hunk-header { /* diff-hunk-header */ background-color: #cccccc; }
.org-diff-index { /* diff-index */ background-color: #b3b3b3; font-weight: bold; }
.org-diff-nonexistent { /* diff-nonexistent */ background-color: #b3b3b3; font-weight: bold; }
.org-diff-refine-change { /* diff-refine-change */ background-color: #d9d9d9; }
.org-dired-directory { /* dired-directory */ color: #0000ff; }
.org-dired-flagged { /* dired-flagged */ color: #ff0000; font-weight: bold; }
.org-dired-header { /* dired-header */ color: #228b22; }
.org-dired-ignored { /* dired-ignored */ color: #7f7f7f; }
.org-dired-mark { /* dired-mark */ color: #008b8b; }
.org-dired-marked { /* dired-marked */ color: #ff0000; font-weight: bold; }
.org-dired-perm-write { /* dired-perm-write */ color: #b22222; }
.org-dired-symlink { /* dired-symlink */ color: #a020f0; }
.org-dired-warning { /* dired-warning */ color: #ff0000; font-weight: bold; }
.org-doc { /* font-lock-doc-face */ color: #8b2252; }
.org-escape-glyph { /* escape-glyph */ color: #a52a2a; }
.org-file-name-shadow { /* file-name-shadow */ color: #7f7f7f; }
.org-flyspell-duplicate { /* flyspell-duplicate */ color: #cdad00; font-weight: bold; text-decoration: underline; }
.org-flyspell-incorrect { /* flyspell-incorrect */ color: #ff4500; font-weight: bold; text-decoration: underline; }
.org-fringe { /* fringe */ background-color: #f2f2f2; }
.org-function-name { /* font-lock-function-name-face */ color: teal; }
.org-header-line { /* header-line */ color: #333333; background-color: #e5e5e5; }
.org-help-argument-name { /* help-argument-name */ font-style: italic; }
.org-highlight { /* highlight */ background-color: #b4eeb4; }
.org-holiday { /* holiday */ background-color: #ffc0cb; }
.org-isearch { /* isearch */ color: #b0e2ff; background-color: #cd00cd; }
.org-isearch-fail { /* isearch-fail */ background-color: #ffc1c1; }
.org-italic { /* italic */ font-style: italic; }
.org-keyword { /* font-lock-keyword-face */ color: #0086b3; }
.org-lazy-highlight { /* lazy-highlight */ background-color: #afeeee; }
.org-link { /* link */ color: #0000ff; text-decoration: underline; }
.org-link-visited { /* link-visited */ color: #8b008b; text-decoration: underline; }
.org-log-edit-header { /* log-edit-header */ color: #a020f0; }
.org-log-edit-summary { /* log-edit-summary */ color: #0000ff; }
.org-log-edit-unknown-header { /* log-edit-unknown-header */ color: #b22222; }
.org-match { /* match */ background-color: #ffff00; }
.org-next-error { /* next-error */ background-color: #eedc82; }
.org-nobreak-space { /* nobreak-space */ color: #a52a2a; text-decoration: underline; }
.org-org-archived { /* org-archived */ color: #7f7f7f; }
.org-org-block { /* org-block */ color: #7f7f7f; }
.org-org-block-begin-line { /* org-block-begin-line */ color: #b22222; }
.org-org-block-end-line { /* org-block-end-line */ color: #b22222; }
.org-org-checkbox { /* org-checkbox */ font-weight: bold; }
.org-org-checkbox-statistics-done { /* org-checkbox-statistics-done */ color: #228b22; font-weight: bold; }
.org-org-checkbox-statistics-todo { /* org-checkbox-statistics-todo */ color: #ff0000; font-weight: bold; }
.org-org-clock-overlay { /* org-clock-overlay */ background-color: #ffff00; }
.org-org-code { /* org-code */ color: #7f7f7f; }
.org-org-column { /* org-column */ background-color: #e5e5e5; }
.org-org-column-title { /* org-column-title */ background-color: #e5e5e5; font-weight: bold; text-decoration: underline; }
.org-org-date { /* org-date */ color: #a020f0; text-decoration: underline; }
.org-org-document-info { /* org-document-info */ color: #191970; }
.org-org-document-info-keyword { /* org-document-info-keyword */ color: #7f7f7f; }
.org-org-document-title { /* org-document-title */ color: #191970; font-size: 144%; font-weight: bold; }
.org-org-done { /* org-done */ color: #228b22; font-weight: bold; }
.org-org-drawer { /* org-drawer */ color: #0000ff; }
.org-org-ellipsis { /* org-ellipsis */ color: #b8860b; text-decoration: underline; }
.org-org-footnote { /* org-footnote */ color: #a020f0; text-decoration: underline; }
.org-org-formula { /* org-formula */ color: #b22222; }
.org-org-headline-done { /* org-headline-done */ color: #bc8f8f; }
.org-org-hide { /* org-hide */ color: #ffffff; }
.org-org-latex-and-export-specials { /* org-latex-and-export-specials */ color: #8b4513; }
.org-org-level-1 { /* org-level-1 */ color: #0000ff; }
.org-org-level-2 { /* org-level-2 */ color: #a0522d; }
.org-org-level-3 { /* org-level-3 */ color: #a020f0; }
.org-org-level-4 { /* org-level-4 */ color: #b22222; }
.org-org-level-5 { /* org-level-5 */ color: #228b22; }
.org-org-level-6 { /* org-level-6 */ color: #008b8b; }
.org-org-level-7 { /* org-level-7 */ color: #7a378b; }
.org-org-level-8 { /* org-level-8 */ color: #8b2252; }
.org-org-link { /* org-link */ color: #0000ff; text-decoration: underline; }
.org-org-meta-line { /* org-meta-line */ color: #b22222; }
.org-org-mode-line-clock { /* org-mode-line-clock */ color: #000000; background-color: #bfbfbf; }
.org-org-mode-line-clock-overrun { /* org-mode-line-clock-overrun */ color: #000000; background-color: #ff0000; }
.org-org-quote { /* org-quote */ color: #7f7f7f; }
.org-org-scheduled { /* org-scheduled */ color: #006400; }
.org-org-scheduled-previously { /* org-scheduled-previously */ color: #b22222; }
.org-org-scheduled-today { /* org-scheduled-today */ color: #006400; }
.org-org-sexp-date { /* org-sexp-date */ color: #a020f0; }
.org-org-special-keyword { /* org-special-keyword */ color: #a020f0; }
.org-org-table { /* org-table */ color: #0000ff; }
.org-org-tag { /* org-tag */ font-weight: bold; }
.org-org-target { /* org-target */ text-decoration: underline; }
.org-org-time-grid { /* org-time-grid */ color: #b8860b; }
.org-org-todo { /* org-todo */ color: #ff0000; font-weight: bold; }
.org-org-upcoming-deadline { /* org-upcoming-deadline */ color: #b22222; }
.org-org-verbatim { /* org-verbatim */ color: #7f7f7f; }
.org-org-verse { /* org-verse */ color: #7f7f7f; }
.org-org-warning { /* org-warning */ color: #ff0000; font-weight: bold; }
.org-outline-1 { /* outline-1 */ color: #0000ff; }
.org-outline-2 { /* outline-2 */ color: #a0522d; }
.org-outline-3 { /* outline-3 */ color: #a020f0; }
.org-outline-4 { /* outline-4 */ color: #b22222; }
.org-outline-5 { /* outline-5 */ color: #228b22; }
.org-outline-6 { /* outline-6 */ color: #008b8b; }
.org-outline-7 { /* outline-7 */ color: #7a378b; }
.org-outline-8 { /* outline-8 */ color: #8b2252; }
.org-preprocessor { /* font-lock-preprocessor-face */ color: #7a378b; }
.org-query-replace { /* query-replace */ color: #b0e2ff; background-color: #cd00cd; }
.org-regexp-grouping-backslash { /* font-lock-regexp-grouping-backslash */ font-weight: bold; }
.org-regexp-grouping-construct { /* font-lock-regexp-grouping-construct */ font-weight: bold; }
.org-region { /* region */ background-color: #eedc82; }
.org-secondary-selection { /* secondary-selection */ background-color: #ffff00; }
.org-shadow { /* shadow */ color: #7f7f7f; }
.org-show-paren-match { /* show-paren-match */ background-color: #40e0d0; }
.org-show-paren-mismatch { /* show-paren-mismatch */ color: #ffffff; background-color: #a020f0; }
.org-string { /* font-lock-string-face */ color: #dd1144; }
.org-tool-bar { /* tool-bar */ color: #000000; background-color: #bfbfbf; }
.org-tooltip { /* tooltip */ color: #000000; background-color: #ffffe0; }
.org-trailing-whitespace { /* trailing-whitespace */ background-color: #ff0000; }
.org-type { /* font-lock-type-face */ color: #228b22; }
.org-underline { /* underline */ text-decoration: underline; }
.org-variable-name { /* font-lock-variable-name-face */ color: teal; }
.org-warning { /* font-lock-warning-face */ color: #ff0000; font-weight: bold; }
.org-widget-button { /* widget-button */ font-weight: bold; }
.org-widget-button-pressed { /* widget-button-pressed */ color: #ff0000; }
.org-widget-documentation { /* widget-documentation */ color: #006400; }
.org-widget-field { /* widget-field */ background-color: #d9d9d9; }
.org-widget-inactive { /* widget-inactive */ color: #7f7f7f; }
.org-widget-single-line-field { /* widget-single-line-field */ background-color: #d9d9d9; }
Loading
Loading