Elijah has asked for the wisdom of the Perl Monks concerning the following question:

I want to be able to parse each line of text on input checking for keywords and coloring them. I already have coloring capabilities on load when I first load the file. That code is the following:
my $browse = $t->getOpenFile(-title => "Browse For A File!"); if ($browse) { $t->delete("1.0", "end"); $status->delete("1.0", "end"); if (!open(TARGET, "$browse")) { $info = "Error!"; $status->insert("end", "ERROR: Could not open $browse\n"); return; } $line_count = 1; $filename = $browse; my @ext = split(/\./, $filename); my $ext = "\." . $ext[1]; $info = "Loading file '$filename'..."; while (<TARGET>) { #$t->insert("end", "$line_count "); $t->insert("end", $_); if ($ext eq ".pl") { if ($_ =~ /\#/) { my @comment = split(//, $_); my $i = 0; foreach my $comment (@comment) { my $range = length($_); if ($comment eq "#") { my $offset = "$line_count\.$i"; my $end = "$line_count\.$range"; $t->tagAdd("orange", $offset, $end); }else{ $i++; } } } } $line_count++; } }
I also have the same code for when a file is saved, to update the new text. I would like to able to color the text as it is input though. Would this be possible? Would any of the existing code to color commented string be of any help in doing so? I know of a way I can color the code by splitting the string on each character input but do not know how to monitor the textbox for character input. Any ideas?

Replies are listed 'Best First'.
Re: Tk Scrolled textbox, parse on input?
by pg (Canon) on Dec 08, 2003 at 00:24 UTC

    All what you need is to be able to capture key release event, and the key pressed. This demo shows you the way:

    use Tk; use strict; use warnings; my $mw = new MainWindow(title => "demo"); my $entry = $mw->Entry(width => 20)->pack; $entry->bind("<KeyRelease>", [sub {print $_[1];}, Ev('A')]); MainLoop;
      Yes this looks like the right teack however I tried to modify it to do what I wanted but get an error when I try to split $_
      use Tk; use strict; use warnings; my $mw = new MainWindow(title => "demo"); my $entry = $mw->Scrolled("Text", -scrollbars => 'e', -font => '12')-> +pack(-side => 'bottom', -fill => 'both', -expand => 1); #$entry->bind("<KeyRelease>", [sub {print $_[1];}, Ev('A')]); $entry->bind("<KeyRelease>", [\&color, Ev('A')]); $entry->tagConfigure("blue", -foreground => "blue"); MainLoop; sub color { my $count = 0; my @char = split(//, $_); my @word = split(/ /, $_); foreach my $char (@char) { $count++; } foreach my $word (@word) { if ($word =~ /color/) { my $len = length($word); my $from = "1\.$count"; my $next = $from + $len; $entry->tagAdd("blue", $from, $next); } } }
      The error says that $_ is not initialized but $_1 is? Why is this so and how can I accomplish what I want to do in this sub if I cannot use $_?

        $_ is not the same as $_[1]. See perlvar for the complete details. In this instance, $_[1] contains the key that was released and $_ truly is uninitialized. However, neither $_ nor $_[1] are going to help you do what you want.

        Look instead to the Tk documentation for the get widget method. It will allow you to "get" the text from the scrolled text widget. (Oh and you'll have to fix the logic for your tag coloring to work with multiple lines.)

        Good luck!

        $_[1] is initialized, as you passed a parameter to sub color(), which takes Ev('A') containing the value of the last key stroke.

        "how can I accomplish what I want to do in this sub if I cannot use $_?"

        Why cannot you? That's you code, and you can always modify it to work ;-) I believe that you expect $_ to contain (part of) the content in your text box. You can always call get() method of the text box to get the content at certain position or a range of positions.

        Slightly modified your code to demo a little bit more: (Played with this code, and I do see some text colored blue. Hey, that's mainly your code!)

        use Tk; use strict; use warnings; my $mw = new MainWindow(title => "demo"); my $entry = $mw->Scrolled("Text", -scrollbars => 'e', -font => '12')-> +pack(-side => 'bottom', -fill => 'both', -expand => 1); #$entry->bind("<KeyRelease>", [sub {print $_[1];}, Ev('A')]); $entry->bind("<KeyRelease>", [\&color, Ev('A')]); $entry->tagConfigure("blue", -foreground => "blue"); MainLoop; sub color { my $content = $entry->get("1.0", "end"); my $count = 0; my @char = split(//, $content); my @word = split(/ /, $content); foreach my $char (@char) { $count++; } foreach my $word (@word) { if ($word =~ /color/) { my $len = length($word); my $from = "1\.$count"; my $next = $from + $len; $entry->tagAdd("blue", $from, $next); } } }

        You still have to do some work to implement your application logic, but I have already given you the right tool. Have fun!