m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1179 lines
39 KiB

6 months ago
  1. # -*- coding: utf-8 -*-
  2. #*****************************************************************************
  3. # Copyright (C) 2003-2006 Gary Bishop.
  4. # Copyright (C) 2006 Michael Graz. <mgraz@plan10.com>
  5. # Copyright (C) 2006 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
  6. #
  7. # Distributed under the terms of the BSD License. The full license is in
  8. # the file COPYING, distributed as part of this software.
  9. #*****************************************************************************
  10. from __future__ import print_function, unicode_literals, absolute_import
  11. import os
  12. import pyreadline.logger as logger
  13. from pyreadline.logger import log
  14. import pyreadline.lineeditor.lineobj as lineobj
  15. import pyreadline.lineeditor.history as history
  16. from . import basemode
  17. class ViMode(basemode.BaseMode):
  18. mode="vi"
  19. def __init__(self,rlobj):
  20. super(ViMode,self).__init__(rlobj)
  21. self.__vi_insert_mode = None
  22. def __repr__(self):
  23. return "<ViMode>"
  24. def process_keyevent(self, keyinfo):
  25. def nop(e):
  26. pass
  27. keytuple=keyinfo.tuple()
  28. #Process exit keys. Only exit on empty line
  29. if keytuple in self.exit_dispatch:
  30. if lineobj.EndOfLine(self.l_buffer) == 0:
  31. raise EOFError
  32. dispatch_func = self.key_dispatch.get(keytuple,self.vi_key)
  33. log("readline from keyboard:%s->%s"%(keytuple,dispatch_func))
  34. r = None
  35. if dispatch_func:
  36. r = dispatch_func(keyinfo)
  37. self.l_buffer.push_undo()
  38. self.previous_func = dispatch_func
  39. if r:
  40. self._update_line()
  41. return True
  42. return False
  43. ### Methods below here are bindable emacs functions
  44. def init_editing_mode(self, e): # (M-C-j)
  45. '''Initialize vi editingmode'''
  46. self.show_all_if_ambiguous = 'on'
  47. self.key_dispatch = {}
  48. self.__vi_insert_mode = None
  49. self._vi_command = None
  50. self._vi_command_edit = None
  51. self._vi_key_find_char = None
  52. self._vi_key_find_direction = True
  53. self._vi_yank_buffer = None
  54. self._vi_multiplier1 = ''
  55. self._vi_multiplier2 = ''
  56. self._vi_undo_stack = []
  57. self._vi_undo_cursor = -1
  58. self._vi_current = None
  59. self._vi_search_text = ''
  60. self._vi_search_position = 0
  61. self.vi_save_line ()
  62. self.vi_set_insert_mode (True)
  63. # make ' ' to ~ self insert
  64. for c in range(ord(' '), 127):
  65. self._bind_key('%s' % chr(c), self.vi_key)
  66. self._bind_key('BackSpace', self.vi_backspace)
  67. self._bind_key('Escape', self.vi_escape)
  68. self._bind_key('Return', self.vi_accept_line)
  69. self._bind_key('Left', self.backward_char)
  70. self._bind_key('Right', self.forward_char)
  71. self._bind_key('Home', self.beginning_of_line)
  72. self._bind_key('End', self.end_of_line)
  73. self._bind_key('Delete', self.delete_char)
  74. self._bind_key('Control-d', self.vi_eof)
  75. self._bind_key('Control-z', self.vi_eof)
  76. self._bind_key('Control-r', self.vi_redo)
  77. self._bind_key('Up', self.vi_arrow_up)
  78. self._bind_key('Control-p', self.vi_up)
  79. self._bind_key('Down', self.vi_arrow_down)
  80. self._bind_key('Control-n', self.vi_down)
  81. self._bind_key('Tab', self.vi_complete)
  82. # self._bind_key('Control-e', self.emacs)
  83. def vi_key (self, e):
  84. if not self._vi_command:
  85. self._vi_command = ViCommand (self)
  86. elif self._vi_command.is_end:
  87. if self._vi_command.is_edit:
  88. self._vi_command_edit = self._vi_command
  89. self._vi_command = ViCommand (self)
  90. self._vi_command.add_char (e.char)
  91. def vi_error (self):
  92. self._bell ()
  93. def vi_get_is_insert_mode (self):
  94. return self.__vi_insert_mode
  95. vi_is_insert_mode = property (vi_get_is_insert_mode)
  96. def vi_escape (self, e):
  97. if self.vi_is_insert_mode:
  98. if self._vi_command:
  99. self._vi_command.add_char (e.char)
  100. else:
  101. self._vi_command = ViCommand (self)
  102. self.vi_set_insert_mode (False)
  103. self.l_buffer.point=lineobj.PrevChar
  104. elif self._vi_command and self._vi_command.is_replace_one:
  105. self._vi_command.add_char (e.char)
  106. else:
  107. self.vi_error ()
  108. def vi_backspace (self, e):
  109. if self._vi_command:
  110. self._vi_command.add_char (e.char)
  111. else:
  112. self._vi_do_backspace (self._vi_command)
  113. def _vi_do_backspace (self, vi_cmd):
  114. if self.vi_is_insert_mode or (self._vi_command and self._vi_command.is_search):
  115. if self.l_buffer.point > 0:
  116. self.l_buffer.point -= 1
  117. if self.l_buffer.overwrite:
  118. try:
  119. prev = self._vi_undo_stack [self._vi_undo_cursor][1][self.l_buffer.point ]
  120. self.l_buffer.line_buffer [self.l_buffer.point] = prev
  121. except IndexError:
  122. del self.l_buffer.line_buffer [self.l_buffer.point ]
  123. else:
  124. self.vi_save_line ()
  125. del self.l_buffer.line_buffer [self.l_buffer.point ]
  126. def vi_accept_line (self, e):
  127. if self._vi_command and self._vi_command.is_search:
  128. self._vi_command.do_search ()
  129. return False
  130. self._vi_command = None
  131. self.vi_set_insert_mode (True)
  132. self._vi_undo_stack = []
  133. self._vi_undo_cursor = -1
  134. self._vi_current = None
  135. if self.l_buffer.line_buffer:
  136. self.add_history(self.l_buffer.copy())
  137. return self.accept_line (e)
  138. def vi_eof (self, e):
  139. raise EOFError
  140. def vi_set_insert_mode (self, value):
  141. if self.__vi_insert_mode == value:
  142. return
  143. self.__vi_insert_mode = value
  144. if value:
  145. self.vi_save_line ()
  146. self.cursor_size=25
  147. else:
  148. self.cursor_size=100
  149. def vi_undo_restart (self):
  150. tpl_undo = (self.l_buffer.point, self.l_buffer.line_buffer[:], )
  151. self._vi_undo_stack = [tpl_undo]
  152. self._vi_undo_cursor = 0
  153. def vi_save_line (self):
  154. if self._vi_undo_stack and self._vi_undo_cursor >= 0:
  155. del self._vi_undo_stack [self._vi_undo_cursor + 1 : ]
  156. # tpl_undo = (self.l_buffer.point, self.l_buffer[:], )
  157. tpl_undo = (self.l_buffer.point, self.l_buffer.line_buffer[:], )
  158. if not self._vi_undo_stack or self._vi_undo_stack[self._vi_undo_cursor][1] != tpl_undo[1]:
  159. self._vi_undo_stack.append (tpl_undo)
  160. self._vi_undo_cursor += 1
  161. def vi_undo_prepare (self):
  162. if self._vi_undo_cursor == len(self._vi_undo_stack)-1:
  163. self.vi_save_line ()
  164. def vi_undo (self, do_pop=True):
  165. self.vi_undo_prepare ()
  166. if not self._vi_undo_stack or self._vi_undo_cursor <= 0:
  167. self.vi_error ()
  168. return
  169. self._vi_undo_cursor -= 1
  170. self.vi_undo_assign ()
  171. def vi_undo_all (self):
  172. self.vi_undo_prepare ()
  173. if self._vi_undo_cursor > 0:
  174. self._vi_undo_cursor = 0
  175. self.vi_undo_assign ()
  176. else:
  177. self.vi_error ()
  178. def vi_undo_assign (self):
  179. tpl_undo = self._vi_undo_stack [self._vi_undo_cursor]
  180. self.l_buffer.line_buffer = tpl_undo [1][:]
  181. self.l_buffer.point = tpl_undo [0]
  182. def vi_redo (self, e):
  183. if self._vi_undo_cursor >= len(self._vi_undo_stack)-1:
  184. self.vi_error ()
  185. return
  186. self._vi_undo_cursor += 1
  187. self.vi_undo_assign ()
  188. def vi_search (self, rng):
  189. for i in rng:
  190. line_history = self._history.history [i]
  191. pos = line_history.get_line_text().find (self._vi_search_text)
  192. if pos >= 0:
  193. self._vi_search_position = i
  194. self._history.history_cursor = i
  195. self.l_buffer.line_buffer = list (line_history.line_buffer)
  196. self.l_buffer.point = pos
  197. self.vi_undo_restart ()
  198. return True
  199. self._bell ()
  200. return False
  201. def vi_search_first (self):
  202. text = ''.join (self.l_buffer.line_buffer [1:])
  203. if text:
  204. self._vi_search_text = text
  205. self._vi_search_position = len (self._history.history) - 1
  206. elif self._vi_search_text:
  207. self._vi_search_position -= 1
  208. else:
  209. self.vi_error ()
  210. self.vi_undo ()
  211. return
  212. if not self.vi_search (list(range(self._vi_search_position, -1, -1))):
  213. # Here: search text not found
  214. self.vi_undo ()
  215. def vi_search_again_backward (self):
  216. self.vi_search (list(range(self._vi_search_position-1, -1, -1)))
  217. def vi_search_again_forward (self):
  218. self.vi_search (list(range(self._vi_search_position+1, len(self._history.history))))
  219. def vi_up (self, e):
  220. if self._history.history_cursor == len(self._history.history):
  221. self._vi_current = self.l_buffer.line_buffer [:]
  222. # self._history.previous_history (e)
  223. self._history.previous_history (self.l_buffer)
  224. if self.vi_is_insert_mode:
  225. self.end_of_line (e)
  226. else:
  227. self.beginning_of_line (e)
  228. self.vi_undo_restart ()
  229. def vi_down (self, e):
  230. if self._history.history_cursor >= len(self._history.history):
  231. self.vi_error ()
  232. return
  233. if self._history.history_cursor < len(self._history.history) - 1:
  234. # self._history.next_history (e)
  235. self._history.next_history (self.l_buffer)
  236. if self.vi_is_insert_mode:
  237. self.end_of_line (e)
  238. else:
  239. self.beginning_of_line (e)
  240. self.vi_undo_restart ()
  241. elif self._vi_current is not None:
  242. self._history.history_cursor = len(self._history.history)
  243. self.l_buffer.line_buffer = self._vi_current
  244. self.end_of_line (e)
  245. if not self.vi_is_insert_mode and self.l_buffer.point > 0:
  246. self.l_buffer.point -= 1
  247. self._vi_current = None
  248. else:
  249. self.vi_error ()
  250. return
  251. def vi_arrow_up (self, e):
  252. self.vi_set_insert_mode (True)
  253. self.vi_up (e)
  254. self.vi_save_line ()
  255. def vi_arrow_down (self, e):
  256. self.vi_set_insert_mode (True)
  257. self.vi_down (e)
  258. self.vi_save_line ()
  259. def vi_complete (self, e):
  260. text = self.l_buffer.get_line_text ()
  261. if text and not text.isspace ():
  262. return self.complete (e)
  263. else:
  264. return self.vi_key (e)
  265. # vi input states
  266. # sequence of possible states are in the order below
  267. _VI_BEGIN = 'vi_begin'
  268. _VI_MULTI1 = 'vi_multi1'
  269. _VI_ACTION = 'vi_action'
  270. _VI_MULTI2 = 'vi_multi2'
  271. _VI_MOTION = 'vi_motion'
  272. _VI_MOTION_ARGUMENT = 'vi_motion_argument'
  273. _VI_REPLACE_ONE = 'vi_replace_one'
  274. _VI_TEXT = 'vi_text'
  275. _VI_SEARCH = 'vi_search'
  276. _VI_END = 'vi_end'
  277. # vi helper class
  278. class ViCommand:
  279. def __init__ (self, readline):
  280. self.readline = readline
  281. self.lst_char = []
  282. self.state = _VI_BEGIN
  283. self.action = self.movement
  284. self.motion = None
  285. self.motion_argument = None
  286. self.text = None
  287. self.pos_motion = None
  288. self.is_edit = False
  289. self.is_overwrite = False
  290. self.is_error = False
  291. self.is_star = False
  292. self.delete_left = 0
  293. self.delete_right = 0
  294. self.readline._vi_multiplier1 = ''
  295. self.readline._vi_multiplier2 = ''
  296. self.set_override_multiplier (0)
  297. self.skip_multipler = False
  298. self.tabstop = 4
  299. self.dct_fcn = {
  300. ord('$') : self.key_dollar,
  301. ord('^') : self.key_hat,
  302. ord(';') : self.key_semicolon,
  303. ord(',') : self.key_comma,
  304. ord('%') : self.key_percent,
  305. ord('.') : self.key_dot,
  306. ord('/') : self.key_slash,
  307. ord('*') : self.key_star,
  308. ord('|') : self.key_bar,
  309. ord('~') : self.key_tilde,
  310. 8 : self.key_backspace,
  311. }
  312. def add_char (self, char):
  313. self.lst_char.append (char)
  314. if self.state == _VI_BEGIN and self.readline.vi_is_insert_mode:
  315. self.readline.vi_save_line ()
  316. self.state = _VI_TEXT
  317. if self.state == _VI_SEARCH:
  318. if char == '\x08': # backspace
  319. self.key_backspace (char)
  320. else:
  321. self.set_text (char)
  322. return
  323. if self.state == _VI_TEXT:
  324. if char == '\x1b': # escape
  325. self.escape (char)
  326. elif char == '\x09': # tab
  327. ts = self.tabstop
  328. ws = ' ' * (ts - (self.readline.l_buffer.point%ts))
  329. self.set_text (ws)
  330. elif char == '\x08': # backspace
  331. self.key_backspace (char)
  332. else:
  333. self.set_text (char)
  334. return
  335. if self.state == _VI_MOTION_ARGUMENT:
  336. self.set_motion_argument (char)
  337. return
  338. if self.state == _VI_REPLACE_ONE:
  339. self.replace_one (char)
  340. return
  341. try:
  342. fcn_instance = self.dct_fcn [ord(char)]
  343. except:
  344. fcn_instance = getattr (self, 'key_%s' % char, None)
  345. if fcn_instance:
  346. fcn_instance (char)
  347. return
  348. if char.isdigit ():
  349. self.key_digit (char)
  350. return
  351. # Here: could not process key
  352. self.error ()
  353. def set_text (self, text):
  354. if self.text is None:
  355. self.text = text
  356. else:
  357. self.text += text
  358. self.set_buffer (text)
  359. def set_buffer (self, text):
  360. for char in text:
  361. if not self.char_isprint (char):
  362. continue
  363. # self.readline.l_buffer.insert_text(char)
  364. # continue
  365. # #overwrite in l_buffer obj
  366. if self.is_overwrite:
  367. if self.readline.l_buffer.point < len (self.readline.l_buffer.line_buffer):
  368. # self.readline.l_buffer[self.l_buffer.point]=char
  369. self.readline.l_buffer.line_buffer [self.readline.l_buffer.point] = char
  370. else:
  371. # self.readline.l_buffer.insert_text(char)
  372. self.readline.l_buffer.line_buffer.append (char)
  373. else:
  374. # self.readline.l_buffer.insert_text(char)
  375. self.readline.l_buffer.line_buffer.insert (self.readline.l_buffer.point, char)
  376. self.readline.l_buffer.point += 1
  377. def replace_one (self, char):
  378. if char == '\x1b': # escape
  379. self.end ()
  380. return
  381. self.is_edit = True
  382. self.readline.vi_save_line ()
  383. times = self.get_multiplier ()
  384. cursor = self.readline.l_buffer.point
  385. self.readline.l_buffer.line_buffer [cursor : cursor + times] = char * times
  386. if times > 1:
  387. self.readline.l_buffer.point += (times - 1)
  388. self.end ()
  389. def char_isprint (self, char):
  390. return ord(char) >= ord(' ') and ord(char) <= ord('~')
  391. def key_dollar (self, char):
  392. self.motion = self.motion_end_in_line
  393. self.delete_right = 1
  394. self.state = _VI_MOTION
  395. self.apply ()
  396. def key_hat (self, char):
  397. self.motion = self.motion_beginning_of_line
  398. self.state = _VI_MOTION
  399. self.apply ()
  400. def key_0 (self, char):
  401. if self.state in [_VI_BEGIN, _VI_ACTION]:
  402. self.key_hat (char)
  403. else:
  404. self.key_digit (char)
  405. def key_digit (self, char):
  406. if self.state in [_VI_BEGIN, _VI_MULTI1]:
  407. self.readline._vi_multiplier1 += char
  408. self.readline._vi_multiplier2 = ''
  409. self.state = _VI_MULTI1
  410. elif self.state in [_VI_ACTION, _VI_MULTI2]:
  411. self.readline._vi_multiplier2 += char
  412. self.state = _VI_MULTI2
  413. def key_w (self, char):
  414. if self.action == self.change:
  415. self.key_e (char)
  416. return
  417. self.motion = self.motion_word_short
  418. self.state = _VI_MOTION
  419. self.apply ()
  420. def key_W (self, char):
  421. if self.action == self.change:
  422. self.key_E (char)
  423. return
  424. self.motion = self.motion_word_long
  425. self.state = _VI_MOTION
  426. self.apply ()
  427. def key_e (self, char):
  428. self.motion = self.motion_end_short
  429. self.state = _VI_MOTION
  430. self.delete_right = 1
  431. self.apply ()
  432. def key_E (self, char):
  433. self.motion = self.motion_end_long
  434. self.state = _VI_MOTION
  435. self.delete_right = 1
  436. self.apply ()
  437. def key_b (self, char):
  438. self.motion = self.motion_back_short
  439. self.state = _VI_MOTION
  440. self.apply ()
  441. def key_B (self, char):
  442. self.motion = self.motion_back_long
  443. self.state = _VI_MOTION
  444. self.apply ()
  445. def key_f (self, char):
  446. self.readline._vi_key_find_direction = True
  447. self.motion = self.motion_find_char_forward
  448. self.delete_right = 1
  449. self.state = _VI_MOTION_ARGUMENT
  450. def key_F (self, char):
  451. self.readline._vi_key_find_direction = False
  452. self.motion = self.motion_find_char_backward
  453. self.delete_left = 1
  454. self.state = _VI_MOTION_ARGUMENT
  455. def key_t (self, char):
  456. self.motion = self.motion_to_char_forward
  457. self.delete_right = 1
  458. self.state = _VI_MOTION_ARGUMENT
  459. def key_T (self, char):
  460. self.motion = self.motion_to_char_backward
  461. self.state = _VI_MOTION_ARGUMENT
  462. def key_j (self, char):
  463. self.readline.vi_down (ViEvent (char))
  464. self.state = _VI_END
  465. def key_k (self, char):
  466. self.readline.vi_up (ViEvent (char))
  467. self.state = _VI_END
  468. def key_semicolon (self, char):
  469. if self.readline._vi_key_find_char is None:
  470. self.error ()
  471. return
  472. if self.readline._vi_key_find_direction:
  473. self.motion = self.motion_find_char_forward
  474. else:
  475. self.motion = self.motion_find_char_backward
  476. self.set_motion_argument (self.readline._vi_key_find_char)
  477. def key_comma (self, char):
  478. if self.readline._vi_key_find_char is None:
  479. self.error ()
  480. return
  481. if self.readline._vi_key_find_direction:
  482. self.motion = self.motion_find_char_backward
  483. else:
  484. self.motion = self.motion_find_char_forward
  485. self.set_motion_argument (self.readline._vi_key_find_char)
  486. def key_percent (self, char):
  487. '''find matching <([{}])>'''
  488. self.motion = self.motion_matching
  489. self.delete_right = 1
  490. self.state = _VI_MOTION
  491. self.apply ()
  492. def key_dot (self, char):
  493. vi_cmd_edit = self.readline._vi_command_edit
  494. if not vi_cmd_edit:
  495. return
  496. if vi_cmd_edit.is_star:
  497. self.key_star (char)
  498. return
  499. if self.has_multiplier ():
  500. count = self.get_multiplier ()
  501. else:
  502. count = 0
  503. # Create the ViCommand object after getting multipler from self
  504. # Side effect of the ViCommand creation is resetting of global multipliers
  505. vi_cmd = ViCommand (self.readline)
  506. if count >= 1:
  507. vi_cmd.set_override_multiplier (count)
  508. vi_cmd_edit.set_override_multiplier (count)
  509. elif vi_cmd_edit.override_multiplier:
  510. vi_cmd.set_override_multiplier (vi_cmd_edit.override_multiplier)
  511. for char in vi_cmd_edit.lst_char:
  512. vi_cmd.add_char (char)
  513. if vi_cmd_edit.is_overwrite and self.readline.l_buffer.point > 0:
  514. self.readline.l_buffer.point -= 1
  515. self.readline.vi_set_insert_mode (False)
  516. self.end ()
  517. def key_slash (self, char):
  518. self.readline.vi_save_line ()
  519. self.readline.l_buffer.line_buffer=['/']
  520. self.readline.l_buffer.point= 1
  521. self.state = _VI_SEARCH
  522. def key_star (self, char):
  523. self.is_star = True
  524. self.is_edit = True
  525. self.readline.vi_save_line ()
  526. completions = self.readline._get_completions()
  527. if completions:
  528. text = ' '.join (completions) + ' '
  529. self.readline.l_buffer.line_buffer [self.readline.begidx : self.readline.endidx + 1] = list (text)
  530. prefix_len = self.readline.endidx - self.readline.begidx
  531. self.readline.l_buffer.point += len(text) - prefix_len
  532. self.readline.vi_set_insert_mode (True)
  533. else:
  534. self.error ()
  535. self.state = _VI_TEXT
  536. def key_bar (self, char):
  537. self.motion = self.motion_column
  538. self.state = _VI_MOTION
  539. self.apply ()
  540. def key_tilde (self, char):
  541. self.is_edit = True
  542. self.readline.vi_save_line ()
  543. for i in range (self.get_multiplier()):
  544. try:
  545. c = self.readline.l_buffer.line_buffer [self.readline.l_buffer.point]
  546. if c.isupper ():
  547. self.readline.l_buffer.line_buffer [self.readline.l_buffer.point] = c.lower()
  548. elif c.islower ():
  549. self.readline.l_buffer.line_buffer [self.readline.l_buffer.point] = c.upper()
  550. self.readline.l_buffer.point += 1
  551. except IndexError:
  552. break
  553. self.end ()
  554. def key_h (self, char):
  555. self.motion = self.motion_left
  556. self.state = _VI_MOTION
  557. self.apply ()
  558. def key_backspace (self, char):
  559. if self.state in [_VI_TEXT, _VI_SEARCH]:
  560. if self.text and len(self.text):
  561. self.text = self.text [:-1]
  562. try:
  563. # Remove backspaces for potential dot command
  564. self.lst_char.pop ()
  565. self.lst_char.pop ()
  566. except IndexError:
  567. pass
  568. else:
  569. self.key_h (char)
  570. self.readline._vi_do_backspace (self)
  571. if self.state == _VI_SEARCH and not (self.readline.l_buffer.line_buffer):
  572. self.state = _VI_BEGIN
  573. def key_l (self, char):
  574. self.motion = self.motion_right
  575. self.state = _VI_MOTION
  576. self.apply ()
  577. def key_i (self, char):
  578. self.is_edit = True
  579. self.state = _VI_TEXT
  580. self.readline.vi_set_insert_mode (True)
  581. def key_I (self, char):
  582. self.is_edit = True
  583. self.state = _VI_TEXT
  584. self.readline.vi_set_insert_mode (True)
  585. self.readline.l_buffer.point = 0
  586. def key_a (self, char):
  587. self.is_edit = True
  588. self.state = _VI_TEXT
  589. self.readline.vi_set_insert_mode (True)
  590. if len (self.readline.l_buffer.line_buffer):
  591. self.readline.l_buffer.point += 1
  592. def key_A (self, char):
  593. self.is_edit = True
  594. self.state = _VI_TEXT
  595. self.readline.vi_set_insert_mode (True)
  596. self.readline.l_buffer.point = len (self.readline.l_buffer.line_buffer)
  597. def key_d (self, char):
  598. self.is_edit = True
  599. self.state = _VI_ACTION
  600. self.action = self.delete
  601. def key_D (self, char):
  602. self.is_edit = True
  603. self.state = _VI_ACTION
  604. self.action = self.delete_end_of_line
  605. self.apply ()
  606. def key_x (self, char):
  607. self.is_edit = True
  608. self.state = _VI_ACTION
  609. self.action = self.delete_char
  610. self.apply ()
  611. def key_X (self, char):
  612. self.is_edit = True
  613. self.state = _VI_ACTION
  614. self.action = self.delete_prev_char
  615. self.apply ()
  616. def key_s (self, char):
  617. self.is_edit = True
  618. i1 = self.readline.l_buffer.point
  619. i2 = self.readline.l_buffer.point + self.get_multiplier ()
  620. self.skip_multipler = True
  621. self.readline.vi_set_insert_mode (True)
  622. del self.readline.l_buffer.line_buffer [i1 : i2]
  623. self.state = _VI_TEXT
  624. def key_S (self, char):
  625. self.is_edit = True
  626. self.readline.vi_set_insert_mode (True)
  627. self.readline.l_buffer.line_buffer = []
  628. self.readline.l_buffer.point = 0
  629. self.state = _VI_TEXT
  630. def key_c (self, char):
  631. self.is_edit = True
  632. self.state = _VI_ACTION
  633. self.action = self.change
  634. def key_C (self, char):
  635. self.is_edit = True
  636. self.readline.vi_set_insert_mode (True)
  637. del self.readline.l_buffer.line_buffer [self.readline.l_buffer.point : ]
  638. self.state = _VI_TEXT
  639. def key_r (self, char):
  640. self.state = _VI_REPLACE_ONE
  641. def key_R (self, char):
  642. self.is_edit = True
  643. self.is_overwrite = True
  644. self.readline.l_buffer.overwrite=True
  645. self.readline.vi_set_insert_mode (True)
  646. self.state = _VI_TEXT
  647. def key_y (self, char):
  648. self._state = _VI_ACTION
  649. self.action = self.yank
  650. def key_Y (self, char):
  651. self.readline._vi_yank_buffer = self.readline.l_buffer.get_line_text()
  652. self.end ()
  653. def key_p (self, char):
  654. if not self.readline._vi_yank_buffer:
  655. return
  656. self.is_edit = True
  657. self.readline.vi_save_line ()
  658. self.readline.l_buffer.point += 1
  659. self.readline.l_buffer.insert_text (self.readline._vi_yank_buffer * self.get_multiplier ())
  660. self.readline.l_buffer.point -= 1
  661. self.state = _VI_END
  662. def key_P (self, char):
  663. if not self.readline._vi_yank_buffer:
  664. return
  665. self.is_edit = True
  666. self.readline.vi_save_line ()
  667. self.readline.l_buffer.insert_text (self.readline._vi_yank_buffer * self.get_multiplier ())
  668. self.readline.l_buffer.point -= 1
  669. self.state = _VI_END
  670. def key_u (self, char):
  671. self.readline.vi_undo ()
  672. self.state = _VI_END
  673. def key_U (self, char):
  674. self.readline.vi_undo_all ()
  675. self.state = _VI_END
  676. def key_v (self, char):
  677. editor = ViExternalEditor (self.readline.l_buffer.line_buffer)
  678. self.readline.l_buffer.line_buffer = list (editor.result)
  679. self.readline.l_buffer.point = 0
  680. self.is_edit = True
  681. self.state = _VI_END
  682. def error (self):
  683. self.readline._bell ()
  684. self.is_error = True
  685. def state_is_end (self):
  686. return self.state == _VI_END
  687. is_end = property (state_is_end)
  688. def state_is_search (self):
  689. return self.state == _VI_SEARCH
  690. is_search = property (state_is_search)
  691. def state_is_replace_one (self):
  692. return self.state == _VI_REPLACE_ONE
  693. is_replace_one = property (state_is_replace_one)
  694. def do_search (self):
  695. self.readline.vi_search_first ()
  696. self.state = _VI_END
  697. def key_n (self, char):
  698. self.readline.vi_search_again_backward ()
  699. self.state = _VI_END
  700. def key_N (self, char):
  701. self.readline.vi_search_again_forward ()
  702. self.state = _VI_END
  703. def motion_beginning_of_line (self, line, index=0, count=1, **kw):
  704. return 0
  705. def motion_end_in_line (self, line, index=0, count=1, **kw):
  706. return max (0, len (self.readline.l_buffer.line_buffer)-1)
  707. def motion_word_short (self, line, index=0, count=1, **kw):
  708. return vi_pos_word_short (line, index, count)
  709. def motion_word_long (self, line, index=0, count=1, **kw):
  710. return vi_pos_word_long (line, index, count)
  711. def motion_end_short (self, line, index=0, count=1, **kw):
  712. return vi_pos_end_short (line, index, count)
  713. def motion_end_long (self, line, index=0, count=1, **kw):
  714. return vi_pos_end_long (line, index, count)
  715. def motion_back_short (self, line, index=0, count=1, **kw):
  716. return vi_pos_back_short (line, index, count)
  717. def motion_back_long (self, line, index=0, count=1, **kw):
  718. return vi_pos_back_long (line, index, count)
  719. def motion_find_char_forward (self, line, index=0, count=1, char=None):
  720. self.readline._vi_key_find_char = char
  721. return vi_pos_find_char_forward (line, char, index, count)
  722. def motion_find_char_backward (self, line, index=0, count=1, char=None):
  723. self.readline._vi_key_find_char = char
  724. return vi_pos_find_char_backward (line, char, index, count)
  725. def motion_to_char_forward (self, line, index=0, count=1, char=None):
  726. return vi_pos_to_char_forward (line, char, index, count)
  727. def motion_to_char_backward (self, line, index=0, count=1, char=None):
  728. return vi_pos_to_char_backward (line, char, index, count)
  729. def motion_left (self, line, index=0, count=1, char=None):
  730. return max (0, index - count)
  731. def motion_right (self, line, index=0, count=1, char=None):
  732. return min (len(line), index + count)
  733. def motion_matching (self, line, index=0, count=1, char=None):
  734. return vi_pos_matching (line, index)
  735. def motion_column (self, line, index=0, count=1, char=None):
  736. return max (0, count-1)
  737. def has_multiplier (self):
  738. return self.override_multiplier or self.readline._vi_multiplier1 or self.readline._vi_multiplier2
  739. def get_multiplier (self):
  740. if self.override_multiplier:
  741. return int (self.override_multiplier)
  742. if self.readline._vi_multiplier1 == '': m1 = 1
  743. else: m1 = int(self.readline._vi_multiplier1)
  744. if self.readline._vi_multiplier2 == '': m2 = 1
  745. else: m2 = int(self.readline._vi_multiplier2)
  746. return m1 * m2
  747. def set_override_multiplier (self, count):
  748. self.override_multiplier = count
  749. def apply (self):
  750. if self.motion:
  751. self.pos_motion = self.motion (self.readline.l_buffer.line_buffer, self.readline.l_buffer.point,
  752. self.get_multiplier(), char=self.motion_argument)
  753. if self.pos_motion < 0:
  754. self.error ()
  755. return
  756. self.action ()
  757. if self.state != _VI_TEXT:
  758. self.end ()
  759. def movement (self):
  760. if self.pos_motion <= len(self.readline.l_buffer.line_buffer):
  761. self.readline.l_buffer.point = self.pos_motion
  762. else:
  763. self.readline.l_buffer.point = len(self.readline.l_buffer.line_buffer) - 1
  764. def yank (self):
  765. if self.pos_motion > self.readline.l_buffer.point:
  766. s = self.readline.l_buffer.line_buffer [self.readline.l_buffer.point : self.pos_motion + self.delete_right]
  767. else:
  768. index = max (0, self.pos_motion - self.delete_left)
  769. s = self.readline.l_buffer.line_buffer [index : self.readline.l_buffer.point + self.delete_right]
  770. self.readline._vi_yank_buffer = s
  771. def delete (self):
  772. self.readline.vi_save_line ()
  773. self.yank ()
  774. # point=lineobj.Point(self.readline.l_buffer)
  775. # pm=self.pos_motion
  776. # del self.readline.l_buffer[point:pm]
  777. # return
  778. if self.pos_motion > self.readline.l_buffer.point:
  779. del self.readline.l_buffer.line_buffer [self.readline.l_buffer.point : self.pos_motion + self.delete_right]
  780. if self.readline.l_buffer.point > len (self.readline.l_buffer.line_buffer):
  781. self.readline.l_buffer.point = len (self.readline.l_buffer.line_buffer)
  782. else:
  783. index = max (0, self.pos_motion - self.delete_left)
  784. del self.readline.l_buffer.line_buffer [index : self.readline.l_buffer.point + self.delete_right]
  785. self.readline.l_buffer.point = index
  786. def delete_end_of_line (self):
  787. self.readline.vi_save_line ()
  788. # del self.readline.l_buffer [self.readline.l_buffer.point : ]
  789. line_text = self.readline.l_buffer.get_line_text ()
  790. line_text = line_text [ : self.readline.l_buffer.point]
  791. self.readline.l_buffer.set_line (line_text)
  792. if self.readline.l_buffer.point > 0:
  793. self.readline.l_buffer.point -= 1
  794. def delete_char (self):
  795. # point=lineobj.Point(self.readline.l_buffer)
  796. # del self.readline.l_buffer[point:point+self.get_multiplier ()]
  797. # return
  798. self.pos_motion = self.readline.l_buffer.point + self.get_multiplier ()
  799. self.delete ()
  800. end = max (0, len (self.readline.l_buffer) - 1)
  801. if self.readline.l_buffer.point > end:
  802. self.readline.l_buffer.point = end
  803. def delete_prev_char (self):
  804. self.pos_motion = self.readline.l_buffer.point - self.get_multiplier ()
  805. self.delete ()
  806. def change (self):
  807. self.readline.vi_set_insert_mode (True)
  808. self.delete ()
  809. self.skip_multipler = True
  810. self.state = _VI_TEXT
  811. def escape (self, char):
  812. if self.state == _VI_TEXT:
  813. if not self.skip_multipler:
  814. times = self.get_multiplier ()
  815. if times > 1 and self.text:
  816. extra = self.text * (times - 1)
  817. self.set_buffer (extra)
  818. self.state = _VI_END
  819. def set_motion_argument (self, char):
  820. self.motion_argument = char
  821. self.apply ()
  822. def end (self):
  823. self.state = _VI_END
  824. if self.readline.l_buffer.point >= len(self.readline.l_buffer.line_buffer):
  825. self.readline.l_buffer.point = max (0, len(self.readline.l_buffer.line_buffer) - 1)
  826. class ViExternalEditor:
  827. def __init__ (self, line):
  828. if type(line) is type([]):
  829. line = ''.join (line)
  830. file_tmp = self.get_tempfile ()
  831. fp_tmp = self.file_open (file_tmp, 'w')
  832. fp_tmp.write (line)
  833. fp_tmp.close ()
  834. self.run_editor (file_tmp)
  835. fp_tmp = self.file_open (file_tmp, 'r')
  836. self.result = fp_tmp.read ()
  837. fp_tmp.close ()
  838. self.file_remove (file_tmp)
  839. def get_tempfile (self):
  840. import tempfile
  841. return tempfile.mktemp (prefix='readline-', suffix='.py')
  842. def file_open (self, filename, mode):
  843. return file (filename, mode)
  844. def file_remove (self, filename):
  845. os.remove (filename)
  846. def get_editor (self):
  847. try:
  848. return os.environ ['EDITOR']
  849. except KeyError:
  850. return 'notepad' # ouch
  851. def run_editor (self, filename):
  852. cmd = '%s %s' % (self.get_editor(), filename, )
  853. self.run_command (cmd)
  854. def run_command (self, command):
  855. os.system (command)
  856. class ViEvent:
  857. def __init__ (self, char):
  858. self.char = char
  859. # vi standalone functions
  860. def vi_is_word (char):
  861. log ('xx vi_is_word: type(%s), %s' % (type(char), char, ))
  862. return char.isalpha() or char.isdigit() or char == '_'
  863. def vi_is_space (char):
  864. return char.isspace ()
  865. def vi_is_word_or_space (char):
  866. return vi_is_word (char) or vi_is_space (char)
  867. def vi_pos_word_short (line, index=0, count=1):
  868. try:
  869. for i in range(count):
  870. in_word = vi_is_word (line[index])
  871. if not in_word:
  872. while not vi_is_word (line[index]):
  873. index += 1
  874. else:
  875. while vi_is_word (line[index]):
  876. index += 1
  877. while vi_is_space (line[index]):
  878. index += 1
  879. return index
  880. except IndexError:
  881. return len(line)
  882. def vi_pos_word_long (line, index=0, count=1):
  883. try:
  884. for i in range(count):
  885. in_space = vi_is_space (line[index])
  886. if not in_space:
  887. while not vi_is_space (line[index]):
  888. index += 1
  889. while vi_is_space (line[index]):
  890. index += 1
  891. return index
  892. except IndexError:
  893. return len(line)
  894. def vi_pos_end_short (line, index=0, count=1):
  895. try:
  896. for i in range(count):
  897. index += 1
  898. while vi_is_space (line[index]):
  899. index += 1
  900. in_word = vi_is_word (line[index])
  901. if not in_word:
  902. while not vi_is_word_or_space (line[index]):
  903. index += 1
  904. else:
  905. while vi_is_word (line[index]):
  906. index += 1
  907. return index - 1
  908. except IndexError:
  909. return max (0, len(line)-1)
  910. def vi_pos_end_long (line, index=0, count=1):
  911. try:
  912. for i in range(count):
  913. index += 1
  914. while vi_is_space (line[index]):
  915. index += 1
  916. while not vi_is_space (line[index]):
  917. index += 1
  918. return index - 1
  919. except IndexError:
  920. return max (0, len(line)-1)
  921. class vi_list (list):
  922. '''This is a list that cannot have a negative index'''
  923. def __getitem__ (self, key):
  924. try:
  925. if int(key) < 0:
  926. raise IndexError
  927. except ValueError:
  928. pass
  929. return list.__getitem__ (self, key)
  930. def vi_pos_back_short (line, index=0, count=1):
  931. line = vi_list (line)
  932. try:
  933. for i in range(count):
  934. index -= 1
  935. while vi_is_space (line[index]):
  936. index -= 1
  937. in_word = vi_is_word (line[index])
  938. if in_word:
  939. while vi_is_word (line[index]):
  940. index -= 1
  941. else:
  942. while not vi_is_word_or_space (line[index]):
  943. index -= 1
  944. return index + 1
  945. except IndexError:
  946. return 0
  947. def vi_pos_back_long (line, index=0, count=1):
  948. line = vi_list (line)
  949. try:
  950. for i in range(count):
  951. index -= 1
  952. while vi_is_space (line[index]):
  953. index -= 1
  954. while not vi_is_space (line[index]):
  955. index -= 1
  956. return index + 1
  957. except IndexError:
  958. return 0
  959. def vi_pos_find_char_forward (line, char, index=0, count=1):
  960. try:
  961. for i in range(count):
  962. index += 1
  963. while line [index] != char:
  964. index += 1
  965. return index
  966. except IndexError:
  967. return -1
  968. def vi_pos_find_char_backward (line, char, index=0, count=1):
  969. try:
  970. for i in range(count):
  971. index -= 1
  972. while 1:
  973. if index < 0:
  974. return -1
  975. if line[index] == char:
  976. break
  977. index -= 1
  978. return index
  979. except IndexError:
  980. return -1
  981. def vi_pos_to_char_forward (line, char, index=0, count=1):
  982. index = vi_pos_find_char_forward (line, char, index, count)
  983. if index > 0:
  984. return index - 1
  985. return index
  986. def vi_pos_to_char_backward (line, char, index=0, count=1):
  987. index = vi_pos_find_char_backward (line, char, index, count)
  988. if index >= 0:
  989. return index + 1
  990. return index
  991. _vi_dct_matching = {
  992. '<': ('>', +1), '>': ('<', -1),
  993. '(': (')', +1), ')': ('(', -1),
  994. '[': (']', +1), ']': ('[', -1),
  995. '{': ('}', +1), '}': ('{', -1),
  996. }
  997. def vi_pos_matching (line, index=0):
  998. '''find matching <([{}])>'''
  999. anchor = None
  1000. target = None
  1001. delta = 1
  1002. count = 0
  1003. try:
  1004. while 1:
  1005. if anchor is None:
  1006. # first find anchor
  1007. try:
  1008. target, delta = _vi_dct_matching [line [index]]
  1009. anchor = line [index]
  1010. count = 1
  1011. except KeyError:
  1012. index += 1
  1013. continue
  1014. else:
  1015. # Here the anchor has been found
  1016. # Need to get corresponding target
  1017. if index < 0:
  1018. return -1
  1019. if line [index] == anchor:
  1020. count += 1
  1021. elif line [index] == target:
  1022. count -= 1
  1023. if count == 0:
  1024. return index
  1025. index += delta
  1026. except IndexError:
  1027. return -1