Just to mention that for urxvt a perl plugin was already posted some
times ago¹. The sad thing is that it has no clue about the "semantic" of
the "last line".
For example you may not want to paste the last line if it's the
prompt. Neither you have the "context" of the output (the last command
entered).

I think that readline could be a good layer for that since it can easily
guess what was the entered and validated command and I guess that it
knows where the output ends and where the prompt and other things are..
(actually only the bash process parses the line and can consistently
say that in ...
$ x=y ls foo
... the actual command is "ls")
And the main uses of grabbing the last line come if we know what was the
command they come from (see the regexp in the attachment...)

The missing bit is probably a link between readline "lines" (and states)
and the terminal. The later could then provide
API/configuration/key-bindings to reuse the last
line-of-output-really-being-the-output-of-a-command.

Anyway I have no clue about the means by which, if possible, the
terminal could interact with readline or vice versa.


¹ http://lists.schmorp.de/pipermail/rxvt-unicode/2011q4/001494.html
  Enhanced version attached

On Wed, Jun 17, 2015 at 04:05:56AM -0700, Hrazel wrote:
> Now it would be nice just to log the last lines on stdout and walk it
> through line by line ready to be put to the clipboard.

This is a bit different since here you're intending to *walk* along the
(multiple) previous lines, not only splitting the last one.
Still in the urxvt case, you may want to take inspiration from the
url-select extension while assuming a set of word boundary characters.
#! perl

# Author:   Raphaël Droz
# Website:  http://gitorious.org/~drzraf
# Version:  0.1
# License:  GPLv2

# TODO
# use Term::ReadLine::Gnu;
use POSIX ();

sub on_user_command {
    my ($self, $cmd) = @_;

    if ($cmd eq "yank-return:true") {
        my ($row, $col) = $self->screen_cur;
        my $line = $self->ROW_t ($row - 1);

        # TODO: if (readline-previous-command-was-grep)
        #       and no newline
        #       and last line was not the prompt

        # bash: xxx command not found
        if ($line =~ /^bash:\s/) {
            $line =~ s/^bash:\s(.*?):\scommand not found\s*/$1/;
            $self->tt_write($line);
        }

        # ls -l (before "grep" because hours contain ":")
        elsif ($line =~ /^[ldp-][r-][w-][x-][r-][w-][x-][r-][w-][tx-]\s+/) {
            # $line =~ 
s/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+\S+\s+(.*?)\s+$/$1/;
            # (in ls -l), these two \d\d may be
            # the minutes or the two last digits of the year
            $line =~ s/^.*\d\d\s(.*?)\s+$/$1/;
            $self->tt_write($line);
        }

        # unzip
        elsif ($line =~ /^\s+inflating:/) {
            $line =~ s/^\s+inflating:\s+(.*?)\s+/$1/;
            $self->tt_write($line);
        }

        # dpkg -l
        elsif ($line =~ /^(ii|hi|rc)\s+/) {
            $line =~ s/^(ii|hi|rc)\s+(.*?)\s+.*/$1/;
            $self->tt_write($line);
        }

        elsif ($line =~ /:/) {
            my $login = getlogin;
            # prompt: return prev path
            if($line =~ /^$login@.*\$\s+$/) {
                $line =~ s/^.*?:(.*?)\s[\$#].*$/$1/;
                $self->tt_write($line);
            }

            # grep
            else {
                # TODO: custom regexp
                $line =~ s/^([^:\s]+):.*$/$1/;
                $self->tt_write($line);
            }
        }

        # wget
        elsif ($line =~ /^\s+$/) {
            my $pline = $self->ROW_t ($row - 2);
            $pline =~ s/^.*«(.*?)» sauvegardé \[.*$/$1/;
            $pline =~ s/^.*'(.*?)' saved \[.*$/$1/;
            $pline =~ s/^.*`(.*?)' saved \[.*$/$1/;
            $self->tt_write($pline);
        }

        # any other
        else {
            $line =~ s/\s+$//;
            $self->tt_write($line);
        }
    }
    
    ()
}

Reply via email to