MacroInspect which comments macros
-
Hello, @mpheath, @alan-kilborn, @peterjones and All,
Note that, if this new attribute would exist, then, using the @mpheath’s solution or any other one, it could be possible to fill in all the
comments
zones automatically, when N++ exits and theshortcuts.xml
file is saved !On restarting N++, the display of the
shortcuts.xml
file would produce good pieces of information, in the user language !However, this would probably need a lot of coding for, I must admit, a little benefice !
Best Regards,
guy038
-
To All, I have updated the gist with revision 2.
Minor changes. The header files will be removed if json files are created or already exist.
@Alan-Kilborn said in MacroInspect which comments macros:
I’d have been more apt to leave them if the code had created a subdir and put them in that.
As is, I don’t like misc files sitting in the root of my config dir.Agree. It could get very messy if scripts follow the trend including this script.
The name of this subdir could be
Config\MacroInspect
though I consider that as starting an ugly trend. Perhaps within theConfig\PythonScript\scripts\MacroInspect
though still the files are not scripts as they are data files.Perhaps a central subdir like
Config\Temp
and temporary data files go there. So a user can clean that directory periodically and the scripts can remake the data files from latest version content as needed. To save name collisions could possibly prefix the files with script name likeMacroInspect-Type0.json
for example. If a script does not remake the data files then this temp directory would not be good to use and so may need a subdir likeConfig\Static
for example.The concept may need some confirmation before I modify the script to alter where the data files go else the script may make a mess with obsolete data files in the
Config
directory. -
When I write a script that needs a permanent data file, I put the data file in the same folder as the script with a common prefix on the name. An example probably helps:
Script:
...\plugins\Config\PythonScript\scripts\fubar.py
Data:...\plugins\Config\PythonScript\scripts\fubar_data.json
It’s not too messy; locate the script (e.g. Windows Explorer) and the data file is visually adjacent to it.
If I need more than one data file (i.e., your situation), I give everything its own folder:
Folder:
...\plugins\Config\PythonScript\scripts\foo\
Script:...\plugins\Config\PythonScript\scripts\foo\foo.py
Data1:...\plugins\Config\PythonScript\scripts\foo\foo_data1.json
Data2:...\plugins\Config\PythonScript\scripts\foo\foo_data2.txt
In this case it isn’t terribly important to name the data files with the common prefix…
YMMV. I’m sure you’ll decide on a workable solution.
-
To All, I have updated the gist with revision 3.
Implemented the @Alan-Kilborn idea of single json file saved next to the script.
Please manually remove existing data files from the Config directory:
FindReplaceDlg_rc.h FindReplaceDlg_rc.h.json Scintilla.h Scintilla.h.json
Update
MacroInspect.py
in theConfig\PythonScript\scripts
directory. On first run should download the header data and save toConfig\PythonScript\scripts\MacroInspect_data.json
. No temporary header files as the data will all be processed in memory.Improved message
1701
comment which isIDC_FRCOMMAND_EXEC
will now show it’slParam
related constant.
Some examples:<!-- IDC_FRCOMMAND_EXEC [IDCMARKALL] --> <!-- IDC_FRCOMMAND_EXEC [IDD_FINDINFILES_FIND_BUTTON] --> <!-- IDC_FRCOMMAND_EXEC [IDD_FINDINFILES_FINDINPROJECTS] -->
-
I ran revision 3 and it seemed to go as desired.
Afterward I looked for the
MacroInspect_data.json
file and curiously I did not find it anywhere on my system.After changing the code to add
print('json_file:', json_file)
I then saw the problem.
I use a script to “run the script in the active tab” so that I can tie it to a keycombo for quickly executing a script under development, over and over again as development proceeds. I think I would go mad if I had to navigate the menus to repeatedly run a script I’m actively working on. (Yes, there are other alternatives…)Anyway, I found that the data file for your script was being created for me as
RunCurrentPyFileAsPythonscript_data.json
because my “script runner” script is namedRunCurrentPyFileAsPythonscript.py
. This results (apparently) from the use of__file__
in your code.No big deal, I can compensate for this… :-)
Again, great job on a great script.
-
Sorry to hear. It’s still a bug even if it is a script running a script. I just tested
sys.argv
and thought argument 0 might be OK though it returns['C:\\Programs\\Notepad++\\notepad++.exe']
. If you can test something that works for you and everyone else then please share. I may test some alternatives though I am not sure if I can reproduce your environment to be sure of a fix. -
In general, a way I’ve found to do it is:
inspect.getframeinfo(inspect.currentframe()).filename
after importing
inspect
, and then getting the directory part of the path from that.This worked great in PythonScript2, as the path to the file was returned from the inspect call. In PythonScript3, however, all that call obtains is a filename without the complete path.
You can experiment with that if you like, or I’ll post some more complete code later.
-
Just tested in a Python interpreter.
__file__
can be set to a value. So perhaps yourRunCurrentPyFileAsPythonscript.py
can set__file__
to the absolute path of the child script before it runs the subprocess, so then the child process use of__file__
is inherited like as if it is the main process. -
@mpheath said:
perhaps your RunCurrentPyFileAsPythonscript.py can set file to the absolute path of the child script before it runs …
A good idea, however it doesn’t work (I still get the calling script’s name/path), at least the way I’m having a script run a script; there are many ways to do it. It’s actually surprisingly difficult to have a script run a script (and have things all turn out like you’d like).
LATER EDIT:
Actually, it did work; what caused it to not work the first time I tried it was programmer error, i.e., me!
I may have to look further into using the__file__
variable technique instead of myinspect
-based technique, as it seems like it could simplify things under Python3. -
I see you didn’t break down the search “boolean” values in your latest script, so, I took the liberty of pulling that code from my now defunct macro disassembler and inserting it into your script:
elif message == 'IDC_FRCOMMAND_BOOLEANS': numeric_data = int(v) bit_weights_numeric_value_to_str_dict = { 1 : 'MATCH_WHOLE_WORD_ONLY', 2 : 'MATCH_CASE', 4 : 'PURGE_MARKS_BEFORE_NEW_SEARCH', 16 : 'BOOKMARK_LINE', 32 : 'IN_SUBFOLDERS', 64 : 'IN_HIDDEN_FOLDERS', 128 : 'IN_SELECTION__OR__PROJECT1', 256 : 'WRAP_AROUND__OR__PROJECT2', 512 : 'FORWARD_DIRECTION__OR__PROJECT3', 1024 : 'DOT_MATCHES_NEWLINE_FOR_REGEX', } running_single_bitweight = 1 search_options_str_list = [] while numeric_data != 0: if running_single_bitweight in bit_weights_numeric_value_to_str_dict: if (numeric_data & running_single_bitweight) != 0: search_options_str_list.append(bit_weights_numeric_value_to_str_dict[running_single_bitweight]) numeric_data &= ~running_single_bitweight running_single_bitweight <<= 1 value_str = 'NONE' if len(search_options_str_list) == 0 else ' / '.join(search_options_str_list) comment += ' [ ' + value_str + ' ]'
-
I have already tested
IDC_FRCOMMAND_BOOLEANS
and ran into issues. If you look at the json data file, you may see lines like:"128": "IDF_IN_SELECTION_CHECK IDF_FINDINFILES_PROJECT1_CHECK", "256": "IDF_WRAP IDF_FINDINFILES_PROJECT2_CHECK", "512": "IDF_WHICH_DIRECTION IDF_FINDINFILES_PROJECT3_CHECK",
which has space delimited pairs of constant names.
as I use this code to fill the dictionary with the constant pairs:
if k in dic: dic[k] += ' ' + v else: dic[k] = v
which are pairs that share the same boolean value in which only 1 can be correct. Though in testing depending on the FindReplaceDLG tab recorded, sometimes none are correct IMO. I am unsure if I can fix the code I have to make it reliable as some incorrect comments may make the user puzzled. I suspect that perhaps some bit flags should not be in the
lParams
value and perhaps the playback ignores them, though that does not help with making the xml comments.
Edit:
There is also a possibility that Notepad++ is getting the checkbox booleans incorrect. Unchecked/checked is ok until disabling the checkbox, which leads to a 3rd state with a enabled/disabled needing to be validated. IDK yet and so may need investigation. This may explain why I get
IDF_FINDINFILES_PROJECT2_CHECK
andIDF_FINDINFILES_PROJECT3_CHECK
in the comments even though they are unchecked and disabled so cannot be valid in the xml comments. -
@mpheath said in MacroInspect which comments macros:
I have already tested IDC_FRCOMMAND_BOOLEANS and ran into issues.
I don’t know…but I’m fairly certain the code I posted works correctly.
which are pairs that share the same boolean value in which only 1 can be correct.
Yep, the “genius” that implemented the project options decided repurposing some bit weighting for that was a great idea.
I suspect that perhaps some bit flags should not be in the lParams value and perhaps the playback ignores them
Yes, there can be items that are not applicable in there.
If one knew in advance what the 1701 value was going to be, one could filter out the n/a items, but alas the 1702 message comes before the 1701.