1# Copyright (c) 2011, Tomohiro Kusumi 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are met: 6# 7# 1. Redistributions of source code must retain the above copyright notice, this 8# list of conditions and the following disclaimer. 9# 2. Redistributions in binary form must reproduce the above copyright notice, 10# this list of conditions and the following disclaimer in the documentation 11# and/or other materials provided with the distribution. 12# 13# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24import sys 25 26from . import console 27from . import edit 28from . import extension 29from . import kbd 30from . import literal 31from . import methods 32from . import panel 33from . import screen 34from . import setting 35from . import util 36 37VISUAL = "VISUAL" 38VISUAL_LINE = "VISUAL LINE" 39VISUAL_BLOCK = "VISUAL BLOCK" 40 41class _visual_methods (object): 42 def init(self): 43 if setting.color_visual is None: 44 if screen.use_alt_chgat(): 45 self.__chgat_head = self.__alt_chgat_head 46 self.__chgat_tail = self.__alt_chgat_tail 47 self.__chgat_single = self.__alt_chgat_single 48 self.__chgat_inside = self.__alt_chgat_inside 49 self.__chgat_outside = self.__alt_chgat_outside 50 else: 51 if screen.use_alt_chgat(): 52 self.__chgat_head = self.__alt_chgat_head_attr 53 self.__chgat_tail = self.__alt_chgat_tail_attr 54 self.__chgat_single = self.__alt_chgat_single_attr 55 self.__chgat_outside = self.__alt_chgat_outside_attr 56 else: # default 57 self.__chgat_head = self.__chgat_head_attr 58 self.__chgat_tail = self.__chgat_tail_attr 59 self.__chgat_single = self.__chgat_single_attr 60 self.__chgat_outside = self.__chgat_outside_attr 61 62 def update_visual(self, full): 63 if not self.fileops.has_region(): 64 return # last repaint before exit 65 t = self.fileops.get_region_type() 66 if t == VISUAL_BLOCK: 67 self.__update_block_visual(full) 68 else: 69 self.__update_visual(t, full) 70 pos = self.fileops.get_pos() 71 self.page_update_search(pos) 72 self.chgat_cursor(pos, screen.A_COLOR_CURRENT, screen.A_COLOR_CURRENT, 73 False) 74 75 def __update_visual(self, t, full): 76 pos = self.fileops.get_pos() 77 ppos = self.fileops.get_prev_pos() 78 if self.in_same_page(pos, ppos): 79 self.chgat_posstr(ppos, screen.A_NONE) 80 else: 81 full = True 82 self.chgat_posstr(pos, self.attr_posstr) 83 84 beg = self.fileops.get_region_origin() 85 end = pos 86 if beg > end: 87 beg, end = end, beg 88 mapx = self.bufmap.x 89 if t == VISUAL_LINE: 90 beg -= beg % mapx 91 end += (mapx - 1 - end % mapx) 92 if setting.use_unit_based and (end % setting.bytes_per_unit == 0): 93 end += (setting.bytes_per_unit - 1) # round up before set region 94 self.fileops.set_region_range(beg, end, self.bufmap) 95 96 pgo = self.get_page_offset() 97 npgo = self.get_next_page_offset() 98 if beg < pgo: 99 beg = pgo 100 if end > npgo - 1: 101 end = npgo - 1 102 lcur = pgo 103 104 l = [] 105 if not full: 106 a = self.get_line_offset(pos) 107 b = self.get_line_offset(ppos) 108 if a == b: 109 l = [a] 110 else: 111 if a < b: 112 a, b = b, a 113 l = [b + i for i in util.get_xrange(0, a - b + mapx, mapx)] 114 115 limit = self.fileops.get_max_pos() 116 y = self.offset.y 117 x = self.offset.x 118 for _ in util.get_xrange(self.bufmap.y): 119 if lcur > limit: 120 break 121 lnext = lcur + mapx 122 if full or (lcur in l): 123 head = lcur <= beg < lnext 124 tail = lcur <= end < lnext 125 if head and tail: 126 self.__chgat_single(y, x, beg, end, lcur) 127 elif head: 128 self.__chgat_head(y, x, beg, lcur) 129 elif tail: 130 self.__chgat_tail(y, x, end, lcur) 131 elif beg < lcur < end: 132 self.__chgat_inside(y, x, lcur) 133 else: 134 self.__chgat_outside(y, x, lcur) 135 lcur = lnext 136 y += 1 137 138 def __update_block_visual(self, full): 139 pos = self.fileops.get_pos() 140 ppos = self.fileops.get_prev_pos() 141 if self.in_same_page(pos, ppos): 142 self.chgat_posstr(ppos, screen.A_NONE) 143 else: 144 full = True 145 self.chgat_posstr(pos, self.attr_posstr) 146 147 beg = self.fileops.get_region_origin() 148 end = pos 149 if beg > end: 150 beg, end = end, beg 151 mapx = self.bufmap.x 152 d1 = beg % mapx 153 d2 = end % mapx 154 lbeg = beg - d1 155 lend = end - d2 156 if d1 > d2: 157 d2, d1 = d1, d2 158 if setting.use_unit_based: 159 d2 += (setting.bytes_per_unit - 1) # round up before set region 160 self.fileops.set_region_range(lbeg + d1, lend + d2, self.bufmap) 161 162 lcur = self.get_page_offset() 163 lpos = self.get_line_offset(pos) 164 lppos = self.get_line_offset(ppos) 165 lr = abs(pos - ppos) != mapx # move left/right 166 167 l = [] 168 if not full: 169 a, b = lpos, lppos 170 if a == b: 171 l = [a] 172 else: 173 if a < b: 174 a, b = b, a 175 l = [b + i for i in util.get_xrange(0, a - b + mapx, mapx)] 176 177 limit = self.fileops.get_max_pos() 178 y = self.offset.y 179 x = self.offset.x 180 for _ in util.get_xrange(self.bufmap.y): 181 if lcur > limit: 182 break 183 if full or lr or (lcur in l): 184 # XXX second and third conditionals are redundant 185 if lbeg <= lcur <= lend: 186 self.__chgat_single(y, x, lcur + d1, lcur + d2, lcur) 187 elif lppos <= lcur < lbeg and lpos == lbeg and lppos < lpos: 188 self.__chgat_outside(y, x, lcur) # down 189 elif lend < lcur <= lppos and lpos == lend and lpos < lppos: 190 self.__chgat_outside(y, x, lcur) # up 191 elif lppos < lbeg: # jump down to other side of region 192 self.__chgat_outside(y, x, lcur) 193 elif lend < lppos: # jump up to other side of region 194 self.__chgat_outside(y, x, lcur) 195 lcur += mapx 196 y += 1 197 198 def post_fill_line(self, y, x, buf): 199 if not self.cell[1]: 200 return 201 # need to drop visual color from space within unit 202 upl, xpu = self.get_units_per_line(len(buf)) 203 for i in util.get_xrange(upl): 204 extra = ' ' * self.cell[1] 205 pos = x + self.get_unit_width(i + 1) - len(extra) 206 if pos < self.get_size_x(): 207 # pos + len(extra) - 1 still needs to fit 208 self.addstr(y, pos, extra) 209 210 # head 211 def __chgat_head(self, y, x, beg, offset): 212 pos = self.get_cell_width(beg - offset) 213 siz = self.get_cell_edge(self.bufmap.x) - pos 214 self.chgat(y, x, pos) 215 if x + pos < self.get_size_x(): 216 self.chgat(y, x + pos, siz, self.attr_visual) 217 218 def __alt_chgat_head(self, y, x, beg, offset): 219 pos = self.get_cell_width(beg - offset) 220 buf = self.fileops.read(offset, self.bufmap.x) 221 s = self.get_str_line(buf) 222 d = self.get_cell_edge(self.bufmap.x) - len(s) 223 if d > 0: 224 s += ' ' * d 225 self.addstr(y, x, s[:pos]) 226 if x + pos < self.get_size_x(): 227 self.addstr(y, x + pos, s[pos:], self.attr_visual) 228 229 def __chgat_head_attr(self, y, x, beg, offset): 230 pos = self.get_cell_width(beg - offset) 231 siz = self.get_cell_edge(self.bufmap.x) - pos 232 buf = self.fileops.read(offset, beg - offset) 233 self.fill_line(y, x, buf, screen.A_NONE, 234 self.get_units_per_line(len(buf))) 235 self.post_fill_line(y, x, buf) 236 if x + pos < self.get_size_x(): 237 self.chgat(y, x + pos, siz, self.attr_visual) 238 239 def __alt_chgat_head_attr(self, y, x, beg, offset): 240 pos = self.get_cell_width(beg - offset) 241 buf = self.fileops.read(offset, self.bufmap.x) 242 s = self.get_str_line(buf) 243 d = self.get_cell_edge(self.bufmap.x) - len(s) 244 if d > 0: 245 s += ' ' * d 246 buf = self.fileops.read(offset, beg - offset) 247 self.fill_line(y, x, buf, screen.A_NONE, 248 self.get_units_per_line(len(buf))) 249 self.post_fill_line(y, x, buf) 250 if x + pos < self.get_size_x(): 251 self.addstr(y, x + pos, s[pos:], self.attr_visual) 252 253 # tail 254 def __chgat_tail(self, y, x, end, offset): 255 pos = self.get_cell_edge(end - offset + 1) 256 siz = self.get_cell_edge(self.bufmap.x) - pos 257 self.chgat(y, x, pos, self.attr_visual) 258 if x + pos < self.get_size_x(): 259 self.chgat(y, x + pos, siz) 260 261 def __alt_chgat_tail(self, y, x, end, offset): 262 pos = self.get_cell_edge(end - offset + 1) 263 buf = self.fileops.read(offset, self.bufmap.x) 264 s = self.get_str_line(buf) 265 d = pos - len(s) 266 if d > 0: 267 s += ' ' * d 268 self.addstr(y, x, s[:pos], self.attr_visual) 269 if x + pos < self.get_size_x(): 270 self.addstr(y, x + pos, s[pos:]) 271 272 def __chgat_tail_attr(self, y, x, end, offset): 273 siz = self.get_cell_edge(end - offset + 1) 274 self.chgat(y, x, siz, self.attr_visual) 275 if end + 1 <= self.fileops.get_max_pos(): 276 self.__chgat_tail_attr_clear(y, x, end, offset) 277 278 def __alt_chgat_tail_attr(self, y, x, end, offset): 279 siz = self.get_cell_edge(end - offset + 1) 280 buf = self.fileops.read(offset, self.bufmap.x) 281 s = self.get_str_line(buf) 282 d = siz - len(s) 283 if d > 0: 284 s += ' ' * d 285 self.addstr(y, x, s[:siz], self.attr_visual) 286 if end + 1 <= self.fileops.get_max_pos(): 287 self.__chgat_tail_attr_clear(y, x, end, offset) 288 289 def __chgat_tail_attr_clear(self, y, x, end, offset): 290 num = end - offset + 1 291 buf = self.fileops.read(end + 1, self.bufmap.x - num) 292 pos = self.get_cell_width(num) 293 xx = self.fill_line_nth(y, x + pos, buf, num, screen.A_NONE) 294 self.post_fill_line(y, xx, buf) 295 if (end + 1) % self.bufmap.x: # not rightmost 296 # clear right side of newly fill'd line (needed when moving left/up) 297 unitlen = setting.bytes_per_unit 298 if (num % unitlen) == 0: 299 self.addstr(y, x + pos - 1, ' ' * self.cell[1]) 300 else: 301 skip = unitlen - (num % unitlen) 302 skip *= self.cell[2] 303 xx = x + pos + skip 304 if xx <= self.get_size_x() - 1: 305 # xx + len(...) - 1 still needs to fit 306 self.addstr(y, xx, ' ' * self.cell[1]) 307 308 # single 309 def __chgat_single(self, y, x, beg, end, offset): 310 pos = self.get_cell_width(beg - offset) 311 siz = self.get_cell_distance(beg, end) 312 wid = self.get_cell_edge(self.bufmap.x) 313 self.chgat(y, x, wid) 314 if x + pos < self.get_size_x(): 315 self.chgat(y, x + pos, siz, self.attr_visual) 316 317 def __alt_chgat_single(self, y, x, beg, end, offset): 318 pos = self.get_cell_width(beg - offset) 319 siz = self.get_cell_distance(beg, end) 320 end = pos + siz 321 buf = self.fileops.read(offset, self.bufmap.x) 322 s = self.get_str_line(buf) 323 d = end - len(s) 324 if d > 0: 325 s += ' ' * d 326 self.addstr(y, x, s[:pos]) 327 if x + pos < self.get_size_x(): 328 self.addstr(y, x + pos, s[pos:end], self.attr_visual) 329 if x + end < self.get_size_x(): 330 self.addstr(y, x + end, s[end:]) 331 332 def __chgat_single_attr(self, y, x, beg, end, offset): 333 pos = self.get_cell_width(beg - offset) 334 siz = self.get_cell_distance(beg, end) 335 buf = self.fileops.read(offset, self.bufmap.x) 336 self.fill_line(y, x, buf, screen.A_NONE, 337 self.get_units_per_line(len(buf))) 338 self.post_fill_line(y, x, buf) 339 if x + pos < self.get_size_x(): 340 self.chgat(y, x + pos, siz, self.attr_visual) 341 342 def __alt_chgat_single_attr(self, y, x, beg, end, offset): 343 pos = self.get_cell_width(beg - offset) 344 siz = self.get_cell_distance(beg, end) 345 end = pos + siz 346 buf = self.fileops.read(offset, self.bufmap.x) 347 s = self.get_str_line(buf) 348 d = end - len(s) 349 if d > 0: 350 s += ' ' * d 351 buf = self.fileops.read(offset, self.bufmap.x) 352 self.fill_line(y, x, buf, screen.A_NONE, 353 self.get_units_per_line(len(buf))) 354 self.post_fill_line(y, x, buf) 355 if x + pos < self.get_size_x(): 356 self.addstr(y, x + pos, s[pos:end], self.attr_visual) 357 358 # inside 359 def __chgat_inside(self, y, x, offset): 360 self.__chgat_body(y, x, offset, self.attr_visual) 361 362 def __alt_chgat_inside(self, y, x, offset): 363 self.__alt_chgat_body(y, x, offset, self.attr_visual) 364 365 # outside 366 def __chgat_outside(self, y, x, offset): 367 self.__chgat_body(y, x, offset, screen.A_NONE) 368 369 def __alt_chgat_outside(self, y, x, offset): 370 self.__alt_chgat_body(y, x, offset, screen.A_NONE) 371 372 def __chgat_outside_attr(self, y, x, offset): 373 self.__chgat_body_attr(y, x, offset, screen.A_NONE) 374 375 def __alt_chgat_outside_attr(self, y, x, offset): 376 self.__chgat_body_attr(y, x, offset, screen.A_NONE) 377 378 # body 379 def __chgat_body(self, y, x, offset, attr): 380 siz = self.get_cell_edge(self.bufmap.x) 381 self.chgat(y, x, siz, attr) 382 383 def __alt_chgat_body(self, y, x, offset, attr): 384 buf = self.fileops.read(offset, self.bufmap.x) 385 s = self.get_str_line(buf) 386 d = self.get_cell_edge(self.bufmap.x) - len(s) 387 if d > 0: 388 s += ' ' * d 389 self.addstr(y, x, s, attr) 390 391 def __chgat_body_attr(self, y, x, offset, attr): 392 buf = self.fileops.read(offset, self.bufmap.x) 393 if self.fileops.get_region_type() == VISUAL_LINE and \ 394 len(buf) != self.bufmap.x: 395 self.clrl(y, x) # clear last line beyond max position 396 self.fill_line(y, x, buf, attr, 397 self.get_units_per_line(len(buf))) 398 self.post_fill_line(y, x, buf) 399 400class BinaryCanvas (panel.BinaryCanvas, _visual_methods): 401 def __init__(self, siz, pos): 402 self.init() 403 super(BinaryCanvas, self).__init__(siz, pos) 404 405 def fill(self, low): 406 self.require_full_repaint() 407 super(BinaryCanvas, self).fill(low) 408 self.update_visual(True) 409 410 def update_highlight(self, low, range_update): 411 self.require_full_repaint() 412 self.update_visual(False) 413 414class TextCanvas (panel.TextCanvas, _visual_methods): 415 def __init__(self, siz, pos): 416 self.init() 417 super(TextCanvas, self).__init__(siz, pos) 418 419 def fill(self, low): 420 self.require_full_repaint() 421 super(TextCanvas, self).fill(low) 422 self.update_visual(True) 423 424 def update_highlight(self, low, range_update): 425 self.require_full_repaint() 426 self.update_visual(False) 427 428class ExtBinaryCanvas (extension.ExtBinaryCanvas, _visual_methods): 429 def __init__(self, siz, pos): 430 self.init() 431 super(ExtBinaryCanvas, self).__init__(siz, pos) 432 433 def fill(self, low): 434 self.require_full_repaint() 435 super(ExtBinaryCanvas, self).fill(low) 436 self.update_visual(True) 437 438 def update_highlight(self, low, range_update): 439 self.require_full_repaint() 440 self.update_visual(False) 441 442class _console (console.Console): 443 def init_method(self): 444 this = sys.modules[__name__] 445 self.add_method(literal.up , methods, "cursor_up") 446 self.add_method(literal.down , methods, "cursor_down") 447 self.add_method(literal.left , methods, "cursor_left") 448 self.add_method(literal.right , methods, "cursor_right") 449 self.add_method(literal.gg , methods, "cursor_head") 450 self.add_method(literal.G , methods, "cursor_tail") 451 self.add_method(literal.zero , methods, "cursor_lhead") 452 self.add_method(literal.doller , methods, "cursor_ltail") 453 self.add_method(literal.H , methods, "cursor_phead") 454 self.add_method(literal.M , methods, "cursor_pcenter") 455 self.add_method(literal.L , methods, "cursor_ptail") 456 self.add_method(literal.w , methods, "cursor_next_char") 457 self.add_method(literal.b , methods, "cursor_prev_char") 458 self.add_method(literal.parens_end , methods, "cursor_next_zero") 459 self.add_method(literal.parens_beg , methods, "cursor_prev_zero") 460 self.add_method(literal.bracket1_end , methods, "cursor_next_nonzero") 461 self.add_method(literal.bracket1_beg , methods, "cursor_prev_nonzero") 462 self.add_method(literal.bracket2_end , methods, "end_read_delayed_input") 463 self.add_method(literal.bracket2_beg , methods, "start_read_delayed_input") 464 self.add_method(literal.go , methods, "cursor_to") 465 self.add_method(literal.sh , methods, "cursor_sector_left") 466 self.add_method(literal.sl , methods, "cursor_sector_right") 467 self.add_method(literal.szero , methods, "cursor_sector_shead") 468 self.add_method(literal.sdoller , methods, "cursor_sector_stail") 469 self.add_method(literal.sgo , methods, "cursor_sector_to") 470 self.add_method(literal.ctrlb , methods, "cursor_pprev") 471 self.add_method(literal.ctrlu , methods, "cursor_hpprev") 472 self.add_method(literal.ctrlf , methods, "cursor_pnext") 473 self.add_method(literal.ctrld , methods, "cursor_hpnext") 474 self.add_method(literal.mouse , methods, "handle_mouse_event_visual") 475 self.add_method(literal.resize , methods, "resize_container") 476 self.add_method(literal.ctrll , methods, "refresh_container") 477 self.add_method(literal.ctrlw_w , this, "_queue_input") 478 self.add_method(literal.ctrlw_W , this, "_queue_input") 479 self.add_method(literal.ctrlw_t , this, "_queue_input") 480 self.add_method(literal.ctrlw_b , this, "_queue_input") 481 self.add_method(literal.ctrlw_s , this, "_queue_input") 482 self.add_method(literal.s_split , this, "_queue_input") 483 self.add_method(literal.s_vsplit , this, "_queue_input") 484 self.add_method(literal.ctrlw_plus , methods, "inc_workspace_height") 485 self.add_method(literal.ctrlw_minus , methods, "dec_workspace_height") 486 self.add_method(literal.s_close , this, "_queue_input") 487 self.add_method(literal.s_only , this, "_queue_input") 488 self.add_method(literal.s_e , this, "_queue_input") 489 self.add_method(literal.s_bdelete , this, "_queue_input") 490 self.add_method(literal.s_bfirst , this, "_queue_input") 491 self.add_method(literal.s_blast , this, "_queue_input") 492 self.add_method(literal.s_bnext , this, "_queue_input") 493 self.add_method(literal.s_bprev , this, "_queue_input") 494 self.add_method(literal.s_set , methods, "set_option") 495 self.add_method(literal.s_auto , methods, "set_auto") 496 self.add_method(literal.ctrlg , this, "_queue_input") 497 self.add_method(literal.g_ctrlg , this, "_queue_input") 498 self.add_method(literal.s_self , this, "_queue_input") 499 self.add_method(literal.s_pwd , this, "_queue_input") 500 self.add_method(literal.s_date , this, "_queue_input") 501 self.add_method(literal.s_kmod , this, "_queue_input") 502 self.add_method(literal.s_fobj , this, "_queue_input") 503 self.add_method(literal.s_bufsiz , this, "_queue_input") 504 self.add_method(literal.s_meminfo , this, "_queue_input") 505 self.add_method(literal.s_osdep , this, "_queue_input") 506 self.add_method(literal.s_screen , this, "_queue_input") 507 self.add_method(literal.s_platform , this, "_queue_input") 508 self.add_method(literal.s_hostname , this, "_queue_input") 509 self.add_method(literal.s_term , this, "_queue_input") 510 self.add_method(literal.s_lang , this, "_queue_input") 511 self.add_method(literal.s_version , this, "_queue_input") 512 self.add_method(literal.s_sector , this, "_queue_input") 513 self.add_method(literal.s_argv , this, "_queue_input") 514 self.add_method(literal.s_args , this, "_queue_input") 515 self.add_method(literal.s_md5 , this, "_show_md5") 516 self.add_method(literal.s_sha1 , this, "_show_sha1") 517 self.add_method(literal.s_sha224 , this, "_show_sha224") 518 self.add_method(literal.s_sha256 , this, "_show_sha256") 519 self.add_method(literal.s_sha384 , this, "_show_sha384") 520 self.add_method(literal.s_sha512 , this, "_show_sha512") 521 self.add_method(literal.s_sha3_224 , this, "_show_sha3_224") 522 self.add_method(literal.s_sha3_256 , this, "_show_sha3_256") 523 self.add_method(literal.s_sha3_384 , this, "_show_sha3_384") 524 self.add_method(literal.s_sha3_512 , this, "_show_sha3_512") 525 self.add_method(literal.s_cmp , this, "_queue_input") 526 self.add_method(literal.s_cmpneg , this, "_queue_input") 527 self.add_method(literal.s_cmpnext , this, "_queue_input") 528 self.add_method(literal.s_cmpnextneg , this, "_queue_input") 529 self.add_method(literal.s_cmpr , this, "_queue_input") 530 self.add_method(literal.s_cmprneg , this, "_queue_input") 531 self.add_method(literal.s_cmprnext , this, "_queue_input") 532 self.add_method(literal.s_cmprnextneg, this, "_queue_input") 533 self.add_method(literal.ctrla , this, "_inc_number") 534 self.add_method(literal.ctrlx , this, "_dec_number") 535 self.add_method(literal.period , this, "_queue_input") 536 self.add_method(literal.toggle , this, "_toggle") 537 self.add_method(literal.ror , this, "_rotate_right") 538 self.add_method(literal.rol , this, "_rotate_left") 539 self.add_method(literal.bswap , this, "_swap_bytes") 540 self.add_method(literal.delete , this, "_delete") 541 self.add_method(literal.X , this, "_delete") 542 self.add_method(literal.D , this, "_delete") 543 self.add_method(literal.u , this, "_queue_input") 544 self.add_method(literal.U , this, "_queue_input") 545 self.add_method(literal.ctrlr , this, "_queue_input") 546 self.add_method(literal.reg_reg , methods, "start_register") 547 self.add_method(literal.m_reg , this, "_queue_input") 548 self.add_method(literal.backtick_reg , this, "_queue_input") 549 self.add_method(literal.s_delmarks , this, "_queue_input") 550 self.add_method(literal.s_delmarksneg, this, "_queue_input") 551 self.add_method(literal.q_reg , methods, "start_record") 552 self.add_method(literal.atsign_reg , methods, "replay_record") 553 self.add_method(literal.atsign_at , methods, "replay_record") 554 self.add_method(literal.atsign_colon , methods, "replay_bind") 555 self.add_method(literal.s_bind , this, "_queue_input") 556 self.add_method(literal.bit_and , this, "_logical_bit_operation") 557 self.add_method(literal.bit_or , this, "_logical_bit_operation") 558 self.add_method(literal.bit_xor , this, "_logical_bit_operation") 559 self.add_method(literal.y , this, "_yank") 560 self.add_method(literal.Y , this, "_yank") 561 self.add_method(literal.P , this, "_put") 562 self.add_method(literal.p , this, "_put") 563 self.add_method(literal.O , this, "_put") 564 self.add_method(literal.o , this, "_put") 565 self.add_method(literal.s_w , this, "_save_buffer") 566 self.add_method(literal.s_wneg , this, "_force_save_buffer") 567 self.add_method(literal.s_wq , this, "_save_buffer_quit") 568 #self.add_method(literal.s_x , None, None) 569 self.add_method(literal.s_q , this, "_queue_input") 570 self.add_method(literal.s_qneg , this, "_queue_input") 571 self.add_method(literal.s_qa , this, "_queue_input") 572 self.add_method(literal.s_qaneg , this, "_queue_input") 573 self.add_method(literal.s_open_md5 , this, "_open_md5") 574 self.add_method(literal.s_open_sha1 , this, "_open_sha1") 575 self.add_method(literal.s_open_sha224, this, "_open_sha224") 576 self.add_method(literal.s_open_sha256, this, "_open_sha256") 577 self.add_method(literal.s_open_sha384, this, "_open_sha384") 578 self.add_method(literal.s_open_sha512, this, "_open_sha512") 579 self.add_method(literal.s_open_sha3_224, this, "_open_sha3_224") 580 self.add_method(literal.s_open_sha3_256, this, "_open_sha3_256") 581 self.add_method(literal.s_open_sha3_384, this, "_open_sha3_384") 582 self.add_method(literal.s_open_sha3_512, this, "_open_sha3_512") 583 self.add_method(literal.s_open_b64e , this, "_open_base64_encode") 584 self.add_method(literal.s_open_b64d , this, "_open_base64_decode") 585 self.add_method(literal.s_open_b32e , this, "_open_base32_encode") 586 self.add_method(literal.s_open_b32d , this, "_open_base32_decode") 587 self.add_method(literal.s_open_b16e , this, "_open_base16_encode") 588 self.add_method(literal.s_open_b16d , this, "_open_base16_decode") 589 self.add_method(literal.s_open_b85e , this, "_open_base85_encode") 590 self.add_method(literal.s_open_b85d , this, "_open_base85_decode") 591 self.add_method(literal.s_fsearchw , methods, "search_word_forward") 592 self.add_method(literal.s_rsearchw , methods, "search_word_backward") 593 self.add_method(literal.n , methods, "search_word_next_forward") 594 self.add_method(literal.N , methods, "search_word_next_backward") 595 self.add_method(literal.fsearchc , methods, "search_char_forward") 596 self.add_method(literal.rsearchc , methods, "search_char_backward") 597 self.add_method(literal.fsearchcb , methods, "search_char_forward_before") 598 self.add_method(literal.rsearchcb , methods, "search_char_backward_before") 599 self.add_method(literal.semicolon , methods, "search_char_next_forward") 600 self.add_method(literal.comma , methods, "search_char_next_backward") 601 self.add_method(literal.escape , this, "_escape_visual") 602 #self.add_method(literal.i , None, None) 603 #self.add_method(literal.I , None, None) 604 #self.add_method(literal.a , None, None) 605 #self.add_method(literal.A , None, None) 606 self.add_method(literal.R , this, "_enter_edit_replace") 607 self.add_method(literal.r , this, "_do_edit_replace") 608 self.add_method(literal.v , this, "_enter_visual") 609 self.add_method(literal.V , this, "_enter_line_visual") 610 self.add_method(literal.ctrlv , this, "_enter_block_visual") 611 for li in literal.get_ext_literals(): 612 self.add_method(li, this, "_queue_input") 613 614 def handle_signal(self): 615 _exit_visual(self) 616 return kbd.INTERRUPT 617 618 def handle_invalid_literal(self, li): 619 self.co.flash("Not a visual command " + li.str) 620 return _exit_visual(self) 621 622 def set_banner(self): 623 console.set_banner(self.co.get_region_type()) 624 625class Console (_console): 626 pass 627 628class ExtConsole (_console): 629 pass 630 631def _queue_input(self, amp, opc, args, raw): 632 if raw[0] in literal.get_slow_ords(): 633 raw.append(kbd.ENTER) 634 self.co.queue_input(raw) 635 return _exit_visual(self) 636 637def _enter_visual(self, amp, opc, args, raw): 638 return __enter_visual(self, VISUAL) 639 640def _enter_line_visual(self, amp, opc, args, raw): 641 return __enter_visual(self, VISUAL_LINE) 642 643def _enter_block_visual(self, amp, opc, args, raw): 644 return __enter_visual(self, VISUAL_BLOCK) 645 646def __enter_visual(self, visual_type): 647 if self.co.get_region_type() == visual_type: 648 return _exit_visual(self) 649 else: 650 self.co.set_region_type(visual_type) 651 return self.set_console(util.get_class(self)) 652 653def _escape_visual(self, amp, opc, args, raw): 654 methods.escape(self, amp, opc, args, raw) 655 return _exit_visual(self) 656 657def _exit_visual(self, amp=None, opc=None, args=None, raw=None): 658 self.co.cleanup_region() 659 # Repaint to ensure space between units are cleared before exit. 660 # This is not a must since consoles are repainted on dispatch. 661 self.co.lrepaint() 662 return self.set_console(None) 663 664def _(a, b): 665 def _exit(fn): 666 def _method(self, amp, opc, args, raw): 667 _fn = b if _in_block_visual(self) else a 668 ret = _fn(self, amp, opc, args, raw) 669 if ret == methods.QUIT: 670 return methods.QUIT 671 assert ret != methods.REWIND 672 assert ret != methods.CONTINUE 673 return fn(self, amp, opc, args, raw) 674 return _method 675 return _exit 676 677def _in_block_visual(self): 678 return self.co.get_region_type() == VISUAL_BLOCK 679 680@_(methods.range_show_md5, methods.block_show_md5) 681def _show_md5(self, amp, opc, args, raw): 682 return _exit_visual(self) 683 684@_(methods.range_show_sha1, methods.block_show_sha1) 685def _show_sha1(self, amp, opc, args, raw): 686 return _exit_visual(self) 687 688@_(methods.range_show_sha224, methods.block_show_sha224) 689def _show_sha224(self, amp, opc, args, raw): 690 return _exit_visual(self) 691 692@_(methods.range_show_sha256, methods.block_show_sha256) 693def _show_sha256(self, amp, opc, args, raw): 694 return _exit_visual(self) 695 696@_(methods.range_show_sha384, methods.block_show_sha384) 697def _show_sha384(self, amp, opc, args, raw): 698 return _exit_visual(self) 699 700@_(methods.range_show_sha512, methods.block_show_sha512) 701def _show_sha512(self, amp, opc, args, raw): 702 return _exit_visual(self) 703 704@_(methods.range_show_sha3_224, methods.block_show_sha3_224) 705def _show_sha3_224(self, amp, opc, args, raw): 706 return _exit_visual(self) 707 708@_(methods.range_show_sha3_256, methods.block_show_sha3_256) 709def _show_sha3_256(self, amp, opc, args, raw): 710 return _exit_visual(self) 711 712@_(methods.range_show_sha3_384, methods.block_show_sha3_384) 713def _show_sha3_384(self, amp, opc, args, raw): 714 return _exit_visual(self) 715 716@_(methods.range_show_sha3_512, methods.block_show_sha3_512) 717def _show_sha3_512(self, amp, opc, args, raw): 718 return _exit_visual(self) 719 720@_(methods.range_inc_number, methods.block_inc_number) 721def _inc_number(self, amp, opc, args, raw): 722 return _exit_visual(self) 723 724@_(methods.range_dec_number, methods.block_dec_number) 725def _dec_number(self, amp, opc, args, raw): 726 return _exit_visual(self) 727 728@_(methods.range_toggle, methods.block_toggle) 729def _toggle(self, amp, opc, args, raw): 730 return _exit_visual(self) 731 732@_(methods.range_rotate_right, methods.block_rotate_right) 733def _rotate_right(self, amp, opc, args, raw): 734 return _exit_visual(self) 735 736@_(methods.range_rotate_left, methods.block_rotate_left) 737def _rotate_left(self, amp, opc, args, raw): 738 return _exit_visual(self) 739 740@_(methods.range_swap_bytes, methods.block_swap_bytes) 741def _swap_bytes(self, amp, opc, args, raw): 742 return _exit_visual(self) 743 744@_(methods.range_delete, methods.block_delete) 745def _delete(self, amp, opc, args, raw): 746 return _exit_visual(self) 747 748@_(methods.range_logical_bit_operation, methods.block_logical_bit_operation) 749def _logical_bit_operation(self, amp, opc, args, raw): 750 return _exit_visual(self) 751 752@_(methods.range_yank, methods.block_yank) 753def _yank(self, amp, opc, args, raw): 754 return _exit_visual(self) 755 756@_(methods.range_put, methods.block_put) 757def _put(self, amp, opc, args, raw): 758 return _exit_visual(self) 759 760@_(methods.range_save_buffer, methods.block_save_buffer) 761def _save_buffer(self, amp, opc, args, raw): 762 return _exit_visual(self) 763 764@_(methods.range_force_save_buffer, methods.block_force_save_buffer) 765def _force_save_buffer(self, amp, opc, args, raw): 766 return _exit_visual(self) 767 768@_(methods.range_save_buffer_quit, methods.block_save_buffer_quit) 769def _save_buffer_quit(self, amp, opc, args, raw): 770 return _exit_visual(self) 771 772@_(methods.range_open_md5, methods.block_open_md5) 773def _open_md5(self, amp, opc, args, raw): 774 return _exit_visual(self) 775 776@_(methods.range_open_sha1, methods.block_open_sha1) 777def _open_sha1(self, amp, opc, args, raw): 778 return _exit_visual(self) 779 780@_(methods.range_open_sha224, methods.block_open_sha224) 781def _open_sha224(self, amp, opc, args, raw): 782 return _exit_visual(self) 783 784@_(methods.range_open_sha256, methods.block_open_sha256) 785def _open_sha256(self, amp, opc, args, raw): 786 return _exit_visual(self) 787 788@_(methods.range_open_sha384, methods.block_open_sha384) 789def _open_sha384(self, amp, opc, args, raw): 790 return _exit_visual(self) 791 792@_(methods.range_open_sha512, methods.block_open_sha512) 793def _open_sha512(self, amp, opc, args, raw): 794 return _exit_visual(self) 795 796@_(methods.range_open_sha3_224, methods.block_open_sha3_224) 797def _open_sha3_224(self, amp, opc, args, raw): 798 return _exit_visual(self) 799 800@_(methods.range_open_sha3_256, methods.block_open_sha3_256) 801def _open_sha3_256(self, amp, opc, args, raw): 802 return _exit_visual(self) 803 804@_(methods.range_open_sha3_384, methods.block_open_sha3_384) 805def _open_sha3_384(self, amp, opc, args, raw): 806 return _exit_visual(self) 807 808@_(methods.range_open_sha3_512, methods.block_open_sha3_512) 809def _open_sha3_512(self, amp, opc, args, raw): 810 return _exit_visual(self) 811 812@_(methods.range_open_base64_encode, methods.block_open_base64_encode) 813def _open_base64_encode(self, amp, opc, args, raw): 814 return _exit_visual(self) 815 816@_(methods.range_open_base64_decode, methods.block_open_base64_decode) 817def _open_base64_decode(self, amp, opc, args, raw): 818 return _exit_visual(self) 819 820@_(methods.range_open_base32_encode, methods.block_open_base32_encode) 821def _open_base32_encode(self, amp, opc, args, raw): 822 return _exit_visual(self) 823 824@_(methods.range_open_base32_decode, methods.block_open_base32_decode) 825def _open_base32_decode(self, amp, opc, args, raw): 826 return _exit_visual(self) 827 828@_(methods.range_open_base16_encode, methods.block_open_base16_encode) 829def _open_base16_encode(self, amp, opc, args, raw): 830 return _exit_visual(self) 831 832@_(methods.range_open_base16_decode, methods.block_open_base16_decode) 833def _open_base16_decode(self, amp, opc, args, raw): 834 return _exit_visual(self) 835 836@_(methods.range_open_base85_encode, methods.block_open_base85_encode) 837def _open_base85_encode(self, amp, opc, args, raw): 838 return _exit_visual(self) 839 840@_(methods.range_open_base85_decode, methods.block_open_base85_decode) 841def _open_base85_decode(self, amp, opc, args, raw): 842 return _exit_visual(self) 843 844@_(methods.range_delete, methods.block_delete) 845def _enter_edit_replace(self, amp, opc, args, raw): 846 self.co.cleanup_region() 847 arg = edit.Arg(amp=methods.get_int(amp)) 848 return self.set_console(edit.get_replace_class(), arg) 849 850def _do_edit_replace(self, amp, opc, args, raw): 851 if _in_block_visual(self): 852 cls = edit.get_block_replace_class() 853 else: 854 cls = edit.get_range_replace_class() 855 arg = edit.Arg(limit=edit.get_input_limit(), 856 start=self.co.get_region_range()[0]) 857 return self.set_console(cls, arg) 858