永井@知能.九工大です.

TkText に実装した search 系メソッドですが,
日本語テキストの場合に,正しく扱えませんでした.(^_^;
ruby-list での 'end' の件も含めて,
value, search_with_length, rsearch_with_length の三つを
以下のものと差し替えてください.

結局,search 系の実装では,Tcl/Tk のテキストウィジェットの
search コマンドは全く使わないことになりました.

# 以前は単純文字列の場合のみ,Tcl/Tk のコマンドを呼び出すように
# していたのですが,日本語文字列でトラブりましたので.

検索結果として Tcl/Tk の場合と同等の情報が得られるようにしてますが,
正規表現は Tcl/Tk のものではなく ruby のものですし,
glob 形式での検索には対応していません.
glob 形式非対応は Tcl/Tk -> Ruby/Tk 移植で
少し問題になるかもしれませんが,
同等の Ruby 正規表現に書き換えるのは難しくないでしょうから
この点は御了承ください.

-----------------------------------------------------------------------
  def value
    tk_send 'get', "1.0", "end - 1 char"
  end

  def search_with_length(pat,start,stop=None)
    pat = pat.char if pat.kind_of? Integer
    if stop != None
      return ["", 0] if compare(start,'>=',stop)
      txt = get(start,stop)
      if (pos = txt.index(pat))
	pos = txt[0..(pos-1)].split('').length if pos > 0
	if pat.kind_of? String
	  return [index(start + " + #{pos} chars"), pat.split('').length]
	else
	  return [index(start + " + #{pos} chars"), $&.split('').length]
	end
      else
	return ["", 0]
      end
    else
      txt = get(start,'end - 1 char')
      if (pos = txt.index(pat))
	pos = txt[0..(pos-1)].split('').length if pos > 0
	if pat.kind_of? String
	  return [index(start + " + #{pos} chars"), pat.split('').length]
	else
	  return [index(start + " + #{pos} chars"), $&.split('').length]
	end
      else
	txt = get('1.0','end - 1 char')
	if (pos = txt.index(pat))
	  pos = txt[0..(pos-1)].split('').length if pos > 0
	  if pat.kind_of? String
	    return [index("1.0 + #{pos} chars"), pat.split('').length]
	  else
	    return [index("1.0 + #{pos} chars"), $&.split('').length]
	  end
	else
	  return ["", 0]
	end
      end
    end
  end

  def rsearch_with_length(pat,start,stop=None)
    pat = pat.char if pat.kind_of? Integer
    if stop != None
      return ["", 0] if compare(start,'<=',stop)
      txt = get(stop,start)
      if (pos = txt.rindex(pat))
	pos = txt[0..(pos-1)].split('').length if pos > 0
	if pat.kind_of? String
	  return [index(stop + " + #{pos} chars"), pat.split('').length]
	else
	  return [index(stop + " + #{pos} chars"), $&.split('').length]
	end
      else
	return ["", 0]
      end
    else
      txt = get('1.0',start)
      if (pos = txt.rindex(pat))
	pos = txt[0..(pos-1)].split('').length if pos > 0
	if pat.kind_of? String
	  return [index("1.0 + #{pos} chars"), pat.split('').length]
	else
	  return [index("1.0 + #{pos} chars"), $&.split('').length]
	end
      else
	txt = get('1.0','end - 1 char')
	if (pos = txt.rindex(pat))
	  pos = txt[0..(pos-1)].split('').length if pos > 0
	  if pat.kind_of? String
	    return [index("1.0 + #{pos} chars"), pat.split('').length]
	  else
	    return [index("1.0 + #{pos} chars"), $&.split('').length]
	  end
	else
	  return ["", 0]
	end
      end
    end
  end
-----------------------------------------------------------------------

-- 
                                         永井 秀利 (九工大 知能情報)
                                             nagai / ai.kyutech.ac.jp