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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
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!
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.