# duat  [](https://crates.io/crates/duat) [](https://docs.rs/duat)
## Duat
Duat is a text editor meant to have as much modularity as
possible, while keeping a sensible default configuration. It is
written *and configured* in Rust, through the use of a
configuration Rust crate, placed in `~/.config/duat/` (or wherever
`$XDG_CONFIG_HOME` is set to).
When installing Duat, this crate will be automatically placed in
that spot, and it will have a default example configuration.
When you first run Duat, and whenever you update the
configuration, it will be compiled and reloaded automatically, so
you can see the changes in *almost* real time. Initially, building
Duat and its configuration crate might take a few minutes. And the
first reload might also take a similar amount of time. But
whenever you make new changes, the next reloads should take only
about a second (for debug profile) and ~3 seconds (for release
profile).
Note that this is an alpha project, so there may be some quirks
and bugs. So if you have a problem, or something seems confusing,
feel free to ask questions or raise an issue, that would be very
welcome đĽ°.
### Getting started
To install Duat, do the following:
```text
cargo install duat
```
Although, since this is an alpha, I would recommend the git
version, since that is kept much more up to date:
```text
git clone https://github.com/AhoyISki/duat
cargo install --path duat
```
### Configuration
In the configuration file, there should be a `setup_duat!` macro,
which takes in a function with no parameters.
This function is the setup for duat, and it can be empty, which is
the equivalent of the default configuration for Duat.
Hereâs an example configuration file, which makes use of the
`duat-kak` crate, which is a plugin for Duat. This plugin, like
all others, is included without the `duat_` prefix, so in the
config it is just `kak`.
```rust
setup_duat!(setup);
use duat::prelude::*;
use kak::{Insert, Normal};
fn setup() {
plug!(kak::Kak);
map::<Insert>("jk", "<Esc>");
print::wrap_on_width();
hooks::remove("FileWidgets");
hooks::add::<OnFileOpen>(|builder| {
builder.push(VertRule::cfg());
builder.push(LineNumbers::cfg());
});
hooks::remove("WindowWidgets");
hooks::add::<OnWindowOpen>(|builder| {
let status = status!(
[File] { File::name } " "
mode " " selections_fmt " " main_fmt
);
let (child, _) = builder.push(status);
builder.push_to(CmdLine::cfg().left_ratioed(3, 7), child);
});
hooks::add::<ModeSwitched>(|&(_, new)| match new {
"Insert" => cursor::set_main(CursorShape::SteadyBar),
_ => cursor::set_main(CursorShape::SteadyBlock)
});
form::set("Mode", Form::dark_magenta());
}
```
This configuration does the following things:
* [plugs][__link0] the `Kak` plugin, which changes the [default mode][__link1];
* [Maps][__link2] jk to esc in the `Insert` mode;
* [Changes][__link3] the wrapping;
* [Removes][__link4] the hook [group][__link5] âFileWidgetsâ;
* [Pushes][__link6] a [vertical rule][__link7] and [line numbers][__link8] to every file;
* Removes the hook group âWindowWidgetsâ;
* Pushes a [custom status line][__link9] and [command line][__link10] to the bottom
of the screen;
* [Adds][__link11] hooks for [mode changes][__link12] in Duat;
* [Changes][__link13] the [style][__link14] of the mode printed on the
status line;
These are some of the ways you can configure Duat. You might
notice some things that can be done with these simple options:
```rust
builder.push(LineNumbers::cfg());
builder.push(LineNumbers::cfg().on_the_right());
builder.push(LineNumbers::cfg().on_the_right());
});
```
Now, every file will open with two lines of numbers, one on each
side. Would you ever want to do this? âŚNo, not really, but it
shows how configurable Duat can be.
Duat also comes with a fully fledged text styling system, which
significantly eases the creation of widgets:
```rust
let text = text!([MyForm] "Waow it's my form! " [] "not anymore đ˘");
```
In this example, Iâm using the âMyFormâ form in order to style the
text, while `[]` reverts back to the âDefaultâ form. The
[`status!`][__link15] macro works similarly.
Duat also has a simple command system, that lets you add commands
with arguments supported by Rustâs type system:
```rust
let callers = ["collapse-cmd-line", "ccmd"];