/// <summary> /// Set font of code completion /// tools>options>Environment>Fonts and Colors>statement completion>courier new. /// https://msdn.microsoft.com/en-us/library/bb166382.aspx /// </summary> private void changeFontAutoComplete() { // experiments to change the font of the autocomplate try { DTE vsEnvironment = (DTE)GetService(typeof(SDTE)); if (false) // test to retrieve asm dude properties { EnvDTE.Properties asmDudePropertiesList = vsEnvironment.get_Properties("AsmDude", "Asm Documentation"); if (asmDudePropertiesList != null) { string url = asmDudePropertiesList.Item("_asmDocUrl").Value as string; AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, "INFO: {0}:changeFontAutoComplete. url=", this.ToString(), url)); } } if (false) { EnvDTE.Properties propertiesList = vsEnvironment.get_Properties("TextEditor", "Basic"); if (propertiesList != null) { Property tabSize = propertiesList.Item("TabSize"); short oldSize = (short)tabSize.Value; string message; if (oldSize != 4) { tabSize.Value = 4; message = string.Format(CultureInfo.CurrentUICulture, "For Basic, the Text Editor had a tab size of {0}" + " and now has a tab size of {1}.", oldSize, tabSize.Value); } else { message = string.Format(CultureInfo.CurrentUICulture, "For Basic, the Text Editor has a tab size of {0}.", tabSize.Value); } AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, message)); } } if (false) { //EnvDTE.Properties propertiesList = vsEnvironment.get_Properties("Environment", "Keyboard"); //EnvDTE.Property prop = propertiesList.Item("Scheme"); //AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, "INFO: {0}:changeFontAutoComplete; prop={1}", this.ToString(), prop.Value)); EnvDTE.Properties propertiesList = vsEnvironment.get_Properties("Environment", "Fonts and Colors"); if (propertiesList != null) { AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, "INFO: {0}:changeFontAutoComplete; prop={1}", this.ToString())); } //EnvDTE.Property prop = propertiesList.Item("Scheme"); //AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, "INFO: {0}:changeFontAutoComplete; prop={1}", this.ToString(), prop.Value)); } } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, "ERROR: {0}:changeFontAutoComplete {1}", this.ToString(), e.Message)); } }
private void initMenus() { // Now get the OleCommandService object provided by the MPF; this object is the one // responsible for handling the collection of commands implemented by the package. OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (null == mcs) { AsmDudeToolsStatic.Output("WARNING: could not retrieve the IMenuCommandService."); } else { AsmDudeToolsStatic.Output("INFO: retrieved the IMenuCommandService."); // Now create one object derived from MenuCommand for each command defined in // the VSCT file and add it to the command service. // For each command we have to define its id that is a unique Guid/integer pair. CommandID id = new CommandID(Guids.guidMenuAndCommandsCmdSet, PkgCmdIDList.cmdidMyCommand); // Now create the OleMenuCommand object for this command. The EventHandler object is the // function that will be called when the user will select the command. OleMenuCommand command = new OleMenuCommand(new EventHandler(MenuCommandCallback), id); // Add the command to the command service. mcs.AddCommand(command); // Create the MenuCommand object for the command placed in the main toolbar. id = new CommandID(Guids.guidMenuAndCommandsCmdSet, PkgCmdIDList.cmdidMyGraph); command = new OleMenuCommand(new EventHandler(GraphCommandCallback), id); mcs.AddCommand(command); // Create the MenuCommand object for the command placed in our toolbar. id = new CommandID(Guids.guidMenuAndCommandsCmdSet, PkgCmdIDList.cmdidMyZoom); command = new OleMenuCommand(new EventHandler(ZoomCommandCallback), id); mcs.AddCommand(command); // Create the DynamicMenuCommand object for the command defined with the TextChanges // flag. id = new CommandID(Guids.guidMenuAndCommandsCmdSet, PkgCmdIDList.cmdidDynamicTxt); command = new DynamicTextCommand(id, VsPackage.ResourceManager.GetString("DynamicTextBaseText")); mcs.AddCommand(command); // Now create two OleMenuCommand objects for the two commands with dynamic visibility id = new CommandID(Guids.guidMenuAndCommandsCmdSet, PkgCmdIDList.cmdidDynVisibility1); dynamicVisibilityCommand1 = new OleMenuCommand(new EventHandler(DynamicVisibilityCallback), id); mcs.AddCommand(dynamicVisibilityCommand1); id = new CommandID(Guids.guidMenuAndCommandsCmdSet, PkgCmdIDList.cmdidDynVisibility2); dynamicVisibilityCommand2 = new OleMenuCommand(new EventHandler(DynamicVisibilityCallback), id); // This command is the one that is invisible by default, so we have to set its visible // property to false because the default value of this property for every object derived // from MenuCommand is true. dynamicVisibilityCommand2.Visible = false; mcs.AddCommand(dynamicVisibilityCommand2); } }
#pragma warning disable 1998 protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress) #pragma warning restore 1998 { StringBuilder sb = new StringBuilder(); sb.Append("Welcome to\n"); sb.Append(" _____ ____ _ \n"); sb.Append("| _ |___ _____ | \\ _ _ _| |___ \n"); sb.Append("| |_ -| | | | | | | . | -_|\n"); sb.Append("|__|__|___|_|_|_| |____/|___|___|___|\n"); sb.Append("INFO: Loaded AsmDude version " + typeof(AsmDudePackage).Assembly.GetName().Version + " (" + ApplicationInformation.CompileDate.ToString() + ")\n"); sb.Append("INFO: Open source assembly extension. Making programming in assembler almost bearable.\n"); sb.Append("INFO: More info at https://github.com/HJLebbink/asm-dude \n"); sb.Append("----------------------------------"); AsmDudeToolsStatic.Output(sb.ToString()); ClearMefCache.ClearMefCache.Initialize(this); }
/// <summary> /// get url for the provided keyword. Returns empty string if the keyword does not exist or the keyword does not have an url. /// </summary> public string Get_Url(string keyword) { // no need to pre-process this information. try { string keywordUpper = keyword.ToUpper(); Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(keyword); if (mnemonic != Mnemonic.UNKNOWN) { string url = this.Mnemonic_Store.GetHtmlRef(mnemonic); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:getUrl: keyword {1}; url {2}.", this.ToString(), keyword, url)); return(url); } return(""); } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:getUrl: exception {1}.", ToString(), e.ToString())); return(""); } }
/// <summary> /// Initialization of the package. This is where you should put all initialization /// code that depends on VS services. /// </summary> protected override void Initialize() { base.Initialize(); this.initMenus(); this.changeFontAutoComplete(); StringBuilder sb = new StringBuilder(); sb.AppendLine(@" _____ ____ _ "); sb.AppendLine(@"| _ |___ _____| \ _ _ _| |___ "); sb.AppendLine(@"| |_ -| | | | | | . | -_|"); sb.AppendLine(@"|__|__|___|_|_|_|____/|___|___|___|"); sb.AppendLine(string.Format("INFO: Loaded AsmDude version {0}.", typeof(AsmDudePackage).Assembly.GetName().Version)); sb.AppendLine(string.Format("INFO: Open source assembly plugin. Making programming in assembler bearable.")); sb.AppendLine(string.Format("INFO: More info at https://github.com/HJLebbink/asm-dude")); sb.AppendLine("----------------------------------"); sb.AppendLine(string.Format("INFO: Is the Tools>Options>AsmDude options pane invisible? Disable and enable this plugin to make it visible again...")); AsmDudeToolsStatic.Output(sb.ToString()); }
protected override void Initialize() { base.Initialize(); //this.disassemblyWindow(); //this.initMenus(); //this.changeFontAutoComplete(); StringBuilder sb = new StringBuilder(); sb.Append("Welcome to\n"); sb.Append(" _____ ____ _ \n"); sb.Append("| _ |___ _____ | \\ _ _ _| |___ \n"); sb.Append("| |_ -| | | | | | | . | -_|\n"); sb.Append("|__|__|___|_|_|_| |____/|___|___|___|\n"); sb.Append("INFO: Loaded AsmDude version " + typeof(AsmDudePackage).Assembly.GetName().Version + " (" + ApplicationInformation.CompileDate.ToString() + ")\n"); sb.Append("INFO: Open source assembly extension. Making programming in assembler almost bearable.\n"); sb.Append("INFO: More info at https://github.com/HJLebbink/asm-dude \n"); sb.Append("----------------------------------"); AsmDudeToolsStatic.Output(sb.ToString()); }
public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets) { //AsmDudeToolsStatic.Output(string.Format(CultureInfo.CurrentCulture, "INFO: {0}:AugmentCompletionSession", this.ToString())); if (!Settings.Default.CodeCompletion_On) { return; } if (_disposed) { throw new ObjectDisposedException("AsmCompletionSource"); } try { 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 if (AsmCompletionSource.isRemark(triggerPoint, line.Start)) { return; } //2] find the start of the current keyword SnapshotPoint start = triggerPoint; while ((start > line.Start) && !AsmTools.Tools.isSeparatorChar((start - 1).GetChar())) { start -= 1; } //3] get the word that is currently being typed var applicableTo = snapshot.CreateTrackingSpan(new SnapshotSpan(start, triggerPoint), SpanTrackingMode.EdgeInclusive); string partialKeyword = applicableTo.GetText(snapshot); bool useCapitals = AsmDudeToolsStatic.isAllUpper(partialKeyword); //4] get the previous keyword to narrow down the possible suggestions string previousKeyword = AsmCompletionSource.getPreviousKeyword(line.Start, start); IList <Completion> completions = null; if ((previousKeyword.Length == 0) || this.isLabel(previousKeyword)) { // no previous keyword exists. Do not suggest a register HashSet <TokenType> selected = new HashSet <TokenType> { TokenType.Directive, TokenType.Jump, TokenType.Misc, TokenType.Mnemonic /*, TokenType.Register*/ }; completions = this.selectedCompletions(useCapitals, selected); } else if (this.isJump(previousKeyword)) { // previous keyword is jump (or call) mnemonic. Suggest "SHORT" or a label completions = this.labelCompletions(); completions.Add(new Completion("SHORT", (useCapitals) ? "SHORT" : "short", null, this._icons[TokenType.Misc], "")); } else if (previousKeyword.Equals("SHORT")) { // previous keyword is SHORT. Suggest a label completions = this.labelCompletions(); } else if (this.isRegister(previousKeyword)) { // if the previous keyword is a register, suggest registers (of equal size), no opcodes and no directives HashSet <TokenType> selected = new HashSet <TokenType> { /*TokenType.Directive, TokenType.Jump,*/ TokenType.Misc, /*TokenType.Mnemonic,*/ TokenType.Register }; completions = this.selectedCompletions(useCapitals, selected); } else if (this.isMnemonic(previousKeyword)) { // if previous keyword is a mnemonic (no jump). Do not suggest a Mnemonic or directive HashSet <TokenType> selected = new HashSet <TokenType> { /*TokenType.Directive, TokenType.Jump,*/ TokenType.Misc, /*TokenType.Mnemonic,*/ TokenType.Register }; completions = this.selectedCompletions(useCapitals, selected); } else { HashSet <TokenType> selected = new HashSet <TokenType> { TokenType.Directive, TokenType.Jump, TokenType.Misc, TokenType.Mnemonic, TokenType.Register }; completions = this.selectedCompletions(useCapitals, selected); } completionSets.Add(new CompletionSet("Tokens", "Tokens", applicableTo, completions, Enumerable.Empty <Completion>())); double elapsedSec = (double)(DateTime.Now.Ticks - time1.Ticks) / 10000000; if (elapsedSec > AsmDudePackage.slowWarningThresholdSec) { AsmDudeToolsStatic.Output(string.Format("WARNING: SLOW: took {0:F3} seconds to prepare code completion for previous keyword \"{1}\" and current keyword \"{2}\".", elapsedSec, previousKeyword, partialKeyword, elapsedSec)); } } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentCompletionSession; e={1}", this.ToString(), e.ToString())); } }
/// <summary> /// Singleton pattern: use AsmDudeTools.Instance for the instance of this class /// </summary> private AsmDudeTools() { //AsmDudeToolsStatic.Output(string.Format("INFO: AsmDudeTools constructor")); #region Initialize ErrorListProvider IServiceProvider serviceProvider = new ServiceProvider(Package.GetGlobalService(typeof(Microsoft.VisualStudio.OLE.Interop.IServiceProvider)) as Microsoft.VisualStudio.OLE.Interop.IServiceProvider); this._errorListProvider = new ErrorListProvider(serviceProvider) { ProviderName = "Asm Errors", ProviderGuid = new Guid(EnvDTE.Constants.vsViewKindCode) }; #endregion this._smartThreadPool = new SmartThreadPool(); //this._smartThreadPool.Start(); // There seems no need to start this threadpool #region load Signature Store and Performance Store string path = AsmDudeToolsStatic.Get_Install_Path() + "Resources" + Path.DirectorySeparatorChar; { //string filename = path + "mnemonics-nasm.txt"; string filename_Regular = path + "signature-june2016.txt"; string filename_Hand = path + "signature-hand-1.txt"; this._mnemonicStore = new MnemonicStore(filename_Regular, filename_Hand); } { this._performanceStore = new PerformanceStore(); this._performanceStore.AddData(MicroArch.Broadwell, path + "Performance" + Path.DirectorySeparatorChar + "Broadwell.tsv"); this._performanceStore.AddData(MicroArch.Skylake, path + "Performance" + Path.DirectorySeparatorChar + "Skylake.tsv"); } #endregion Init_Data(); #region Experiments if (false) { string filename2 = AsmDudeToolsStatic.Get_Install_Path() + "Resources" + Path.DirectorySeparatorChar + "mnemonics-nasm.txt"; MnemonicStore store2 = new MnemonicStore(filename2, null); ISet <String> archs = new SortedSet <String>(); IDictionary <string, string> signaturesIntel = new Dictionary <string, string>(); IDictionary <string, string> signaturesNasm = new Dictionary <string, string>(); foreach (Mnemonic mnemonic in Enum.GetValues(typeof(Mnemonic))) { IList <AsmSignatureElement> intel = this._mnemonicStore.GetSignatures(mnemonic); IList <AsmSignatureElement> nasm = store2.GetSignatures(mnemonic); signaturesIntel.Clear(); signaturesNasm.Clear(); foreach (AsmSignatureElement e in intel) { string instruction = e.Mnemonic.ToString() + " " + e.Operands_Str; if (signaturesIntel.ContainsKey(instruction)) { AsmDudeToolsStatic.Output("WARNING: Intel " + instruction + ": is already present with arch " + signaturesIntel[instruction] + "; new arch " + e.Arch_Str); } else { signaturesIntel.Add(instruction, e.Arch_Str); } } foreach (AsmSignatureElement e in nasm) { string instruction = e.Mnemonic.ToString() + " " + e.Operands_Str; if (signaturesNasm.ContainsKey(instruction)) { // AsmDudeToolsStatic.Output("WARNING: Nasm " + instruction + ": is already present with arch " + signaturesNasm[instruction] + "; new arch " + e.archStr); } else { signaturesNasm.Add(instruction, e.Arch_Str); } } foreach (AsmSignatureElement e in intel) { string instruction = e.Mnemonic.ToString() + " " + e.Operands_Str; //AsmDudeToolsStatic.Output("Intel " + instruction + ": arch" + e.archStr); if ((e.Arch_Str == null) || (e.Arch_Str.Length == 0)) { if (signaturesNasm.ContainsKey(instruction)) { AsmDudeToolsStatic.Output("Intel " + instruction + " has no arch, but NASM has \"" + signaturesNasm[instruction] + "\"."); } else { if (signaturesNasm.Count == 1) { AsmDudeToolsStatic.Output("Intel " + instruction + " has no arch, but NASM has \"" + signaturesNasm.GetEnumerator().Current + "\"."); } else { AsmDudeToolsStatic.Output("Intel " + instruction + " has no arch:"); foreach (KeyValuePair <string, string> pair in signaturesNasm) { AsmDudeToolsStatic.Output("\tNASM has " + pair.Key + ": \"" + pair.Value + "\"."); } AsmDudeToolsStatic.Output(" ----"); } } } } if (false) { if (intel.Count != nasm.Count) { foreach (AsmSignatureElement e in intel) { AsmDudeToolsStatic.Output("INTEL " + mnemonic + ": " + e); } foreach (AsmSignatureElement e in nasm) { AsmDudeToolsStatic.Output("NASM " + mnemonic + ": " + e); } } } } foreach (String str in archs) { AsmDudeToolsStatic.Output("INTEL arch " + str); } } if (false) { foreach (Arch arch in Enum.GetValues(typeof(Arch))) { int counter = 0; ISet <Mnemonic> usedMnemonics = new HashSet <Mnemonic>(); foreach (Mnemonic mnemonic in Enum.GetValues(typeof(Mnemonic))) { if (this.Mnemonic_Store.GetArch(mnemonic).Contains(arch)) { //AsmDudeToolsStatic.Output("INFO: AsmDudeTools constructor: arch="+arch+"; mnemonic=" + mnemonic); counter++; usedMnemonics.Add(mnemonic); } } string str = ""; foreach (Mnemonic mnemonic in usedMnemonics) { str += mnemonic.ToString() + ","; } AsmDudeToolsStatic.Output("INFO: AsmDudeTools constructor: Architecture Option " + arch + " enables mnemonics " + str); } } if (false) { foreach (Mnemonic mnemonic in Enum.GetValues(typeof(Mnemonic))) { string keyword = mnemonic.ToString().ToUpper(); if (this._description.ContainsKey(keyword)) { string description = this._description[keyword]; string reference = Get_Url(keyword); this.Mnemonic_Store.SetHtmlRef(mnemonic, reference); } } AsmDudeToolsStatic.Output(this.Mnemonic_Store.ToString()); } if (false) { ISet <string> archs = new HashSet <string>(); foreach (Mnemonic mnemonic in Enum.GetValues(typeof(Mnemonic))) { if (!this._mnemonicStore.HasElement(mnemonic)) { AsmDudeToolsStatic.Output("INFO: AsmDudeTools constructor: mnemonic " + mnemonic + " is not present"); } foreach (AsmSignatureElement e in this._mnemonicStore.GetSignatures(mnemonic)) { foreach (string s in e.Arch_Str.Split(',')) { archs.Add(s.Trim()); } } } foreach (string s in archs) { AsmDudeToolsStatic.Output(s + ","); } } #endregion }
public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets) { //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentCompletionSession", this.ToString())); if (_disposed) { return; } if (!Settings.Default.CodeCompletion_On) { return; } try { 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) && !AsmTools.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.isAllUpper(partialKeyword); SortedSet <Completion> completions = null; string lineStr = line.GetText(); var t = AsmSourceTools.parseLine(lineStr); Mnemonic mnemonic = t.Item2; if (mnemonic == Mnemonic.UNKNOWN) { ISet <AsmTokenType> selected = new HashSet <AsmTokenType> { AsmTokenType.Directive, AsmTokenType.Jump, AsmTokenType.Misc, AsmTokenType.Mnemonic /*, AsmTokenType.Register */ }; completions = this.selectedCompletions(useCapitals, selected); } else // the current line contains a mnemonic { string previousKeyword = AsmDudeToolsStatic.getPreviousKeyword(line.Start, start); //AsmDudeToolsStatic.Output("INFO: AsmCompletionSource:AugmentCompletionSession; mnemonic=" + mnemonic+ "; previousKeyword="+ previousKeyword); if (AsmSourceTools.isJump(AsmSourceTools.parseMnemonic(previousKeyword))) { //AsmDudeToolsStatic.Output("INFO: AsmCompletionSource:AugmentCompletionSession; previous keyword is a jump mnemonic"); // previous keyword is jump (or call) mnemonic. Suggest "SHORT" or a label completions = this.labelCompletions(); completions.Add(new Completion("SHORT", (useCapitals) ? "SHORT" : "short", null, this._icons[AsmTokenType.Misc], "")); completions.Add(new Completion("NEAR", (useCapitals) ? "NEAR" : "near", null, this._icons[AsmTokenType.Misc], "")); } else if (previousKeyword.Equals("SHORT") || previousKeyword.Equals("NEAR")) { // previous keyword is SHORT. Suggest a label completions = this.labelCompletions(); } else { IList <Operand> operands = AsmSourceTools.makeOperands(t.Item3); ISet <AsmSignatureEnum> allowed = new HashSet <AsmSignatureEnum>(); int commaCount = AsmSignature.countCommas(lineStr); IList <AsmSignatureElement> allSignatures = this._asmDudeTools.mnemonicStore.getSignatures(mnemonic); ISet <Arch> selectedArchitectures = AsmDudeToolsStatic.getArchSwithedOn(); foreach (AsmSignatureElement se in AsmSignatureHelpSource.constrainSignatures(allSignatures, operands, selectedArchitectures)) { if (commaCount < se.operands.Count) { foreach (AsmSignatureEnum s in se.operands[commaCount]) { allowed.Add(s); } } } completions = this.mnemonicOperandCompletions(useCapitals, allowed); } } //AsmDudeToolsStatic.Output("INFO: AsmCompletionSource:AugmentCompletionSession; nCompletions=" + completions.Count); #endregion completionSets.Add(new CompletionSet("Tokens", "Tokens", applicableTo, completions, Enumerable.Empty <Completion>())); AsmDudeToolsStatic.printSpeedWarning(time1, "Code Completion"); } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentCompletionSession; e={1}", this.ToString(), e.ToString())); } }