Ehwaz is a native code editor built in Rust with Slint. https://github.com/rdenadai/ehwaz
Find a file
2026-04-08 17:59:43 +00:00
.cargo Refine editor workflows and integrations 2026-04-05 10:11:01 -03:00
benches Implement second-pass CODE_REVIEW improvements 2026-02-20 00:52:50 -03:00
queries Refine editor workflows and integrations 2026-04-05 10:11:01 -03:00
src fix(app): harden search, AI, and media workflows 2026-04-08 14:44:56 -03:00
static ui: fix explorer toggle refactor, git diff vertical alignment, and padding 2026-03-30 13:49:38 -03:00
tests Refine editor workflows and integrations 2026-04-05 10:11:01 -03:00
ui fix(ui): improve inline blame and markdown preview layout 2026-04-08 09:46:26 -03:00
vendor/tree-sitter-toml Add syntax highlighting for more formats 2026-02-07 11:37:22 -03:00
.gitignore Release v0.0.6 2026-03-25 06:40:18 -03:00
build.rs feat: Improvements for intaller 2026-03-06 08:56:50 -03:00
Cargo.lock fix(app): harden search, AI, and media workflows 2026-04-08 14:44:56 -03:00
Cargo.toml fix(app): harden search, AI, and media workflows 2026-04-08 14:44:56 -03:00
installer.sh feat: Improvements on highlight 2026-02-25 08:12:09 -03:00
LICENCE feat: Improvements-v0.0.5 2026-03-10 14:51:56 -03:00
README.md Finalize chat markdown preview work 2026-04-07 16:39:22 -03:00
RULES.md Implement missing UI polish items 2026-04-01 08:47:45 -03:00

Ehwaz Logo

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, and Issues tabs, .slint files 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 the View menu, and Alt+Z opens 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 main entrypoint
  • 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 .ml files with a let () = entrypoint

First-time usage flow

  1. Open Ehwaz with cargo run.
  2. Open a project folder (Alt+F).
  3. Open files in the explorer, or collapse the explorer to its slim toggle rail when you want more editor space.
  4. Open file search (Ctrl+P) and command palette (Ctrl+Shift+P) and test:
    • file search inside the open explorer roots
    • @symbol navigation in the active file
    • #query workspace symbol search
    • :line navigation
    • ~new_name rename at cursor
    • LSP actions such as definition, implementation, references, signature help, rename, and workspace symbols on saved files
  5. Open search (Ctrl+F) or replace (Ctrl+H).
  6. Split tabs with View -> Split Left or View -> Split Right.
  7. Open tools panel from the View menu to manage themes, formatters, and LSPs.
  8. Open the Git panel from the status bar branch indicator, the command palette, or Alt+Z to review changes, inspect diffs/history, click changed files for the side-by-side diff preview, and apply per-row keep-left/keep-right selections.
  9. Open a runnable file and use the play/stop bar to run it in the integrated terminal.
  10. 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+Enter to 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.

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:

  • @name to jump to symbols in the active file
  • #name to search workspace symbols and open clickable results in the output tab
  • :120 to jump to line 120
  • ~new_name to rename the symbol at the current cursor through LSP
  • theme to quickly switch color themes
  • lsp / formatter to find tool actions quickly

Current LSP editor actions from the command palette include:

  • LSP: Hover at Cursor
  • LSP: Rename Symbol (~new_name)
  • LSP: Go to Definition
  • LSP: Go to Implementation
  • LSP: Find References (opens the output tab with clickable results)
  • LSP: Signature Help
  • LSP: 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 AI menu 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:

  1. Install the GitHub Copilot CLI so the copilot command is available.
  2. Authenticate the Copilot CLI with your GitHub account.
  3. Enable Copilot chat in AI -> GitHub Copilot Settings.
  4. 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:

  1. Install Ollama from ollama.com/download.

  2. Pull a local model such as qwen2.5-coder:7b, or choose any other model you already have:

    ollama pull qwen2.5-coder:7b
    
  3. Start the local Ollama service.

  4. 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 local lsp/ or formatters/ config directory.
  • If Copilot chat or inline completions stay unavailable, verify that copilot --help works 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_size in settings.toml.
  • If syntax highlighting looks stale after heavy edits, save and reopen the file to force a clean refresh.

License

MIT