• Login
Community
  • Login

Pythonscript plugin: how to end the script but not quit Notepad++

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
13 Posts 4 Posters 2.0k 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.
  • P
    P Cooper
    last edited by Jan 21, 2023, 8:24 AM

    Am rather new to this stuff and have a simple question:

    For me when I use quit() or exit() in a Python script run via the plugin, Notepad++ is shut down. But I want to end execution of the script as part of an if statement only. Alternatively, I guess I could jump to a label at the very end of the script if that was possible.

    Many thanks for any pointers.

    A 1 Reply Last reply Jan 21, 2023, 11:18 AM Reply Quote 1
    • A
      Alan Kilborn @P Cooper
      last edited by Alan Kilborn Jan 21, 2023, 11:24 AM Jan 21, 2023, 11:18 AM

      @P-Cooper

      This came up relatively recently; see this THREAD and look at the Jan 10, 2023, 6:48 PM posting. Therein you’ll find someone asking about sys.exit() and you’ll find solutions further down in the thread’s postings.

      In addition to the technique presented in the other thread, one could also achieve the goal with a custom exception, but that’s a rather advanced solution.


      I guess I could jump to a label at the very end of the script

      Do you have an example of how you might do that? Sharing it might be instructive…

      P 1 Reply Last reply Jan 21, 2023, 2:20 PM Reply Quote 3
      • P
        P Cooper @Alan Kilborn
        last edited by P Cooper Jan 21, 2023, 5:27 PM Jan 21, 2023, 2:20 PM

        @Alan-Kilborn

        Thanks for directing me that interesting thread! Possible solutions seem to be indirect:

        • a dummy if-statement with the entire rest of the script indented so that the script reaches the bottom of the file if the statement is untrue

        • defining a function with the body of the main script and calling that conditionally

        • a ‘while true’ loop concluded by ‘break’

        My ‘jump to label’ idea was merely an assumption based on my total ignorance of Python. It’s just not possible it seems.

        It’s fine for the small stuff I’m trying to do but I reckon this lack of a suitable command could prove annoying for large projects anyone wanted to do based on the plugin…

        A 1 Reply Last reply Jan 21, 2023, 3:38 PM Reply Quote 1
        • A
          Alan Kilborn @P Cooper
          last edited by Jan 21, 2023, 3:38 PM

          @P-Cooper said in Pythonscript plugin: how to end the script but not quit Notepad++:

          I reckon this lack of a suitable command could prove annoying for large projects anyone wanted to do based on the plugin…

          You reckon wrongly.
          Any “large” effort would include “structuring” such that the solutions you call “indirect” are just, well, natural to do.

          I suppose everyone starts out doing PythonScript with all their statements slammed up against the left side (aka column 1):

          x=7
          if x==4:
              pass
          y=3
          

          etc.

          But I’d think/hope most people would “graduate” beyond that type of thing fairly quickly.

          BTW, the code snippet above puts x and y into the global namespace where they could possibly accidentally be resused in a bad way by other scripts. The “structure” that I’m talking about would prevent that.

          P 1 Reply Last reply Jan 21, 2023, 5:40 PM Reply Quote 2
          • P
            P Cooper @Alan Kilborn
            last edited by P Cooper Jan 21, 2023, 5:42 PM Jan 21, 2023, 5:40 PM

            @Alan-Kilborn

            I believe that for much of the stuff done in PythonScript, especially by those otherwise unfamilar with Python, a ‘terminate script’ command would be useful and would save some effort, not meaning to say it’s best practice.

            Thanks for pointing out that those ‘wall-slammed’ variables aren’t local / temporary. I’ve now slammed

            variable = "" / = 0
            

            statements against the wall at the bottom of my scripts, hoping that will do the trick.

            A 1 Reply Last reply Jan 21, 2023, 8:03 PM Reply Quote 0
            • A
              Alan Kilborn @P Cooper
              last edited by Alan Kilborn Jan 21, 2023, 9:34 PM Jan 21, 2023, 8:03 PM

              @P-Cooper said in Pythonscript plugin: how to end the script but not quit Notepad++:

              I believe that for much of the stuff done in PythonScript, especially by those otherwise unfamilar with Python, a ‘terminate script’ command would be useful

              Something people often don’t understand is that PythonScript is not a programming/scripting language. PythonScript is the plugin; the language is Python.

              Thus, the plugin can’t do anything that Python can’t do. For example, you’re asking for something that alters control flow. That’s like asking for PythonScript to offer a slightly different version of Python’s if or while keywords. It simply can’t be done.

              When you’re executing code with the plugin, you’re running Python. PythonScript gives you some extra objects that make working with Notepad++ easier (e.g. editor and notepad objects), but that’s the extent of it.

              All other the other “solutions” to the “problem” posed by this thread (found in the linked-to thread) work exactly the same way in pure Python.

              So I have advice for “those otherwise unfamilar with Python”, thinking that PythonScript is some lightweight (and simpler) thing… it’s not, so don’t think of it that way.

              One key way in which PythonScript’s Python IS different though, is that you can’t end it (its Python interpreter) without exiting Notepad++. With standalone Python, you execute it from a Cmd or PowerShell prompt with: python myscript.py. The program runs and control returns to the OS prompt. At that point myscript is gone from memory; its variables don’t “hang around” and can’t mess with the running of python my_second_script.py’s variables. Not so with PythonScript. Since under Notepad++, since the Python interpreter never stops running, variables with global scope remain in the namespace and can be used (if that’s the real intent) in subsequent scripts that are executed.


              I’ve now slammed
              …
              statements against the wall at the bottom of my scripts, hoping that will do the trick.

              Hmm, it won’t, but maybe I don’t fully understand what you mean… You can’t do a bunch of “hoping” and be successful with programming. :-)

              What I do when I’m PythonScripting, and what you’d need to do, to keep things like my x and y from global visibility, is to give them some localized scope.

              If people just want to “hack away” at Python/Notepad++, doing it the simple “slammed to the left” way is fine, but you can possibly open yourself up to some “strange” bugs sometimes.

              Even the simple construct shown before (to solve the problem originally posed):

              
              def main():
                  x=7
                  if x == 4:
                      return              # <-- this achieves the goal of a "quick exit the script"
                  y=3
              
              main()
              

              protects you from this a good deal, because x and y now “belong” to main, so you can’t run into problems with other scripts that might use an (uninitialized) x and y (because those won’t exist in the global space). You’d have to refer to them as main.x and main.y for this to happen, which is much harder to do by accident. Well, unless you use main in every script, but even for that case, when you run the above script, it redefines main at every run, so you can’t possibly use an old main.x from another script.

              So, there are a ton of advantages to using the def main() / main() approach; maybe it is just difficult for noobs to get their head around it. I’d say “just do it”.

              There’s more to the story, and I’ve tried to keep it very simple and not always use totally correct terminology, just in an attempt of simple knowledge transfer…

              P V 2 Replies Last reply Jan 21, 2023, 10:12 PM Reply Quote 4
              • P
                P Cooper @Alan Kilborn
                last edited by P Cooper Jan 21, 2023, 10:13 PM Jan 21, 2023, 10:12 PM

                @Alan-Kilborn

                Thanks a lot for sharing your insights in detail.

                It was surprising (and seemed unnecessary) to me that quit() / exit() and sys.exit() all shut down Notepad++ rather than just terminate the script, and I thought maybe something could be done about that so that they could do what I had in mind, but as you point out that’s not possible in the Notepad++ environment. It strikes me as odd, though, that it’s not possible for the process to retain that kind of control over the script it’s running – can’t run it in a “new thread” or “sandbox-type thingy”, but I don’t have the foggiest idea about the internals.

                Well, this noob has finally gotten his head round the def main() / main() approach thanks to you and is now proudly using cleaner code!

                A 1 Reply Last reply Jan 21, 2023, 10:23 PM Reply Quote 3
                • A
                  Alan Kilborn @P Cooper
                  last edited by Alan Kilborn Jan 21, 2023, 10:24 PM Jan 21, 2023, 10:23 PM

                  @P-Cooper said in Pythonscript plugin: how to end the script but not quit Notepad++:

                  sys.exit()

                  Quite frankly, I was surprised the first time I encountered it, that sys.exit() will shut down Notepad++.

                  However, sys.exit() in standalone Python is a really drastic way of ending a program, and, in practice, isn’t used much in real-world programming. I could go into detail, but perhaps a “trust me” on it will suffice.

                  Since all of your PythonScripting efforts should be considered “real world” :-), “just don’t use sys.exit()” is the mantra good PS programmers should chant.

                  P 1 Reply Last reply Jan 22, 2023, 10:31 AM Reply Quote 2
                  • P
                    P Cooper @Alan Kilborn
                    last edited by Jan 22, 2023, 10:31 AM

                    @Alan-Kilborn
                    If I ever decide to dabble in Python proper, I’ll bear your advice in mind, thanks!

                    A 1 Reply Last reply Jan 23, 2023, 3:05 PM Reply Quote 1
                    • A
                      Alan Kilborn @P Cooper
                      last edited by Alan Kilborn Jan 23, 2023, 3:25 PM Jan 23, 2023, 3:05 PM

                      @P-Cooper and everyone:

                      OK, so we’ve hinted a bit at structuring a PythonScript (thus far we’ve been doing it for purposes of easily exiting a running script).

                      So far, we’ve got this as a minimal technique:

                      def main():
                          x = 7
                          print('x:', x)
                          if x == 4: return  # <----- "terminate script" early
                          y = 3
                          print('y:', y)
                          # ...
                      
                      main()
                      

                      It works, no doubt about that. If you want to make a template out of it, just delete the demo junk and you’ll have:

                      def main():
                          # ...
                      
                      main()
                      

                      But, if you want to put a bit more “flair” on it, as well as set yourself up for more advanced script-writing in the future, consider this:

                      # -*- coding: utf-8 -*-
                      from __future__ import print_function
                      
                      # refs:
                      #  https://community.notepad-plus-plus.org/topic/24045
                      
                      from Npp import *
                      
                      #-------------------------------------------------------------------------------
                      
                      class XXXX(object):
                      
                          def __init__(self):
                              x = 7
                              print('x:', x)
                              if x == 4: return  # <----- "terminate script" early
                              y = 3
                              print('y:', y)
                              # ...
                      
                      #-------------------------------------------------------------------------------
                      
                      if __name__ == '__main__':
                          XXXX()
                      

                      Things to note:

                      • the from __future__ line is only needed if you intend to use “print” statements (for output onto the console) and you’re not using PythonScript 3.x
                      • nice refs: section so you can put info about where the script (or parts of it) originated
                      • the XXXX should be replaced with a nice “tag” for the script; when I’m doing it, if the name of my file is BarebonesBoilerplateDemo.py, then instead of XXXX, I use BBD, obviously the capital letter “acronym” of the filename (this is just the way I do it, you can totally go your own way here…)
                      • the “meat” of your script can go entirely in the __init__ function
                      • if you want/need some additional logical functions (encouraged!), you can certainly do that, like what is shown below:
                      # -*- coding: utf-8 -*-
                      from __future__ import print_function
                      
                      # refs:
                      #  https://community.notepad-plus-plus.org/topic/24045
                      
                      from Npp import *
                      
                      #-------------------------------------------------------------------------------
                      
                      class XXXX(object):
                      
                          def __init__(self):
                              x = 7
                              print('x:', x)
                              if x == 4: return  # <----- "terminate script" early
                              y = 3
                              print('y:', y)
                              # ...
                              self.my_function_1(x, y)
                              q = self.my_function_2(y)
                      
                          def my_function_1(self, a, b):
                              print('a:', a, 'b:', b)
                      
                          def my_function_2(self, z):
                              print('z:', z)
                              return z + 6
                      
                      #-------------------------------------------------------------------------------
                      
                      if __name__ == '__main__':
                          XXXX()
                      
                      1 Reply Last reply Reply Quote 3
                      • A Alan Kilborn referenced this topic on Jan 23, 2023, 3:05 PM
                      • V Victorel Petrovich referenced this topic on Aug 2, 2023, 12:18 AM
                      • V
                        Victorel Petrovich @Alan Kilborn
                        last edited by Victorel Petrovich Aug 2, 2023, 12:47 AM Aug 2, 2023, 12:35 AM

                        @Alan-Kilborn said in Pythonscript plugin: how to end the script but not quit Notepad++:

                        because x and y now “belong” to main, so you can’t run into problems with other scripts that might use an (uninitialized) x and y (because those won’t exist in the global space). You’d have to refer to them as main.x and main.y for this to happen

                        From what I can tell, it’s impossible to access variables that way (main.x, gives error)… but then it’s even more to your point :)

                        I wonder whether you found advantages to wrapping in a class vs just using nested functions inside main() ?

                        No need to go in detail ; just curious whether you indeed found advantages or it’s just… a way that also works.

                        Mark OlsonM 1 Reply Last reply Aug 2, 2023, 2:05 AM Reply Quote 0
                        • Mark OlsonM
                          Mark Olson @Victorel Petrovich
                          last edited by Aug 2, 2023, 2:05 AM

                          @Victorel-Petrovich said in Pythonscript plugin: how to end the script but not quit Notepad++:

                          I wonder whether you found advantages to wrapping in a class vs just using nested functions inside main() ?

                          More advanced scripts can have multiple callbacks, and the result of one function can depend on the output of other functions.

                          Just a simple example (not going to bother writing the script, left as an exercise to the reader):

                          NOTIFICATION.BUFFERACTIVATED callback: save the current filename to a class variable
                          when the script is invoked: print(the current filename (saved by the callback))
                          
                          V 1 Reply Last reply Aug 2, 2023, 2:31 AM Reply Quote 0
                          • V
                            Victorel Petrovich @Mark Olson
                            last edited by Victorel Petrovich Aug 2, 2023, 3:29 AM Aug 2, 2023, 2:31 AM

                            @Mark-Olson
                            Well, when I get to the point that functions won’t suffice, I’ll consider classes.

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