using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.ComponentModel;
namespace ScintillaNet
{
[TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class SnippetManager : ScintillaHelperBase
{
#region Private Member variables
private SnippetChooser _snipperChooser;
private Timer _snippetLinkTimer = new Timer();
private bool _pendingUndo = false;
private readonly Regex snippetRegex1 = new Regex(@"(?<dm>\�DropMarker(?<dmi>\[[0-9]*\])?\�)|(?<c>\�caret\�)|(?<a>\�anchor\�)|(?<e>\�end\�)|(?<s>\�selected\�)|(?<l>\�.+?(?<li>\[[0-9]*\])?\�)", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
private SnippetLinkCollection _snippetLinks = new SnippetLinkCollection();
#endregion
public SnippetManager(Scintilla scintilla)
: base(scintilla)
{
_list = new SnippetList(this);
_snippetLinkTimer.Interval = 1;
_snippetLinkTimer.Tick += new EventHandler(_snippetLinkTimer_Tick);
IsEnabled = _isEnabled;
}
internal void SetIndicators()
{
Scintilla.Indicators[_activeSnippetIndicator].Style = _activeSnippetIndicatorStyle;
Scintilla.Indicators[_activeSnippetIndicator].Color = _activeSnippetColor;
Scintilla.Indicators[_inactiveSnippetIndicator].Style = _inactiveSnippetIndicatorStyle;
Scintilla.Indicators[_inactiveSnippetIndicator].Color = _inactiveSnippetColor;
}
internal bool ShouldSerialize()
{
return ShouldSerializeActiveSnippetColor() ||
ShouldSerializeActiveSnippetIndicator() ||
ShouldSerializeActiveSnippetIndicatorStyle() ||
ShouldSerializeInactiveSnippetColor() ||
ShouldSerializeInactiveSnippetIndicator() ||
ShouldSerializeInactiveSnippetIndicatorStyle()||
ShouldSerializeIsOneKeySelectionEmbedEnabled() ||
ShouldSerializeIsOneKeySelectionEmbedEnabled() ||
ShouldSerializeDefaultDelimeter();
}
#region Public Methods
public bool NextSnippetRange()
{
// This would be a whole lot easier if I had the Command Contexts set
// up. The way it's working now is that this command will always execute
// irregardlessly of if the SnippetLinks are active. Since we may not have
// a valid context to execute we don't necessarily want to eat the
// keystroke in all circumstances, hence the bool return
if (!_snippetLinks.IsActive || Scintilla.AutoComplete.IsActive)
return false;
// OK So we want to find the next SnippetLink in
// whatever order they are in and then select it
// so that they can fill it out.
SnippetLink sl = _snippetLinks.NextActiveSnippetLink;
if (sl != null)
{
// However it is possible that all of this Snippet Links'
// ranges have been deleted by the user. If this is the case
// we need to remove this snippet link from the list and go
// to the next link.
while (sl.Ranges.Count == 0)
{
_snippetLinks.Remove(sl);
sl = _snippetLinks.NextActiveSnippetLink;
// No more snippet links? Nothing to do but quit
if (sl == null)
{
Scintilla.Commands.StopProcessingCommands = true;
return true;
}
}
// Yay we have it. Select the first Range in the Snippet Link's Series
sl.Ranges[0].Select();
Scintilla.Commands.StopProcessingCommands = true;
return true;
}
return false;
}
public bool PreviousSnippetRange()
{
// Same as NextSnippetRange but going in the opposite direction
if (!_snippetLinks.IsActive || Scintilla.AutoComplete.IsActive)
return false;
SnippetLink sl = _snippetLinks.PreviousActiveSnippetLink;
if (sl != null)
{
while (sl.Ranges.Count == 0)
{
_snippetLinks.Remove(sl);
sl = _snippetLinks.PreviousActiveSnippetLink;
if (sl == null)
{
Scintilla.Commands.StopProcessingCommands = true;
return true;
}
}
sl.Ranges[0].Select();
Scintilla.Commands.StopProcessingCommands = true;
return true;
}
return false;
}
public bool CancelActiveSnippets()
{
if (_snippetLinks.IsActive && !Scintilla.AutoComplete.IsActive)
{
IsActive = false;
Scintilla.Commands.StopProcessingCommands = true;
return true;
}
return false;
}
public bool AcceptActiveSnippets()
{
if (_snippetLinks.IsActive && !Scintilla.AutoComplete.IsActive)
{
int pos = Scintilla.Caret.Position;
bool end = false;
foreach (SnippetLink sl in _snippetLinks.Values)
{
foreach (SnippetLinkRange sr in sl.Ranges)
{
if (sr.PositionInRange(pos))
{
end = true;
break;
}
}
if (end)
break;
}
if (end)
{
cascadeSnippetLinkRangeChange(_snippetLinks.ActiveSnippetLink, _snippetLinks.ActiveRange);
if (_snippetLinks.EndPoint != null)
Scintilla.Caret.Goto(_snippetLinks.EndPoint.Start);
IsActive = false;
Scintilla.Commands.StopProcessingCommands = true;
return true;
}
}
return false;
}
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
if (pos <= 0 || Scintilla.NativeInterface.GetCharAt(pos - 1).ToString().IndexOfAny(Scintilla.Lexing.WhiteSpaceCharsArr) >= 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 void InsertSnippet(string shortcut)
{
Snippet snip;
if (!_list.TryGetValue(shortcut, out snip))
{
// Not a match. Buh-bye
return;
}
InsertSnippet(snip, Math.Min(NativeScintilla.GetCurrentPos(), NativeScintilla.GetAnchor()));
}
public void InsertSnippet(Snippet snip)
{
InsertSnippet(snip, Math.Min(NativeScintilla.GetCurrentPos(), NativeScintilla.GetAnchor()));
}
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 (true)
{
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();
}
#endregion
#region Event Handlers
private void _snippetLinkTimer_Tick(object sender, EventArgs e)
{
_snippetLinkTimer.Enabled = false;
Range sr = Scintilla.Selection.Range;
if (_snippetLinks.IsActive)
{
SnippetLink oldActiveSnippetLink = _snippetLinks.ActiveSnippetLink;
SnippetLinkRange oldActiveRange = _snippetLinks.ActiveRange;
if (oldActiveRange != null && (oldActiveRange.IntersectsWith(sr) || oldActiveRange.Equals(sr)))
{
Scintilla.BeginInvoke(new MethodInvoker(delegate()
{
cascadeSnippetLinkRangeChange(oldActiveSnippetLink, oldActiveRange);
foreach (SnippetLink sl in _snippetLinks.Values)
foreach (Range r in sl.Ranges)
{
if (sl == _snippetLinks.ActiveSnippetLink)
{
r.ClearIndicator(Scintilla.Snippets.InactiveSnippetIndicator);
r.SetIndicator(Scintilla.Snippets.ActiveSnippetIndicator);
}
else
{
r.SetIndicator(Scintilla.Snippets.InactiveSnippetIndicator);
r.ClearIndicator(Scintilla.Snippets.ActiveSnippetIndicator);
}
}
if (_pendingUndo)
{
_pendingUndo = false;
Scintilla.UndoRedo.EndUndoAction();
}
Scintilla.NativeInterface.Colourise(0, -1);
}));
}
}
}
private void Scintilla_TextInserted(object sender, TextModifiedEventArgs e)
{
// I'm going to have to look into making this a little less "sledge hammer to
// the entire documnet"ish
if (_snippetLinks.IsActive && (e.UndoRedoFlags.IsUndo || e.UndoRedoFlags.IsRedo))
Scintilla.NativeInterface.Colourise(0, -1);
}
private void Scintilla_BeforeTextInsert(object sender, TextModifiedEventArgs e)
{
if (_snippetLinks.IsActive && !_pendingUndo && !(e.UndoRedoFlags.IsUndo || e.UndoRedoFlags.IsRedo))
{
_pendingUndo = true;
Scintilla.UndoRedo.BeginUndoAction();
_snippetLinkTimer.Enabled = true;
}
}
private void Scintilla_BeforeTextDelete(object sender, TextModifiedEventArgs e)
{
if (!_isEnabled)
return;
if (_snippetLinks.IsActive && !_pendingUndo && !(e.UndoRedoFlags.IsUndo || e.UndoRedoFlags.IsRedo))
{
_pendingUndo = true;
Scintilla.UndoRedo.BeginUndoAction();
_snippetLinkTimer.Enabled = true;
}
ManagedRange undoneSnippetLinkRange = null;
if (e.UndoRedoFlags.IsUndo && _snippetLinks.IsActive)
{
foreach (ManagedRange mr in Scintilla.ManagedRanges)
{
if (mr.Start == e.Position && mr.Length == e.Length && mr.Length > 1)
{
undoneSnippetLinkRange = mr;
// Expanding the range So that it won't get marked for deletion
mr.End++;
}
}
}
// It's possible that the end point may have been deleted. The endpoint
// is an ultra persistent marker that cannot be deleted until the Snippet
// Link mode is deactivated. Place a new EndPoint at the begining of the
// deleted range.
if (_snippetLinks.IsActive && _snippetLinks.EndPoint != null && _snippetLinks.EndPoint.Scintilla == null)
{
SnippetLinkEnd eci = new SnippetLinkEnd(e.Position, Scintilla);
Scintilla.ManagedRanges.Add(eci);
_snippetLinks.EndPoint = eci;
}
// Now collapse the Undone range in preparation for the
// newly inserted text that will be put in here
if (undoneSnippetLinkRange != null)
undoneSnippetLinkRange.End = undoneSnippetLinkRange.Start;
// Check to see if all SnippetLink ranges have been deleted.
// If this is the case we need to turn Deactivate SnippetLink
// mode.
bool deactivate = true;
foreach (SnippetLink sl in _snippetLinks.Values)
{
if (sl.Ranges.Count > 0)
{
foreach (SnippetLinkRange slr in sl.Ranges)
{
if (slr.Scintilla != null)
{
deactivate = false;
break;
}
}
}
if (!deactivate)
break;
}
if (deactivate && IsActive)
IsActive = false;
}
private void Scintilla_SelectionChanged(object sender, EventArgs e)
{
Range sr = Scintilla.Selection.Range;
if (_snippetLinks.IsActive)
{
SnippetLink oldActiveSnippetLink = _snippetLinks.ActiveSnippetLink;
SnippetLinkRange oldActiveRange = _snippetLinks.ActiveRange;
_snippetLinks.ActiveSnippetLink = null;
_snippetLinks.ActiveRange = null;
for (int i = 0; i < _snippetLinks.Count; i++)
{
SnippetLink sl = _snippetLinks[i];
foreach (SnippetLinkRange r in sl.Ranges)
{
if (r.IntersectsWith(sr))
{
_snippetLinks.ActiveSnippetLink = sl;
_snippetLinks.ActiveRange = r;
break;
}
}
if (_snippetLinks.ActiveRange != null)
break;
}
foreach (SnippetLink sl in _snippetLinks.Values)
foreach (Range r in sl.Ranges)
{
if (sl == _snippetLinks.ActiveSnippetLink)
{
r.ClearIndicator(Scintilla.Snippets.InactiveSnippetIndicator);
r.SetIndicator(Scintilla.Snippets.ActiveSnippetIndicator);
}
else
{
r.SetIndicator(Scintilla.Snippets.InactiveSnippetIndicator);
r.ClearIndicator(Scintilla.Snippets.ActiveSnippetIndicator);
}
}
}
}
#endregion
#region IsOneKeySelectionEmbedEnabled
// Yeah I know this is a bit unwieldly but I can't come up with a better name
private bool _isOneKeySelectionEmbedEnabled = false;
public bool IsOneKeySelectionEmbedEnabled
{
get
{
return _isOneKeySelectionEmbedEnabled;
}
set
{
_isOneKeySelectionEmbedEnabled = value;
}
}
private bool ShouldSerializeIsOneKeySelectionEmbedEnabled()
{
return _isOneKeySelectionEmbedEnabled;
}
private void ResetIsOneKeySelectionEmbedEnabled()
{
_isOneKeySelectionEmbedEnabled = false;
}
#endregion
#region Private Methods
private void cascadeSnippetLinkRangeChange(SnippetLink oldActiveSnippetLink, SnippetLinkRange oldActiveRange)
{
Scintilla.ManagedRanges.Sort();
int offset = 0;
string newText = oldActiveRange.Text;
Scintilla.NativeInterface.SetModEventMask(0);
foreach (ManagedRange mr in Scintilla.ManagedRanges)
{
if (offset != 0)
mr.Change(mr.Start + offset, mr.End + offset);
SnippetLinkRange slr = mr as SnippetLinkRange;
if (slr == null || !oldActiveSnippetLink.Ranges.Contains(slr) || slr.Text == newText)
continue;
int oldLength = slr.Length;
slr.Text = newText;
slr.End += newText.Length - oldLength;
offset += newText.Length - oldLength;
}
Scintilla.NativeInterface.SetModEventMask(Constants.SC_MODEVENTMASKALL);
}
private SnippetLinkRange addSnippetLink(SnippetLinkRange range)
{
string key = range.Key;
SnippetLink sl = null;
for (int i = 0; i < _snippetLinks.Count; i++)
{
if (_snippetLinks[i].Key.Equals(key, StringComparison.CurrentCultureIgnoreCase))
{
sl = _snippetLinks[i];
break;
}
}
if (sl == null)
{
sl = new SnippetLink(key);
_snippetLinks.Add(sl);
}
sl.Ranges.Add(range);
range.Parent = sl.Ranges;
return range;
}
#endregion
#region Public Properties
#region Active
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsActive
{
get
{
return _snippetLinks.IsActive;
}
internal set
{
_snippetLinks.IsActive = value;
if (value)
{
SetIndicators();
_snippetLinks[0].Ranges[0].Select();
}
else
{
// Deactivating Snippet Link mode. First make sure all
// the snippet link ranges have their indicators cleared
foreach (SnippetLink sl in _snippetLinks.Values)
foreach (Range r in sl.Ranges)
{
r.ClearIndicator(Scintilla.Snippets.InactiveSnippetIndicator);
r.ClearIndicator(Scintilla.Snippets.ActiveSnippetIndicator);
}
// Then clear out the _snippetLinks list cuz we're done with them
_snippetLinks.Clear();
if (_snippetLinks.EndPoint != null)
{
_snippetLinks.EndPoint.Dispose();
_snippetLinks.EndPoint = null;
}
}
}
}
#endregion
#region ActiveSnippetColor
private Color _activeSnippetColor = Color.Lime;
public Color ActiveSnippetColor
{
get
{
return _activeSnippetColor;
}
set
{
_activeSnippetColor = value;
}
}
private bool ShouldSerializeActiveSnippetColor()
{
return _activeSnippetColor != Color.Lime;
}
private void ResetActiveSnippetColor()
{
_activeSnippetColor = Color.Lime;
}
#endregion
#region ActiveSnippetIndicator
private int _activeSnippetIndicator = 15;
public int ActiveSnippetIndicator
{
get
{
return _activeSnippetIndicator;
}
set
{
_activeSnippetIndicator = value;
}
}
private bool ShouldSerializeActiveSnippetIndicator()
{
return _activeSnippetIndicator != 15;
}
private void ResetActiveSnippetIndicator()
{
_activeSnippetIndicator = 15;
}
#endregion
#region ActiveSnippetIndicatorStyle
private IndicatorStyle _activeSnippetIndicatorStyle = IndicatorStyle.RoundBox;
public IndicatorStyle ActiveSnippetIndicatorStyle
{
get
{
return _activeSnippetIndicatorStyle;
}
set
{
_activeSnippetIndicatorStyle = value;
}
}
private bool ShouldSerializeActiveSnippetIndicatorStyle()
{
return _activeSnippetIndicatorStyle != IndicatorStyle.RoundBox;
}
private void ResetActiveSnippetIndicatorStyle()
{
_activeSnippetIndicatorStyle = IndicatorStyle.RoundBox;
}
#endregion
#region DefaultDelimeter
private char _defaultDelimeter = '$';
public char DefaultDelimeter
{
get
{
return _defaultDelimeter;
}
set
{
_defaultDelimeter = value;
}
}
private bool ShouldSerializeDefaultDelimeter()
{
return _defaultDelimeter != '$';
}
private void ResetDefaultDelimeter()
{
_defaultDelimeter = '$';
}
#endregion
#region IsEnabled
private bool _isEnabled = true;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool IsEnabled
{
get
{
return _isEnabled;
}
set
{
_isEnabled = value;
if (value)
{
Scintilla.TextInserted += new EventHandler<TextModifiedEventArgs>(Scintilla_TextInserted);
Scintilla.BeforeTextInsert += new EventHandler<TextModifiedEventArgs>(Scintilla_BeforeTextInsert);
Scintilla.BeforeTextDelete += new EventHandler<TextModifiedEventArgs>(Scintilla_BeforeTextDelete);
Scintilla.SelectionChanged += new EventHandler(Scintilla_SelectionChanged);
}
else
{
Scintilla.TextInserted -= new EventHandler<TextModifiedEventArgs>(Scintilla_TextInserted);
Scintilla.BeforeTextInsert -= new EventHandler<TextModifiedEventArgs>(Scintilla_BeforeTextInsert);
Scintilla.BeforeTextDelete -= new EventHandler<TextModifiedEventArgs>(Scintilla_BeforeTextDelete);
Scintilla.SelectionChanged -= new EventHandler(Scintilla_SelectionChanged);
}
}
}
private bool ShouldSerializeIsEnabled()
{
return !_isEnabled;
}
private void ResetIsEnabled()
{
_isEnabled = true;
}
#endregion
#region InactiveSnippetColor
private Color _inactiveSnippetColor = Color.Lime;
public Color InactiveSnippetColor
{
get
{
return _inactiveSnippetColor;
}
set
{
_inactiveSnippetColor = value;
}
}
private bool ShouldSerializeInactiveSnippetColor()
{
return _inactiveSnippetColor != Color.Lime;
}
private void ResetInactiveSnippetColor()
{
_inactiveSnippetColor = Color.Lime;
}
#endregion
#region InactiveSnippetIndicator
private int _inactiveSnippetIndicator = 16;
public int InactiveSnippetIndicator
{
get
{
return _inactiveSnippetIndicator;
}
set
{
_inactiveSnippetIndicator = value;
}
}
private bool ShouldSerializeInactiveSnippetIndicator()
{
return _inactiveSnippetIndicator != 16;
}
private void ResetInactiveSnippetIndicator()
{
_inactiveSnippetIndicator = 16;
}
#endregion
#region InactiveSnippetIndicatorStyle
private IndicatorStyle _inactiveSnippetIndicatorStyle = IndicatorStyle.Box;
public IndicatorStyle InactiveSnippetIndicatorStyle
{
get
{
return _inactiveSnippetIndicatorStyle;
}
set
{
_inactiveSnippetIndicatorStyle = value;
}
}
private bool ShouldSerializeInactiveSnippetIndicatorStyle()
{
return _inactiveSnippetIndicatorStyle != IndicatorStyle.Box;
}
private void ResetInactiveSnippetIndicatorStyle()
{
_inactiveSnippetIndicatorStyle = IndicatorStyle.Box;
}
#endregion
#region List
private SnippetList _list;
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SnippetList List
{
get
{
return _list;
}
set
{
_list = value;
}
}
#endregion
#endregion
public void ShowSnippetList()
{
if (_list.Count == 0)
return;
if (_snipperChooser == null)
{
_snipperChooser = new SnippetChooser();
_snipperChooser.Scintilla = Scintilla;
_snipperChooser.SnippetList = _list.ToString();
_snipperChooser.Scintilla.Controls.Add(_snipperChooser);
}
_snipperChooser.SnippetList = _list.ToString();
_snipperChooser.Show();
}
public void ShowSurroundWithList()
{
SnippetList sl = new SnippetList(null);
foreach (Snippet s in _list)
{
if (s.IsSurroundsWith)
sl.Add(s);
}
if (sl.Count == 0)
return;
if (_snipperChooser == null)
{
_snipperChooser = new SnippetChooser();
_snipperChooser.Scintilla = Scintilla;
_snipperChooser.SnippetList = _list.ToString();
_snipperChooser.Scintilla.Controls.Add(_snipperChooser);
}
_snipperChooser.SnippetList = sl.ToString();
_snipperChooser.Show();
}
}
}