summaryrefslogtreecommitdiffstats
path: root/scripts/copy.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/copy.pl')
-rw-r--r--scripts/copy.pl290
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();