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. This code also lacks the feature found in the default tkTextUpDownLine where the original column is maintained across repeated operations even though some lines passed through don't have enough columns: 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] }