Remove "save file" prompt?
-
As @TBugReporter linked, just call the
editor.setSavePoint()
function to make the editor think that the current tab contents have been saved. The tab icon will change state to reflect this. Needless to say, be careful when using this.I think @TBugReporter only remembers this function because he didn’t like my usage of it in a previously published script. :-)
-
@Alan-Kilborn I appreciate the elaboration! I was able to test out the functionality of it, but unfortunately I can’t quite get it to work.
Anyways, I’ll admit, I borrowed a script that was made by Eko palypse, found at the bottom of this thread. I made one tiny modification to it for modern XML Tools standards. This portion works beautifully.
Having tested it, running
editor.setSavePoint()
direct from the console works, but appears to have no effect when this script is run. I can tell as it both prompts me, and the editor specifies that changes haven’t been saved on the side. I know it imports the editor module as well, so I’m guessing some context somewhere.The function works as I’d hoped though, just not when as part of a script. Can’t help but feel I’m missing something!
-
The function works as I’d hoped though, just not when as part of a script. Can’t help but feel I’m missing something!
I don’t get the feeling your customized script is going to be huge, so how about posting it? Maybe something will jump out.
-
from Npp import notepad, editor, NOTIFICATION, LANGTYPE editor.setSavePoint() def BufferActivated(args): if notepad.getLangType() == LANGTYPE.XML and editor.getProperty('already_formatted') == '': notepad.runPluginCommand('XML Tools','Pretty print - indent attributes') editor.setProperty('already_formatted', '1') notepad.callback(BufferActivated, [NOTIFICATION.BUFFERACTIVATED])
Really, the only difference between the original and mine is an update to the pretty print function here to run the updated version of the command, and the addition of
editor.setSavePoint()
. But, even then it doesn’t act as intended. Pretty print runs, but still prompts for save.I know for a fact I’m missing something. Figured it should be after the
from
in this code though. Thanks for your help! -
Hmmmmmmmmmmmmmmmmmm. How to explain this to the uninitiated…?
Forget where you put
editor.setSavePoint()
for a moment; consider the remainder of the script.When you run that script, it becomes “resident”. You don’t have to keep running that script when you want the “pretty print” stuff to execute, it just happens whenever you change tabs in Notepad++, after you’ve run the script ONCE.
It runs on the tab you make active. Hence “buffer activated – callback”. Get it? It’s code that gets called when a certain thing happens, specifically, when activating a tab. There are all kinds of other callbacks, e.g. when a file is saved by the user, when a file is renamed by the user, etc.
Now the smart thing to do might be to put the script into user startup.py, or call the script from there. You can find more details about script setup and use HERE. But this is off topic from your original question.
So if you want the
setSavePoint()
call to do its stuff at the same time (well, right after) as the “pretty print” (not saying you do, I’m not really following your exact need), then you should put theeditor.setSavePoint()
call directly below thesetProperty
line, and indented to the same level.That way it will happen when a tab is activated, right after the pretty printing. But again, I don’t know for sure that’s what you want.
Seriously, this stuff isn’t that hard to “read” and know what it does. Now, if you had to write it from scratch, that’s a different story.
-
I should have mentioned that “buffer activated” also occurs when you open a file. There’s a “file opened” callback, but my experience with that one is that you can’t really do much there, because the tab with data that you want to act on isn’t fully formed at that point. You have to wait for “buffer activated” to be signalled (from N++).
So after you’ve run the script ONCE, then the logic should run anytime you switch the active tab, or when you open a file. Since the script has logic to only do stuff when the tab is an XML file, nothing will happen in those scenarios where you are dealing with a non-XML file.
-
@Alan-Kilborn Thank you again for all the information! Fortunately I’ve been writing some basic Powershell scripts recently so I’m getting the hang of this. Your explanation made total sense when I realized that it needed to go into the executed part of the if statement, if that makes sense. This is now working exactly as I hoped, which amazes me. I did, however, call that function(?) before running the pretty print as I wanted to be sure that any modifications made would not be saved. The undo button has been proving that!
EDIT: Almost forgot to mention, this is part of my startup.py script, so this runs by default and works automatically as a result once set to “ATSTARTUP” for the initialization.
EDIT 2: Apparently I misconfigured this, and Alan was indeed right, it should be after the setProperty line. Code is updated, realized my mistake after I re-tested it just now.
Also, for those interested in exactly what the code looks like:
from Npp import notepad, editor, NOTIFICATION, LANGTYPE def BufferActivated(args): if notepad.getLangType() == LANGTYPE.XML and editor.getProperty('already_formatted') == '': notepad.runPluginCommand('XML Tools','Pretty print - indent attributes') editor.setProperty('already_formatted', '1') editor.setSavePoint() notepad.callback(BufferActivated, [NOTIFICATION.BUFFERACTIVATED])
Thank you so much for your time, I think my users are going to be very pleased!
-
And so far I’ve found one quirk I needed to iron out. Probably due to my lack of understanding how the buffer works and the function, this only applies when an active tab is switched to, not when Notepad++ is opened. This also applies to opening files directly, where it would not format until another tab is opened. Of course, this poses an issue for me as I can very quickly see users complaining about how it doesn’t format correctly as I see them opening one file, closing Notepad++, then immediately opening a completely different file.
I did find out that (sloppily) copying the same to run a singular if command works, and the
BufferActivated
function still runs for any new tabs, thus solving my issue! I’m posting this here in hopes that someone else might get some use out of it, or an opportunity for someone to optimize the code.from Npp import notepad, editor, NOTIFICATION, LANGTYPE if notepad.getLangType() == LANGTYPE.XML and editor.getProperty('already_formatted') == '': notepad.runPluginCommand('XML Tools','Pretty print - indent attributes') editor.setProperty('already_formatted', '1') editor.setSavePoint() def BufferActivated(args): if notepad.getLangType() == LANGTYPE.XML and editor.getProperty('already_formatted') == '': notepad.runPluginCommand('XML Tools','Pretty print - indent attributes') editor.setProperty('already_formatted', '1') editor.setSavePoint() notepad.callback(BufferActivated, [NOTIFICATION.BUFFERACTIVATED])
The catch here is that it runs a bit too often. Good if you’re looking to look at a single file, not good if you’re looping between multiple XML files. Still gets the job done though!
-
STOP! You’re doing it wrong!
Every time you run that script, you put another callback in place.
If you run it twice, then after that when you switch tabs, the callback function will run twice. If you manually run the script n times, the callback function will run n times when you switch tabs. Do you really want the same functionality to run n times over when you switch tabs? No, once is enough when you switch tabs.If you want additional functionality, to run “on demand”, put that in a separate script, and then run that script at the right time.
-
@Alan-Kilborn said in Remove “save file” prompt?:
I think @TBugReporter only remembers this function because he didn’t like my usage of it in a previously published script. :-)
No, that wasn’t it; I just wasn’t expecting the result of adding this to the script. (My latest version of that script has this as a configurable option. I haven’t published my version because I still feel it’s not ready for prime time.)
@BrunchTime said in Remove "save file" prompt?:
I did, however, call that function before running the pretty print as I wanted to be sure that any modifications made would not be saved.
This was exactly the wrong thing to do, because every change you make unsets this. As you’ve found out, you have to do this after you’ve made all your changes.
-
@Alan-Kilborn said in Remove “save file” prompt?:
STOP! You’re doing it wrong!
Every time you run that script, you put another callback in place.So let’s explore this a bit further.
Create a script much like the earlier one in this thread:
# -*- coding: utf-8 -*- from __future__ import print_function from Npp import * console.show() print('user ran the script! (let us flash the screen for fun)') editor.flash(250) def BufferActivated(args): print('system-generated buffer activated! tab:', notepad.getCurrentFilename().rsplit('\\', 1)[-1]) notepad.callback(BufferActivated, [NOTIFICATION.BUFFERACTIVATED])
Run it once via the Plugins > Python Script > Scripts menu. Then click on different tabs, get something like this as output in the PythonScript console window:
user ran the script! (let us flash the screen for fun) system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 1 system-generated buffer activated! tab: new 2 system-generated buffer activated! tab: new 3
All good. Now run the script 3 more times from the Plugins > Python Script > _Run Previous Script() _ menu.
Now select a few different tabs (I did same sequence as above) to obtain:
user ran the script! (let us flash the screen for fun) user ran the script! (let us flash the screen for fun) user ran the script! (let us flash the screen for fun) system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 1 system-generated buffer activated! tab: new 1 system-generated buffer activated! tab: new 1 system-generated buffer activated! tab: new 1 system-generated buffer activated! tab: new 2 system-generated buffer activated! tab: new 2 system-generated buffer activated! tab: new 2 system-generated buffer activated! tab: new 2 system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 3 system-generated buffer activated! tab: new 3
As one can see, each time you switch a tab now, the callback gets called FOUR times! That’s because the script was run 4 times, and 4 separate callback functions were registered. It doesn’t matter that it was the “same” function that was registered each time.
How does one avoid/prevent this kind of thing from happening? Well, don’t run the script multiple times. But, accidents happen, so change the code to protect yourself. But how?
The changed script below shows how I like to do it (there are certainly other ways to achieve it):
# -*- coding: utf-8 -*- from __future__ import print_function from Npp import * console.show() print('user ran the script! (let us flash the screen for fun)') editor.flash(250) def BufferActivated(args): print('system-generated buffer activated! tab:', notepad.getCurrentFilename().rsplit('\\', 1)[-1]) # --- vvv --- differences from original script are below --- vvv --- try: i_am_installed except NameError: notepad.callback(BufferActivated, [NOTIFICATION.BUFFERACTIVATED]) i_am_installed = True else: print('callback is already installed!')
The effect should be somewhat self-explanatory from the code. If you try the multiple runs experiment with this new version of the script, you shouldn’t see multiple buffer-activated processing when tabs are switched in the Notepad++ UI.