• Select data between tabs

    6
    0 Votes
    6 Posts
    783 Views
    PeterJonesP

    @Vasile-Caraus ,

    The OP’s data has a TAB character (\t or \x09) followed by some data followed by a TAB character, and wants to select the data that comes between two
    490bb2c0-2678-4ac6-831e-4bcc3a6a1dd7-image.png

  • Way to disallow copying text?

    7
    1 Votes
    7 Posts
    2k Views
    Alan KilbornA

    So I “solved” this issue.
    Disclaimer: I didn’t do it all by myself; I enlisted the aid of a former contributor on this forum to get it done with a PythonScript – and he said that even he consulted some others about certain aspects…so it is not a trivial endeavor!

    And solving this problem is not an absolute. It only prevents the novice user from copying from a Notepad++ window – it can totally be circumvented if a user renames a file to have a file extension that isn’t enforced, or one that knows how to disable the script, or one that does a Find All in Current Document search and then copies results from “THAT” window, etc., etc., etc… That’s why I said “solved” – with the quotes.

    Ok, so let’s go with some details before presenting the script…

    The general approach is to “hook” the Windows message loops for the Notepad++ window, and the two editor windows used for Notepad++'s two views. “Hooking” allows one to pre-process messages, and when you do this, you can “filter out” messages selectively – and not allow Notepad++ to process them. This is perfect for when you want to disallow a copy – you just intercept messages relating to copying of text and don’t allow Notepad++ to get them and do their default duty.

    However, we can’t get at certain things by hooking the message loops. Meaning, we can’t get at a WM_COPY or an SCI_COPY message directly. This would be ideal: Any time we receive something that looks like a user request to copy data, it should look like a WM_COPY message which we could throw away – and nothing will be copied. Reality, however, is a bit more complicated. Here are the general rules:

    A Notepad++ command that has no keycombo assigned in Shortcut Mapper is easily intercepted; one merely has to “hook” into WM_COMMAND messages and check to see if wParam has a value corresponding to the command of interest. The command values are found by looking at the Notepad++ source code file called menuCmdID.h, see HERE.

    A Notepad++ command that has a keycombo assigned to it in Shortcut Mapper – and one that is NOT a “Scintilla command” – gets translated into something else BEFORE the “hook” function can obtain the keycombo. These commands get translated into a WM_COMMAND message with a wParam parameter (as described above for an command with no keycombo assigned). But it does mean that you can’t decide, for example, “I’m going to intercept anytime the user presses F5!” because it just won’t work; your “hook” function won’t see the WM_KEYDOWN messages for F5 (by default, this is the “Run” command on N++'s Run menu).

    A keycombo that has a “Scintilla command” function tied to it can be directly intercepted as a WM_KEYDOWN message. While you can intercept at the keycombo level, you can’t – for key-assigned “Scintilla commands” – intercept at the functional (or command) level. As an example, you can intercept “Ctrl+c” but you can’t intercept the “copy” functionality itself – thus if your intent is to intercept “copy” and user assigns it to a non-standard keycombo, you can’t get at it that way, you have to go directly after the specific keycombo. And how would you know what that non-standard assignment is? – you wouldn’t.

    So how do we apply the “rules” above to what I originally wanted to do, specifically, prevent a user from copying data out of Notepad++?

    Well, we need to:

    prevent menu commands (which possibly have keycombos assigned to them) that have to do with copying (or cutting) data from running – examples include Edit menu’s Copy and Cut commands, the right-click context menu’s Copy and Cut commands, the Edit menu’s Paste Special commands for Copy Binary Content and Cut Binary Content

    prevent Scintilla cut/copy-related keycombos from executing their functions – examples include Ctrl+c, Ctrl+x, Ctrl+Ins, Shift+Delete

    we also need to decide what file types (extensions) the copy functionality should be disabled for

    The following script does all that. I call the script PreventCopyFromCertainFileTypes.py and here’s its listing:

    # -*- coding: utf-8 -*- from __future__ import print_function from Npp import editor, notepad import ctypes from ctypes.wintypes import HWND, INT, UINT, WPARAM, LPARAM, BOOL import platform import os user32 = ctypes.WinDLL('user32', use_last_error=True) LRESULT = LPARAM WndProcType = ctypes.WINFUNCTYPE(LRESULT, HWND, UINT, WPARAM, LPARAM) user32.CallWindowProcW.restype = LRESULT user32.CallWindowProcW.argtypes = [WndProcType, HWND, UINT, WPARAM, LPARAM] if platform.architecture()[0] == '32bit': user32.SetWindowLongW.restype = WndProcType user32.SetWindowLongW.argtypes = [HWND, INT, WndProcType] SetWindowLong = user32.SetWindowLongW else: user32.SetWindowLongPtrW.restype = WndProcType user32.SetWindowLongPtrW.argtypes = [HWND, INT, WndProcType] SetWindowLong = user32.SetWindowLongPtrW GWL_WNDPROC = -4 WM_KEYDOWN = 0x100; WM_COMMAND = 0x111; WM_CHAR = 0x102 VK_SHIFT = 0x10; VK_CONTROL = 0x11; VK_MENU = VK_ALT = 0x12 VK_C = 67; VK_X = 88; VK_INSERT = 45; VK_DELETE = 46 CTRL_C_CHAR = 3; CTRL_X_CHAR = 24 IDM_EDIT_COPY = 42002; IDM_EDIT_CUT = 42001; IDM_EDIT_COPY_BINARY = 42048; IDM_EDIT_CUT_BINARY = 42049 class PCFCFT(object): def __init__(self, debug=False): self.debug = debug self.registered = False self.npp_hwnd = user32.FindWindowW(u'Notepad++', None) assert self.npp_hwnd self.enum_scintilla(self.npp_hwnd) # get hwnds for editor1 and editor2 assert all([ self.scintilla1_hwnd, self.scintilla2_hwnd ]) self.STOP_PROCESSING_MSG = False # consume the msg; don't let npp/scintilla process it when we return self.CONTINUE_PROCESSING_MSG = True # let npp/scintilla process the message when we return self.register() def enum_scintilla(self, npp_hwnd): self.scintilla1_hwnd = self.scintilla2_hwnd = None EnumWindowsProc = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM) def foreach_window(hwnd, lParam): curr_class = ctypes.create_unicode_buffer(256) user32.GetClassNameW(hwnd, curr_class, 256) if curr_class.value in [u'Scintilla']: if user32.GetParent(hwnd) == npp_hwnd: if self.scintilla1_hwnd is None: self.scintilla1_hwnd = hwnd elif self.scintilla2_hwnd is None: self.scintilla2_hwnd = hwnd return False # stop enumeration return True # continue enumeration user32.EnumChildWindows(npp_hwnd, EnumWindowsProc(foreach_window), 0) def register(self): if not self.registered: self.new_npp_wnd_proc = WndProcType(self.new_npp_hook_proc) self.old_npp_wnd_proc = SetWindowLong(self.npp_hwnd, GWL_WNDPROC, self.new_npp_wnd_proc) self.new_editor1_wnd_proc = WndProcType(self.new_editor1_hook_proc) self.old_editor1_wnd_proc = SetWindowLong(self.scintilla1_hwnd, GWL_WNDPROC, self.new_editor1_wnd_proc) self.new_editor2_wnd_proc = WndProcType(self.new_editor2_hook_proc) self.old_editor2_wnd_proc = SetWindowLong(self.scintilla2_hwnd, GWL_WNDPROC, self.new_editor2_wnd_proc) self.registered = True def unregister(self): if self.registered: _ = SetWindowLong(self.npp_hwnd, GWL_WNDPROC, self.old_npp_wnd_proc) _ = SetWindowLong(self.scintilla1_hwnd, GWL_WNDPROC, self.old_editor1_wnd_proc) _ = SetWindowLong(self.scintilla2_hwnd, GWL_WNDPROC, self.old_editor2_wnd_proc) self.registered = False def modifier_key_pressed(self, the_key): # the_key can be VK_SHIFT, VK_CONTROL, VK_ALT return (user32.GetAsyncKeyState(the_key) & 0x8000) == 0x8000 def new_npp_hook_proc(self, hWnd, msg, wParam, lParam): retval = self.common_msg_processing_function(hWnd, msg, wParam, lParam) if retval: retval = user32.CallWindowProcW(self.old_npp_wnd_proc, hWnd, msg, wParam, lParam) return retval def new_editor1_hook_proc(self, hWnd, msg, wParam, lParam): retval = self.common_msg_processing_function(hWnd, msg, wParam, lParam) if retval: retval = user32.CallWindowProcW(self.old_editor1_wnd_proc, hWnd, msg, wParam, lParam) return retval def new_editor2_hook_proc(self, hWnd, msg, wParam, lParam): retval = self.common_msg_processing_function(hWnd, msg, wParam, lParam) if retval: retval = user32.CallWindowProcW(self.old_editor2_wnd_proc, hWnd, msg, wParam, lParam) return retval def common_msg_processing_function(self, hWnd, msg, wParam, lParam): if msg in [ WM_KEYDOWN, WM_COMMAND, WM_CHAR ]: # maybe the active file is NOT one that we are looking for... filename = notepad.getCurrentFilename().rsplit(os.sep, 1)[-1] if '.' in filename: (file, ext) = filename.rsplit('.', 1) if ext.lower() not in [ 'txt', 'py' ]: if self.debug: print('received a msg we handle, but not in a file with an excluded extension') return self.CONTINUE_PROCESSING_MSG if self.debug: origin = 'npp' if hWnd == self.npp_hwnd else 'editor1' if hWnd == self.scintilla1_hwnd else 'editor2' if msg == WM_KEYDOWN: if wParam not in [ VK_SHIFT, VK_CONTROL, VK_ALT ]: # these keys come thru when they are pressed by themselves (we don't care about that case) shift = self.modifier_key_pressed(VK_SHIFT) control = self.modifier_key_pressed(VK_CONTROL) alt = self.modifier_key_pressed(VK_ALT) if self.debug: print('origin:{o}, msg:WM_KEYDOWN, wParam:{w}, lParam:{L}, Shift:{s}, Ctrl:{c}, Alt:{a}'.format( o=origin, w=wParam, L=lParam, s=shift, c=control, a=alt)) if wParam == VK_C and control and not shift and not alt: if self.debug: print('Ctrl+c keydown consumed!') return self.STOP_PROCESSING_MSG if wParam == VK_X and control and not shift and not alt: if self.debug: print('Ctrl+x keydown consumed!') return self.STOP_PROCESSING_MSG if wParam == VK_INSERT and control and not shift and not alt: if self.debug: print('Ctrl+Insert keydown consumed!') return self.STOP_PROCESSING_MSG if wParam == VK_DELETE and not control and shift and not alt: if self.debug: print('Shift+Delete keydown consumed!') return self.STOP_PROCESSING_MSG elif msg == WM_COMMAND: if wParam not in [ VK_SHIFT, VK_CONTROL, VK_ALT ]: # for some reason these happen with WM_COMMAND...filter them out if self.debug: print('origin:{o}, msg:WM_COMMAND, wParam:{w}, lParam:{L}'.format(o=origin, w=wParam, L=lParam)) if wParam in [ IDM_EDIT_COPY, IDM_EDIT_CUT, IDM_EDIT_COPY_BINARY, IDM_EDIT_CUT_BINARY ]: if self.debug: print('copy/cut related menu item consumed!') return self.STOP_PROCESSING_MSG elif msg == WM_CHAR: if self.debug: print('origin:{o}, msg:WM_CHAR, wParam:{w}, lParam:{L}'.format(o=origin, w=wParam, L=lParam)) if wParam == CTRL_C_CHAR: if self.debug: print('Ctrl+c char consumed!') return self.STOP_PROCESSING_MSG if wParam == CTRL_X_CHAR: if self.debug: print('Ctrl+x char consumed!') return self.STOP_PROCESSING_MSG return self.CONTINUE_PROCESSING_MSG if __name__ == '__main__': try: pcfcft except NameError: debug = True if 1 else False pcfcft = PCFCFT(debug) if pcfcft.debug: print('installed') else: if pcfcft.registered: pcfcft.unregister() if pcfcft.debug: print('deactivated') else: pcfcft.register() if pcfcft.debug: print('reactivated')

    Some supplmental info:

    An interesting thing about “hook” functions is that you can use them to either avoid original functionality (like our example here shows) or you can “add on” functionality. To “add on” you simply call the original window function in addition to doing your special functionality. So maybe some add on functionality is just to print to the console “got message” or something like that. You do that print in your hook function, and then call the original function – blammo, add-on functionality! If you’re interested in seeing how that is accomplished in the script, look for usage of CONTINUE_PROCESSING_MSG and STOP_PROCESSING_MSG. This is also what lets the script be selective about which filetypes copies/cuts are disallowed from (the demo script chooses .txt and .py files).

    In the case of the non-keycombo commands, looking up the IDs for the commands in menuCmdID.h in Notepad++ source code yields this information (C++ code):

    #define IDM 40000 #define IDM_EDIT (IDM + 2000) #define IDM_EDIT_CUT (IDM_EDIT + 1) #define IDM_EDIT_COPY (IDM_EDIT + 2) #define IDM_EDIT_COPY_BINARY (IDM_EDIT + 48) #define IDM_EDIT_CUT_BINARY (IDM_EDIT + 49)

    leading to these "equivalent"s in the PythonScript code:

    IDM_EDIT_COPY = 42002; IDM_EDIT_CUT = 42001; IDM_EDIT_COPY_BINARY = 42048; IDM_EDIT_CUT_BINARY = 42049

    Another interesting thing with the script’s execution is that if you don’t allow Notepad++ to process the Ctrl+c keycombo as a WM_KEYDOWN event, you’ll get an “ETX” (hex code = 0x03) character in your document at the caret position. This occurs because, with Notepad++ ignoring the Ctrl+c as a command, it thinks that you want to embed a control character with value “3” into the doc (it gets a WM_CHAR message to that effect, which it would normally filter out on its own). So… in the case of preventing copying data, we have to remove any Ctrl+c or Ctrl+x characters that might get inserted; we do this by processing the WM_CHAR message and filtering those as well.

  • Simple is as Simple Does

    12
    0 Votes
    12 Posts
    719 Views
    Doc Trins O'GraceD

    @Alan-Kilborn Thank you!

  • 0 Votes
    2 Posts
    501 Views
    PeterJonesP

    @thompsop ,

    For Notepad++ versions through v7.9.5, the Style Configurator > Global Styles > Selected Text Color defines the background color for selection, but ignores the foreground color of that setting. So you could set the background color to something that contrasts with your active foreground color.

    However, the developers have heard the cries of pain over that setting, and for the v8.0 and newer, the Style Configurator will honor both the background and the foreground if you put the new 0-byte enableSelectFgColor.xml in the same folder as the notepad++.exe executable. Right now, v8 is in Release Candidate mode, and you can download it from the announcement topic, but it will likely be fully released soon (and sent to auto-update shortly after that). If you need that feature right away, feel free to download the v8.0-RC version. Otherwise, you can wait for the full release or for it to be pushed to the Notepad++ auto-updater.

  • "Dot Notation" Folding

    2
    0 Votes
    2 Posts
    460 Views
    PeterJonesP

    @Daniel-McMahon said in "Dot Notation" Folding:

    How can I get the code to fold (using a custom language) such that collapsing “O” would hide everything below it

    If O were your only start keyword, then you could define your UserDefinedLanguage with Folding-in-Code-2 with START = O and something else (maybe ((A B C D E F G H I J K L M N O P Q R S T U V W X Y Z))) as the close.

    Actually, using the ((A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)) list shown for both open and close comes close, but not quite, because it’s seeing each one as a new nested open, rather than a close for the previous one.

    The User Defined Language feature is great for “simple” languages, where the folding is just pairs of OPEN/CLOSE keywords or symbols (with optional middle for “if-else-endif”-like situations)… but it’s not hard to find yourself straying beyond what it can handle.

    In theory, you could look at the FAQ section of this Forum, and see the FAQ Desk entry on creating official feature requests … but the UDL system hasn’t had much attention (really, not any attention) for a few years, and nothing is likely to come about from such a feature request, unfortunately.

    The first options at this point are creating your own lexer plugin, which would be able to implement the syntax highlighting and code folding according to whatever rules you want to program.

    The second option is that the scripting plugins like PythonScript have access to the underlying Scintilla folding commands – so you might be able to code up a script that will enable the folding you want; I don’t know if there are examples in the forum, but you could search for “pythonscript fold” or some such and see what you find. (My guess in PythonScript is that editor.setFoldLevel(line, level) which implements scintilla SCI_SETFOLDLEVEL message is where you would start, which would define how many levels deep, and which line is the start of each fold block).

  • 0 Votes
    3 Posts
    2k Views
    Vasile CarausV

    @Vasile-Caraus said in Regex: Parsing / Extract the content of a html tag and save it another file?:

    (?s)<title>(.*?)</title>

    ok, so I run this regex: (?s)(<title>)(.*?)(<\/title>) in all files. I copy the results in save.txt file, and I got something like this

    <title>My name is Prince</title> <title>I love cars</title> <title>My book is here</title>

    Now, I must extract the content from tags, and I use the same regex, with replace:

    Find: (?s)(<title>)(.*?)(<\/title>)
    Replace by: \2

    The output

    My name is Prince I love cars My book is here

    thanks. I thought it could be done in one move. :)

  • Stop searching a line after one match

    11
    1 Votes
    11 Posts
    3k Views
    R JR

    @Alan-Kilborn Thanks a lot, this is very useful and I also couldn’t figure it out.

  • reg expressions Multiple search

    8
    0 Votes
    8 Posts
    402 Views
    claudio pergolinC

    @Alan-Kilborn said in reg expressions Multiple search:

    @claudio-pergolin

    Posting in your native language isn’t going to help me understand, it’s just going to make me translate it to English – if I feel like it – when that is something you should do before posting on an English language forum.

    Probably the part that confused me the most was not anything to do with language, it was that you suddenly introduced blah instead of bah into it.

    Anyway, I think probably Peter’s reply cleared up any confusion for you.
    Cheers!

    sorry but with chrome that translates automatically, I forgot to translate it directly into English …sorry!

  • Replacing word between specific characters

    2
    0 Votes
    2 Posts
    253 Views
    PeterJonesP

    @shpock-boss ,

    In a single step? Not easily.

    Basically, what you gave would make a good program, written in your favorite language, which would search for URLs and then do all the logic, written in a way that you could understand and maintain in the future. And this isn’t a programming forum or a codewriting service.

    I was curious, and no one had replied yet, so I ran a few experiments. Using some really complicated regex, I was able to come up with something that worked for up to three directory levels; but every level requires more logic and more nested capture groups.

    So if you never have more than 3 directories (and if you define a directory’s valid characters the same way I do), then this will work:

    FIND = (?-s)(https?://[^\s/]+/)([^\s/]+/)(((?2))?(((?2))?(.*))) REPLACE = (?2${1}XYZ/${3})(?4\r\n${1}${2}XYZ/${5})(?6\r\n${1}${2}${4}XYZ/${7}) SEARCH MODE = regular expression https://developers.apple.com/XYZ/profile/ShadowDES/Boy?view=FUZZ https://developers.apple.com/forums/XYZ/ShadowDES/Boy?view=FUZZ https://developers.apple.com/forums/profile/XYZ/Boy?view=FUZZ

    No, I am not going to explain it in full detail. Basically, it is using capture groups to store various pieces in numbered groups, and using the numbered subexpression control flow to repeat previous conditions later in the match, and nesting groups so that you can reference various layers, For the replacment, it’s using substitution replacements for deciding how many output lines there will be, and what they will look like.

    But I do not recommend this. Using regex you don’t understand is dangerous, and this is something complex enough that you should only use it if you understand it, and are willing to read the document I linked, and backup your data, and keep experimenting with it until you do understand it.

    An alternate way, which is slightly easier to understand, would still use conditionals, but the sequence is less complex (no nesting), so you can make it work for more terms by just copying the last term in the search, and copying the pattern

    Step one of this would be to run a regular expression that would make N copies of the URL, and would add an indicator at the beginning (I chose N ∙ characters) to indicate which level of directory should be replaced on each line.

    Starting with data

    https://developers.apple.com/forums/profile/ShadowDES/Boy?view=FUZZ https://developers.apple.com/one/two/three/four/five/six/seven/end.html

    the end of first step will be

    ∙https://developers.apple.com/forums/profile/ShadowDES/Boy?view=FUZZ ∙∙https://developers.apple.com/forums/profile/ShadowDES/Boy?view=FUZZ ∙∙∙https://developers.apple.com/forums/profile/ShadowDES/Boy?view=FUZZ ∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html ∙∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html ∙∙∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html ∙∙∙∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html ∙∙∙∙∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html ∙∙∙∙∙∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html ∙∙∙∙∙∙∙https://developers.apple.com/one/two/three/four/five/six/seven/end.html

    The regex to do this would be

    FIND = (?x-s)(https?://[^\s/]+/) ([^\s/]+/)? ([^\s/]+/)? ([^\s/]+/)? ([^\s/]+/)? ([^\s/]+/)? ([^\s/]+/)? ([^\s/]+/)? [^\s]* REPLACE = (?{2}∙$0)(?{3}\r\n∙∙$0)(?{4}\r\n∙∙∙$0)(?{5}\r\n∙∙∙∙$0)(?{6}\r\n∙∙∙∙∙$0)(?{7}\r\n∙∙∙∙∙∙$0)(?{8}\r\n∙∙∙∙∙∙∙$0)

    If you need more than seven directories deep, add another ([^\s/]+/)? in the sequence of those in the FIND, and another (?{ℕ}\r\n∙∙∙∙∙∙∙$0) at the end of the REPLACE

    The second and following steps would look for 7 ∙ symbols followed by a URL, then 6, then 5, then … on down, replacing the right piece in each one:

    FIND = (?x-s) ∙{7} (https?://[^\s/]+/) (([^\s/]+/){6}) (?3) (.*$) for each time, the numbers in the curly braces in the FIND would each decrease by 1, so it’s 7 and 6 for the seventh subdir, 6 and 5 for the sixth subdir, and so on down. (I did confirm that {0} will properly match 0 instances of the match, so it even works on the final pair of 1 and 0.) REPLACE = ${1}${2}XYZ/${4}

    After all of those, I had:

    https://developers.apple.com/XYZ/profile/ShadowDES/Boy?view=FUZZ https://developers.apple.com/forums/XYZ/ShadowDES/Boy?view=FUZZ https://developers.apple.com/forums/profile/XYZ/Boy?view=FUZZ https://developers.apple.com/XYZ/two/three/four/five/six/seven/end.html https://developers.apple.com/one/XYZ/three/four/five/six/seven/end.html https://developers.apple.com/one/two/XYZ/four/five/six/seven/end.html https://developers.apple.com/one/two/three/XYZ/five/six/seven/end.html https://developers.apple.com/one/two/three/four/XYZ/six/seven/end.html https://developers.apple.com/one/two/three/four/five/XYZ/seven/end.html https://developers.apple.com/one/two/three/four/five/six/XYZ/end.html

    I give you this solution because it’s easier to extend to work with more subdirectories if you’ve got huge URLs. But it’s still a multistep process. I think this has less room for error than the previous one, but still back up your data and study the resources given, and see if you can understand each piece.

    caveat emptor

    This suggestions given seemed to work for me, based on my understanding of your issue, and is published here to help you learn how to do this. I make no guarantees or warranties as to the functionality for you. You are responsible to save and backup all data before and after running anything contained herein. If you want to use it long term, I recommend investing time in adding error checking and verifying with edge cases, and making sure you understand every piece of any of the suggestions.

  • Default Directory - So Annoying

    2
    1 Votes
    2 Posts
    170 Views
    Alan KilbornA

    @Courtney-Fay

    People get so “uppity” about software they pay zilch for. It can be amazing at times…

    So the dialogs for opening and saving files were changed out recently. This was determined to be such a needed change, that it actually ended Notepad++ support for Windows XP (but that’s a side note), but it brought (mostly) improved functionality.

    Anyway, several unexpected consequences resulted from that swap out, and one of them happens to be the issue you mention.

    Your options: Go to a slight earlier version than 7.9.5 (probably 7.9.2 will do it) or try the new 8.0 release candidate (where the problem you describe should be fixed).

  • Highlight specific part within a word/text

    2
    0 Votes
    2 Posts
    166 Views
    PeterJonesP

    @thomyka ,

    In a UDL, you should be able to make step a keyword, rather than trying to split it into some strange set of operators or delimiter pair.

    But maybe I haven’t understood what you want correctly.

  • CRLF inserts Parenthesis and True, and Comma's on next line

    6
    0 Votes
    6 Posts
    1k Views
    Bryce HartfordB

    @Marcos-Ferreira Hey Marcos, I did not see your reply, but did go through every plugin in, and 1 by 1, uninstalled, restarted NPP and tested. And guess what?! It was indeed “NPPCalc” that was causing the issue. After reading comments on that plugin, I decided I don’t need it anyway. So now I can CR/LF all day long without those annoying characters. Thank you for confirming!
    Bryce

  • add line breaks without breaking word

    5
    0 Votes
    5 Posts
    420 Views
    Abed99A

    PeterJones mention a good way and here is another way using regex:

    search for :(\w+\.?!?\s){2} replace with : $&\r\n search mode : regular expression

    change 2 to the X amount of characters you want
    3.png

  • 0 Votes
    7 Posts
    6k Views
    OzBobO

    @Max-Lovic has provided a nice looking solution.
    How can this be merge into the main notepad++ repo?
    I tried removing all the ‘styles’ from userDefineLang.xml which did not work.

  • Replace a character by using a list of names

    2
    0 Votes
    2 Posts
    163 Views
    Daniel FuchsD

    I am afraid this is not possible with the build-in Replace function.
    You could however install the PythonScript plugin, where you can then script such a replace.

  • End python script execution

    5
    0 Votes
    5 Posts
    740 Views
    claudio pergolinC

    i resolved. thank you

  • Pythonscript :RuntimeError

    5
    0 Votes
    5 Posts
    447 Views
    claudio pergolinC

    thanks for the tip to both of you

  • Npp too many profiles

    3
    0 Votes
    3 Posts
    220 Views
    Michael VincentM

    @Jonathan-MICHELON said in Npp too many profiles:

    But now i’ve got a problem, too many profiles are in the list.

    What version of NppFTP are you using? Both the latest and the latest pre-release both offer grouping of individual profiles:

    4296ed23-1050-4a04-b687-96d583dfe3f8-image.png

    Cheers.

  • Confused by Replace versus Replace-All

    8
    0 Votes
    8 Posts
    495 Views
    AdrianTweeterA

    Thank you Terry and Alan for the detailed answer to my question. I have seldom used the \K and so had not run into the problem before. Your explanations of why the behaviours are different are very interesting.

  • How to find unclosed / hanging tags?

    3
    0 Votes
    3 Posts
    4k Views
    Ramanand JhingadeR

    Thanks @Michael-Vincent
    I used this HTML validator