owl-write 0.5.0

A TUI for managing your writing
# 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.

![](docs/check-demo.gif)

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.

![](docs/spell-demo.gif)

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/