public static void OnCurrentFileChanged() { string file = Npp.GetCurrentFile(); string dbg = CSScriptHelper.GetDbgInfoFile(file); if (File.Exists(dbg)) { PlaceBreakPointsForCurrentTab(); } if (!IsRunning) { OnNextFileOpenComplete = null; Npp.ClearIndicator(INDICATOR_DEBUGSTEP, 0, -1); //clear all document } else { if (OnNextFileOpenComplete != null) { OnNextFileOpenComplete(); OnNextFileOpenComplete = null; } } if (OnBreakpointChanged != null) { OnBreakpointChanged(); } }
public void RefreshContent() { string file = Npp.GetCurrentFile(); if (file.IsScriptFile() || file.IsPythonFile()) { membersList.Visible = true; if (file != currentFile) { currentFile = file; watcher.Path = Path.GetDirectoryName(currentFile); watcher.Filter = Path.GetFileName(currentFile); } if (file.IsScriptFile()) { GenerateContent(Npp.GetTextBetween(0)); } else if (file.IsPythonFile()) { GenerateContentPython(Npp.GetTextBetween(0)); } } else { membersList.Visible = false; } }
public static void EnsureIntellisenseIntegration() { //Debug.Assert(false); //Merge Configs CSScriptIntellisense.Config.Location = Plugin.ConfigDir; CSScriptNpp.Config.InitData(); //will also exchange required data between configs CSScriptIntellisense.Plugin.SuppressCodeTolltips = () => Debugger.IsInBreak; CSScriptIntellisense.Plugin.DisplayInOutputPanel = message => { Plugin.EnsureOutputPanelVisible(); OutputPanel.DisplayInGenericOutputPanel(message); }; CSScriptIntellisense.Plugin.ResolveCurrentFile = () => { if (string.IsNullOrEmpty(ProjectPanel.currentScript)) { return(Npp.GetCurrentFile()); } else { return(ProjectPanel.currentScript); } }; }
static public void ToggleBreakpoint(int lineClick = -1) { string file = Npp.GetCurrentFile(); int line = 0; if (lineClick != -1) { line = lineClick; } else { line = Npp.GetCaretLineNumber(); } bool isAutoGenerated = file.EndsWith(".g.cs", StringComparison.OrdinalIgnoreCase); if (!isAutoGenerated) { ToggleBreakpoint(file, line); } if (OnBreakpointChanged != null) { OnBreakpointChanged(); } }
private static void ClearDebuggingMarkers() { if (lastLocation != null) { if (string.Compare(Npp.GetCurrentFile(), lastLocation.File, true) == 0) { Npp.ClearIndicator(INDICATOR_DEBUGSTEP, lastLocation.Start, lastLocation.End); Npp.DeleteAllMarkers(MARK_DEBUGSTEP); } } }
public static void RefreshBreakPointsFromContent() { var chengedFiles = new List <string>(); var currFile = Npp.GetCurrentFile(); foreach (string key in breakpoints.Keys.ToArray()) { //IMPORTANT: GetLineOfMarker returns line form the handle of the marker within a //current file. Value of handles are file specific and reused between the files/documents. //This is because marker handles are just marker indexes within a document. //Thus resolving a given handle for a non current document can in fact return a proper line //of the current doc if it has the marker with the same handle value. This already led to //the break points drifting. if (!key.StartsWith(currFile, StringComparison.OrdinalIgnoreCase)) { continue; } IntPtr marker = breakpoints[key]; if (marker != IntPtr.Zero) { int line = Npp.GetLineOfMarker(marker); if (line != -1 && !key.EndsWith("|" + (line + 1))) { //key = <file>|<line + 1> //server debugger operates in '1-based' and NPP in '0-based' lines string file = key.Split('|').First(); if (!chengedFiles.Contains(file)) { chengedFiles.Add(file); } string newKey = file + "|" + (line + 1); breakpoints.Remove(key); if (breakpoints.ContainsKey(newKey)) { breakpoints.Add(newKey, marker); } else { breakpoints[newKey] = marker; } } } } if (OnBreakpointChanged != null) { OnBreakpointChanged(); } }
static public void SetInstructionPointer() { if (IsRunning && IsInBreak) { ClearDebuggingMarkers(); int line = TranslateSourceLineLocation(Npp.GetCurrentFile(), Npp.GetCaretLineNumber()); DebuggerServer.SetInstructionPointer(line + 1); //debugger is 1-based DebuggerServer.Break(); //need to break to trigger reporting the current step } }
static public void RunToCursor() { if (IsRunning && IsInBreak) { string file = Npp.GetCurrentFile(); int line = Npp.GetCaretLineNumber(); string key = BuildBreakpointKey(file, line); string actualBreakpoint = TranslateSourceBreakpoint(key); DebuggerServer.AddBreakpoint(actualBreakpoint); DebuggerServer.Go(); DebuggerServer.OnBreak = () => { DebuggerServer.RemoveBreakpoint(actualBreakpoint); }; } }
static public void SaveAllButNew() { //Win32.SendMessage(Npp.NppHandle, NppMsg.NPPM_SAVEALLFILES, 0, 0); var files = Npp.GetOpenFiles(); var current = Npp.GetCurrentFile(); foreach (var item in files) { if (Path.IsPathRooted(item)) //the "new" file is not saved so it has no root { Npp.OpenFile(item); Win32.SendMessage(Npp.NppHandle, NppMsg.NPPM_SAVECURRENTFILE, 0, 0); } } Npp.OpenFile(current); }
static public void RestartNpp(int?afterProcessExit = null) { Win32.SendMenuCmd(Npp.NppHandle, NppMenuCmd.IDM_FILE_EXIT, 0); string file = Npp.GetCurrentFile(); if (string.IsNullOrEmpty(file)) //the Exit request has been processed and user did not cancel it { Application.DoEvents(); int processIdToWaitForExit = afterProcessExit ?? Process.GetCurrentProcess().Id; string appToStart = Process.GetCurrentProcess().MainModule.FileName; string restarter = Path.Combine(Plugin.PluginDir, "launcher.exe"); //the re-starter will also wait for this process to exit Process.Start(restarter, string.Format("/start {0} \"{1}\"", processIdToWaitForExit, appToStart)); } }
static public void SaveDocuments(string[] files) { var filesToSave = files.Select(x => Path.GetFullPath(x)); var openFiles = Npp.GetOpenFiles(); var current = Npp.GetCurrentFile(); foreach (var item in files) { if (Path.IsPathRooted(item)) //the "new" file is not saved so it has no root { var path = Path.GetFullPath(item); if (filesToSave.Contains(path)) { Npp.OpenFile(item); Win32.SendMessage(Npp.NppHandle, NppMsg.NPPM_SAVECURRENTFILE, 0, 0); } } } Npp.OpenFile(current); }
private static void PlaceBreakPointsForCurrentTab() { try { string file = Npp.GetCurrentFile(); string expectedkeyPrefix = file + "|"; string[] fileBreakpoints = breakpoints.Keys.Where(x => x.StartsWith(expectedkeyPrefix, StringComparison.OrdinalIgnoreCase)).ToArray(); foreach (var key in fileBreakpoints) { if (breakpoints[key] == IntPtr.Zero) //not placed yet { //key = <file>|<line + 1> //server debugger operates in '1-based' and NPP in '0-based' lines int line = int.Parse(key.Split('|').Last()) - 1; breakpoints[key] = Npp.PlaceMarker(MARK_BREAKPOINT, line); } } } catch { } }
static public void NavigateToFileLocation(string sourceLocation) { var location = FileLocation.Parse(sourceLocation); location.Start = Npp.CharOffsetToPosition(location.Start, location.File); location.End = Npp.CharOffsetToPosition(location.End, location.File); TranslateCompiledLocation(location); if (File.Exists(location.File)) { if (Npp.GetCurrentFile().IsSameAs(location.File, true)) { ShowBreakpointSourceLocation(location); } else { OnNextFileOpenComplete = () => ShowBreakpointSourceLocation(location); Npp.OpenFile(location.File); //needs to by asynchronous } } }
static void beNotified(IntPtr notifyCode) { try { CSScriptIntellisense.Interop.NppUI.OnNppTick(); SCNotification nc = (SCNotification)Marshal.PtrToStructure(notifyCode, typeof(SCNotification)); //Debug.WriteLine(">>>>> ncnc.nmhdr.code={0}, {1}", nc.nmhdr.code, (int)nc.nmhdr.code); if (nc.nmhdr.code == (uint)NppMsg.NPPN_READY) { CSScriptIntellisense.Plugin.OnNppReady(); CSScriptNpp.Plugin.OnNppReady(); Npp.SetCalltipTime(500); } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_SHUTDOWN) { CSScriptNpp.Plugin.StopVBCSCompilers(); } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_TBMODIFICATION) { CSScriptNpp.Plugin.OnToolbarUpdate(); } else if (nc.nmhdr.code == (uint)NppMsg.NPPM_SAVECURRENTFILEAS || (Config.Instance.HandleSaveAs && nc.nmhdr.code == (uint)SciMsg.SCN_SAVEPOINTREACHED)) //for some strange reason NPP doesn't fire NPPM_SAVECURRENTFILEAS but does 2002 instead. { string file = Npp.GetCurrentFile(); if (file != lastActivatedBuffer) { CSScriptNpp.Plugin.OnFileSavedAs(lastActivatedBuffer, file); } } else if (nc.nmhdr.code == (uint)SciMsg.SCN_CHARADDED) { CSScriptIntellisense.Plugin.OnCharTyped((char)nc.ch); } //else if (nc.nmhdr.code == (uint)SciMsg.SCN_KEY) //{ // System.Diagnostics.Debug.WriteLine("SciMsg.SCN_KEY"); //} else if (nc.nmhdr.code == (uint)SciMsg.SCN_MARGINCLICK) { if (nc.margin == _SC_MARGE_SYBOLE && nc.modifiers == SCI_CTRL) { int lineClick = Npp.GetLineFromPosition(nc.position); Debugger.ToggleBreakpoint(lineClick); } } else if (nc.nmhdr.code == (uint)SciMsg.SCN_DWELLSTART) //tooltip { //Npp.ShowCalltip(nc.position, "\u0001 1 of 3 \u0002 test tooltip " + Environment.TickCount); //Npp.ShowCalltip(nc.position, CSScriptIntellisense.Npp.GetWordAtPosition(nc.position)); //tooltip = @"Creates all directories and subdirectories as specified by path. Npp.OnCalltipRequest(nc.position); } else if (nc.nmhdr.code == (uint)SciMsg.SCN_DWELLEND) { Npp.CancelCalltip(); } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_BUFFERACTIVATED) { string file = Npp.GetCurrentFile(); lastActivatedBuffer = file; if (file.EndsWith("npp.args")) { Win32.SendMessage(Npp.NppHandle, NppMsg.NPPM_MENUCOMMAND, 0, NppMenuCmd.IDM_FILE_CLOSE); string args = File.ReadAllText(file); Plugin.ProcessCommandArgs(args); try { File.Delete(file); } catch { } } else { CSScriptIntellisense.Plugin.OnCurrentFileChanegd(); CSScriptNpp.Plugin.OnCurrentFileChanged(); Debugger.OnCurrentFileChanged(); } } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_FILEOPENED) { string file = Npp.GetTabFile((int)nc.nmhdr.idFrom); Debugger.LoadBreakPointsFor(file); } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_FILESAVED || nc.nmhdr.code == (uint)NppMsg.NPPN_FILEBEFORECLOSE) { string file = Npp.GetTabFile((int)nc.nmhdr.idFrom); Debugger.RefreshBreakPointsFromContent(); Debugger.SaveBreakPointsFor(file); if (nc.nmhdr.code == (uint)NppMsg.NPPN_FILESAVED) { Plugin.OnDocumentSaved(); } } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_FILEBEFORESAVE) { CSScriptIntellisense.Plugin.OnBeforeDocumentSaved(); } else if (nc.nmhdr.code == (uint)NppMsg.NPPN_SHUTDOWN) { Marshal.FreeHGlobal(_ptrPluginName); Plugin.CleanUp(); } if (nc.nmhdr.code == (uint)SciMsg.SCI_ENDUNDOACTION) { //CSScriptIntellisense.Plugin.OnSavedOrUndo(); } Plugin.OnNotification(nc); } catch { }//this is indeed the last line of defense as all CS-S calls have the error handling inside }
public void RefreshProjectStructure() { this.InUiThread(() => { if (Npp.GetCurrentFile() == currentScript) { try { Project project = CSScriptHelper.GenerateProjectFor(currentScript); treeView1.BeginUpdate(); /* * root * references * assembly_1 * assembly_2 * assembly_n * script_1 * script_2 * script_N */ TreeNode root = treeView1.Nodes[0]; TreeNode references = root.Nodes[0]; Action <TreeNode, string[]> updateNode = (node, files) => { string[] currentFiles = node.Nodes .Cast <TreeNode>() .Where(x => x.Tag is ProjectItem) .Select(x => (x.Tag as ProjectItem).File) .ToArray(); string[] newItems = files.Except(currentFiles).ToArray(); var orphantItems = node.Nodes .Cast <TreeNode>() .Where(x => x.Tag is ProjectItem) .Where(x => !files.Contains((x.Tag as ProjectItem).File)) .Where(x => x != root && x != references) .ToArray(); orphantItems.ForEach(x => node.Nodes.Remove(x)); newItems.ForEach(file => { int imageIndex = includeImage; var info = new ProjectItem(file) { IsPrimary = (file == project.PrimaryScript) }; if (info.IsAssembly) { imageIndex = assemblyImage; } node.Nodes.Add(new TreeNode(info.Name) { ImageIndex = imageIndex, SelectedImageIndex = imageIndex, Tag = info, ToolTipText = file, ContextMenuStrip = itemContextMenu }); }); }; updateNode(references, project.Assemblies); updateNode(root, project.SourceFiles); root.Expand(); treeView1.EndUpdate(); } catch (Exception e) { e.LogAsError(); } } }); }
void favoritesBtn_Click(object sender, EventArgs e) { tabControl1.SelectTabWith(favPanel); favPanel.Add(Npp.GetCurrentFile()); }
static public void OnCalltipRequest(int position) { if (position == -2) { Calltip.LastEval = Calltip.LastExpression = null; //if DBG frame is changed so clear the data } else { if (Calltip.IsShowing) { return; } Calltip.IsShowing = true; Task.Factory.StartNew(() => //must be asynch to allow processing other Debugger notifications { string underMouseExpression = CSScriptIntellisense.Npp.GetStatementAtPosition(position); string document = Npp.GetCurrentFile(); string tooltip = null; //if (Debugger.IsInBreak) //The calltips are used to show the values of the variables only. For everything else (e.g. MemberInfo) modal borderless forms are used //{ if (!string.IsNullOrEmpty(underMouseExpression)) { //also need to check expression start position (if not debugging) as the same expression can lead to different tooltip //NOTE: if DBG frame is changed the LastExpression is cleared if (underMouseExpression == Calltip.LastExpression && Calltip.LastDocument == document) { if (Debugger.IsInBreak) { tooltip = Calltip.LastEval; } } //if (underMouseExpression != Calltip.LastExpression) //{ // System.Diagnostics.Debug.WriteLine("GetDebugTooltipValue -> expression is changed..."); // System.Diagnostics.Debug.WriteLine("old: " + Calltip.LastExpression); // System.Diagnostics.Debug.WriteLine("new: " + underMouseExpression); //} //if (Calltip.LastDocument != document) // System.Diagnostics.Debug.WriteLine("GetDebugTooltipValue -> document is changed..."); if (tooltip == null) { if (Debugger.IsInBreak) { tooltip = Debugger.GetDebugTooltipValue(underMouseExpression); } else if (CSScriptIntellisense.Config.Instance.ShowQuickInfoAsNativeNppTooltip) { tooltip = CSScriptIntellisense.Plugin.GetMemberUnderCursorInfo().FirstOrDefault(); } Calltip.LastDocument = document; Calltip.LastEval = tooltip.TruncateLines(Config.Instance.CollectionItemsInTooltipsMaxCount, "\n<Content was truncated. Use F12 to see the raw API documentation data.>"); Calltip.LastExpression = underMouseExpression; } if (tooltip != null) { Npp.ShowCalltip(position, tooltip); return; } } Calltip.IsShowing = false; }); } }