Tk-TextHighlight

 view release on metacpan or  search on metacpan

lib/Tk/TextHighlight.pm  view on Meta::CPAN

		$w->configure('-rules' => undef);
		$w->highlightPlug;
	}
	$w->{'background'} = $val;
}

sub jumpToMatchingChar  #ADDED 20060630 JWT TO CAUSE ^p TO WORK LIKE VI & SUPERTEXT - JUMP TO MATCHING CHARACTER!
{
	my $cw = shift;
	my $selectbetween = shift || 0;

	$cw->markSet('insert', $cw->index('insert'));
	my $pm = -1;
	eval { $pm = $cw->index('MyMatch'); };
	if ($pm >= 0)
	{
		my $prevMatch = $cw->index('insert');
		$prevMatch .= '.0'  unless ($prevMatch =~ /\./o);
		$cw->markSet('insert', $cw->index('MyMatch'));
		$cw->see('insert');
		$cw->markSet('MyMatch', $prevMatch);
		if ($selectbetween) {
			my @ranges = $cw->tagRanges('sel');
			my $idx = $cw->index('insert');
			if (@ranges && ($cw->compare($idx,'==',$cw->index('sel.first'))
						|| $cw->compare($idx,'==',$cw->index('sel.last - 1c')))) {
				#SELECT EXCLUDING BRACES (WAS ALREADY SELECTED & INCLUDING BRACES):
				$cw->tagRemove('sel','1.0','end');
				$cw->compare($prevMatch,'<',$cw->index('insert'))
						? $cw->tagAdd('sel','MyMatch + 1c','insert')
						: $cw->tagAdd('sel','insert + 1c','MyMatch');
			} else {
				#SELECT INCLUDING BRACES:
				$cw->tagRemove('sel','1.0','end');
				$cw->compare($prevMatch,'<',$cw->index('insert'))
						? $cw->tagAdd('sel','MyMatch','insert + 1c')
						: $cw->tagAdd('sel','insert','MyMatch + 1c');
			}
		}
	}
}

sub ClassInit
{
	my ($class,$w) = @_;
	
	$class->SUPER::ClassInit($w);

	# reset default Tk::Text binds:
	$w->bind($class,	'<Control-p>', sub {} );  #OVERRIDE BINDINGS WE HANDLE EXCLUSIVELY!:
	$w->bind($class,	'<Control-P>', sub {} );          #ADDED SELECT BETWEEN BRACES (INCLUSIVE).
	$w->bind($class,	'<Key-Return>', sub {} )  unless ($TEXTWIDGET =~ /SuperText/);
	$w->bind($class,	'<Key-BackSpace>', 'Backspace' ); #MAKE CONSISTANT BETWEEN ALL SUPPORTED TEXT WIDGETS.
	$w->bind($class,	'<Key-space>', 'Space' );         #MAKE CONSISTANT BETWEEN ALL SUPPORTED TEXT WIDGETS.
	$w->bind($class,	'<Alt-Tab>', 'insertTabChar' );   #ADDED TO ALLOW INSERTION OF TABS!
	$w->bind($class,	'<Tab>', 'insertTab' );           #ADDED TO ALLOW INSERTION OF TABS OR SPACES!
	$w->bind($class,	'<ButtonRelease-2>', '');         #CHECK READONLY STATUS BEFORE PASTING SELECTION!
	return $class;
}

sub clipboardCopy {
	my $cw = shift;
	my @ranges = $cw->tagRanges('sel');
	if (@ranges) {
		$cw->SUPER::clipboardCopy(@_);
	}
}

sub beginUndoBlock
{
	my $cw = shift;

	if ($TEXTWIDGET =~ /SuperText/)   #GROUP CHANGES FOR UNDO (DIFFERENT FN NAMES USED).
	{
		$cw->_BeginUndoBlock;
	}
	elsif ($TEXTWIDGET =~ /TextUndo/)
	{
		$cw->addGlobStart;
	}
	#OTHERWISE NO-OP (UNDO/REDO NOT SUPPORTED).
}

sub endUndoBlock
{
	my $cw = shift;

	if ($TEXTWIDGET =~ /SuperText/)   #ADDED 20080411 TO GROUP CHANGES FOR UNDO.
	{
		$cw->_EndUndoBlock;
	}
	elsif ($TEXTWIDGET =~ /TextUndo/)
	{
		eval $cw->addGlobEnd;
	}
}
sub doAutoIndent {  #WE HANDLE AUTOINDENT NOW FOR EVERYONE!:
	my $cw = shift;

	my $doAutoIndent = $cw->cget('-autoindent') ? shift : 0;
	if ($cw->{READONLY}) {  #JUST POSITION CURSOR ON NEXT LINE (INDENTED IF NEEDED):
		my $marginlen = 1;
		if ($doAutoIndent) {
			my $margin = $cw->get('insert lineend + 1 char', 'insert lineend + 1 char lineend');
			$marginlen = length($1) + 1  if ($margin =~ /^(\s+)/o);
		}
		$cw->SetCursor($cw->index("insert lineend + $marginlen char"));
		$cw->see('insert linestart');
		Tk->break;
		return;
	}

	my $i = $cw->index('insert linestart');
	my $begin = $cw->linenumber($i);
	my $insertStuff = "\n";
	my $s = $cw->get("$i", "$i lineend");
	$cw->beginUndoBlock;
	#if ($s =~ /\S/o)  #JWT: UNCOMMENT TO CAUSE SUBSEQUENT BLANK LINES TO NOT BE AUTOINDENTED.
	#{
		#$s =~ /^(\s+)/;  #JWT:CHGD. TO NEXT 20060701 TO FIX "e" BEING INSERTED INTO LINE WHEN AUTOINDENT ON?!
		$s =~ /^(\s*)/o;
		if ($doAutoIndent) {
			my $thisindent = defined($1) ? $1 : '';
			if ($cw->cget('-smartindent')) {  #TRY TO DO INTELLIGENT (CODE-FRIENDLY) INDENTING BASE ON CURRENT & NEXT LINE:
				my $s2 = '';

lib/Tk/TextHighlight.pm  view on Meta::CPAN

	foreach my $sect (sort keys %{$sectionHash})
	{
		$nextMenu = $ViewSyntaxMenu->Menu;
		foreach my $lang (@{$sectionHash->{$sect}})
		{
			$menuTitle = "Kate::$lang";
			$nextMenu->radiobutton( -label => $menuTitle,
					-variable => $var,
					-value => $menuTitle,
					-command => sub
			{
				$cw->configure('-rules' => undef);
				$cw->highlightPlug;
			}
			);
		}
		$ViewSyntaxMenu->insert($kateIndx, 'cascade',
				-label => "Kate: $sect...",
				-menu => $nextMenu);
		++$kateIndx  if ($kateIndx =~ /^\d/o);
	}
}

sub getViewMenu  #ADDED 2024624 TO ALLOW CALLING PROGRAM TO INCLUDE IN THEIR OWN CUSTOM MENUS:
{
	my $cw = shift;

	return $cw->menu->entrycget('View','-menu');
}

sub Load {
	my ($cw,$filename) = @_;
	return 0  unless (defined($filename) && -r $filename);
	if (open(my $fid,"<$filename")) {
		$cw->MainWindow->Busy;
		$cw->EmptyDocument;
		$cw->insert('end',$_)  while (<$fid>);
		close($fid);

		$cw->markSet('insert' => '1.0');
		$cw->MainWindow->Unbusy;
		return 1;
	}
	return 0;
}

#NEEDED FOR CLEARING ENTIRE DOCUMENTS PROGRAMATICALLY IN READ-ONLY VIEWERS (ROText IS OK WITH THIS!):
sub EmptyDocument {
	my $cw = shift;

	my $rostatus = $cw->{READONLY};
	$cw->{READONLY} = 0;
	$cw->delete('0.0','end');
	$cw->{READONLY} = $rostatus;
	$cw->ResetUndo;
	#WARNING, DOESN'T SEEM TO EXECUTE ANYTHING AFTER THE ResetUndo?!:
}

#FUNCTIONS NOT USED IN THE READ-ONLY VERSION:

sub clipboardCut {
	my $cw = shift;
	return  if ($cw->{READONLY});

	my @ranges = $cw->tagRanges('sel');
	$cw->SUPER::clipboardCut(@_)  if (@ranges);
}

sub clipboardPaste {
	my $cw = shift;
	return  if ($cw->{READONLY});

	my @ranges = $cw->tagRanges('sel');
	if (@ranges) {
		$cw->tagRemove('sel', '1.0', 'end');
		return;
	}
	$cw->SUPER::clipboardPaste(@_);
}

sub delete {
	my $cw = shift;
	return  if ($cw->{READONLY});

	my $begin = $_[0];
	$begin = (defined $begin) ? $cw->linenumber($begin)
			: $cw->linenumber('insert');
	my $end = $_[1];
	$end = (defined $end) ? $cw->linenumber($end) : $begin;
	$cw->SUPER::delete(@_);
	$cw->highlightCheck($begin, $end);
}

sub insert {
	my $cw = shift;
	my $pos = shift;
	##NOTE:  CAN'T CHECK FOR READONLY HERE B/C FILES ARE INITIALLY LOADED USING THIS.
	#        AND $cw->{READONLY} IS *NOT* ALWAYS INITIATED YET IF USING RO*text.pl MODULES!:

	$pos = $cw->index($pos);
	my $begin = $cw->linenumber("$pos - 1 chars");
	$cw->SUPER::insert($pos, @_);
	$cw->highlightCheck($begin, $cw->linenumber('insert lineend'));
	#WE'LL GO AHEAD AND INITIALIZE IT HERE IF NOT ALREADY (WILL ALREADY BE IF CALLED FROM $cw->Load())!
	$cw->{READONLY} = $readonly  unless (defined $cw->{READONLY});
}

sub Insert {
	my $cw = shift;
	return  if ($cw->{READONLY});

	$cw->beginUndoBlock;
	$cw->SUPER::Insert(@_);
	$cw->endUndoBlock;
	$cw->see('insert');
}

sub InsertKeypress {
	my ($cw,$char) = @_;
	return  if ($cw->{READONLY});

	if ($char ne '') {
		my $index = $cw->index('insert');
		my $line = $cw->linenumber($index);
		if ($char =~ /^\S$/o and !$cw->OverstrikeMode and !$cw->tagRanges('sel')) {
			my $undo_item = $cw->getUndoAtIndex(-1);
			if (defined($undo_item) &&
					($undo_item->[0] eq 'delete') &&
					($undo_item->[2] == $index))
			{
				$cw->Tk::Text::insert($index,$char);
				$undo_item->[2] = $cw->index('insert');
				$cw->highlightCheck($line, $line);
				$cw->see('insert');  #ADDED 20060703 TO ALLOW USER TO SEE WHAT HE'S TYPING PAST END OF LINE (THIS IS BROKEN IN TEXTUNDO TOO).
				return;
			}
		}
		$cw->addGlobStart;

lib/Tk/TextHighlight.pm  view on Meta::CPAN


If L<Syntax::Highlight::Engine::Kate> is installed, you may specify any 
language that the B<Kate> syntax highlight engine supports.

Alternatively it is possible to specify a reference to your independent plugin. 

=item Name: B<syntax>

=item Class: B<Syntax>

=item Switch: B<-syntaxcomments>

Boolean, when set to I<true>, the I<-commentchar> will be set (overridden) 
to the comment string for the specific language (I<-syntax>) for certain 
supported languages (C, C++, CSS, HTML, Modula-II, Pascal, Perl, and XML).

Default:  B<false> (use the preset string in B<-commentchar>.

=item Name: Not available

=item Class: Not available

=item Switch: B<-updatecall>

Here you can specify a callback that will be executed whenever the insert 
cursor has moved or text has been modified, so your application can keep 
track of position etc. Don't make this callback to heavy, the widget will 
get sluggish quickly!

Default:  none (B<sub {}>)

=back

=head1 METHODS

=over 4

=item B<addKate2ViewMenu(I<sections>)>

Inserts the list of B<Kate>-supported languages to the widget's Syntax.  View 
right-mousebutton popup menu along with the basic TextHight-supported choices. 
These choices can then be selected to change the current language-highlighting 
used in the text in the widget.  B<sections> is a hash-ref normally returned 
as the 1st item in the list returned by B<fetchKateInfo>.  NOTE:  No menu 
items will be added if B<Kate> is not installed or if B<-noRulesMenu> or 
B<-noSyntaxMenu> are set!

=item B<Backspace()>

Mostly for internal use - Handles user-pressing of the [backspace] key so that 
it's not passed down to the underlying *Text* widgets.  This is so we can have 
consistant behavior regardless of which one us chosen/loaded.

=item B<beginUndoBlock>

Used in application programs when wishing to group together a series of edits 
that, in the event of a call to B<Undo()> should be undone together as a 
group.  This method should be called before the first insertion or deletion.  
See also B<endUndoBlock>.

=item B<clipboardCopy>

Copies any selected text to the system's CLIPBOARD paste-buffer.

Default bindings:  B<Control-c>.

=item B<clipboardCut>

Default bindings:  B<Control-x>.

Deletes the selected text from the widget and puts it in the system's 
CLIPBOARD paste-buffer.

=item B<clipboardPaste>

Pastes the content of the system's CLIPBOARD paste-buffer at the current 
cursor position and selects it.

Default bindings:  B<Control-v>.

=item B<delete(I<index1, ?index2?>)>

Delete a range of characters from the text. If both index1 and index2 are 
specified, then delete all the characters starting with the one given by 
index1 and stopping just before index2 (i.e. the character at index2 is not 
deleted).  If index2 doesn't specify a position later in the text than index1 
then no characters are deleted. If index2 isn't specified then the single 
character at index1 is deleted. It is not allowable to delete characters in a 
way that would leave the text without a newline as the last character. The 
command returns an empty string. If more indices are given, multiple ranges of 
text will be deleted. All indices are first checked for validity before any 
deletions are made. They are sorted and the text is removed from the last 
range to the first range to deleted text does not cause a undesired index 
shifting side-effects. If multiple ranges with the same start index are given, 
then the longest range is used. If overlapping ranges are given, then they 
will be merged into spans that do not cause deletion of text outside the 
given ranges due to text shifted during deletion.

=item B<doAutoIndent(I<boolean>)>

Checks the indention of the previous line and indents the line where the 
cursor is equally deep.  If a <true> value is passed in, and I<-autoindent> 
is set to I<true>.  Otherwise, I<false> will cause no indentation to be added 
when pressing the I<Return> key.  Note if both I<-autoindent> and 
I<-smartindent> are set to I<true> values, indentation will also be affected 
by the indentation of the next line, and whether the current line ends with 
an opening brace character or the next line begins with an opening brace 
character, causing indentation to be more typical to that used in computer 
source code.  I<-smartindent> is ignored if I<-autoindent> is false.

Default bindings:  B<Return key>:  doAutoIndent(I<true>), B<Shift-Return>:  
doAutoIndent(I<false>)

=item B<EmptyDocument()>

Resets the widget to an empty state (ie. $w->delete('0.0', 'end'), except is 
actionable even if the widget is readonly!

=item B<extendSelect()>

Selects text between the insert cursor to the current mouse position when 
pressed, then adjusted again if the mouse is released in a different place 
than when pressed.  The insert cursor should remain in it's current location 
(like a pivot point).

Default bindings:  B<Shift-ButtonPress-3>, and B<ButtonPress-3> if the 
I<-noPopupMenu> option is set to I<true>.

=item B<endUndoBlock()>

Used in application programs when wishing to group together a series of edits 
that, in the event of a call to B<Undo()> should be undone together as a 
group.  This method should be called after the last insertion or deletion.  
See also B<beginUndoBlock>.



( run in 3.089 seconds using v1.01-cache-2.11-cpan-84e82930d8c )