Mercurial > kinput2.yaz
comparison lib/ruby/kinput2.rb @ 16:598fcbe482b5
imported patch 19_kinput2-v3.1-ruby.patch
| author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
|---|---|
| date | Mon, 08 Mar 2010 20:38:17 +0900 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 15:89750191b165 | 16:598fcbe482b5 |
|---|---|
| 1 $KCODE = 'e' | |
| 2 require "jcode" | |
| 3 require "kconv" | |
| 4 require 'suikyo/suikyo' | |
| 5 | |
| 6 module Debug | |
| 7 attr_accessor :debug_mode | |
| 8 def debug_message (message, output = nil) | |
| 9 if Debug::debug_mode?(output) || @debug_mode then | |
| 10 puts "#{self.class}[#{self.id}]: #{message}" | |
| 11 end | |
| 12 end | |
| 13 | |
| 14 def Debug::message (message, output = nil) | |
| 15 if Debug::debug_mode?(output) then | |
| 16 puts message | |
| 17 end | |
| 18 end | |
| 19 | |
| 20 def Debug::debug_mode? (output = nil) | |
| 21 return (ENV['RUBY_DEBUG'] || $DEBUG || output) | |
| 22 end | |
| 23 end | |
| 24 | |
| 25 class TextEdit | |
| 26 include Debug | |
| 27 | |
| 28 attr_reader :cursor | |
| 29 def initialize (text = "", cursor = 0) | |
| 30 @debug_mode = false | |
| 31 set (text, cursor) | |
| 32 end | |
| 33 | |
| 34 def set (data, cursor = 0) | |
| 35 @data = data | |
| 36 @cursor = cursor | |
| 37 end | |
| 38 | |
| 39 def text | |
| 40 return @data | |
| 41 end | |
| 42 | |
| 43 def reset | |
| 44 set ("", 0) | |
| 45 end | |
| 46 | |
| 47 def insert (string) | |
| 48 @data = @data[0,@cursor] + string + @data[@cursor..-1] | |
| 49 @cursor += string.length; | |
| 50 end | |
| 51 | |
| 52 def delete | |
| 53 if (@cursor < @data.length) then | |
| 54 @data = @data[0,@cursor] + @data[(@cursor + 1)..-1] | |
| 55 end | |
| 56 end | |
| 57 | |
| 58 def backspace | |
| 59 if (@cursor > 0) then | |
| 60 @data = @data[0,(@cursor - 1)] + @data[@cursor..-1] | |
| 61 @cursor -= 1 | |
| 62 end | |
| 63 end | |
| 64 | |
| 65 def cursor_left | |
| 66 if (@cursor > 0) then | |
| 67 @cursor -= 1 | |
| 68 end | |
| 69 end | |
| 70 | |
| 71 def cursor_right | |
| 72 if (@cursor < @data.length) then | |
| 73 @cursor += 1 | |
| 74 end | |
| 75 end | |
| 76 | |
| 77 def cursor_beginning | |
| 78 @cursor = 0 | |
| 79 end | |
| 80 | |
| 81 def cursor_end | |
| 82 @cursor = @data.length | |
| 83 end | |
| 84 | |
| 85 def segments | |
| 86 # [text before the cursor, text on the cursor, text after the cursor] | |
| 87 return [@data[0,@cursor], @data[@cursor,1], @data[(@cursor + 1)..-1]] | |
| 88 end | |
| 89 end | |
| 90 | |
| 91 class JTextEdit < TextEdit | |
| 92 def initialize (text = "", cursor = 0) | |
| 93 super | |
| 94 @suikyo = Suikyo.new | |
| 95 @suikyo.table.loadfile("romaji-kana") | |
| 96 end | |
| 97 | |
| 98 def text | |
| 99 if @cursor == @data.length then | |
| 100 return @suikyo.convert (@data) | |
| 101 else | |
| 102 return super | |
| 103 end | |
| 104 end | |
| 105 | |
| 106 def segments | |
| 107 if @cursor == @data.length then | |
| 108 return [@suikyo.convert (@data), '', ''] | |
| 109 else | |
| 110 return super | |
| 111 end | |
| 112 end | |
| 113 end | |
| 114 | |
| 115 class Window | |
| 116 attr_reader :call_open, :call_close, :visible | |
| 117 | |
| 118 def initialize (parent) | |
| 119 @parent = parent | |
| 120 @visible = false | |
| 121 end | |
| 122 | |
| 123 def open | |
| 124 @call_open = true unless @visible | |
| 125 end | |
| 126 def open_end | |
| 127 @call_open = false | |
| 128 @visible = true | |
| 129 end | |
| 130 | |
| 131 def close | |
| 132 @call_close = true if @visible | |
| 133 end | |
| 134 def close_end | |
| 135 @call_close = false | |
| 136 @visible = false | |
| 137 end | |
| 138 end | |
| 139 | |
| 140 class Dialog < Window | |
| 141 def text | |
| 142 @parent.cand_list.join(" ") | |
| 143 end | |
| 144 end | |
| 145 | |
| 146 class Selection < Window | |
| 147 attr_reader :call_right, :call_left, :call_line_beginning, :call_line_end, | |
| 148 :call_up, :call_down | |
| 149 | |
| 150 def right | |
| 151 @call_right = true | |
| 152 end | |
| 153 def right_end | |
| 154 @call_right = false | |
| 155 end | |
| 156 | |
| 157 def left | |
| 158 @call_left = true | |
| 159 end | |
| 160 def left_end | |
| 161 @call_left = false | |
| 162 end | |
| 163 | |
| 164 def line_beginning | |
| 165 @call_line_beginning = true | |
| 166 end | |
| 167 def line_beginning_end | |
| 168 @call_line_beginning = false | |
| 169 end | |
| 170 | |
| 171 def line_end | |
| 172 @call_line_end = true | |
| 173 end | |
| 174 def line_end_end | |
| 175 @call_line_end = false | |
| 176 end | |
| 177 | |
| 178 def up | |
| 179 @call_up = true | |
| 180 end | |
| 181 def up_end | |
| 182 @call_up = false | |
| 183 end | |
| 184 | |
| 185 def down | |
| 186 @call_down = true | |
| 187 end | |
| 188 def down_end | |
| 189 @call_down = false | |
| 190 end | |
| 191 end | |
| 192 | |
| 193 class KeyMap | |
| 194 @@keysym = { | |
| 195 :enter => 65293, | |
| 196 :space => 32, | |
| 197 :tab => 65289, | |
| 198 :delete => 65535, | |
| 199 :insert => 65379, | |
| 200 :home => 65360, | |
| 201 :end => 65367, | |
| 202 :page_up => 65365, | |
| 203 :page_down => 65366, | |
| 204 :esc => 65307, | |
| 205 :f1 => 65470, | |
| 206 :f2 => 65471, | |
| 207 :f3 => 65472, | |
| 208 :f4 => 65473, | |
| 209 :f5 => 65474, | |
| 210 :f6 => 65475, | |
| 211 :f7 => 65476, | |
| 212 :f8 => 65477, | |
| 213 :f9 => 65478, | |
| 214 :f10 => 65479, | |
| 215 :f11 => 65480, | |
| 216 :f12 => 65481, | |
| 217 :backspace => 65288, | |
| 218 :muhenkan => 65314, | |
| 219 :henkan => 65315, | |
| 220 :hankaku_zenkaku => 65322, | |
| 221 :katakana_hiragana => 65319, | |
| 222 :up => 65362, | |
| 223 :down => 65364, | |
| 224 :right => 65363, | |
| 225 :left => 65361, | |
| 226 :ctrl_l => 65507, | |
| 227 :ctrl_r => 65508, | |
| 228 :alt_l => 65513, | |
| 229 :alt_r => 65514, | |
| 230 :shift_l => 65505, | |
| 231 :shift_r => 65506, | |
| 232 } | |
| 233 | |
| 234 # @@enter = [13, 65293, 0] | |
| 235 # @@ctrl_a = [1, 97, 4]; @@alt_a = [97, 97, 8] | |
| 236 # @@ctrl_b = [2, 98, 4]; @@alt_b = [98, 98, 8] | |
| 237 # @@ctrl_c = [3, 99, 4]; @@alt_c = [99, 99, 8] | |
| 238 # @@ctrl_d = [4, 100, 4]; @@alt_d = [100, 100, 8] | |
| 239 # @@ctrl_e = [5, 101, 4]; @@alt_e = [101, 101, 8] | |
| 240 # @@ctrl_f = [6, 102, 4]; @@alt_f = [102, 102, 8] | |
| 241 # @@ctrl_g = [7, 103, 4]; @@alt_g = [103, 103, 8] | |
| 242 # @@ctrl_h = [8, 104, 4]; @@alt_h = [104, 104, 8] | |
| 243 # @@ctrl_i = [9, 105, 4]; @@alt_i = [105, 105, 8] | |
| 244 # @@ctrl_j = [10, 106, 4]; @@alt_j = [106, 106, 8] | |
| 245 # @@ctrl_k = [11, 107, 4]; @@alt_k = [107, 107, 8] | |
| 246 # @@ctrl_l = [12, 108, 4]; @@alt_l = [108, 108, 8] | |
| 247 # @@ctrl_m = [13, 109, 4]; @@alt_m = [109, 109, 8] | |
| 248 # @@ctrl_n = [14, 110, 4]; @@alt_n = [110, 110, 8] | |
| 249 # @@ctrl_o = [15, 111, 4]; @@alt_o = [111, 111, 8] | |
| 250 # @@ctrl_p = [16, 112, 4]; @@alt_p = [112, 112, 8] | |
| 251 # @@ctrl_q = [17, 113, 4]; @@alt_q = [113, 113, 8] | |
| 252 # @@ctrl_r = [18, 114, 4]; @@alt_r = [114, 114, 8] | |
| 253 # @@ctrl_s = [19, 115, 4]; @@alt_s = [115, 115, 8] | |
| 254 # @@ctrl_t = [20, 116, 4]; @@alt_t = [116, 116, 8] | |
| 255 # @@ctrl_u = [21, 117, 4]; @@alt_u = [117, 117, 8] | |
| 256 # @@ctrl_v = [22, 118, 4]; @@alt_v = [118, 118, 8] | |
| 257 # @@ctrl_w = [23, 119, 4]; @@alt_w = [119, 119, 8] | |
| 258 # @@ctrl_x = [24, 120, 4]; @@alt_x = [120, 120, 8] | |
| 259 # @@ctrl_y = [25, 121, 4]; @@alt_y = [121, 121, 8] | |
| 260 # @@ctrl_z = [26, 122, 4]; @@alt_z = [122, 122, 8] | |
| 261 | |
| 262 @@modifier = { :shift => 1, :ctrl => 4, :alt => 8 } | |
| 263 | |
| 264 def initialize | |
| 265 @keymap = Hash.new | |
| 266 end | |
| 267 | |
| 268 def key (stroke) | |
| 269 modifiers = 0 | |
| 270 if stroke.kind_of?(Array) then | |
| 271 main_key = stroke[0] | |
| 272 stroke[1..-1].each {|modifier| | |
| 273 modifiers |= | |
| 274 (modifier.kind_of?(Symbol) ? @@modifier[modifier] : modifier) | |
| 275 } | |
| 276 else | |
| 277 main_key = stroke | |
| 278 end | |
| 279 if main_key.kind_of?(Symbol) then | |
| 280 main_key = @@keysym[main_key] | |
| 281 end | |
| 282 return [main_key, modifiers] | |
| 283 end | |
| 284 | |
| 285 def ignore_shift (key) | |
| 286 (main_key, modifiers) = key | |
| 287 return [main_key, (modifiers & ~@@modifier[:shift])] | |
| 288 end | |
| 289 | |
| 290 def add (stroke, command) | |
| 291 @keymap[key(stroke)] = command | |
| 292 end | |
| 293 | |
| 294 def del (stroke) | |
| 295 @keymap.delete(key(stroke)) | |
| 296 end | |
| 297 | |
| 298 def command (stroke) | |
| 299 return @keymap[key(stroke)] || @keymap[ignore_shift(key(stroke))] | |
| 300 end | |
| 301 end | |
| 302 | |
| 303 | |
| 304 class ModeCore | |
| 305 attr_accessor :trap | |
| 306 attr_reader :label, :keymap | |
| 307 def initialize (parent) | |
| 308 @parent = parent | |
| 309 @label = "" | |
| 310 @keymap = KeyMap.new | |
| 311 initialize_keys | |
| 312 @trap = true | |
| 313 end | |
| 314 | |
| 315 def on (prev_mode = nil) | |
| 316 end | |
| 317 | |
| 318 def off (next_mode = nil) | |
| 319 end | |
| 320 | |
| 321 def entries | |
| 322 return [] | |
| 323 end | |
| 324 | |
| 325 def call (char, keysym, modifiers) | |
| 326 command = @keymap.command([keysym, modifiers]) | |
| 327 if command then | |
| 328 return send(command, keysym, modifiers) | |
| 329 else | |
| 330 return @trap | |
| 331 end | |
| 332 end | |
| 333 end | |
| 334 | |
| 335 class ModeMaster | |
| 336 attr_reader :current_name | |
| 337 | |
| 338 def initialize (parent, mode = :fund) | |
| 339 @parent = parent | |
| 340 @mode = Hash.new | |
| 341 @current_name = nil | |
| 342 end | |
| 343 | |
| 344 def set (name, mode) | |
| 345 @mode[name] = mode | |
| 346 unless @current then | |
| 347 @current_name = name | |
| 348 end | |
| 349 end | |
| 350 | |
| 351 def current | |
| 352 return @mode[@current_name] | |
| 353 end | |
| 354 | |
| 355 def change (name) | |
| 356 if @mode.key?(name) then | |
| 357 @current_name = name | |
| 358 current.on | |
| 359 return true | |
| 360 else | |
| 361 return false | |
| 362 end | |
| 363 end | |
| 364 | |
| 365 def label (name = @current_name) | |
| 366 if name then | |
| 367 mode = @mode[name] | |
| 368 else | |
| 369 mode = current | |
| 370 end | |
| 371 | |
| 372 if mode then | |
| 373 return mode.label.toeuc | |
| 374 else | |
| 375 return "NOMODE" | |
| 376 end | |
| 377 end | |
| 378 end | |
| 379 | |
| 380 class KanjiConvCore | |
| 381 include Debug | |
| 382 attr_reader :cand_list, :cand_index, | |
| 383 :value_fixed, :call_fix, :mode | |
| 384 | |
| 385 def initialize | |
| 386 @debug_mode = false | |
| 387 | |
| 388 @textEdit = TextEdit.new | |
| 389 @mode = ModeMaster.new (self) | |
| 390 clear | |
| 391 end | |
| 392 | |
| 393 def reset | |
| 394 clear | |
| 395 end | |
| 396 | |
| 397 def clear | |
| 398 @cand_list = [] | |
| 399 @cand_index = 0 | |
| 400 | |
| 401 @call_fix = false | |
| 402 @value_fixed = "" | |
| 403 end | |
| 404 | |
| 405 ## inputEvent (keynum, keysym = nil, state = nil) | |
| 406 ## ReturnValue 1:Pass 0:Trap | |
| 407 def inputEvent (keynum, keysym = nil, state = nil) | |
| 408 return 1 | |
| 409 end | |
| 410 | |
| 411 def fix (fixed_arg) | |
| 412 # fixed_arg is a string or an index number of cand_list. | |
| 413 @call_fix = true | |
| 414 if fixed_arg.kind_of?(Integer) then | |
| 415 word = @cand_list[fixed_arg] | |
| 416 else | |
| 417 word = fixed_arg | |
| 418 end | |
| 419 @value_fixed = word | |
| 420 end | |
| 421 def fix_end | |
| 422 @call_fix = false | |
| 423 @value_fixed = "" | |
| 424 end | |
| 425 | |
| 426 def modeline | |
| 427 return @mode.label | |
| 428 end | |
| 429 | |
| 430 def set_cand_list (list, index = nil) | |
| 431 if (list.is_a?(Array) && list.length > 0) then | |
| 432 @cand_list = list.map {|cand| cand.toeuc} | |
| 433 @cand_index = index if index | |
| 434 return true | |
| 435 else | |
| 436 reset_cand_list | |
| 437 return false | |
| 438 end | |
| 439 end | |
| 440 def set_cand_index (index) | |
| 441 debug_message("<<set_cand_index>> #{index}") | |
| 442 @cand_index = index | |
| 443 end | |
| 444 def reset_cand_list | |
| 445 @cand_list = [] | |
| 446 @cand_index = 0 | |
| 447 end | |
| 448 | |
| 449 def segment_length | |
| 450 segments = (@mode.current.entries - ['']) | |
| 451 return segments.length | |
| 452 end | |
| 453 def segment_word (n) | |
| 454 segments = (@mode.current.entries - ['']) | |
| 455 return segments[n] | |
| 456 end | |
| 457 def segment_status (n) | |
| 458 segments = @mode.current.entries | |
| 459 offset = 0 | |
| 460 if segments[0] == "" then | |
| 461 offset += 1 | |
| 462 end | |
| 463 return ((n + offset) % 3 == 1) ? :highlight : :normal | |
| 464 end | |
| 465 end |
