📝 dioxus_codemirror
A Dioxus web component that wraps the CodeMirror 6 editor, for use in Dioxus web applications.
Demo: https://azriel.im/dioxus_codemirror.
[!NOTE]
🚧 This crate is new and not yet stable; its API may change between releases.
No JavaScript build step is required: the component drives CodeMirror through a
single long-lived document::eval channel. CodeMirror itself is vendored as
a Dioxus folder asset, so there is no runtime CDN dependency.
Features
- Pure Rust build / no
nodedependency. - Set / receive text via
Signal<String>. - Syntax highlighting per-language (YAML, Markdown, JavaScript, CSS, HTML).
- Light / dark / auto theme (auto follows
prefers-color-scheme). - In-page LSP bridge -- synchronous, or async / worker-backed.
Usage
Add the following to Cargo.toml:
[]
= "0.1.0"
All bundled languages (YAML, Markdown, JavaScript, CSS, HTML) are available out
of the box. The lang-* Cargo features are currently no-ops; see
Choosing languages.
In code:
use *;
use ;
The editor is always editable. Props:
value: Signal<String>-- two-way bound document text (required).line_numbers: bool-- show a line-number gutter (defaultfalse).language: Language-- syntax highlighting (default plain text). All languages are bundled; see Choosing languages.- editor feature toggles (e.g.
allow_multiple_selections: bool) -- optional CodeMirror features, off by default; see Editor features. theme: Theme-- color theme,Theme::Auto(default, follows the OSprefers-color-scheme),Theme::Light, orTheme::Dark.lsp: LspBridge-- connect an in-page language server, synchronous or async (optional); see LSP.
Editor features
Optional CodeMirror behaviours are individual props, each named after the CodeMirror extension it enables (API parity). All are off by default; set the ones you want:
use CodeMirror;
rsx!
| Prop | CodeMirror extension |
|---|---|
allow_multiple_selections |
Allows multiple selections in the editor. Also binds Ctrl/Cmd-d to select the next match and Ctrl/Cmd-F2 to select all matches. |
bracket_matching |
Highlight the bracket matching the one next to the cursor. |
close_brackets |
Auto-insert closing brackets and quotes. |
highlight_active_line |
Highlight the line the primary cursor is on. |
highlight_selection_matches |
Highlight every occurrence of the selected text, the selection included. |
highlight_whitespace |
Render whitespace characters visibly. |
indent_on_input |
Re-indent lines as you type. |
indent_with_tab |
Bind Tab/Shift-Tab to indent, so Tab inserts indentation rather than moving focus out of the editor. |
language |
Syntax highlighting language, e.g. Language::Yaml. Defaults to plain text (None). |
line_numbers |
Show a line-number gutter. |
line_wrapping |
Wrap long lines instead of scrolling horizontally. |
read_only |
Make the document read-only, |
rectangular_selection |
Allow rectangular (block) selection via Alt-drag. |
tab_size |
Width of a tab in spaces. |
theme |
Color theme, e.g. Theme::Dark. Defaults to Theme::Auto. |
Choosing languages
Every supported language -- Language::Yaml, Markdown, Javascript, Css,
Html -- is bundled and ready to use; no feature selection is required.
The lang-yaml, lang-markdown, lang-javascript, lang-css, lang-html, and
lang-all Cargo features still exist but are currently no-ops: the whole
language superset is shipped regardless. This is because Dioxus cannot yet serve
a build-script-generated, per-feature asset folder -- see
DioxusLabs/dioxus#4426. Once that lands, the features will once again trim the
shipped JS to only the languages you enable, so it is worth setting them now to
match the languages you actually use.
To add a language not listed above, see DEVELOPMENT.md.
LSP
CodeMirror takes an optional LspBridge, which connects the editor's
@codemirror/lsp-client to an in-page language server. There are two transport
flavours, chosen by which constructor you call:
-
Synchronous --
LspBridge::lsp_bridge_from_serverdrives anLspServer, the extension point a real in-page language server implements. It is request/response: each message from the editor is handed to the server, and the messages it returns are forwarded straight back. -
Async / worker-capable --
LspBridge::lsp_bridge_from_server_asyncdrives anLspServerAsync, for a server running in a Web Worker (or off the main thread), or one that emits diagnostics after a processing step. Instead of returning replies, the server pushes messages onto anLspPusherwhenever they are ready -- which is what makes server-initiated, unprompted messages (e.g.textDocument/publishDiagnostics) work.
The example ships mock servers for both flavours. Replace either mock with your
WASM language server to get genuine language features. See
DEVELOPMENT.md for the wire protocol and architecture.
Development
See DEVELOPMENT.md for the architecture, the message
protocol, the vendored CodeMirror assets, and how to add a language.
To run the bundled example:
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.