IdleHistory.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import string
  2. class History:
  3. def __init__(self, text, output_sep = "\n"):
  4. self.text = text
  5. self.history = []
  6. self.history_prefix = None
  7. self.history_pointer = None
  8. self.output_sep = output_sep
  9. text.bind("<<history-previous>>", self.history_prev)
  10. text.bind("<<history-next>>", self.history_next)
  11. def history_next(self, event):
  12. self.history_do(0)
  13. return "break"
  14. def history_prev(self, event):
  15. self.history_do(1)
  16. return "break"
  17. def _get_source(self, start, end):
  18. # Get source code from start index to end index. Lines in the
  19. # text control may be separated by sys.ps2 .
  20. lines = self.text.get(start, end).split(self.output_sep)
  21. return "\n".join(lines)
  22. def _put_source(self, where, source):
  23. output = self.output_sep.join(source.split("\n"))
  24. self.text.insert(where, output)
  25. def history_do(self, reverse):
  26. nhist = len(self.history)
  27. pointer = self.history_pointer
  28. prefix = self.history_prefix
  29. if pointer is not None and prefix is not None:
  30. if self.text.compare("insert", "!=", "end-1c") or \
  31. self._get_source("iomark", "end-1c") != self.history[pointer]:
  32. pointer = prefix = None
  33. if pointer is None or prefix is None:
  34. prefix = self._get_source("iomark", "end-1c")
  35. if reverse:
  36. pointer = nhist
  37. else:
  38. pointer = -1
  39. nprefix = len(prefix)
  40. while 1:
  41. if reverse:
  42. pointer = pointer - 1
  43. else:
  44. pointer = pointer + 1
  45. if pointer < 0 or pointer >= nhist:
  46. self.text.bell()
  47. if self._get_source("iomark", "end-1c") != prefix:
  48. self.text.delete("iomark", "end-1c")
  49. self._put_source("iomark", prefix)
  50. pointer = prefix = None
  51. break
  52. item = self.history[pointer]
  53. if item[:nprefix] == prefix and len(item) > nprefix:
  54. self.text.delete("iomark", "end-1c")
  55. self._put_source("iomark", item)
  56. break
  57. self.text.mark_set("insert", "end-1c")
  58. self.text.see("insert")
  59. self.text.tag_remove("sel", "1.0", "end")
  60. self.history_pointer = pointer
  61. self.history_prefix = prefix
  62. def history_store(self, source):
  63. source = source.strip()
  64. if len(source) > 2:
  65. # avoid duplicates
  66. try:
  67. self.history.remove(source)
  68. except ValueError:
  69. pass
  70. self.history.append(source)
  71. self.history_pointer = None
  72. self.history_prefix = None
  73. def recall(self, s):
  74. s = s.strip()
  75. self.text.tag_remove("sel", "1.0", "end")
  76. self.text.delete("iomark", "end-1c")
  77. self.text.mark_set("insert", "end-1c")
  78. self.text.insert("insert", s)
  79. self.text.see("insert")