moe - CLI based editor inspired by vi/vim written in Nim

# はじめに
この記事は[Nim Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nim) 2日目の記事で自分がNimで開発しているテキストエディタの宣伝です.
今回の記事では技術的な内容にはあまり触れません.
技術的な内容についてはそこまで大したことはしていないのですが要望があれば別の記事で書くかもしれません.

# moe
自分がNimを使って趣味で開発を行っているvim likeなCLIベースのテキストエディタです.
GitHub: https://github.com/fox0430/moe

moeはまだ開発で十分に安定していません. 自動バックアップの機能などはありますが重要なデータを編集する際は自己責任でお願いします.

# 名前について
テキストエディターに詳しい方ならすでに気づいてる方もいらっしゃるかもしれませんがGNU moeと名前が被っています. しかも同じくテキストエディターです.
名前を付けたあとに被っていることに気づいてしまったのですが由来含めて気に入っていることとコントリビューターの方にそのままで良いと言われたこともありとりあえずmoeのままで行くことにしました.
GitHubのページでも触れているのですが名前の由来は日本語の萌えとMoe is an Optimal Editorの頭文字を取って名付けました. GNU is Not Unixのノリです.

# Screenshots

![moe1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/48f4a414-25a0-5758-a4c4-da3638e396d9.png)
![moe3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/2a1100db-3269-9094-c027-983e5c23ed95.png)
![moe18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/f9c677eb-9350-2de1-f2a6-c41a21efb4d6.png)

# Install
UNIX likeなOSでnimbleとncursesを使用できる環境ならば簡単にインストールできます. Nimのバージョンは1.4.0以上が必要です.
基本的に最新のリリースよりdevelop branchの最新版推奨です.
macOSや*BSDでも動くとは思いますがLinuxかWSL推奨です.

```
nimble install moe@#head
```

# Features
気づいたら割と機能が多くなっていたので今回は自分が紹介したい機能だけ紹介したいと思います.

## GapBuffer
moeではGapBufferというデータ構造を採用しています. GapBufferはまさにテキストエディタのためのようなデータ構造で名前の通り挿入した場所にギャップを作り連続挿入を高速に行うことが可能となるデータ構造です. moeでは行をGapBufferで保持しています.
GapBufferはEmacsなどにも採用されています.

## Infinite undo/redo
moeは無制限のundo/redoが可能になっています. 現在insert modeでの動作はvimと異なっていて1文字ずつのundo/redoとなっています. これは将来vimと同じような挙動へ変更するかもしれません.

## Mode
vim likeなテキストエディタなので勿論vimのようにモードの概念が存在します. 現在使用できる主要なモードは以下のようになっています.

- Normal mode
- Insert mode
- Visual mode
- Visual block mode
- Replace mode
- Filer mode
- Ex (command line) mode

## Keybinds
勿論vim likeなキーバインドを使用することができます.
以下がmoeで使用できるキーバインドの一覧です.
https://github.com/fox0430/moe/blob/develop/documents/howtouse.md

まだvimには程遠いですが初心者が使うのには十分くらいのキーバインドは揃っていると思います. vimのキーバインドは順次追加中で要望があればどんどん追加していくつもりです.

## Statusline
ぱっと見は良い感じのステータスラインです. 設定で表示する項目の選択は可能ですがもっとカスタマイズ性を上げたいです.

![moe19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/bf504b54-da18-fe0f-735d-b131c54711ce.png)
![moe20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/e1210eec-c09b-28ba-cb25-64843153ad66.png)

## Incremental search
moeではvimにあるようなインクリメンタルサーチが可能になっています. 勿論検索でマッチした文字列は全てハイライトされ即座に移動することが可能です.

![moe8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/81e96c7e-3ef0-e385-fb6b-4be942640487.png)


## QuickRun
Vimのプラグインとして有名な[vim-quickrun](https://github.com/thinca/vim-quickrun)的な機能をビルドインで搭載しています.
```:run``` か ```\r```で実行することが可能です.

![moe4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/890cdca8-1d0e-49fa-f67b-cce67b18d12d.png)


今後の目標としては非同期での動作やターミナルビューに対応してログを見やすくするようなことをしていきたいです.

## Automatic backups
moeは自動バックアップに対応しておりデフォルトで有効になっています. moeは現在開発中でまだ十分に成熟していないので残念ながら安定しておらずクラッシュすることもあります.
もしクラッシュなどをしても自動バックアップをしたところまでは編集中のデーターを失わないようにこの機能をデフォルトで有効にしています.
ユーザーの操作を邪魔することが無いように一定時間操作がない場合にバックアップをするような形になっています(30秒操作がない場合など) 自動バックアップを行うタイミングなどは設定ファイルで設定することが可能です.

さらにAutomatic backupsでバックアップされたファイルをHistory modeというモードで管理することが可能です.
History modeではバックアップされたファイルの確認は勿論, 削除やリストアをすることが可能となっています.

![moe14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/8560bd84-2fde-5c52-d18a-a21aa9743a66.png)


## Auto save
デフォルトでは無効になっていますがmoeでは, Automatic backupsに加えてAuto saveを使用することも可能です.
Automatic backupsではバックアップ用のディレクトリ内にオリジナルのファイルのコピーを作成するのに対しこちらは純粋なAuto saveです.


## Auto-complete
moeは現在簡単な補完に対応しています. 仕組みとしては現在開いているバッファに存在する単語を補完の候補に入れる形になっています.
今後の目標としては, LSP (languae server prorocol) や nimsuggest といった物を使ってIDE likeな補完を実現したいと考えています.
さらにバッファの編集時だけではなくEx modeでの補完にも対応していてコマンドとコマンドのオプション, さらにファイルパスが補完されるようになっています.

![moe6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/d8e543e0-4939-df1a-c506-5166d7d88665.png)
![moe21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/d6a42675-aca8-611c-091b-79e78a7b9dea.png)
![moe13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/48397aff-1983-31e3-a65c-9b0971be321a.png)


## Configuration file
moeはTOMLを使用した設定ファイルで設定を行うことが可能となっています. TOMLはVim scriptなどのスクリプト言語と比べるとシンプルかつ直感的に設定が可能となっており初心者でも扱いやすいだろうと考えて初めに採用しました. moeはプロジェクトのゴールとして高いカスタマイズ性を目指しているので可能な限り設定項目を増やしていきたいと考えています.
サンプルの設定ファイル: https://github.com/fox0430/moe/blob/develop/example/moerc.toml

## Highlight trailing spaces
moeではデフォルトで行末のスペースをハイライトする機能が有効になっています. さらに行末のスペースだけではなく全角スペースのハイライトにも対応しています.

![moe7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/9d537c3f-1b62-e26b-0570-20b917847511.png)

## VSCode theme
moeはUIやSyntax highlightingの色を設定ファイルで設定可能ですがそれだけではなくVSCodeのthemeをmoeに反映することが可能となっています.
themeの設定でvscodeを選ぶと現在VSCodeに設定しているthemeファイルを自動で取得してなるべく雰囲気を近づけるような形で反映します.
まだ不完全ですが簡単に普段使用しているVSCodeと同じような雰囲気のテーマに設定することが可能です.

![moe15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/7059f354-7240-2932-e52e-231dae7eaf43.png)

## Highlight current words
moeは現在のカーソルの下にある単語をハイライトすることが可能になっています. これはvimの[vim_current_word](https://github.com/dominikduda/vim_current_word)のような物となっています.

![moe9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/b351b3df-06ac-9415-35cc-07f577623f0f.png)

## Indentation lines
スクリーンショットだと少し薄くて分かりづらいかもしれませんがインデントの深さを視覚的に表示する機能です.
vimで言う[indentLine](https://github.com/Yggdroot/indentLine)のような物となっています.

![moe16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/3a60a0ae-bac9-a592-2ac8-d8e29654e9b3.png)

## Live reloading configuration file
moeは設定ファイルのリアルタイムリロードに対応しています. デフォルトでは無効ですが設定ファイルの変更を即座に反映させたい場合はこの機能を使用して実現することが可能です.
基本的に設定ファイルのリアルタイムロードは設定ファイルで事前に設定しておく必要がありますがもしもmoeの起動中にいきなり使用したくなった場合でもEx modeから有効にすることが可能です.

## Auto close/delete paren
moeではデフォルトでカッコやクオーテーションの自動補完や自動削除に対応しています. さらにカッコの対応のハイライトも可能になっています.

![moe17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/1356355d-04f8-fae3-57a0-5c6c86a98165.png)

## Configuration mode
これはvimには無いmoeオリジナルのモードですが現在のエディタの設定をUI上で簡単に確認, 変更ができるモードです.
Configuration modeを使用することによりドキュメントを確認してわざわざ設定ファイルへ記述しなくても簡単に設定の変更が可能になります. 
実は設定の変更にはまだ対応できていないのですが次のリリースまでには対応予定です.

![moe10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/16d334a6-b34d-d28e-9856-c66b8d7c2381.png)

## File manager
vimでもnetrwがビルドインされていますが, moeでもfiler modeでファイルの管理が可能になっています.
現在はディレクトリの移動, ファイルのオープンや削除といった基本的な機能しか備えていませんが要望があれば機能を強化していきたいです.

![moe11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37650/7993d7e6-dd14-01d6-f624-aa78170694c2.png)

## Clipboard
moeでは標準でシステムクリップボードとの連携が可能です. Linuxではxclip、WSLではclip.exe、そしてmacOSではpbcopyを使用します.

# Roadmap

## Language Server Protocol
最近は対応しているエディターが増えてきました. LSPに対応することにより多くの言語のサポートが個別に対応することなく対応可能になるので開発リソースが足りていないmoeがLSPに対応することは非常に重要なことだと考えています.

## NimScript
Nimには[NimScript](https://nim-lang.org/docs/nims.html)というサブセットがあり、これを使用することで設定やプラグインの機能を提供する予定です.
NimScriptによるエディターの設定は近日対応予定です.

## Asynchronous
Auto saveやQuickRunといった機能は現在同期的に実行されるためそれらの機能を実行している間はエディターの操作ができなくなってしまう状態です.
将来的にはそれらの機能を非同期化する予定です.

## Terminal
VimやVSCodeではエディター内にTerminalを内蔵しています. moeもこれらのエディターのようにTerminalを実装する予定です.

## Plugin system
NimScriptのセクションでも触れましたがNimScriptを利用したプラグインシステムの実装を予定しています.
さらに将来的には、Xi editorのようなJSON RPCを使用した任意の言語でプラグインの開発が可能なプラグインシステムのサポートの構想もあります.

## Data structure
現在moeはデータ構造にGapBufferを採用していますが、将来的にRopeやPiece Tableといった他のデータ構造に対応し設定で好きなデータ構造をユーザーが選択できる機能というもの考えています.

## Performance
現在はハイライトを有効にしている状態では決して良いパフォーマンスとは言えないので近々改善したいです.

## ロゴとマスコットキャラクター
萌えな感じのロゴやマスコットキャラクターが欲しい. Webサイトも良い感じにしたい.

# さいごに
ここまで読んでくれた方ありがとうございます. とりあえず自分が紹介したい機能を軽く紹介してみました.
これからもどんどん改善や新機能の追加をしていくつもりなので興味を持った方はよろしくお願いします.
要望、バグの報告、コントリビュート大歓迎です.