Community
    • Login

    How to use runMenuCommand() in python script?

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    11 Posts 4 Posters 3.4k 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.
    • Eko palypseE
      Eko palypse @古旮
      last edited by

      @古旮

      for builtin menu function you do use menuCommand, for foreign menus like the famous TextFX you use runMenuCommand.

      To answer your first question notepad.menuCommand(MENUCOMMAND.VIEW_INDENT_GUIDE)

      Concerning your second question I would say it depends what exactly is needed to be done like providing arguments …
      What about using the python way and importing it?

      Eko

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

        @古旮,

        It turns out you don’t need to prefix with the “View” menu first:
        notepad.runMenuCommand('Show Symbol','Show Indent Guide')

        From the PythonScript console, if you want to run a script, the syntax is notepad.runPluginCommand('Python Script', 'anotherScript') – whether that script is only in the Scripts submenu, or whether it’s also been made a menu-item through the Configuration. At least for me, on NPP 7.5.8 with PythonScript 1.3.0.0.

        However, when I tried to run one script from another, I got a dialog box: “Another script is currently running. Running two scripts at the same time could produce unpredicable [sic] results, and is therefore disabled.” So they obviously don’t want you doing it that way.

        I had partial success in using Python’s import syntax:

        console.show()
        console.write("Hello World")
        import SomeOtherScript
        # note that you drop the ".py" off of SomeOtherScript.py
        

        If I ran this, it would write to the PythonScript console, then attempt to run SomeOtherScript. However, the attempt would only be successful if SomeOtherScript.py included the from Npp import *: most of my scripts rely on that having been imported in startup.py, but apparently when you add the level of indirection through import, it loses that overhead. When I added from Npp import *, then it would work.

        As a second “however”: it would also only import/run the extra script once. If I tried again, it wouldn’t. My experiments and researched showed that it’s because the “module” (script) has already been “imported”, and since the PythonScript module has just one instance of Python, it stays “imported”. I have some ideas on how to get around that … but not enough time to get to that right now. I’ll come back to this later today.

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

          @古旮,

          Okay, I found a couple more minutes right away while waiting for something else to get ready:

          If the primary script is below, and if anotherScript.py starts with from Npp import *, (and if primaryScript.py and anotherScript.py are in the same directory), then I believe the following will work: it will re-run anotherScript every time primaryScript is run.

          console.show()
          console.write("\nHello World\n")
          
          # run the script called "anotherScript.py":
          if 'anotherScript' in globals():
              console.write("anotherScript already exists\n")
              reload(anotherScript)
          else:
              console.write("anotherScript will be loaded\n")
              import anotherScript
          
          console.write("\nThe End\n")
          

          (There may be some other caveats, but this combination worked in my experiments.)

          In your final version, you don’t need all the console.write()s: those were just to show what was going on.

          1 Reply Last reply Reply Quote 2
          • Eko palypseE
            Eko palypse @PeterJones
            last edited by

            @PeterJones

            It turns out you don’t need to prefix with the “View” menu first:

            nice one - wasn’t aware of this, so menuCommand is not needed anymore??

            You are correct, python caches imported modules to avoid and prevent import loops.
            One way to force to reimport the module would be to use the reload function but a
            better way would be do define the function needed and call it explicitly like

            SomeOtherScript.py contains

            import time
            def someOtherFunction():
                print('someOtherFunction:{}'.format(time.time()))
            

            and the main script contains something like

            import SomeOtherScript
            print('main script')
            SomeOtherScript.someOtherFunction()
            

            Eko

            1 Reply Last reply Reply Quote 2
            • Alan KilbornA
              Alan Kilborn
              last edited by

              I find that I can use the Python function execfile() to run one script from another…no need to worry about import/reload etc.

              Eko palypseE 1 Reply Last reply Reply Quote 3
              • Eko palypseE
                Eko palypse @Alan Kilborn
                last edited by

                @Alan-Kilborn

                yes, you can use exec or execfile to execute python code but have to be aware
                that it differs how the code gets included.
                Let’s assume you do have a script with name SomeOtherScript.py and within there is
                one function SomeOtherFunction as well as one variable SomeOtherVariable

                If you import SomeOtherScript then you’ve ensured that SomeOtherFunction and SomeOtherVariable
                are only accessible via the module namespace.

                By using execfile or exec without using the optional global and local dicts you are importing
                SomeOtherFunction and SomeOtherVariable into the namespace of the current script which might
                override existing functions/variables.

                Eko

                Alan KilbornA 1 Reply Last reply Reply Quote 3
                • Alan KilbornA
                  Alan Kilborn @Eko palypse
                  last edited by

                  @Eko-palypse said:

                  By using execfile or exec without using the optional global and local dicts you are importing
                  SomeOtherFunction and SomeOtherVariable into the namespace of the current script which might
                  override existing functions/variables.

                  Yes but Pythonscripts are usually small things with very well compartmentalized naming. At least mine are. I use the technique that someone else here showed, where funcs/vars have names that start with abbreviations of the script file names. Thus no collisions; but yes, no guarantees.

                  Eko palypseE 1 Reply Last reply Reply Quote 1
                  • Eko palypseE
                    Eko palypse @Alan Kilborn
                    last edited by

                    @Alan-Kilborn

                    absolutely agreed - there is no wrong or right here as long as there is no requirement which
                    forces either the one or the other way to use.

                    Eko

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

                      @Alan-Kilborn said:

                      I use the technique that someone else here showed, where funcs/vars have names that start with abbreviations of the script file names

                      BTW this is a good thing to do in general. Consider a different scenario, no longer the one where running one script from another. Say you run script 1. Ok, fine, script one is finished and done. Now you want to use script 2. Well, script 1’s variables and functions still exist, so you could potentially be accessing old data from script 2. Not with the artificial namespace forcing (the names starting with abbrevs)–doesn’t happen.

                      Eko palypseE 1 Reply Last reply Reply Quote 0
                      • Eko palypseE
                        Eko palypse @Alan Kilborn
                        last edited by

                        @Alan-Kilborn

                        I assume as long as you are the only one who maintains and executes the scripts it is ok
                        but as soon as further people are involved it might get a little bit tricky and, personally,
                        I find it hard to read and is there really a benefit of, let’s say XYZ_myfunction contrary to XYZ.myfunction?
                        Guess, is a matter of taste.

                        Eko

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        The Community of users of the Notepad++ text editor.
                        Powered by NodeBB | Contributors