|
|
||
|---|---|---|
| .cargo | ||
| benches | ||
| queries | ||
| src | ||
| static | ||
| tests | ||
| ui | ||
| vendor/tree-sitter-toml | ||
| .gitignore | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| installer.sh | ||
| LICENCE | ||
| README.md | ||
| RULES.md | ||
Ehwaz
Ehwaz is a native code editor built in Rust with Slint. It focuses on speed, split-pane editing, strong keyboard workflows, and local-first tooling.
Current version: 0.0.6
What's new in v0.0.6
- Expanded Git workflows: stage/unstage, commit/amend, stash, branch management, sync, repo/file diff and history previews, explorer Git badges, and a new side-by-side file diff review surface with per-row keep/apply selection are now built into the editor.
- Fresh security hardening: safer formatter/Markdown/media/file-handling paths landed across the current tree.
- Workflow polish: the bottom panel now shows
Terminal,Output, andIssuestabs,.slintfiles gained better highlighting/folding support, the editor can show inline blame on the active line, search/replace now uses tabs with cleaner shared controls, AI chat is reachable from theViewmenu, andAlt+Zopens the Git panel. - Release polish: the About modal and status bar reflect the current release and highlight the broader SCM + security surface area.
Quick start
1) Prerequisites
- Rust stable toolchain (install with rustup)
2) Build and run
cargo build
cargo run
3) Install locally on Linux (optional)
cargo build --release
./installer.sh install
To update an existing local install:
cargo build --release
./installer.sh update
If the launcher icon was cached by your desktop, run ./installer.sh update again to rewrite the desktop entry with the full icon path.
On macOS and Windows, build from source with cargo build --release. The checked-in installer script only targets Linux desktops.
Useful development commands:
cargo test
cargo test --test buffer
cargo test --test parser
cargo test --test markdown
cargo bench --no-run
Integration tests are grouped by domain under tests/ (buffer, parser, markdown).
Private implementation-focused unit tests may still remain colocated in src/ modules.
What you can do in Ehwaz
- Edit multiple files with tab reordering and close actions.
- Track unsaved tabs with an orange dot that clears automatically when the buffer matches the last saved state again.
- Split the editor into left/right panes and drag tabs across panes.
- Collapse the explorer into a slim restore rail when you want more room for the editor.
- Reorder explorer roots and move files/folders inside the explorer with drag and drop.
- Use project/file search and replace with optional regex mode and grouped project results.
- Review inline blame details on the active cursor line without leaving the editor.
- Select a whole word to highlight other exact matches in the active file.
- Work with Markdown preview for tables, code blocks, and linked assets.
- Run directly runnable files from a draggable play/stop bar that opens the integrated terminal when a run starts.
- Use command palette actions for navigation, snippets, theme switching, tool setup, and richer LSP workflows.
- Use GitHub Copilot and Ollama side-by-side with LSP inline completions, including a shared inline chooser when providers disagree and a shared, theme-aware AI chat panel with provider switching, rendered assistant Markdown/code replies, per-message copy buttons, file attachments, and a multiline composer.
- Use the Source Control workflow for staging, committing, stashing, switching branches, syncing, and opening repo/file diffs or history, including a side-by-side file diff preview where you can choose whether each changed row keeps the previous or current version before applying it.
- Install and update LSP servers and formatters into local Ehwaz tool directories.
- Use syntax highlighting, code folding, bracket matching, indentation highlights, ruler support, and richer
.slint-aware editor feedback.
Supported languages
Ehwaz ships different levels of built-in language support.
Bundled tree-sitter highlighting is available for:
- Rust
- Python
- JavaScript / TypeScript
- Vue (HTML-based highlighting)
- HTML / CSS
- YAML / XML / TOML
- Dockerfile
- Markdown
- Slint
Detected by file type and editor workflows, but without bundled tree-sitter highlighting in this tree:
- Bash
- JSON
- OCaml
Runnable files
Ehwaz shows a small play/stop bar above the editor when the active file looks directly runnable. Starting a run opens the integrated terminal automatically, and the same bar can stop the running process.
Current runnable-file detection covers:
- Rust files with a
mainentrypoint - Python files with an
if __name__ == "__main__"entrypoint - JavaScript and TypeScript files with common Node-style entrypoint patterns
- Shell scripts (
.sh,.bash,.zsh, or matching shebangs) - OCaml
.mlfiles with alet () =entrypoint
First-time usage flow
- Open Ehwaz with
cargo run. - Open a project folder (
Alt+F). - Open files in the explorer, or collapse the explorer to its slim toggle rail when you want more editor space.
- Open file search (
Ctrl+P) and command palette (Ctrl+Shift+P) and test:- file search inside the open explorer roots
@symbolnavigation in the active file#queryworkspace symbol search:linenavigation~new_namerename at cursor- LSP actions such as definition, implementation, references, signature help, rename, and workspace symbols on saved files
- Open search (
Ctrl+F) or replace (Ctrl+H). - Split tabs with View -> Split Left or View -> Split Right.
- Open tools panel from the View menu to manage themes, formatters, and LSPs.
- Open the Git panel from the status bar branch indicator, the command palette, or
Alt+Zto review changes, inspect diffs/history, click changed files for the side-by-side diff preview, and apply per-row keep-left/keep-right selections. - Open a runnable file and use the play/stop bar to run it in the integrated terminal.
- Open the AI menu or View -> Chat to configure GitHub Copilot or Ollama, then use AI: Chat to open the shared chat panel. The transcript follows the active theme, renders assistant Markdown/code replies, and adds per-message copy buttons; the composer supports multiline prompts, removable file attachments, and
Ctrl+Enterto send.
Keyboard shortcuts
File and UI
| Shortcut | Action |
|---|---|
Ctrl+N |
New file |
Alt+O |
Open file |
Alt+F |
Open folder |
Ctrl+S |
Save file |
Ctrl+W |
Close active tab |
Ctrl+T |
Toggle terminal panel |
Ctrl+K |
Open configuration file |
Ctrl++ / Ctrl+= |
Increase UI/editor font size |
Ctrl+- |
Decrease UI/editor font size |
Editing
| Shortcut | Action |
|---|---|
Ctrl+Z |
Undo |
Ctrl+Shift+Z / Ctrl+Y |
Redo |
Ctrl+X |
Cut (selection, or current line if no selection) |
Ctrl+C |
Copy (selection, or current line if no selection) |
Ctrl+V |
Paste |
Tab |
Accept visible inline completion (or the selected inline chooser option), otherwise indent by tab size |
Enter |
Accept the selected inline chooser option |
Up / Down |
Switch inline chooser options when it is open |
Shift+Tab |
Outdent current line by tab size |
Esc |
Dismiss visible inline completion or chooser |
Ctrl+A |
Select all |
Ctrl+D |
Duplicate line |
Ctrl+Shift+K |
Delete line |
Ctrl+Enter |
Insert line below |
Ctrl+Shift+Enter |
Insert line above |
Ctrl+] |
Indent |
Ctrl+[ |
Outdent |
Ctrl+/ |
Toggle line comment |
Alt+Shift+R |
Format document (external formatter) |
Navigation and tools
| Shortcut | Action |
|---|---|
Ctrl+P |
Search files in open explorer roots; empty query shows recent Ctrl+P picks |
Ctrl+Shift+P |
Open command palette |
Ctrl+Shift+P, then @query |
Symbol navigation in active file |
Ctrl+Shift+P, then :<line> |
Go to line |
Alt+X |
Open AI chat panel |
Alt+Z |
Open Git panel |
Ctrl+F |
Open search panel |
Ctrl+H |
Open replace panel |
Alt+Shift+H |
LSP hover |
Alt+Shift+C |
LSP completion hints |
Alt+Shift+D |
LSP go-to-definition |
Configuration
Ehwaz creates settings.toml on first launch.
Missing fields fall back to defaults.
If an older settings.json or storage.json exists, Ehwaz still reads it and rewrites the current config into TOML on the next save.
Settings file location
| OS | Path |
|---|---|
| Linux | ~/.config/ehwaz/settings.toml |
| macOS | ~/Library/Application Support/ehwaz/settings.toml |
| Windows | %APPDATA%\ehwaz\settings.toml |
Common settings
[editor]
font_family = "monospace"
font_size = 14.0
line_height = 22.0
letter_spacing = 0.0
cursor_width = "thin"
tab_size = 4
max_column = 120
ruler_color = "#3a3a3a"
ruler_width = 1.0
theme = "One Dark Pro"
format_on_save = false
[highlights]
bracket_matching_highlight = true
indentation_rainbow_highlight = true
[window]
width = 1200
height = 800
[ai.copilot]
enabled = false
completion_enabled = true
chat_enabled = true
chat_model = ""
inline_model = ""
bridge_command = ""
bridge_args = ""
[ai.ollama]
enabled = false
completion_enabled = true
endpoint = "http://127.0.0.1:11434"
model = "qwen2.5-coder:14b"
Persistent UI/session data
Ehwaz stores recent files, explorer roots, expanded folders, split-pane tab state, per-panel sizes, and references to unsaved untitled buffers in storage.toml in the same config directory:
- Linux:
~/.config/ehwaz/storage.toml - macOS:
~/Library/Application Support/ehwaz/storage.toml - Windows:
%APPDATA%\ehwaz\storage.toml
Unsaved untitled buffers with text are mirrored into an unsaved-buffers/ folder beside storage.toml and restored on the next launch. Panel widths and the terminal/output height are also restored, so the workspace comes back with the same layout you last used.
Recommended first-run settings
If you are starting from defaults, these are usually the most useful values to review first:
| Setting | Why it matters |
|---|---|
font_size |
Controls editor and panel readability |
line_height |
Improves text scanning comfort |
tab_size |
Keeps indentation style consistent across files |
max_column |
Enables a visual line-length guide |
theme |
Improves contrast and visual comfort |
format_on_save |
Automates formatting on save when tools are installed |
Themes
Built-in themes (22):
- One Dark Pro
- Dracula
- Monokai Pro
- Tokyo Night
- Ayu Dark
- GitHub Dark
- Night Owl
- Cobalt2
- Hagalaz
- Nauthiz
- Eihwaz
- Algiz
- Catppuccin Mocha
- Catppuccin Macchiato
- Catppuccin Frappe
- Catppuccin Latte
- One Light
- Solarized Light
- Sowilo
- Dagaz
- Berkano
- Ingwaz
LSP and formatter management
Ehwaz can install/update tools through command palette and tools panel actions.
Installed tools live inside Ehwaz-owned local directories under the same config root as settings.toml:
- Linux:
~/.config/ehwaz/{lsp,formatters} - macOS:
~/Library/Application Support/ehwaz/{lsp,formatters} - Windows:
%APPDATA%\ehwaz\{lsp,formatters}
Install logs are written under each toolchain's logs/ directory.
Examples from command palette:
LSP: Install/Update rust-analyzer (Rust)LSP: Install/Update pyright (Python)Formatter: Install/Update rustfmt (Rust)Formatter: Install/Update prettier (TypeScript)
Formatter runs now start from a detected project/config root instead of the editor process cwd. That lets project-level formatter config files be picked up more reliably, including Python pyproject.toml, ruff.toml, rustfmt.toml, .prettierrc, taplo.toml, .editorconfig, and .ocamlformat when they exist for the current file.
Useful command palette queries:
@nameto jump to symbols in the active file#nameto search workspace symbols and open clickable results in the output tab:120to jump to line 120~new_nameto rename the symbol at the current cursor through LSPthemeto quickly switch color themeslsp/formatterto find tool actions quickly
Current LSP editor actions from the command palette include:
LSP: Hover at CursorLSP: Rename Symbol (~new_name)LSP: Go to DefinitionLSP: Go to ImplementationLSP: Find References(opens the output tab with clickable results)LSP: Signature HelpLSP: Completion Hints
Rename applies the returned workspace edit to affected files, refreshes clean open tabs, and refuses to overwrite unrelated dirty tabs.
Inline LSP completion ghost text is shown only when the cursor is at the end of the current identifier, which avoids overlaying suggestions on already-complete words.
On saved files with LSP support, holding Ctrl over a symbol that actually resolves through the active LSP now shows a small themed definition preview card, switches the cursor to a pointing hand, and keeps Ctrl + left-click wired to jump directly to that symbol definition.
LSP servers now start from a detected workspace root instead of the current file's parent directory, which improves cross-file resolution for registered servers like rust-analyzer, pyright, basedpyright, pylsp, and the JS/TS/Vue language servers. For Python workspaces, Ehwaz also auto-detects a local .venv and passes its interpreter path to the LSP when available.
AI integrations
Ehwaz now ships an AI top-level menu that groups the current Copilot and Ollama integrations:
- a top-level
AImenu entry - a themed Copilot settings modal
- a themed Ollama settings modal
- separate chat and inline model pickers in settings
- a command-palette action to open chat quickly
- inline Copilot ghost-text completions in the editor, including multiline suggestions
- local Ollama-backed inline ghost-text completions through the Ollama HTTP API
- a small chooser when LSP, Copilot, and Ollama return different inline completions
- a dedicated right-side AI chat panel with a VS Code-style composer card, provider/model footer controls, theme-aware transcript cards that render assistant Markdown and syntax-highlighted code replies, per-message copy buttons, removable file attachments, and multiline prompts
- live Copilot diagnostics in the settings modal and behind the status-bar GitHub/Copilot icon hover
GitHub Copilot
The chat panel is backed by the official GitHub Copilot CLI ACP server. By default, Ehwaz starts:
copilot --acp --stdio
on the first chat prompt, then keeps that session alive for follow-up turns until you clear the panel. Inside the shared chat panel you can switch providers from the composer footer, see the active chat model beside it, attach files with the + button, review them as removable pills inside the composer card, and use Ctrl+Enter to send multiline prompts. The transcript follows the active theme, renders assistant Markdown when possible, promotes code-only replies into a syntax-highlighted code view, and adds a copy button to each message. The footer keeps the provider/model controls on the left and the config/send actions on the right, wrapping into a second row automatically on narrower panel widths.
To use it:
- Install the GitHub Copilot CLI so the
copilotcommand is available. - Authenticate the Copilot CLI with your GitHub account.
- Enable Copilot chat in AI -> GitHub Copilot Settings.
- Open AI: Chat from the command palette, or open it from the AI menu flow and choose GitHub Copilot from the provider pill in the composer footer.
The command and argument fields in the Copilot settings modal are overrides. Leave them empty to use the official default launch command above. Chat and inline models are stored separately and each selector applies the Copilot CLI --model flag only for that feature. Leaving either selector at Use Copilot CLI default avoids adding --model for that path. If you edit settings.toml directly, the current keys live under [ai.copilot] as chat_model and inline_model; older single-model configs still migrate into the chat-model setting on load.
When Copilot completions are enabled, Ehwaz asks Copilot for a continuation at eligible cursor positions and renders it through the inline ghost-text overlay. Suggestions can span multiple lines. If Copilot, Ollama, and/or LSP all have distinct inline suggestions, Ehwaz shows a small chooser near the cursor; use Up / Down to switch options, Tab or Enter to accept, and Esc to dismiss. If Copilot is unavailable for that moment, Ehwaz falls back to the other enabled completion providers when possible.
For safety, Ehwaz currently treats Copilot chat as a read-oriented assistant surface:
- tool and permission requests are denied by default
- transport or auth problems are surfaced in the panel status
- clearing the panel resets the local Copilot chat session
The bottom status bar also includes a GitHub/Copilot indicator with a hover card that summarizes chat/inline health, selected models, launch commands, resolved working roots, and the last reported issue.
Ollama
The Ollama integration covers both local chat and inline completion. Ehwaz calls the Ollama HTTP API for chat turns and for fill-in-the-middle inline suggestions, then merges the inline results into the same chooser used for LSP and Copilot. The shared chat panel gives Ollama the same themed Markdown/code transcript rendering, per-message copy buttons, multiline composer, and file-attachment flow that it does for GitHub Copilot.
To use it:
-
Install Ollama from ollama.com/download.
-
Pull a local model such as
qwen2.5-coder:7b, or choose any other model you already have:ollama pull qwen2.5-coder:7b -
Start the local Ollama service.
-
Open AI -> Ollama Settings, enable the integration, confirm the endpoint (default
http://127.0.0.1:11434), and set the model name you want Ehwaz to use.
The Ollama settings modal keeps a small diagnostics panel with the resolved endpoint/model and the last integration issue. The endpoint field should point at the Ollama server root (for example http://127.0.0.1:11434); Ehwaz normalizes legacy /api, /chat, and /api/chat suffixes automatically before calling the correct Ollama API routes.
Project structure (high level)
src/
main.rs app startup and wiring
app.rs core AppState and editor model
config.rs settings and storage management
command_palette.rs command palette logic
git_diff.rs Git diff parsing and keep/apply selection logic
lsp_sync.rs LSP sync and UI updates
formatting.rs formatter integration
tools_panel.rs tools panel actions and data
ui/handlers/ keyboard/mouse/file/tab/explorer handlers
ui/
main.slint window composition
editor.slint editor component
git_diff_preview.slint side-by-side Git diff preview UI
search_panel.slint search/replace UI
tools_panel.slint themes/formatter/LSP panel UI
terminal_pane.slint terminal and output panel UI
tests/
buffer.rs buffer domain integration suite entrypoint
parser.rs parser domain integration suite entrypoint
markdown.rs markdown domain integration suite entrypoint
Troubleshooting
- If Markdown media controls appear unavailable, that is expected in this tree. The checked-in build ships the media controller stub rather than external playback support.
- If LSP/formatter install fails, inspect the
logs/subdirectory under your locallsp/orformatters/config directory. - If Copilot chat or inline completions stay unavailable, verify that
copilot --helpworks in your shell and that the Copilot CLI is already authenticated. Then hover the GitHub/Copilot status-bar icon to inspect the separate chat/inline launch details and the last reported issue. - If Ollama completions stay unavailable, confirm that the Ollama service is running, that the configured model exists locally (
ollama list), and that AI -> Ollama Settings points at the correct endpoint. - If a Git file diff opens with a non-editable summary instead of selectable rows, the diff is probably binary or metadata-only; the interactive panel currently targets text hunks.
- If UI font size becomes too large/small, edit
[editor].font_sizeinsettings.toml. - If syntax highlighting looks stale after heavy edits, save and reopen the file to force a clean refresh.
License
MIT