aboutsummaryrefslogtreecommitdiffstats
path: root/sb-position/sb_position.pl
blob: 5fb9654cdba869684b77ed4b4e2a7859a47a29e1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Display current position in scrollback in a statusbar item named 'position'.

# Copyright (C) 2010  Simon Ruderich & Tom Feist
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


use strict;
use warnings;

use Irssi;
use Irssi::TextUI;
use POSIX qw(ceil);

{ package Irssi::Nick }

our $VERSION = '0.1';
our %IRSSI = (
    authors     => 'Simon Ruderich, Tom Feist',
    contact     => 'simon@ruderich.org, shabble+irssi@metavore.org',
    name        => 'sb_position',
    description => 'Displays current position in scrollback.',
    license     => 'GPLv3 or later',
    changed     => '2010-12-02'
);

my ($buf, $size, $pos, $height, $empty);
my ($pages, $cur_page, $buf_pos_cache);


init();

sub init {

    # (re-)register it so we can access the WIN_REC object directly.
    Irssi::signal_register({'gui page scrolled' => [qw/Irssi::UI::Window/]});
    # primary update signal.
    Irssi::signal_add('gui page scrolled', \&update_position);
    Irssi::statusbar_item_register('position', 0, 'position_statusbar');

    Irssi::signal_add("window changed",          \&update_position);
    Irssi::signal_add_last("command clear",      \&update_cmd_shim);
    Irssi::signal_add_last("command scrollback", \&update_cmd_shim);
    # Irssi::signal_add_last("gui print text finished", sig_statusbar_more_updated);

    update_position(Irssi::active_win());
}

sub update_cmd_shim {
    my ($cmd, $server, $witem) = @_;
    return unless $witem;
    my $win = $witem->window;
    update_position($win);
}

sub update_position {

    my $win = shift;
    return unless $win;

    my $view = $win->view;

    $pos    = $view->{ypos};
    $buf    = $view->{buffer};
    $height = $view->{height};
    $size   = $buf->{lines_count};

    $empty  = $view->{empty_linecount};
    $empty  = 0 unless $empty;

    # $size -= $empty;

    $pages = ceil($size / $height);
    $pages = 1 unless $pages;

    $pos   = $pos < 0 ? 0 : $pos;

    $buf_pos_cache = $size - $pos + ($height - $empty) - 1;
    $cur_page      = ceil($buf_pos_cache / $height);

    Irssi::statusbar_items_redraw('position');
}

sub position_statusbar {
    my ($statusbar_item, $get_size_only) = @_;

    my $percent;
    if ($size < $height) {
        $percent = 100;
    } else {
        $percent = ceil($buf_pos_cache / $size * 100);
    }

    # Alternate view.
    #my $sb = "p=$pos, s=$size, h=$height, pp:$cur_page/$pages $percent%%";
    my $sb = "Page: $cur_page/$pages $percent%%";

    $statusbar_item->default_handler($get_size_only, "{sb $sb}", 0, 1);
}