private IniLexer(Scintilla scintilla, int startPos, int length) { this._scintilla = scintilla; this._startPos = startPos; // One line of _text this._text = scintilla.GetRange(startPos, startPos + length).Text; }
public bool DoSnippetCheck() { if (!_isEnabled || _snippetLinks.IsActive || Scintilla.AutoComplete.IsActive || Scintilla.Selection.Length > 0) { return(false); } int pos = Scintilla.NativeInterface.GetCurrentPos(); // In order to even _start searching for a snippet keyword the // current position needs to meet these conditions: // Can't be at the very beginning of the document. Why? becuase // then obviously there can't be a preceding keyword then can it? // The preceding character can't be whitespace (same reason) // // I decided I like expanding a template in the middle of a word char[] whitespaceChars = Scintilla.Lexing.GetClassificationChars(CharClassification.Whitespace); if (pos <= 0 || Scintilla.NativeInterface.GetCharAt(pos - 1).ToString().IndexOfAny(whitespaceChars) >= 0) { return(false); } // We also don't want a template expand if we're in a Comment or // String. Be sure and mask out any indicator style that may be applied int currentStyle = Scintilla.NativeInterface.GetStyleAt(pos - 1) & 0x1f; if (currentStyle == 1 || currentStyle == 2 || currentStyle == 4) { return(false); } // Let Scintilla figure out where the beginning of // the word to the left is. int newPos = Scintilla.NativeInterface.WordStartPosition(pos, true); Range snipRange = Scintilla.GetRange(newPos, pos); string keyworkCandidate = snipRange.Text; Snippet snip; if (!_list.TryGetValue(keyworkCandidate, out snip)) { // Not a match. Buh-bye return(false); } InsertSnippet(snip, newPos); Scintilla.Commands.StopProcessingCommands = true; return(true); }
public List <Range> SearchAll(Range searchRange) { Range foundRange = Scintilla.GetRange(-1, -1); List <Range> ret = new List <Range>(); do { foundRange = Search(searchRange, foundRange); if (foundRange != null) { ret.Add(foundRange); } }while (foundRange != null); return(ret); }
private static TagMatch getHtmlTag(Scintilla scintilla, int pos) { int startPos = 0; int stopPos = 0; bool inTag = false; for (int i = pos; i >= 0; i--) { char ch = scintilla.NativeInterface.GetCharAt(i); if (ch == '<') { // In a tag inTag = true; startPos = i; break; } if (ch == '\n' || ch == '\r' || ch == '>') { break; } } if (inTag) { for (int i = startPos + 1; i < scintilla.TextLength; i++) { char ch = scintilla.NativeInterface.GetCharAt(i); if (ch == '>') { stopPos = i + 1; break; } } } if (inTag && stopPos > startPos) { return(new TagMatch(scintilla.GetRange(startPos, stopPos).Text, startPos, stopPos)); } return(null); }
public void ToggleLineComment() { if (string.IsNullOrEmpty(_lineCommentPrefix)) { return; } NativeScintilla.BeginUndoAction(); Range selRange = Scintilla.Selection.Range; int start = selRange.StartingLine.Number; int end = selRange.EndingLine.Number; int offset = _lineCommentPrefix.Length; for (int i = start; i <= end; i++) { Line l = Scintilla.Lines[i]; int firstWordChar = FindFirstNonWhitespaceChar(l.Text); if (firstWordChar >= 0) { int startPos = l.StartPosition + firstWordChar; Range commentRange = Scintilla.GetRange(startPos, startPos + offset); if (commentRange.Text == _lineCommentPrefix) { commentRange.Text = string.Empty; selRange.End -= offset; } else { Scintilla.InsertText(l.StartPosition + firstWordChar, _lineCommentPrefix); selRange.End += offset; } } } NativeScintilla.EndUndoAction(); selRange.Select(); }
public void LineUncomment() { if (string.IsNullOrEmpty(_lineCommentPrefix)) { return; } NativeScintilla.BeginUndoAction(); // Uncommenting is a lot like line commenting. However in addition // to looking for a non-whitespace character, the string that follows // it MUST be our line Comment Prefix. If this is the case the prefex // is removed from the line at its position. Range selRange = Scintilla.Selection.Range; int start = selRange.StartingLine.Number; int end = selRange.EndingLine.Number; int offset = _lineCommentPrefix.Length; for (int i = start; i <= end; i++) { Line l = Scintilla.Lines[i]; int firstWordChar = FindFirstNonWhitespaceChar(l.Text); if (firstWordChar >= 0) { int startPos = l.StartPosition + firstWordChar; Range commentRange = Scintilla.GetRange(startPos, startPos + offset); if (commentRange.Text == _lineCommentPrefix) { commentRange.Text = string.Empty; } } } NativeScintilla.EndUndoAction(); }
internal void InsertSnippet(Snippet snip, int startPos) { NativeScintilla.BeginUndoAction(); IsActive = false; string snippet = snip.RealCode; // First properly indent the template. We do this by // getting the indent string of the current line and // adding it to all newlines int indentPoint = 0; string line = Scintilla.Lines.Current.Text; if (line != string.Empty) { while (indentPoint < line.Length) { char c = line[indentPoint]; if (c != ' ' && c != '\t') { break; } indentPoint++; } } // Grab the current selected text in case we have a surrounds with scenario. string selText = Scintilla.Selection.Text; // Now we clear the selection if (selText != string.Empty) { Scintilla.Selection.Clear(); } if (indentPoint > 0) { string indent = line.Substring(0, indentPoint); // This is a bit of a tough decision, but I think the best way to handle it // is to assume that the Snippet's Eol Marker matches the Platform DOCUMENT_DEFAULT // but the target Eol Marker should match the Document's. snippet = snippet.Replace(Environment.NewLine, Scintilla.EndOfLine.EolString + indent); // Same deal with the selected text if any selText = selText.Replace(Environment.NewLine, Scintilla.EndOfLine.EolString + indent); } int anchorPos = -1; int caretPos = -1; int endPos = -1; int selPos = -1; SortedList <int, int> dropMarkers = new SortedList <int, int>(); SortedList <int, SnippetLinkRange> indexedRangesToActivate = new SortedList <int, SnippetLinkRange>(); List <SnippetLinkRange> unindexedRangesToActivate = new List <SnippetLinkRange>(); Match m = snippetRegex1.Match(snippet); while (m.Success) { // Did it match a $DropMarker$ token? if (m.Groups["dm"].Success) { // Yep, was it an indexed or unindexed DropMarker if (m.Groups["dmi"].Success) { // Indexed, set the indexed drop marker's character offset // if it is specified more than once the last one wins. dropMarkers[int.Parse(m.Groups["dmi"].Value)] = m.Groups["dm"].Index; } else { // Unindexed, just tack it on at the _end dropMarkers[dropMarkers.Count] = m.Groups["dm"].Index; } // Take the token out of the string snippet = snippet.Remove(m.Groups["dm"].Index, m.Groups["dm"].Length); } else if (m.Groups["c"].Success) { // We matched the $Caret$ Token. Since there can be // only 1 we set the caretPos. If this is specified // more than once the last one wins caretPos = m.Groups["c"].Index; // Take the token out of the string snippet = snippet.Remove(m.Groups["c"].Index, m.Groups["c"].Length); } else if (m.Groups["a"].Success) { // We matched the $Anchor$ Token. Since there can be // only 1 we set the anchorPos. If this is specified // more than once the last one wins anchorPos = m.Groups["a"].Index; // Take the token out of the string snippet = snippet.Remove(m.Groups["a"].Index, m.Groups["a"].Length); } else if (m.Groups["e"].Success) { // We matched the $End$ Token. Since there can be // only 1 we set the endPos. If this is specified // more than once the last one wins endPos = m.Groups["e"].Index; // Take the token out of the string snippet = snippet.Remove(m.Groups["e"].Index, m.Groups["e"].Length); } else if (m.Groups["s"].Success) { // We matched the $Selection$ Token. Simply insert the // selected text at this position selPos = m.Groups["s"].Index; // Take the token out of the string snippet = snippet.Remove(m.Groups["s"].Index, m.Groups["s"].Length); snippet = snippet.Insert(m.Groups["s"].Index, selText); } else if (m.Groups["l"].Success) { // Finally match for Snippet Link Ranges. This is at the bottom of the if/else // because we want the more specific regex groups to match first so that this // generic expression group doesn't create a SnippetLinkRange for say the // $Caret$ Token. Group g = m.Groups["l"]; int rangeIndex; string groupKey; if (m.Groups["li"].Success) { // We have a subindexed SnippetLinkRange along the lines of $sometoken[1]$ Group sg = m.Groups["li"]; // At this point g.Value = $sometoken[1]$ // and sg.Value = [1]. // We want the range's Key, which would be sometoken groupKey = g.Value.Substring(1, g.Value.Length - sg.Length - 2); // Now we need the range's Index which would be 1 in our fictitional case rangeIndex = int.Parse(sg.Value.Substring(1, sg.Value.Length - 2)); // Now we need to determine the actual _start and _end positions of the range. // Keep in mind we'll be stripping out the 2 $ and the subindex string (eg [1]) int start = startPos + g.Index; int end = start + g.Length - sg.Length - 2; // And now we add (or replace) the snippet link range at the index // keep in mind duplicates will stomp all over each other, the last // one wins. Replaced tokens won't get a range indexedRangesToActivate[rangeIndex] = new SnippetLinkRange(start, end, Scintilla, groupKey);; // And remove all the token info including the subindex from the snippet text // leaving only the key snippet = snippet.Remove(g.Index, 1).Remove(g.Index - 2 + g.Length - sg.Length, sg.Length + 1); } else { // We have a regular old SnippetLinkRange along the lines of $sometoken$ // We want the range's Key, which would be sometoken groupKey = g.Value.Substring(1, g.Value.Length - 2); // Now we need to determine the actual _start and _end positions of the range. // Keep in mind we'll be stripping out the 2 $ int start = startPos + g.Index; int end = start + g.Length - 2; // Now create the range object unindexedRangesToActivate.Add(new SnippetLinkRange(start, end, Scintilla, groupKey)); // And remove all the token info from the snippet text // leaving only the key snippet = snippet.Remove(g.Index, 1).Remove(g.Index + g.Length - 2, 1); } } // Any more matches? Note that I'm rerunning the regexp query // on the snippet string becuase it's contents have been modified // and we need to get the updated index values. m = snippetRegex1.Match(snippet); } // Replace the snippet Keyword with the snippet text. Or if this // isn't triggered by a shortcut, it will insert at the current // Caret Position Scintilla.GetRange(startPos, NativeScintilla.GetCurrentPos()).Text = snippet; // Now that we have the text set we can activate our link ranges // we couldn't do it before becuase they were managed ranges and // would get offset by the text change // Since we are done adding new SnippetLinkRanges we can tack // on the unindexed ranges to the _end of the indexed ranges SnippetLinkRange[] allLinks = new SnippetLinkRange[indexedRangesToActivate.Count + unindexedRangesToActivate.Count]; for (int i = 0; i < indexedRangesToActivate.Values.Count; i++) { allLinks[i] = indexedRangesToActivate[i]; } for (int i = 0; i < unindexedRangesToActivate.Count; i++) { allLinks[i + indexedRangesToActivate.Count] = unindexedRangesToActivate[i]; } foreach (SnippetLinkRange slr in allLinks) { addSnippetLink(slr); } foreach (SnippetLinkRange slr in allLinks) { slr.Init(); } // Now we need to activate the Snippet links. However we have a bit // of a styling confilct. If we set the indicator styles before the // SQL Lexer styles the newly added text it won't get styled. So to // make sure we set the Indicator Styles after we put the call on // a timer. if (_snippetLinks.Count > 0) { Timer t = new Timer(); t.Interval = 10; // Oh how I love anonymous delegates, this is starting to remind // me of JavaScript and SetTimeout... t.Tick += new EventHandler(delegate(object sender, EventArgs te) { t.Dispose(); IsActive = true; }); t.Start(); } // Add all the Drop markers in the indexed order. The // order is reversed of course because drop markers work // in a FILO manner for (int i = dropMarkers.Count - 1; i >= 0; i--) { Scintilla.DropMarkers.Drop(startPos + dropMarkers.Values[i]); } // Place the caret at either the position of the token or // at the _end of the snippet text. if (caretPos >= 0) { Scintilla.Caret.Goto(startPos + caretPos); } else { Scintilla.Caret.Goto(startPos + snippet.Length); } // Ahoy, way anchor! if (anchorPos >= 0) { Scintilla.Caret.Anchor = startPos + anchorPos; } // Do we have an _end cursor? if (endPos >= 0) { // If they have snippet link ranges activated in this snippet // go ahead and set up an EndPoint marker if (allLinks.Length > 0) { SnippetLinkEnd eci = new SnippetLinkEnd(endPos + startPos, Scintilla); Scintilla.ManagedRanges.Add(eci); _snippetLinks.EndPoint = eci; } else { // Otherwise we treat it like an Anchor command because // the SnippetLink mode isn't activated Scintilla.Caret.Goto(endPos + startPos); } } NativeScintilla.EndUndoAction(); }
public Range Search() { return(Search(_scintilla.GetRange())); }
public List <Range> SearchAll() { return(SearchAll(Scintilla.GetRange())); }