# $Header: /usr/build/vile/vile/perl/RCS/syntax.pl,v 1.3 1998/10/01 10:29:26 tom Exp $ # # See 'hilite.doc' for an overview. This (with hilite.pl) provide a simple # syntax highlighting mode. # # Caveat: this is experimental code; the chief drawback is that it is slow. # # The following two lines need to be added to .vilerc # # ---------------------------------------- # perl "Vile::register 'synon', 'synon', 'Syntax Hilighting, do', 'syntax.pl'" # perl "Vile::register 'synoff', 'synoff', 'Syntax Hilighting, undo', 'syntax.pl'" # ---------------------------------------- # # this way :synon turns on hiliting and :synoff turns off hiliting. # (You must have a majormode defined, as well). # require 'hilite.pl'; sub synon { my $cb = $Vile::current_buffer; my $mode = scalar($cb->get("majormode")); return if (!defined($mode) || !length($mode)); my $syntaxer = "syntax$mode"; if (defined(&$syntaxer)) { $cb->setregion(1,'$')->attribute("normal"); my $work = Vile::working(0); print "[Syntax hiliting for $mode...]"; &$syntaxer($cb); &syntax($cb); print "[Syntax hiliting for $mode... done]"; Vile::working($work); Vile::update; } else { print "[No syntax hilighting defined for $mode]" } } sub synoff { my $cb = $Vile::current_buffer; my $mode = scalar($cb->get("majormode")); return if (!defined($mode) || !length($mode)); $cb->setregion(1,'$')->attribute("normal"); Vile::update; } sub syntax { my ($cb) = @_; my (%kdata, $kdata, @kdot, $koff); my (%mdata, $mdata, @mdot, $moff); my (%rdata, $rdata, @rdot, $roff); my ($line, $group, $l, @data, $pat, $start, $patt); my ($save_line, $save_delim, $save_flag); %kdata = %syntax'kdata; %mdata = %syntax'mdata; %rdata = %syntax'rdata; # mangle the keyword lists into a regexp foreach $kdata (keys %kdata) { $kdata{$kdata} = "(^|\\b)(" . join("|", split(/\s+/, $kdata{$kdata})) . ")(\\b|\$)"; } @data = <$cb>; for ($l = 0; $l <= $#data; $l++) { $save_line = $data[$l]; @kdot = @mdot = ($l + 1, 0, $l + 1, 0); foreach $group (@hilite) { $line = $save_line; next if (!defined $kdata{$group}); while ($line =~ m!$kdata{$group}!g) { $koff = pos($line); $kdot[3] = $koff; $kdot[1] = length($`); $cb->setregion(@kdot); $cb->attribute("normal"); $cb->attribute(@{$hilite{$group}}); } } foreach $group (@hilite) { next if (!defined @{$mdata{$group}}); foreach $mdata (@{$mdata{$group}}) { my ($pat, $hls, $hle) = @$mdata; $line = $save_line; while ($line =~ m!$pat!g) { $moff = pos($line); $mdot[3] = $moff + $hle; $mdot[1] = length($`) + $hls; $cb->setregion(@mdot); $cb->attribute("normal"); $cb->attribute(@{$hilite{$group}}); } } } } $save_delim = $/; $save_flag = $*; $/ = ""; $* = 1; $save_line = $cb->setregion(1,'$')->fetch; foreach $group (@hilite) { next if (!defined @{$rdata{$group}}); foreach $rdata (@{$rdata{$group}}) { my ($rps, $rpe, $rskip, $hls, $hle) = @$rdata; $line = $save_line; $l = 1; $start = 1; $patt = $rps; @rdot = (1, 0); while ($line =~ m!($patt|\n)!g) { if ($& eq "\n") { ++$l; $line = substr($line, length($`)+1, length($line)); } else { $roff = pos($line); if ( $start == 1 ) { $rdot[0] = $l; $rdot[1] = length($`) + $hls; $patt = $rpe; $start = 0; } elsif ( $start == 0 ) { next if ("$`$&" =~ m!${rskip}$!); $rdot[2] = $l; $rdot[3] = length($`) + $hle + 1; $cb->setregion(@rdot); $cb->attribute("normal"); $cb->attribute(@{$hilite{$group}}); $patt = $rps; $start = 1; } } } } } $/ = $save_delim; $* = $save_flag; } 1;