diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/copy.pl | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/scripts/copy.pl b/scripts/copy.pl new file mode 100644 index 0000000..7b1e6e2 --- /dev/null +++ b/scripts/copy.pl @@ -0,0 +1,290 @@ +use strict; +use vars qw($VERSION %IRSSI); + +use Irssi; +use Irssi::UI; +use Irssi::TextUI; +use MIME::Base64; +use File::Glob qw/:bsd_glob/; + +$VERSION = '0.10'; +%IRSSI = ( + authors => 'vague,bw1', + contact => 'bw1@aol.at', + name => 'copy', + description => 'copy a line in a paste buffer', + license => 'Public Domain', + url => 'https://scripts.irssi.org/', + changed => '2020-09-26', + modules => 'MIME::Base64 File::Glob', + commands=> 'copy', +); + +my $help = << "END"; +%9Name%9 + $IRSSI{name} +%9Version%9 + $VERSION +%9Synopsis%9 + /copy [start [end]] + /copy <-f word> +%9Description%9 + $IRSSI{description} + + Tested with xterm, tmux, screen and ssh + see man xterm /disallowedWindowOps +%9Settings%9 + $IRSSI{name}_selection + c clipboard + p primary + q secondary + s select + 0-7 cut buffers + $IRSSI{name}_method + xterm + xclip + xsel + screen + print + file + $IRSSI{name}_file + filename for method 'file' + $IRSSI{name}_file_mode + open mode for method 'file' + $IRSSI{name}_file_eol + end of line string for method 'file' +%9See also%9 + https://www.freecodecamp.org/news/tmux-in-practice-integration-with-system-clipboard-bcd72c62ff7b/ + http://anti.teamidiot.de/static/nei/*/Code/urxvt/ + https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands +END + +# Thanks +# +# dive +# /tmp/screen-exchange +# nei +# http://anti.teamidiot.de/static/nei/*/Code/urxvt/ +# vague +# line buffer + +my ($copy_selection, $copy_method); +my ($copy_file, $copy_file_mode, $copy_file_eol); + + +sub cmd_copy { + my ($args, $server, $witem)=@_; + my ($opt, $arg) = Irssi::command_parse_options('copy', $args); + if (exists $opt->{f}) { + cmd_find($opt->{f}, $server, $witem); + } else { + cmd_num($args, $server, $witem); + } +} + +sub cmd_find { + my ($args, $server, $witem)=@_; + my $line=Irssi::active_win->view->{startline}; + my $str; + while ( defined $line ) { + my $s= $line->get_text(0); + if ( $s =~ /$args/ ) { + $str =$s; + last; + } + $line= $line->next(); + } + if (defined $str) { + paste ($str); + } +} + +sub cmd_num { + my ($args, $server, $witem)=@_; + my $line=Irssi::active_win->view->{buffer}{cur_line}; + unless (defined $line) { + Irssi::print('No Copy!', MSGLEVEL_CLIENTCRAP); + return(); + } + + my @arg = split /[\s-]/, $args; + if(@arg > 2 || grep {/[^\d]+/} @arg) { + Irssi::print('Illegal range!', MSGLEVEL_CLIENTCRAP); + return(); + } + + $arg[0] = 1 if ($arg[0]==0); + $arg[0] -= 1; + $arg[1] -= 1 if defined $arg[1]; + + for(1..$arg[0]) { + last unless $line->prev; + $line = $line->prev; + } + + my $str; + for($arg[0]..($arg[1] // $arg[0])) { + $str = join $copy_file_eol, $line->get_text(0), $str; + + last unless $line->prev; + $line = $line->prev; + } + paste ($str); +} + +sub paste { + my ($str)= @_; + if ( $copy_method eq 'xterm' ) { + paste_xterm($str, $copy_selection); + } elsif ( $copy_method eq 'xclip' ) { + paste_xclip($str, $copy_selection); + } elsif ( $copy_method eq 'xsel' ) { + paste_xsel($str, $copy_selection); + } elsif ( $copy_method eq 'screen' ) { + paste_screen($str, $copy_selection); + } elsif ( $copy_method eq 'print' ) { + paste_print($str, $copy_selection); + } elsif ( $copy_method eq 'file' ) { + paste_file($str, $copy_selection); + } +} + +sub paste_file { + my ($str, $par)= @_; + open my $fa, $copy_file_mode, $copy_file; + print $fa $str, $copy_file_eol; + close $fa; +} + +sub paste_print { + my ($str, $par)= @_; + Irssi::print($str, MSGLEVEL_CLIENTCRAP); +} + +sub paste_screen { + my ($str, $par)= @_; + my $fn= '/tmp/screen-exchange'; + open my $fa, ">", $fn; + print $fa $str; + close $fa; +} + +sub paste_xclip { + my ($str, $par)= @_; + my %ma= ( + 0=>'buffer-cut', + p=>'primary', + q=>'secondary', + c=>'clipboard', + ); + my $sel= $ma{substr($par,0,1)}; + if (defined $sel) { + $sel= "-selection $sel"; + } + my $cmd="xclip -i $sel"; + open my $fa, "|-", $cmd; + print $fa $str; + close $fa; +} + +sub paste_xsel { + my ($str, $par)= @_; + my %ma= ( + p=>'--primary', + q=>'--secondary', + c=>'--clipboard', + ); + my $sel= $ma{substr($par,0,1)}; + my $cmd="xsel -i $sel"; + open my $fa, "|-", $cmd; + print $fa $str; + close $fa; +} + +sub paste_xterm { + my ($str,$par)=@_; + my $b64=encode_base64($str,''); + #print STDERR "\033]52;cpqs01234;".$b64."\007"; + my $pstr="\033]52;".$par.";".$b64."\007"; + if ($ENV{TERM} =~ m/^xterm/) { + print STDERR $pstr; + } elsif ($ENV{TERM} eq 'screen') { + # tmux + if (defined $ENV{TMUX}) { + my $tc = `tmux list-clients`; + $ENV{TMUX} =~ m/,(\d+)$/; + my $tcn =$1; + my $pty; + foreach (split /\n/,$tc) { + $_ =~ m/^(.*?): (\d+)/; + if ($tcn == $2) { + $pty = $1; + last(); + } + } + my $fa; + open $fa,'>',$pty; + print $fa $pstr; + close $fa; + # screen + } elsif (defined $ENV{STY}) { + $ENV{STY} =~ m/\..*?-(\d+)\./; + my $pty = "/dev/pts/$1"; + my $fa; + open $fa,'>',$pty; + print $fa $pstr; + close $fa; + } + } +} + +sub cmd_help { + my ($args, $server, $witem)=@_; + $args=~ s/\s+//g; + if ($IRSSI{name} eq $args) { + Irssi::print($help, MSGLEVEL_CLIENTCRAP); + Irssi::signal_stop(); + } +} + +sub sig_setup_changed { + my $cs= Irssi::settings_get_str($IRSSI{name}.'_selection'); + if ($cs =~ m/^[cpqs0-7]*$/ ) { + $copy_selection=$cs; + } else { + $cs =~ s/[^cpqs0-7]//g; + $copy_selection=$cs; + Irssi::settings_set_str($IRSSI{name}.'_selection', $cs); + } + my $cm= Irssi::settings_get_str($IRSSI{name}.'_method'); + my %md=(xterm=>1, xclip=>1, xsel=>1, screen=>1, print=>1, file=>1 ); + if (exists $md{$cm} ) { + $copy_method= $cm; + } else { + $cm= $copy_method; + Irssi::settings_set_str($IRSSI{name}.'_method', $cm); + } + my $fn= Irssi::settings_get_str($IRSSI{name}.'_file'); + $copy_file= bsd_glob($fn); + my $fm= Irssi::settings_get_str($IRSSI{name}.'_file_mode'); + $copy_file_mode= $fm; + my $fe= Irssi::settings_get_str($IRSSI{name}.'_file_eol'); + $fe =~ s/\\n/\n/g; + $fe =~ s/\\t/\t/g; + $copy_file_eol= $fe; +} + +Irssi::signal_add('setup changed', \&sig_setup_changed); + +Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_selection', ''); +Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_method', 'xterm'); +Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_file', ''); +Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_file_mode', '>'); +Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_file_eol', '\n'); + +Irssi::command_bind($IRSSI{name}, \&cmd_copy); +Irssi::command_bind('help', \&cmd_help); + +Irssi::command_set_options('copy','+f'); + +sig_setup_changed(); |