Community
    • Login

    How to create a C# plugin?

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    plugins
    29 Posts 7 Posters 1.7k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      scampsd
      last edited by

      I’m trying to create a plugin for Notepad++ in order to integrate NLog (like line colouring, filtering, …).

      For that I’ve tried to get the so-called “Demo” plugin working, but I’m having lots of troubles (see StackOverflow post “https://stackoverflow.com/questions/79632308”).

      Is there somewhere a working C# plugin (together with a working “DllExport”) that I can use as a starting point?

      Thanks in advance
      Dominique

      PeterJonesP Mark OlsonM 2 Replies Last reply Reply Quote 0
      • PeterJonesP
        PeterJones @scampsd
        last edited by PeterJones

        @scampsd ,

        Please be patient, and do not post two copies of the same question. A message similar to the following, when you were creating your post(s), should have made it clear that you would have to wait until your post was approved:
        fb0e9fda-225f-490f-a7b0-f0d75121d4a2-image.png

        Is there somewhere a working C# plugin (together with a working “DllExport”) that I can use as a starting point?

        Have you tried looking in the Online User Manual at https://npp-user-manual.org/, where the Plugins page has a section on plugin templates for various languages, which includes two actively-maintained C# plugin templates?

        kbilsted’s NotepadPlusPlusPluginPack.Net, mentioned in the SO discussion you linked to, hadn’t been updated for years (which is why it was recently removed from the User Manual list of templates): @Mark-Olson’s NppCSharpPluginPack mentioned in the Manual is a fork of that template, and has been updated to work with modern Notpead++ (and he’s a regular here and actively maintaining that template), so he’ll probably chime in with more advice for you.

        1 Reply Last reply Reply Quote 2
        • Mark OlsonM
          Mark Olson @scampsd
          last edited by

          @scampsd
          I would recommend NppCSharpPluginPack, which @PeterJones referenced above. I maintain it, and I don’t know of any other C# plugin templates that are actively maintained.

          S 1 Reply Last reply Reply Quote 3
          • S
            scampsd @Mark Olson
            last edited by

            @Mark-Olson
            Let me start reacting with one word: WOW!!!

            The Plugin template you provide is indeed what I’m looking for.
            Let me also explain what I’m aiming at:
            In my company were are using NLog as a logging library and all of our logs have a similar look, as can be seen in the following example:

            2025-02-10 00:02:54.9425 | Debug | Namespace.InternalClass(.Method) | Some information

            1. Starting with a timestamp with a fix format
            2. Followed by the loglevel
            3. After that, there is “namespace”, “class”, sometimes there is also “method”
            4. The last part is the information, which is to be logged.
            5. The separation between the logging fields is always “<space><pipe><space>”.

            I would like to create a plugin, which can colour the background of the logs according to loglevel. In top of that, I might develop a filtering mechanism, based on timestamp. (This is just a start)

            In order to do that, I would like to program the following in my plugin:

            • An event, which is triggered when a line is shown in Notepad++. When that line contains “| Debug |”, the line needs to be coloured (background colour and font colour, if possible). Is it possible subscribing to such an event and how?
            • A form, where those things can be configured. As I have some background in XAML, this might be interesting. Does the plugin development engine provide XAML support?

            Thanks in advance

            EkopalypseE Mark OlsonM 2 Replies Last reply Reply Quote 0
            • EkopalypseE
              Ekopalypse @scampsd
              last edited by

              @scampsd

              You can see how csvlint does this.

              S 1 Reply Last reply Reply Quote 2
              • S
                scampsd @Ekopalypse
                last edited by scampsd

                @Ekopalypse

                Dear,
                As you can see from my question, I was thinking in the sense of creating an event and handling accordingly, but the plugin you provided, seems to be based on a completely different way of working. As an example, let me show you a line of code from the function, which enables/disables the background colouring:

                Win32.SendMessage(
                    PluginBase.nppData._nppHandle, 
                    (uint)NppMsg.NPPM_SETCURRENTLANGTYPE,
                    0,
                    newLanguageId);
                

                For a Notepad++ plugin newbie like me, this is really not simple. Can you shed some light on what this all means? (How does the mentioned line of source code modify the background of a piece of a line in Notepad++?)

                Thanks
                Dominique

                EkopalypseE 1 Reply Last reply Reply Quote 1
                • EkopalypseE
                  Ekopalypse @scampsd
                  last edited by Ekopalypse

                  @scampsd

                  NPPM_SETCURRENTLANGTYPE is an NPP message that asks Npp to set a specific lexer and the code of the lexer is ultimately responsible for coloring the code. Your plugin can, but does not have to, define a lexer, this is how csvlint has solved this and is usually the better solution. Another approach would be to search for the desired lines and color them accordingly. I can’t say what makes more sense for you, as I don’t know what kind of data you are working with or what your knowledge of lexers, styles etc… is like.
                  Regarding the events, Npp calls a callback, beNotified, which is exported by plugins. Using the C# template this is the OnNotification in Main.cs. The plugin can use this to react to various events.
                  EDIT: Here the link to the scintilla documentation.

                  1 Reply Last reply Reply Quote 5
                  • Mark OlsonM
                    Mark Olson @scampsd
                    last edited by

                    @scampsd said in How to create a C# plugin?:

                    A form, where those things can be configured. As I have some background in XAML, this might be interesting. Does the plugin development engine provide XAML support?

                    XAML is not supported by NppCSharpPluginPack. I know nothing about XAML, so I couldn’t comment on how easy it would be to modify the template to support that.

                    I use Windows Forms to make forms in plugins based on that template. See the NppDemo.Forms namespace for how I make forms.

                    1 Reply Last reply Reply Quote 3
                    • Mark OlsonM
                      Mark Olson
                      last edited by Mark Olson

                      @scampsd
                      Probably the easiest way to colorize text is with indicators. You can see an example of how JsonTools works with indicators in this file.

                      A lexer is way better than indicators for dynamically restyling a document as the user edits it, but if you don’t need that capability, I would stick with indicators.

                      EDIT: To clarify, indicators do resize and move when the user edits the document, a feature that JsonTools uses to improve performance. However, the algorithm Scintilla uses for dynamically resizing indicators is not suitable for syntax coloring.

                      S 1 Reply Last reply Reply Quote 3
                      • S
                        scampsd @Mark Olson
                        last edited by

                        @Mark-Olson : thanks for the help until now, but I’m having some doubts: I have been playing with the mentioned indicators, and all I get is something like the following screenshot:

                        009f6a08-b06d-4dd4-8e8e-bd0d147c692e-image.png

                        As you see, the text is underlined in different ways but the text itself does not modify, while I’m particularly interested in changing the background colour, something like in this screenshot:

                        0922313f-c500-4418-84ac-99da945fa206-image.png

                        Remark: I have created the second screenshot, using the context menu’s “Style one token” command. As far as I’ve understood, that search feature can mark only a token, not the entire line, and in top of that only five tokens can be added. Is that correct? (I’m asking this because in case the entire line can be coloured and more than five tokens are possible, it makes no sense developing the plugin I’m currently working on).

                        EkopalypseE PeterJonesP 2 Replies Last reply Reply Quote 0
                        • EkopalypseE
                          Ekopalypse @scampsd
                          last edited by

                          @scampsd said in How to create a C# plugin?:

                          that search feature can mark only a token, not the entire line, and in top of that only five tokens can be added. Is that correct?

                          Yes

                          Without the information of what you have done, it is hard to say what is wrong. At the moment I assume that you have not chosen the right indicator.

                          alt text

                          1 Reply Last reply Reply Quote 3
                          • PeterJonesP
                            PeterJones @scampsd
                            last edited by PeterJones

                            @scampsd said in How to create a C# plugin?:

                            As far as I’ve understood, that search feature can mark only a token, not the entire line

                            The Search > Mark dialog’s “Mark” feature uses a different Mark style (Global styles > Find Mark Style), separate from the 5 “token” styles (Global styles > Mark Style #). They are two separate features.

                            The Search > Style xxx Token actions are controlled by the Settings > Preferences > Highlighting > Style All Occurrences of Token settings as to whether they require one true word/token (checkmarked option), or whether it allows part of a word or extending over multiple words. There is no way to set it to “style entire line when token XYZ is present”, but if the checkbox is not checkmarked, and the selection covers the whole line when Search > Style One Token > Using Nth Style is run, then that whole line will be styled.

                            and in top of that only five tokens can be added. Is that correct? (I’m asking this because in case the entire line can be coloured and more than five tokens are possible, it makes no sense developing the plugin I’m currently working on).

                            Tokens can be combined: here’s an example of line 1 using 1st token style, line 2 in 2nd token style, and line 3 in both 1st and 2nd applied – they have partial “alpha”/transparency, so they can “add” the colors together:
                            df131573-c22d-4443-a730-5cfd67f20522-image.png
                            (so one and two is highlighted both cyan and peach, coming out as a pale greenish color)

                            With 5 token styles, and the binary choices of “yes” or “no” on each of those, it’s actually 2⁵=32 different combinations of token-styles that can be applied. If 32 distinct sum-of-colors is sufficient for you, then the style-token could help you. But, again, you cannot say “any line that contains | Trace | gets Style 1 for the whole line”. So the token-styler probably won’t meet your needs, alone. But if you cannot get your plugin to apply the Indicator in the way you like, you might be able to switch it to applying some combination of the 5 token-styles.

                            Mark OlsonM 1 Reply Last reply Reply Quote 1
                            • Mark OlsonM
                              Mark Olson @PeterJones
                              last edited by Mark Olson

                              @PeterJones mentioned the Search > Mark feature, which moves in the direction of what @scampsd was asking for.

                              Given that background color customization specifically is requested, the Marker API (which is what the Search > Mark feature uses under the hood (EDIT: corrected a false assertion)) could be used instead of the Indicator API.

                              I have not used Markers at all, so @scampsd would need to figure out how to use it by reading the documentation I linked above.

                              PeterJonesP EkopalypseE 2 Replies Last reply Reply Quote 1
                              • PeterJonesP
                                PeterJones @Mark Olson
                                last edited by

                                @Mark-Olson said in How to create a C# plugin?:

                                the Marker API (which is what the Search > Mark feature uses under the hood) could be used instead of the Indicator API.

                                The first paragraph of the Marker API docs say, “Markers appear in the selection margin to the left of the text.” They are the margin symbols like the folding symbols, as shown in the image on that page:

                                I don’t think the Search > Mark highlighting is done with Markers.

                                The Smart Matching, Tag Matching, and Token Styles are all done with indicators.

                                And the stylers.model.xml “Find Mark Style” is StyleID#31 SCE_UNIVERSAL_FOUND_STYLE – and when you do the Search > JumpUp/JumpDown to the “Find Mark Style”, it runs this case, where it searches for the next indicator with value SCE_UNIVERSAL_FOUND_STYLE = 31. So I’m pretty sure that the Search > Mark is also using an Indicator, just like the Smart/Tag/Token, above.

                                Alan KilbornA 1 Reply Last reply Reply Quote 2
                                • EkopalypseE
                                  Ekopalypse @Mark Olson
                                  last edited by

                                  @Mark-Olson said in How to create a C# plugin?:

                                  the Marker API

                                  and it has a really nice feature, it provides calls to jump to next or previous marks.

                                  1 Reply Last reply Reply Quote 0
                                  • Alan KilbornA
                                    Alan Kilborn @PeterJones
                                    last edited by Alan Kilborn

                                    @PeterJones said:

                                    The first paragraph of the Marker API docs say, “Markers appear in the selection margin to the left of the text.”

                                    It says that, but it is not 100% true.
                                    If one uses SC_MARK_BACKGROUND or SC_MARK_UNDERLINE, the result is not in the margin, but rather in the text itself (as the graphical image that shows the examples–above, in Peter’s most-recent post–implies).

                                    Entire-line coloring seems to be what @scampsd is trying to achieve, so perhaps using marker(s) with SC_MARK_BACKGROUND will be useful.

                                    S 1 Reply Last reply Reply Quote 3
                                    • S
                                      scampsd @Alan Kilborn
                                      last edited by

                                      @Alan-Kilborn Sorry for the late reply: I don’t have the time to work on this matter every day.

                                      If I understand well, I seem to have the following choices:

                                      1. Indicators : this is something which might work, but the provided example is based on the method Npp.notepad.AllocateIndicators(numberOfIndicators, out int[] indicators), which is not very clear yet.
                                      2. Styles : if I understood correctly, the maximum number of styles (being 5) is not only a limitation for Notepad++ users, but also for Notepad++ plugin developers.
                                      3. Markers : again another approach.

                                      If you don’t mind, I’d like to proceed with the “Indicators” approach, but then I need to understand the AllocateIndicators() method, and it looks really not simple: the provided example launches that method and as a result, a list of indicators seems to be linked with some individual characters, present in the text.
                                      I have done the following modifications to the example:

                                      for (int ii = firstIndicator; ii <= lastIndicator; ii++)
                                      {
                                          Npp.editor.SetIndicatorCurrent(ii);
                                          Npp.editor.IndicSetFore(ii, new Colour(255, 0, 0)); // Colour RED
                                          Npp.editor.IndicSetStyle(ii, IndicatorStyle.FULLBOX); // Use full rectangle
                                          Npp.editor.IndicatorFillRange(ii, 5); // Not one but five characters long
                                      }
                                      

                                      The result is the following:
                                      445a9474-8cc9-4a70-b8ea-666a8112e6cc-image.png

                                      Can anybody explain me why the mentioned indicators get linked to the 9th, the 10th, … up to the 14th character? How can I change that and link those indicators to other characters, words, lines, …?

                                      EkopalypseE Mark OlsonM 2 Replies Last reply Reply Quote 0
                                      • EkopalypseE
                                        Ekopalypse @scampsd
                                        last edited by

                                        @scampsd said in How to create a C# plugin?:

                                        Can anybody explain me why the mentioned indicators get linked to the 9th, the 10th

                                        You have used the IDs as the starting position.

                                        SCI_INDICATORFILLRANGE(position start, position lengthFill)
                                        
                                        S 1 Reply Last reply Reply Quote 2
                                        • Mark OlsonM
                                          Mark Olson @scampsd
                                          last edited by Mark Olson

                                          @scampsd
                                          So the purpose of AllocateIndicators is to tell Notepad++ that you want to use a certain number of indicators. Based on how many indicators you requested, Notepad++ tells you which ones you can use (that’s the out int[] parameter). These are reserved for you for the rest of the session.

                                          Once you have the indicators, you customize their appearance using methods like IndicSetStyle and IndicSetFore. You can do this once at startup; once you’ve customized the style it stays that way for the rest of the session.

                                          To style a given region of a document with an indicator, use SetIndicatorCurrent and IndicatorFillRange.

                                          To find all the regions of a document that are styled with a given indicator, use IndicatorStart, IndicatorEnd, and IndicatorValueAt as shown in this example from JsonTools.

                                          1 Reply Last reply Reply Quote 1
                                          • S
                                            scampsd @Ekopalypse
                                            last edited by scampsd

                                            @Ekopalypse Thanks, I get that now.
                                            I’m succeeding colouring some pieces of text now but you might imagine the next question: the method Npp.editor.IndicatorFillRange(int start, int length) is, as you mentioned, depending on start integer and length integer, while I’m working with entire lines.

                                            I’m obviously capable to calculate the start and length, based on content of “| Trace |” or “| Debug |” and the newline characters (hardcoded "\r\n"), but I’m wondering if there’s not an easier way to work with lines of text in the editor.

                                            Alan KilbornA Mark OlsonM EkopalypseE 3 Replies Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            The Community of users of the Notepad++ text editor.
                                            Powered by NodeBB | Contributors