Community
    • Login

    How to change syntax via hotkey ?

    Scheduled Pinned Locked Moved General Discussion
    27 Posts 8 Posters 5.4k 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.
    • BarbadosB
      Barbados
      last edited by

      Hi.

      How to change syntax via hotkey ? Notepad ++ does not support this option ?

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

        @Barbados

        Please CLICK-HERE.

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

          @Barbados said in How to change syntax via hotkey ?:

          How to change syntax via hotkey?

          I’m going to make an assumption that you mean “how do I change the [programming language / lexer / syntax highlighter] via hotkey”. (I’ll call it “Language” from now on, because that’s the name of the menu, in the default English localization).

          short answer

          You don’t, natively.

          helpful answer

          Use a plugin like PythonScript (which you can install via Plugins > Plugins Admin. In PythonScript, you could save one script per Language that you want a hotkey for.

          Each script will contain two lines, similar to below:

          from Npp import *
          notepad.setLangType(LANGTYPE.HTML)
          

          Replace the LANGTYPE.HTML enum with whichever LANGTYPE.value you need.
          For each script, PythonScript Configuration dialog will allow you to add them as menu items, and then (possibly after reload), Notepad++'s Preferences > Shortcut Mapper > Plugin Commands will allow you to assign a keyboard shortcut.

          From then on, the shortcut key should run that script, and that script will change the current document’s Language.

          more on that later

          I was trying to keep my introduction short, to get you to the helpful answer sooner. Really, this isn’t much background information. But for the technically inclined: they apparently didn’t make the Language menu entries macro-recordable; that would have been easier. You might be able to experiment with manually editing the <Macros> in shortcuts.xml to call the menu ID’s for those entries. Once in a working macro, you can use Preferences > Shortcut Mapper > Macros to set a shortcut for it.

          BarbadosB Szymon SzymonS 2 Replies Last reply Reply Quote 5
          • BarbadosB
            Barbados @PeterJones
            last edited by

            @Alan-Kilborn said in How to change syntax via hotkey ?:

            Please CLICK-HERE.

            OK. I will do it next time ;)

            @PeterJones said in How to change syntax via hotkey ?:

            I’m going to make an assumption that you mean “how do I change the [programming language / lexer / syntax highlighter] via hotkey”. (I’ll call it “Language” from now on, because that’s the name of the menu, in the default English localization).

            Yes, you are right :)

            @PeterJones said in How to change syntax via hotkey ?:

            Use a plugin like PythonScript (which you can install via Plugins > Plugins Admin. In PythonScript, you could save one script per Language that you want a hotkey for.

            Thank you, this solution worked )))

            @PeterJones said in How to change syntax via hotkey ?:

            But for the technically inclined: they apparently didn’t make the Language menu entries macro-recordable; that would have been easier.

            Yes, I tried to write a macro switching the language, but that didn’t work.

            @PeterJones said in How to change syntax via hotkey ?:

            You might be able to experiment with manually editing the <Macros> in shortcuts.xml to call the menu ID’s for those entries. Once in a working macro, you can use Preferences > Shortcut Mapper > Macros to set a shortcut for it.

            Maybe I will try this solution later, now this solution is too complicated for me :(

            1 Reply Last reply Reply Quote 1
            • PeterJonesP
              PeterJones
              last edited by

              @Barbados said in How to change syntax via hotkey ?:

              …PythonScript…
              this solution worked )))

              Glad it worked for you.

              now this solution is too complicated for me

              Maybe I can help make it less complicated. For you, or any future readers, to be able to have Macros for switch-to-HTML and switch-to-XML, here is the process:

              1. Close all instances of Notepad++

              2. Open a single instance of Notepad++

              3. File > Open %AppData%\Notepad++\shortcuts.xml

                • (this assumes standard installation; with portable installation, you will need to open shortcuts.xml from the same folder that contains notepad++.exe)
              4. Just before the line that says </Macros>, insert:

                 <Macro name="Switch Language to HTML" Ctrl="no" Alt="no" Shift="no" Key="0">
                     <Action type="2" message="0" wParam="46005" lParam="0" sParam="" />
                 </Macro>
                 <Macro name="Switch Language to XML" Ctrl="no" Alt="no" Shift="no" Key="0">
                     <Action type="2" message="0" wParam="46006" lParam="0" sParam="" />
                 </Macro>
                
              5. Save. Exit Notepad++. Reload Notepad++

              6. Now your Macros menu should contain two entries: Switch Language to HTML and Switch Language to XML

                • if you don’t like those names, use a different name="..." in step #4
              7. You can use the Preferences > Shortcut Mapper > Macros dialog to assign keyboard shortcuts to those.

              For other languages: The IDM_LANG_... list shows values of (IDM_LANG + ##); the constant IDM_LANG evaluates to 46000, so each of the language menuCmdID values are in the range 46001 - 46083 (for now). So if you wanted one with Language PHP instead, you would look up and see the constant IDM_LANG_PHP (IDM_LANG + 8), so it would be 46000+8=46008. You would then use that as the wParam="46008" in the macro line, with an appropriate name="..." as well.

              Again, glad the PythonScript solution worked for you.

              BarbadosB László BeneL 2 Replies Last reply Reply Quote 4
              • webketjeW
                webketje
                last edited by webketje

                It’s not a hotkey, but Notepad++ does have access keys for its top-level menus.
                To open the language menu, type Alt+L, then change the language with arrow keys.

                (btw hitting Alt will underline all access keys for top menu items)

                1 Reply Last reply Reply Quote 3
                • guy038G
                  guy038
                  last edited by guy038

                  Hi, @barbados, @alan-kilborn, @peterjones, @webketje, and All,

                  I’ve just tested your two macros, Alan, and I confirm that they correctly switch current file to the HTML and XML language ;-)) Also, Peter, your fears seem unfounded : switching languages, via macros, is possible ! It works perfectly, at least, with my portable version 7.8.3. :-))

                  Of course, I did not try all values of the wParam attribute to verify if the switch to the corresponding language was effective, but I’m rather confident regarding this assumption !

                  Best Regards,

                  guy038

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

                    @guy038 said in How to change syntax via hotkey ?:

                    I’ve just tested your two macros, Alan,

                    Please give credit where it’s due; they were not mine. :-)

                    1 Reply Last reply Reply Quote 0
                    • guy038G
                      guy038
                      last edited by guy038

                      Hi, @barbados, @alan-kilborn, @peterjones, @webketje, and All,

                      Oh ! I’m terribly sorry ! I didn’t verify and I assumed you were the poster Alan… But, indeed ,it’s from Peter ! So , my post was completely useless ;-))

                      BR

                      guy038

                      1 Reply Last reply Reply Quote 1
                      • BarbadosB
                        Barbados @PeterJones
                        last edited by

                        @PeterJones said in How to change syntax via hotkey ?:

                        Maybe I can help make it less complicated. For you, or any future readers, to be able to have Macros for switch-to-HTML and switch-to-XML, here is the process:

                        Thank you, this solution is much simpler :)

                        @PeterJones said in How to change syntax via hotkey ?:

                        Again, glad the PythonScript solution worked for you.
                        Is it possible to “tweak” the script and add disabling syntax when I press the hotkey again ?

                        P.S.

                        Is it possible to create a similar python script to change the page encodin ? And the macro ?

                        EkopalypseE 1 Reply Last reply Reply Quote 2
                        • EkopalypseE
                          Ekopalypse @Barbados
                          last edited by

                          @Barbados

                          Is it possible to create a similar python script to change the page encodin ?

                          Yes

                          from Npp import notepad, BUFFERENCODING, MENUCOMMAND
                          
                          # notepad.menuCommand(MENUCOMMAND.FORMAT_ANSI)
                          notepad.menuCommand(MENUCOMMAND.FORMAT_AS_UTF_8)
                          

                          if you execute the following in the python script console you will see
                          the possible values.

                          print('\n'.join([x for x in dir(MENUCOMMAND) if x.startswith('FORMAT_')]))
                          

                          And the macro ?

                          I don’t understand this. Do you mean create a macro with pythonscript?

                          BarbadosB 1 Reply Last reply Reply Quote 3
                          • PeterJonesP
                            PeterJones
                            last edited by PeterJones

                            @Barbados said in How to change syntax via hotkey ?:

                            And the macro ?

                            @Ekopalypse showed the PythonScript version.

                            The macros to do the same look identical to the macros I showed above, but should be given unique names (of course) and use different values for the wParam. In this case, the wParam values are found in the IDM_FORMAT section of menuCmdID.h, starting at value 45000. So IDM_FORMAT_ANSI would be wParam="45004" and IDM_FORMAT_AS_UTF_8 would be wParam="45008".

                            If you are interested in delving deeper in manually creating macros: The menuCmdID.h file contains the IDs for most of the Notepad++ menus (there are a few that are auto-generated and don’t have fixed menuCmdID values). The official docs include a section on the details of the <Macros> in shortcuts.xml.

                            1 Reply Last reply Reply Quote 3
                            • BarbadosB
                              Barbados @Ekopalypse
                              last edited by

                              @Ekopalypse said in How to change syntax via hotkey ?:

                              @Barbados

                              Is it possible to create a similar python script to change the page encodin ?

                              Yes

                              Thanks, it works.

                              Is it possible to add a switch in the language switching script to default (User-defined) language when I press the hotkey again ? And loop it ? An encoding switch script needs an “ANSI” switch (default)

                              @PeterJones said in How to change syntax via hotkey ?:

                              The macros to do the same look identical to the macros I showed above, but should be given unique names (of course) and use different values for the wParam. In this case, the wParam values are found in the IDM_FORMAT section of menuCmdID.h, starting at value 45000. So IDM_FORMAT_ANSI would be wParam="45004" and IDM_FORMAT_AS_UTF_8 would be wParam="45008".

                              Thank you very much, you really helped in solving this problem :)

                              @PeterJones said in How to change syntax via hotkey ?:

                              If you are interested in delving deeper in manually creating macros: The menuCmdID.h file contains the IDs for most of the Notepad++ menus (there are a few that are auto-generated and don’t have fixed menuCmdID values). The official docs include a section on the details of the <Macros> in shortcuts.xml.

                              I will try to work on this issue in the future ;)

                              P.S. Is it possible to make a “User-defined” switch in the language macro and an “ANSI” switch in the encoding switching script?

                              EkopalypseE 1 Reply Last reply Reply Quote 0
                              • PeterJonesP
                                PeterJones
                                last edited by PeterJones

                                @Barbados said in How to change syntax via hotkey ?:

                                Is it possible to add a switch in the language switching script to default (User-defined) language when I press the hotkey again ? And loop it ? An encoding switch script needs an “ANSI” switch (default)

                                If you want one script that will set it to HTML if it’s set to XML, and to XML if it’s not set to XML (ie, toggle between the two), it’s a simple if statement:

                                from Npp import * 
                                if notepad.getLangType() == LANGTYPE.XML:
                                    notepad.setLangType(LANGTYPE.HTML)
                                else:
                                    notepad.setLangType(LANGTYPE.XML)
                                

                                If your alternate language is a UDL (user-defined language), then I’m not sure. There is a LANGTYPE.USER – unfortunately, it selects the generic UDL “User-Defined”, rather than whichever of the various UDL is appropriate for the filename. I don’t know that there’s a way to get it to reload the correct UDL for the filetype. (It might be possible with some clever programming… but I am not sure where I’d start.)

                                For UTF8-vs-ANSI toggle, there should be a way, using the notepad.getEncoding()/.setEncoding() pair… unfortunately, notepad.getEncoding() seems to always be returning BUFFERENCODING.COOKIE, which isn’t helpful. With the .getEncoding() not returning anything useful, I cannot get a smart encoding toggle. I am assuming that’s why @Ekopalypse 's example originally included the BUFFERENCODING in the import, but didn’t actually use it. :-)

                                For a dumb encoding toggle, which will set it to UTF8 the first time you call it and ANSI the second (regardless of current state), you could use:

                                from Npp import notepad, MENUCOMMAND
                                
                                try:
                                    toggle = 1 - toggle
                                except NameError:
                                    toggle = 0
                                
                                notepad.menuCommand( (MENUCOMMAND.FORMAT_AS_UTF_8, MENUCOMMAND.FORMAT_ANSI)[toggle] )
                                

                                The toggle variable will go between 0 and 1 every call, and the menuCommand will choose between the tuple of encoding MENUCOMMAND enums, depending on the current value of toggle. (The try/except was a way to determine whether toggle had ever been initialized yet or not.)

                                You could do a similar “dumb toggle” for the LANGTYPE, too.

                                P.S. Is it possible to make a “User-defined” switch in the language macro and an “ANSI” switch in the encoding switching script?

                                If you wanted the same toggle-between-two-states using macros: sorry. The macro doesn’t have any if/else or global variables that can hold the current state of a toggle, so you cannot do the toggle; you’d have to just use two different macros, and thus two different keystrokes.

                                1 Reply Last reply Reply Quote 1
                                • EkopalypseE
                                  Ekopalypse @Barbados
                                  last edited by

                                  @Barbados
                                  not sure I understand 100% correctly but here the two scripts

                                  from Npp import notepad, editor
                                  
                                  
                                  if editor.getCodePage() == 0:
                                      notepad.menuCommand(MENUCOMMAND.FORMAT_AS_UTF_8)
                                  else:
                                      notepad.menuCommand(MENUCOMMAND.FORMAT_ANSI)
                                  

                                  and the language script

                                  from Npp import notepad, LANGTYPE
                                  import ctypes
                                  
                                  NAME_OF_UDL = 'DEFAULT' # <<- needs to be specified
                                  
                                  user32 = ctypes.windll.user32
                                  NPPM_GETLANGUAGEDESC = 1024+1000+84
                                  
                                  language = notepad.getLangType()
                                  npp_hwnd = user32.FindWindowW(u'Notepad++', None)
                                  length = user32.SendMessageW(npp_hwnd, NPPM_GETLANGUAGEDESC, language, None)
                                  buffer = ctypes.create_unicode_buffer(u' ' * length)
                                  user32.SendMessageW(npp_hwnd, NPPM_GETLANGUAGEDESC, language, ctypes.byref(buffer))
                                  
                                  if buffer.value == 'User Defined language file - %s' % NAME_OF_UDL:
                                      notepad.setLangType(LANGTYPE.HTML)
                                  else:
                                      notepad.runMenuCommand('Language', NAME_OF_UDL)
                                  

                                  Replace my DEFAULT name with your udl name exactly how it
                                  looks like from the language menu.

                                  @PeterJones, yes, it seems notepad.getEncoding isn’t correct always, strange.

                                  1 Reply Last reply Reply Quote 1
                                  • PeterJonesP
                                    PeterJones
                                    last edited by

                                    @Ekopalypse said in How to change syntax via hotkey ?:

                                    runMenuCommand()...

                                    Oh, right, I should have thought of that.

                                    I see you use SendMessageW for the language description here. Do notepad.getLanguageName() and notepad.getLanguageDesc() still have the bugs mentioned in your 2019 workaround code? Has anyone reported the bug to the PythonScript team – I cannot see a report – or has anyone proven whether it’s the plugin or Notepad++ that is mishandling those? (I have those two equivalent functions “working” in my Perl library… but I don’t know whether it’s just because I haven’t hit the edge cases that cause the problem, or whether the PythonScript implementation is buggy.)

                                    EkopalypseE PeterJonesP 2 Replies Last reply Reply Quote 1
                                    • EkopalypseE
                                      Ekopalypse @PeterJones
                                      last edited by

                                      @PeterJones

                                      it seems that it still is an issue, let me do some test to see if I can find out when and where it happens.

                                      If I run the code from below with PS it crashes my npp

                                      from Npp import notepad, LANGTYPE
                                      
                                      LANGUAGES = LANGTYPE.values.values()
                                      for language in LANGUAGES:
                                          print(notepad.getLanguageDesc(language))
                                      
                                      1 Reply Last reply Reply Quote 0
                                      • PeterJonesP
                                        PeterJones
                                        last edited by

                                        Using @Michael-Vincent’s NppConsole/plsh wrapper around my perl library,

                                        @language_keys = sort { $nppm{$a} <=> $nppm{$b} } grep { /^L_/ } keys %nppm;
                                        printf "%s => %s: '%s'\n", $_, $nppm{$_}, notepad->getLanguageDesc($nppm{$_}) for (@language_keys);
                                        

                                        gives

                                        L_TEXT => 0: 'Normal text file'
                                        L_PHP  => 1: 'PHP Hypertext Preprocessor file'
                                        L_C => 2: 'C source file'
                                        L_CPP => 3: 'C++ source file'
                                        L_CS => 4: 'C# source file'
                                        L_OBJC => 5: 'Objective-C source file'
                                        L_JAVA => 6: 'Java source file'
                                        L_RC => 7: 'Windows Resource file'
                                        L_HTML => 8: 'Hyper Text Markup Language file'
                                        L_XML => 9: 'eXtensible Markup Language file'
                                        L_MAKEFILE => 10: 'Makefile'
                                        L_PASCAL => 11: 'Pascal source file'
                                        L_BATCH => 12: 'Batch file'
                                        L_INI => 13: 'MS ini file'
                                        L_ASCII => 14: 'MSDOS Style/ASCII Art'
                                        L_USER => 15: 'User Defined language file'
                                        L_ASP => 16: 'Active Server Pages script file'
                                        L_SQL => 17: 'Structured Query Language file'
                                        L_VB => 18: 'Visual Basic file'
                                        L_JS => 19: 'JavaScript file'
                                        L_CSS => 20: 'Cascade Style Sheets File'
                                        L_PERL => 21: 'Perl source file'
                                        L_PYTHON => 22: 'Python file'
                                        L_LUA => 23: 'Lua source File'
                                        L_TEX => 24: 'TeX file'
                                        L_FORTRAN => 25: 'Fortran free form source file'
                                        L_BASH => 26: 'Unix script file'
                                        L_FLASH => 27: 'Flash ActionScript file'
                                        L_NSIS => 28: 'Nullsoft Scriptable Install System script file'
                                        L_TCL => 29: 'Tool Command Language file'
                                        L_LISP => 30: 'List Processing language file'
                                        L_SCHEME => 31: 'Scheme file'
                                        L_ASM => 32: 'Assembly language source file'
                                        L_DIFF => 33: 'Diff file'
                                        L_PROPS => 34: 'Properties file'
                                        L_PS => 35: 'PostScript file'
                                        L_RUBY => 36: 'Ruby file'
                                        L_SMALLTALK => 37: 'Smalltalk file'
                                        L_VHDL => 38: 'VHSIC Hardware Description Language file'
                                        L_KIX => 39: 'KiXtart file'
                                        L_AU3 => 40: 'AutoIt'
                                        L_CAML => 41: 'Categorical Abstract Machine Language'
                                        L_ADA => 42: 'Ada file'
                                        L_VERILOG => 43: 'Verilog file'
                                        L_MATLAB => 44: 'MATrix LABoratory'
                                        L_HASKELL => 45: 'Haskell'
                                        L_INNO => 46: 'Inno Setup script'
                                        L_SEARCHRESULT => 47: 'Internal Search'
                                        L_CMAKE => 48: 'CMake file'
                                        L_YAML => 49: 'YAML Ain't Markup Language'
                                        L_COBOL => 50: 'COmmon Business Oriented Language'
                                        L_GUI4CLI => 51: 'Gui4Cli file'
                                        L_D => 52: 'D programming language'
                                        L_POWERSHELL => 53: 'Windows PowerShell'
                                        L_R => 54: 'R programming language'
                                        L_JSP => 55: 'JavaServer Pages script file'
                                        L_COFFEESCRIPT => 56: 'CoffeeScript file'
                                        L_JSON => 57: 'JSON file'
                                        L_JAVASCRIPT => 58: 'JavaScript file'
                                        L_FORTRAN_77 => 59: 'Fortran fixed form source file'
                                        L_BAANC => 60: 'BaanC File'
                                        L_SREC => 61: 'Motorola S-Record binary data'
                                        L_IHEX => 62: 'Intel HEX binary data'
                                        L_TEHEX => 63: 'Tektronix extended HEX binary data'
                                        L_SWIFT => 64: 'Swift file'
                                        L_ASN1 => 65: 'Abstract Syntax Notation One file'
                                        L_AVS => 66: 'AviSynth scripts files'
                                        L_BLITZBASIC => 67: 'BlitzBasic file'
                                        L_PUREBASIC => 68: 'PureBasic file'
                                        L_FREEBASIC => 69: 'FreeBasic file'
                                        L_CSOUND => 70: 'Csound file'
                                        L_ERLANG => 71: 'Erlang file'
                                        L_ESCRIPT => 72: 'ESCRIPT file'
                                        L_FORTH => 73: 'Forth file'
                                        L_LATEX => 74: 'LaTeX file'
                                        L_MMIXAL => 75: 'MMIXAL file'
                                        L_NIMROD => 76: 'Nimrod file'
                                        L_NNCRONTAB => 77: 'extended crontab file'
                                        L_OSCRIPT => 78: 'OScript source file'
                                        L_REBOL => 79: 'REBOL file'
                                        L_REGISTRY => 80: 'registry file'
                                        L_RUST => 81: 'Rust file'
                                        L_SPICE => 82: 'spice file'
                                        L_TXT2TAGS => 83: 'txt2tags file'
                                        L_VISUALPROLOG => 84: 'Visual Prolog file'
                                        L_EXTERNAL => 85: 'External'
                                        

                                        without crashing.
                                        I think there must be a bug in the PythonScript implementation.

                                        PeterJonesP 1 Reply Last reply Reply Quote 2
                                        • PeterJonesP
                                          PeterJones @PeterJones
                                          last edited by PeterJones

                                          … working on bug report now…

                                          https://github.com/bruderstein/PythonScript/issues/146

                                          EkopalypseE 1 Reply Last reply Reply Quote 1
                                          • EkopalypseE
                                            Ekopalypse @PeterJones
                                            last edited by Ekopalypse

                                            @PeterJones

                                            it seems that this doesn’t create a null-terminated buffer

                                            and if I use some python code like

                                                length = self.__npp_send(NPPM_GETLANGUAGEDESC, langType, 0)
                                                lang_desc = ctypes.create_unicode_buffer(length)
                                                self.__npp_send(NPPM_GETLANGUAGEDESC, langType, ctypes.byref(lang_desc))
                                            

                                            I do get the same behavior aka the crash but if I do, what I expect that needs to be done

                                                length = self.__npp_send(NPPM_GETLANGUAGEDESC, langType, 0)
                                                lang_desc = ctypes.create_unicode_buffer(length+1)
                                                self.__npp_send(NPPM_GETLANGUAGEDESC, langType, ctypes.byref(lang_desc))
                                            

                                            then it works.

                                            If one is confused about the previous example with create_unicode_buffer,
                                            please note that create_unicode_buffer allocates the buffer differently
                                            depending on the initialization with Int or String.

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