Tk-TextVi
view release on metacpan or search on metacpan
lib/Tk/TextVi.pm view on Meta::CPAN
# Get the next character in the sequence
my $c = substr $sequence, 0, 1, '';
# Advance the mapping locations
for my $map ( @mapmodes ) {
# Nothing at this location yet, add a hash
if( not defined $map->{$c} ) {
$map->{$c} = { };
}
# Something is already mapped here
elsif( 'HASH' ne ref $map->{$c} ) {
return unless $force;
# If $force was defined, nuke the previous entry
$map->{$c} = { };
}
$map = $map->{$c};
}
}
# Check that a mapping can be placed here
for my $map ( @mapmodes ) {
if( defined $map->{$sequence} and # Something is here
'HASH' eq ref $map->{$sequence} and # it's a longer mapping
scalar keys %{ $map->{$sequence}} ) # and its in use
{
return unless $force;
delete $map->{$sequence}; # wipe out existing maps
}
}
for my $map ( @mapmodes ) {
$map->{$sequence} = $ref;
}
# TODO: return the mappings that were replaced in a format that
# would permit them to be restored
return 1;
}
# 'Private' Methods ##################################################
# Store text in a register
#
# Caller is responsible for determining when text should also be
# written to the unnamed register or the small delete register at the
# moment (XXX: This should be handled here in the future)
sub registerStore {
my ( $w, $register, $text ) = @_;
# Registers are all single characters or unnamed
die X_BAD_STATE if length($register) > 1;
# Read-only registers and blackhole are never written to
return if $register =~ /[_:.%#0-9]/;
# Always store in the unnamed register
$w->{VI_REGISTER}{''} = $text;
# * is the clipboard
if( $register eq '*' ) {
$w->clipboardClear;
$w->clipboardAppend( '--', $text );
}
else {
if( $register =~ tr/A-Z/a-z/ ) {
$w->{VI_REGISTER}{$register} .= $text;
}
else {
$w->{VI_REGISTER}{$register} = $text;
}
}
}
# Fetch the contents of a register
sub registerGet {
my ( $w, $register ) = @_;
# Registers are single characters or unnamed
die X_BAD_STATE if length($register) > 1;
# Nothing comes out of a black hole
return '' if $register eq '_';
# TODO: other special registers
# Register contains nothing
return '' unless defined $w->{VI_REGISTER}{$register};
return $w->{VI_REGISTER}{$register};
}
sub setMessage {
my ($w,$msg) = @_;
push @{ $w->{VI_MESSAGE} }, $msg;
$w->{VI_FLAGS} |= F_MSG;
}
sub setError {
my ($w,$msg) = @_;
push @{ $w->{VI_ERROR} }, $msg;
$w->{VI_FLAGS} |= F_ERR;
}
sub settingGet {
my ($w,$key) = @_;
# TODO: decide what to do about widget-specific vs class settings
# possibly something like Vim's b: vs g:
$key = ${ $settings{$key} } if 'SCALAR' eq ref $settings{$key};
return $settings{$key}[0];
}
# Handle keyboard input
#
# Replaces method in Tk::Text
sub InsertKeypress {
my ($w,$key) = @_;
my $res;
lib/Tk/TextVi.pm view on Meta::CPAN
The split callback should return a new Tk::TextVi widget to the caller or a string to be used as an error message. The module will copy the contents and make sure all changes in the text are visible in both widgets.
=head2 WRITING COMMANDS
Perl subroutines can be mapped to keystrokes using the viMap() method described above. Normal and visual mode commands receive arguments like:
my ( $widget, $keys, $count, $register, $wantmotion ) = @_;
Where $widget is the Tk::TextVi object, $keys are any key presses entered after those that triggered the function. Unless you've raised X_NO_KEYS this should be an empty string. $count is the current count, zero if none has been set. $register con...
Commands receive arguments in the following format:
my ( $widget, $forced, $argument, $range ) = @_;
$forced is set to a true value if the command ended with an exclamation point. $argument is set to anything that comes after the command. $range is an array reference that contains any line numbers removed from the front of the command. The elemen...
To move the cursor a normal-mode command should return an array reference. The first parameter is a string representing the new character position in a format suitable to Tk::Text. The second is either 'line' or 'char' to specify line-wise or chara...
Scalar references will be treated as a sequence of keys to process. All other return values will be ignored, but avoid returning references (any future expansion will use leave plain scalar returns alone).
=head3 Exceptions
=over 4
=item X_NO_MOTION
If a true value is passed for $wantmotion and the function is not a motion command, die with this value.
=item X_NO_KEYS
Use when additional key presses are required to complete the command.
=item X_BAD_STATE
For when the command can't complete and panic is more appropriate than doing nothing.
=back
=head3 Methods
=over 4
=item $text->EvalKeys( $keys, $count, $register, $wantmotion )
Uses keys to determine the function to call passing it the count, register and wantmotion parameters specified. The return value will be whatever that function returns. If wantmotion is a true value the return value will always be an array referenc...
Normally you want to call this function like this, passing in the set of keystrokes after the command, the current count, the current register and setting wantmotion to true:
$w->EvalKeys( @_[1..3], 1 )
=item $text->setMessage( $msg )
Queue a message to be displayed and generate the associated event.
=item $text->setError( $msg )
Same as setMessage, but the message is added to the error list and the error message event is generated.
=item $text->registerStore( $register, $text )
Store the contents of $text into the specified register. The text will also be stored in the unnamed register. If the '*' register is specified, the clipboard will be used. If the black-hole or a read-only register is specified nothing will happen...
=item $text->registerGet( $register )
Returns the text stored in a register
=item $text->settingGet( $setting )
Returns the value of the specified setting.
=back
=head1 BUGS AND CAVEATS
If you find a bug in the handling of a vi-command, please try to produce an example that looks something like this:
$text->Contents( <<END );
Some
Initial
State
END
$text->InsertKeypress( $_ ) for split //, 'commands in error';
Along with the expected final state of the widget (contents, cursor location, register contents etc).
If the bug relates to the location of the cursor after the command, note the difference between Tk::Text cursor positions and vi cursor positions described above. The command may be correct, but the cursor location looks wrong due to this difference...
=head2 Known Bugs
=over 4
=item *
Using the mouse or $text->SetCursor you may illegally place the cursor after the last character in the line.
=item *
Similarly, movement with the mouse or arrow keys can cause problems when a the state of the widget depends on cursor location.
=item *
Counts are not implemented on insert commands like normal-i or normal-o.
=item *
Commands that use mappings internally (D and x) do not correctly use the count or registers.
=item *
Normal-/ should behave like a motion, but doesn't.
=item *
Normal-/ and normal-n will not wrap after hitting end of file.
=item *
Normal-u undoes individual Tk::Text actions rather than vi-commands.
=item *
( run in 1.927 second using v1.01-cache-2.11-cpan-84e82930d8c )