foxygit / Hush Log in
commits tags

/README.md · 7.45 KB

raw

Hush

A small WYSIWYG markdown editor, built in C with Clay and raylib.

Markdown syntax you type is rendered as styled text as you go, rather than shown as raw markup — the underlying markup only reappears around a span while your cursor is inside it. See Markdown syntax below for exactly what's supported.

Features

  • Headings (H1–H6), bold, italic, strikethrough, highlight, subscript/superscript, inline code, links (including bare URLs), block quotes, horizontal rules, task lists, fenced code blocks (with a language tag), bullet and numbered lists
  • Text selection (Shift+arrows or click-drag) with copy/paste
  • Undo/redo
  • A status bar showing the document name, size, and line count
  • A config file for font, text color, background color, zoom, and rebindable keyboard shortcuts
  • Translatable UI (Swedish and English included; see Language below)
  • Full Swedish/Latin-1 character support (åäö, etc.)

Building

Requires CMake 3.15+, a C11 compiler, and a network connection on first build (raylib is fetched automatically via CMake's FetchContent).

cmake -B build
cmake --build build

This produces two binaries in build/:

  • hush — the editor itself
  • hush_test — a headless test suite for the document/editor logic (no window or GPU context needed, so it can run over SSH or in CI)

Building on macOS

Install Xcode Command Line Tools, CMake, and Git. The first build also needs a network connection because SDL2, SDL2_ttf, and SDL2_image are fetched automatically.

On CMake 4, pass the policy compatibility setting required by the vendored FreeType dependency:

cmake -B build -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake --build build --target hush

This creates a macOS application bundle at build/hush.app, including the Hush icon. Open it with:

open build/hush.app

Build and run the headless tests with:

cmake --build build --target hush_test
./build/hush_test

Installing (optional)

To put hush on your PATH:

sudo cmake --install build

This installs the binary to <prefix>/bin and its fonts/language files to <prefix>/share/hush/assets, found at runtime relative to the installed binary — so it's a fully relocatable install, not tied to this source directory. CMAKE_INSTALL_PREFIX defaults to /usr/local, whose bin/ is already on PATH on virtually every Linux distro, hence the sudo. To install for just your own user instead (no sudo needed, as long as ~/.local/bin is already on your PATH):

cmake --install build --prefix ~/.local

Usage

./build/hush [file.md]

(or just hush [file.md] if you installed it, see above). Run without an argument to start with an empty, untitled document.

Keyboard shortcuts

ShortcutAction
Arrow keysMove the cursor
Shift + arrow keysExtend the selection
Click + dragSelect text with the mouse
Ctrl+SSave
Ctrl+OOpen a file (prompts to save first if there are unsaved changes)
Ctrl+C / Ctrl+VCopy / paste
Ctrl+Z / Ctrl+Shift+ZUndo / redo
Ctrl+XQuit (prompts to save if there are unsaved changes)
F1 (or Ctrl+/)Show this shortcut list
Ctrl+MView the raw markdown source (read-only; Ctrl+M or Esc to go back)
Ctrl++ / Ctrl+- (or numpad +/-)Zoom in / out
Ctrl+0 (or numpad 0)Reset zoom to 100%
EnterNew line / new block
Backspace / DeleteDelete a character (merges/demotes blocks at boundaries)
Home / EndStart / end of the current line

The window's close button goes through the same unsaved-changes prompt as Ctrl+X.

Every shortcut above (except plain text-editing keys like the arrows, Enter, and Backspace) can be rebound in the config file with a key.* line, e.g. key.save = ctrl+shift+s. A binding is modifier+modifier+key, where modifiers are any of ctrl/shift/alt and key is a single letter or digit, f1-f12, punctuation (e.g. / or slash), or a name like enter/escape/tab/space/home/end/up/down/left/right/pageup/pagedown/insert. The numpad zoom fallback and F1 for help always keep working regardless of what's rebound, so there's no way to lock yourself out. See the generated config file (below) for the full list of key.* names and their defaults.

Markdown syntax

SyntaxResult
# ###### Heading 1–6
**bold**bold
*italic*italic
~~strikethrough~~strikethrough
==highlight==highlighted text
H~2~Osubscript
X^2^superscript
` code `inline code
` ` or `lang `fenced code block, optionally with a language tag
- or * Bullet list
1. Numbered list (renumbered automatically on save)
- [ ] / - [x] Task list (click the checkbox to toggle)
> Blockquote
--- (on its own line)Horizontal rule
[text](url)Link
a bare https://… or http://…Autolink

A block's own markdown (e.g. the **/*/# markers) is only shown while your cursor is inside it; otherwise you see the styled result. Not on this list is deliberately out of scope for now — see TODO.md for what's missing (tables, images, footnotes, ...) and why.

Configuration

On first run, Hush creates a config file at $XDG_CONFIG_HOME/hush/config (or ~/.config/hush/config if that variable isn't set), with every available key present but commented out. Uncomment and edit a line to change it; unknown or malformed lines are ignored.

text_color = #1F2328
bg_color = #FDFDFB

font_sans_regular = /path/to/font.ttf
font_sans_bold = /path/to/font-bold.ttf
font_sans_italic = /path/to/font-italic.ttf
font_sans_bold_italic = /path/to/font-bold-italic.ttf
font_mono_regular = /path/to/mono.ttf
font_mono_bold = /path/to/mono-bold.ttf
font_mono_italic = /path/to/mono-italic.ttf
font_mono_bold_italic = /path/to/mono-bold-italic.ttf

key.save = ctrl+s
key.open = ctrl+o
key.zoom_in = ctrl++

Font paths are optional per style; any left unset fall back to the bundled DejaVu fonts. text_color and bg_color accept #RRGGBB (the # is optional). key.* lines rebind shortcuts (see Keyboard shortcuts above for the format and the full list of names); the generated file lists all twelve.

Language

The status bar and the quit/shortcuts dialogs are translated via plain-text files in assets/lang/ (document content itself is never touched — Hush doesn't translate what you write). Two are included: sv.lang (Swedish, the default) and en.lang (English, also the built-in fallback for any string a translation leaves out).

Set the active language in the config file:

language = en

To add a new language, copy assets/lang/en.lang to assets/lang/<code>.lang, translate the values (not the keys), and set language = <code>. Malformed lines are ignored, same as the main config file. Note that the bundled fonts only cover ASCII and Latin-1 (Western European accented characters); a translation needing other scripts would need a matching font as well (see Configuration above).

Testing

./build/hush_test

Runs the full logic test suite (document editing, markdown round-tripping, undo/redo, selection, config parsing, ...) and prints a pass/fail summary.

Acknowledgments

Built with Clay and raylib, and bundles the DejaVu fonts.