• Login
Community
  • Login

Can clickable links contain line numbers?

Scheduled Pinned Locked Moved General Discussion
8 Posts 2 Posters 3.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.
  • D
    David Miller229
    last edited by Dec 9, 2016, 8:41 PM

    I have log files that have clickable links in them like:

    ____________________________________________
    (2)file:///C:/Scot/config/BaseTBAutomationPosMgr.xml#3686
    

    I can click this link and it opens the file in Notepad++ like I intended. However, it doesn’t go to line 3686. Is there any way I can make this link or another format link open the file in Notepad++ and go to that line?

    C 1 Reply Last reply Dec 9, 2016, 10:02 PM Reply Quote 0
    • C
      Claudia Frank @David Miller229
      last edited by Dec 9, 2016, 10:02 PM

      @David-Miller229

      I don’t think it is possible using native npp functions.
      What I can think of is using a scripting language like python script or lua script
      and using the hotspotclick notification send by scintilla.
      We would receive the location/position of this click event and could get the text
      from that line. If your format is always the same I assume we could prepare such a script.
      Let us know if you wanna go this way.

      Cheers
      Claudia

      1 Reply Last reply Reply Quote 0
      • D
        David Miller229
        last edited by Dec 12, 2016, 9:43 PM

        Python would be great! I already have it installed. I have never used these kinds of scripts with NPP so that would be a great learning experience for me.

        C 4 Replies Last reply Dec 13, 2016, 3:06 AM Reply Quote 0
        • C
          Claudia Frank @David Miller229
          last edited by Dec 13, 2016, 3:06 AM

          @David-Miller229

          because the latest python script version tends to fail if installed by plugin manager
          just double check if it has correctly installed on your side. Plugins->PythonScript->Show Console should report something like

          Python 2.7.6-notepad++ r2 (default, Apr 21 2014, 19:26:54) [MSC v.1600 32 bit (Intel)]
          Initialisation took 145ms
          Ready.
          

          If this doesn’t appear or you get an error download the MSI package and reinstall it.

          Once done, create a new script by Plugin->PythonScript-New Script
          name the file startup.py and paste the following content into it.

          import os
          
          file_identifier = 'file:///'
          position_seperator = '#'
          file_to_load = None
          line_in_file = 0
           
          def callbackBUFFERACTIVATED(args):
              global file_to_load
              if file_to_load is not None:
                  current_file = notepad.getBufferFilename(args['bufferID'])
                  if file_to_load.lower() == os.path.normpath(current_file).lower():
                      editor.gotoLine(int(line_in_file))
                      editor.verticalCentreCaret()
                      file_to_load = None
          
          
          def callbackHOTSPOTCLICK(args):
              line_of_link = editor.lineFromPosition(args['position'])
              link_text = editor.getLine(line_of_link)
              if file_identifier in link_text and position_seperator in link_text:
                  global file_to_load
                  global line_in_file
                  file_to_load, line_in_file = link_text.split(position_seperator)
                  file_to_load = file_to_load.replace(file_identifier, '')
                  file_to_load = os.path.normpath(file_to_load)
                  notepad.open(file_to_load)
          
          editor.callback(callbackHOTSPOTCLICK, [SCINTILLANOTIFICATION.HOTSPOTCLICK])
          notepad.callback(callbackBUFFERACTIVATED, [NOTIFICATION.BUFFERACTIVATED])
          

          Take care about indention, python is strict about it (don’t know if you familar with python language).

          One additional step -> Plugins->PythonScript->Configuration
          change Initialisation from LAZY to ATSTARTUP.

          Done - every time you start npp this script gets executed automatically.

          What does the script?
          It registers a callback for hotspotclick and bufferactivated notification. Once you click
          on a link the callback gets executed and tries to get the text from the link.
          If it starts with file:/// and has # in the line it is supposed to be a file link and gets
          the details, file_to_load and line_in_file. Then it asks notepad to open that file.
          If this is successful, npp sends a notification (bufferactivated) once the buffer has been loaded. Now the second part starts - it gets checked if this is the file we want
          and if so we goto the line in question.
          Currently I have no windows environment to test but under Linux(wine)
          I do have a strange behavior. When the goto line is called some text before that
          line gets selected. I hope this isn’t an issue under windows.

          Cheers
          Claudia

          1 Reply Last reply Reply Quote 0
          • C
            Claudia Frank @David Miller229
            last edited by Dec 13, 2016, 3:23 AM

            @David-Miller229

            ok, found the culprit, we need to use HOTSPOTRELEASECLICK instead HOTSPOTCLICK. The following should work.

            import os
            
            file_identifier = 'file:///'
            position_seperator = '#'
            file_to_load = None
            line_in_file = 0
             
            def callbackBUFFERACTIVATED(args):
                global file_to_load
                if file_to_load is not None:
                    current_file = notepad.getBufferFilename(args['bufferID'])
                    if file_to_load.lower() == os.path.normpath(current_file).lower():
                        editor.gotoLine(int(line_in_file))
                        editor.verticalCentreCaret()
                        file_to_load = None
            
            
            def callbackHOTSPOTRELEASECLICK(args):
                line_of_link = editor.lineFromPosition(args['position'])
                link_text = editor.getLine(line_of_link)
                if file_identifier in link_text and position_seperator in link_text:
                    global file_to_load
                    global line_in_file
                    file_to_load, line_in_file = link_text.split(position_seperator)
                    file_to_load = file_to_load.replace(file_identifier, '')
                    file_to_load = os.path.normpath(file_to_load)
                    notepad.open(file_to_load)
            
            editor.callback(callbackHOTSPOTRELEASECLICK, [SCINTILLANOTIFICATION.HOTSPOTRELEASECLICK])
            notepad.callback(callbackBUFFERACTIVATED, [NOTIFICATION.BUFFERACTIVATED])
            

            Cheers
            Claudia

            1 Reply Last reply Reply Quote 0
            • C
              Claudia Frank @David Miller229
              last edited by Dec 13, 2016, 3:29 AM

              @David-Miller229

              and if your program starts counting lines from 1 instead of 0 you need to
              change the line

              editor.gotoLine(int(line_in_file))
              

              to

              editor.gotoLine(int(line_in_file)-1)
              

              So, hopefully this was the last update today ;-)

              Cheers
              Claudia

              1 Reply Last reply Reply Quote 0
              • C
                Claudia Frank @David Miller229
                last edited by Claudia Frank Dec 13, 2016, 4:27 AM Dec 13, 2016, 4:26 AM

                @David-Miller229

                ok, one last change before going to bed.
                Maybe there is text before and after the link, in such a case
                it would break the logic. Here a solution which gets the link text only.
                Replace callbackHOTSPOT… with this one

                def callbackHOTSPOTRELEASECLICK(args):
                    __pos = args['position']
                    __style_id = editor.getStyleAt(__pos)
                    __word_start = None
                    __word_end = None
                    
                    _p = __pos
                    while True:
                        __word_start = _p
                        if editor.getStyleAt(_p) != __style_id:
                            break
                        _p -= 1
                
                    _p = __pos
                    while True:
                        if editor.getStyleAt(_p) != __style_id:
                            __word_end = _p
                            break
                        _p += 1
                    
                    link_text = editor.getTextRange(__word_start, __word_end+1) 
                    
                    if file_identifier in link_text and position_seperator in link_text:
                        global file_to_load
                        global line_in_file
                        file_to_load, line_in_file = link_text[link_text.find(file_identifier):].split(position_seperator)
                        file_to_load = file_to_load.replace(file_identifier, '')
                        file_to_load = os.path.normpath(file_to_load)
                        notepad.open(file_to_load)
                

                Good Night.

                Cheers
                Claudia

                1 Reply Last reply Reply Quote 0
                • D
                  David Miller229
                  last edited by Dec 13, 2016, 6:45 PM

                  Thank you! The last works perfect.

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