You use the Text's search function for the word, why not also for the comment?
Update: Modified slightly to only un/highlight current line, hopefully improving efficiency some.
Update2: Made functions slightly more modular, and fixed paste issue caused by previous update. Added style for comments. Added comment regexp global.
Update3: There's an issue w/ comments on lines w/o keywords. I'll fix it later.
Update4: Fixed the comment issue.
#!/usr/bin/winperl
use strict;
use warnings;
use Tk;
our @Keywords = qw(
print
sprintf
);
our $Comment = '#|//';
our %Highlights = (
Keyword => [qw(red bold)],
Comment => [qw(gray italic)],
);
setup_window();
MainLoop;
sub setup_window {
my $mw = MainWindow->new();
my $t = $mw->Scrolled('Text', -font => ['Courier New', 10])->pack()
+;
$t->tagConfigure('red', -foreground => 'red');
$t->tagConfigure('gray', -foreground => 'gray');
$t->tagConfigure('green', -foreground => 'green');
$t->tagConfigure('bold', -font => ['Courier New', 10, 'bold']);
$t->tagConfigure('italic', -font => ['Courier New', 10, 'italic']);
$t->bind(
'<KeyRelease>',
# Automatically prepends $t to called sub's args
[\&highlight_range, 'insert linestart', 'insert lineend'],
);
# Paste events my include more than one line to be highlighted,
# so we rehighlight the entire text.
$t->bind(
'<<Paste>>',
[\&highlight_range, '1.0', 'end'],
);
$t->focus();
}
# Remove all formatting so that updates will unhighlight things proper
+ly
sub unhighlight_range {
my $t = shift;
my $start = shift;
my $end = shift;
foreach my $style (keys %Highlights) {
foreach my $tag (@{$Highlights{$style}}) {
$t->tagRemove($tag, $start, $end);
}
}
}
sub highlight_range {
my $t = shift;
my $start = shift;
my $end = shift;
unhighlight_range($t, $start, $end);
# Highlight keywords
foreach my $word (@Keywords) {
my $word_len = length $word;
my $next = $start;
while (my $from = $t->search(-regexp, "\\b\Q$word\E\\b", $next, $e
+nd)) {
$next = "$from + $word_len chars";
# Search for a comment character on the same line
my $comment = $t->search(
-regexp => $Comment,
"$from linestart" => "$from lineend"
);
# If comment found and is before keyword, skip formatting
unless($comment and $t->compare($comment, '<', $from)) {
mark_word($t, $from, $next, 'Keyword');
}
}
}
# Highlight comments
my $next = $start;
while (my $from = $t->search(-regexp => $Comment, $next, $end)) {
$next = "$from lineend";
mark_word($t, $from, $next, 'Comment');
}
}
sub mark_word {
my $text = shift;
my $start = shift;
my $end = shift;
my $style = shift;
return unless exists $Highlights{$style};
foreach my $tag (@{$Highlights{$style}}) {
$text->tagAdd($tag, $start, $end);
}
}
bbfu
Black flowers blossom
Fearless on my breath
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.