public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets) { try { //AsmDudeToolsStatic.Output_INFO(string.Format("{0}:AugmentCompletionSession", this.ToString())); if (!Settings.Default.CodeCompletion_On) { return; } DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this._buffer.CurrentSnapshot; SnapshotPoint triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { return; } ITextSnapshotLine line = triggerPoint.GetContainingLine(); //1] check if current position is in a remark; if we are in a remark, no code completion #region if (triggerPoint.Position > 1) { char currentTypedChar = (triggerPoint - 1).GetChar(); //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession: current char = "+ currentTypedChar); if (!currentTypedChar.Equals('#')) { //TODO UGLY since the user can configure this starting character int pos = triggerPoint.Position - line.Start; if (AsmSourceTools.IsInRemark(pos, line.GetText())) { //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession: currently in a remark section"); return; } else { // AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession: not in a remark section"); } } } #endregion //2] find the start of the current keyword #region SnapshotPoint start = triggerPoint; while ((start > line.Start) && !AsmSourceTools.IsSeparatorChar((start - 1).GetChar())) { start -= 1; } #endregion //3] get the word that is currently being typed #region ITrackingSpan applicableTo = snapshot.CreateTrackingSpan(new SnapshotSpan(start, triggerPoint), SpanTrackingMode.EdgeInclusive); string partialKeyword = applicableTo.GetText(snapshot); bool useCapitals = AsmDudeToolsStatic.Is_All_Upper(partialKeyword); string lineStr = line.GetText(); (string Label, Mnemonic Mnemonic, string[] Args, string Remark)t = AsmSourceTools.ParseLine(lineStr); Mnemonic mnemonic = t.Mnemonic; string previousKeyword = AsmDudeToolsStatic.Get_Previous_Keyword(line.Start, start).ToUpper(); //AsmDudeToolsStatic.Output_INFO(string.Format("{0}:AugmentCompletionSession. lineStr=\"{1}\"; previousKeyword=\"{2}\"", this.ToString(), lineStr, previousKeyword)); if (mnemonic == Mnemonic.NONE) { if (previousKeyword.Equals("INVOKE")) //TODO INVOKE is a MASM keyword not a NASM one... { // Suggest a label IEnumerable <Completion> completions = this.Label_Completions(useCapitals, false); if (completions.Any()) { completionSets.Add(new CompletionSet("Labels", "Labels", applicableTo, completions, Enumerable.Empty <Completion>())); } } else { { ISet <AsmTokenType> selected1 = new HashSet <AsmTokenType> { AsmTokenType.Directive, AsmTokenType.Jump, AsmTokenType.Misc, AsmTokenType.Mnemonic }; IEnumerable <Completion> completions1 = this.Selected_Completions(useCapitals, selected1, true); if (completions1.Any()) { completionSets.Add(new CompletionSet("All", "All", applicableTo, completions1, Enumerable.Empty <Completion>())); } } if (false) { ISet <AsmTokenType> selected2 = new HashSet <AsmTokenType> { AsmTokenType.Jump, AsmTokenType.Mnemonic }; IEnumerable <Completion> completions2 = this.Selected_Completions(useCapitals, selected2, false); if (completions2.Any()) { completionSets.Add(new CompletionSet("Instr", "Instr", applicableTo, completions2, Enumerable.Empty <Completion>())); } } if (false) { ISet <AsmTokenType> selected3 = new HashSet <AsmTokenType> { AsmTokenType.Directive, AsmTokenType.Misc }; IEnumerable <Completion> completions3 = this.Selected_Completions(useCapitals, selected3, true); if (completions3.Any()) { completionSets.Add(new CompletionSet("Directive", "Directive", applicableTo, completions3, Enumerable.Empty <Completion>())); } } } } else { // the current line contains a mnemonic //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession; mnemonic=" + mnemonic+ "; previousKeyword="+ previousKeyword); if (AsmSourceTools.IsJump(AsmSourceTools.ParseMnemonic(previousKeyword, true))) { //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession; previous keyword is a jump mnemonic"); // previous keyword is jump (or call) mnemonic. Suggest "SHORT" or a label IEnumerable <Completion> completions = this.Label_Completions(useCapitals, true); if (completions.Any()) { completionSets.Add(new CompletionSet("Labels", "Labels", applicableTo, completions, Enumerable.Empty <Completion>())); } } else if (previousKeyword.Equals("SHORT") || previousKeyword.Equals("NEAR")) { // Suggest a label IEnumerable <Completion> completions = this.Label_Completions(useCapitals, false); if (completions.Any()) { completionSets.Add(new CompletionSet("Labels", "Labels", applicableTo, completions, Enumerable.Empty <Completion>())); } } else { IList <Operand> operands = AsmSourceTools.MakeOperands(t.Args); ISet <AsmSignatureEnum> allowed = new HashSet <AsmSignatureEnum>(); int commaCount = AsmSignature.Count_Commas(lineStr); IEnumerable <AsmSignatureElement> allSignatures = this._asmDudeTools.Mnemonic_Store.GetSignatures(mnemonic); ISet <Arch> selectedArchitectures = AsmDudeToolsStatic.Get_Arch_Swithed_On(); foreach (AsmSignatureElement se in AsmSignatureHelpSource.Constrain_Signatures(allSignatures, operands, selectedArchitectures)) { if (commaCount < se.Operands.Count) { foreach (AsmSignatureEnum s in se.Operands[commaCount]) { allowed.Add(s); } } } IEnumerable <Completion> completions = this.Mnemonic_Operand_Completions(useCapitals, allowed, line.LineNumber); if (completions.Any()) { completionSets.Add(new CompletionSet("All", "All", applicableTo, completions, Enumerable.Empty <Completion>())); } } } #endregion AsmDudeToolsStatic.Print_Speed_Warning(time1, "Code Completion"); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR(string.Format("{0}:AugmentCompletionSession; e={1}", this.ToString(), e.ToString())); } }