File: quotelastmsg.tcl

package info (click to toggle)
tkabber-plugins 1.1.2%2B20170328-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 5,392 kB
  • sloc: tcl: 27,289; xml: 2,313; makefile: 83; sh: 21
file content (136 lines) | stat: -rw-r--r-- 3,997 bytes parent folder | download | duplicates (4)
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# quotelastmsg.tcl --
#
#       "Quote last message" chat plugin for Tkabber.
#       Allows to copy message located at the bottom of the
#       conversation log in the chat window to the input box
#       of that chat window.
#
# Author: Konstantin Khomoutov <flatworm@users.sourceforge.net>
#
# See license.terms for the terms of distribution.
# See README for usage details.

package require msgcat

namespace eval quotelastmsg {
    variable state
    variable options

    ::msgcat::mcload [file join [file dirname [info script]] msgs]

    variable desc [::msgcat::mc \
            "This plugin provides a way to copy a message located\
            at the bottom of a chat window conversation log\
            to the input box of that chat window."]

    if {![::plugins::is_registered quotelastmsg]} {
        ::plugins::register quotelastmsg \
            -namespace [namespace current] \
            -source [info script] \
            -description [::msgcat::mc \
                "Whether the last message quoting plugin is loaded."]\n$desc \
            -loadcommand [namespace code load] \
            -unloadcommand [namespace code unload]
        return
    }

    custom::defgroup Plugins [::msgcat::mc "Plugins options."] -group Tkabber

    custom::defgroup {Quote Last Message} \
        [::msgcat::mc "Quote Last Message plugin options."]\ $desc \
        -group Plugins \
        -group Chat

    custom::defvar options(format) {>> %m} \
        [::msgcat::mc "Format string used to quote the message.\
            Format specifer \"%m\" is replaced by the whole message\
            being quoted. Format specifier \"%%\" is replaced by\
            a single character \"%\"."] \
        -group {Quote Last Message} \
        -type string

}

proc quotelastmsg::load {} {
    hook::add open_chat_post_hook [namespace current]::prepare_chat_window
    hook::add close_chat_post_hook [namespace current]::cleanup_state
    hook::add draw_message_post_hook [namespace current]::on_message_drawn

    event add <<QuoteLastMessage>> <Alt-q>
    event add <<QuoteLastMessage>> <Meta-q>

    foreach chatid [chat::opened] {
        prepare_chat_window $chatid ?
    }
}

proc quotelastmsg::unload {} {
    foreach chatid [chat::opened] {
        unprepare_chat_window $chatid
    }

    event delete <<QuoteLastMessage>> <Alt-q>
    event delete <<QuoteLastMessage>> <Meta-q>

    hook::remove open_chat_post_hook [namespace current]::prepare_chat_window
    hook::remove close_chat_post_hook [namespace current]::cleanup_state
    hook::remove draw_message_post_hook [namespace current]::on_message_drawn
}

proc quotelastmsg::prepare_chat_window {chatid type} {
    set iw [::chat::input_win $chatid]
    set cw [::chat::chat_win $chatid]
    bind $iw <<QuoteLastMessage>> \
         [list [namespace current]::quote [double% $chatid]]

    variable state
    set state($chatid,last) [$cw index {end - 1 char}]
}

proc quotelastmsg::unprepare_chat_window {chatid} {
    set iw [::chat::input_win $chatid]
    bind $iw <<QuoteLastMessage>> {}

    set cw [::chat::chat_win $chatid]
    $cw tag delete lastmsg

    cleanup_state $chatid
}

proc quotelastmsg::cleanup_state {chatid} {
    variable state
    unset state($chatid,last)
}

proc quotelastmsg::on_message_drawn {chatid from type body x} {
    if {![chat::is_opened $chatid]} return


    variable state
    upvar 0 state($chatid,last) last

    set cw [::chat::chat_win $chatid]
    set now [$cw index {end - 1 char}]
    if {[$cw compare $last < $now]} {
        $cw tag delete lastmsg
        $cw tag add lastmsg $last $now
    }

    set last $now
}

proc quotelastmsg::quote {chatid} {
    variable options

    set cw [::chat::chat_win $chatid]
    set iw [::chat::input_win $chatid]

    set range [$cw tag prevrange lastmsg end]
    if {$range == ""} return
    lassign $range x y
    $iw insert end [string map \
        [list %% % %m [$cw get $x $y]] $options(format)]
    $iw see end
}

# vim:ts=8:sw=4:sts=4:et