html/reorder.pl
1 # Save window layout to an arbitrary file and load layouts upon demand
2 # Useful for being able to temporarily reorder your windows and then reverting to your "normal" layout
3 # Also useful as an easy way to reorder your windows
4 #
5 # A special thanks to billnye, Zed` and Bazerka for their help
6 #
7 # Usage:
8 # /layout_save filename
9 # Saves the layout to the textfile "filename.layout"
10 # /layout_load filename
11 # Loads the layout from the textfile "filename.layout"
12 # /set layout_savepath path
13 # Use to set a default path for layouts
14 #
15 # TODO:
16 # Check the layout file for a number used twice
17 #
18
19 use strict;
20 use Irssi;
21 use Data::Dumper;
22 use vars qw($VERSION %IRSSI);
23
24 %IRSSI = (
25 authors => "Isaac G",
26 contact => "irssi\@isaac.otherinbox.com",
27 name => "reorder",
28 description => "Reordering windows based on a textfile.",
29 license => "GPL",
30 );
31
32 sub doFilenameFixing
33 {
34 my ($filename) = @_;
35 unless ($filename)
36 {
37 print "No filename specified!";
38 return;
39 }
40
41 $filename = glob($filename);
42
43 if ($filename =~ /\//)
44 {
45 unless ($filename =~ /^\//)
46 {
47 print "I don't like /'s in filenames. Unless you want to specify an absolute path.";
48 return;
49 }
50 # Let it go?
51 }
52
53 $filename .= '.layout' unless ($filename =~ /.layout$/);
54
55 my $path = Irssi::settings_get_str('layout_savepath');
56 $path .= '/' unless ($path =~ /\/$/);
57 $filename = $path . $filename unless ($filename =~ /\//);
58
59 return $filename;
60 }
61
62 sub canReadFile
63 {
64 my ($filename) = @_;
65 unless (-f $filename)
66 {
67 print "No such file $filename";
68 return;
69 }
70 unless (-r $filename)
71 {
72 print "Can not read file $filename";
73 return;
74 }
75 return 1;
76 }
77
78 # Save a list of refnum and window info to file
79 sub cmd_layout_save
80 {
81 my ($filename, $data, $more) = @_;
82 my $FH;
83
84 $filename = doFilenameFixing($filename);
85 return unless ($filename);
86
87 unless(open $FH, ">", $filename)
88 {
89 print "Can not open $filename";
90 return;
91 }
92
93 # Order by ref. Print ref and an id tag
94 for my $win (sort {$a->{'refnum'} <=> $b->{'refnum'}} Irssi::windows())
95 {
96 my $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'} . ":" . $win->{'active'}->{'server'}->{'tag'};
97 printf $FH "%d\t%s\n", $win->{'refnum'}, $id;
98 }
99 close $FH;
100 print "Layout saved to $filename";
101 }
102
103 # Load a list and use it to reorder
104 sub cmd_layout_load
105 {
106 # Check filename supplied, exists and readable
107 my ($filename, $data, $more) = @_;
108 $filename = doFilenameFixing($filename);
109 return unless ($filename);
110
111 return unless canReadFile($filename);
112
113 my @layout;
114 my ($ref, $id, $FH);
115
116 # Pull the refnum and id
117 unless(open $FH, "<", $filename)
118 {
119 print "Can not open file $filename.";
120 return;
121 }
122 while (my $line = <$FH>)
123 {
124 chomp $line;
125 my ($ref, $id) = split(/\t/, $line, 2);
126 next unless ($ref and $id);
127
128 push @layout, {refnum => $ref, id => $id};
129 }
130 close $FH;
131
132 # For each layout item from the file, find the window and set it's ref to that number
133 for my $position (sort {$a->{'refnum'} <=> $b->{'refnum'}} @layout)
134 {
135 for my $win (Irssi::windows())
136 {
137 $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'} . ":" . $win->{'active'}->{'server'}->{'tag'};
138 if ($id eq $position->{'id'})
139 {
140 $win->set_refnum($position->{'refnum'});
141 last;
142 }
143 }
144 }
145 }
146
147 Irssi::settings_add_str('misc', 'layout_savepath', Irssi::get_irssi_dir());
148
149 Irssi::command_bind( 'layout_save', 'cmd_layout_save' );
150 Irssi::command_bind( 'layout_load', 'cmd_layout_load' );