Community
    • Login

    UDL highlight hex numbers

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    hexudl
    5 Posts 2 Posters 1.7k 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.
    • Unc3nZureDU
      Unc3nZureD
      last edited by

      In my language every single number is by default treated as hexadecimal, no prefix or suffix needed. num,bers can be strictly LOWERCASE numbers, everything else is treated as variable. I’d like to detect and highlight these numbers. When it comes to operators, no space is necessary, so making: D=e a totally valid state. Hexadecimal numbers can have question mark (as wildcard) as part of them, so actually I can treat them as a valid hex character (it would be even better and amazing to handle differently, so I could use different color for wildcards).

      I’ve tried every combination I could using the UDL GUI, but I couldn’t find a well-working version which works in every case.

      Do you have any good idea how could I achieve this highlighting? Or is it impossible to do with UDL?

      Thanks a lot!

      Eko palypseE 1 Reply Last reply Reply Quote 1
      • Eko palypseE
        Eko palypse @Unc3nZureD
        last edited by

        @Unc3nZureD

        It sounds like one of those areas which aren’t possible to solve by UDL but I have to admit that
        I didn’t fully understand how your language works.

        A.) Do you mind sharing some examples of how it is and should look like?
        B.) I have something in mind which would involve pythonscript plugin.Would you be interested in?
        If yes, I would need, again, some example data for testing.

        1 Reply Last reply Reply Quote 1
        • Unc3nZureDU
          Unc3nZureD
          last edited by

          Sure. It’s mostly some custom and private thing, which I can’t fully reveal (company related), but I’ll try to give some example which might make you understand some basics.

          ; Comment. These all are checks if variable D equals to the hex number given on the right
          D==de07ed76            ; 0xde07ed76    
          D==e                   ; 0xe
          D == 123               ; 0x123   - note that spaces doesn't matter
          
          ; This is some pattern finding code. Everything is treated as hex and ?? marks are allowed. Note that spaces are UNNECESSARY and OPTIONAL here.
          [3ff] (
              68 ?? ?? 40 00   
            )
          

          I hope you can more or less understand me now :)

          I’ve never tried pythonscripted plugin, but sure, if it’s interesting, then why not? :)

          1 Reply Last reply Reply Quote 1
          • Eko palypseE
            Eko palypse
            last edited by

            Being back to work, partially, lunch break over :-)
            Will come back later this day

            1 Reply Last reply Reply Quote 0
            • Eko palypseE
              Eko palypse
              last edited by

              So what I was thinking about is to use the UDL as the main lexer while
              using this script to do additional colorings.
              To use this script you need to install PythonScript plugin, create a new script,
              paste content from below, safe it.

              Then modify it to your needs - see configure section for more details.
              Basically add/modify the regexes and more important modify the lexer name

              self.lexer_name = 'User Defined language file'

              Once done, save it and run it. It should, hopefully, go hand ind hand with your UDL
              I have added two regular expressions just to show you how it can be extended.
              From the problem given, I assume you only need the second one.

              from Npp import editor, notepad, NOTIFICATION, SCINTILLANOTIFICATION, INDICATORSTYLE
              import ctypes
              import ctypes.wintypes as wintypes
              
              from collections import OrderedDict
              
              try:
                  EnhanceUDLLexer().main()
              except NameError:
              
                  user32 = wintypes.WinDLL('user32')
              
                  WM_USER = 1024
                  NPPMSG = WM_USER+1000
                  NPPM_GETLANGUAGEDESC = NPPMSG+84
              
              
                  class SingletonEnhanceUDLLexer(type):
                      _instance = None
                      def __call__(cls, *args, **kwargs):
                          if cls._instance is None:
                              cls._instance = super(SingletonEnhanceUDLLexer, cls).__call__(*args, **kwargs)
                          return cls._instance
              
              
                  class EnhanceUDLLexer(object):
              
                      __metaclass__ = SingletonEnhanceUDLLexer
              
                      @staticmethod
                      def rgb(r,g,b):
                          return (b << 16) + (g << 8) + r
              
              
                      @staticmethod
                      def paint_it(color, pos, length):
                          editor.setIndicatorCurrent(0)
                          editor.setIndicatorValue(color)
                          editor.indicatorFillRange(pos, length)
              
              
                      def style(self):
                          start_line = editor.getFirstVisibleLine()
                          end_line = start_line + editor.linesOnScreen()
                          start_position = editor.positionFromLine(start_line)
                          end_position = editor.getLineEndPosition(end_line)
                          editor.setIndicatorCurrent(0)
                          editor.indicatorClearRange(0, editor.getTextLength())
                          for color, regex in self.regexes.items():
                              editor.research(regex,
                                              lambda m: self.paint_it(color[1], m.span()[0], m.span()[1] - m.span()[0]),
                                              0,
                                              start_position,
                                              end_position)
              
              
                      def configure(self):
                          SC_INDICVALUEBIT = 0x1000000
                          SC_INDICFLAG_VALUEFORE = 1
                          editor.indicSetFore(0, (181, 188, 201))
                          editor.indicSetStyle(0, INDICATORSTYLE.TEXTFORE)
                          editor.indicSetFlags(0, SC_INDICFLAG_VALUEFORE)
                          self.regexes = OrderedDict()
              
                          # configuration area
                          # self.regexes is a dictionary, basically a key=value list
                          # the key is tuple starting with an increasing number and
                          # the color which should be used, ored with SC_INDICVALUEBIT
                          # the value is a raw bytestring which is the regex whose
                          # matches get styled with the previously defined color
                          #
                          # using OrderedDict ensures that the regex will be
                          # always executed in the same order.
                          # This might matter if more than one regex is used.
                          self.regexes[(0, self.rgb(79, 175, 239)  | SC_INDICVALUEBIT)] = r'\b([A-F0-9]+[\s\?]*)+\b'
                          self.regexes[(1, self.rgb(189, 102, 216) | SC_INDICVALUEBIT)] = r'\b([a-f0-9]+[\s\?]*)+\b'
              
                          # defining the lexer_name ensures that
                          # only this type of document get stlyed
                          # should be the same name as displayed in first field of statusbar
                          self.lexer_name = 'User Defined language file'
              
              
              
                      def get_lexer_name(self):
                          '''
                              returns the text which is shown in the
                              first field of the statusbar
                          '''
                          language = notepad.getLangType()
                          length = user32.SendMessageW(self.npp_hwnd, NPPM_GETLANGUAGEDESC, language, None)
                          buffer = ctypes.create_unicode_buffer(u' '*length)
                          user32.SendMessageW(self.npp_hwnd, NPPM_GETLANGUAGEDESC, language, ctypes.byref(buffer))
                          # print buffer.value  # uncomment if unsure how the lexername in configure should look like
                          return buffer.value
              
              
                      def __init__(self):
                          editor.callbackSync(self.on_updateui, [SCINTILLANOTIFICATION.UPDATEUI])
                          notepad.callback(self.on_langchanged, [NOTIFICATION.LANGCHANGED])
                          notepad.callback(self.on_bufferactivated, [NOTIFICATION.BUFFERACTIVATED])
                          self.__is_lexer_doc = False
                          self.lexer_name = None
                          self.npp_hwnd = user32.FindWindowW(u'Notepad++', None)
                          self.configure()
              
              
                      def set_lexer_doc(self, bool_value):
                          editor.setProperty(self.__class__.__name__, 1 if bool_value is True else -1)
                          self.__is_lexer_doc = bool_value
              
              
                      def on_bufferactivated(self, args):
                          if (self.get_lexer_name() == self.lexer_name) and (editor.getPropertyInt(self.__class__.__name__) != -1):
                              self.__is_lexer_doc = True
                          else:
                              self.__is_lexer_doc = False
              
              
                      def on_updateui(self, args):
                          if self.__is_lexer_doc:
                              self.style()
              
              
                      def on_langchanged(self, args):
                          self.set_lexer_doc(True if self.get_lexer_name() == self.lexer_name else False)
              
              
                      def main(self):
                          self.set_lexer_doc(True)
                          self.style()
              
              
                  EnhanceUDLLexer().main()
              
              1 Reply Last reply Reply Quote 1
              • First post
                Last post
              The Community of users of the Notepad++ text editor.
              Powered by NodeBB | Contributors