自作エディターを作る! コンソールのサイズ/ファイル名、モード表示

今回はコンソールサイズを取得して、ページの行数を可変にしていきます。

今回やったこと

今回は前回の記事で書いたように、コンソールのサイズによって表示行数を可変にし、編集中のファイル名と現在のモードを表示するようにしました。またCEditEngineでやっていたファイルの表示をCEditControlに任せるようにしました。

各クラスの変更点は以下のようになっています。

  • class CEditEngine - 表示やページの切り替えをやめて、バッファの編集操作のみを担うクラスにする。
  • class CEditControl - 表示やページの切り替えをこのクラスでやる。コンソールのサイズで表示行数などを変える。編集中のファイル名と現在のモードを表示する。
  • console.cpp - コンソールのサイズを取得するAPIを追加する。

github.com

f:id:sanseido:20201031202553g:plain

ファイル名、現在の編集モード表示

 今回の開発内容

コンソールサイズの取得

この記事を参考にしました。

qiita.com

MSizeは高さと幅をセットにした構造体です。取得した結果を返しているだけです。

ちなみに、コンソールにアクセスする関数をconsole.cppにまとめている理由としては、別のライブラリや別の環境でのAPIを導入したときに、変更箇所をconsole.cppのみに限定するためです。よくラップ関数を作ってやるやつですね。

 

編集中のファイル名の表示

CEditControlクラスは編集中のファイル名をm_filenameに持っているので、それを表示しているだけです。ファイル名の表示は1行目全部を反転させたかったので、コンソールの幅分の長さの文字列をつくって(あまりは空白で埋めます)、背景色を変更した状態でprintf()しています。

文字列の空白埋め

文字列の空白埋めはstringstreamを使っています。std::setw()で文字列長を指定し、std::setfill(' ')で空白埋めしました。

最後にsstream::str()でstringを出力しています。

前景色(文字色)、背景色の制御

制御文字をprintf()することで背景色や前景色を変えることができます。この記事が非常に参考になりました。一度変更したら、もとに戻すのを忘れずに…。

dev.grapecity.co.jp

現在のモードの表示

これはそんなに語ることはありませんね。カーソル位置を調整してそこからprintf()すればいいです。カーソル位置の制御も制御文字をprintf()すればできます。こちらもこの記事に記載があります。

CEditEngineの役割の変更

これが今回一番悩みました。

CEditEngineクラスには今までエディタの描画も担当してもらっていて、なのでPageUp()、PageDown()もこのクラスのメソッドですし、現在どの行を表示しているか?などの情報も持っていました。

ですが、描画周りまで担当させてしまうと、コンソールとガチガチに組み合わさって移植性が下がっちゃうかな、と思って表示周りをCEditControlクラスに移しました。

(もともと今回の開発は、単独のアプリケーションとしてやろうとしていたものを、難しそうだから一旦コンソールで動くエディタとして作ろうとしているだけなので、今後の移植性を考えたときにCEditEngineにはあまり環境に依存するコードを入れたくないんですよね…。このこともあって、CEditEngineクラスからはconsole.cppの関数をあまり使いたくないです。)

次にやること

カーソルの移動をやりたいですね。十字キーは難しいらしいので、ひとまずアルファベットを適当に割り当ててやろうかな。折返しの事を考えて、論理行と物理行の概念を取り入れると思います。

あとは編集方式を考えないといけないですね。面倒なので最小は行エディタにしちゃおうかな?