Community
    • Login

    Announcing Perl-based automation of Notepad++

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    perlautomation
    16 Posts 2 Posters 3.1k 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.
    • PeterJonesP
      PeterJones
      last edited by

      At long last, I have a version of my Perl module for automating Notepad++ that I’ve been willing to publish. It’s been a long road from last summer, but here it is.

      For those who haven’t read the original thread last summer, this is not a plugin, though it uses the same hooks into Notepad++ that a plugin uses. You need an external copy of Perl, this module, and a copy of Notepad++ (of course). The perl executable and Notepad++ executable must both have the same bits (64-bit or 32-bit). You can write your scripts inside of Notepad++, but to run, it needs to call the external perl instance.

      Like the PythonScript or LuaScript plugins, this module is able to automate actions in the Notepad++ GUI, and access and modify the contents of the open files inside Notepad++.


      NAME

      Win32::Mechanize::NotepadPlusPlus - Automate the Windows application Notepad++

      SYNOPSIS

      use Win32::Mechanize::NotepadPlusPlus ':main';
      my $npp = notepad();    # main application
      

      DESCRIPTION

      Automate the Windows application Notepad++. This is inspired by the Notepad++ plugin PythonScript, but I decided to automate the application from the outside, rather than from inside a Notepad++ plugin. But this module uses similar naming conventions and interface to the PythonScript plugin.

      LIMITATIONS

      This is the first public release of the module. In general, it works. As with all first releases, there is room for improvement; I welcome feedback.

      The first known limitation is that none of the hooks for Scintilla or Notepad++ callbacks have been enabled. That may come sometime in the future.

      All the testing and development was done with a US-English installation of Notepad++, and all the file encodings have been ANSI or UTF-8. I know that I need to include better tests for encoding, and any help you can provide with that is appreciated.

      Notepad++ is a Windows application, so that’s the intended platform for this module. However, I know Notepad++ can be made to run in Wine and similar environments in Linux, so it may be possible to make this module drive Notepad++ in such an environment. Feedback on this process is welcome.

      INSTALLATION

      To install this module, use your favorite CPAN client.

      I recommend installing the newest 64-bit Strawberry Perl with a 64-bit Notepad++. Then install this module by running cpanm Win32::Mechanize::NotepadPlusPlus. Please note that for the test suite to work, Notepad++ should be in your path, or in one of the standard install locations (%ProgramFiles%\Notepad++ or %ProgramFiles(x86)%\Notepad++)

      For a manual installation of this Perl module, type the following:

      perl Makefile.PL
      make
      make test
      make install
      

      (You may need to use “dmake” or “gmake” instead of “make”, depending on your setup.)

      AUTHOR

      Peter C. Jones

      Please report any bugs or feature requests thru the repository’s interface at https://github.com/pryrt/Win32-Mechanize-NotepadPlusPlus/issues, or by emailing <bug-Win32-Mechanize-NotepadPlusPlus AT rt.cpan.org> or thru the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Win32-Mechanize-NotepadPlusPlus.

      COPYRIGHT

      Copyright © 2019,2020 Peter C. Jones

      LICENSE

      This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information.

      1 Reply Last reply Reply Quote 6
      • Michael VincentM
        Michael Vincent
        last edited by

        Just downloaded it and playing with it now. I ran my first simple script from within Notepad++ (wrote it and i have ‘F10’ shortcut to compile and run current file based on extension) and it worked!!

        #!perl
        
        use strict;
        use warnings;
        
        use Win32::Mechanize::NotepadPlusPlus ':main';
        my $npp = notepad();
        
        $npp->newFile();
        

        Notepad++ 7.8.3 64-bit
        Strawberry Perl 5, version 24, subversion 1 (v5.24.1) built for MSWin32-x64-multi-thread

        Cheers.

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

          @Michael-Vincent said in Announcing Perl-based automation of Notepad++:

          and it worked!!

          Thanks for the feedback. Often on my perl releases on CPAN, my post-release test runs are the only passes in cpantesters; if you happen to have the setup necessary to submit cpantester reports manually, it would be appreciated. If not, I hope that the module ends up being useful for you.

          1 Reply Last reply Reply Quote 0
          • Michael VincentM
            Michael Vincent
            last edited by Michael Vincent

            I use NppConsole (modified) to get a PowerShell console in a N++ dockable. I also wrote App::PerlShell which provides a REPL-like shell-like interactive Perl. So a quick Batch script called “nppplsh.bat”:

            @echo off
            
            plsh -P Win32::Mechanize::NotepadPlusPlus -p "npp> "
            

            … and now from my NppConsole, I can run nppplsh.bat and then:

            PS MVINCENT ~ > nppplsh.bat
            
            npp> print notepad()->getCurrentFilename();
            C:\Users\mvincent\source\pynetsim\Notes.md
            npp> print notepad()->getNumberOpenFiles();
            8
            npp> print notepad()->getNumberOpenFiles(1);
            6
            npp> print editor->getSelText();
            This is the text I selected for the 
            plsh and Win32::Mechanize::NotepadPlusPlus demo!
            npp> exit
            PS MVINCENT ~ >
            

            Cheers.

            1 Reply Last reply Reply Quote 2
            • Michael VincentM
              Michael Vincent
              last edited by

              Perhaps an even more interesting demo using the same selected text from the previous demo and some code from a recent post, I can get the MD5 hash of each line:

              PS MVINCENT ~\source\pynetsim > nppplsh
              
              npp> use Digest::MD5;
              
              npp> $eol = ("\r\n", "\r", "\n")[editor->getEOLMode()];
              
              npp> @lines = split /$eol/, editor->getSelText();
              
              npp> for $line (@lines) {
              More? $ctx = Digest::MD5->new();
              More? $ctx->add($line);
              More? printf qq(%32.32s\n), $ctx->hexdigest();
              More? }
              eae987951e7acc2d994c4d1d279f7112
              a00f5ac7854397bcac1c348685dc429c
              
              npp>
              

              Cheers.

              1 Reply Last reply Reply Quote 1
              • PeterJonesP
                PeterJones
                last edited by

                @Michael-Vincent,

                I had never really gotten into REPL – never found one that I liked enough to frequently use – but I think App::PerlShell might be the one that starts me down that road, especially with this solution for NppConsole to embed the REPL in Notepad++. (If I ever get around to the v2.0 features – specifically, writing a wrapper Notepad++ plugin and thus enabling the notifications – I will probably try to use a combination of NppConsole as the starting code and @Ekopalypse’s experiments with embedding perl in a plugin, and include App::PerlShell as the default REPL for the plugin. That said, I have to get from early versions into a sold v1.0 before I work on v2.0 feastures. :-) )

                Speaking of working toward v1.0: I am working on documenting the hashes that are used for holding the message name/value pairs, and the argument name/value pairs (equivalent to PythonScript’s enum documentation). But I’m wondering if I should change from having just a couple hashes with messages and message-arguments intertwined (%nppm, %nppidm, and %scimsg) into having a different named hash for the messages compared to the arguments (pythonscript uses a separate enum/class for each type of argument). Or maybe go the other direction, and have a big hash-of-hashes like %enum = ( NPPMSG => { … } , SCINTILLAMSG => { … } , MENUCMD => { FILE_CLOSE => …, …}, … ), so if you were going for the FILE_CLOSE, it would be $enum{MENUCMD}{FILE_CLOSE}.

                I had originally kept them as just those three hashes, because that was easy from my convert-.h-to-hash method. But since I’m moving over to manual .pm for the messages/arguments, to allow for easier POD documentation of those hashes, now seems like a good time to make changes to the structure, if it makes sense.

                So, if it were up to you(*), would you prefer just the enums as they are, split into multiple separate hash variables, or combined into one mega hash-of-hashs? Or should I just do all three (I could easily build the existing-three out of individual variables, and the mega hash-of-hashes could actually just embed the individual variables.

                *: “up to you”, where “you” is defined as @Michael-Vincent , or anyone else who is likely to use Win32::Mechanize::NotepadPlusPlus as more than a one-or-two-time curiosity. :-)

                Michael VincentM 1 Reply Last reply Reply Quote 1
                • Michael VincentM
                  Michael Vincent @PeterJones
                  last edited by

                  @PeterJones said in Announcing Perl-based automation of Notepad++:

                  So, if it were up to you(*)

                  Let me give it think. My first instinct is to keep them separate instead of a single big hash-of-hash. To me that just makes more sense grouping N++, messages and Scintilla with their like instead of mixing.

                  More on App::PerlShell - if you read the POD, there are other REPL’s for Perl that excel at certain aspects of REPL - one duplicates Python look and feel, another uses PPI for correct Perl parsing at the expense of many dependencies, etc. I wanted one that behaved more like a shell (e.g., bash, Powershell) but took Perl commands and none did that. That said, my implementation is probably pretty poor, rough around the edges and makes a multitude of assumptions. All this to say, happy for you to use it, that’s what it’s there for … but “production ready” it may not be like say Devel::REPL.

                  Cheers.

                  1 Reply Last reply Reply Quote 1
                  • PeterJonesP
                    PeterJones
                    last edited by

                    v0.002 released to CPAN

                    • Reorganize the hash variables for easier and clearer use going forward (#13)
                    • editor->getLine() on an empty line will now correctly return an empty string, not “\0” (fixed #14)
                    • update API for getNumberOpenFiles to correctly use the constants (#17)
                    • add notepad->getNppVar() for accessing the “user variables”, like FULL_CURRENT_PATH and CURRENT_WORD (#19)
                    • improve documentation internal links (#20)
                    • make the editor->hwnd() a public method (instead of using editor()->{_hwnd})
                    • make the notepad->hwnd() a public method (instead of using notepad()->{_hwnd})
                    • add helper editor->getEOLString(): convert EOL Mode integer to a string
                    • editor->getFileEndPosition(): gives the end position of the whole document
                    • improve test coverage: add encoding names and getLanguageName coverage to npp-buffer.t
                    • examples/ folder: adding more example usages
                    • improve Editor documentation on ->findText and some other methods, and clean up set/get pairs, so they share the same information
                    • improve Notepad documentation, especially fixing the link for menuCmdID source file
                    PeterJonesP 1 Reply Last reply Reply Quote 3
                    • PeterJonesP
                      PeterJones @PeterJones
                      last edited by

                      v0.003 released to CPAN

                      The user-centric changes that were made:

                      • some of the Scintilla v4.2.0 messages that were implemented in Notepad++ v7.8 were missing, so add them (#29: thanks @Michael-Vincent for pointing this out!)
                      • runPluginsCommand() = fixed command cache feature and improved test (#30)
                      • added version notes, to say which messages and “enums” (hashes/keys) require NPP v7.8 (because these are the Scintilla v4.2.0 updates)

                      I keep trying to improve this, and make it more usable. Suggestions and bug reports welcome.

                      Michael VincentM 1 Reply Last reply Reply Quote 3
                      • Michael VincentM
                        Michael Vincent @PeterJones
                        last edited by

                        @PeterJones

                        Saw your N++ commit updating Perl keywords and the autocomplete API. BRAVO!!! I had an updated perl.xml autocomplete, but yours is way more complete and I’ve started using it this morning to test.

                        Thanks for keeping Perl updated in N++!!

                        Cheers.

                        PeterJonesP 2 Replies Last reply Reply Quote 1
                        • PeterJonesP
                          PeterJones @Michael Vincent
                          last edited by

                          This post is deleted!
                          1 Reply Last reply Reply Quote 0
                          • PeterJonesP
                            PeterJones @Michael Vincent
                            last edited by

                            @Michael-Vincent,

                            I was trying to figure out if I had a place to reply with that link, or whether I’d have to create a new post. I guess here was as good a place as any. Since Don accepted the PR, it should be in the next official release! (This is my first contribution to the main Notepad++, rather than just documentation or UDL, so I’m happy about that!)

                            I basically wrote a regex to trim out just the functions (=item) and the brief summary line (=for Pod::Functions) from perlfunc.pod, then used another few regex to merge those together into the auto-complete format; that way, I am hopeful I didn’t miss any functions from v5.30.

                            Michael VincentM 1 Reply Last reply Reply Quote 0
                            • Michael VincentM
                              Michael Vincent @PeterJones
                              last edited by

                              @PeterJones said in Announcing Perl-based automation of Notepad++:

                              I basically wrote a regex

                              I did mine by hand. Happy to throw that away for your more complete and automated creation solution. I’ll be grabbing 7.8.7 when officially released.

                              Cheers.

                              PeterJonesP 1 Reply Last reply Reply Quote 0
                              • PeterJonesP
                                PeterJones @Michael Vincent
                                last edited by

                                v0.005 released to CPAN

                                The user-centric changes that were made:

                                • replace %ENCODINGKEY with %BUFFERENCODING, because the old hash had wrong values that didn’t match getEncoding()'s return values (#50)
                                • add setEncoding() command to call NPPM_SETBUFFERENCODING as the logical pair to getEncoding() (#51)

                                I had apparently missed announcing v0.004 and bugfix 0.004001, so for historical purposes, quoting from my CHANGES file

                                v0.004001 2020-Jun-20

                                • fix bug in notepad->prompt(), which only used two of the three
                                  arguments, in wrong order (#47); test suite verifies default
                                  values for title and default when they aren’t used
                                • added new examples/pasteSpecial.pl to show how to paste a
                                  clipboard entry other than CF_TEXT into Notepad++

                                v0.004 2020-Jun-04

                                • fix bug in propertyNames() which deleted final char (#45)
                                • implemented helper methods: forEachLine, deleteLine, replaceWholeLine,
                                  replaceLine, flash, getWord, getCurrentWord, getUserLineSelection,
                                  getUserCharSelection (#15)
                                • make setTarget an alias of setTargetRange, and write an alias of
                                  addText, for PythonScript compatibility (#15)
                                • implemented new auto-wrapper to get searchInTarget and similar calls
                                  to work right (#42)
                                • fixed replaceTarget() and replaceTargetRE() replacing target with the
                                  empty string (#41)
                                • fixed length bug in getTargetText() (#40)
                                • fixed bug in editor->setText(‘’) which had empty strings
                                  cause crash (#39)
                                PeterJonesP 1 Reply Last reply Reply Quote 0
                                • PeterJonesP
                                  PeterJones @PeterJones
                                  last edited by

                                  v0.007 released to CPAN

                                  • Update Editor object for the Notepad++ 7.9.4 update to Scintilla v4.4.6

                                  And, again, I had forgotten to announce last month:

                                  v0.006 2021-Mar-06

                                  • add getSettingsOnCloudPath() with test (#54)
                                  • add getLineNumberWidthMode(), setLineNumberWidthMode(), and the %LINENUMWIDTH enumeration with test (#54 addendeum)
                                  • test suite bug: with v7.9.1 and newer, replaceTargetText() changes the selection/getTargetText() value, so update the readback to be version agnostic (#57)
                                  • documentation error: fox %NPPIDM description in Notepad.pm (#53)
                                  • meta fix: make test suite pass on cpantesters smoke testers, even if smoke tester machine doesn’t have Notepad++, or has an old, incompatible version (#56)

                                  v0.006001 2021-Mar-07

                                  • meta fix: turn off the auto-download on smoke tester machines, because it was causing fails
                                  PeterJonesP 1 Reply Last reply Reply Quote 2
                                  • PeterJonesP
                                    PeterJones @PeterJones
                                    last edited by

                                    v0.008 released to CPAN

                                    • add notepad->showDocList, notepad->isDocListShown, and notepad->docListDisableColumn for working with the Document List panel (previously “Doc Switcher” panel)
                                    • incorporate the new messages and menu commands thru v8.1.4 (#80)
                                    • add notepad->getStatusBar(), which will get the text of one of the sections of the status bar (#65)
                                    • add notepad->getDebugInfo(), which (for new-enough Notepad++) includes the ‘Command line’ entry from Debug Info (#74)
                                    • add %WINMSGBOX for use with notepad->messageBox (#73)
                                    1 Reply Last reply Reply Quote 1
                                    • First post
                                      Last post
                                    The Community of users of the Notepad++ text editor.
                                    Powered by NodeBB | Contributors