public override ITextSegmentStyled FindStyledTextSegment(ITextEditor textEditor, ITextSegment textSegment, ITextDocument document, int index, int length, int textColumnIndex) { // TODO: This is way too slow. Should be able to speed up significantly. foreach (var textView in document.GetTextViews()) { this._cultureInfo = textView.Language; if (this._cultureInfo != null) { break; } } if (textEditor.Settings.SpellcheckEnabled(this._cultureInfo) == false || textEditor.Settings.InlineEnabled == false) { return(null); } var searchStartIndex = textSegment.Index + index; var selectedWord = document.GetWord(searchStartIndex, textSegment, true, textColumnIndex); if (selectedWord == null) { // If the current index has no word, then we exit. return(null); } if (selectedWord.End - selectedWord.Start < 3) { // If the word is shorter than 3 characters, then we exit. return(null); } if (textEditor.Settings.CheckIfWordIsValid(selectedWord.Word, textSegment.GetText(textColumnIndex)) == false) { // If the word is not a valid word according to out filter settings, then we exit. return(null); } try { //var spellcheckValid = ; //foreach (var check in LanguageFeature.FeatureFetchMultiple<bool>(this._cultureInfo, "Spellcheck.Check", new LFSString(selectedWord.Word))) //{ // spellcheckValid = check; // if (spellcheckValid) // { // break; // } //} if (textEditor.Settings.IsSpelledCorrectly(selectedWord.Word)) { // If the word is a correctly spelled word, then we exit. return(null); } } catch (Exception) { } // The word is not spelled correctly, so we create a style and return it. var incorrectlySpelledTextSegment = document.CreateStyledTextSegment(this); incorrectlySpelledTextSegment.Index = selectedWord.Start - textSegment.Index; incorrectlySpelledTextSegment.SetLength(textColumnIndex, selectedWord.End - selectedWord.Start); incorrectlySpelledTextSegment.Object = selectedWord.Word; return(incorrectlySpelledTextSegment); }
public override ITextSegmentStyled FindStyledTextSegment(ITextEditor textEditor, ITextSegment textSegment, ITextDocument document, int startIndex, int length, int textColumnIndex) { var text = textSegment.GetText(textColumnIndex); if (startIndex >= text.Length) { return(null); } foreach (var word in this.WordList) { for (var i = 0; i < word.Length; i++) { if (word[i] != text[startIndex]) { continue; } var found = true; var left = i - 1; for (; left >= 0; left--) { var relativeIndex = startIndex - (i - left); if (relativeIndex < 0) { found = false; break; } var c = text[relativeIndex]; if (word[left] != c) { found = false; break; } } if (found == false) { break; } left = Math.Max(0, left); var right = i + 1; for (; right < word.Length; right++) { var relativeIndex = startIndex + (right - i); if (relativeIndex >= text.Length) { found = false; break; } var c = text[relativeIndex]; if (word[right] != c) { found = false; break; } } if (found) { var newTextSegment = document.CreateStyledTextSegment(this); var relativeIndex = startIndex - (i - left); newTextSegment.Index = relativeIndex; newTextSegment.SetLength(textColumnIndex, right - left); newTextSegment.Object = word; return(newTextSegment); } } } return(null); }
/// <summary> /// TODO: Make this threaded and make the text control not editable meanwhile /// </summary> public bool SearchAndApplyTo(ITextView textView, ITextSegment textSegment, int index, int length, bool changeWasFinalizer, int textColumnIndex) { var foundOne = false; var canSkip = false; var previousWasWhitespace = false; var textLine = textSegment as TextLine; var textStyles = new List <TextStyleBase>(textView.GetTextStyles()); string previousStyleType = null; var previousStyleIndex = -1; if (textLine == null) { return(false); } for (var i = index; i <= index + length && i < textSegment.GetLength(textColumnIndex); i++) { #region If whitespace found, enable word-jump-search and only search on first char per word var isWhitespace = i < index + length && Char.IsWhiteSpace(textSegment.GetText(textColumnIndex)[i]); if (canSkip) { if (isWhitespace == false) { if (previousWasWhitespace == false) { continue; } } else { previousWasWhitespace = true; continue; // Don't need to search on a whitespace. } } else if (isWhitespace) { canSkip = true; previousWasWhitespace = true; continue; // Don't need to search on a whitespace. } previousWasWhitespace = false; #endregion ITextSegmentStyled newStyledTextSegment = null; for (var s = 0; s < textStyles.Count; s++) { if (textStyles[s].UpdateOnlyOnFinalizingChange && changeWasFinalizer == false) { continue; } newStyledTextSegment = textStyles[s].FindStyledTextSegment(textView, textSegment, this.TextHandler, i, -1, textColumnIndex); if (newStyledTextSegment != null) { //textStyles.RemoveAt(s); break; } } if (newStyledTextSegment == null) { continue; } var found = false; foreach (var existingStyle in GetAll(textLine, i, newStyledTextSegment.Style.NameKey)) { if (existingStyle.Style.NameKey == newStyledTextSegment.Style.NameKey) { if (newStyledTextSegment.Index == existingStyle.Index && newStyledTextSegment.GetLength(textColumnIndex) == existingStyle.GetLength(textColumnIndex)) { found = true; break; } this.RemoveTextSegment(existingStyle); break; } } if (found == false) { foundOne = true; // TODO: Make this line actually work. (NOTE: what did I mean here? ;D) this.AddManualTextSegment(newStyledTextSegment, textLine.Index + newStyledTextSegment.Index, textColumnIndex); } if (previousStyleType != newStyledTextSegment.Style.NameKey && previousStyleIndex != newStyledTextSegment.Index) { // Decrease it so that we stay on the same location, in case there are several styles overlapping on the same spot. i--; } previousStyleType = newStyledTextSegment.Style.NameKey; previousStyleIndex = newStyledTextSegment.Index; } return(foundOne); }
public override WordSegment GetWord(int globalIndex, ITextSegment insideSegment, bool strict, int textColumnIndex) { return(insideSegment.GetText(textColumnIndex).GetWord(globalIndex, insideSegment.Index, strict)); }