/// <summary> /// Shows the completion list automaticly after typing three chars /// </summary> private void SciControlCharAdded(ScintillaControl sci, Int32 value) { String language = sci.ConfigurationLanguage.ToLower(); if (this.IsSupported(language)) { Language config = ScintillaControl.Configuration.GetLanguage(sci.ConfigurationLanguage); String characters = config.characterclass.Characters; // Do not autocomplete in word Char c = (char)sci.CharAt(sci.CurrentPos); if (characters.IndexOf(c) >= 0) { return; } // Autocomplete after typing word chars only if (characters.IndexOf((char)value) < 0) { return; } String curWord = sci.GetWordLeft(sci.CurrentPos - 1, false); if (curWord == null || curWord.Length < 3) { return; } List <ICompletionListItem> items = this.GetCompletionListItems(language, sci.FileName); if (items != null && items.Count > 0) { items.Sort(); CompletionList.Show(items, true, curWord); CompletionList.DisableAutoInsertion(); } } }
static private bool HandleDocTagCompletion(ScintillaControl Sci) { if (ASContext.CommonSettings.JavadocTags == null || ASContext.CommonSettings.JavadocTags.Length == 0) { return(false); } string txt = Sci.GetLine(Sci.LineFromPosition(Sci.CurrentPos)).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); }
/// <summary> /// 入力補完リスト表示 /// </summary> /// <param name="itemList"></param> private void showCompletion(List <ICompletionListItem> itemList) { if (itemList == null || itemList.Count == 0) { //表示項目がないので何もしない return; } if (string.IsNullOrEmpty(m_compProvider.PreSelection)) { //選択ワードがないとき CompletionList.Show(itemList, true); } else if (this.CurrentSci.MBSafeTextLength(m_compProvider.PreSelection) != m_compProvider.PreSelection.Length) { //日本語単語選択時 this.CurrentSci.SelectWord(); CompletionList.Show(itemList, true); } else { //通常選択時 CompletionList.Show(itemList, true, m_compProvider.PreSelection); } }
static private bool HandleDocTagCompletion(ScintillaNet.ScintillaControl Sci) { string txt = Sci.GetLine(Sci.LineFromPosition(Sci.CurrentPos)).TrimStart(); if (!Regex.IsMatch(txt, "^\\*[\\s]*\\@")) { return(false); } DebugConsole.Trace("Documentation tag completion"); // build tag list if (docVariables == null) { docVariables = new ArrayList(); TagItem item; string[] tags = ASContext.DocumentationTags.Split(' '); foreach (string tag in tags) { item = new TagItem(tag); docVariables.Add(item); } } // show CompletionList.Show(docVariables, true, ""); return(true); }
static public bool HandleAttribute(object data) { if (!GetContext(data)) { return(false); } string type = ResolveType(mxmlContext, tagContext.Name); ClassModel tagClass = context.ResolveType(type, mxmlContext.model); if (tagClass.IsVoid()) { return(true); } tagClass.ResolveExtends(); List <ICompletionListItem> mix = new List <ICompletionListItem>(); List <string> excludes = new List <string>(); GetTagAttributes(tagClass, mix, excludes, null); // cleanup and show list mix.Sort(new MXMLListItemComparer()); List <ICompletionListItem> items = new List <ICompletionListItem>(); string previous = null; foreach (ICompletionListItem item in mix) { if (previous == item.Label) { continue; } previous = item.Label; if (excludes.Contains(previous)) { continue; } items.Add(item); } if (items.Count == 0) { return(true); } if (!string.IsNullOrEmpty(tokenContext)) { CompletionList.Show(items, false, tokenContext); } else { CompletionList.Show(items, true); } CompletionList.MinWordLength = 0; return(true); }
static private bool HandleBoxCompletion(ScintillaNet.ScintillaControl Sci, int position) { DebugConsole.Trace("Documentation tag completion"); // is the block before a function declaration? int len = Sci.TextLength - 1; char c; StringBuilder sb = new StringBuilder(); while (position < len) { c = (char)Sci.CharAt(position); sb.Append(c); if ((c == '(') || (c == ';') || (c == '{')) { break; } position++; } string signature = sb.ToString(); if (re_functionDeclaration.IsMatch(signature)) { // get method signature position++; while (position < len) { c = (char)Sci.CharAt(position); sb.Append(c); if ((c == ';') || (c == '{')) { break; } position++; } signature = sb.ToString(); } else { signature = null; } // build templates list ArrayList templates = new ArrayList(); if (signature != null) { boxMethodParams.Context = signature; templates.Add(boxMethodParams); } templates.Add(boxSimpleClose); // show CompletionList.Show(templates, true, ""); return(true); }
private void StartFileCompletion(Object sender, System.EventArgs e) { this.completing = true; ScintillaControl sci = PluginBase.MainForm.CurrentDocument.SciControl; sci.PreviewKeyDown += new PreviewKeyDownEventHandler(sci_PreviewKeyDown); UITools.Manager.OnCharAdded += new UITools.CharAddedHandler(OnChar); UITools.Manager.OnTextChanged += new UITools.TextChangedHandler(OnTextChanged); CompletionList.OnInsert += new InsertedTextHandler(CompletionList_OnInsert); CompletionList.Show(this.FormatCompletionList(null), true); }
private void HandleCompletion(CompleteMode mode, LocalContext context, bool autoInsert, bool autoHide) { List <ICompletionListItem> items = null; switch (mode) { case CompleteMode.Selector: items = HandleSelectorCompletion(context); break; case CompleteMode.Pseudo: items = HandlePseudoCompletion(context); break; case CompleteMode.Prefix: items = HandlePrefixCompletion(context); break; case CompleteMode.Attribute: items = HandlePropertyCompletion(context); break; case CompleteMode.Variable: items = HandleVariableCompletion(context); break; case CompleteMode.Value: items = HandleValueCompletion(context); break; } if (items == null) { return; } if (autoInsert && !string.IsNullOrEmpty(context.Word)) { var matches = new List <ICompletionListItem>(); foreach (var item in items) { if (item.Label.StartsWithOrdinal(context.Word)) { matches.Add(item); } } if (matches.Count == 1) { ScintillaControl sci = PluginBase.MainForm.CurrentDocument.SciControl; sci.SetSel(context.Position, sci.CurrentPos); sci.ReplaceSel(matches[0].Label); } //else } else { CompletionList.Show(items, autoHide, context.Word); } }
private void OnChar(ScintillaControl sci, Int32 value) { Char ch = (Char)value; String match; String[] parts; DirectoryInfo di = this.FindRoot(); String remainder; if (di == null) { if (this.completing) { CompletionList.Show(this.FormatCompletionList(this.pathSoFar), true); } } else { parts = this.pathSoFar.Split(new Char[2] { '/', '\\' }); match = parts[parts.Length - 1]; if (this.currentFolder == null) { this.currentFolder = di; CompletionList.Show(this.FormatCompletionList(match), true); } else { Queue <String> q = new Queue <String>(parts); q.Dequeue(); remainder = ""; foreach (String s in q) { remainder += "\\" + s; } remainder = remainder.Substring(1); this.currentFolder = new DirectoryInfo(Path.Combine(di.FullName, remainder)); CompletionList.Show(this.FormatCompletionList(match), true); } } }
/// <summary> /// Shows the completion list automaticly after typing three chars /// </summary> private void SciControlCharAdded(ScintillaControl sci, Int32 value) { ITabbedDocument doc = DocumentManager.FindDocument(sci); if (this.isSupported && !settingObject.DisableAutoCompletion) { String lang = sci.ConfigurationLanguage; AutoInsert insert = settingObject.AutoInsertType; Language config = ScintillaControl.Configuration.GetLanguage(lang); String characters = config.characterclass.Characters; // Do not autocomplete in word Char c = (char)sci.CharAt(sci.CurrentPos); if (characters.IndexOf(c) >= 0) { return; } // Autocomplete after typing word chars only if (characters.IndexOf((char)value) < 0) { return; } String curWord = sci.GetWordLeft(sci.CurrentPos - 1, false); if (curWord == null || curWord.Length < 3) { return; } List <ICompletionListItem> items = this.GetCompletionListItems(lang, sci.FileName); if (items != null && items.Count > 0) { items.Sort(); CompletionList.Show(items, true, curWord); if (insert == AutoInsert.Never || (insert == AutoInsert.CPP && sci.Lexer != 3 /*CPP*/) || lang == "text") { CompletionList.DisableAutoInsertion(); } } } }
/// <summary> /// Handles the incoming events /// </summary> public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority prority) { ITabbedDocument document = PluginBase.MainForm.CurrentDocument; if (document == null || !document.IsEditable) { return; } switch (e.Type) { case EventType.Keys: { Keys keys = (e as KeyEvent).Value; if (this.isSupported && keys == (Keys.Control | Keys.Space)) { String lang = document.SciControl.ConfigurationLanguage; List <ICompletionListItem> items = this.GetCompletionListItems(lang, document.FileName); if (items != null && items.Count > 0) { items.Sort(); Int32 curPos = document.SciControl.CurrentPos - 1; String curWord = document.SciControl.GetWordLeft(curPos, false); if (curWord == null) { curWord = String.Empty; } CompletionList.Show(items, false, curWord); e.Handled = true; } } else if (this.isSupported && keys == (Keys.Control | Keys.Alt | Keys.Space)) { PluginBase.MainForm.CallCommand("InsertSnippet", "null"); e.Handled = true; } break; } case EventType.UIStarted: { this.isSupported = false; this.isActive = true; break; } case EventType.UIClosing: { isActive = false; break; } case EventType.FileSwitch: { this.isSupported = false; break; } case EventType.Completion: { if (!e.Handled && isActive) { this.isSupported = true; e.Handled = true; } this.HandleFile(document); break; } case EventType.SyntaxChange: case EventType.ApplySettings: { this.HandleFile(document); break; } case EventType.FileSave: { TextEvent te = e as TextEvent; if (te.Value == document.FileName && this.isSupported) { this.AddDocumentKeywords(document); } else { ITabbedDocument saveDoc = DocumentManager.FindDocument(te.Value); if (saveDoc != null) { this.updateTable[te.Value] = true; } } break; } case EventType.Command: { DataEvent de = e as DataEvent; if (de.Action == "ProjectManager.Project") { IProject project = de.Data as IProject; if (project != null) { this.LoadProjectKeywords(project); } } break; } } }
protected override void OnClick(EventArgs e) { CompletionList.Show(items, false); }
/** * Handles the incoming events */ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority) { try { // ignore all events when leaving if (PluginBase.MainForm.ClosingEntirely) { return; } // current active document ITabbedDocument doc = PluginBase.MainForm.CurrentDocument; // application start if (!started && e.Type == EventType.UIStarted) { started = true; PathExplorer.OnUIStarted(); // associate context to initial document e = new NotifyEvent(EventType.SyntaxChange); this.pluginUI.UpdateAfterTheme(); } // editor ready? if (doc == null) { return; } ScintillaControl sci = doc.IsEditable ? doc.SciControl : null; // // Events always handled // bool isValid; DataEvent de; switch (e.Type) { // caret position in editor case EventType.UIRefresh: if (!doc.IsEditable) { return; } timerPosition.Enabled = false; timerPosition.Enabled = true; return; // key combinations case EventType.Keys: Keys key = (e as KeyEvent).Value; if (ModelsExplorer.HasFocus) { e.Handled = ModelsExplorer.Instance.OnShortcut(key); return; } if (!doc.IsEditable) { return; } e.Handled = ASComplete.OnShortcut(key, sci); return; // user-customized shortcuts case EventType.Shortcut: de = e as DataEvent; if (de.Action == "Completion.ShowHelp") { ASComplete.HelpKeys = (Keys)de.Data; de.Handled = true; } return; // // File management // case EventType.FileSave: if (!doc.IsEditable) { return; } ASContext.Context.CheckModel(false); // toolbar isValid = ASContext.Context.IsFileValid; if (isValid && !PluginBase.MainForm.SavingMultiple) { if (ASContext.Context.Settings.CheckSyntaxOnSave) { CheckSyntax(null, null); } ASContext.Context.RemoveClassCompilerCache(); } return; case EventType.SyntaxDetect: // detect Actionscript language version if (!doc.IsEditable) { return; } if (doc.FileName.ToLower().EndsWithOrdinal(".as")) { settingObject.LastASVersion = DetectActionscriptVersion(doc); (e as TextEvent).Value = settingObject.LastASVersion; e.Handled = true; } break; case EventType.ApplySettings: case EventType.SyntaxChange: case EventType.FileSwitch: if (!doc.IsEditable) { ASContext.SetCurrentFile(null, true); ContextChanged(); return; } currentDoc = doc.FileName; currentPos = sci.CurrentPos; // check file bool ignoreFile = !doc.IsEditable; ASContext.SetCurrentFile(doc, ignoreFile); // UI ContextChanged(); return; case EventType.Completion: if (ASContext.Context.IsFileValid) { e.Handled = true; } return; // some commands work all the time case EventType.Command: de = e as DataEvent; string command = de.Action ?? ""; if (command.StartsWithOrdinal("ASCompletion.")) { string cmdData = de.Data as string; // add a custom classpath if (command == "ASCompletion.ClassPath") { Hashtable info = de.Data as Hashtable; if (info != null) { ContextSetupInfos setup = new ContextSetupInfos(); setup.Platform = (string)info["platform"]; setup.Lang = (string)info["lang"]; setup.Version = (string)info["version"]; setup.TargetBuild = (string)info["targetBuild"]; setup.Classpath = (string[])info["classpath"]; setup.HiddenPaths = (string[])info["hidden"]; ASContext.SetLanguageClassPath(setup); if (setup.AdditionalPaths != null) // report custom classpath { info["additional"] = setup.AdditionalPaths.ToArray(); } } e.Handled = true; } // send a UserClasspath else if (command == "ASCompletion.GetUserClasspath") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); if (context != null && context.Settings != null && context.Settings.UserClasspath != null) { info["cp"] = new List <string>(context.Settings.UserClasspath); } } e.Handled = true; } // update a UserClasspath else if (command == "ASCompletion.SetUserClasspath") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language") && info.ContainsKey("cp")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); List <string> cp = info["cp"] as List <string>; if (cp != null && context != null && context.Settings != null) { string[] pathes = new string[cp.Count]; cp.CopyTo(pathes); context.Settings.UserClasspath = pathes; } } e.Handled = true; } // send the language's default compiler path else if (command == "ASCompletion.GetCompilerPath") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); if (context != null) { info["compiler"] = context.GetCompilerPath(); } } e.Handled = true; } // show a language's compiler settings else if (command == "ASCompletion.ShowSettings") { e.Handled = true; IASContext context = ASContext.GetLanguageContext(cmdData); if (context == null) { return; } string filter = "SDK"; string name = ""; switch (cmdData.ToUpper()) { case "AS2": name = "AS2Context"; break; case "AS3": name = "AS3Context"; break; default: name = cmdData.Substring(0, 1).ToUpper() + cmdData.Substring(1) + "Context"; break; } PluginBase.MainForm.ShowSettingsDialog(name, filter); } // Open types explorer dialog else if (command == "ASCompletion.TypesExplorer") { TypesExplorer(null, null); } // call the Flash IDE else if (command == "ASCompletion.CallFlashIDE") { if (flashErrorsWatcher == null) { flashErrorsWatcher = new FlashErrorsWatcher(); } e.Handled = CallFlashIDE.Run(settingObject.PathToFlashIDE, cmdData); } // create Flash 8+ trust file else if (command == "ASCompletion.CreateTrustFile") { if (cmdData != null) { string[] args = cmdData.Split(';'); if (args.Length == 2) { e.Handled = CreateTrustFile.Run(args[0], args[1]); } } } else if (command == "ASCompletion.GetClassPath") { if (cmdData != null) { string[] args = cmdData.Split(';'); if (args.Length == 1) { FileModel model = ASContext.Context.GetFileModel(args[0]); ClassModel aClass = model.GetPublicClass(); if (!aClass.IsVoid()) { Clipboard.SetText(aClass.QualifiedName); e.Handled = true; } } } } else if (command == "ProjectManager.FileActions.DisableWatchers") { foreach (PathModel cp in ASContext.Context.Classpath) { cp.DisableWatcher(); } } else if (command == "ProjectManager.FileActions.EnableWatchers") { // classpaths could be invalid now - remove those, BuildClassPath() is too expensive ASContext.Context.Classpath.RemoveAll(cp => !Directory.Exists(cp.Path)); foreach (PathModel cp in ASContext.Context.Classpath) { cp.EnableWatcher(); } } // Return requested language SDK list else if (command == "ASCompletion.InstalledSDKs") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); if (context != null) { info["sdks"] = context.Settings.InstalledSDKs; } } e.Handled = true; } } // Create a fake document from a FileModel else if (command == "ProjectManager.OpenVirtualFile") { string cmdData = de.Data as string; if (reVirtualFile.IsMatch(cmdData)) { string[] path = Regex.Split(cmdData, "::"); string fileName = path[0] + Path.DirectorySeparatorChar + path[1].Replace('.', Path.DirectorySeparatorChar).Replace("::", Path.DirectorySeparatorChar.ToString()); FileModel found = ModelsExplorer.Instance.OpenFile(fileName); if (found != null) { e.Handled = true; } } } else if (command == "ProjectManager.UserRefreshTree") { ASContext.UserRefreshRequestAll(); } break; } // // Actionscript context specific // if (ASContext.Context.IsFileValid) { switch (e.Type) { case EventType.ProcessArgs: TextEvent te = (TextEvent)e; if (reArgs.IsMatch(te.Value)) { // resolve current element Hashtable details = ASComplete.ResolveElement(sci, null); te.Value = ArgumentsProcessor.Process(te.Value, details); if (te.Value.IndexOf('$') >= 0 && reCostlyArgs.IsMatch(te.Value)) { ASResult result = ASComplete.CurrentResolvedContext.Result ?? new ASResult(); details = new Hashtable(); // Get closest list (Array or Vector) string closestListName = "", closestListItemType = ""; ASComplete.FindClosestList(ASContext.Context, result.Context, sci.CurrentLine, ref closestListName, ref closestListItemType); details.Add("TypClosestListName", closestListName); details.Add("TypClosestListItemType", closestListItemType); // get free iterator index string iterator = ASComplete.FindFreeIterator(ASContext.Context, ASContext.Context.CurrentClass, result.Context); details.Add("ItmUniqueVar", iterator); te.Value = ArgumentsProcessor.Process(te.Value, details); } } break; // menu commands case EventType.Command: de = e as DataEvent; string command = de.Action ?? ""; if (command.StartsWith("ASCompletion.", StringComparison.Ordinal)) { string cmdData = de.Data as string; switch (command) { // run MTASC case "ASCompletion.CustomBuild": if (cmdData != null) { ASContext.Context.RunCMD(cmdData); } else { ASContext.Context.RunCMD(""); } e.Handled = true; break; // build the SWF using MTASC case "ASCompletion.QuickBuild": ASContext.Context.BuildCMD(false); e.Handled = true; break; // resolve element under cursor and open declaration case "ASCompletion.GotoDeclaration": ASComplete.DeclarationLookup(sci); e.Handled = true; break; // resolve element under cursor and send a CustomData event case "ASCompletion.ResolveElement": ASComplete.ResolveElement(sci, cmdData); e.Handled = true; break; case "ASCompletion.MakeIntrinsic": ASContext.Context.MakeIntrinsic(cmdData); e.Handled = true; break; // alternative to default shortcuts case "ASCompletion.CtrlSpace": ASComplete.OnShortcut(Keys.Control | Keys.Space, ASContext.CurSciControl); e.Handled = true; break; case "ASCompletion.CtrlShiftSpace": ASComplete.OnShortcut(Keys.Control | Keys.Shift | Keys.Space, ASContext.CurSciControl); e.Handled = true; break; case "ASCompletion.CtrlAltSpace": ASComplete.OnShortcut(Keys.Control | Keys.Alt | Keys.Space, ASContext.CurSciControl); e.Handled = true; break; case "ASCompletion.ContextualGenerator": if (ASContext.HasContext && ASContext.Context.IsFileValid) { var options = new List <ICompletionListItem>(); ASGenerator.ContextualGenerator(ASContext.CurSciControl, options); EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ASCompletion.ContextualGenerator.AddOptions", options)); if (options.Count == 0) { PluginBase.MainForm.StatusLabel.Text = TextHelper.GetString("Info.NoContextGeneratorCode"); } CompletionList.Show(options, false); } break; } } return; case EventType.ProcessEnd: string procResult = (e as TextEvent).Value; ASContext.Context.OnProcessEnd(procResult); break; } } } catch (Exception ex) { ErrorManager.ShowError(ex); } }
static public bool OnShortCut(Keys keys) { if (keys == (Keys.Control | Keys.Space)) { // context ScintillaControl sci = mainForm.CurSciControl; if (sci == null) { return(false); } XMLContextTag ctag = GetXMLContextTag(sci, sci.CurrentPos); // starting tag if (ctag.Tag == null && (sci.CurrentPos > 0)) { if ((char)sci.CharAt(sci.CurrentPos - 1) == '<') { ctag.Tag = "<"; ctag.Name = ""; } else { return(false); } } else if (ctag.Tag.EndsWith(">")) { return(false); } // closing tag else if (ctag.Tag.StartsWith("</") && (ctag.Tag.IndexOf(' ') < 0)) { ctag.Name = ctag.Tag.Substring(2); ctag.Tag = "<" + ctag.Name; } // element completion if (ctag.Name != null && (ctag.Tag.Length == ctag.Name.Length + 1)) { if (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, false, ctag.Name); } else { // allow another plugin to handle this mainForm.DispatchEvent(new DataEvent(EventType.CustomData, "XMLCompletion.Element", ctag)); } } // attributes completion else { if (InQuotes(ctag.Tag) || ctag.Tag.LastIndexOf('"') < ctag.Tag.LastIndexOf('=')) { return(true); } // get word int position = sci.CurrentPos - 1; string word = GetWordLeft(sci, ref position); if (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, word.Trim()); return(true); } } } else { // allow another plugin to handle this object[] o = new object[] { ctag, word }; mainForm.DispatchEvent(new DataEvent(EventType.CustomData, "XMLCompletion.Attribute", o)); } } return(true); } return(false); }
static public bool HandleAttributeValue(object data) { if (!GetContext(data)) { return(false); } string type = ResolveType(mxmlContext, tagContext.Name); ClassModel tagClass = context.ResolveType(type, mxmlContext.model); if (tagClass.IsVoid()) { return(true); } tagClass.ResolveExtends(); string currentAttribute; StringBuilder caBuilder = new StringBuilder(); bool possibleStartFound = false, startFound = false; for (int i = tagContext.Tag.Length - 1; i >= 0; i--) { char currChar = tagContext.Tag[i]; if (currChar == '=') { possibleStartFound = true; } else if (startFound) { if (Char.IsWhiteSpace(currChar)) { break; } caBuilder.Insert(0, currChar); } else if (possibleStartFound && !Char.IsWhiteSpace(currChar)) { startFound = true; caBuilder.Insert(0, currChar); } } currentAttribute = caBuilder.ToString(); List <ICompletionListItem> mix = GetTagAttributeValues(tagClass, null, currentAttribute); if (mix == null || mix.Count == 0) { return(true); } // cleanup and show list mix.Sort(new MXMLListItemComparer()); List <ICompletionListItem> items = new List <ICompletionListItem>(); string previous = null; foreach (ICompletionListItem item in mix) { if (previous == item.Label) { continue; } previous = item.Label; items.Add(item); } if (items.Count == 0) { return(true); } if (!string.IsNullOrEmpty(tokenContext)) { CompletionList.Show(items, false, tokenContext); } else { CompletionList.Show(items, true); } CompletionList.MinWordLength = 0; return(true); }
/// <summary> /// Called /// </summary> /// <param name="data"></param> /// <returns></returns> static public bool HandleElement(object data) { if (!GetContext(data)) { return(false); } if (!string.IsNullOrEmpty(tagContext.Name) && tagContext.Name.IndexOf(':') > 0) { return(HandleNamespace(data)); } List <ICompletionListItem> mix = new List <ICompletionListItem>(); List <string> excludes = new List <string>(); bool isContainer = AddParentAttributes(mix, excludes); // current tag attributes if (isContainer) // container children tag { foreach (string ns in mxmlContext.namespaces.Keys) { string uri = mxmlContext.namespaces[ns]; if (ns != "*") { mix.Add(new NamespaceItem(ns, uri)); } if (!allTags.ContainsKey(ns)) { continue; } foreach (string tag in allTags[ns]) { if (ns == "*") { mix.Add(new HtmlTagItem(tag, tag)); } else { mix.Add(new HtmlTagItem(tag, ns + ":" + tag, uri)); } } } } // cleanup and show list mix.Sort(new MXMLListItemComparer()); List <ICompletionListItem> items = new List <ICompletionListItem>(); string previous = null; foreach (ICompletionListItem item in mix) { if (previous == item.Label) { continue; } previous = item.Label; if (excludes.Contains(previous)) { continue; } items.Add(item); } if (mix.Count == 0) { return(true); } if (!string.IsNullOrEmpty(tagContext.Name)) { CompletionList.Show(items, false, tagContext.Name); } else { CompletionList.Show(items, true); } CompletionList.MinWordLength = 0; return(true); }
/// <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(" "); * } * }*/ 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; } }
/// <summary> /// Handles the incoming keys object /// </summary> public static Boolean OnShortCut(Keys keys) { if (cType == XMLType.Invalid) { return(false); } if (keys == (Keys.Control | Keys.Space)) { ITabbedDocument document = PluginBase.MainForm.CurrentDocument; if (!document.IsEditable) { return(false); } ScintillaControl sci = document.SciControl; XMLContextTag ctag = GetXMLContextTag(sci, sci.CurrentPos); // Starting tag if (ctag.Tag == null && (sci.CurrentPos > 0)) { if ((Char)sci.CharAt(sci.CurrentPos - 1) == '<') { ctag.Tag = "<"; ctag.Name = ""; } else { return(false); } } else if (ctag.Tag.EndsWith(">")) { return(false); } // Closing tag else if (ctag.Tag.StartsWith("</") && (ctag.Tag.IndexOf(' ') < 0)) { ctag.Name = ctag.Tag.Substring(2); ctag.Tag = "<" + ctag.Name; ctag.Closing = true; } // Element completion if (ctag.Name != null && (ctag.Tag.Length == ctag.Name.Length + 1)) { // Allow another plugin to handle this DataEvent de = new DataEvent(EventType.Command, "XMLCompletion.Element", ctag); EventManager.DispatchEvent(PluginBase.MainForm, de); if (de.Handled) { return(true); } if (cType == XMLType.Known) { List <ICompletionListItem> items = new List <ICompletionListItem>(); 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, false, ctag.Name); } } // Attribute completion else { Int32 position; String word; Object[] obj; DataEvent de; if (InQuotes(ctag.Tag)) { position = sci.CurrentPos - 1; word = GetWordLeft(sci, ref position); obj = new Object[] { ctag, word }; de = new DataEvent(EventType.Command, "XMLCompletion.AttributeValue", obj); EventManager.DispatchEvent(PluginBase.MainForm, de); return(true); } if (ctag.Tag.LastIndexOf('"') < ctag.Tag.LastIndexOf('=')) { return(true); } position = sci.CurrentPos - 1; word = GetWordLeft(sci, ref position); // Allow another plugin to handle this obj = new Object[] { ctag, word }; de = new DataEvent(EventType.Command, "XMLCompletion.Attribute", obj); EventManager.DispatchEvent(PluginBase.MainForm, de); if (de.Handled) { return(true); } if (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, word.Trim()); return(true); } } } } return(true); } return(false); }
public bool ContextualGenerator(ScintillaControl sci, int position, List <ICompletionListItem> options) { if ((position <= 2) || (sci.CharAt(position - 3) != '/') || (sci.CharAt(position - 2) != '*') || ((position != 3) && (sci.BaseStyleAt(position - 4) == 3))) { return(false); } // is the block before a function declaration? var len = sci.TextLength - 1; var c = ' '; var sb = new StringBuilder(); while (position < len) { c = (char)sci.CharAt(position); sb.Append(c); if (c == '(' || c == ';' || c == '{' || c == '}') { break; } position++; } var signature = sb.ToString(); if (re_functionDeclaration.IsMatch(signature)) { // get method signature position++; var dquCount = 0; var squCount = 0; var parCount = c == '(' ? 1 : 0; while (position < len) { c = (char)sci.CharAt(position); sb.Append(c); if (dquCount > 0) { if (c != '"' || sci.CharAt(position - 1) == '\\') { position++; continue; } if (sci.CharAt(position - 1) != '\\') { dquCount--; } } else if (squCount > 0) { if (c != '\'' || sci.CharAt(position - 1) == '\\') { position++; continue; } if (sci.CharAt(position - 1) != '\\') { squCount--; } } else if (c == '"' && (sci.CharAt(position - 1) != '\\' || IsEscapedCharacter(sci, position - 1))) { dquCount++; } else if (c == '\'' && (sci.CharAt(position - 1) != '\\' || IsEscapedCharacter(sci, position - 1))) { squCount++; } else if (c == '(') { parCount++; } else if (c == ')') { parCount--; } else if (parCount == 0 && (c == ';' || c == '{')) { break; } position++; } signature = sb.ToString(); } else { signature = null; } if (signature != null) { options.Add(new GeneratorItem(TextHelper.GetString("Label.CompleteDocDetails"), MethodDetails, () => GenerateJob(MethodDetails, signature))); } options.Add(new GeneratorItem(TextHelper.GetString("Label.CompleteDocEmpty"), Empty, () => GenerateJob(Empty, string.Empty))); CompletionList.Show(options, true, ""); return(true); }
static public bool HandleNamespace(object data) { if (!GetContext(data) || string.IsNullOrEmpty(tagContext.Name)) { return(false); } int p = tagContext.Name.IndexOf(':'); if (p < 0) { return(false); } string ns = tagContext.Name.Substring(0, p); if (!mxmlContext.namespaces.ContainsKey(ns)) { return(true); } string uri = mxmlContext.namespaces[ns]; List <ICompletionListItem> mix = new List <ICompletionListItem>(); List <string> excludes = new List <string>(); bool isContainer = AddParentAttributes(mix, excludes); // current tag attributes if (isContainer && allTags.ContainsKey(ns)) // container children tags { foreach (string tag in allTags[ns]) { mix.Add(new HtmlTagItem(tag, ns + ":" + tag, uri)); } } // cleanup and show list mix.Sort(new MXMLListItemComparer()); List <ICompletionListItem> items = new List <ICompletionListItem>(); string previous = null; foreach (ICompletionListItem item in mix) { if (previous == item.Label) { continue; } previous = item.Label; if (excludes.Contains(previous)) { continue; } items.Add(item); } if (mix.Count == 0) { return(true); } CompletionList.Show(items, true, tagContext.Name ?? ""); CompletionList.MinWordLength = 0; return(true); }
/// <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.EndsWithOrdinal("?>") && !text.EndsWithOrdinal("%>")) || text.EndsWithOrdinal("<!--") || text.EndsWithOrdinal("<![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.EndsWithOrdinal("<!--")) { checkStart = "-->"; subIndent = false; } else if (text.EndsWithOrdinal("<![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.StartsWithOrdinal(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(" "); * } * }*/ 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.StartsWithOrdinal("<!")) { // 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; } }
/// <summary> /// Inserts text from the snippets class /// </summary> public static Boolean InsertTextByWord(String word, Boolean emptyUndoBuffer) { ScintillaControl sci = Globals.SciControl; if (sci == null) { return(false); } Boolean canShowList = false; String snippet = null; if (word == null) { canShowList = true; word = sci.GetWordFromPosition(sci.CurrentPos); } if (word != null && word.Length > 0) { snippet = GetSnippet(word, sci.ConfigurationLanguage, sci.Encoding); } // let plugins handle the snippet Hashtable data = new Hashtable(); data["word"] = word; data["snippet"] = snippet; DataEvent de = new DataEvent(EventType.Command, "SnippetManager.Expand", data); EventManager.DispatchEvent(Globals.MainForm, de); if (de.Handled) { return(true); } snippet = (string)data["snippet"]; if (!String.IsNullOrEmpty(sci.SelText)) { // Remember the previous selection ArgsProcessor.PrevSelText = sci.SelText; } if (snippet != null) { Int32 endPos = sci.SelectionEnd; Int32 startPos = sci.SelectionStart; String curWord = sci.GetWordFromPosition(endPos); if (startPos == endPos) { endPos = sci.WordEndPosition(sci.CurrentPos, true); startPos = sci.WordStartPosition(sci.CurrentPos, true); sci.SetSel(startPos, endPos); } if (!String.IsNullOrEmpty(curWord)) { // Remember the current word ArgsProcessor.PrevSelWord = curWord; } SnippetHelper.InsertSnippetText(sci, endPos, snippet); return(true); } else if (canShowList) { ICompletionListItem item; List <ICompletionListItem> items = new List <ICompletionListItem>(); PathWalker walker = new PathWalker(PathHelper.SnippetDir, "*.fds", false); List <String> files = walker.GetFiles(); foreach (String file in files) { item = new SnippetItem(Path.GetFileNameWithoutExtension(file), file); items.Add(item); } String path = Path.Combine(PathHelper.SnippetDir, sci.ConfigurationLanguage); if (Directory.Exists(path)) { walker = new PathWalker(path, "*.fds", false); files = walker.GetFiles(); foreach (String file in files) { item = new SnippetItem(Path.GetFileNameWithoutExtension(file), file); items.Add(item); } } if (items.Count > 0) { items.Sort(); if (!String.IsNullOrEmpty(sci.SelText)) { word = sci.SelText; } else { word = sci.GetWordFromPosition(sci.CurrentPos); if (word == null) { word = String.Empty; } } CompletionList.OnInsert += new InsertedTextHandler(HandleListInsert); CompletionList.OnCancel += new InsertedTextHandler(HandleListInsert); CompletionList.Show(items, false, word); return(true); } } return(false); }
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; } }