home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
- #
- # euc_jp.pm : EUC Japanese Character Support Functions
- # This modules is experimental. API may be changed.
- #
- # $Id: euc_jp.pm,v 1.2 2001-04-22 22:35:41+09 hayashi Exp $
- #
- # Copyright (c) 2001 Hiroo Hayashi. All rights reserved.
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the same terms as Perl itself.
- #
-
- package Term::ReadLine::Gnu::XS;
-
- use Carp;
- use strict;
-
- # make aliases
- use vars qw(%Attribs);
- *Attribs = \%Term::ReadLine::Gnu::Attribs;
-
- # enable Meta
- rl_prep_terminal(1);
-
- rl_add_defun('euc-jp-forward', \&ej_forward);
- rl_add_defun('euc-jp-backward', \&ej_backward);
- rl_add_defun('euc-jp-backward-delete-char', \&ej_rubout);
- rl_add_defun('euc-jp-delete-char', \&ej_delete);
- rl_add_defun('euc-jp-forward-backward-delete-char', \&ej_rubout_or_delete);
- rl_add_defun('euc-jp-transpose-chars', \&ej_transpose_chars);
-
- rl_bind_key(ord "\cf", 'euc-jp-forward');
- rl_bind_key(ord "\cb", 'euc-jp-backward');
- rl_bind_key(ord "\ch", 'euc-jp-backward-delete-char');
- #rl_bind_key(ord "\cd", 'euc-jp-delete-char');
- rl_bind_key(ord "\cd", 'euc-jp-forward-backward-delete-char');
- rl_bind_key(ord "\ct", 'euc-jp-transpose-chars');
-
- 1;
-
- # An EUC Japanese character consists of two 8 bit characters.
- # And the MSBs (most significant bit) of both bytes are set.
-
- # To support Shift-JIS charactor set the following two functions
- # must be extended.
- sub ej_first_byte_p {
- my ($p) = @_;
- my $l = $Attribs{line_buffer};
- return substr($l, $p, 1) =~ /[\x80-\xff]/
- && substr($l, 0, $p) =~ /^([\x00-x7f]|([\x80-\xff][\x80-\xff]))*$/;
- }
-
- sub ej_second_byte_p {
- my ($p) = @_;
- my $l = $Attribs{line_buffer};
- return $p > 0 && substr($l, $p, 1) =~ /[\x80-\xff]/
- && substr($l, 0, $p) !~ /^([\x00-x7f]|([\x80-\xff][\x80-\xff]))*$/;
- }
-
- #forward-char
- sub ej_forward {
- my($count, $key) = @_;
- if ($count < 0) {
- ej_backward(-$count, $key);
- } else {
- while ($count--) {
- if (ej_first_byte_p($Attribs{point})) {
- rl_call_function('forward-char', 2, $key);
- } else {
- rl_call_function('forward-char', 1, $key);
- }
- }
- }
- return 0;
- }
-
- #backward-char
- sub ej_backward {
- my($count, $key) = @_;
- if ($count < 0) {
- ej_forward(-$count, $key);
- } else {
- while ($count--) {
- if (ej_second_byte_p($Attribs{point})) {
- rl_call_function('backward-char', 1, $key);
- }
- if (ej_second_byte_p($Attribs{point} - 1)) {
- rl_call_function('backward-char', 2, $key);
- } else {
- rl_call_function('backward-char', 1, $key);
- }
- }
- }
- return 0;
- }
-
- #backward-delete-char
- sub ej_rubout {
- my($count, $key) = @_;
- if ($count < 0) {
- ej_delete(-$count, $key);
- } else {
- if ($Attribs{point} <= 0) {
- rl_ding();
- return 1;
- }
- while ($count--) {
- if (ej_second_byte_p($Attribs{point})) {
- $Attribs{point}--;
- }
- if (ej_second_byte_p($Attribs{point} - 1)) {
- rl_call_function('backward-delete-char', 2, $key);
- } else {
- rl_call_function('backward-delete-char', 1, $key);
- }
- }
- }
- return 0;
- }
-
- #delete-char
- sub ej_delete {
- my($count, $key) = @_;
- if ($count < 0) {
- ej_rubout(-$count, $key);
- } else {
- while ($count--) {
- if (ej_first_byte_p($Attribs{point})) {
- rl_call_function('delete-char', 2, $key);
- } elsif (ej_second_byte_p($Attribs{point})) {
- rl_call_function('backward-delete-char', 1, $key);
- rl_call_function('delete-char', 1, $key);
- } else {
- rl_call_function('delete-char', 1, $key);
- }
- }
- }
- return 0;
- }
-
- #forward-backward-delete-char
- sub ej_rubout_or_delete {
- my($count, $key) = @_;
- if ($Attribs{end} != 0 && $Attribs{point} == $Attribs{end}) {
- return ej_rubout($count, $key);
- } else {
- return ej_delete($count, $key);
- }
- }
-
- #transpose-chars
- sub ej_transpose_chars {
- my($count, $key) = @_;
-
- return 0 unless $count;
-
- if (ej_second_byte_p($Attribs{point})) {
- $Attribs{point}--;
- }
- if ($Attribs{point} == 0 # the beginning of the line
- || ($Attribs{end} < 2) # only one ascii char
- # only one EUC char
- || ($Attribs{end} == 2 && ej_first_byte_p(0))) {
- rl_ding();
- return -1;
- }
- rl_begin_undo_group();
- if ($Attribs{point} == $Attribs{end}) {
- # If point is at the end of the line
- ej_backward(1, $key);
- $count = 1;
- }
- ej_backward(1, $key);
- my $dummy;
- if (ej_first_byte_p($Attribs{point})) {
- $dummy = substr($Attribs{line_buffer}, $Attribs{point}, 2);
- rl_delete_text($Attribs{point}, $Attribs{point} + 2);
- } else {
- $dummy = substr($Attribs{line_buffer}, $Attribs{point}, 1);
- rl_delete_text($Attribs{point}, $Attribs{point} + 1);
- }
- ej_forward($count, $key);
- rl_insert_text($dummy);
- rl_end_undo_group();
- return 0;
- }
-