Yes please post if you don't mind, i can learn from it.
Okay, this works in one direction. That is, it will select sequential lines that start with the same letter, but only in a downward direction. It doesn't loop around to the first line with that letter, but with some more tinkering it could. If the user types a letter that doesn't start any line, the selection does not change.
Code: Select all
on keydown pKey
if char 1 of line (the hilitedline of me) of me = pKey then
put the hilitedline of me into tSkip
else
put 0 into tSkip
end if
put lineoffset(cr & pKey,cr & me,tSkip) + tSkip into tLineNum
if tLineNum > 0 then
set the hilitedline of me to tLineNum
end if
end keydown
Put the handler into a list field script. The field must have focus, as Bernd said, or key presses will not be caught. That's probably where I went wrong before.
The first "if" clause checks to see if the hilited line of the field starts with the requested character in pKey. If so,the character has already been found once so it puts that line number into the amount of text to skip when doing the search. If there is no match line, the skip amount is set to zero and no lines will be skipped.
The next line in the handler finds the lineoffset for a carriage return concatenated with the requested character ("cr & pKey"). The reason the carriage return is included is to be sure that we are only finding the first character in a line; that character will always be preceded by a CR from the previous line so we only look for that. If we looked only for the character itself, we'd find any matching character anywhere in the line. (That's why your script was finding the "c" after the @ in each email address.)
There's one problem with looking for a CR plus a character; there will be no CR before the first line of the field. That means you can never get a match for the first line. But because lineOffset can search through a variable, we can add an extra CR before the variable's text to be sure that even the first line can be matched. That's why the offset uses "cr & me" in the second parameter of the lineOffset function.
If there is a match, lineoffset will return the number of the line after the skip amount. For example, if we are skipping 6 lines and the match is on line 7, lineOffset will return 1. We need to add that 1 to the original skip amount to get the real line number. The lineoffset number (1) is added to the skip amount (6) to get line 7.
Finally, we check to see if the line number is greater than zero. If so, we set the hilitedline of the field to that number (i.e., 7.) If it is zero, there is no match and nothing changes.
Edit: There's another way to find matches for more than one character so that the user can type the first few letters of a line and the match will be found. "a" will match "
a@xx.com" and "aa" will match "
aa@xx.com". But that's more complicated.