How to write macro for Notepad++? - macros

I would like to write a macro for Notepad++ which should replace char1, char2, char3 with char4, char5, char6, respectively.

Macros in Notepad++ are just a bunch of encoded operations: you start recording, operate on the buffer, perhaps activating menus, stop recording then play the macro.
After investigation, I found out they are saved in the file shortcuts.xml in the Macros section. For example, I have there:
<Macro name="Trim Trailing and save" Ctrl="no" Alt="yes" Shift="yes" Key="83">
<Action type="1" message="2170" wParam="0" lParam="0" sParam=" " />
<Action type="1" message="2170" wParam="0" lParam="0" sParam=" " />
<Action type="1" message="2170" wParam="0" lParam="0" sParam=" " />
<Action type="0" message="2327" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2327" wParam="0" lParam="0" sParam="" />
<Action type="2" message="0" wParam="42024" lParam="0" sParam="" />
<Action type="2" message="0" wParam="41006" lParam="0" sParam="" />
</Macro>
I haven't looked at the source, but from the look, I would say we have messages sent to Scintilla (the editing component, perhaps type 0 and 1), and to Notepad++ itself (probably activating menu items).
I don't think it will record actions in dialogs (like search/replace).
Looking at Scintilla.iface file, we can see that 2170 is the code of ReplaceSel (ie. insert string is nothing is selected), 2327 is Tab command, and Resource Hacker (just have it handy...) shows that 42024 is "Trim Trailing Space" menu item and 41006 is "Save".
I guess action type 0 is for Scintilla commands with numerical params, type 1 is for commands with string parameter, 2 is for Notepad++ commands.
Problem: Scintilla doesn't have a "Replace all" command: it is the task of the client to do the iteration, with or without confirmation, etc.
Another problem: it seems type 1 action is limited to 1 char (I edited manually, when exiting N++ it was truncated).
I tried some tricks, but I fear such task is beyond the macro capabilities.
Maybe that's where SciTE with its Lua scripting ability (or Programmer's Notepad which seems to be scriptable with Python) has an edge... :-)
[EDIT] Looks like I got the above macro from this thread or a similar place... :-) I guess the first lines are unnecessary (side effect or recording) but they were good examples of macro code anyway.

I found 'Python Script' plugin for Notepad++ more useful since with the plugin, I could write simple macros in the form of python and It has also got very good documentation and sample macros written in python as well. If you are quite comfortable with python, then I think 'Python Script' will provide justice.
For more information, refer : http://npppythonscript.sourceforge.net/

I recorded a macro and I found it in %APPDATA%\Notepad++\shortcuts.xml. It looks like posted in the first post of this thread.
I use NPP Ver. 5.9.6.2 with Win7.

Posting more than 10 years after the OP, but I think that this is still a relevant question (it is for me, at least). Today, there is quite some information in the Notepad++ User Manual, relating to the OP's question:
General Info about macros: https://npp-user-manual.org/docs/macros/
General explanation about the language used is in the config files docs: https://npp-user-manual.org/docs/config-files/#macros
Search and Replace Actions (as requested by the OP) are covered in more detail here: https://npp-user-manual.org/docs/searching/#searching-actions-when-recorded-as-macros
Here is a block of macro code: replace SEARCHTEXT by REPLACETEXT, using regular expressions, "." finds /r and /n, in every file matching the filter GLOBFILEFILTER in a folder PATH (no subfolders, not sure where this flag is defined/set).
<Macro name="REPLACE_IN_FILES_REGEX_DOT_FINDS_CR_AND_LF" Ctrl="no" Alt="no" Shift="no" Key="0">
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam="SEARCHTEXT" />
<Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
<Action type="3" message="1602" wParam="0" lParam="0" sParam="REPLACETEXT" />
<Action type="3" message="1653" wParam="0" lParam="0" sParam="PATH" />
<Action type="3" message="1652" wParam="0" lParam="0" sParam="GLOBFILEFILTER" />
<Action type="3" message="1702" wParam="0" lParam="1024" sParam="" />
<!-- #COMMENT: "1024" seems to be the flag ". finds /n and /r". This is not in the documentation. -->
<Action type="3" message="1701" wParam="0" lParam="1660" sParam="" />
</Macro>
Remarks about this code:
The path to the folder needs to end with a backslash.
Characters like <, >, & need to be escaped in the xml. Rather create your search and replace strings by recording a macro.

This post can help you as a little bit related :
Using RegEX To Prefix And Append In Notepad++
Assuming alphanumeric words, you can use:
Search = ^([A-Za-z0-9]+)$
Replace = able:"\1"
Or, if you just want to highlight the lines and use "Replace All" & "In Selection" (with the same replace):
Search = ^(.+)$
^ points to the start of the line.
$ points to the end of the line.
\1 will be the source match within the parentheses.

My personal experience is that shortcuts.xml is overwritten with the initially loaded + later recorded macros and settings when Notepad++ exits. So you can't use Notepad++ itself for editing this file.
Close Notepad++, edit shortcuts.xml by another tool, save it and restart Notepad++.

I'm not sure if this helps, but I needed to create a macro to hold a snippet, so I simply recorded myself inserting the items and set a shortcut to it. Granted, I'm not using version 5.9 so there might be some slight version differences. To access the macro recorder go to Macro > Start Recording. Then you will perform your action and then go to Macro > Stop Recording. I'd recommend playing it back to ensure it's correct and then save and set your shortcut key.
Hope the helps.

I just did this in v5.9.1. Just go to the Macro Menu, click "Start Recording", perform your 3 replace all commands, then stop recording. You can then select "Save Current Recorded Macro", and play it back as often as you like, and it will perform the replaces as you expect.

Actually, the shortcuts.xml file does not store user-generated macros and no obvious candidates contain this info. These instructions are out of date.
Contrary to various websites' tips, storing user-generated macros isn't enabled for v.5.4.2. That XML file is there, but your macro does not get stored it in.
I'm guessing it's a bug that'll be fixed by the next version.

Related

How to add condition checks in eclipse plugin.xml file?

I need to hide a menu item (File -> Exit) that is not relevant to me. I could do this using org.eclipse.ui.activities extension. The following code works great:
<activity
description="Capability to filter all menus not relevant to the product"
id="com.xxx.productspecific.filter.menus"
name="Common UI Filter for menus">
</activity>
<activityPatternBinding
activityId="com.xxx.productspecific.filter.menus"
isEqualityPattern="true"
pattern="org.eclipse.ui.file.exit">
</activityPatternBinding>`
Now I need to make this work based on some condition. I have a program argument (or command-line argument) "targetEnv=FDK". The menu should be hidden only when this argument is available. I tried the below snippet, but the menu items continue to be hidden no matter what I provide in the argument.
<activity
description="Capability to filter all menus not relevant to the product"
id="com.xxx.productspecific.filter.menus"
name="Common UI Filter for menus">
<enabledWhen>
<with
variable="%targetEnv">
<equals
value="FDK">
</equals>
</with>
</enabledWhen>
Is this the right way to use a program argument in plugin.xml?

Visual Studio Code and Prettier html formatting on separate lines

I'm using VS Code, and Prettier and cannot get it to format the way I want it to be upon saving.
If I have a line like
<input type="checkbox" /> Label<br />
upon format/save, it becomes
<input type="checkbox" />
Label
<br />
I don't want to turn off Format on Save since I want to be able to Format Document from time-to-time. Is there a setting to get the line breaks how I want them? I'd prefer it only wrap on line length and other wanted places (e.g. select and option tags on different lines)
Note: this is just a simplified example. There are many other cases where it's putting every tag on a separate line when I'd like them to stay on one.
You need to update your .prettierrc file in your root to have
"printWidth": 1000
or whatever print width you are looking to have and it should fix this. Also check out the Prettier docs at https://prettier.io/docs/en/configuration.html to see other items you can configure.

Karabiner: Change double quote to single

Is it possible to replace double quote key to single quote with Karabiner (keyboard customizer for OS X)?
https://pqrs.org/osx/karabiner/
Yes, I think so. Look into how the private.xml works, which you can open via the Misc & Uninstall Tab. However, I think for changing the actual key codes you need seil, but you can probably do it with Karabiner alone by remapping SHIFT_L + QUOTE.
You might end up w/ s.th. like this:
<?xml version="1.0"?>
<root>
<item>
<name>Double Quote to Single Quote</name>
<identifier>private.double_quote_to_single_quote</identifier>
<autogen>
__KeyToKey__
KeyCode::QUOTE, ModifierKey::SHIFT_L,
KeyCode::QUOTE
</autogen>
</item>
</root>
This is just a guess though, but hopefully brings you in the right direction.
I have found this when I was searching for a way to swap single quote and double quote. This is how I've managed to do it with this: https://ke-complex-modifications.pqrs.org/#exchange_single_and_double_quote

Automating Notepad++ macros

I've created a macro that parses reports generated from an Access DB, Database Documenter tool.
I have multiple reports I want to run this on, but even though I've opened multiple reports within Notepad++, I can only run it on one report at a time.
When I recorded the macro, I didn't select Replace All in All Opened Documents.
Is there a change in Shortcuts.xml I can make that will cause the macro to run on all the open docs?
I have recorded other macros, where I did select Replace All in All Opened Documents, But I have seen no difference between those ones and the one I just worked on.
I have 60 documents and the macro has 125 steps.
Your help would be greatly appreciated
Thanks
I did some playing around with macros and here's what I've come up with.
The "Replace All" button click is represented by these two lines in shortcuts.xml:
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
The "Replace All in All Open Documents" click is represented by these two lines:
<Action type="3" message="1702" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1635" sParam="" />
If you look for those first two lines in your shortcuts.xml file, you should be able to replace them with the last two and have it work. I'd make a backup of your shortcuts file before doing so though. Just in case.

Replacing content in Word 2010 Textboxes using OpenXML

Using the Open XML SDK I've been successful in programatically finding bookmarks or text strings in a word document and inserting new content. I'm using OpenXmlPowerTools.SearchAndReplacer to do the text search and replace and this post's answer for the bookmarks Replace bookmark text in Word file using Open XML SDK
This all fails when the bookmark or the text I am trying to replace is located inside a Textbox.
Why does neither approach work within a Textbox? The Word documents I am trying to replace content within use Texboxes for layout and I can't work out what the problem is.
Does anybody have suggestions as to what might be the problem? Thanks
I did this - it works on text boxes in the case where there are not multiple runs with text (like 1 word bolded
Dim searchQuery = From tx In mainPart.Document.Body.Descendants(Of Text)()
Where tx.Text.Contains(replaceData.OldText)
Dim i As Integer
For i = 0 To searchQuery.Count - 1
searchQuery(i).Text = searchQuery(i).Text.Replace(replaceData.OldText, replaceData.NewText)
Next
Here is the XML for a simple textbox with the word test in it:
<w:pict xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
<v:stroke joinstyle="miter" />
<v:path gradientshapeok="t" o:connecttype="rect" />
</v:shapetype>
<v:shape id="_x0000_s1027" style="position:absolute;margin-left:0;margin-top:0;width:186.35pt;height:110.6pt;z-index:251660288;mso-width-percent:400;mso-height-percent:200;mso-position-horizontal:center;mso-width-percent:400;mso-height-percent:200;mso-width-relative:margin;mso-height-relative:margin" type="#_x0000_t202" xmlns:v="urn:schemas-microsoft-com:vml">
<v:textbox style="mso-fit-shape-to-text:t">
<w:txbxContent>
<w:p w:rsidR="00B558B5" w:rsidRDefault="00B558B5">
<w:proofErr w:type="gramStart" />
<w:r>
<w:t>test</w:t>
</w:r>
<w:proofErr w:type="gramEnd" />
</w:p>
</w:txbxContent>
</v:textbox>
</v:shape>
</w:pict>
You can see the structure is different then when searching for text within a bookmark since a textbox is actually stored as a picture. If you adjust your searching algorithm to deal with this different structure then you should be able to find the text and replace it.