Christian Heide Damm responded in comp.lang.tcl [http://groups.google.com/groups?hl=en&selm=3BBC54DF.5D77B25%40daimi.au.dk] on how to move the cursor up and down visible lines instead of real text widget lines: ...namely binding up/down to something like this: # Find the coordinates of the cursor and set the new height # manually. Note: errors rounding off, since # coordinates don't match character positions exactly. lset {lines char} [split [$textWidget index insert] .] lset {x y textWidth textHeight} [$textWidget bbox [$textWidget index insert]] lset {_ maxy _ _} [$textWidget bbox "end - 1 char"] # When updating position, make sure y is within text boundaries switch -- $upOrDown { "up" { set y [max [expr $y-$textHeight] 0] } "down" { set y [min [expr $y+$textHeight] $maxy] } } lset {newx newy width _} [$textWidget bbox [$textWidget index @$x,$y]] # Test on which side of the character # we should position the cursor if {$x>[expr $newx+$width/2]} { set x [expr $newx+$width+1] } set newIndex [$textWidget index @$x,$y] ---- Here is the above code in a function, with the non-existent function lset replaced with calls to scan and missing functions min/max defined. Note that this code needs to be modified to handle more than a screenful of text: proc min args {lindex [lsort -real $args] 0} proc max args {lindex [lsort -real $args] end} proc moveUpDown {textWidget upOrDown} { # Find the coordinates of the cursor and set the new height # manually. Note: errors rounding off, since # coordinates don't match character positions exactly. scan [$textWidget index insert] {%d.%d} lines char scan [$textWidget bbox [$textWidget index insert]] {%d %d %d %d} x y textWidth textHeight scan [$textWidget bbox "end - 1 char"] {%*d %d %*d %*d} maxy # When updating position, make sure y is within text boundaries switch -- $upOrDown { "up" { set y [max [expr $y-$textHeight] 0] } "down" { set y [min [expr $y+$textHeight] $maxy] } } scan [$textWidget bbox [$textWidget index @$x,$y]] {%d %d %d %*d} newx newy width # Test on which side of the character # we should position the cursor if {$x>[expr $newx+$width/2]} { set x [expr $newx+$width+1] } return [$textWidget index @$x,$y] } # Replace the default Text widget bindings to try it out bind Text { tkTextSetCursor %W [moveUpDown %W up] } bind Text { tkTextSetCursor %W [moveUpDown %W down] }