Community
    • Login

    Colors not shown when open code files

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    4 Posts 3 Posters 5.9k 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.
    • Pablo EviaP
      Pablo Evia
      last edited by

      Hi, I just installed Windows 11 and wanted to install Notepad++ as I use it primarily for code editing (Stata, R, and related). My new Notepad++ installation is not showing colors as were shown before (e.g. with “commenting” I use “*”, which used to turn to green in comparison with other code chunks. How can I restore this old setting? Thanks!

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

        @Pablo-Evia ,

        “Stata” isn’t in the Language menu (and never has been), but “R” is, so Notepad++ doesn’t handle Stata by default.

        For R, if you open a file that has the extension .r or .s or .splus, it will apply syntax highlighting. And my quick search claims that R comments are #: Notepad++ highlights # ... as green with the default styler:
        56a61d09-2cfc-4047-847d-0c49d22d788a-image.png

        As I said, Notepad++ has never made Stata highlighting available. You may have previously used a User Defined Language for Stata.

        While Notepad++ doesn’t make Stata available, the underlying Lexilla lexer which Notepad++ uses does have Stata, at least in Notepad++ versions 8.4 and newer. And we discussed in a recent topic that if you are willing to install and use the PythonScript plugin, you can activate one of the “hidden” lexers – that discussion showed how using SAS, but the procedure for Stata should be the same:

        You would grab the script that I linked in this post in that discussion, follow the instructions in the How to run a script in PythonScript plugin FAQ for instructions on installing and running the script. Then you would have to edit that script to refer to the STATA constants and keywords rather than the SAS list.

        Even better, @Ekopalypse might confirm whether with the addition of NPPM_CREATELEXER in v8.4.3, it might be easier to implement than the script I showed before.

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

          @Pablo-Evia ,

          This script “enable-stata-lexer.py” is an edited version of the script linked earlier, customized for Stata. It probably doesn’t have every keyword (I am not a Stata user, so just hacked together from a few web searches)

          17d53d20-d18d-4c1c-a63f-67722f7a8152-image.png

          The Stata lexer has two keyword lists, so you can only have two individual colors that you specify in the script. It labels them as “words” and as “types”, so I assumed the “words” were meant as keywords, and the “types” as the data types.

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

            @PeterJones

            Yes, with the newly introduced NPPM_CREATELEXER message we can get rid of the function determining definitions.
            So something like this works now.

            # -*- coding: utf-8 -*-
            '''
                Makes the builtin SAS lexer available for NPP.
            
                To toggle the escape characters on/off one can
                create another script with these two lines of code.
            
                sas_lexer.show_escape_chars = not sas_lexer.show_escape_chars
                editor.styleSetVisible(sas_lexer.SCE_ERR_ESCSEQ, sas_lexer.show_escape_chars)
            
            '''
            """
            Peter trying to adapt https://raw.githubusercontent.com/Ekopalypse/NppPythonScripts/master/npp/error_list_lexer_support2.py
            based on Eko's comments https://community.notepad-plus-plus.org/topic/23147/missing-lexers-from-lexilla/7
            """
            
            from Npp import notepad, editor, NOTIFICATION
            from ctypes import windll, WINFUNCTYPE, addressof, create_unicode_buffer
            from ctypes.wintypes import HWND, UINT, WPARAM, LPARAM, HMODULE, LPCWSTR, LPCSTR, LPVOID
            
            
            class SasLexer:
            
                def __init__(self):
                    '''
                        Initialize the class, should be called only once.
                    '''
            
                    # **************** configuration area ****************
                    # files with these extensions and a null lexer,
                    # aka normal text, assigned do get handled
                    self.known_extensions = ['sas']
                    #
                    # ****************************************************
                    self.SCE_SAS_DEFAULT                                        = 0
                    self.SCE_SAS_COMMENT                                        = 1
                    self.SCE_SAS_COMMENTLINE                                    = 2
                    self.SCE_SAS_COMMENTBLOCK                                   = 3
                    self.SCE_SAS_NUMBER                                         = 4
                    self.SCE_SAS_OPERATOR                                       = 5
                    self.SCE_SAS_IDENTIFIER                                     = 6
                    self.SCE_SAS_STRING                                         = 7
                    self.SCE_SAS_TYPE                                           = 8
                    self.SCE_SAS_WORD                                           = 9
                    self.SCE_SAS_GLOBAL_MACRO                                   = 10
                    self.SCE_SAS_MACRO                                          = 11
                    self.SCE_SAS_MACRO_KEYWORD                                  = 12
                    self.SCE_SAS_BLOCK_KEYWORD                                  = 13
                    self.SCE_SAS_MACRO_FUNCTION                                 = 14
                    self.SCE_SAS_STATEMENT                                      = 15
            
                    self.NPPM_CREATELEXER                                       = (1024 + 1000 + 110)
                    self.SCI_SETILEXER                                          = 4033
                    
                    self.user32 = windll.user32
            
                    self.notepad_hwnd = self.user32.FindWindowW(u'Notepad++', None)
                    self.editor1_hwnd = self.user32.FindWindowExW(self.notepad_hwnd, None, u"Scintilla", None)
                    self.editor2_hwnd = self.user32.FindWindowExW(self.notepad_hwnd, self.editor1_hwnd, u"Scintilla", None)
            
                    self.lexer_name = create_unicode_buffer('sas')
            
                    self.user32.SendMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
                    self.user32.SendMessageW.restype = LPARAM
            
                    notepad.callback(self.on_langchanged, [NOTIFICATION.LANGCHANGED])
                    notepad.callback(self.on_bufferactivated, [NOTIFICATION.BUFFERACTIVATED])
            
            
                    console.write("Initialized SAS lexer\n")
            
                def __del__(self):
                    '''
                        Destructor (kind of)
                    '''
                    console.write("Clear SAS lexer callbacks...\n")
                    notepad.clearCallbacks(self.on_langchanged)
                    notepad.clearCallbacks(self.on_bufferactivated)
                    console.write("Destroyed SAS lexer\n")
            
                def init_lexer(self):
                    '''
                        Initializes the lexer and its properties
                        Args:
                            None
                        Returns:
                            None
                    '''
                    editor.styleSetFore(self.SCE_SAS_DEFAULT               , notepad.getEditorDefaultForegroundColor())
                    editor.styleSetFore(self.SCE_SAS_COMMENT               , (0,255,0))
                    editor.styleSetFore(self.SCE_SAS_COMMENTLINE           , (0,255,0))
                    editor.styleSetFore(self.SCE_SAS_COMMENTBLOCK          , (0,255,0))
                    editor.styleSetFore(self.SCE_SAS_NUMBER                , (255,0,0))
                    editor.styleSetFore(self.SCE_SAS_OPERATOR              , (128,64,0))
                    editor.styleSetFore(self.SCE_SAS_IDENTIFIER            , (64,64,64))
                    editor.styleSetFore(self.SCE_SAS_STRING                , (128,128,128))
                    editor.styleSetFore(self.SCE_SAS_TYPE                  , (128,0,255))       # not implemented
                    editor.styleSetFore(self.SCE_SAS_WORD                  , (255,128,0))       # not implemented
                    editor.styleSetFore(self.SCE_SAS_GLOBAL_MACRO          , (255,255,0))       # not implemented
                    editor.styleSetFore(self.SCE_SAS_MACRO                 , (0,0,255))         # start with %
                    editor.styleSetFore(self.SCE_SAS_MACRO_KEYWORD         , (0,255,255))       # keywords/keywords1
                    editor.styleSetFore(self.SCE_SAS_BLOCK_KEYWORD         , (0,0,127))         # keywords2
                    editor.styleSetFore(self.SCE_SAS_MACRO_FUNCTION        , (0,127,127))       # keywords3
                    editor.styleSetFore(self.SCE_SAS_STATEMENT             , (0xAA,0,0))        # keywords4
            
                    # ordering is important
                    ilexer_ptr = self.user32.SendMessageW(self.notepad_hwnd, self.NPPM_CREATELEXER, 0, addressof(self.lexer_name))
                    editor_hwnd = self.editor1_hwnd if notepad.getCurrentView() == 0 else self.editor2_hwnd
                    self.user32.SendMessageW(editor_hwnd, self.SCI_SETILEXER, 0, ilexer_ptr)
                    
                    
                    editor.setKeyWords(0, "%let %do")
                    editor.setKeyWords(1, "also cards class data input model ods proc var where")
                    editor.setKeyWords(2, "%printz")
                    editor.setKeyWords(3, "run")
                    console.write("SAS lexer: set styles\n")
            
                def check_lexers(self):
                    '''
                        Checks if the current document is of interest.
            
                        Args:
                            None
                        Returns:
                            None
                    '''
            
                    has_no_lexer_assigned = editor.getLexerLanguage() == 'null'
                    _, _, file_extension = notepad.getCurrentFilename().rpartition('.')
                    if has_no_lexer_assigned and file_extension in self.known_extensions:
                        self.init_lexer()
                    console.write("check_lexers: {} {}\n".format(editor.getLexerLanguage(), has_no_lexer_assigned))
            
            
                def on_bufferactivated(self, args):
                    '''
                        Callback which gets called every time one switches a document.
                        Triggers the check if the document is of interest.
            
                        Args:
                            provided by notepad object but none are of interest
                        Returns:
                            None
                    '''
                    self.check_lexers()
                    console.write("on_bufferactivated\n")
            
            
                def on_langchanged(self, args):
                    '''
                        Callback gets called every time one uses the Language menu to set a lexer
                        Triggers the check if the document is of interest
            
                        Args:
                            provided by notepad object but none are of interest
                        Returns:
                            None
                    '''
                    self.check_lexers()
                    console.write("on_langchanged\n")
            
            
                def main(self):
                    '''
                        Main function entry point.
                        Simulates the buffer_activated event to enforce
                        detection of current document and potential styling.
            
                        Args:
                            None
                        Returns:
                            None
                    '''
                    self.on_bufferactivated(None)
            
            console.show()
            sas_lexer = SasLexer()
            sas_lexer.main()
            
            
            """ example junk SAS (just lists some of the keywords):
            
            %let
            
            %do
            
            also
            
            cards
            class
            data
            input
            model
            ods
            proc
            var
            where
            
            %printz
            
            run
            
            * ... comment style 1;
            
            run
            
            // ... comment style 2;
            
            run
            
            /* comment style 3 */
            
            5 + 7 = 9
            
            one
            
            blech
            
            
            """
            
            1 Reply Last reply Reply Quote 2
            • First post
              Last post
            The Community of users of the Notepad++ text editor.
            Powered by NodeBB | Contributors