QScintilla/SpellChecker.py

changeset 945
8cd4d08fa9f6
parent 890
b4736e256f8c
child 1112
8a7d1b9d18db
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
18 18
19 from PyQt4.QtCore import * 19 from PyQt4.QtCore import *
20 20
21 import Preferences 21 import Preferences
22 import Utilities 22 import Utilities
23
23 24
24 class SpellChecker(QObject): 25 class SpellChecker(QObject):
25 """ 26 """
26 Class implementing a pyenchant based spell checker. 27 Class implementing a pyenchant based spell checker.
27 """ 28 """
28 # class attributes to be used as defaults 29 # class attributes to be used as defaults
29 _spelling_lang = None 30 _spelling_lang = None
30 _spelling_dict = None 31 _spelling_dict = None
31 32
32 def __init__(self, editor, indicator, defaultLanguage = None, checkRegion = None): 33 def __init__(self, editor, indicator, defaultLanguage=None, checkRegion=None):
33 """ 34 """
34 Constructor 35 Constructor
35 36
36 @param editor reference to the editor object (QScintilla.Editor) 37 @param editor reference to the editor object (QScintilla.Editor)
37 @param indicator spell checking indicator 38 @param indicator spell checking indicator
81 except NameError: 82 except NameError:
82 pass 83 pass
83 return False 84 return False
84 85
85 @classmethod 86 @classmethod
86 def _getDict(cls, lang, pwl = "", pel = ""): 87 def _getDict(cls, lang, pwl="", pel=""):
87 """ 88 """
88 Protected classmethod to get a new dictionary. 89 Protected classmethod to get a new dictionary.
89 90
90 @param lang the language to be used as the default (string). 91 @param lang the language to be used as the default (string).
91 The string should be in language locale format (e.g. en_US, de). 92 The string should be in language locale format (e.g. en_US, de).
126 The string should be in language locale format (e.g. en_US, de). 127 The string should be in language locale format (e.g. en_US, de).
127 """ 128 """
128 cls._spelling_lang = language 129 cls._spelling_lang = language
129 cls._spelling_dict = cls._getDict(language) 130 cls._spelling_dict = cls._getDict(language)
130 131
131 def setLanguage(self, language, pwl = "", pel = ""): 132 def setLanguage(self, language, pwl="", pel=""):
132 """ 133 """
133 Public method to set the current language. 134 Public method to set the current language.
134 135
135 @param language the language to be used as the default (string). 136 @param language the language to be used as the default (string).
136 The string should be in language locale format (e.g. en_US, de). 137 The string should be in language locale format (e.g. en_US, de).
137 @keyparam pwl name of the personal/project word list (string) 138 @keyparam pwl name of the personal/project word list (string)
138 @keyparam pel name of the personal/project exclude list (string) 139 @keyparam pel name of the personal/project exclude list (string)
139 """ 140 """
140 self._spelling_lang = language 141 self._spelling_lang = language
141 self._spelling_dict = self._getDict(language, pwl = pwl, 142 self._spelling_dict = self._getDict(language, pwl=pwl,
142 pel = pel) 143 pel=pel)
143 144
144 def getLanguage(self): 145 def getLanguage(self):
145 """ 146 """
146 Public method to get the current language. 147 Public method to get the current language.
147 148
161 """ 162 """
162 Private method to get the next word in the text after the given position. 163 Private method to get the next word in the text after the given position.
163 164
164 @param pos position to start word extraction (integer) 165 @param pos position to start word extraction (integer)
165 @param endPosition position to stop word extraction (integer) 166 @param endPosition position to stop word extraction (integer)
166 @return tuple of three values (the extracted word (string), 167 @return tuple of three values (the extracted word (string),
167 start position (integer), end position (integer)) 168 start position (integer), end position (integer))
168 """ 169 """
169 if pos < 0 or pos >= endPosition: 170 if pos < 0 or pos >= endPosition:
170 return "", -1, -1 171 return "", -1, -1
171 172
173 # 1. skip non-word characters 174 # 1. skip non-word characters
174 while pos < endPosition and not ch.isalnum(): 175 while pos < endPosition and not ch.isalnum():
175 pos = self.editor.positionAfter(pos) 176 pos = self.editor.positionAfter(pos)
176 ch = self.editor.charAt(pos) 177 ch = self.editor.charAt(pos)
177 if pos == endPosition: 178 if pos == endPosition:
178 return "", -1, -1 179 return "", -1, -1
179 startPos = pos 180 startPos = pos
180 181
181 # 2. extract the word 182 # 2. extract the word
182 word = "" 183 word = ""
183 while pos < endPosition and ch.isalnum(): 184 while pos < endPosition and ch.isalnum():
247 return 248 return
248 249
249 while True: 250 while True:
250 try: 251 try:
251 next(self) 252 next(self)
252 self.editor.setIndicatorRange(self.indicator, self.wordStart, 253 self.editor.setIndicatorRange(self.indicator, self.wordStart,
253 self.wordEnd - self.wordStart) 254 self.wordEnd - self.wordStart)
254 except StopIteration: 255 except StopIteration:
255 break 256 break
256 257
257 def __incrementalCheck(self): 258 def __incrementalCheck(self):
267 if self.lastCheckedLine >= self.editor.lines(): 268 if self.lastCheckedLine >= self.editor.lines():
268 self.lastCheckedLine = -1 269 self.lastCheckedLine = -1
269 else: 270 else:
270 QTimer.singleShot(0, self.__incrementalCheck) 271 QTimer.singleShot(0, self.__incrementalCheck)
271 272
272 def checkWord(self, pos, atEnd = False): 273 def checkWord(self, pos, atEnd=False):
273 """ 274 """
274 Public method to check the word at position pos. 275 Public method to check the word at position pos.
275 276
276 @param pos position to check at (integer) 277 @param pos position to check at (integer)
277 @keyparam atEnd flag indicating the position is at the end of the word 278 @keyparam atEnd flag indicating the position is at the end of the word
294 pos0 = self.editor.positionBefore(pos) 295 pos0 = self.editor.positionBefore(pos)
295 296
296 for pos in [pos0, pos1]: 297 for pos in [pos0, pos1]:
297 if self.editor.charAt(pos).isalnum(): 298 if self.editor.charAt(pos).isalnum():
298 line, index = self.editor.lineIndexFromPosition(pos) 299 line, index = self.editor.lineIndexFromPosition(pos)
299 word = self.editor.getWord(line, index, useWordChars = False) 300 word = self.editor.getWord(line, index, useWordChars=False)
300 if len(word) >= self.minimumWordSize: 301 if len(word) >= self.minimumWordSize:
301 ok = spell.check(word) 302 ok = spell.check(word)
302 else: 303 else:
303 ok = True 304 ok = True
304 start, end = \ 305 start, end = \
305 self.editor.getWordBoundaries(line, index, useWordChars = False) 306 self.editor.getWordBoundaries(line, index, useWordChars=False)
306 if ok: 307 if ok:
307 self.editor.clearIndicator(self.indicator, line, start, line, end) 308 self.editor.clearIndicator(self.indicator, line, start, line, end)
308 else: 309 else:
309 # spell check indicated an error 310 # spell check indicated an error
310 self.editor.setIndicator(self.indicator, line, start, line, end) 311 self.editor.setIndicator(self.indicator, line, start, line, end)
353 Private method to check the current selection. 354 Private method to check the current selection.
354 """ 355 """
355 selStartLine, selStartIndex, selEndLine, selEndIndex = \ 356 selStartLine, selStartIndex, selEndLine, selEndIndex = \
356 self.editor.getSelection() 357 self.editor.getSelection()
357 self.__checkDocumentPart( 358 self.__checkDocumentPart(
358 self.editor.positionFromLineIndex(selStartLine, selStartIndex), 359 self.editor.positionFromLineIndex(selStartLine, selStartIndex),
359 self.editor.positionFromLineIndex(selEndLine, selEndIndex) 360 self.editor.positionFromLineIndex(selEndLine, selEndIndex)
360 ) 361 )
361 362
362 def checkCurrentPage(self): 363 def checkCurrentPage(self):
363 """ 364 """
385 suggestions = spell.suggest(word) 386 suggestions = spell.suggest(word)
386 return suggestions 387 return suggestions
387 388
388 return [] 389 return []
389 390
390 def add(self, word = None): 391 def add(self, word=None):
391 """ 392 """
392 Public method to add a word to the personal word list. 393 Public method to add a word to the personal word list.
393 394
394 @param word word to add (string) 395 @param word word to add (string)
395 """ 396 """
407 """ 408 """
408 spell = self._spelling_dict 409 spell = self._spelling_dict
409 if spell: 410 if spell:
410 spell.remove(word) 411 spell.remove(word)
411 412
412 def ignoreAlways(self, word = None): 413 def ignoreAlways(self, word=None):
413 """ 414 """
414 Public method to tell the checker, to always ignore the given word 415 Public method to tell the checker, to always ignore the given word
415 or the current word. 416 or the current word.
416 417
417 @param word word to be ignored (string) 418 @param word word to be ignored (string)
421 if word not in self.__ignoreWords: 422 if word not in self.__ignoreWords:
422 self.__ignoreWords.append(word) 423 self.__ignoreWords.append(word)
423 424
424 def replace(self, replacement): 425 def replace(self, replacement):
425 """ 426 """
426 Public method to tell the checker to replace the current word with 427 Public method to tell the checker to replace the current word with
427 the replacement string. 428 the replacement string.
428 429
429 @param replacement replacement string (string) 430 @param replacement replacement string (string)
430 """ 431 """
431 sline, sindex = self.editor.lineIndexFromPosition(self.wordStart) 432 sline, sindex = self.editor.lineIndexFromPosition(self.wordStart)

eric ide

mercurial