weechat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ module Weechat
2
+ # Note: As opposed to plain WeeChat, we properly parse arguments
3
+ # given to a command, like a shell would.
4
+ class Modifier < Hook
5
+ attr_reader :modifier
6
+ def initialize(modifier, &callback)
7
+ super
8
+ @modifier = modifier.to_s
9
+ @callback = callback # we do not use the Callback class
10
+ # here because we need the return
11
+ # value of the callback
12
+ @ptr = Weechat.hook_modifier(modifier, "modifier_callback", id.to_s)
13
+ end
14
+
15
+ alias_method :exec, :call
16
+
17
+ class << self
18
+ def call(modifier, data, string)
19
+ Weechat.hook_modifier_exec(modifier.to_s, data.to_s, string.to_s)
20
+ end
21
+ alias_method :exec, :call
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ module Weechat
2
+ class Option < Blankslate
3
+ @options = [] # we can't use a Hash because hashing
4
+ # blankslate... breaks things
5
+
6
+
7
+ def self.options
8
+ @options
9
+ end
10
+
11
+ def initialize(config, option)
12
+ self.__class__.options << [config, option, self]
13
+ @old_obj = config.__get(option)
14
+ @config = config
15
+ @option = option
16
+ @frozen = false
17
+ end
18
+
19
+ def __freeze__
20
+ @frozen = true
21
+ end
22
+
23
+ def method_missing(m, *args, &block)
24
+ if @frozen
25
+ obj = @old_obj
26
+ else
27
+ obj = @config.__get(@option)
28
+ end
29
+ ret = obj.__send__(m, *args, &block)
30
+
31
+ if (@old_obj != obj) && !@frozen
32
+ @config.set!(@option, obj)
33
+ end
34
+
35
+ unless @frozen
36
+ begin
37
+ @old_obj = obj.dup
38
+ rescue TypeError
39
+ @old_obj = obj
40
+ end
41
+ end
42
+
43
+ ret
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,106 @@
1
+ module Weechat
2
+ # == Gettable properties
3
+ #
4
+ # [filename] Filename of the plugin
5
+ # [handle] ?
6
+ # [name] Name of the plugin
7
+ # [description] Description of the plugin
8
+ # [author] Author of the plugin
9
+ # [version] Version of the plugin
10
+ # [license] Licence of the plugin
11
+ # [charset] ?
12
+ # [debug?] ?
13
+ class Plugin
14
+ include Weechat::Pointer
15
+ extend Weechat::Properties
16
+
17
+ @mappings = {
18
+ :licence => :license,
19
+ :debug? => :debug,
20
+ }
21
+
22
+ @transformations = {
23
+ [:debug] => lambda {|v| Weechat.integer_to_bool(v) },
24
+ }
25
+
26
+ init_properties
27
+
28
+ class << self
29
+ def find_by_name(name)
30
+ if name.nil? or name.empty? or name == "core"
31
+ return Plugin.new("")
32
+ end
33
+ plugins.find {|plugin| plugin.name == name}
34
+ end
35
+ alias_method :find, :find_by_name
36
+
37
+ def plugins
38
+ plugins = [Plugin.new("")]
39
+ Weechat::Infolist.parse("plugin").each do |plugin|
40
+ plugins << Plugin.new(plugin[:pointer])
41
+ end
42
+ plugins
43
+ end
44
+ alias_method :all, :plugins
45
+
46
+ # Loads a plugin.
47
+ #
48
+ # @return [void]
49
+ def load(name)
50
+ Weechat.exec("/plugin load #{name}")
51
+ end
52
+
53
+ # Reloads all plugins.
54
+ #
55
+ # Note: This will not reload the ruby plugin.
56
+ #
57
+ # @return [Array<Plugin>] All plugins that have been reloaded.
58
+ def reload_all
59
+ plugins = all.select{|plugin| plugin.name != "ruby"}
60
+ plugins.each {|plugin| plugin.reload}
61
+ end
62
+ end
63
+
64
+ def name
65
+ Weechat.plugin_get_name(@ptr)
66
+ end
67
+
68
+ # Unloads the plugin.
69
+ #
70
+ # @param [Boolean] force If the plugin to be unloaded is "ruby",
71
+ # +force+ has to be true.
72
+ # @return [Boolean] true if we attempted to unload the plugin
73
+ def unload(force = false)
74
+ if name == "ruby" and !force
75
+ Weechat.puts "Won't unload the ruby plugin unless you force it."
76
+ false
77
+ else
78
+ Weechat.exec("/plugin unload #{name}")
79
+ true
80
+ end
81
+ end
82
+
83
+ # Reload the plugin.
84
+ #
85
+ # @param [Boolean] force If the plugin to be reloaded is "ruby", +force+ has to be true.
86
+ # @return [Boolean] true if we attempted to reload the plugin
87
+ def reload(force = false)
88
+ if name == "ruby" and !force
89
+ Weechat.puts "Won't reload the ruby plugin unless you force it."
90
+ else
91
+ Weechat.exec("/plugin reload #{name}")
92
+ end
93
+ end
94
+
95
+ # Returns an array of all scripts loaded by this plugin.
96
+ #
97
+ # @return [Array<Script>]
98
+ def scripts
99
+ scripts = []
100
+ Infolist.parse("#{name}_script").each do |script|
101
+ scripts << Script.new(script[:pointer], self)
102
+ end
103
+ scripts
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,28 @@
1
+ module Weechat
2
+ module Pointer
3
+ attr_reader :ptr
4
+ alias_method :pointer, :ptr
5
+
6
+ def to_s
7
+ @ptr
8
+ end
9
+
10
+ def initialize(ptr)
11
+ @ptr = ptr
12
+ end
13
+
14
+ def ==(other)
15
+ @ptr == other.ptr
16
+ end
17
+ alias_method :eql?, "=="
18
+ alias_method :equal?, "=="
19
+
20
+ def hash
21
+ @ptr.hash
22
+ end
23
+
24
+ def inspect
25
+ sprintf "#<%s:0x%x @ptr=%p>", self.class, object_id << 1, @ptr
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ module Weechat
2
+ class Process < Hook
3
+ # Returns a new instance of Process
4
+ #
5
+ # @param [String] command Command to execute
6
+ # @param [Integer] timeout Timeout after which to terminate the process
7
+ # @param [Boolean] collect If true, buffer output until process ends
8
+
9
+ attr_reader :collect
10
+ def initialize(command, timeout = 0, collect = false, &callback)
11
+ super
12
+ @command = command
13
+ @collect = collect
14
+ @stdout, @stderr = [], []
15
+ @callback = Callback.new(callback)
16
+ @ptr = Weechat.hook_process(command, timeout, "process_callback", id.to_s)
17
+ end
18
+
19
+ def stdout
20
+ @stdout.join("")
21
+ end
22
+
23
+ def stderr
24
+ @stderr.join("")
25
+ end
26
+
27
+ def buffer(stdout, stderr)
28
+ @stdout << stdout
29
+ @stderr << stderr
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,312 @@
1
+ module Weechat
2
+ module Properties
3
+ module ClassMethods
4
+ # Returns all known properties.
5
+ #
6
+ # @return [Array<Symbol>] The properties
7
+ def known_properties
8
+ @known_integer_properties + @known_string_properties
9
+ end
10
+
11
+ def known_integer_properties
12
+ @known_integer_properties
13
+ end
14
+
15
+ def known_string_properties
16
+ @known_string_properties
17
+ end
18
+
19
+ def settable_properties
20
+ @settable_properties
21
+ end
22
+
23
+ def transformations
24
+ @transformations
25
+ end
26
+
27
+ def rtransformations
28
+ @rtransformations
29
+ end
30
+
31
+ def mappings
32
+ @mappings
33
+ end
34
+
35
+ def type
36
+ @type
37
+ end
38
+
39
+ def init_properties
40
+ @known_string_properties ||= [].freeze
41
+ @known_integer_properties ||= [].freeze
42
+ @settable_properties ||= [].freeze
43
+ @transformations ||= {}.freeze
44
+ @rtransformations ||= {}.freeze
45
+ @mappings ||= {}.freeze
46
+
47
+ @type = self.name.downcase.split("::").last
48
+
49
+ # this defines all the getter methods
50
+ known_properties.each do |property|
51
+ define_method(property) { get_property(property) }
52
+ end
53
+
54
+ # this defined all the setter methods
55
+ @settable_properties.each do |property|
56
+ define_method(property + '=') {|v| set_property(property, v, true) }
57
+ end
58
+
59
+ # this adds a few aliases to make interfaces more rubyish
60
+ @mappings.each do |key, value|
61
+ if respond_to?(value)
62
+ # it is a string/integer property
63
+ alias_method key, value
64
+ else
65
+ # it is an infolist property
66
+ define_method(key) do |*args|
67
+ __send__(value, *args)
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ InstanceMethods.alias_methods(@type)
74
+ include InstanceMethods
75
+ end
76
+
77
+ def apply_transformation(property, value)
78
+ Utilities.apply_transformation(property, value, @transformations)
79
+ end
80
+ end
81
+
82
+ module InstanceMethods
83
+ # Get a property. Transformations, if appropriate, will be applied to the value
84
+ # before returning it. This means that e.g. 0 and 1 might be turned into false and true.
85
+ #
86
+ # @raise [Exception::UnknownProperty]
87
+ # @return [String, Number, Boolean]
88
+ # @see #get_integer_property
89
+ # @see #get_string_property
90
+ # @see #get_infolist_property
91
+ # @see #set_property
92
+ def get_property(property)
93
+ raise Exception::UnknownProperty.new(property) unless valid_property?(property)
94
+ case ret = __get_property(property)
95
+ when true, false, nil
96
+ ret
97
+ else
98
+ Property.new(self, property)
99
+ end
100
+ end
101
+
102
+ # @private
103
+ def __get_property(property)
104
+ property = property.to_s
105
+ if valid_property?(property, :integer)
106
+ v = get_integer_property(property)
107
+ elsif valid_property?(property, :string)
108
+ v = get_string_property(property)
109
+ elsif valid_property?(property, :infolist)
110
+ v = get_infolist_property(property)
111
+ else
112
+ raise Exception::UnknownProperty.new(property)
113
+ end
114
+
115
+ return self.class.apply_transformation(property, v)
116
+ end
117
+
118
+ # Returns an integer property.
119
+ #
120
+ # @raise [Exception::UnknownProperty]
121
+ # @return [Number]
122
+ # @see #get_integer
123
+ # @see #get_property
124
+ # @see #get_string_property
125
+ # @see #get_infolist_property
126
+ def get_integer_property(property)
127
+ property = property.to_s
128
+ raise Exception::UnknownProperty.new(property) unless valid_property?(property, :integer)
129
+ get_integer(property)
130
+ end
131
+
132
+ # Returns an integer property, not doing any checks.
133
+ #
134
+ # @return [Number]
135
+ # @see #get_integer_property
136
+ # @see #get_string
137
+ # @see #get_property
138
+ def get_integer(property)
139
+ Weechat.__send__("#{self.class.type}_get_integer", @ptr, property.to_s).to_i
140
+ end
141
+
142
+ # Returns a string property.
143
+ #
144
+ # @raise [Exception::UnknownProperty]
145
+ # @return [String]
146
+ # @see #get_string
147
+ # @see #get_property
148
+ # @see #get_integer_property
149
+ # @see #set_string_property
150
+ def get_string_property(property)
151
+ property = property.to_s
152
+ raise Exception::UnknownProperty.new(property) unless valid_property?(property, :string)
153
+ get_string(property)
154
+ end
155
+
156
+ # Returns a string property, not doing any checks.
157
+ #
158
+ # @return [String]
159
+ # @see #get_string_property
160
+ # @see #get_property
161
+ # @see #get_integer
162
+ # @see #set_string_property
163
+ def get_string(property)
164
+ Weechat.__send__("#{self.class.type}_get_string", @ptr, property.to_s)
165
+ end
166
+
167
+ # Returns a hash representation of the associated infolist.
168
+ #
169
+ # @return [Hash{Symbol => Object}] All properties in the infolist
170
+ def get_infolist
171
+ Weechat::Infolist.parse(self.class.type, @ptr)
172
+ end
173
+
174
+ # Returns a property obtained by an infolist.
175
+ #
176
+ # @raise [Exception::UnknownProperty]
177
+ # @return [String]
178
+ # @see #get_property
179
+ # @see #get_string_property
180
+ # @see #get_integer_property
181
+ def get_infolist_property(property)
182
+ property = property.to_sym
183
+ values = get_infolist.first
184
+ raise Exception::UnknownProperty.new(property.to_s) unless values[property]
185
+ values[property]
186
+ end
187
+
188
+ # Checks if a property can be set.
189
+ #
190
+ # @return [Boolean]
191
+ # @see #valid_property?
192
+ # @see #set_property
193
+ def settable_property?(property)
194
+ set_method = "#{self.class.type}_set"
195
+ return false unless Weechat.respond_to?(set_method)
196
+
197
+ property = property.to_s
198
+ self.class.settable_properties.include?(property)
199
+ end
200
+
201
+ # Sets a property. Transformations, if appropriate, will be applied to the value
202
+ # before setting it. This means that e.g. true and false will be turned into 1 and 0.
203
+ #
204
+ # @raise [Exception::UnsettableProperty]
205
+ # @return [String, Integer] The value after if has been transformed
206
+ # @see #set_string_property
207
+ # @see #set
208
+ def set_property(property, v, freeze = false)
209
+ property = property.to_s
210
+ raise Exception::UnsettableProperty.new(property) unless settable_property?(property)
211
+ v = Utilities.apply_transformation(property, v, self.class.rtransformations)
212
+
213
+ set(property, v)
214
+ if freeze
215
+ Property.properties.each do |prop|
216
+ if prop[0..1] == [@ptr, property]
217
+ prop[2].__freeze__
218
+ end
219
+ end
220
+ end
221
+ end
222
+
223
+ # Sets a string property, not applying any transformations.
224
+ #
225
+ # @raise [Exception::UnsettableProperty]
226
+ # @return [String] The value
227
+ # @see #set_property
228
+ # @see #set
229
+ def set_string_property(property, v)
230
+ property = property.to_s
231
+ raise Exception::UnsettableProperty.new(property) unless settable_property?(property)
232
+ set(property, v)
233
+ end
234
+
235
+ # Sets a property, not doing any checks or conversions whatsoever.
236
+ #
237
+ # @return [Object] The value
238
+ # @see #set_property
239
+ # @see #set_string_property
240
+ def set(property, value)
241
+ set_method = "#{self.class.type}_set"
242
+ raise CannotSetProperties unless Weechat.respond_to?(set_method)
243
+ Weechat.__send__(set_method, @ptr, property.to_s, value.to_s)
244
+ value
245
+ end
246
+
247
+ # Checks if a property is valid. That is, if get_(integer|string|infolist)_property are
248
+ # able to return a value.
249
+ #
250
+ # @param [#to_s] property The name of the property
251
+ # @param [Symbol] type The type of properties to check for.
252
+ # Can be one of :all, :string, :integer, :localvar or :infolist
253
+ # @return [Boolean]
254
+ # @see #settable_property?
255
+ # @see #get_property
256
+ def valid_property?(property, type = :all)
257
+ property = property.to_s
258
+ case type
259
+ when :all
260
+ valid_property?(property, :string) or
261
+ valid_property?(property, :integer) or
262
+ valid_property?(property, :localvar) or
263
+ valid_property?(property, :infolist)
264
+ when :string
265
+ self.class.known_string_properties.include?(property) or valid_property?(property, :localvar)
266
+ when :integer
267
+ self.class.known_integer_properties.include?(property)
268
+ when :localvar
269
+ property =~ /^localvar_.+$/
270
+ when :infolist
271
+ get_infolist.first[property.to_sym]
272
+ end
273
+ end
274
+
275
+ # method_missing returns buffer local variables.
276
+ #
277
+ # @return [String]
278
+ def method_missing(m, *args)
279
+ if args.empty? && valid_property?(m.to_s)
280
+ get_property(m.to_s)
281
+ else
282
+ super
283
+ end
284
+ end
285
+
286
+ # Returns a Hash representation of the object.
287
+ #
288
+ # @return [Hash{Symbol => Object}]
289
+ def to_h
290
+ h = {}
291
+ self.class.known_properties.each do |property|
292
+ val = __get_property(property)
293
+ h[property.to_sym] = val
294
+ end
295
+
296
+ get_infolist.first.each do |property, value|
297
+ prop = __get_property(property)
298
+ h[property] = prop
299
+ end
300
+
301
+ h
302
+ end
303
+
304
+ def self.alias_methods(type)
305
+ alias_method "#{type}_get_integer", :get_integer
306
+ alias_method "#{type}_get_string", :get_string
307
+ end
308
+ end
309
+
310
+ include ClassMethods
311
+ end
312
+ end