Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

RubyとCursesを使ったテキストエディタに編集と保存機能を追加する

作って覚えるRuby再入門(第3回)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/03/31 12:00

ダウンロード ソースコード (5.3 KB)

連載第三回目です。前回の続きでCursesを使ったテキストエディタを作っていきます。この例題を作っていくことで、Rubyの勘所と親近感を養ってもらえるとうれしいです。

目次

対象読者

  1. Rubyの入門書を一読した方
  2. 練習用にRubyのプログラムを作りたいが良い課題が見つからない方

必要なもの

 Ruby本体とお好きなエディタを用意してください。

 筆者は以下の環境で執筆しています。

 ruby 1.8.6-p111 / SAKURAエディタ / WindowsXPsp2

今回作る物

 前回の続きでコンソールベースのテキストエディタを作ります。前回では表示部分を主に作ったので、今回は編集と保存ができるようにしたいと思います。

 記事の最後には、下図のようなクラス構成になります。

クラス構成
クラス構成

バグの修正

 いきなりですが、前回のソースコードに少しバグがあるので修正してください。

 以下、「バグ修正」と書かれた次の行を追記してください。

editwind.rb
# カーソルを下へ移動。ウィンドウの下端より下へカーソルが移動
# しようとした場合はスクロール
def cursor_down
  if @cursor_y >= (@window.maxy-1)
    scroll_down
    # バグ修正
  elsif @cursor_y >= (@data.length-1)
    # 文章最大行数より下にはカーソルが動かないように
  else
    @cursor_y += 1
  end
## 中略 ##
end

編集モードの追加

 前回ではカーソルを動かせるコマンドモード用にHandlerクラスを作りましたが、今回は文字を入力する編集モード用にEditHandlerクラスを追加することにします。編集モードとコマンドモードの切り替えはESCキーで行うようにします。文字の削除は[x]で行うようにします。

handler.rb
require "editwind"
class Handler
  def execute(wind,input_ch)
      # コマンド入力を処理
      case input_ch
      when 27 # ESC
        return EditHandler.new
      when ?x
        wind.delete
      ## 中略 ##
  end
end

class EditHandler
  def execute(wind,input_ch)
      # 文字入力を処理
      case input_ch
      when 27 # ESC
        return Handler.new
      else
        wind.input(input_ch)
      end
      return self
  end
end

 ここであらかじめ入れておいた「ちいさな仕掛け」を活用します。Handlerクラスを利用しているFeクラスのメインループではexecuteメソッドの戻り値を、次に使うイベント処理オブジェクトとして受け取っています。(下記参照)

fe.rb
begin
  while true
    ch = edit_wind.getch #1文字入力。
    # イベント処理クラスで処理分岐を行う
    handler = handler.execute(edit_wind,ch)
  end
end

 HandlerEditHandlerの両クラスの方では、ESCキーを押されるたびに次に使用するイベント処理オブジェクト(HandlerではEditHandlerを、EditHandlerではその逆)をリターンしています。これによりメインループでは現在のモードを意識せずに「押されたキーを受け取りそれをイベント処理オブジェクトに渡す」事に専念できます。

 次にEditWindクラスに、編集モードで文字が入力された場合に呼び出されるメソッドinputとコマンドモードで[x]を押された時に呼び出されるメソッドdeleteを追加します。下記のようにeditwind.rbに追加してください。

editwind.rb
# 1文字(1バイト)入力
def input(input_ch)
  # ウィンドウ上で一文字挿入
  @window.insch(input_ch)
  # カーソルを微調整
  @window.setpos(@cursor_y,@cursor_x+=1)
end
# 1文字(1バイト)削除
def delete
  # ウィンドウ上で一文字削除
  @window.delch
end

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 越智 理夫(オチ マサオ)

    株式会社カサレアル プロフェッショナルサービスセンター所属。エンジニア向けトレーニングコースの開発および講師を行う。専門はJava,Ruby,OOAD,DOA,テスト駆動開発など。最近二歳の娘にこき使われている。

バックナンバー

連載:作って覚えるRuby再入門
All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5