Jump or go to the nth element



  • Hello,
    Is there a way to easily navigate into some delimited based file, like csv files? I was wondering if there is some shortcut like ctrl+G for lines, but instead go to the nth specific separator(,) in the current line? This kind of plug-in or shortcut would be really appreciated and good to people who have to deal with this kind of files everyday.



  • Hello Bruno,

    The general syntax to move to the location just after the Nth “Car” character, of each line,can be achieved with the simple regex ^(.*?Car){N}\K

    Therefore, as in CSV files, “Car” is the , character, this syntax becomes ^(.*?,){N}\K

    So given the example text, below :

    123,12,12345678,13245,12345,123,1,123456789,,1234,12,123456
    

    The regex ^(.*?,){9}\K, for instance, would place the caret, just after the two consecutive comma separators ! ( 9th comma of the line )

    Best regards,

    guy038



  • Hello guy038,
    Thanks a lot for your answer, this will definitely help. Besides this regex, could anyone point out how should I do to create a plugin or pyton script to do this task automatically? Like associating a shortcut to open a simple popup where we can insert the number of element to find (nth). We can think in something similar to Ctrl+G (Shortcut and Popup). Is it possible? This would be very usefull.

    Thanks.
    Best regards,
    Bruno



  • @Bruno-Miguel-Pereira

    how should such a script be used and designed?
    I mean, the files could have different separators like comma and semicolon etc…
    Should the script ask for it? Should it assume a default and change only if another one is provided?
    How would be the expected format? Number followed by whatever followed by new separator?
    Maybe two prompts - first one for separator next for position?
    Concerning position, is each run relative to the previous one, for example if you provide the number 8.
    Does it mean first run it jumps to element 8 and next jump would be 16 or should it jump from
    current cursor location? Should the script remember the settings for consecutive runs(per document)?

    If you have other ideas, feel free to post it. I assume when having a defined flow is should be easy
    to write/provide a script for it.

    Cheers
    Claudia



  • I found the general idea useful as I find myself working with CSV files more than I’d like…so I whipped up the following on my lunch break. Maybe it is of use to someone else, perhaps as a base for changes. The delimiter string starts life as a comma, but will persist if changed at the run-time prompt. The script will cause a change in current position to the position after the (absolute) Nth occurrence of the delimiter string on the current line.

    # PositionJustPastNthDelimiterOnLine.py (PJPNDOL)
    
    import re
    
    try:
    
        PJPNDOL__delimiter
    
    except NameError:
    
        PJPNDOL__delimiter = ','  # default
    
        def PJPNDOL__main():
    
            global PJPNDOL__delimiter
    
            reply = notepad.prompt(
                'Edit the "template", or just replace the initially highlighted text with the number N',
                'Move caret just-past the Nth delimiter on current line',
                'delimiter:{0}\r\nN:'.format(PJPNDOL__delimiter))
    
            if reply:
    
                count = 0
    
                try:
                    count = int(reply)
                except ValueError:
                    pass
    
                if count <= 0:
    
                    input_scan_regex = r'delimiter:([^\r\n]+)\r\nN:(\d+)'
                    m = re.search(input_scan_regex, reply)
                    if m:
                        PJPNDOL__delimiter = m.group(1)
                        count = int(m.group(2))
    
                if count > 0:
    
                    curr_pos = editor.getCurrentPos()
                    curr_line_nbr = editor.lineFromPosition(curr_pos)
                    curr_line_contents = editor.getCurLine()
    
                    start_pos_of_curr_line = editor.positionFromLine(curr_line_nbr)
                    end_pos_of_curr_line = editor.getLineEndPosition(curr_line_nbr)
    
                    # cap the count to the smaller of the user-specifed count and the number of delimiters actually present:
                    count = min(count, curr_line_contents.count(PJPNDOL__delimiter))
    
                    if count > 0:
    
                        line_search_regex = '(.*?' + PJPNDOL__delimiter + '){' + str(count) + '}'
    
                        f = editor.findText(FINDOPTION.REGEXP, start_pos_of_curr_line, end_pos_of_curr_line, line_search_regex)
                        if f != None:
                            (found_start_pos, found_end_pos) = f
                            editor.setCurrentPos(found_end_pos)
                            editor.setSelectionStart(found_end_pos); editor.setSelectionEnd(found_end_pos)
    
    PJPNDOL__main()


  • @Claudia-Frank
    Thanks for your time and there are really good questions, I will describe the points I was thinking:

    • The script could assume a default separator and only will change if another one is provided.
    • Concerning the format I normally work with CSV files that can have any kind of printable character separated by semicolon, so is the most generic format.
    • Maybe two prompts would be the best option, having the separator filled by last default choice?
    • Regarding the position, I guess to be more generic, the search could be done taking into account the current cursor location.
    • I guess it would be good to have the script remembering the settings for consecutive runs(per document).

    @Scott-Sumner
    Thanks for your script. I was trying it as a base version to test, but I’m not being very successful. I’m not expert at all in python and I never used it in notepad++, so I’m probably doing some beginner mistake… I’ve done some search in order to successfully run some script but I’m not having great results.

    • I’ve installed “Python Script” plugin in notepad++ through Plugin Manager.
    • I’ve installed Python 2.7.13 in my computer
    • I’ve added your script to User Scripts under “Python Script”.
      I’m missing something?

    Sorry about some beginner questions.

    Thanks a lot for your help.
    Regards,
    Bruno



  • @Bruno-Miguel-Pereira

    Well, you seem to have done everything correctly (possible exception: some people don’t have luck running the plugin after installing Pythonscript plugin via PluginManager…), but you need to take things further to get it to actually do something.

    So let’s go! Open a CSV file in Notepad++ and be on a line with a some comma-delimiters (shouldn’t be hard to achieve). Then, invoke the script from the menu (Plugins -> Pythonscript -> Scripts -> NameOfScript [PositionJustPastNthDelimiterOnLine.py if you kept my name]). A dialog box should appear asking you to verify the delimiter and to enter a numeric value for “N”. When you do that and press the OK button, the caret should move one character position past comma number “N” on the current line.

    If it works when running it from the menu, THEN it is very reasonable to tie running the script to a custom key-combination for running it in the future. This is a two-step process, done first in the Pythonscript Configuration menu item (to tell the Shortcut Mapper that the script is shortcut-enabled), then second in the Preferences -> Shortcut Mapper itself. I’m typing on my Mac at the moment, so sorry but I can’t be any more specific than that…



  • Hello Bruno,

    User Scripts?
    What you normally do after installation of python script is running menu
    Plugins->PythonScript->New Script
    give a meaningful name to it and copy/paste Scotts example
    into the new created editor.
    Save -> Done.

    If you run the example, open the python script console to see if errors are reported.
    Plugins->Python Script->Show console.

    As Scott has already done the work, I leave it to you to test it and ask for
    changes if needed. ;-)

    Cheers
    Claudia



  • Hello,
    Just to thank you all :)

    It seems @Scott-Summer was right and the issue came from the install through plugin manager. I did it again manually and now the script is working. I will use it as a base and I will probably do some adjustments.

    Cheers,
    Bruno


Log in to reply