Prev: get highlighted text
Next: Keybinding hell.
From: eb303 on 11 Feb 2010 03:55 On Feb 10, 6:02 pm, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > On Feb 10, 5:27 pm, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > > > > > On Feb 10, 4:32 pm, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > > > > Hello all, > > > > I've been trying to do a text editor showing line numbers on the left > > > side of a text, which can also set the initial position of the > > > insertion point. To do this, I pack 2 texts side by side, one for the > > > line numbers and one for the actual text, and configure them to scroll > > > together whenever one of them is scrolling. To see the initial cursor > > > position, I use the 'see' subcommand on the text, but it seems > > > something's wrong, since it doesn't seem to work. > > > > Here is a simplified script demonstrating the problem: > > > ----------------- > > > ## Frame for both texts > > > pack [frame .texts] -side top > > > ## Text for line numbers > > > text .texts.lines -width 5 > > > pack .texts.lines -side left -fill y > > > ## Text for actual text > > > text .texts.txt > > > pack .texts.txt -side left -fill both > > > > ## Vertical scrollbar > > > scrollbar .texts.vscroll -orient vertical -command { .texts.txt > > > yview } > > > > ## Trick to make both texts scroll together, as well as update the > > > scrollbar > > > proc scroll_text { first last } { > > > .texts.vscroll set $first $last > > > .texts.lines yview moveto $first} > > > > proc scroll_lines { first last } { > > > .texts.vscroll set $first $last > > > .texts.txt yview moveto $first} > > > > .texts.txt configure -yscrollcommand scroll_text > > > .texts.lines configure -yscrollcommand scroll_lines > > > > ## Fill text and line numbers with dummy lines > > > for { set i 1 } { $i <= 2000 } { incr i } { > > > .texts.lines insert end "$i\n" > > > .texts.txt insert end "This is line number $i\n" > > > > } > > > > ## Procedure to center the text on a given line and set the insertion > > > point on it > > > proc center_text {} { > > > .texts.txt see 789.0 > > > .texts.txt mark set insert 789.0 > > > > } > > > > ## Initial positionning <= does not work > > > center_text > > > > ## Button to do positionning again <= works > > > button .btn -text Center -command center_text > > > pack .btn > > > > focus .texts.txt > > > ----------------- > > > > The initial call to center_text doesn't work: the insertion point is > > > actually moved, but the line is not centered in the text. However, > > > after the initial display, clicking on the 'Center' button works: the > > > insertion point moves, and the line is centered. > > > > I've tried various tricks to make this work, like calls to 'update' or > > > 'update idletasks' before calling center_text, or triggering it later > > > via an 'after idle', but with no result: I can't get the line to be > > > centered on display. > > > > Do I do anything wrong here? Is it the trick I used to scroll both > > > texts at the same time that messes things up? > > > > My tcl version is 8.5.5; I've tried this on Linux (Fedora Core 10) and > > > Mac OS X 10.5, and the result is the same. > > > > Thanks. > > > - Eric - > > > Replying to myself: my problem seems to be related to bug 1739605 > > (http://sourceforge.net/tracker/? > > func=detail&aid=1739605&group_id=12997&atid=112997), except in my > > case, 'update idletasks' does not seem to make things work. I tried > > everything I could think of ('after idle', 'tkwait visibility', > > posting custom events and doing the 'see' when they are received and > > combinations of all of the above), but I only succeeded in making it > > work with an 'after <delay>'. The problem now is that the delay seems > > to depend on the number of lines I display: the more lines there is, > > the bigger the delay must be. Quite unsatisfactory... > > Indeed ! > > The problem is that idle tasks in Tk do some real work, and we lack a > "after really_idle"... > Even calling center_text from within a <Configure> binding (which is > called many times) doesn't seem to help. > Sigh. > > Please report a fresh bug. If it is the same as an older one, at least > that isn't obvious. No shame in marking it as duplicate afterwards ;-) > > -Alex I think I'll do that: the answer to bug 1739605 was basically 'do an update idletasks before', which doesn't help here, so even if the cause is the same, it feels like something new indeed. Thanks!
From: MSEdit on 11 Feb 2010 05:20 On Feb 11, 9:55 am, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > On Feb 10, 6:02 pm, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> > wrote: > > > > > On Feb 10, 5:27 pm, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > > > > On Feb 10, 4:32 pm, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > > > > > Hello all, > > > > > I've been trying to do a text editor showing line numbers on the left > > > > side of a text, which can also set the initial position of the > > > > insertion point. To do this, I pack 2 texts side by side, one for the > > > > line numbers and one for the actual text, and configure them to scroll > > > > together whenever one of them is scrolling. To see the initial cursor > > > > position, I use the 'see' subcommand on the text, but it seems > > > > something's wrong, since it doesn't seem to work. > > > > > Here is a simplified script demonstrating the problem: > > > > ----------------- > > > > ## Frame for both texts > > > > pack [frame .texts] -side top > > > > ## Text for line numbers > > > > text .texts.lines -width 5 > > > > pack .texts.lines -side left -fill y > > > > ## Text for actual text > > > > text .texts.txt > > > > pack .texts.txt -side left -fill both > > > > > ## Vertical scrollbar > > > > scrollbar .texts.vscroll -orient vertical -command { .texts.txt > > > > yview } > > > > > ## Trick to make both texts scroll together, as well as update the > > > > scrollbar > > > > proc scroll_text { first last } { > > > > .texts.vscroll set $first $last > > > > .texts.lines yview moveto $first} > > > > > proc scroll_lines { first last } { > > > > .texts.vscroll set $first $last > > > > .texts.txt yview moveto $first} > > > > > .texts.txt configure -yscrollcommand scroll_text > > > > .texts.lines configure -yscrollcommand scroll_lines > > > > > ## Fill text and line numbers with dummy lines > > > > for { set i 1 } { $i <= 2000 } { incr i } { > > > > .texts.lines insert end "$i\n" > > > > .texts.txt insert end "This is line number $i\n" > > > > > } > > > > > ## Procedure to center the text on a given line and set the insertion > > > > point on it > > > > proc center_text {} { > > > > .texts.txt see 789.0 > > > > .texts.txt mark set insert 789.0 > > > > > } > > > > > ## Initial positionning <= does not work > > > > center_text > > > > > ## Button to do positionning again <= works > > > > button .btn -text Center -command center_text > > > > pack .btn > > > > > focus .texts.txt > > > > ----------------- > > > > > The initial call to center_text doesn't work: the insertion point is > > > > actually moved, but the line is not centered in the text. However, > > > > after the initial display, clicking on the 'Center' button works: the > > > > insertion point moves, and the line is centered. > > > > > I've tried various tricks to make this work, like calls to 'update' or > > > > 'update idletasks' before calling center_text, or triggering it later > > > > via an 'after idle', but with no result: I can't get the line to be > > > > centered on display. > > > > > Do I do anything wrong here? Is it the trick I used to scroll both > > > > texts at the same time that messes things up? > > > > > My tcl version is 8.5.5; I've tried this on Linux (Fedora Core 10) and > > > > Mac OS X 10.5, and the result is the same. > > > > > Thanks. > > > > - Eric - > > > > Replying to myself: my problem seems to be related to bug 1739605 > > > (http://sourceforge.net/tracker/? > > > func=detail&aid=1739605&group_id=12997&atid=112997), except in my > > > case, 'update idletasks' does not seem to make things work. I tried > > > everything I could think of ('after idle', 'tkwait visibility', > > > posting custom events and doing the 'see' when they are received and > > > combinations of all of the above), but I only succeeded in making it > > > work with an 'after <delay>'. The problem now is that the delay seems > > > to depend on the number of lines I display: the more lines there is, > > > the bigger the delay must be. Quite unsatisfactory... > > > Indeed ! > > > The problem is that idle tasks in Tk do some real work, and we lack a > > "after really_idle"... > > Even calling center_text from within a <Configure> binding (which is > > called many times) doesn't seem to help. > > Sigh. > > > Please report a fresh bug. If it is the same as an older one, at least > > that isn't obvious. No shame in marking it as duplicate afterwards ;-) > > > -Alex > > I think I'll do that: the answer to bug 1739605 was basically 'do an > update idletasks before', which doesn't help here, so even if the > cause is the same, it feels like something new indeed. > Thanks! Hi, I too have written an editor usint a text widget, but I use ctext which is in the tklib. Here the line numbers are not displayed for all lines but only those lines displayed, I even posted an update which pixel adjusts the linenumbers to handle the new 8.5 pixel scrolling. ctext also does text hichlighting and with only a fex adjustments I have added bookmarks and tcl proc relative line numbering, including not numbering wrapped lines. If you do not use ctext at least look at the code to see how the numbering works. I have openned files with more than 500000 lines and the numbering works great. Martyn
From: Bryan Oakley on 11 Feb 2010 07:51 On Feb 10, 9:32 am, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > Hello all, > > I've been trying to do a text editor showing line numbers on the left > side of a text, which can also set the initial position of the > insertion point. To do this, I pack 2 texts side by side, one for the > line numbers and one for the actual text, and configure them to scroll > together whenever one of them is scrolling. To see the initial cursor > position, I use the 'see' subcommand on the text, but it seems > something's wrong, since it doesn't seem to work. I used to do line numbers this way and it was indeed a pain to keep everything synced up. Not to mention the fact it doesn't work if you use multiple fonts. Another solution is to use a canvas for the line numbers, and simply redraw them whenever anything changes. It sounds like it is computationally intensive, but it's not. It works remarkably well, plus it gives you all sorts of flexibility for coloring, annotation, etc. You can see the code here: http://wiki.tcl.tk/20916
From: eb303 on 11 Feb 2010 11:41 Thanks Martyn and Brian for your suggestions. I'm actually in a case where having two texts side by side for the line numbers and the actual text work quite well. The only problem I had was that the 'see' command did not work as expected, but it doesn't really seem related to the way I handle text lines. I'll take a look at your solutions anyway. Thanks again! - Eric -
From: Uwe Klein on 11 Feb 2010 11:49
eb303 wrote: > Thanks Martyn and Brian for your suggestions. I'm actually in a case > where having two texts side by side for the line numbers and the > actual text work quite well. The only problem I had was that the 'see' > command did not work as expected, but it doesn't really seem related > to the way I handle text lines. I'll take a look at your solutions > anyway. > > Thanks again! > - Eric - tkdiff is a wellworking example of sync scrolling text widgets with linenumbering and marker columns. uwe |