Skip to content

Instantly share code, notes, and snippets.

@wakaba
Created June 25, 2012 02:30
Show Gist options
  • Save wakaba/2986084 to your computer and use it in GitHub Desktop.
Save wakaba/2986084 to your computer and use it in GitHub Desktop.

NAME

screenlist - List of screens

INSTALL

Add following lines to ~/.bashrc:

perl ~/screenlist/add.pl
alias s="perl ~/screenlist/run.pl"

USAGE

$ s
2012/06/25 11:27   A   1822.pts-2.debian          #1   ~/apps/wakabatan
2012/06/25 11:35   A   2399.pts-6.debian          #0   ~/apps/nano2
Number:

Input the number (e.g. "1").

AUTHOR

Wakaba <wakabatan@hatena.ne.jp>.

LICENSE

Copyright 2009-2012 Hatena <http://www.hatena.com/>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

#!/usr/bin/perl
use strict;
BEGIN {
my $file_name = __FILE__;
$file_name =~ s{[^/]+$}{};
$file_name ||= '.';
$file_name .= '/../config/perl/libs.txt';
open my $file, '<', $file_name or die "$0: $file_name: $!";
unshift @INC, split /:/, scalar <$file>;
}
use warnings;
use Path::Class;
my $sty = $ENV{STY} or die "$0: Not in a screen\n";
require(file(__FILE__)->dir->file('common.pl')->stringify);
our $SCREENS;
use Cwd;
$SCREENS->{$sty}->{cwd} = getcwd;
$SCREENS->{$sty}->{time} = time;
save_screens_file();
use Path::Class;
our $SCREENS_FILE_NAME = file(__FILE__)->dir->file('screens.dat');
our $SCREENS = {};
if (-f $SCREENS_FILE_NAME) {
open my $screens_file, '<:encoding(utf8)', $SCREENS_FILE_NAME
or die "$0: $SCREENS_FILE_NAME: $!";
while (<$screens_file>) {
chomp;
my ($sty, $cwd, $time) = split /\t/, $_;
$SCREENS->{$sty}->{cwd} = $cwd;
$SCREENS->{$sty}->{time} = $time;
}
}
sub save_screens_file () {
open my $screens_file, '>:encoding(utf8)', $SCREENS_FILE_NAME
or die "$0: $SCREENS_FILE_NAME: $!";
print $screens_file join '', map { (join "\t", $_, $SCREENS->{$_}->{cwd}, $SCREENS->{$_}->{time}) . "\n" } keys %$SCREENS;
}
1;
#!/usr/bin/perl
use strict;
BEGIN {
my $file_name = __FILE__;
$file_name =~ s{[^/]+$}{};
$file_name ||= '.';
$file_name .= '/../config/perl/libs.txt';
open my $file, '<', $file_name or die "$0: $file_name: $!";
unshift @INC, split /:/, scalar <$file>;
}
use warnings;
use Path::Class;
if ($ENV{STY}) {
warn "Current screen: $ENV{STY}\n";
exit;
}
require(file(__FILE__)->dir->file('common.pl')->stringify);
our $SCREENS;
sub convert_path ($) {
my $p = shift;
return '?' unless defined $p;
$p = file($p)->relative($ENV{HOME});
if ($p =~ m[^(?:/|\.\.?/)]) {
return $p;
} else {
return '~/' . $p;
}
}
sub convert_time ($) {
my $time = shift || 0;
my @lt = localtime $time;
return sprintf '%04d/%02d/%02d %02d:%02d', $lt[5] + 1900, $lt[4] + 1, $lt[3], $lt[2], $lt[1];
}
sub convert_status ($) {
my $status = shift || '';
return {
Attached => 'A',
Detached => 'D',
}->{$status} || $status;
}
sub print_s ($$) {
my ($n, $s) = @_;
my $n_sp = $n - length $s;
print $s;
print ' ' x $n_sp if $n_sp > 0;
}
my $avail_screens = [];
for (split /\n/, `screen -list`) {
if (/^\s+(\S+)\s+(?:\(([^()]+)\)\s+)?\((Attached|Detached)\)/) {
my $sty = $1;
my $status = $3;
push @$avail_screens, {sty => $sty, status => $status, cwd => $SCREENS->{$sty}->{cwd}, time => $SCREENS->{$sty}->{time}};
}
}
{
no warnings 'uninitialized';
$avail_screens = [sort { $a->{time} cmp $b->{time} } @$avail_screens];
}
my $id = $#$avail_screens;
for my $screen (@$avail_screens) {
print_s 17 + 2, convert_time($screen->{time});
print_s 2 + 2, convert_status($screen->{status});
print_s 25 + 2, $screen->{sty};
print_s 3 + 2, '#' . $id;
print convert_path($screen->{cwd});
print "\n";
$id--;
}
{
print 'Number: ';
my $num = <STDIN>;
chomp $num;
if ($num =~ /^\d+$/ and $num < @$avail_screens) {
my @cmd = ('screen', '-d', '-r', $avail_screens->[$#$avail_screens - $num]->{sty});
warn join ' ', @cmd, "\n";
exec @cmd;
} elsif ($num =~ /^\s*(?:q|quit|exit)\s*$/i) {
exit;
} else {
redo;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment