# Hush A small WYSIWYG markdown editor, built in C with [Clay](https://github.com/nicbarker/clay) and [raylib](https://www.raylib.com/). 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](#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](#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`). ```sh 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: ```sh 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: ```sh open build/hush.app ``` Build and run the headless tests with: ```sh cmake --build build --target hush_test ./build/hush_test ``` ### Installing (optional) To put `hush` on your `PATH`: ```sh sudo cmake --install build ``` This installs the binary to `/bin` and its fonts/language files to `/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`): ```sh cmake --install build --prefix ~/.local ``` ## Usage ```sh ./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 | Shortcut | Action | |---|---| | Arrow keys | Move the cursor | | Shift + arrow keys | Extend the selection | | Click + drag | Select text with the mouse | | Ctrl+S | Save | | Ctrl+O | Open a file (prompts to save first if there are unsaved changes) | | Ctrl+C / Ctrl+V | Copy / paste | | Ctrl+Z / Ctrl+Shift+Z | Undo / redo | | Ctrl+X | Quit (prompts to save if there are unsaved changes) | | F1 (or Ctrl+/) | Show this shortcut list | | Ctrl+M | View 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% | | Enter | New line / new block | | Backspace / Delete | Delete a character (merges/demotes blocks at boundaries) | | Home / End | Start / 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 | Syntax | Result | |---|---| | `# ` … `###### ` | Heading 1–6 | | `**bold**` | **bold** | | `*italic*` | *italic* | | `~~strikethrough~~` | ~~strikethrough~~ | | `==highlight==` | highlighted text | | `H~2~O` | subscript | | `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](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/.lang`, translate the values (not the keys), and set `language = `. 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 ```sh ./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](https://github.com/nicbarker/clay) and [raylib](https://www.raylib.com/), and bundles the [DejaVu fonts](https://dejavu-fonts.github.io/).