From c57b7368bad4da26fdb5f2ffa3494e8c34322452 Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Tue, 23 Aug 2022 14:14:20 -0700 Subject: [PATCH 1/4] docs improvement for demo.cs, change WhatIsNpp WhatIsNpp previously continued writing text slowly even if the user switched files during the writing. This led to annoying addition of text to existing files with no way to stop it other than closing Notepad++. Now simply switching files will terminate this process. --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 44 ++++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 96bae70..e4128ac 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -222,6 +222,7 @@ static void callbackHelloFX() static void WhatIsNpp() { + // from https://notepad-plus-plus.org/ string text2display = "Notepad++ is a free (as in \"free speech\" and also as in \"free beer\") " + "source code editor and Notepad replacement that supports several languages.\n" + "Running in the MS Windows environment, its use is governed by GPL License.\n\n" + @@ -233,34 +234,53 @@ static void WhatIsNpp() new Thread(new ParameterizedThreadStart(callbackWhatIsNpp)).Start(text2display); } + /// + /// Open up a new file and slowly printing out the "What is NPP" text above.

+ /// Stops printing text if the new file is closed. + ///
+ /// static void callbackWhatIsNpp(object data) { string text2display = (string)data; notepad.FileNew(); + string new_file_name = getCurrentPath(NppMsg.FULL_CURRENT_PATH); Random srand = new Random(DateTime.Now.Millisecond); int rangeMin = 0; - int rangeMax = 250; + int rangeMax = 125; for (int i = 0; i < text2display.Length; i++) { Thread.Sleep(srand.Next(rangeMin, rangeMax) + 30); + // stop adding new text if the user closes or switches out of the new file. + // otherwise you get this obnoxious addition of text to existing files. + string selected_file_name = getCurrentPath(NppMsg.FULL_CURRENT_PATH); + if (selected_file_name != new_file_name) break; editor.AppendTextAndMoveCursor(text2display[i].ToString()); } } static void insertCurrentFullPath() { - insertCurrentPath(NppMsg.FULL_CURRENT_PATH); + editor.ReplaceSel(getCurrentPath(NppMsg.FULL_CURRENT_PATH)); } static void insertCurrentFileName() { - insertCurrentPath(NppMsg.FILE_NAME); + editor.ReplaceSel(getCurrentPath(NppMsg.FILE_NAME)); } static void insertCurrentDirectory() { - insertCurrentPath(NppMsg.CURRENT_DIRECTORY); + editor.ReplaceSel(getCurrentPath(NppMsg.CURRENT_DIRECTORY)); } - static void insertCurrentPath(NppMsg which) + + /// + /// Returns a property of the currently open file, depending on argument:

+ /// * If NppMsg.NPPM_GETFULLCURRENTPATH -> return absolute path to current file

+ /// * If NppMsg.NPPM_GETFILENAME -> return file name of current file

+ /// * If NppMsg.NPPM_GETCURRENTDIRECTORY -> return directory of current file

+ ///
+ /// + /// + static string getCurrentPath(NppMsg which) { NppMsg msg = NppMsg.NPPM_GETFULLCURRENTPATH; if (which == NppMsg.FILE_NAME) @@ -269,9 +289,9 @@ static void insertCurrentPath(NppMsg which) msg = NppMsg.NPPM_GETCURRENTDIRECTORY; StringBuilder path = new StringBuilder(Win32.MAX_PATH); - Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) msg, 0, path); + Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)msg, 0, path); - editor.ReplaceSel(path.ToString()); + return path.ToString(); } static void insertShortDateTime() @@ -293,7 +313,7 @@ static void checkInsertHtmlCloseTag() PluginBase.CheckMenuItemToggle(9, ref doCloseTag); // 9 = menu item index } - static Regex regex = new Regex(@"[\._\-:\w]", RegexOptions.Compiled); + static Regex XmlTagNameRegex = new Regex(@"[\._\-:\w]", RegexOptions.Compiled); static internal void doInsertHtmlCloseTag(char newChar) { @@ -335,7 +355,7 @@ static internal void doInsertHtmlCloseTag(char newChar) var insertString = new StringBuilder(" Date: Wed, 24 Aug 2022 19:38:41 -0700 Subject: [PATCH 2/4] add NanInf.cs for compiler errors with nan, inf MAJOR ADDITIONS Some issue (probably associated with IlMerge and more indirectly with [ildasm.exe](https://developercommunity.visualstudio.com/t/ildasmexe-regression-with-infinum-floating-point-v/545431) causes compiler errors whenever you use double.NegativeInfinity, double.PositiveInfinity, or double.NaN. You can use NanInf.neginf, NanInf.inf, and NanInf.nan instead. They're just generated at runtime. MINOR CHANGES Change the callbackWhatIsNpp function so that it prints text a little more quickly, and also stops printing text if the active file changes. That way it doesn't keep typing into existing files when you don't want it to. --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 16 ++++++++++ .../NppManagedPluginDemo.csproj | 1 + .../PluginInfrastructure/NanInf.cs | 30 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 Demo Plugin/NppManagedPluginDemo/PluginInfrastructure/NanInf.cs diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index e4128ac..1cdf114 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -136,6 +136,7 @@ static internal void CommandMenuInit() PluginBase.SetCommand(16, "---", null); PluginBase.SetCommand(17, "Print Scroll and Row Information", PrintScrollInformation); + PluginBase.SetCommand(18, "Use NanInf class for -inf, inf, nan!!", PrintNanInf); } /// @@ -412,6 +413,21 @@ static void saveCurrentSessionDemo() MessageBox.Show(sessionPath, "Saved Session File :", MessageBoxButtons.OK); } + static void PrintNanInf() + { + string naninf = $@"-infinity = NanInf.neginf = {NanInf.neginf} +infinity = NanInf.inf = {NanInf.inf} +NaN = NanInf.nan = {NanInf.nan} + +If you want these constants in your plugin, you can find them in the NanInf class in PluginInfrastructure. + +DO NOT USE double.PositiveInfinity, double.NegativeInfinity, or double.NaN. +You will get a compiler error if you do. "; + MessageBox.Show(naninf, "Use the NanInf class for NaN, -inf, inf!", MessageBoxButtons.OK, MessageBoxIcon.Warning); + notepad.FileNew(); + editor.AppendTextAndMoveCursor(naninf); + } + static void DockableDlgDemo() { // Dockable Dialog Demo diff --git a/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj b/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj index f71a267..bb2278d 100644 --- a/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj +++ b/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj @@ -121,6 +121,7 @@ frmGoToLine.cs + Resources.resx diff --git a/Demo Plugin/NppManagedPluginDemo/PluginInfrastructure/NanInf.cs b/Demo Plugin/NppManagedPluginDemo/PluginInfrastructure/NanInf.cs new file mode 100644 index 0000000..79f812e --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/PluginInfrastructure/NanInf.cs @@ -0,0 +1,30 @@ +using System; + +namespace Kbg.NppPluginNET.PluginInfrastructure +{ + /// + /// holds NaN, Infinity, and -Infinity as things generated at runtime

+ /// because the compiler freaks out if it sees any of

+ /// double.NegativeInfinity, double.PositiveInfinity, or double.NaN

+ /// or any statically analyzed function of two constants that makes one of those constants

+ /// like 1d/0d, 0d/0d, or -1d/0d. + ///
+ public class NanInf + { + /// + /// a/b

+ /// may be necessary to generate infinity or nan at runtime + /// to avoid the compiler pre-computing things

+ /// since if the compiler sees literal 1d/0d in the code + /// it just pre-computes it at compile time + ///
+ /// + /// + /// + public static double Divide(double a, double b) { return a / b; } + + public static readonly double inf = Divide(1d, 0d); + public static readonly double neginf = Divide(-1d, 0d); + public static readonly double nan = Divide(0d, 0d); + } +} From 45a6bef967f113d2229d8f00fe9bc0c048d83ce8 Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Fri, 26 Aug 2022 13:48:25 -0700 Subject: [PATCH 3/4] flag SetLexerLanguage, add JsonTools to plugins --- README.md | 1 + .../PluginInfrastructure/IScintillaGateway.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ccf325..2379c49 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ This is a fork of UFO's plugin package updated for VS2015, 2017 and 2019 * https://github.com/wakatime/notepadpp-wakatime * https://github.com/alex-ilin/WebEdit * https://github.com/Fruchtzwerg94/PlantUmlViewer + * https://github.com/molsonkiko/JsonToolsNppPlugin If your plugin is not on the list, please make a PR with a link to it.. :-) diff --git a/Visual Studio Project Template C#/PluginInfrastructure/IScintillaGateway.cs b/Visual Studio Project Template C#/PluginInfrastructure/IScintillaGateway.cs index 981e1b7..c19ac58 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/IScintillaGateway.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/IScintillaGateway.cs @@ -2516,7 +2516,10 @@ public interface IScintillaGateway /// Set up the key words used by the lexer. (Scintilla feature 4005) unsafe void SetKeyWords(int keyWordSet, string keyWords); - /// Set the lexing language of the document based on string name. (Scintilla feature 4006) + /// Set the lexing language of the document based on string name. (Scintilla feature 4006)

+ /// WARNING! This does not appear to do anything.

+ /// Use INotepadPPGateway.SetCurrentLanguage instead. + ///
unsafe void SetLexerLanguage(string language); /// Load a lexer library (dll / so). (Scintilla feature 4007) From a7ef5be3b809c263072e6028bea3bf5be7cedf5d Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Sun, 9 Oct 2022 20:09:17 -0700 Subject: [PATCH 4/4] change GetFilePath param from int to IntPtr Previously the GetFilePath method of NotepadPPGateway was unusable in 64-bit Notepad++ because it accepted an int parameter, but the buffer id (the IdFrom parameter of the NPPN_FILEBEFORECLOSE notification) could be 64-bit. Also added a new plugin command to Demo.cs illustrating how tracking the NPPN_FILEBEFORECLOSE notification allows the plugin to keep a list of all the filenames that were closed this session. --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 47 ++++++++++++++++++- .../PluginInfrastructure/NotepadPPGateway.cs | 4 +- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 1cdf114..a435ec1 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -1,5 +1,6 @@ // NPP plugin platform for .Net v0.91.57 by Kasper B. Graversen etc. using System; +using System.Collections.Generic; using System.IO; using System.Text; using System.Drawing; @@ -36,10 +37,33 @@ static internal void SetToolBarIcon() public static void OnNotification(ScNotification notification) { + uint code = notification.Header.Code; + // This method is invoked whenever something is happening in notepad++ + // use eg. as + // if (code == (uint)NppMsg.NPPN_xxx) + // { ... } + // or + // + // if (code == (uint)SciMsg.SCNxxx) + // { ... } + // when closing a file + if (code == (uint)NppMsg.NPPN_FILEBEFORECLOSE) + { + Kbg.Demo.Namespace.Main.AddToFilesClosed(notification.Header.IdFrom); + return; + } + if (notification.Header.Code == (uint)SciMsg.SCN_CHARADDED) { Kbg.Demo.Namespace.Main.doInsertHtmlCloseTag((char)notification.Character); + return; } + + //if (code > int.MaxValue) // windows messages + //{ + // int wm = -(int)code; + // } + //} } internal static string PluginName { get { return Kbg.Demo.Namespace.Main.PluginName; }} @@ -59,6 +83,7 @@ class Main static string sessionFilePath = @"C:\text.session"; static frmGoToLine frmGoToLine = null; static internal int idFrmGotToLine = -1; + static internal List filesClosedThisSession = new List(); // toolbar icons static Bitmap tbBmp = Properties.Resources.star; @@ -137,6 +162,7 @@ static internal void CommandMenuInit() PluginBase.SetCommand(17, "Print Scroll and Row Information", PrintScrollInformation); PluginBase.SetCommand(18, "Use NanInf class for -inf, inf, nan!!", PrintNanInf); + PluginBase.SetCommand(19, "Show files closed this session", FilesClosedThisSession); } /// @@ -413,6 +439,22 @@ static void saveCurrentSessionDemo() MessageBox.Show(sessionPath, "Saved Session File :", MessageBoxButtons.OK); } + public static void AddToFilesClosed(IntPtr buffer_closed_id) + { + string buffer_closed = notepad.GetFilePath(buffer_closed_id); + filesClosedThisSession.Add(buffer_closed); + } + + static void FilesClosedThisSession() + { + notepad.FileNew(); + StringBuilder sb = new StringBuilder(); + sb.AppendLine("Files closed this session:"); + foreach (string file_closed in filesClosedThisSession) + sb.AppendLine(file_closed); + editor.AppendTextAndMoveCursor(sb.ToString()); + } + static void PrintNanInf() { string naninf = $@"-infinity = NanInf.neginf = {NanInf.neginf} @@ -437,7 +479,8 @@ static void DockableDlgDemo() if (frmGoToLine == null) { frmGoToLine = new frmGoToLine(editor); - + + // not sure what this block does but it's necessary using (Bitmap newBmp = new Bitmap(16, 16)) { Graphics g = Graphics.FromImage(newBmp); @@ -450,7 +493,7 @@ static void DockableDlgDemo() g.DrawImage(tbBmp_tbTab, new Rectangle(0, 0, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel, attr); tbIcon = Icon.FromHandle(newBmp.GetHicon()); } - + NppTbData _nppTbData = new NppTbData(); _nppTbData.hClient = frmGoToLine.Handle; _nppTbData.pszName = "Go To Line #"; diff --git a/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs b/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs index 747712a..d2d101f 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs @@ -16,7 +16,7 @@ public interface INotepadPPGateway string GetNppPath(); string GetPluginConfigPath(); string GetCurrentFilePath(); - unsafe string GetFilePath(int bufferId); + unsafe string GetFilePath(IntPtr bufferId); // use IntPtr to work with 32-bit and 64-bit Notepad++ void SetCurrentLanguage(LangType language); bool OpenFile(string path); } @@ -108,7 +108,7 @@ public bool OpenFile(string path) /// /// Gets the path of the current document. /// - public unsafe string GetFilePath(int bufferId) + public unsafe string GetFilePath(IntPtr bufferId) { var path = new StringBuilder(2000); Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_GETFULLPATHFROMBUFFERID, bufferId, path);