Skip Menu |

This queue is for tickets about the Term-ReadLine-Perl CPAN distribution.

Report information
The Basics
Id: 9400
Status: new
Priority: 0/
Queue: Term-ReadLine-Perl

People
Owner: Nobody in particular
Requestors: ramey [...] ti.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.0203
Fixed in: (no value)



Subject: bug in redisplay() when cursor is (length($prompt) from right margin
This bug is in Term-ReadLine-Perl-1.0203. I'm using perl version 5.8.3 on Solaris 8. The error occurs when the cursor is (length($prompt) characters from the right margin. If you insert a character, the readline library incorrectly assumes that the cursor is at the end of the line and so it leaves it there. Here is an example: run the "make test" in the Term-ReadLine-Perl distribution: PERL_DL_NONLAZY=1 /apps/perl/5.8.3/bin/perl "-Iblib/lib" "-Iblib/arch" test.pl Features present: preput 1 getHistory 1 addHistory 1 attribs 1 ornaments 1 appname 1 minline 1 autohistory 1 newTTY 1 tkRunning 1 setHistory 1 Enter arithmetic or Perl expression: exit To make it easier to see the bug, make the prompt shorter: delete the "exit" string and put in $prompt = "test:"; and then press return to get: test: test:exit Now, add 5 characters to the end of the line: test: test:exit12345 Assuming you are in vi mode, press Escape to exit "edit" mode, and then back up until the cursor is over the "1" (by pressing "h" four times). Press "i" to enter insert mode, and type some input, say, "abc": test:exitabc12345 It inserts correctly, but the cursor is now at the end of the line. Press Escape and it will stay over the "5". Now press "h" repeatedly to try to get to the beginning of the line. It won't work. The cursor only goes back as far as the "b". I hope that you were able to reproduce the problem using this explanation. Again, basically the way to see the problem is to make the cursor be N characters from the end of the string, where N is the length of the prompt. Then try inserting something and the readline module is now confused about where the cursor is displayed. The problem seems to be in the redisplay() subroutine, in particular in these lines (lines 1795-1796 in my copy of the code): print $term_OUT "\r",substr_with_props($prompt, $line, 0, $delta, $have_ket) if $delta != length ("$line") || $lastlen > $thislen; Basically what's going on here is it's going to reprint a portion of the line in order to position the cursor in the correct place. The first part of the if statement checks to see if the cursor is already at the end of the line ($delta is the desired cursor position, counted from the left margin, and $line is the line of input). If it's already at the end of the line, it doesn't bother reprinting the line. The problem is that while at the beginning of the function $line is the entire printed line, including the prompt *and* the input, at this part of the function $line is now just the input string - not the prompt. So comparing $delta to length($line) doesn't compare the right things (again, $delta is measured from the left column, before the prompt, but length($line) is the length of the input - *after* the prompt). The fix appears to be to compare $delta to the input line and prompt together. Here's one way to fix the problem. Change the lines to read: print $term_OUT "\r",substr_with_props($prompt, $line, 0, $delta, $have_ket) if $delta != length ("$prompt$line") || $lastlen > $thislen; So it now checks length of "$prompt$line", not just $line. I made this change in my copy of the code and now the redisplay function seems to work correctly.