Exemple #1
0
        private static bool IsMethod(ScintillaControl sci, string name)
        {
            if (!Regex.IsMatch(name, "^[a-z0-9_]+$", RegexOptions.IgnoreCase))
                return false;

            string line = sci.GetLine(sci.CurrentLine);
            string pattern = "\\bfunction\\s+" + Regex.Escape(name) + "\\s*\\(";
            return Regex.IsMatch(line, pattern);
        }
        private static int FindNewVarPosition(ScintillaControl sci, ClassModel inClass, MemberModel latest)
        {
            firstVar = false;
            // found a var?
            if ((latest.Flags & FlagType.Variable) > 0)
                return sci.PositionFromLine(latest.LineTo + 1) - ((sci.EOLMode == 0) ? 2 : 1);

            // add as first member
            int line = 0;
            int maxLine = sci.LineCount;
            if (inClass != null)
            {
                line = inClass.LineFrom;
                maxLine = inClass.LineTo;
            }
            else if (ASContext.Context.InPrivateSection) line = ASContext.Context.CurrentModel.PrivateSectionIndex;
            else maxLine = ASContext.Context.CurrentModel.PrivateSectionIndex;
            while (line < maxLine)
            {
                string text = sci.GetLine(line++);
                if (text.IndexOf('{') >= 0)
                {
                    firstVar = true;
                    return sci.PositionFromLine(line) - ((sci.EOLMode == 0) ? 2 : 1);
                }
            }
            return -1;
        }
        private static void GenerateVariableJob(GeneratorJobType job, ScintillaControl sci, MemberModel member,
            bool detach, ClassModel inClass)
        {
            int position = 0;
            MemberModel latest = null;
            bool isOtherClass = false;

            Visibility varVisi = job.Equals(GeneratorJobType.Variable) ? GetDefaultVisibility(inClass) : Visibility.Public;
            FlagType ft = job.Equals(GeneratorJobType.Constant) ? FlagType.Constant : FlagType.Variable;

            // evaluate, if the variable (or constant) should be generated in other class
            ASResult varResult = ASComplete.GetExpressionType(sci, sci.WordEndPosition(sci.CurrentPos, true));

            int contextOwnerPos = GetContextOwnerEndPos(sci, sci.WordStartPosition(sci.CurrentPos, true));
            MemberModel isStatic = new MemberModel();
            if (contextOwnerPos != -1)
            {
                ASResult contextOwnerResult = ASComplete.GetExpressionType(sci, contextOwnerPos);
                if (contextOwnerResult != null)
                {
                    if (contextOwnerResult.Member == null && contextOwnerResult.Type != null)
                    {
                        isStatic.Flags |= FlagType.Static;
                    }
                }
            }
            else if (member != null && (member.Flags & FlagType.Static) > 0)
            {
                isStatic.Flags |= FlagType.Static;
            }

            ASResult returnType = null;
            int lineNum = sci.CurrentLine;
            string line = sci.GetLine(lineNum);
            
            Match m = Regex.Match(line, "\\b" + Regex.Escape(contextToken) + "\\(");
            if (m.Success)
            {
                returnType = new ASResult();
                returnType.Type = ASContext.Context.ResolveType("Function", null);
            }
            else
            {
                m = Regex.Match(line, @"=\s*[^;\n\r}}]+");
                if (m.Success)
                {
                    int posLineStart = sci.PositionFromLine(lineNum);
                    if (posLineStart + m.Index >= sci.CurrentPos)
                    {
                        line = line.Substring(m.Index);
                        StatementReturnType rType = GetStatementReturnType(sci, inClass, line, posLineStart + m.Index);
                        if (rType != null)
                        {
                            returnType = rType.resolve;
                        }
                    }
                }
            }

            if (varResult.RelClass != null && !varResult.RelClass.IsVoid() && !varResult.RelClass.Equals(inClass))
            {
                AddLookupPosition();
                lookupPosition = -1;

                ASContext.MainForm.OpenEditableDocument(varResult.RelClass.InFile.FileName, false);
                sci = ASContext.CurSciControl;
                isOtherClass = true;

                FileModel fileModel = new FileModel();
                fileModel.Context = ASContext.Context;
                ASFileParser parser = new ASFileParser();
                parser.ParseSrc(fileModel, sci.Text);

                foreach (ClassModel cm in fileModel.Classes)
                {
                    if (cm.QualifiedName.Equals(varResult.RelClass.QualifiedName))
                    {
                        varResult.RelClass = cm;
                        break;
                    }
                }
                inClass = varResult.RelClass;

                ASContext.Context.UpdateContext(inClass.LineFrom);
            }

            latest = GetLatestMemberForVariable(job, inClass, varVisi, isStatic);
            
            // if we generate variable in current class..
            if (!isOtherClass && member == null)
            {
                detach = false;
                lookupPosition = -1;
                position = sci.WordStartPosition(sci.CurrentPos, true);
                sci.SetSel(position, sci.WordEndPosition(position, true));
            }
            else // if we generate variable in another class
            {
                if (latest != null)
                {
                    position = FindNewVarPosition(sci, inClass, latest);
                }
                else
                {
                    position = GetBodyStart(inClass.LineFrom, inClass.LineTo, sci);
                    detach = false;
                }
                if (position <= 0) return;
                sci.SetSel(position, position);
            }

            // if this is a constant, we assign a value to constant
            string returnTypeStr = null;
            string eventValue = null;
            if (job == GeneratorJobType.Constant && returnType == null)
            {
                isStatic.Flags |= FlagType.Static;
                eventValue = "String = \"" + Camelize(contextToken) + "\"";
            }
            else if (returnType != null)
            {
                ClassModel inClassForImport = null;
                if (returnType.InClass != null)
                {
                    inClassForImport = returnType.InClass;
                }
                else if (returnType.RelClass != null)
                {
                    inClassForImport = returnType.RelClass;
                }
                else
                {
                    inClassForImport = inClass;
                }
                List<String> imports = new List<string>();
                if (returnType.Member != null)
                {
                    if (returnType.Member.Type != ASContext.Context.Features.voidKey)
                    {
                        returnTypeStr = FormatType(GetShortType(returnType.Member.Type));
                        imports.Add(GetQualifiedType(returnType.Member.Type, inClassForImport));
                    }
                }
                else if (returnType != null && returnType.Type != null)
                {
                    returnTypeStr = FormatType(GetShortType(returnType.Type.QualifiedName));
                    imports.Add(GetQualifiedType(returnType.Type.QualifiedName, inClassForImport));
                }
                if (imports.Count > 0)
                {
                    position += AddImportsByName(imports, sci.LineFromPosition(position));
                    sci.SetSel(position, position);
                }
            }
            MemberModel newMember = NewMember(contextToken, isStatic, ft, varVisi);
            if (returnTypeStr != null)
            {
                newMember.Type = returnTypeStr;
            }
            else if (eventValue != null)
            {
                newMember.Type = eventValue;
            }
            GenerateVariable(newMember, position, detach);
        }
        private static void EventMetatag(ClassModel inClass, ScintillaControl sci, MemberModel member)
        {
            ASResult resolve = ASComplete.GetExpressionType(sci, sci.WordEndPosition(sci.CurrentPos, true));
            string line = sci.GetLine(inClass.LineFrom);
            int position = sci.PositionFromLine(inClass.LineFrom) + (line.Length - line.TrimStart().Length);

            string value = resolve.Member.Value;
            if (value != null)
            {
                if (value.StartsWith('\"'))
                {
                    value = value.Trim(new char[] { '"' });
                }
                else if (value.StartsWith('\''))
                {
                    value = value.Trim(new char[] { '\'' });
                }
            }
            else value = resolve.Member.Type;

            if (string.IsNullOrEmpty(value))
                return;

            Regex re1 = new Regex("'(?:[^'\\\\]|(?:\\\\\\\\)|(?:\\\\\\\\)*\\\\.{1})*'");
            Regex re2 = new Regex("\"(?:[^\"\\\\]|(?:\\\\\\\\)|(?:\\\\\\\\)*\\\\.{1})*\"");
            Match m1 = re1.Match(value);
            Match m2 = re2.Match(value);

            if (m1.Success || m2.Success)
            {
                Match m = null;
                if (m1.Success && m2.Success) m = m1.Index > m2.Index ? m2 : m1;
                else if (m1.Success) m = m1;
                else m = m2;
                value = value.Substring(m.Index + 1, m.Length - 2);
            }

            string template = TemplateUtils.GetTemplate("EventMetatag");
            template = TemplateUtils.ReplaceTemplateVariable(template, "Name", value);
            template = TemplateUtils.ReplaceTemplateVariable(template, "Type", contextParam);
            template += "\n$(Boundary)";

            AddLookupPosition();

            sci.CurrentPos = position;
            sci.SetSel(position, position);
            InsertCode(position, template, sci);
        }
Exemple #5
0
        /// <summary>
        /// Handles the incoming character
        /// </summary> 
		public static void OnChar(ScintillaControl sci, Int32 value)
		{
            if (cType == XMLType.Invalid || (sci.ConfigurationLanguage != "xml" && sci.ConfigurationLanguage != "html")) 
                return;
			XMLContextTag ctag;
			Int32 position = sci.CurrentPos;
            if (sci.BaseStyleAt(position) == 6 && value != '"')
                return; // in XML attribute

			Char c = ' ';
            DataEvent de;
			switch (value)
			{
				case 10:
                    // Shift+Enter to insert <BR/>
                    Int32 line = sci.LineFromPosition(position);
					if (Control.ModifierKeys == Keys.Shift)
					{
						ctag = GetXMLContextTag(sci, position);
						if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
						{
							int start = sci.PositionFromLine(line)-((sci.EOLMode == 0)? 2:1);
							sci.SetSel(start, position);
                            sci.ReplaceSel((PluginSettings.UpperCaseHtmlTags) ? "<BR/>" : "<br/>");
							sci.SetSel(start+5, start+5);
							return;
						}
					}
                    if (PluginSettings.SmartIndenter)
					{
                        // Get last non-empty line
						String text = "";
                        Int32 line2 = line - 1;
						while (line2 >= 0 && text.Length == 0)
						{
							text = sci.GetLine(line2).TrimEnd();
							line2--;
						}
						if ((text.EndsWith(">") && !text.EndsWith("?>") && !text.EndsWith("%>") && !closingTag.IsMatch(text)) || text.EndsWith("<!--") || text.EndsWith("<![CDATA["))
						{
                            // Get the previous tag
                            do
                            {
								position--;
								c = (Char)sci.CharAt(position);
							}
							while (position > 0 && c != '>');
							ctag = GetXMLContextTag(sci, c == '>' ? position + 1 : position);
							if ((Char)sci.CharAt(position-1) == '/') return;
                            // Insert blank line if we pressed Enter between a tag & it's closing tag
                            Int32 indent = sci.GetLineIndentation(line2 + 1);
							String checkStart = null;
                            bool subIndent = true;
							if (text.EndsWith("<!--")) { checkStart = "-->"; subIndent = false; }
                            else if (text.EndsWith("<![CDATA[")) { checkStart = "]]>"; subIndent = false; }
                            else if (ctag.Closed) subIndent = false;
                            else if (ctag.Name != null)
                            {
                                checkStart = "</" + ctag.Name;
                                if (ctag.Name.ToLower() == "script" || ctag.Name.ToLower() == "style") 
                                    subIndent = false;
                                if (ctag.Tag.IndexOf('\r') > 0 || ctag.Tag.IndexOf('\n') > 0)
                                    subIndent = false;
                            }
							if (checkStart != null)
							{
								text = sci.GetLine(line).TrimStart();
								if (text.StartsWith(checkStart))
								{
									sci.SetLineIndentation(line, indent);
									sci.InsertText(sci.PositionFromLine(line), LineEndDetector.GetNewLineMarker(sci.EOLMode));
								}
							}
                            // Indent the code
                            if (subIndent) indent += sci.Indent;
                            sci.SetLineIndentation(line, indent);
							position = sci.LineIndentPosition(line);
							sci.SetSel(position, position);
							return;
						}
					}
					break;
					
				case '<':
				case '/':
					if (value == '/')
					{
						if ((position < 2) || ((Char)sci.CharAt(position-2) != '<')) return;
                        ctag = new XMLContextTag();
                        ctag.Closing = true;
					}
					else 
					{
						ctag = GetXMLContextTag(sci, position);
						if (ctag.Tag != null) return;
					}
                    // Allow another plugin to handle this
                    de = new DataEvent(EventType.Command, "XMLCompletion.Element", ctag);
                    EventManager.DispatchEvent(PluginBase.MainForm, de);
                    if (de.Handled) return;

                    // New tag
                    if (PluginSettings.EnableXMLCompletion && cType == XMLType.Known)
					{
                        List<ICompletionListItem> items = new List<ICompletionListItem>();
						String previous = null;
                        foreach (string ns in namespaces)
                        {
                            items.Add(new NamespaceItem(ns));
                        }
                        foreach (HTMLTag tag in knownTags) 
						    if (tag.Name != previous && (tag.NS == "" || tag.NS == defaultNS)) 
                            {
							    items.Add( new HtmlTagItem(tag.Name, tag.Tag));
							    previous = tag.Name;
						    }
                        items.Sort(new ListItemComparer());
                        CompletionList.Show(items, true);
					}
					return;

                case ':':
                    ctag = GetXMLContextTag(sci, position);
                    if (ctag.NameSpace == null || position - ctag.Position > ctag.Name.Length + 2) return;
                    // Allow another plugin to handle this
                    de = new DataEvent(EventType.Command, "XMLCompletion.Namespace", ctag);
                    EventManager.DispatchEvent(PluginBase.MainForm, de);
                    if (de.Handled) return;

                    // Show namespace's tags
                    if (PluginSettings.EnableXMLCompletion && cType == XMLType.Known)
                    {
                        List<ICompletionListItem> items = new List<ICompletionListItem>();
                        String previous = null;
                        foreach (HTMLTag tag in knownTags)
                            if (tag.Name != previous && tag.NS == ctag.NameSpace)
                            {
                                items.Add(new HtmlTagItem(tag.Name, tag.Name));
                                previous = tag.Name;
                            }
                        CompletionList.Show(items, true);
                    }
                    return;

				case '>':
                    if (PluginSettings.CloseTags)
					{
						ctag = GetXMLContextTag(sci, position);
						if (ctag.Name != null && !ctag.Closed)
						{
                            // Allow another plugin to handle this
                            de = new DataEvent(EventType.Command, "XMLCompletion.CloseElement", ctag);
                            EventManager.DispatchEvent(PluginBase.MainForm, de);
                            if (de.Handled) return;

                            if (ctag.Closing) return;

							Boolean isLeaf = false;
							if (cType == XMLType.Known)
							foreach(HTMLTag tag in knownTags)
							{
								if (String.Compare(tag.Tag, ctag.Name, true) == 0)
								{
									isLeaf = tag.IsLeaf;
									break;
								}
							}
							if (isLeaf)
							{
								sci.SetSel(position-1,position);
								sci.ReplaceSel("/>");
								sci.SetSel(position+1, position+1);
							}
							else
							{
								String closeTag = "</"+ctag.Name+">";
								sci.ReplaceSel(closeTag);
								sci.SetSel(position, position);
							}
						}
					}
					return;
					
				case ' ':
					c = (char)sci.CharAt(position);
					if (c > 32 && c != '/' && c != '>' && c != '<') return;
					ctag = GetXMLContextTag(sci, position);
                    if (ctag.Tag != null)
                    {
                        if (InQuotes(ctag.Tag) || ctag.Tag.LastIndexOf('"') < ctag.Tag.LastIndexOf('=')) return;
                        // Allow another plugin to handle this
                        Object[] obj = new Object[] { ctag, "" };
                        de = new DataEvent(EventType.Command, "XMLCompletion.Attribute", obj);
                        EventManager.DispatchEvent(PluginBase.MainForm, de);
                        if (de.Handled) return;
                        
                        if (PluginSettings.EnableXMLCompletion && cType == XMLType.Known)
                        {
                            foreach (HTMLTag tag in knownTags)
                                if (String.Compare(tag.Tag, ctag.Name, true) == 0)
                                {
                                    List<ICompletionListItem> items = new List<ICompletionListItem>();
                                    String previous = null;
                                    foreach (String attr in tag.Attributes)
                                        if (attr != previous)
                                        {
                                            items.Add(new HtmlAttributeItem(attr));
                                            previous = attr;
                                        }
                                    CompletionList.Show(items, true);
                                    return;
                                }
                        }
                    }
                    /*else
                    {
                        if (Control.ModifierKeys == Keys.Shift)
                        {
                            sci.SetSel(position - 1, position);
                            sci.ReplaceSel("&nbsp;");
                        }
                    }*/
					return;
				
				case '=':
					if (PluginSettings.InsertQuotes)
					{
						ctag = GetXMLContextTag(sci, position);
						position = sci.CurrentPos-2;
						if (ctag.Tag != null && !ctag.Tag.StartsWith("<!") && !InQuotes(ctag.Tag) && (GetWordLeft(sci, ref position).Length > 0))
						{
							position = sci.CurrentPos;
							c = (Char)sci.CharAt(position);
							if (c > 32 && c != '>') sci.ReplaceSel("\"\" ");
							else sci.ReplaceSel("\"\"");
							sci.SetSel(position+1, position+1);
                            justInsertedQuotesAt = position+1;
                            // Allow another plugin to handle this
                            de = new DataEvent(EventType.Command, "XMLCompletion.AttributeValue", new XMLContextTag());
                            EventManager.DispatchEvent(PluginBase.MainForm, de);
						}
					}
					return;

                case '"':
                    ctag = GetXMLContextTag(sci, position);
                    if (position > 1 && ctag.Tag != null && !ctag.Tag.StartsWith("<!"))
                    {
                        // TODO  Colorize text change to highlight what's been done
                        if (justInsertedQuotesAt == position - 1)
                        {
                            justInsertedQuotesAt = -1;
                            c = (Char)sci.CharAt(position - 2);
                            if (c == '"' && (Char)sci.CharAt(position-2) == '"')
                            {
                                sci.SetSel(position - 2, position);
                                sci.ReplaceSel("\"");
                            }
                            // Allow another plugin to handle this
                            de = new DataEvent(EventType.Command, "XMLCompletion.AttributeValue", new XMLContextTag());
                            EventManager.DispatchEvent(PluginBase.MainForm, de);
                        }
                        else
                        {
                            c = (Char)sci.CharAt(position - 1);
                            if (c == '"' && (Char)sci.CharAt(position) == '"')
                            {
                                sci.SetSel(position - 1, position + 1);
                                sci.ReplaceSel("\"");
                            }
                        }
                    }
                    break;
					
				case '?':
				case '%':
					if (PluginSettings.CloseTags && position > 1)
					{
						ctag = GetXMLContextTag(sci, position-2);
						if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
						{
							if ((Char)sci.CharAt(position-2) == '<')
							{
								sci.ReplaceSel((Char)value + ">");
								sci.SetSel(position, position);
							}
						}
					}
					break;
				
				case '!':
                    if (PluginSettings.CloseTags && position > 1)
					{
						ctag = GetXMLContextTag(sci, position-2);
						if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
						{
							if ((Char)sci.CharAt(position-2) == '<')
							{
								CompletionList.Show(xmlBlocks, true);
							}
						}						
					}
					break;
			}
		}
        public static MemberModel GetTemplateBlockMember(ScintillaControl Sci, string blockTmpl)
        {
            if (string.IsNullOrEmpty(blockTmpl))
                return null;

            string firstLine = blockTmpl;
            int lineCount = 0;

            int index = blockTmpl.IndexOf('\n');
            if (index != -1)
            {
                firstLine = blockTmpl.Substring(0, index);
                lineCount = Regex.Matches(blockTmpl, "\n").Count;
            }

            int lineNum = 0;
            while (lineNum < Sci.LineCount)
            {
                string line = Sci.GetLine(lineNum);
                int funcBlockIndex = line.IndexOfOrdinal(firstLine);
                if (funcBlockIndex != -1)
                {
                    MemberModel latest = new MemberModel();
                    latest.LineFrom = lineNum;
                    latest.LineTo = lineNum;
                    latest.LineTo = lineNum + lineCount;
                    return latest;
                }
                lineNum++;
            }
            return null;
        }
        public static void ContextualGenerator(ScintillaControl Sci, List<ICompletionListItem> options)
        {
            if (ASContext.Context is ASContext) (ASContext.Context as ASContext).UpdateCurrentFile(false); // update model
            if ((ASContext.Context.CurrentClass.Flags & (FlagType.Enum | FlagType.TypeDef)) > 0) return;

            lookupPosition = -1;
            int position = Sci.CurrentPos;
            int style = Sci.BaseStyleAt(position);
            if (style == 19) // on keyword
                return;

            bool isNotInterface = (ASContext.Context.CurrentClass.Flags & FlagType.Interface) == 0;
            int line = Sci.LineFromPosition(position);
            contextToken = Sci.GetWordFromPosition(position);
            contextMatch = null;

            FoundDeclaration found = GetDeclarationAtLine(Sci, line);
            string text = Sci.GetLine(line);
            bool suggestItemDeclaration = false;

            if (isNotInterface && ASComplete.IsLiteralStyle(style))
            {
                ShowConvertToConst(found, options);
                return;
            }

            ASResult resolve = ASComplete.GetExpressionType(Sci, Sci.WordEndPosition(position, true));
            contextResolved = resolve;
            
            // ignore automatic vars (MovieClip members)
            if (isNotInterface
                && resolve.Member != null
                && (((resolve.Member.Flags & FlagType.AutomaticVar) > 0) || (resolve.InClass != null && resolve.InClass.QualifiedName == "Object")))
            {
                resolve.Member = null;
                resolve.Type = null;
            }

            if (isNotInterface && found.inClass != ClassModel.VoidClass && contextToken != null)
            {
                if (resolve.Member == null && resolve.Type != null
                    && (resolve.Type.Flags & FlagType.Interface) > 0) // implement interface
                {
                    contextParam = resolve.Type.Type;
                    ShowImplementInterface(found, options);
                    return;
                }

                if (resolve.Member != null && !ASContext.Context.CurrentClass.IsVoid()
                    && (resolve.Member.Flags & FlagType.LocalVar) > 0) // promote to class var
                {
                    contextMember = resolve.Member;
                    ShowPromoteLocalAndAddParameter(found, options);
                    return;
                }
            }
            
            if (contextToken != null && resolve.Member == null) // import declaration
            {
                if ((resolve.Type == null || resolve.Type.IsVoid() || !ASContext.Context.IsImported(resolve.Type, line)) && CheckAutoImport(found, options)) return;
                if (resolve.Type == null)
                {
                    suggestItemDeclaration = ASComplete.IsTextStyle(Sci.BaseStyleAt(position - 1));
                }
            }

            if (isNotInterface && found.member != null)
            {
                // private var -> property
                if ((found.member.Flags & FlagType.Variable) > 0 && (found.member.Flags & FlagType.LocalVar) == 0)
                {
                    // maybe we just want to import the member's non-imported type
                    Match m = Regex.Match(text, String.Format(patternVarDecl, found.member.Name, contextToken));
                    if (m.Success)
                    {
                        contextMatch = m;
                        ClassModel type = ASContext.Context.ResolveType(contextToken, ASContext.Context.CurrentModel);
                        if (type.IsVoid() && CheckAutoImport(found, options))
                            return;
                    }
                    ShowGetSetList(found, options);
                    return;
                }
                // inside a function
                else if ((found.member.Flags & (FlagType.Function | FlagType.Getter | FlagType.Setter)) > 0
                    && resolve.Member == null && resolve.Type == null)
                {
                    if (contextToken != null)
                    {
                        // "generate event handlers" suggestion
                        string re = String.Format(patternEvent, contextToken);
                        Match m = Regex.Match(text, re, RegexOptions.IgnoreCase);
                        if (m.Success)
                        {
                            contextMatch = m;
                            contextParam = CheckEventType(m.Groups["event"].Value);
                            ShowEventList(found, options);
                            return;
                        }
                        m = Regex.Match(text, String.Format(patternAS2Delegate, contextToken), RegexOptions.IgnoreCase);
                        if (m.Success)
                        {
                            contextMatch = m;
                            ShowDelegateList(found, options);
                            return;
                        }
                        // suggest delegate
                        if (ASContext.Context.Features.hasDelegates)
                        {
                            m = Regex.Match(text, @"([a-z0-9_.]+)\s*\+=\s*" + contextToken, RegexOptions.IgnoreCase);
                            if (m.Success)
                            {
                                int offset = Sci.PositionFromLine(Sci.LineFromPosition(position))
                                    + m.Groups[1].Index + m.Groups[1].Length;
                                resolve = ASComplete.GetExpressionType(Sci, offset);
                                if (resolve.Member != null)
                                    contextMember = ResolveDelegate(resolve.Member.Type, resolve.InFile);
                                contextMatch = m;
                                ShowDelegateList(found, options);
                                return;
                            }
                        }
                    }
                    else
                    {
                        // insert a default handler name, then "generate event handlers" suggestion
                        Match m = Regex.Match(text, String.Format(patternEvent, ""), RegexOptions.IgnoreCase);
                        if (m.Success)
                        {
                            int regexIndex = m.Index + Sci.PositionFromLine(Sci.CurrentLine);
                            GenerateDefaultHandlerName(Sci, position, regexIndex, m.Groups["event"].Value, true);
                            resolve = ASComplete.GetExpressionType(Sci, Sci.CurrentPos);
                            if (resolve.Member == null || (resolve.Member.Flags & FlagType.AutomaticVar) > 0)
                            {
                                contextMatch = m;
                                contextParam = CheckEventType(m.Groups["event"].Value);
                                ShowEventList(found, options);
                            }
                            return;
                        }

                        // insert default delegate name, then "generate delegate" suggestion
                        if (ASContext.Context.Features.hasDelegates)
                        {
                            m = Regex.Match(text, @"([a-z0-9_.]+)\s*\+=\s*", RegexOptions.IgnoreCase);
                            if (m.Success)
                            {
                                int offset = Sci.PositionFromLine(Sci.LineFromPosition(position))
                                        + m.Groups[1].Index + m.Groups[1].Length;
                                resolve = ASComplete.GetExpressionType(Sci, offset);
                                if (resolve.Member != null)
                                {
                                    contextMember = ResolveDelegate(resolve.Member.Type, resolve.InFile);
                                    string delegateName = resolve.Member.Name;
                                    if (delegateName.StartsWithOrdinal("on")) delegateName = delegateName.Substring(2);
                                    GenerateDefaultHandlerName(Sci, position, offset, delegateName, false);
                                    resolve = ASComplete.GetExpressionType(Sci, Sci.CurrentPos);
                                    if (resolve.Member == null || (resolve.Member.Flags & FlagType.AutomaticVar) > 0)
                                    {
                                        contextMatch = m;
                                        ShowDelegateList(found, options);
                                    }
                                    return;
                                }
                            }
                        }
                    }
                }

                // "Generate fields from parameters" suggestion
                if (found.member != null
                    && (found.member.Flags & FlagType.Function) > 0
                    && found.member.Parameters != null && (found.member.Parameters.Count > 0)
                    && resolve.Member != null && (resolve.Member.Flags & FlagType.ParameterVar) > 0)
                {
                    contextMember = resolve.Member;
                    ShowFieldFromParameter(found, options);
                    return;
                }

                // "add to interface" suggestion
                if (resolve.Member != null
                    && resolve.Member.Name == found.member.Name
                    && line == found.member.LineFrom
                    && ((found.member.Flags & FlagType.Function) > 0 
                            || (found.member.Flags & FlagType.Getter) > 0
                            || (found.member.Flags & FlagType.Setter) > 0)
                    && found.inClass != ClassModel.VoidClass
                    && found.inClass.Implements != null
                    && found.inClass.Implements.Count > 0)
                {
                    string funcName = found.member.Name;
                    FlagType flags = found.member.Flags & ~FlagType.Access;
                    
                    List<string> interfaces = new List<string>();
                    foreach (string interf in found.inClass.Implements)
                    {
                        bool skip = false;
                        ClassModel cm = ASContext.Context.ResolveType(interf, ASContext.Context.CurrentModel);
                        foreach (MemberModel m in cm.Members)
                        {
                            if (m.Name.Equals(funcName) && m.Flags.Equals(flags))
                            {
                                skip = true;
                                break;
                            }
                        }
                        if (!skip)
                        {
                            interfaces.Add(interf);
                        }
                    }
                    if (interfaces.Count > 0)
                    {
                        ShowAddInterfaceDefList(found, interfaces, options);
                        return;
                    }
                }

                // "assign var to statement" suggestion
                int curLine = Sci.CurrentLine;
                string ln = Sci.GetLine(curLine).TrimEnd();
                if (ln.Length > 0 && ln.IndexOf('=') == -1 
                    && ln.Length <= Sci.CurrentPos - Sci.PositionFromLine(curLine)) // cursor at end of line
                {
                    ShowAssignStatementToVarList(found, options);
                    return;
                }
            }
            
            // suggest generate constructor / toString
            if (isNotInterface && found.member == null && found.inClass != ClassModel.VoidClass && contextToken == null)
            {
                bool hasConstructor = false;
                bool hasToString = false;
                foreach (MemberModel m in ASContext.Context.CurrentClass.Members)
                {
                    if (!hasConstructor && (m.Flags & FlagType.Constructor) > 0)
                        hasConstructor = true;

                    if (!hasToString && (m.Flags & FlagType.Function) > 0 && m.Name.Equals("toString"))
                        hasToString = true;
                }

                if (!hasConstructor || !hasToString)
                {
                    ShowConstructorAndToStringList(found, hasConstructor, hasToString, options);
                    return;
                }
            }

            if (isNotInterface 
                && resolve.Member != null
                && resolve.Type != null
                && resolve.Type.QualifiedName == ASContext.Context.Features.stringKey
                && found.inClass != ClassModel.VoidClass)
            {
                int lineStartPos = Sci.PositionFromLine(Sci.CurrentLine);
                string lineStart = text.Substring(0, Sci.CurrentPos - lineStartPos);
                Match m = Regex.Match(lineStart, String.Format(@"new\s+(?<event>\w+)\s*\(\s*\w+", lineStart));
                if (m.Success)
                {
                    Group g = m.Groups["event"];
                    ASResult eventResolve = ASComplete.GetExpressionType(Sci, lineStartPos + g.Index + g.Length);
                    if (eventResolve != null && eventResolve.Type != null)
                    {
                        ClassModel aType = eventResolve.Type;
                        aType.ResolveExtends();
                        while (!aType.IsVoid() && aType.QualifiedName != "Object")
                        {
                            if (aType.QualifiedName == "flash.events.Event")
                            {
                                contextParam = eventResolve.Type.QualifiedName;
                                ShowEventMetatagList(found, options);
                                return;
                            }
                            aType = aType.Extends;
                        }
                    }
                }
            }
            
            // suggest declaration
            if (contextToken != null)
            {
                if (suggestItemDeclaration)
                {
                    Match m = Regex.Match(text, String.Format(patternClass, contextToken));
                    if (m.Success)
                    {
                        contextMatch = m;
                        ShowNewClassList(found, options);
                    }
                    else if (!found.inClass.IsVoid())
                    {
                        m = Regex.Match(text, String.Format(patternMethod, contextToken));
                        if (m.Success)
                        {
                            contextMatch = m;
                            ShowNewMethodList(found, options);
                        }
                        else ShowNewVarList(found, options);
                    }
                }
                else
                {
                    if (resolve != null
                        && resolve.InClass != null
                        && resolve.InClass.InFile != null
                        && resolve.Member != null
                        && (resolve.Member.Flags & FlagType.Function) > 0
                        && File.Exists(resolve.InClass.InFile.FileName)
                        && !resolve.InClass.InFile.FileName.StartsWithOrdinal(PathHelper.AppDir))
                    {
                        Match m = Regex.Match(text, String.Format(patternMethodDecl, contextToken));
                        Match m2 = Regex.Match(text, String.Format(patternMethod, contextToken));
                        if (!m.Success && m2.Success)
                        {
                            contextMatch = m;
                            ShowChangeMethodDeclList(found, options);
                        }
                    }
                    else if (resolve != null
                        && resolve.Type != null
                        && resolve.Type.InFile != null
                        && resolve.RelClass != null
                        && File.Exists(resolve.Type.InFile.FileName)
                        && !resolve.Type.InFile.FileName.StartsWithOrdinal(PathHelper.AppDir))
                    {
                        Match m = Regex.Match(text, String.Format(patternClass, contextToken));
                        if (m.Success)
                        {
                            contextMatch = m;
                            ShowChangeConstructorDeclList(found, options);
                        }
                    }
                }
            }
            // TODO: Empty line, show generators list? yep
        }
        public static bool RenameMember(ScintillaControl Sci, MemberModel member, string newName)
        {
            ContextFeatures features = ASContext.Context.Features;
            string kind = features.varKey;

            if ((member.Flags & FlagType.Getter) > 0)
                kind = features.getKey;
            else if ((member.Flags & FlagType.Setter) > 0)
                kind = features.setKey;
            else if (member.Flags == FlagType.Function)
                kind = features.functionKey;

            Regex reMember = new Regex(String.Format(@"{0}\s+({1})[\s:]", kind, member.Name));

            string line;
            Match m;
            int index, position;
            for (int i = member.LineFrom; i <= member.LineTo; i++)
            {
                line = Sci.GetLine(i);
                m = reMember.Match(line);
                if (m.Success)
                {
                    index = Sci.MBSafeTextLength(line.Substring(0, m.Groups[1].Index));
                    position = Sci.PositionFromLine(i) + index;
                    Sci.SetSel(position, position + member.Name.Length);
                    Sci.ReplaceSel(newName);
                    UpdateLookupPosition(position, 1);
                    return true;
                }
            }
            return false;
        }
        internal void OnCharAdded(ScintillaControl sci, int position, int value)
        {
            if (!enabled) return;

            bool autoInsert = false;

            char c = (char)value;
            if (wordChars.IndexOf(c) < 0)
            {
                if (c == ':')
                {
                    if (lastColonInsert == position - 1)
                    {
                        sci.DeleteBack();
                        lastColonInsert = -1;
                        return;
                    }
                }
                else if (c == ';')
                {
                    char c2 = (char)sci.CharAt(position);
                    if (c2 == ';')
                    {
                        sci.DeleteBack();
                        sci.SetSel(position, position);
                        return;
                    }
                }
                else if (c == '\n' && !settings.DisableAutoCloseBraces)
                {
                    int line = sci.LineFromPosition(position);
                    string text = sci.GetLine(line - 1).TrimEnd();
                    if (text.EndsWith("{")) AutoCloseBrace(sci, line);
                }
                else if (c == '\t') // TODO get tab notification!
                {
                    position--;
                    autoInsert = true;
                }
                else return;
            }

            var context = GetContext(sci, position);
            var mode = CompleteMode.None;

            if (context.InComments) return;
            else if (context.InBlock)
            {
                if (context.Word == "-") mode = CompleteMode.Prefix;
                else if (context.Word.Length >= 2 || (char)value == '-')
                    mode = CompleteMode.Attribute;
            }
            else if (context.InValue)
            {
                if (features.Mode != "CSS" && c == features.Trigger)
                {
                    context.Word = context.Word.Substring(1);
                    context.Position++;
                    mode = CompleteMode.Variable;
                }
                else if (context.Word.Length == 1 && "abcdefghijklmnopqrstuvwxyz".IndexOf(context.Word[0]) >= 0)
                    mode = CompleteMode.Value;
            }
            else if (c == ':' && !context.IsVar) mode = CompleteMode.Pseudo;

            HandleCompletion(mode, context, autoInsert, true);
        }
 private List<CssBlock> ParseBlocks(ScintillaControl sci)
 {
     List<CssBlock> blocks = new List<CssBlock>();
     blocks.Clear();
     int lines = sci.LineCount;
     int inString = 0;
     bool inComment = false;
     CssBlock block = null;
     for (int i = 0; i < lines; i++)
     {
         string line = sci.GetLine(i);
         int len = line.Length;
         int safeLen = len - 1;
         for (int j = 0; j < len; j++)
         {
             char c = line[j];
             if (inComment)
             {
                 if (c == '*' && j < safeLen && line[j + 1] == '/') inComment = false;
                 else continue;
             }
             else if (inString > 0)
             {
                 if (inString == 1 && c == '\'') inString = 0;
                 else if (inString == 2 && c == '"') inString = 0;
                 else continue;
             }
             else if (c == '\'') inString = 1;
             else if (c == '"') inString = 2;
             else if (c == '/' && j < safeLen && line[j + 1] == '/')
                 break;
             else if (c == '/' && j < safeLen && line[j + 1] == '*')
                 inComment = true;
             else if (c == '{')
             {
                 CssBlock parent = block;
                 block = new CssBlock();
                 block.LineFrom = i;
                 block.ColFrom = j;
                 if (parent != null)
                 {
                     block.Parent = parent;
                     parent.Children.Add(block);
                 }
                 else blocks.Add(block);
             }
             else if (c == '}')
             {
                 if (block != null)
                 {
                     block.LineTo = i;
                     block.ColTo = j;
                     block = block.Parent;
                     if (block != null)
                     {
                         block.LineTo = i;
                         block.ColTo = j;
                     }
                 }
             }
         }
     }
     return blocks;
 }
 private bool IsVarDecl(ScintillaControl sci, int i)
 {
     if (features.Pattern == null) return false;
     int line = sci.LineFromPosition(i);
     string text = sci.GetLine(line);
     return features.Pattern.IsMatch(text);
 }
Exemple #12
0
 /// <summary>
 /// Convert multibyte column to byte length
 /// </summary>
 private int MBSafeColumn(ScintillaControl sci, int line, int length)
 {
     String text = sci.GetLine(line) ?? "";
     length = Math.Min(length, text.Length);
     return sci.MBSafeTextLength(text.Substring(0, length));
 }
Exemple #13
0
 private static bool IsMethoDecl(ScintillaControl sci)
 {
     string line = sci.GetLine(sci.CurrentLine);
     return Regex.IsMatch(line, "\\bfunction\\b");
 }
Exemple #14
0
 private static bool IsMethodBodyStart(ScintillaControl sci)
 {
     string line = sci.GetLine(sci.CurrentLine);
     int openBrace = line.LastIndexOf('{');
     return openBrace > 0 && openBrace > line.LastIndexOf('}') && openBrace > line.LastIndexOf(')');
 }
Exemple #15
0
 private static bool RemoveOneLocalDeclaration(ScintillaControl sci, MemberModel contextMember)
 {
     string type = "";
     if (contextMember.Type != null && (contextMember.Flags & FlagType.Inferred) == 0)
     {
         type = FormatType(contextMember.Type);
         if (type.IndexOf('*') > 0)
             type = type.Replace("/*", @"/\*\s*").Replace("*/", @"\s*\*/");
         type = @":\s*" + type;
     }
     Regex reDecl = new Regex(String.Format(@"[\s\(]((var|const)\s+{0}\s*{1})\s*", contextMember.Name, type));
     for (int i = contextMember.LineFrom; i <= contextMember.LineTo + 10; i++)
     {
         string text = sci.GetLine(i);
         Match m = reDecl.Match(text);
         if (m.Success)
         {
             int index = sci.MBSafeTextLength(text.Substring(0, m.Groups[1].Index));
             int position = sci.PositionFromLine(i) + index;
             int len = sci.MBSafeTextLength(m.Groups[1].Value);
             sci.SetSel(position, position + len);
             if (contextMember.Type == null || (contextMember.Flags & FlagType.Inferred) != 0) sci.ReplaceSel(contextMember.Name + " ");
             else sci.ReplaceSel(contextMember.Name);
             UpdateLookupPosition(position, contextMember.Name.Length - len);
             return true;
         }
     }
     return false;
 }
        /// <summary>
        /// Add closing brace to a code block.
        /// If enabled, move the starting brace to a new line.
        /// </summary>
        /// <param name="Sci"></param>
        /// <param name="txt"></param>
        /// <param name="line"></param>
        public static void AutoCloseBrace(ScintillaControl Sci, int line)
        {
            // find matching brace
            int bracePos = Sci.LineEndPosition(line - 1) - 1;
            while ((bracePos > 0) && (Sci.CharAt(bracePos) != '{')) bracePos--;
            if (bracePos == 0 || Sci.BaseStyleAt(bracePos) != 5) return;
            int match = Sci.SafeBraceMatch(bracePos);
            int start = line;
            int indent = Sci.GetLineIndentation(start - 1);
            if (match > 0)
            {
                int endIndent = Sci.GetLineIndentation(Sci.LineFromPosition(match));
                if (endIndent + Sci.TabWidth > indent)
                    return;
            }

            // find where to include the closing brace
            int startIndent = indent;
            int count = Sci.LineCount;
            int lastLine = line;
            int position;
            string txt = Sci.GetLine(line).Trim();
            line++;
            int eolMode = Sci.EOLMode;
            string NL = LineEndDetector.GetNewLineMarker(eolMode);

            if (txt.Length > 0 && ")]};,".IndexOf(txt[0]) >= 0)
            {
                Sci.BeginUndoAction();
                try
                {
                    position = Sci.CurrentPos;
                    Sci.InsertText(position, NL + "}");
                    Sci.SetLineIndentation(line, startIndent);
                }
                finally
                {
                    Sci.EndUndoAction();
                }
                return;
            }
            else
            {
                while (line < count - 1)
                {
                    txt = Sci.GetLine(line).TrimEnd();
                    if (txt.Length != 0)
                    {
                        indent = Sci.GetLineIndentation(line);
                        if (indent <= startIndent) break;
                        lastLine = line;
                    }
                    else break;
                    line++;
                }
            }
            if (line >= count - 1) lastLine = start;

            // insert closing brace
            Sci.BeginUndoAction();
            try
            {
                position = Sci.LineEndPosition(lastLine);
                Sci.InsertText(position, NL + "}");
                Sci.SetLineIndentation(lastLine + 1, startIndent);
            }
            finally
            {
                Sci.EndUndoAction();
            }
        }
Exemple #17
0
        public static bool MakePrivate(ScintillaControl Sci, MemberModel member, ClassModel inClass)
        {
            ContextFeatures features = ASContext.Context.Features;
            string visibility = GetPrivateKeyword(inClass);
            if (features.publicKey == null || visibility == null) return false;
            Regex rePublic = new Regex(String.Format(@"\s*({0})\s+", features.publicKey));

            string line;
            Match m;
            int index, position;
            for (int i = member.LineFrom; i <= member.LineTo; i++)
            {
                line = Sci.GetLine(i);
                m = rePublic.Match(line);
                if (m.Success)
                {
                    index = Sci.MBSafeTextLength(line.Substring(0, m.Groups[1].Index));
                    position = Sci.PositionFromLine(i) + index;
                    Sci.SetSel(position, position + features.publicKey.Length);
                    Sci.ReplaceSel(visibility);
                    UpdateLookupPosition(position, features.publicKey.Length - visibility.Length);
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// Handles the incoming character
        /// </summary> 
        public static void OnChar(ScintillaControl sci, Int32 value)
        {
            if (cType == XMLType.Invalid || (sci.ConfigurationLanguage != "xml" && sci.ConfigurationLanguage != "html")) 
                return;
            XMLContextTag ctag;
            Int32 position = sci.CurrentPos;
            if (sci.BaseStyleAt(position) == 6 && value != '"')
                return; // in XML attribute

            Char c = ' ';
            DataEvent de;
            switch (value)
            {
                case 10:
                    // Shift+Enter to insert <BR/>
                    Int32 line = sci.LineFromPosition(position);
                    if (Control.ModifierKeys == Keys.Shift)
                    {
                        ctag = GetXMLContextTag(sci, position);
                        if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
                        {
                            int start = sci.PositionFromLine(line)-((sci.EOLMode == 0)? 2:1);
                            sci.SetSel(start, position);
                            sci.ReplaceSel((PluginSettings.UpperCaseHtmlTags) ? "<BR/>" : "<br/>");
                            sci.SetSel(start+5, start+5);
                            return;
                        }
                    }
                    if (PluginSettings.SmartIndenter)
                    {
                        // There is no standard for XML formatting, although most IDEs have similarities. We are mostly going with Visual Studio style with slight differences.
                        // Get last non-empty line.
                        String text = "";
                        Int32 line2 = line - 1;
                        while (line2 >= 0 && text.Length == 0)
                        {
                            text = sci.GetLine(line2).TrimEnd();
                            line2--;
                        }
                        if ((text.EndsWith(">") && !text.EndsWith("?>") && !text.EndsWith("%>")) || text.EndsWith("<!--") || text.EndsWith("<![CDATA["))
                        {
                            // Get the previous tag.
                            do
                            {
                                position--;
                                c = (Char)sci.CharAt(position);
                            }
                            while (position > 0 && c != '>');
                            ctag = GetXMLContextTag(sci, c == '>' ? position + 1 : position);
                            // Line indentation.
                            Int32 indent = sci.GetLineIndentation(line2 + 1);

                            String checkStart = null;
                            bool subIndent = true;
                            if (text.EndsWith("<!--")) { checkStart = "-->"; subIndent = false; }
                            else if (text.EndsWith("<![CDATA[")) { checkStart = "]]>"; subIndent = false; }
                            else if (ctag.Closed || ctag.Closing)
                            {
                                //Closed tag. Look for the nearest open and not closed tag for proper indentation
                                subIndent = false;
                                if (ctag.Name != null)
                                {
                                    var tmpTags = new Stack<XMLContextTag>();
                                    var tmpTag = ctag;

                                    if (!tmpTag.Closed) tmpTags.Push(tmpTag);
                                    while (tmpTag.Position != 0)
                                    {
                                        tmpTag = GetXMLContextTag(sci, tmpTag.Position);
                                        if (tmpTag.Tag != null && tmpTag.Name != null)
                                        {
                                            if (tmpTag.Closed) 
                                                continue;
                                            else if (tmpTag.Closing)
                                            {
                                                tmpTags.Push(tmpTag);
                                            }
                                            else
                                            {
                                                if (tmpTags.Count > 0 && tmpTags.Peek().Name == tmpTag.Name)
                                                    tmpTags.Pop();
                                                else
                                                    break;
                                            }
                                        }
                                    }
                                    if (tmpTags.Count > 0)
                                        indent = sci.GetLineIndentation(sci.LineFromPosition(tmpTags.Pop().Position));
                                    else if (tmpTag.Name != null)
                                    {
                                        subIndent = true;
                                        checkStart = "</" + tmpTag.Name;
                                        indent = sci.GetLineIndentation(sci.LineFromPosition(tmpTag.Position));
                                    }
                                    else
                                    {
                                        indent = sci.GetLineIndentation(sci.LineFromPosition(tmpTag.Position));
                                    }
                                }
                            }
                            else if (ctag.Name != null)
                            {
                                // Indentation. Some IDEs use the tag position, VS uses the tag start line indentation. 
                                indent = sci.GetLineIndentation(sci.LineFromPosition(ctag.Position));
                                checkStart = "</" + ctag.Name;
                                if (ctag.Name.ToLower() == "script" || ctag.Name.ToLower() == "style") 
                                    subIndent = false;
                            }
                            try
                            {
                                sci.BeginUndoAction();
                                if (checkStart != null)
                                {
                                    text = sci.GetLine(line).TrimStart();
                                    if (text.StartsWith(checkStart))
                                    {
                                        sci.SetLineIndentation(line, indent);
                                        sci.InsertText(sci.PositionFromLine(line), LineEndDetector.GetNewLineMarker(sci.EOLMode));
                                    }
                                }
                                // Indent the code
                                if (subIndent) indent += sci.Indent;
                                sci.SetLineIndentation(line, indent);
                                position = sci.LineIndentPosition(line);
                                sci.SetSel(position, position);
                            }
                            finally { sci.EndUndoAction(); }
                            return;
                        }
                        else if (!text.EndsWith(">"))
                        {
                            ctag = GetXMLContextTag(sci, sci.CurrentPos);
                            if (ctag.Tag == null || ctag.Name == null) return;
                            // We're inside a tag. Visual Studio indents with regards to the first line, other IDEs indent using the indentation of the last line with text.
                            int indent;
                            string tag = (ctag.Tag.IndexOf('\r') > 0 || ctag.Tag.IndexOf('\n') > 0) ? ctag.Tag.Substring(0, ctag.Tag.IndexOfAny(new[] {'\r', '\n'})).TrimEnd() : ctag.Tag.TrimEnd();
                            if (tag.EndsWith("\""))
                            {
                                int i;
                                int l = tag.Length;
                                for (i = ctag.Name.Length + 1; i < l; i++)
                                {
                                    if (!char.IsWhiteSpace(tag[i]))
                                        break;
                                }
                                indent = sci.Column(ctag.Position) + sci.MBSafePosition(i);
                            }
                            else
                            {
                                indent = sci.GetLineIndentation(sci.LineFromPosition(ctag.Position)) + sci.Indent;
                            }

                            sci.SetLineIndentation(line, indent);
                            position = sci.LineIndentPosition(line);
                            sci.SetSel(position, position);
                            return;
                        }
                    }
                    break;
                    
                case '<':
                case '/':
                    if (value == '/')
                    {
                        if ((position < 2) || ((Char)sci.CharAt(position-2) != '<')) return;
                        ctag = new XMLContextTag();
                        ctag.Position = position - 2;
                        ctag.Closing = true;
                    }
                    else 
                    {
                        ctag = GetXMLContextTag(sci, position);
                        if (ctag.Tag != null) return;
                    }
                    // Allow another plugin to handle this
                    de = new DataEvent(EventType.Command, "XMLCompletion.Element", ctag);
                    EventManager.DispatchEvent(PluginBase.MainForm, de);
                    if (de.Handled) return;

                    // New tag
                    if (PluginSettings.EnableXMLCompletion && cType == XMLType.Known)
                    {
                        List<ICompletionListItem> items = new List<ICompletionListItem>();
                        String previous = null;
                        foreach (string ns in namespaces)
                        {
                            items.Add(new NamespaceItem(ns));
                        }
                        foreach (HTMLTag tag in knownTags) 
                            if (tag.Name != previous && (tag.NS == "" || tag.NS == defaultNS)) 
                            {
                                items.Add( new HtmlTagItem(tag.Name, tag.Tag));
                                previous = tag.Name;
                            }
                        items.Sort(new ListItemComparer());
                        CompletionList.Show(items, true);
                    }
                    return;

                case ':':
                    ctag = GetXMLContextTag(sci, position);
                    if (ctag.NameSpace == null || position - ctag.Position > ctag.Name.Length + 2) return;
                    // Allow another plugin to handle this
                    de = new DataEvent(EventType.Command, "XMLCompletion.Namespace", ctag);
                    EventManager.DispatchEvent(PluginBase.MainForm, de);
                    if (de.Handled) return;

                    // Show namespace's tags
                    if (PluginSettings.EnableXMLCompletion && cType == XMLType.Known)
                    {
                        List<ICompletionListItem> items = new List<ICompletionListItem>();
                        String previous = null;
                        foreach (HTMLTag tag in knownTags)
                            if (tag.Name != previous && tag.NS == ctag.NameSpace)
                            {
                                items.Add(new HtmlTagItem(tag.Name, tag.Name));
                                previous = tag.Name;
                            }
                        CompletionList.Show(items, true);
                    }
                    return;

                case '>':
                    if (PluginSettings.CloseTags)
                    {
                        ctag = GetXMLContextTag(sci, position);
                        if (ctag.Name != null && !ctag.Closed)
                        {
                            // Allow another plugin to handle this
                            de = new DataEvent(EventType.Command, "XMLCompletion.CloseElement", ctag);
                            EventManager.DispatchEvent(PluginBase.MainForm, de);
                            if (de.Handled) return;

                            if (ctag.Closing) return;

                            Boolean isLeaf = false;
                            if (cType == XMLType.Known)
                            foreach(HTMLTag tag in knownTags)
                            {
                                if (String.Compare(tag.Tag, ctag.Name, true) == 0)
                                {
                                    isLeaf = tag.IsLeaf;
                                    break;
                                }
                            }
                            if (isLeaf)
                            {
                                sci.SetSel(position-1,position);
                                sci.ReplaceSel("/>");
                                sci.SetSel(position+1, position+1);
                            }
                            else
                            {
                                String closeTag = "</"+ctag.Name+">";
                                sci.ReplaceSel(closeTag);
                                sci.SetSel(position, position);
                            }
                        }
                    }
                    return;
                    
                case ' ':
                    c = (char)sci.CharAt(position);
                    if (c > 32 && c != '/' && c != '>' && c != '<') return;
                    ctag = GetXMLContextTag(sci, position);
                    if (ctag.Tag != null)
                    {
                        if (InQuotes(ctag.Tag) || ctag.Tag.LastIndexOf('"') < ctag.Tag.LastIndexOf('=')) return;
                        // Allow another plugin to handle this
                        Object[] obj = new Object[] { ctag, "" };
                        de = new DataEvent(EventType.Command, "XMLCompletion.Attribute", obj);
                        EventManager.DispatchEvent(PluginBase.MainForm, de);
                        if (de.Handled) return;
                        
                        if (PluginSettings.EnableXMLCompletion && cType == XMLType.Known)
                        {
                            foreach (HTMLTag tag in knownTags)
                                if (String.Compare(tag.Tag, ctag.Name, true) == 0)
                                {
                                    List<ICompletionListItem> items = new List<ICompletionListItem>();
                                    String previous = null;
                                    foreach (String attr in tag.Attributes)
                                        if (attr != previous)
                                        {
                                            items.Add(new HtmlAttributeItem(attr));
                                            previous = attr;
                                        }
                                    CompletionList.Show(items, true);
                                    return;
                                }
                        }
                    }
                    /*else
                    {
                        if (Control.ModifierKeys == Keys.Shift)
                        {
                            sci.SetSel(position - 1, position);
                            sci.ReplaceSel("&nbsp;");
                        }
                    }*/
                    return;
                
                case '=':
                    if (PluginSettings.InsertQuotes)
                    {
                        ctag = GetXMLContextTag(sci, position);
                        position = sci.CurrentPos-2;
                        if (ctag.Tag != null && !String.IsNullOrEmpty(ctag.Name) && Char.IsLetter(ctag.Name[0]) 
                            && !InQuotes(ctag.Tag) && (GetWordLeft(sci, ref position).Length > 0))
                        {
                            position = sci.CurrentPos;
                            c = (Char)sci.CharAt(position);
                            if (c > 32 && c != '>') sci.ReplaceSel("\"\" ");
                            else sci.ReplaceSel("\"\"");
                            sci.SetSel(position+1, position+1);
                            justInsertedQuotesAt = position+1;
                            // Allow another plugin to handle this
                            de = new DataEvent(EventType.Command, "XMLCompletion.AttributeValue", new Object[] { ctag, string.Empty });
                            EventManager.DispatchEvent(PluginBase.MainForm, de);
                        }
                    }
                    return;

                case '"':
                    ctag = GetXMLContextTag(sci, position);
                    if (position > 1 && ctag.Tag != null && !ctag.Tag.StartsWith("<!"))
                    {
                        // TODO  Colorize text change to highlight what's been done
                        if (justInsertedQuotesAt == position - 1)
                        {
                            justInsertedQuotesAt = -1;
                            c = (Char)sci.CharAt(position - 2);
                            if (c == '"' && (Char)sci.CharAt(position-2) == '"')
                            {
                                sci.SetSel(position - 2, position);
                                sci.ReplaceSel("\"");
                            }
                            // Allow another plugin to handle this
                            de = new DataEvent(EventType.Command, "XMLCompletion.AttributeValue", new Object[] {ctag, string.Empty});
                            EventManager.DispatchEvent(PluginBase.MainForm, de);
                        }
                        else
                        {
                            c = (Char)sci.CharAt(position - 1);
                            if (c == '"' && (Char)sci.CharAt(position) == '"')
                            {
                                sci.SetSel(position - 1, position + 1);
                                sci.ReplaceSel("\"");
                            }
                        }
                    }
                    break;
                    
                case '?':
                case '%':
                    if (PluginSettings.CloseTags && position > 1)
                    {
                        ctag = GetXMLContextTag(sci, position-2);
                        if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
                        {
                            if ((Char)sci.CharAt(position-2) == '<')
                            {
                                sci.ReplaceSel((Char)value + ">");
                                sci.SetSel(position, position);
                            }
                        }
                    }
                    break;
                
                case '!':
                    if (PluginSettings.CloseTags && position > 1)
                    {
                        ctag = GetXMLContextTag(sci, position-2);
                        if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
                        {
                            if ((Char)sci.CharAt(position-2) == '<')
                            {
                                CompletionList.Show(xmlBlocks, true);
                            }
                        }                       
                    }
                    break;
            }
        }
Exemple #19
0
        static public void GenerateOverride(ScintillaControl Sci, ClassModel ofClass, MemberModel member, int position)
        {
            ContextFeatures features = ASContext.Context.Features;
            List<string> typesUsed = new List<string>();
            bool isProxy = (member.Namespace == "flash_proxy");
            if (isProxy) typesUsed.Add("flash.utils.flash_proxy");
            bool isAS2Event = ASContext.Context.Settings.LanguageId == "AS2" && member.Name.StartsWithOrdinal("on");
            bool isObjectMethod = ofClass.QualifiedName == "Object";

            int line = Sci.LineFromPosition(position);
            string currentText = Sci.GetLine(line);
            int startPos = currentText.Length;
            GetStartPos(currentText, ref startPos, features.privateKey);
            GetStartPos(currentText, ref startPos, features.protectedKey);
            GetStartPos(currentText, ref startPos, features.internalKey);
            GetStartPos(currentText, ref startPos, features.publicKey);
            GetStartPos(currentText, ref startPos, features.staticKey);
            GetStartPos(currentText, ref startPos, features.overrideKey);
            startPos += Sci.PositionFromLine(line);

            FlagType flags = member.Flags;
            string acc = "";
            string decl = "";
            if (features.hasNamespaces && !string.IsNullOrEmpty(member.Namespace) && member.Namespace != "internal")
                acc = member.Namespace;
            else if ((member.Access & Visibility.Public) > 0) acc = features.publicKey;
            else if ((member.Access & Visibility.Internal) > 0) acc = features.internalKey;
            else if ((member.Access & Visibility.Protected) > 0) acc = features.protectedKey;
            else if ((member.Access & Visibility.Private) > 0 && features.methodModifierDefault != Visibility.Private) 
                acc = features.privateKey;

            bool isStatic = (flags & FlagType.Static) > 0;
            if (isStatic) acc = features.staticKey + " " + acc;

            if (!isAS2Event && !isObjectMethod)
                acc = features.overrideKey + " " + acc;

            acc = Regex.Replace(acc, "[ ]+", " ").Trim();

            if ((flags & (FlagType.Getter | FlagType.Setter)) > 0)
            {
                string type = member.Type;
                string name = member.Name;
                if (member.Parameters != null && member.Parameters.Count == 1)
                    type = member.Parameters[0].Type;
                type = FormatType(type);
                if (type == null && !features.hasInference) type = features.objectKey;

                bool genGetter = ofClass.Members.Search(name, FlagType.Getter, 0) != null;
                bool genSetter = ofClass.Members.Search(name, FlagType.Setter, 0) != null;

                if (IsHaxe)
                {
                    // property is public but not the methods
                    acc = features.overrideKey;
                }

                if (genGetter)
                {
                    string tpl = TemplateUtils.GetTemplate("OverrideGetter", "Getter");
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Modifiers", acc);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Name", name);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Type", type);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Member", "super." + name);
                    decl += tpl;
                }
                if (genSetter)
                {
                    string tpl = TemplateUtils.GetTemplate("OverrideSetter", "Setter");
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Modifiers", acc);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Name", name);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Type", type);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Member", "super." + name);
                    tpl = TemplateUtils.ReplaceTemplateVariable(tpl, "Void", ASContext.Context.Features.voidKey ?? "void");
                    if (decl.Length > 0)
                    {
                        tpl = "\n\n" + tpl.Replace("$(EntryPoint)", "");
                    }
                    decl += tpl;
                }
                decl = TemplateUtils.ReplaceTemplateVariable(decl, "BlankLine", "");
            }
            else
            {
                string type = FormatType(member.Type);
                //if (type == null) type = features.objectKey;
                
                decl = acc + features.functionKey + " ";
                bool noRet = type == null || type.Equals("void", StringComparison.OrdinalIgnoreCase);
                type = (noRet && type != null) ? ASContext.Context.Features.voidKey : type;
                if (!noRet)
                {
                    string qType = GetQualifiedType(type, ofClass);
                    typesUsed.Add(qType);
                    if (qType == type)
                    {
                        ClassModel rType = ASContext.Context.ResolveType(type, ofClass.InFile);
                        if (!rType.IsVoid()) type = rType.Name;
                    }
                }

                string action = (isProxy || isAS2Event) ? "" : GetSuperCall(member, typesUsed, ofClass);
                string template = TemplateUtils.GetTemplate("MethodOverride");
                
                // fix parameters if needed
                if (member.Parameters != null)
                    foreach (MemberModel para in member.Parameters)
                       if (para.Type == "any") para.Type = "*";

                template = TemplateUtils.ReplaceTemplateVariable(template, "Modifiers", acc);
                template = TemplateUtils.ReplaceTemplateVariable(template, "Name", member.Name);
                template = TemplateUtils.ReplaceTemplateVariable(template, "Arguments", TemplateUtils.ParametersString(member, true));
                template = TemplateUtils.ReplaceTemplateVariable(template, "Type", type);
                template = TemplateUtils.ReplaceTemplateVariable(template, "Method", action);
                decl = template;
            }

            Sci.BeginUndoAction();
            try
            {
                if (ASContext.Context.Settings.GenerateImports && typesUsed.Count > 0)
                {
                    int offset = AddImportsByName(typesUsed, line);
                    position += offset;
                    startPos += offset;
                }

                Sci.SetSel(startPos, position + member.Name.Length);
                InsertCode(startPos, decl, Sci);
            }
            finally { Sci.EndUndoAction(); }
        }
Exemple #20
0
 /// <summary>
 /// Checks if bookmark list view needs updating
 /// </summary>
 private Boolean NeedRefresh(ScintillaControl sci, List<Int32> markers, ListView.ListViewItemCollection items)
 {
     if (items.Count != markers.Count) return true;
     foreach (ListViewItem item in items)
     {
         Int32 marker = (Int32)item.Tag;
         if (!markers.Contains(marker)) return true;
         if (sci.GetLine(marker).Trim() != item.SubItems[1].Text) return true;
     }
     return false;
 }
Exemple #21
0
        static private bool HandleDocTagCompletion(ScintillaControl Sci)
        {
            if (ASContext.CommonSettings.JavadocTags == null || ASContext.CommonSettings.JavadocTags.Length == 0)
                return false;

            string txt = Sci.GetLine(Sci.CurrentLine).TrimStart();
            if (!Regex.IsMatch(txt, "^\\*[\\s]*\\@"))
                return false;
            
            // build tag list
            if (docVariables == null)
            {
                docVariables = new List<ICompletionListItem>();
                TagItem item;
                foreach (string tag in ASContext.CommonSettings.JavadocTags)
                {
                    item = new TagItem(tag);
                    docVariables.Add(item);
                }               
            }
            
            // show
            CompletionList.Show(docVariables, true, "");
            return true;
        }
Exemple #22
0
        private static void AssignStatementToVar(ClassModel inClass, ScintillaControl sci, MemberModel member)
        {
            int lineNum = sci.CurrentLine;
            string line = sci.GetLine(lineNum);
            StatementReturnType returnType = GetStatementReturnType(sci, inClass, line, sci.PositionFromLine(lineNum));

            if (returnType == null) return;
            
            string type = null;
            string varname = null;
            ASResult resolve = returnType.resolve;
            string word = returnType.word;

            if (resolve != null && !resolve.IsNull())
            {
                if (resolve.Member != null && resolve.Member.Type != null)
                {
                    type = resolve.Member.Type;
                }
                else if (resolve.Type != null && resolve.Type.Name != null)
                {
                    type = resolve.Type.QualifiedName;
                }

                if (resolve.Member != null && resolve.Member.Name != null)
                {
                    varname = GuessVarName(resolve.Member.Name, type);
                }
            }

            if (!string.IsNullOrEmpty(word) && Char.IsDigit(word[0])) word = null;

            if (!string.IsNullOrEmpty(word) && (string.IsNullOrEmpty(type) || Regex.IsMatch(type, "(<[^]]+>)")))
                word = null;

            if (!string.IsNullOrEmpty(type) && type.Equals("void", StringComparison.OrdinalIgnoreCase))
                type = null;

            if (varname == null) varname = GuessVarName(word, type);

            if (varname != null && varname == word)
                varname = varname.Length == 1 ? varname + "1" : varname[0] + "";

            string cleanType = null;
            if (type != null) cleanType = FormatType(GetShortType(type));
            
            string template = TemplateUtils.GetTemplate("AssignVariable");
            template = TemplateUtils.ReplaceTemplateVariable(template, "Name", varname);
            template = TemplateUtils.ReplaceTemplateVariable(template, "Type", cleanType);

            int indent = sci.GetLineIndentation(lineNum);
            int pos = sci.PositionFromLine(lineNum) + indent / sci.Indent;

            sci.CurrentPos = pos;
            sci.SetSel(pos, pos);
            InsertCode(pos, template, sci);

            if (type != null)
            {
                ClassModel inClassForImport = null;
                if (resolve.InClass != null)
                {
                    inClassForImport = resolve.InClass;
                }
                else if (resolve.RelClass != null)
                {
                    inClassForImport = resolve.RelClass;
                }
                else 
                {
                    inClassForImport = inClass;
                }
                List<string> l = new List<string>();
                l.Add(GetQualifiedType(type, inClassForImport));
                pos += AddImportsByName(l, sci.LineFromPosition(pos));
            }
        }
Exemple #23
0
        public override bool OnCompletionInsert(ScintillaControl sci, int position, string text, char trigger)
        {
            if (text == "Dictionary")
            {
                string insert = null;
                string line = sci.GetLine(sci.LineFromPosition(position));
                Match m = Regex.Match(line, @"\svar\s+(?<varname>.+)\s*:\s*Dictionary\.<(?<indextype>.+)(?=(>\s*=))");
                if (m.Success)
                {
                    insert = String.Format(".<{0}>", m.Groups["indextype"].Value);
                }
                else
                {
                    m = Regex.Match(line, @"\s*=\s*new");
                    if (m.Success)
                    {
                        ASResult result = ASComplete.GetExpressionType(sci, sci.PositionFromLine(sci.LineFromPosition(position)) + m.Index);
                        if (result != null && !result.IsNull() && result.Member != null && result.Member.Type != null)
                        {
                            m = Regex.Match(result.Member.Type, @"(?<=<).+(?=>)");
                            if (m.Success)
                            {
                                insert = String.Format(".<{0}>", m.Value);
                            }
                        }
                    }
                    if (insert == null)
                    {
                        if (trigger == '.' || trigger == '(') return true;
                        insert = ".<>";
                        sci.InsertText(position + text.Length, insert);
                        sci.CurrentPos = position + text.Length + 2;
                        sci.SetSel(sci.CurrentPos, sci.CurrentPos);
                        ASComplete.HandleAllClassesCompletion(sci, "", false, true);
                        return true;
                    }
                }
                if (insert == null) return false;
                if (trigger == '.')
                {
                    sci.InsertText(position + text.Length, insert.Substring(1));
                    sci.CurrentPos = position + text.Length;
                }
                else
                {
                    sci.InsertText(position + text.Length, insert);
                    sci.CurrentPos = position + text.Length + insert.Length;
                }
                sci.SetSel(sci.CurrentPos, sci.CurrentPos);
                return true;
            }

            return base.OnCompletionInsert(sci, position, text, trigger);
        }
Exemple #24
0
		static public void OnChar(ScintillaControl sci, int value)
		{
			if (cType == XMLType.Invalid)
				return;
			
			XMLContextTag ctag;
			int position = sci.CurrentPos;
			char c = ' ';
			switch (value)
			{
				case 10:
					int line = sci.LineFromPosition(position);
					
					// Shift+Enter to insert <BR/>
					if (Control.ModifierKeys == Keys.Shift)
					{
						ctag = GetXMLContextTag(sci, position);
						if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
						{
							int start = sci.PositionFromLine(line)-((sci.EOLMode == 0)? 2:1);
							sci.SetSel(start, position);
							sci.ReplaceSel((lowerCaseHtmlTags)?"<br/>":"<BR/>");
							sci.SetSel(start+5, start+5);
							return;
						}
					}
					if (autoIndent)
					{
						// get last non-empty line
						string text = "";
						int line2 = line-1;
						while (line2 >= 0 && text.Length == 0)
						{
							text = sci.GetLine(line2).TrimEnd();
							line2--;
						}
						
						if ((text.EndsWith(">") && !text.EndsWith("?>") && !text.EndsWith("%>") && !re_closingTag.IsMatch(text)) 
						    || text.EndsWith("<!--") || text.EndsWith("<![CDATA["))
						{
							// get the previous tag
							do {
								position--;
								c = (char)sci.CharAt(position);
							}
							while (position > 0 && c != '>');
							ctag = GetXMLContextTag(sci, position);
							
							if ((char)sci.CharAt(position-1) == '/')
								return;
							
							// insert blank line if we pressed Enter between a tag & it's closing tag
							int indent = sci.GetLineIndentation(line2+1);
							string checkStart = null;
							if (text.EndsWith("<!--")) checkStart = "-->";
							else if (text.EndsWith("<![CDATA[")) checkStart = "]]>";
							else if (ctag.Name != null) checkStart = "</"+ctag.Name;
							if (checkStart != null)
							{
								text = sci.GetLine(line).TrimStart();
								if (text.StartsWith(checkStart))
								{
									sci.SetLineIndentation(line, indent);
									sci.InsertText(sci.PositionFromLine(line), mainForm.GetNewLineMarker(sci.EOLMode));
								}
							}
							
							// indent
							sci.SetLineIndentation(line, indent+sci.Indent);
							position = sci.LineIndentPosition(line);
							sci.SetSel(position, position);
							return;
						}
					}
					break;
					
				case '<':
				case '/':
					if (value == '/')
					{
						if ((position < 2) || ((char)sci.CharAt(position-2) != '<'))
							return;
					}
					else 
					{
						ctag = GetXMLContextTag(sci, position);
						if (ctag.Tag != null)
							return;
					}
					// new tag
					if (enableHtmlCompletion && cType == XMLType.Known)
					{
						ArrayList items = new ArrayList();
						string previous = null;
						foreach(HTMLTag tag in knownTags) 
						if (tag.Name != previous) {
							items.Add( new HtmlTagItem(tag.Name, tag.Tag) );
							previous = tag.Name;
						}
						CompletionList.Show(items, true);
					}
					else
					{
						// allow another plugin to handle this
						mainForm.DispatchEvent(new DataEvent(EventType.CustomData,"XMLCompletion.Element",new XMLContextTag()));
					}
					return;
					
				case '>':
					if (autoCloseTags)
					{
						ctag = GetXMLContextTag(sci, position);
						if (ctag.Name != null && !ctag.Tag.EndsWith("/>"))
						{
							// est-ce un tag sans enfant?
							bool isLeaf = false;
							if (cType == XMLType.Known)
							foreach(HTMLTag tag in knownTags)
							{
								if (String.Compare(tag.Tag, ctag.Name, true) == 0)
								{
									isLeaf = tag.IsLeaf;
									break;
								}
							}
							if (isLeaf)
							{
								sci.SetSel(position-1,position);
								sci.ReplaceSel("/>");
								sci.SetSel(position+1, position+1);
							}
							else
							{
								string closeTag = "</"+ctag.Name+">";
								sci.ReplaceSel(closeTag);
								sci.SetSel(position, position);
							}
						}
					}
					return;
					
				case ' ':
					c = (char)sci.CharAt(position);
					if (c > 32 && c != '/' && c != '>' && c != '<')
						return;
						
					ctag = GetXMLContextTag(sci, position);
					if (ctag.Tag != null)
					{
						if (InQuotes(ctag.Tag) || ctag.Tag.LastIndexOf('"') < ctag.Tag.LastIndexOf('='))
							return;
						//
						if (enableHtmlCompletion && cType == XMLType.Known)
						{
							foreach(HTMLTag tag in knownTags)
							if (String.Compare(tag.Tag, ctag.Name, true) == 0)
							{
								ArrayList items = new ArrayList();
								string previous = null;
								foreach(string attr in tag.Attributes)
								if (attr != previous) {
									items.Add( new HtmlAttributeItem(attr) );
									previous = attr;
								}
								CompletionList.Show(items, true);
								return;
							}
						}
						else
						{
							// allow another plugin to handle this
							object[] o = new object[]{ctag,""};
							mainForm.DispatchEvent(new DataEvent(EventType.CustomData,"XMLCompletion.Attribute",o));
						}
					}
					return;
				
				case '=':
					if (insertQuotes)
					{
						ctag = GetXMLContextTag(sci, position);
						position = sci.CurrentPos-2;
						if (ctag.Tag != null && !InQuotes(ctag.Tag) && (GetWordLeft(sci, ref position).Length > 0))
						{
							position = sci.CurrentPos;
							c = (char)sci.CharAt(position);
							if (c > 32 && c != '>') sci.ReplaceSel("\"\" ");
							else sci.ReplaceSel("\"\"");
							sci.SetSel(position+1, position+1);
						}
					}
					return;
					
				case '?':
				case '%':
					if (autoCloseTags && position > 1)
					{
						ctag = GetXMLContextTag(sci, position-2);
						if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
						{
							if ((char)sci.CharAt(position-2) == '<')
							{
								sci.ReplaceSel((char)value + ">");
								sci.SetSel(position, position);
							}
						}
					}
					break;
				
				case '!':
					if (autoCloseTags && position > 1)
					{
						ctag = GetXMLContextTag(sci, position-2);
						if (ctag.Tag == null || ctag.Tag.EndsWith(">"))
						{
							if ((char)sci.CharAt(position-2) == '<')
							{
								CompletionList.Show(xmlBlocks, true);
							}
						}						
					}
					break;
			}
		}