# owl-write
<img src="docs/owl.svg" width=128 height=128>
🦉: a TUI for managing your writing
## features
This project is a companion for those that find themselves working on projects comprised of directories of markdown: `hugo`, `zola`, `quarto`, `mkdocs`, `zensical`, etc.
It offers a project-wide view of potential issues in your files.
It is designed for my workflow of editing files (mostly in [Helix](https://helix-editor.com)) and doing editing/cleanup later.
- fast hunspell/spellbook-powered spellcheck over entire project:
- per-project & global ignore files
- suggest changes & replace in all files
- configurable checkers to ban words/phrases including:
- weasel words
- passive voice
- accidentally repeated words
- TODO/FIXME statements
- any regex pattern
- project overview including:
- failed checks per file
- word count & other file metadata
- TOML/YAML frontmatter support
- when everything has been resolved, a visit from the cosmic owl
### roadmap
`owl` is still very much a work-in-progress. While I use it daily for my own work, it is my first Rust TUI project and has lots of room to improve.
The focus of the next release will be on improving the UI & error handling.
The release after that will look at integrating [Harper](https://github.com/Automattic/harper) for more advanced checking.
I am open to *human* contributions.
If you'd like to contribute please open/comment on an issue first.
## usage
### owl init
`owl` operates on projects.
A project is a directory containing markdown as well as an `owl.toml` file.
To initialize a directory as a project run `owl init`. This will:
- write an `owl.toml` in the current directory if it doesn't exist
- download some default dictionaries if needed
### owl.toml
A TOML config file with the keys:
- **lang** - language code, used to download a dictionary for spellchecker
- **extensions** - list of extensions to treat as writing
- **content_dir** - subdirectory of project that contains writing
- **ignored_words** - list of ignored words
- **checks** - each check adds a check column to `owl check` output, each has:
- **name** - name of the check column
- **rule** - word_count|repeat|ban_pattern|status - kind of check to perform
- _word\_count_: count words in the file
- _repeat_: detect accidental double words, e.g. "the the"
- _ban_pattern_: ban words, requires additional `pattern` regex. Can also use a pre-defined banned list: `'@todo'`, `'@weasel'`, `'@passive'`.
- _frontmatter_: extract a frontmatter field, requires additional `field`
### owl check
Run configured checks against the project. The default view is to show a list of all files in the project.

In this view: *Tab* changes the sort column, *Enter* shows detailed check output for the selected file.
### owl spell
Show a list of all misspelled words in the project.
This interactive TUI allows quickly making replacements and adding words to the project ignore list.

While browsing the list you can tap a single key to:
- Add the word to a project ignore list stored in plain text, useful for project-specific technical terms or words not found in your default dictionary.
- View the word's context.
- Replace all occurrences of the word with a suggestion or word of your choice.
#### --report
There is also a (experimental) non-interactive mode:
```sh
$ owl spell --report
8 misspelled words in 5 files
```
This exits with a nonzero error code if there are misspellings, suitable for use in a CI-type context.
### owl word <words>
Quick non-interactive check of one or more words.
Example:
```sh
$ owl word good misteak
good ✓
misteak: ✗
mistake
mi steak
mi-steak
steak
```
### owl help
```
A TUI for managing your writing
Usage: owl <COMMAND>
Commands:
init Initialize a new project's owl.toml
check Show all checks for the project
spell Show all misspellings
word Check a single word
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
```
## Credits
Heavy-lifting done by [spellbook](https://github.com/helix-editor/spellbook), thanks to Helix team.
Dictionaries from [wooorm/dictionaries](https://github.com/wooorm/dictionaries/).
Inspiration for weasel words/duplicate checks from [Matt Might](https://matt.might.net/articles/shell-scripts-for-passive-voice-weasel-words-duplicates/).
Logo created using licensed Noun Project resources:
- [owl by Oksana Latysheva](https://thenounproject.com/icon/owl-1313864/)
- [pencil by Oksana Latysheva](https://thenounproject.com/icon/pencil-7979264/)