Community
    • Login

    Special characters with unmapped "shortcut" combos

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    11 Posts 4 Posters 1.5k 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.
    • Michael VincentM
      Michael Vincent
      last edited by Michael Vincent

      Take a fresh portable Notepad++ 8.6 64-bit (older is fine, this is not a new behavior) and open it.

      View => Show Symbol => Show All Characters

      Now type SHIFT+CTRL+A and you should get a SOH “icon”:

      a283bf3d-c333-4392-a028-d588c79fee51-image.png

      I pressed the key-combo 3 times.

      If you now alias the SHIFT+CTRL+A to a shortcut:

      Settings => Shortcut Mapper…

      ba37f279-4981-4fc9-9a98-c0fd18b59af2-image.png

      anything at all, it really doesn’t matter … subsequent SHIFT+CTRL+A will no longer insert the SOH character but will perform the shortcut (as expected).

      The question is - can we prevent non-assigned shortcut-like key combos (e.g., SHIFT+CTRL+A) from inserting invisible special characters if they are not mapped to a shortcut? Sometimes I find myself fat-fingering a shortcut combo I have mapped and accidentally type one that is not mapped and I get these special characters inserted which causes all types of problems with certain languages and validators.

      Cheers.

      Alan KilbornA Michael VincentM 2 Replies Last reply Reply Quote 2
      • Alan KilbornA
        Alan Kilborn @Michael Vincent
        last edited by Alan Kilborn

        @Michael-Vincent

        can we prevent non-assigned shortcut-like key combos (e.g., SHIFT+CTRL+A) from inserting invisible special characters if they are not mapped to a shortcut?

        Yes, it is possible.

        Some versions of such a PythonScript have been posted before, but those versions use a callback for when the document is modified, to check for and remove such control characters. This is okay, but I believe the character goes into the undo buffer, so if you undo a change(s), you could get the character back at some point.

        The following script is a bit lower level and avoids that possible problem. I call the script ControlCharsPreventBeingEnteredInText.py and here is its listing:

        # -*- coding: utf-8 -*-
        from __future__ import print_function
        
        #-------------------------------------------------------------------------------
        
        # references:
        #  https://community.notepad-plus-plus.org/topic/25179/special-characters-with-unmapped-shortcut-combos    <-- contains the script below
        #  https://community.notepad-plus-plus.org/topic/18921/ctrl-e-and-ctrl-shift-alt-not-working
        #  possibly the script here: https://community.notepad-plus-plus.org/topic/20471 (see Dec 14, 2020, 4:38 PM posting)
        #  https://community.notepad-plus-plus.org/topic/23734
        #  https://github.com/notepad-plus-plus/notepad-plus-plus/issues/13279
        
        #-------------------------------------------------------------------------------
        
        from Npp import *
        import ctypes
        from ctypes import wintypes
        import platform
        
        #-------------------------------------------------------------------------------
        
        user32 = ctypes.WinDLL('user32')
        
        try:
            editor1.hwnd
            editor2.hwnd
        except AttributeError:
            notepad.hwnd = user32.FindWindowW(u'Notepad++', None)
            editor1.hwnd = user32.FindWindowExW(notepad.hwnd, None, u'Scintilla', None)
            editor2.hwnd = user32.FindWindowExW(notepad.hwnd, editor1.hwnd, u'Scintilla', None)
        
        LRESULT = wintypes.LPARAM
        
        WndProcType = ctypes.WINFUNCTYPE(
            LRESULT,  # return type
            wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM  # arguments
            )
        
        running_32bit = platform.architecture()[0] == '32bit'
        
        SetWindowLong = user32.SetWindowLongW if running_32bit else user32.SetWindowLongPtrW
        SetWindowLong.restype = WndProcType
        SetWindowLong.argtypes = [wintypes.HWND, wintypes.INT, WndProcType]
        
        GWL_WNDPROC = -4
        
        WM_CHAR = 0x102
        
        #-------------------------------------------------------------------------------
        
        class CCPBEIT(object):
        
            def __init__(self):
        
                self.new_editor1_wnd_proc_hook_for_SetWindowLong = WndProcType(self.new_editor1_wnd_proc_hook)
                self.orig_editor1_wnd_proc = SetWindowLong(editor1.hwnd, GWL_WNDPROC, self.new_editor1_wnd_proc_hook_for_SetWindowLong)
        
                self.new_editor2_wnd_proc_hook_for_SetWindowLong = WndProcType(self.new_editor2_wnd_proc_hook)
                self.orig_editor2_wnd_proc = SetWindowLong(editor2.hwnd, GWL_WNDPROC, self.new_editor2_wnd_proc_hook_for_SetWindowLong)
        
            def common_editor_wnd_proc_hook(self, hwnd, msg, wParam, lParam):
                retval = True
                if msg == WM_CHAR:
                    if 0 <= wParam <= 31 or wParam >= 0x7F:
                        retval = False  # set to False if we don't want further processing of this message
                return retval
        
            def new_editor1_wnd_proc_hook(self, hwnd, msg, wParam, lParam):
                retval = self.common_editor_wnd_proc_hook(hwnd, msg, wParam, lParam)
                if retval: retval = self.orig_editor1_wnd_proc(hwnd, msg, wParam, lParam)
                return retval
        
            def new_editor2_wnd_proc_hook(self, hwnd, msg, wParam, lParam):
                retval = self.common_editor_wnd_proc_hook(hwnd, msg, wParam, lParam)
                if retval: retval = self.orig_editor2_wnd_proc(hwnd, msg, wParam, lParam)
                return retval
        
        #-------------------------------------------------------------------------------
        
        CCPBEIT()
        

        The script should work under PythonScript2 or PythonScript3, and on 32-bit or 64-bit.

        To set up the script to run upon Notepad++ startup, modify (user) startup.py to contain the following line:

        import ControlCharsPreventBeingEnteredInText

        and set PythonScript’s Configuration for Initialisation to be ATSTARTUP.

        kuzduk = kuzdukK 2 Replies Last reply Reply Quote 4
        • Michael VincentM
          Michael Vincent @Michael Vincent
          last edited by

          @Michael-Vincent

          Should have done Google searching instead of on the forum - my forum search-fu is not quite up to par apparently:

          https://community.notepad-plus-plus.org/topic/11233/disable-ascii-control-characters-shortcuts

          I already have lots of CTRL+SHIFT+ keys mapped, the ones I don’t have mapped are:

          • 6
          • B
          • H
          • I

          So in my PythonScript startup, I just added:

          SCI_NULL = 2172
          keys = ['6', 'B', 'H', 'I']
          editor.assignCmdKey(7 + (KEYMOD.SHIFT<<16), SCI_NULL) # Shift+ESC (weird that it's 7 and not 27)
          for key in keys:
              editor.assignCmdKey(ord(key) + ((KEYMOD.CTRL|KEYMOD.SHIFT)<<16), SCI_NULL)
          

          Cheers.

          1 Reply Last reply Reply Quote 2
          • mkupperM mkupper referenced this topic on
          • Alan KilbornA Alan Kilborn referenced this topic on
          • kuzduk = kuzdukK
            kuzduk = kuzduk @Alan Kilborn
            last edited by

            @Alan-Kilborn it is work! Thank u very much!!!

            i dont understand why Don Ho do not off by default this Special characters with unmapped “shortcut”…

            Alan KilbornA PeterJonesP 2 Replies Last reply Reply Quote 0
            • Alan KilbornA
              Alan Kilborn @kuzduk = kuzduk
              last edited by

              @kuzduk-kuzduk said in Special characters with unmapped "shortcut" combos:

              i dont understand why Don Ho do not off by default this Special characters with unmapped “shortcut”…

              When a new feature is added, existing behavior is maintained for the default for the new feature setting.

              So… in this case, before the ability to control it was added, control characters would be typable. With the setting in its default state, typable control characters are maintained.
              It is only if you set the setting to the non-default state that there is a behavior change.

              1 Reply Last reply Reply Quote 0
              • PeterJonesP
                PeterJones @kuzduk = kuzduk
                last edited by

                @kuzduk-kuzduk said in Special characters with unmapped "shortcut" combos:

                i dont understand why Don Ho do not off by default this Special characters with unmapped “shortcut”…

                For clarification: this used to be a problem, like in November 2023 when this Topic was active. But Don Ho released v8.6.5 at the end of March, and that new version contains a fix for this issue, thanks to the work that @Alan-Kilborn put into implementing the fix. So this was fixed before @kuzduk-kuzduk made this post, though you might not have noticed that in the change list for the recent release.

                So now, in v8.6.5, there is a new setting Prevent control character (C0 code) typing into document:
                07efb140-beb1-4cad-a270-36e9023d7527-image.png
                If you leave it in the default, it will have the old behavior (can type the control codes for unmapped shortcuts); if you checkmark the option, then it will have the desired behavior which was previously obtained through the PythonScript code shared above. You no longer need to run one of those PythonScript scripts if you use the newest version of Notepad++ with the option enabled.

                kuzduk = kuzdukK 1 Reply Last reply Reply Quote 5
                • kuzduk = kuzdukK
                  kuzduk = kuzduk @PeterJones
                  last edited by

                  @PeterJones Thanks, but this doesn’t work for me because I’m using npp 8.5.8

                  I can’t use 8.6 and higher because they don’t work correctly with the PauseBreak global hotkey: https://community.notepad-plus-plus.org/topic/25582/global- hotkey-pausebreak-not-correct-in-npp-8-6-via-puntoswitcher/3?_=1712842017033

                  Alan KilbornA PeterJonesP 2 Replies Last reply Reply Quote 0
                  • kuzduk = kuzdukK
                    kuzduk = kuzduk @Alan Kilborn
                    last edited by

                    @Alan-Kilborn @Alan-Kilborn so sad, but it not work in russian layout: russian keys А…Я not typed symbols in npp 8.5.8. May be this script can be modidfied for given this drawback?

                    Alan KilbornA 1 Reply Last reply Reply Quote 0
                    • Alan KilbornA
                      Alan Kilborn @kuzduk = kuzduk
                      last edited by Alan Kilborn

                      @kuzduk-kuzduk said in Special characters with unmapped "shortcut" combos:

                      Thanks, but this doesn’t work for me because I’m using npp 8.5.8

                      You have to pick your poison on this: Either use a version that supports the Prevent control character… checkbox, or don’t (and thus you don’t get the functionality).

                      1 Reply Last reply Reply Quote 0
                      • Alan KilbornA
                        Alan Kilborn @kuzduk = kuzduk
                        last edited by

                        @kuzduk-kuzduk said in Special characters with unmapped "shortcut" combos:

                        so sad, but it not work in russian layout: russian keys А…Я not typed symbols in npp 8.5.8.

                        I don’t know what this means, exactly, since I don’t have familiarity with Russian keyboard and their characters that might be different from a US keyboard.

                        May be this script can be modified for given this drawback?

                        Perhaps, but that modification would have to be made by you.

                        1 Reply Last reply Reply Quote 0
                        • PeterJonesP
                          PeterJones @kuzduk = kuzduk
                          last edited by PeterJones

                          @kuzduk-kuzduk,

                          You earlier said,

                          i dont understand why Don Ho do not off by default this Special characters with unmapped “shortcut”…

                          And now you say

                          Thanks, but this doesn’t work for me because I’m using npp 8.5.8

                          I am sorry.

                          Some applications use a model where they are able to release patch fixes to old releases of software; Notepad++ does not work that way. If there are bug fixes, they go in the next revision. So, to be able to get a fix, you have to be willing to update to a new version.

                          (Yes, I said “willing” , not “able”, because despite your assertion, your choice to not upgrade Notepad++ instead of choosing to remap the weird PauseBreak global shortcut to something other than PauseBreak is just that… your choice. And it’s your choice to prioritize keeping PauseBreak over keeping )

                          so sad, but [Alan’s script does] not work in russian layout

                          As an alternative, figure out all the Ctrl sequences that type ASCII control characters based on your setup. Then create a NULL macro for each of those. A “NULL macro” is a “do nothing” macro. The scintilla action 2172 is a do-nothing/no-op/null-op action. So, you could insert a macro like the following into shortcuts.xml, then save and restart:

                          <Macro name="NULL-CTRL-R" Ctrl="yes" Alt="no" Shift="no" Key="82" FolderName="Control Remaps">
                              <Action type="0" message="2172" wParam="0" lParam="0" sParam="" />
                          </Macro>
                          

                          This mapped macro it would stop Ctrl+R from inserting the DC2 ASCII 18 control character, and instead run a no-op command, making it “do nothing”.

                          Creating multiple such macros, one for each unmapped sequence, would get rid of the accidental ASCII control characters in your documents. (And I showed putting it in FolderName="Control Remaps", so they would all show up in a sub-menu of Macros instead of cluttering your main Macros menu)

                          -----

                          update: earlier in this discussion, @Michael-Vincent linked to this old discussion. It turns out, my suggestion is essentially what Claudia suggested 8 years ago (good to know that her excellent answers have apparently become part of my subconscious mind), though she chose message 0 instead of 2172. And in this February’s replies to that ancient thread, @mkupper showed a mapping with lots of macros that show how to do the “one macro for each unmapped sequence” that I just suggested today. (Though I would again recommend changing to 2172, and I’d add the FolderName attribute to de-clutter the Macro menu.) And @Alan-Kilborn already made the 2172 correction in that other discussion. So basically, it turns out I said nothing new anywhere in the second half of this post of mine. ;-)

                          1 Reply Last reply Reply Quote 4
                          • First post
                            Last post
                          The Community of users of the Notepad++ text editor.
                          Powered by NodeBB | Contributors