weechat 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS.md +11 -0
- data/COPYING +674 -0
- data/ChangeLog +0 -0
- data/README.md +296 -0
- data/Rakefile +55 -0
- data/TODO +188 -0
- data/lib/weechat.rb +229 -0
- data/lib/weechat/blankslate.rb +13 -0
- data/lib/weechat/buffer.rb +559 -0
- data/lib/weechat/callback.rb +11 -0
- data/lib/weechat/color.rb +41 -0
- data/lib/weechat/command.rb +66 -0
- data/lib/weechat/exceptions.rb +31 -0
- data/lib/weechat/hook.rb +93 -0
- data/lib/weechat/hooks.rb +8 -0
- data/lib/weechat/hooks/command_run.rb +30 -0
- data/lib/weechat/hooks/config.rb +11 -0
- data/lib/weechat/hooks/print.rb +14 -0
- data/lib/weechat/info.rb +14 -0
- data/lib/weechat/infolist.rb +32 -0
- data/lib/weechat/input.rb +45 -0
- data/lib/weechat/line.rb +60 -0
- data/lib/weechat/modifier.rb +24 -0
- data/lib/weechat/option.rb +46 -0
- data/lib/weechat/plugin.rb +106 -0
- data/lib/weechat/pointer.rb +28 -0
- data/lib/weechat/process.rb +32 -0
- data/lib/weechat/properties.rb +312 -0
- data/lib/weechat/property.rb +47 -0
- data/lib/weechat/rubyext/array.rb +22 -0
- data/lib/weechat/rubyext/boolean.rb +17 -0
- data/lib/weechat/rubyext/float.rb +9 -0
- data/lib/weechat/rubyext/integer.rb +9 -0
- data/lib/weechat/rubyext/object.rb +10 -0
- data/lib/weechat/rubyext/string.rb +142 -0
- data/lib/weechat/script.rb +85 -0
- data/lib/weechat/script/config.rb +146 -0
- data/lib/weechat/server.rb +137 -0
- data/lib/weechat/terminal.rb +8 -0
- data/lib/weechat/timer.rb +56 -0
- data/lib/weechat/utilities.rb +47 -0
- data/lib/weechat/window.rb +103 -0
- metadata +96 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module Weechat
|
2
|
+
class Property < Blankslate
|
3
|
+
@properties = [] # we can't use a Hash because hashing
|
4
|
+
# blankslate... breaks things
|
5
|
+
|
6
|
+
|
7
|
+
def self.properties
|
8
|
+
@properties
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(weechat_obj, property)
|
12
|
+
self.__class__.properties << [weechat_obj.ptr, property, self]
|
13
|
+
@old_obj = weechat_obj.__get_property(property)
|
14
|
+
@weechat_obj = weechat_obj
|
15
|
+
@property = property
|
16
|
+
@settable = weechat_obj.settable_property?(property)
|
17
|
+
@frozen = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def __freeze__
|
21
|
+
@frozen = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(m, *args, &block)
|
25
|
+
if @frozen
|
26
|
+
obj = @old_obj
|
27
|
+
else
|
28
|
+
obj = @weechat_obj.__get_property(@property)
|
29
|
+
end
|
30
|
+
ret = obj.__send__(m, *args, &block)
|
31
|
+
|
32
|
+
if (@old_obj != obj) && @settable && !@frozen
|
33
|
+
@weechat_obj.set_property(@property, obj)
|
34
|
+
end
|
35
|
+
|
36
|
+
unless @frozen
|
37
|
+
begin
|
38
|
+
@old_obj = obj.dup
|
39
|
+
rescue TypeError
|
40
|
+
@old_obj = obj
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
ret
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Array
|
2
|
+
def self.from_weechat_config(v)
|
3
|
+
v.escaped_split(",")
|
4
|
+
end
|
5
|
+
|
6
|
+
def to_weechat_config
|
7
|
+
map {|entry|
|
8
|
+
case entry
|
9
|
+
when String
|
10
|
+
entry.gsub(/(\\+)?,/) {|m|
|
11
|
+
if $1.nil?
|
12
|
+
"\\,"
|
13
|
+
else
|
14
|
+
$1 + $1 + "\\,"
|
15
|
+
end
|
16
|
+
}
|
17
|
+
else
|
18
|
+
entry.to_weechat_config
|
19
|
+
end
|
20
|
+
}.join(",")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Boolean
|
2
|
+
def self.from_weechat_config(v)
|
3
|
+
Weechat.integer_to_bool(Weechat.config_string_to_boolean(v))
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class TrueClass
|
8
|
+
def to_weechat_config
|
9
|
+
"on"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class FalseClass
|
14
|
+
def to_weechat_config
|
15
|
+
"off"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
class String
|
2
|
+
def self.from_weechat_config(v)
|
3
|
+
v
|
4
|
+
end
|
5
|
+
|
6
|
+
def to_weechat_config
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
# Checks if the string represents a valid channel name
|
11
|
+
#
|
12
|
+
# @return [Boolean]
|
13
|
+
def channel?
|
14
|
+
Weechat.info_get("irc_is_channel", self) == '1' ? true : false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the nick part of a banmask
|
18
|
+
#
|
19
|
+
# @return [String] The nick
|
20
|
+
def nick
|
21
|
+
Weechat.info_get("irc_nick_from_host", self)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Removes or replaces all color codes
|
25
|
+
#
|
26
|
+
# @param [String] replacement The replacement string for color codes
|
27
|
+
# @return [String] A new string without color codes
|
28
|
+
def remove_color(replacement='')
|
29
|
+
Weechat.string_remove_color(self, replacement)
|
30
|
+
end
|
31
|
+
alias_method :remove_colors, :remove_color
|
32
|
+
alias_method :strip_colors, :remove_color
|
33
|
+
|
34
|
+
# Same as {#remove_color} but changing the string in place.
|
35
|
+
#
|
36
|
+
# @param (see String#remove_color)
|
37
|
+
# @return [String] self
|
38
|
+
def remove_color!(replacement='')
|
39
|
+
self.replace(remove_color(replacement))
|
40
|
+
end
|
41
|
+
alias_method :remove_colors!, :remove_color!
|
42
|
+
alias_method :strip_colors!, :remove_color!
|
43
|
+
|
44
|
+
def escaped_split(split_char, escape_char = "\\")
|
45
|
+
parts = []
|
46
|
+
escaping = false
|
47
|
+
cur = ""
|
48
|
+
|
49
|
+
self.split('').each do |char|
|
50
|
+
if char == escape_char
|
51
|
+
if escaping
|
52
|
+
cur << char
|
53
|
+
escaping = false
|
54
|
+
else
|
55
|
+
escaping = true
|
56
|
+
end
|
57
|
+
elsif char == split_char
|
58
|
+
if !escaping
|
59
|
+
parts << cur
|
60
|
+
cur = ""
|
61
|
+
else
|
62
|
+
cur << char
|
63
|
+
escaping = false
|
64
|
+
end
|
65
|
+
else
|
66
|
+
if escaping
|
67
|
+
cur << escape_char
|
68
|
+
escaping = false
|
69
|
+
end
|
70
|
+
cur << char
|
71
|
+
end
|
72
|
+
end
|
73
|
+
parts << cur
|
74
|
+
if parts.size == 1 && parts[0].empty?
|
75
|
+
[]
|
76
|
+
else
|
77
|
+
parts
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @author Loren Segal
|
82
|
+
def shell_split
|
83
|
+
out = [""]
|
84
|
+
state = :none
|
85
|
+
escape_next = false
|
86
|
+
quote = ""
|
87
|
+
strip.split(//).each do |char|
|
88
|
+
case state
|
89
|
+
when :none, :space
|
90
|
+
case char
|
91
|
+
when /\s/
|
92
|
+
out << "" unless state == :space
|
93
|
+
state = :space
|
94
|
+
escape_next = false
|
95
|
+
when "\\"
|
96
|
+
if escape_next
|
97
|
+
out.last << char
|
98
|
+
escape_next = false
|
99
|
+
else
|
100
|
+
escape_next = true
|
101
|
+
end
|
102
|
+
when '"', "'"
|
103
|
+
if escape_next
|
104
|
+
out.last << char
|
105
|
+
escape_next = false
|
106
|
+
else
|
107
|
+
state = char
|
108
|
+
quote = ""
|
109
|
+
end
|
110
|
+
else
|
111
|
+
state = :none
|
112
|
+
out.last << char
|
113
|
+
escape_next = false
|
114
|
+
end
|
115
|
+
when '"', "'"
|
116
|
+
case char
|
117
|
+
when '"', "'"
|
118
|
+
if escape_next
|
119
|
+
quote << char
|
120
|
+
escape_next = false
|
121
|
+
elsif char == state
|
122
|
+
out.last << quote
|
123
|
+
state = :none
|
124
|
+
else
|
125
|
+
quote << char
|
126
|
+
end
|
127
|
+
when '\\'
|
128
|
+
if escape_next
|
129
|
+
quote << char
|
130
|
+
escape_next = false
|
131
|
+
else
|
132
|
+
escape_next = true
|
133
|
+
end
|
134
|
+
else
|
135
|
+
quote << char
|
136
|
+
escape_next = false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
out
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Weechat
|
2
|
+
class Script
|
3
|
+
module Skeleton
|
4
|
+
def self.included(other)
|
5
|
+
other.__send__ :include, InstanceMethods
|
6
|
+
other.__send__ :extend, InstanceMethods
|
7
|
+
other.__send__ :extend, ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def script
|
12
|
+
{
|
13
|
+
:license => 'unlicensed',
|
14
|
+
:version => '0.0.1',
|
15
|
+
:author => 'Anonymous',
|
16
|
+
:description => 'Empty script description',
|
17
|
+
:charset => '',
|
18
|
+
:gem_version => '0.0.1',
|
19
|
+
}.merge(@script)
|
20
|
+
end
|
21
|
+
|
22
|
+
def config
|
23
|
+
@config || Weechat::Script::Config.new({})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module InstanceMethods
|
28
|
+
def weechat_init
|
29
|
+
if (self.script[:gem_version].split('.') <=> Weechat::VERSION.split('.')) > 0
|
30
|
+
Weechat.puts "This script ('#{self.script[:name]}') "\
|
31
|
+
"requires a version of the weechat ruby gem of at least #{self.script[:gem_version]}. "\
|
32
|
+
"You are currently using the version #{Weechat::VERSION}"
|
33
|
+
return Weechat::WEECHAT_RC_ERROR
|
34
|
+
end
|
35
|
+
|
36
|
+
ret = Weechat.register(self.script[:name],
|
37
|
+
self.script[:author],
|
38
|
+
self.script[:version],
|
39
|
+
self.script[:license],
|
40
|
+
self.script[:description],
|
41
|
+
'weechat_script_unload',
|
42
|
+
self.script[:charset])
|
43
|
+
if Weechat.integer_to_bool(ret)
|
44
|
+
self.config.set_script_name!(self.script[:name])
|
45
|
+
self.config.init!
|
46
|
+
if respond_to?(:setup)
|
47
|
+
return Weechat::Utilities.evaluate_call { setup }
|
48
|
+
end
|
49
|
+
|
50
|
+
return Weechat::WEECHAT_RC_OK
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def weechat_script_unload
|
55
|
+
if respond_to?(:teardown)
|
56
|
+
return Weechat::Utilities.evaluate_call { teardown }
|
57
|
+
end
|
58
|
+
|
59
|
+
return Weechat::WEECHAT_RC_OK
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
include Weechat::Pointer
|
65
|
+
extend Weechat::Properties
|
66
|
+
|
67
|
+
init_properties
|
68
|
+
|
69
|
+
class << self
|
70
|
+
def scripts(plugin = nil)
|
71
|
+
Plugin.all.map {|plugin| plugin.scripts}.flatten
|
72
|
+
end
|
73
|
+
alias_method :all, :scripts
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize(ptr, plugin)
|
77
|
+
super(ptr)
|
78
|
+
@plugin = plugin
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_infolist
|
82
|
+
Weechat::Infolist.parse("#{@plugin.name}_script", @ptr)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Weechat
|
2
|
+
class Script
|
3
|
+
class Config
|
4
|
+
def initialize(specification)
|
5
|
+
@specification = specification
|
6
|
+
@script = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def init!
|
10
|
+
populate!
|
11
|
+
hook!(false) {|config, value|
|
12
|
+
config.gsub!(/^plugins\.var\.ruby\.#{@script}\./, '')
|
13
|
+
spec = @specification[config]
|
14
|
+
begin
|
15
|
+
spec[0].from_weechat_config(value)
|
16
|
+
rescue
|
17
|
+
set!(config, spec[1])
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Hook for config changes
|
23
|
+
def hook!(evaluate = true, &callback)
|
24
|
+
@specification.each do |config, spec|
|
25
|
+
type = spec[0]
|
26
|
+
default = spec[1]
|
27
|
+
Weechat::Hooks::Config.new("plugins.var.ruby.#{@script}.#{config}") {|config, value|
|
28
|
+
if evaluate
|
29
|
+
value = type.from_weechat_config(value) rescue default
|
30
|
+
end
|
31
|
+
callback.call(config, value)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_script_name!(name)
|
37
|
+
@script = name
|
38
|
+
end
|
39
|
+
|
40
|
+
# Resets all options to their default.
|
41
|
+
#
|
42
|
+
# @return [void]
|
43
|
+
def reset!
|
44
|
+
clear!
|
45
|
+
populate!
|
46
|
+
end
|
47
|
+
|
48
|
+
# Unsets all options.
|
49
|
+
#
|
50
|
+
# @return [void]
|
51
|
+
def clear!
|
52
|
+
@specification.keys.each {|key| unset!(key)}
|
53
|
+
end
|
54
|
+
|
55
|
+
# This will set the default values for all unset options.
|
56
|
+
#
|
57
|
+
# @return [void]
|
58
|
+
def populate!
|
59
|
+
@specification.each do |key, value|
|
60
|
+
if not set?(key)
|
61
|
+
set!(key, value[1])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Checks if an option is set.
|
67
|
+
#
|
68
|
+
# @param [#to_s] option
|
69
|
+
# @return [Boolean]
|
70
|
+
def set?(option)
|
71
|
+
Weechat.integer_to_bool(Weechat.config_is_set_plugin(option.to_s))
|
72
|
+
end
|
73
|
+
|
74
|
+
# Unsets an option.
|
75
|
+
#
|
76
|
+
# @param [#to_s] The option to unset
|
77
|
+
# @return [Weechat::CONFIG_OPTION_UNSET_OK_NO_RESET,
|
78
|
+
# Weechat::CONFIG_OPTION_UNSET_RESET,
|
79
|
+
# Weechat::CONFIG_OPTION_UNSET_REMOVED,
|
80
|
+
# Weechat::CONFIG_OPTION_UNSET_ERROR] Integer denoting in how
|
81
|
+
# far unsetting the option worked.
|
82
|
+
# @see http://www.weechat.org/files/doc/stable/weechat_plugin_api.en.html#_weechat_config_unset_plugin
|
83
|
+
def unset!(option)
|
84
|
+
Weechat.config_unset_plugin(option.to_s)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns an option. If it isn't set, return the default value.
|
88
|
+
#
|
89
|
+
# @param [#to_s] option
|
90
|
+
# @return [Object]
|
91
|
+
def get!(option)
|
92
|
+
case ret = __get(option)
|
93
|
+
when true, false, nil
|
94
|
+
ret
|
95
|
+
else
|
96
|
+
Option.new(self, option)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def __get(option)
|
101
|
+
if set?(option)
|
102
|
+
return @specification[option][0].from_weechat_config(Weechat.config_get_plugin(option))
|
103
|
+
else
|
104
|
+
return @specification[option][1]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Sets the value of an option.
|
109
|
+
#
|
110
|
+
# @param [#to_s] option
|
111
|
+
# @param [#to_weechat_config, #to_s] value
|
112
|
+
# @return [Weechat::CONFIG_OPTION_SET_OK_CHANGED,
|
113
|
+
# Weechat::CONFIG_OPTION_SET_OK_SAME_VALUE,
|
114
|
+
# Weechat::CONFIG_OPTION_SET_OPTION_NOT_FOUND,
|
115
|
+
# Weechat::CONFIG_OPTION_SET_ERROR] Integer denoting in how
|
116
|
+
# far setting the option worked.
|
117
|
+
# @see http://www.weechat.org/files/doc/stable/weechat_plugin_api.en.html#_weechat_config_set_plugin
|
118
|
+
def set!(option, value, freeze = false)
|
119
|
+
value = value.to_weechat_config
|
120
|
+
Weechat.config_set_plugin(option.to_s, value)
|
121
|
+
if freeze
|
122
|
+
Option.options.each do |opt|
|
123
|
+
if opt[0..1] == [self, option]
|
124
|
+
opt[2].__freeze__
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def method_missing(m, *args)
|
131
|
+
ms = m.to_s
|
132
|
+
if ms[-1..-1] != '='
|
133
|
+
if @specification.has_key?(ms)
|
134
|
+
return get!(ms)
|
135
|
+
end
|
136
|
+
else
|
137
|
+
if @specification.has_key?(ms[0..-2])
|
138
|
+
return set!(ms[0..-2], args[0], true)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
super
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|