AutoExpand.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import string
  2. import re
  3. ###$ event <<expand-word>>
  4. ###$ win <Alt-slash>
  5. ###$ unix <Alt-slash>
  6. class AutoExpand:
  7. keydefs = {
  8. '<<expand-word>>': ['<Alt-slash>'],
  9. }
  10. unix_keydefs = {
  11. '<<expand-word>>': ['<Meta-slash>'],
  12. }
  13. menudefs = [
  14. ('edit', [
  15. ('E_xpand word', '<<expand-word>>'),
  16. ]),
  17. ]
  18. wordchars = string.ascii_letters + string.digits + "_"
  19. def __init__(self, editwin):
  20. self.text = editwin.text
  21. self.text.wordlist = None # XXX what is this?
  22. self.state = None
  23. def expand_word_event(self, event):
  24. curinsert = self.text.index("insert")
  25. curline = self.text.get("insert linestart", "insert lineend")
  26. if not self.state:
  27. words = self.getwords()
  28. index = 0
  29. else:
  30. words, index, insert, line = self.state
  31. if insert != curinsert or line != curline:
  32. words = self.getwords()
  33. index = 0
  34. if not words:
  35. self.text.bell()
  36. return "break"
  37. word = self.getprevword()
  38. self.text.delete("insert - %d chars" % len(word), "insert")
  39. newword = words[index]
  40. index = (index + 1) % len(words)
  41. if index == 0:
  42. self.text.bell() # Warn we cycled around
  43. self.text.insert("insert", newword)
  44. curinsert = self.text.index("insert")
  45. curline = self.text.get("insert linestart", "insert lineend")
  46. self.state = words, index, curinsert, curline
  47. return "break"
  48. def getwords(self):
  49. word = self.getprevword()
  50. if not word:
  51. return []
  52. before = self.text.get("1.0", "insert wordstart")
  53. wbefore = re.findall(r"\b" + word + r"\w+\b", before)
  54. del before
  55. after = self.text.get("insert wordend", "end")
  56. wafter = re.findall(r"\b" + word + r"\w+\b", after)
  57. del after
  58. if not wbefore and not wafter:
  59. return []
  60. words = []
  61. dict = {}
  62. # search backwards through words before
  63. wbefore.reverse()
  64. for w in wbefore:
  65. if dict.get(w):
  66. continue
  67. words.append(w)
  68. dict[w] = w
  69. # search onwards through words after
  70. for w in wafter:
  71. if dict.get(w):
  72. continue
  73. words.append(w)
  74. dict[w] = w
  75. words.append(word)
  76. return words
  77. def getprevword(self):
  78. line = self.text.get("insert linestart", "insert")
  79. i = len(line)
  80. while i > 0 and line[i-1] in self.wordchars:
  81. i = i-1
  82. return line[i:]