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.

263 lines
10 KiB

6 months ago
  1. # -*- coding: utf-8 -*-
  2. #*****************************************************************************
  3. # Copyright (C) 2006 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
  4. #
  5. # Distributed under the terms of the BSD License. The full license is in
  6. # the file COPYING, distributed as part of this software.
  7. #*****************************************************************************
  8. from __future__ import print_function, unicode_literals, absolute_import
  9. import re, operator, string, sys, os
  10. from pyreadline.unicode_helper import ensure_unicode, ensure_str
  11. if "pyreadline" in sys.modules:
  12. pyreadline = sys.modules["pyreadline"]
  13. else:
  14. import pyreadline
  15. from . import lineobj
  16. class EscapeHistory(Exception):
  17. pass
  18. from pyreadline.logger import log
  19. class LineHistory(object):
  20. def __init__(self):
  21. self.history = []
  22. self._history_length = 100
  23. self._history_cursor = 0
  24. self.history_filename = os.path.expanduser(ensure_str('~/.history')) #Cannot expand unicode strings correctly on python2.4
  25. self.lastcommand = None
  26. self.query = ""
  27. self.last_search_for = ""
  28. def get_current_history_length(self):
  29. '''Return the number of lines currently in the history.
  30. (This is different from get_history_length(), which returns
  31. the maximum number of lines that will be written to a history file.)'''
  32. value = len(self.history)
  33. log("get_current_history_length:%d"%value)
  34. return value
  35. def get_history_length(self):
  36. '''Return the desired length of the history file. Negative values imply
  37. unlimited history file size.'''
  38. value = self._history_length
  39. log("get_history_length:%d"%value)
  40. return value
  41. def get_history_item(self, index):
  42. '''Return the current contents of history item at index (starts with index 1).'''
  43. item = self.history[index - 1]
  44. log("get_history_item: index:%d item:%r"%(index, item))
  45. return item.get_line_text()
  46. def set_history_length(self, value):
  47. log("set_history_length: old:%d new:%d"%(self._history_length, value))
  48. self._history_length = value
  49. def get_history_cursor(self):
  50. value = self._history_cursor
  51. log("get_history_cursor:%d"%value)
  52. return value
  53. def set_history_cursor(self, value):
  54. log("set_history_cursor: old:%d new:%d"%(self._history_cursor, value))
  55. self._history_cursor = value
  56. history_length = property(get_history_length, set_history_length)
  57. history_cursor = property(get_history_cursor, set_history_cursor)
  58. def clear_history(self):
  59. '''Clear readline history.'''
  60. self.history[:] = []
  61. self.history_cursor = 0
  62. def read_history_file(self, filename=None):
  63. '''Load a readline history file.'''
  64. if filename is None:
  65. filename = self.history_filename
  66. try:
  67. for line in open(filename, 'r'):
  68. self.add_history(lineobj.ReadLineTextBuffer(ensure_unicode(line.rstrip())))
  69. except IOError:
  70. self.history = []
  71. self.history_cursor = 0
  72. def write_history_file(self, filename = None):
  73. '''Save a readline history file.'''
  74. if filename is None:
  75. filename = self.history_filename
  76. fp = open(filename, 'wb')
  77. for line in self.history[-self.history_length:]:
  78. fp.write(ensure_str(line.get_line_text()))
  79. fp.write('\n'.encode('ascii'))
  80. fp.close()
  81. def add_history(self, line):
  82. '''Append a line to the history buffer, as if it was the last line typed.'''
  83. line = ensure_unicode(line)
  84. if not hasattr(line, "get_line_text"):
  85. line = lineobj.ReadLineTextBuffer(line)
  86. if not line.get_line_text():
  87. pass
  88. elif len(self.history) > 0 and self.history[-1].get_line_text() == line.get_line_text():
  89. pass
  90. else:
  91. self.history.append(line)
  92. self.history_cursor = len(self.history)
  93. def previous_history(self, current): # (C-p)
  94. '''Move back through the history list, fetching the previous command. '''
  95. if self.history_cursor == len(self.history):
  96. self.history.append(current.copy()) #do not use add_history since we do not want to increment cursor
  97. if self.history_cursor > 0:
  98. self.history_cursor -= 1
  99. current.set_line(self.history[self.history_cursor].get_line_text())
  100. current.point = lineobj.EndOfLine
  101. def next_history(self, current): # (C-n)
  102. '''Move forward through the history list, fetching the next command. '''
  103. if self.history_cursor < len(self.history) - 1:
  104. self.history_cursor += 1
  105. current.set_line(self.history[self.history_cursor].get_line_text())
  106. def beginning_of_history(self): # (M-<)
  107. '''Move to the first line in the history.'''
  108. self.history_cursor = 0
  109. if len(self.history) > 0:
  110. self.l_buffer = self.history[0]
  111. def end_of_history(self, current): # (M->)
  112. '''Move to the end of the input history, i.e., the line currently
  113. being entered.'''
  114. self.history_cursor = len(self.history)
  115. current.set_line(self.history[-1].get_line_text())
  116. def reverse_search_history(self, searchfor, startpos=None):
  117. if startpos is None:
  118. startpos = self.history_cursor
  119. origpos = startpos
  120. result = lineobj.ReadLineTextBuffer("")
  121. for idx, line in list(enumerate(self.history))[startpos:0:-1]:
  122. if searchfor in line:
  123. startpos = idx
  124. break
  125. #If we get a new search without change in search term it means
  126. #someone pushed ctrl-r and we should find the next match
  127. if self.last_search_for == searchfor and startpos > 0:
  128. startpos -= 1
  129. for idx, line in list(enumerate(self.history))[startpos:0:-1]:
  130. if searchfor in line:
  131. startpos = idx
  132. break
  133. if self.history:
  134. result = self.history[startpos].get_line_text()
  135. else:
  136. result = ""
  137. self.history_cursor = startpos
  138. self.last_search_for = searchfor
  139. log("reverse_search_history: old:%d new:%d result:%r"%(origpos, self.history_cursor, result))
  140. return result
  141. def forward_search_history(self, searchfor, startpos=None):
  142. if startpos is None:
  143. startpos = min(self.history_cursor, max(0, self.get_current_history_length()-1))
  144. origpos = startpos
  145. result = lineobj.ReadLineTextBuffer("")
  146. for idx, line in list(enumerate(self.history))[startpos:]:
  147. if searchfor in line:
  148. startpos = idx
  149. break
  150. #If we get a new search without change in search term it means
  151. #someone pushed ctrl-r and we should find the next match
  152. if self.last_search_for == searchfor and startpos < self.get_current_history_length()-1:
  153. startpos += 1
  154. for idx, line in list(enumerate(self.history))[startpos:]:
  155. if searchfor in line:
  156. startpos = idx
  157. break
  158. if self.history:
  159. result = self.history[startpos].get_line_text()
  160. else:
  161. result = ""
  162. self.history_cursor = startpos
  163. self.last_search_for = searchfor
  164. return result
  165. def _search(self, direction, partial):
  166. try:
  167. if (self.lastcommand != self.history_search_forward and
  168. self.lastcommand != self.history_search_backward):
  169. self.query = ''.join(partial[0:partial.point].get_line_text())
  170. hcstart = max(self.history_cursor,0)
  171. hc = self.history_cursor + direction
  172. while (direction < 0 and hc >= 0) or (direction > 0 and hc < len(self.history)):
  173. h = self.history[hc]
  174. if not self.query:
  175. self.history_cursor = hc
  176. result = lineobj.ReadLineTextBuffer(h, point=len(h.get_line_text()))
  177. return result
  178. elif (h.get_line_text().startswith(self.query) and (h != partial.get_line_text())):
  179. self.history_cursor = hc
  180. result = lineobj.ReadLineTextBuffer(h, point=partial.point)
  181. return result
  182. hc += direction
  183. else:
  184. if len(self.history) == 0:
  185. pass
  186. elif hc >= len(self.history) and not self.query:
  187. self.history_cursor = len(self.history)
  188. return lineobj.ReadLineTextBuffer("", point=0)
  189. elif self.history[max(min(hcstart, len(self.history) - 1), 0)]\
  190. .get_line_text().startswith(self.query) and self.query:
  191. return lineobj.ReadLineTextBuffer(self.history\
  192. [max(min(hcstart, len(self.history) - 1),0)],
  193. point = partial.point)
  194. else:
  195. return lineobj.ReadLineTextBuffer(partial,
  196. point=partial.point)
  197. return lineobj.ReadLineTextBuffer(self.query,
  198. point=min(len(self.query),
  199. partial.point))
  200. except IndexError:
  201. raise
  202. def history_search_forward(self, partial): # ()
  203. '''Search forward through the history for the string of characters
  204. between the start of the current line and the point. This is a
  205. non-incremental search. By default, this command is unbound.'''
  206. q= self._search(1, partial)
  207. return q
  208. def history_search_backward(self, partial): # ()
  209. '''Search backward through the history for the string of characters
  210. between the start of the current line and the point. This is a
  211. non-incremental search. By default, this command is unbound.'''
  212. q= self._search(-1, partial)
  213. return q
  214. if __name__ == "__main__":
  215. q = LineHistory()
  216. r = LineHistory()
  217. s = LineHistory()
  218. RL = lineobj.ReadLineTextBuffer
  219. q.add_history(RL("aaaa"))
  220. q.add_history(RL("aaba"))
  221. q.add_history(RL("aaca"))
  222. q.add_history(RL("akca"))
  223. q.add_history(RL("bbb"))
  224. q.add_history(RL("ako"))
  225. r.add_history(RL("ako"))