question about editor.forEachLine()

Help
2013-07-12
2013-07-19
  • Is the editor.forEachLine function supposed to terminate on blank lines?

    I have the following script to bookmark lines that start with "#":

    from Npp import *

    def testForBookmark(contents, lineNumber, totalLines):
    if contents.strip()[0] == "#":
    editor.gotoLine(lineNumber)
    notepad.menuCommand(MENUCOMMAND.SEARCH_TOGGLE_BOOKMARK)
    return 1

    notepad.menuCommand(MENUCOMMAND.SEARCH_CLEAR_BOOKMARKS)
    editor.forEachLine(testForBookmark)

    It works great until it hits the first blank line in the file, and ignores the rest of the file. I threw in a console write before the if statement in the function, and it appears the function is never called for any lines after the first blank line.

    Is this a bug, a known limitation of editor.forEachLine, or am I doing something wrong? Thanks to anyone who can provide any insight here.

     
  • Dave W.
    Dave W.
    2013-07-12

    Howard,
    A blank line is a zero-length string. You can't index into it. You get an "index out of range" error.
    I suspect what is happening is the forEachLine function is then just exiting, but it should pass thru the error message.
    You should be seeing something like this:
    Traceback (most recent call last):
    File "<console>", line 1, in <module>
    File "<console>", line 2, in checkit
    IndexError: string index out of range

    But even if not, for some reason, code defensively.
    Don't expect a library routine to CYA for you. ;-)
    Put in a length check just before you try to do the contents check, e.g.

    if len(contents) >= 1:
        if contents.strip()[0] == "#":
        ...
    return 1
    

    See if that helps.

    Dave W.

     
    Last edit: Dave W. 2013-07-12
    • Dave, thanks for your reply. I agree with your statement about defensive coding, and added the if statement. The problem still occurs though. I made the following change to test:

      def testForBookmark(contents, lineNumber, totalLines):
      notepad.messageBox(contents)
      if len(contents) >= 1:
      if contents.strip()[0] == "#":
      ...

      I hit the message box only until I get to the first blank line, then the forEachLine terminates, so my original question remains: does editor.forEachLine terminate on blank lines. I'm going to write a couple of test scripts to see if this is indeed the case.

      Thanks again,
      Howard

       
  • Well, I checked, and forEachLine does in fact work in files with blank lines. My problem was that something was failing (likely the contents.strip()[0] when contents was just a CRLF, so the result of strip was probably empty and not a string, and indexing would crash it, causing the script to terminate). I was able to use a contents.find("#") instead, and my script now works. Thanks again, Dave W!

     
  • Well, I checked, and forEachLine does in fact work in files with blank lines. My problem was that something was failing (likely the contents.strip()[0] when contents was just a CRLF, so the result of strip was probably empty and not a string, and indexing would crash it, causing the script to terminate). I was able to use a contents.find("#") instead, and my script now works. Thanks again, Dave W!

     
  • Dave W.
    Dave W.
    2013-07-19

    Howard,
    Sorry I had to go dark on you - (I don't get around here as much as I'd like to) - Got hit with a slew of 'other issues'. Hate that. ;-)
    Yep, sounds like you're dead on there. Good call.
    Glad you got it working.

    Dave W.