weechat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,229 @@
1
+ if not defined? Weechat
2
+ raise LoadError.new('The weechat gem can only be required from scripts ' +
3
+ 'that are run under the WeeChat IRC client using the Ruby plugin.')
4
+ end
5
+
6
+ require 'pp'
7
+
8
+ module Weechat
9
+ VERSION = "0.0.1"
10
+ module Helper
11
+ def command_callback(id, buffer, args)
12
+ Weechat::Command.find_by_id(id).call(Weechat::Buffer.new(buffer), args)
13
+ end
14
+
15
+ def command_run_callback(id, buffer, command)
16
+ Weechat::Hooks::CommandRunHook.find_by_id(id).call(Weechat::Buffer.new(buffer), command)
17
+ end
18
+
19
+ def timer_callback(id, remaining)
20
+ Weechat::Timer.find_by_id(id).call(remaining.to_i)
21
+ end
22
+
23
+ def input_callback(method, buffer, input)
24
+ Weechat::Buffer.call_input_callback(method, buffer, input)
25
+ end
26
+
27
+ def close_callback(method, buffer)
28
+ Weechat::Buffer.call_close_callback(method, buffer)
29
+ end
30
+
31
+ def info_callback(id, info, arguments)
32
+ Weechat::Info.find_by_id(id).call(arguments).to_s
33
+ end
34
+
35
+ def print_callback(id, buffer, date, tags, displayed, highlight, prefix, message)
36
+ buffer = Weechat::Buffer.new(buffer)
37
+ date = Time.at(date.to_i)
38
+ tags = tags.split(",")
39
+ displayed = Weechat.integer_to_bool(displayed)
40
+ highlight = Weechat.integer_to_bool(highlight)
41
+ Weechat::Hooks::Print.find_by_id(id).call(buffer, date, tags, displayed, highlight, prefix, message)
42
+ end
43
+
44
+ def config_callback(id, option, value)
45
+ ret = Weechat::Hooks::Config.find_by_id(id).call(option, value)
46
+ end
47
+
48
+ def process_callback(id, command, code, stdout, stderr)
49
+ code = case code
50
+ when Weechat::WEECHAT_HOOK_PROCESS_RUNNING
51
+ :running
52
+ when Weechat::WEECHAT_HOOK_PROCESS_ERROR
53
+ :error
54
+ else
55
+ code
56
+ end
57
+
58
+ process = Weechat::Process.find_by_id(id)
59
+ if process.collect
60
+ process.buffer(stdout, stderr)
61
+ if code == :error || code != :running
62
+ process.call(code, process.stdout, process.stderr)
63
+ end
64
+ else
65
+ Weechat::Process.find_by_id(id).call(code, stdout, stderr)
66
+ end
67
+ end
68
+
69
+ ModifierCallbackTransformations = {
70
+ ['irc_color_decode', 'irc_color_encode'] => lambda { |v| Weechat.integer_to_bool(v) },
71
+ [/^bar_condition_.+$/] => lambda { |v| Weechat::Window.new(v) },
72
+ ["input_text_content", "input_text_display",
73
+ "input_text_display_with_cursor"] => lambda { |v| Weechat::Buffer.new(v) },
74
+ ["weechat_print"] => lambda { |v|
75
+ parts = v.split(";")
76
+ parts[0] = Weechat::Plugin.find(parts[0])
77
+ parts[1] = Weechat::Buffer.find(parts[1], parts[0])
78
+ if parts[2]
79
+ parts[2] = parts[2].split(",")
80
+ else
81
+ parts[2] = []
82
+ end
83
+ parts
84
+ },
85
+ }
86
+
87
+ ModifierCallbackRTransformations = {
88
+ [/^bar_condition_.+$/] => lambda { |v| Weechat.bool_to_integer(v) },
89
+ }
90
+
91
+ def modifier_callback(id, modifier, modifier_data, s)
92
+ modifier_data = Weechat::Utilities.apply_transformation(modifier, modifier_data, ModifierCallbackTransformations)
93
+ args = modifier_data + [Weechat::Line.parse(s)]
94
+ ret = Weechat::Modifier.find_by_id(id).call(*args)
95
+ return Weechat::Utilities.apply_transformation(modifier, ret, ModifierCallbackRTransformations).to_s
96
+ end
97
+ end
98
+
99
+ class << self
100
+ def exec(command, buffer=nil)
101
+ Weechat.command(buffer.to_s, command)
102
+ end
103
+ alias_method :send_command, :exec
104
+ alias_method :execute, :exec
105
+
106
+ def puts(text, buffer = nil)
107
+ buffer = case buffer
108
+ when nil
109
+ ""
110
+ when :current
111
+ Weechat::Buffer.current
112
+ else
113
+ buffer
114
+ end
115
+ Weechat.print(buffer.to_s, text.to_s)
116
+ nil # to mimic Kernel::puts
117
+ end
118
+
119
+ def p(object, buffer = nil)
120
+ self.puts(object.inspect, buffer)
121
+ end
122
+
123
+ def pp(object, buffer = nil)
124
+ puts(object.pretty_inspect, buffer)
125
+ end
126
+
127
+ # Writes text to the WeeChat log +weechat.log+
128
+ #
129
+ # @return [void]
130
+ def log(text)
131
+ Weechat.log_print(text)
132
+ end
133
+
134
+ def integer_to_bool(int)
135
+ int.to_i == 0 ? false : true
136
+ end
137
+
138
+ def bool_to_integer(bool)
139
+ bool ? 1 : 0
140
+ end
141
+
142
+ alias_method :old_mkdir_home, :mkdir_home
143
+ alias_method :old_mkdir, :mkdir
144
+ alias_method :old_mkdir_parents, :mkdir_parents
145
+ def mkdir_home(*args)
146
+ integer_to_bool(old_mkdir_home(*args))
147
+ end
148
+
149
+ def mkdir(*args)
150
+ integer_to_bool(old_mkdir(*args))
151
+ end
152
+
153
+ def mkdir_parents(*args)
154
+ integer_to_bool(old_mkdir_parents(*args))
155
+ end
156
+
157
+ def fifo
158
+ Weechat.info_get("fifo_filename", "")
159
+ end
160
+
161
+ def compilation_date
162
+ Date.parse(Weechat.info_get("date", ""))
163
+ end
164
+
165
+ def filtering?
166
+ integer_to_bool(Weechat.info_get("filters_enabled", ""))
167
+ end
168
+
169
+ def keyboard_inactivity
170
+ Weechat.info_get("inactivity", "").to_i
171
+ end
172
+ alias_method :inactivity, :keyboard_inactivity
173
+
174
+ def version
175
+ Weechat.info_get("version", "")
176
+ end
177
+
178
+ def charsets
179
+ {
180
+ :internal => Weechat.info_get("charset_internal", ""),
181
+ :terminal => Weechat.info_get("charset_terminal", ""),
182
+ }
183
+ end
184
+
185
+ def directories
186
+ {
187
+ :weechat => Weechat.info_get("weechat_dir", ""),
188
+ :lib => Weechat.info_get("weechat_libdir", ""),
189
+ :locale => Weechat.info_get("weechat_localedir", ""),
190
+ :share => Weechat.info_get("weechat_sharedir", ""),
191
+ :separator => Weechat.info_get("dir_separator", "")
192
+ }
193
+ end
194
+ alias_method :dirs, :directories
195
+ end
196
+ end
197
+
198
+ require 'weechat/blankslate.rb'
199
+ require 'weechat/line.rb'
200
+ require 'weechat/terminal.rb'
201
+ require 'weechat/callback.rb'
202
+ require 'weechat/property.rb'
203
+ require 'weechat/properties.rb'
204
+ require 'weechat/exceptions.rb'
205
+ require 'weechat/utilities.rb'
206
+ require 'weechat/pointer.rb'
207
+ require 'weechat/hook.rb'
208
+ require 'weechat/timer.rb'
209
+ require 'weechat/command.rb'
210
+ require 'weechat/modifier.rb'
211
+ require 'weechat/input.rb'
212
+ require 'weechat/buffer.rb'
213
+ require 'weechat/window.rb'
214
+ require 'weechat/server.rb'
215
+ require 'weechat/infolist.rb'
216
+ require 'weechat/color.rb'
217
+ require 'weechat/plugin.rb'
218
+ require 'weechat/rubyext/string.rb'
219
+ require 'weechat/rubyext/boolean.rb'
220
+ require 'weechat/rubyext/object.rb'
221
+ require 'weechat/rubyext/array.rb'
222
+ require 'weechat/rubyext/integer.rb'
223
+ require 'weechat/rubyext/float.rb'
224
+ require 'weechat/hooks.rb'
225
+ require 'weechat/script.rb'
226
+ require 'weechat/script/config.rb'
227
+ require 'weechat/option.rb'
228
+ require 'weechat/info.rb'
229
+ require 'weechat/process.rb'
@@ -0,0 +1,13 @@
1
+ class NullOutput
2
+ def write(*args)
3
+ end
4
+ end
5
+
6
+ class Blankslate
7
+ alias_method :__class__, :class
8
+
9
+ old_stderr = $stderr.dup
10
+ $stderr = NullOutput.new
11
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
12
+ $stderr = old_stderr
13
+ end
@@ -0,0 +1,559 @@
1
+ module Weechat
2
+ # This class provides a wrapper around WeeChat buffers.
3
+ #
4
+ # == Creating new buffers
5
+ #
6
+ # Using {Buffer.create}, one can create new buffers which even
7
+ # respond to input and closing using hooks (procs or methods or
8
+ # anything that responds to #call).
9
+ # Buffer.create("my buffer",
10
+ # lambda {|b, i|
11
+ # # work with input
12
+ # },
13
+ # lambda {|b|
14
+ # # respond to the closing of a buffer
15
+ # }
16
+ # )
17
+ #
18
+ # == The input line
19
+ #
20
+ # While internally the input line is managed by two properties
21
+ # (+input+ and +input_get_unknown_commands+), the WeeChat Ruby
22
+ # abstraction uses one instance of the {Input} class per buffer (see
23
+ # {#input}). The content of the input line thus can be read using
24
+ # {Input#text} and set using {Input#text=} (or using the shorthand
25
+ # {#input=}). To turn on/off the receiving of unknown commands, use
26
+ # {Input#get_unknown_commands=}.
27
+ #
28
+ # == Key binds
29
+ #
30
+ # Buffer local key binds can be set/unset using {#bind_keys} and
31
+ # {#unbind_keys}. Note, however, that key binds can only invoke
32
+ # commands, not callbacks (you can, however, pass in existing
33
+ # {Command} instances).
34
+ #
35
+ # == Closed buffers
36
+ #
37
+ # The library is *NOT* doing any checks if the pointer points at a
38
+ # valid/still existing buffer. That means, if you do not take care
39
+ # of this yourself (by keeping your variables up to date or calling
40
+ # {#valid?} yourself), you might risk crashes.
41
+ #
42
+ # == List of getters
43
+ #
44
+ # [plugin] The plugin which created the buffer
45
+ # [name] The name of the buffer
46
+ # [short_name] The short name of the buffer
47
+ # [title] The title of the buffer
48
+ # [number] The number (position) of the buffer
49
+ # [num_displayed] How many windows are displaying this buffer
50
+ # [notify] The buffer's notify level. Can be +:never+, +:highlights+, +:messages+ and +:always+
51
+ # [lines_hidden?] true if at least one line is hidden (filtered), otherwise false
52
+ # [prefix_max_length] "max length for prefix align"
53
+ # [show_times?] true if timestamps are shown, false otherwise (also called show_times?)
54
+ # [text_search] The type of search. Can be +:none+, +:backward+ and +:forward+
55
+ # [text_search_exact?] true if search is case sensitive
56
+ # [text_search_found?] true if text was found, false otherwise
57
+ # [text_search_input] The content of the input buffer before the search was started
58
+ # [active?] Whether this is the current buffer
59
+ # [highlight_words] An array of words that trigger highlighting
60
+ # [highlight_tags] An array of tags that trigger highlighting
61
+ # [type] The type of the buffer, can be either +:formatted+ or +:free+
62
+ #
63
+ # == List of gettable properties using the infolist
64
+ #
65
+ # :print_hooks_enabled=>1,
66
+ # :first_line_not_read=>0,
67
+ # :prefix_max_length=>0,
68
+ # :nicklist_case_sensitive=>0,
69
+ # :nicklist_display_groups=>1,
70
+ #
71
+ #
72
+ #
73
+ # == List of setters
74
+ #
75
+ # [hotlist] (not implemented yet)
76
+ # [name] The name of the buffer
77
+ # [short_name] The short name of the buffer
78
+ # [type] The type of the buffer, can be either +:formatted+ or +:free+
79
+ # [notify] The buffer's notify level. Can be +:never+, +:highlights+, +:messages+ and +:everything+
80
+ # [title] The title of the buffer
81
+ # [show_times] Whether to display times or not
82
+ # [nicklist] (not implemented yet)
83
+ # [nicklist_case_sensitive] (not implemented yet)
84
+ # [nicklist_display_groups] (not implemented yet)
85
+ # [highlight_words] The words to highlight in the buffer, expects an array
86
+ # [highlight_tags] The tags to highlight in the buffer, expects an array
87
+ # [input] Sets the content of the input line (See {Input#text=})
88
+ #
89
+ # === Notify levels
90
+ #
91
+ # [:never] Don't notify at all
92
+ # [:highlights] Only notify on highlights
93
+ # [:messages] Notify on highlights and messages
94
+ # [:everything] Notify on everything
95
+ #
96
+ # @see http://www.weechat.org/files/doc/stable/weechat_plugin_api.en.html#buffers The WeeChat Buffer API
97
+ class Buffer
98
+ include Weechat::Pointer
99
+ extend Weechat::Properties
100
+
101
+ # @overload input
102
+ # @return [Weechat::Input]
103
+ # @overload input=(val)
104
+ # Sets the content of the input line.
105
+ #
106
+ # @return [void]
107
+ # @see Input#text=
108
+ attr_accessor :input
109
+
110
+ @callbacks = []
111
+
112
+ # A list of all properties that can be retrieved using {#get_string_property}.
113
+ #
114
+ # @private
115
+ @known_string_properties = %w(plugin name short_name title input).freeze
116
+
117
+ # A list of all properties that can be retrieved using {#get_integer_property}.
118
+ #
119
+ # @private
120
+ @known_integer_properties = %w(number num_displayed notify lines_hidden prefix_max_length
121
+ time_for_each_line text_search text_search_exact
122
+ text_search_found).freeze
123
+
124
+ # A list of all properties that can be set using {#set_property}.
125
+ #
126
+ # @private
127
+ @settable_properties = %w(hotlist unread display number name short_name type notify
128
+ title time_for_each_line nicklist nicklist_case_sensitive nicklist_display_groups
129
+ highlight_words highlight_tags input input_get_unknown_commands).freeze
130
+ # @todo localvar_set_xxx
131
+ # @todo localvar_del_xxx
132
+
133
+ NOTIFY_LEVELS = [:never, :highlights, :messages, :always].freeze
134
+
135
+ # The transformation procedures that get applied to values after
136
+ # they've been received using {#get_property}.
137
+ #
138
+ # @private
139
+ @transformations = {
140
+ [:lines_hidden, :time_for_each_line, :text_search_exact,
141
+ :text_search_found, :current_buffer] => lambda {|v| Weechat.integer_to_bool(v) },
142
+ [:highlight_words, :highlight_tags] => lambda {|v| v == "-" ? [] : v.split(",") },
143
+ [:notify] => lambda {|v| NOTIFY_LEVELS[v] },
144
+ [:text_search] => lambda {|v| [:none, :backward, :foward][v] },
145
+ [:type] => lambda {|v| [:formatted, :free][v]},
146
+ }.freeze
147
+
148
+ # The transformation procedures that get applied to values before they
149
+ # are set by {#set_property}.
150
+ #
151
+ # @private
152
+ @rtransformations = {
153
+ [:lines_hidden, :time_for_each_line, :text_search_exact,
154
+ :text_search_found] => lambda {|v| Weechat.bool_to_integer(v) },
155
+ [:unread] => lambda {|v| !v ? nil : 1},
156
+ [:highlight_words, :highlight_tags] => lambda {|v|
157
+ s = v.join(",")
158
+ s.empty? ? "-" : s
159
+ },
160
+ [:notify] => lambda {|v|
161
+ i = NOTIFY_LEVELS.index(v)
162
+ i or raise Exception::InvalidPropertyValue.new(v.to_s)
163
+ },
164
+ [:type] => lambda {|v|
165
+ v = v.to_s
166
+ raise Exception::InvalidPropertyValue.new(v) if !["formatted", "free"].include?(v)
167
+ v
168
+ },
169
+ }.freeze
170
+
171
+ # @private
172
+ @mappings = {
173
+ :lines_hidden? => :lines_hidden,
174
+ :time_for_each_line? => :time_for_each_line,
175
+ :show_times? => :time_for_each_line,
176
+ :show_times= => :time_for_each_line=,
177
+ :text_search_exact? => :text_search_exact,
178
+ :text_search_found? => :text_search_found,
179
+ :position => :number,
180
+ :position= => :number=,
181
+ :active? => :current_buffer,
182
+ }.freeze
183
+
184
+ init_properties
185
+
186
+ class << self
187
+ # @return [Buffer]
188
+ # @see #initialize
189
+ def from_ptr(ptr)
190
+ self.new(ptr)
191
+ end
192
+
193
+ # Returns a list of all buffers
194
+ #
195
+ # @return [Array<Buffer>]
196
+ # @todo move into own module
197
+ def buffers
198
+ buffers = []
199
+ Weechat::Infolist.parse("buffer").each do |buffer|
200
+ buffers << Buffer.new(buffer[:pointer])
201
+ end
202
+ buffers
203
+ end
204
+ alias_method :all, :buffers
205
+
206
+ # Finds a buffer by its name and its plugin.
207
+ #
208
+ # @param [String] name The name of the buffer to find
209
+ # @param [String, Plugin] plugin The plugin of the buffer to find
210
+ # @return [Buffer, nil] An existing buffer or nil if non was found.
211
+ def find_by_name(name, plugin = "ruby")
212
+ plugin = case plugin
213
+ when Plugin
214
+ plugin.name
215
+ else
216
+ plugin.to_s
217
+ end
218
+ ptr = Weechat.buffer_search(plugin, name)
219
+ if ptr == ""
220
+ nil
221
+ else
222
+ Buffer.new(ptr)
223
+ end
224
+ end
225
+ alias_method :find, :find_by_name
226
+
227
+ # Returns all buffers with a certain name
228
+ #
229
+ # @param [String, Regexp] pattern The name of the buffers to find or a regular expression
230
+ # @param [Hash{Symbol => Object}] properties A hash with property => value pairs, defining requirements
231
+ # for the found buffers.
232
+ # @see .find_by_name
233
+ # @return [Array<Buffer>]
234
+ def search(pattern, properties={})
235
+ if pattern.is_a? String
236
+ pattern = Regexp.new("^#{pattern}$")
237
+ end
238
+
239
+ Weechat::Infolist.parse("buffer").select {|h|
240
+ h[:name] =~ pattern
241
+ }.map {|h|
242
+ Buffer.new(h[:pointer])
243
+ }.select {|b|
244
+ properties.all? {|key, value|
245
+ b.__send__(key) == value
246
+ }
247
+ }
248
+ end
249
+
250
+ # This method manages all input callbacks, resolving the
251
+ # callback to use by an ID which gets supplied by
252
+ # {Weechat::Helper#input_callback}. This shouldn't be called
253
+ # directly by the user.
254
+ #
255
+ # @return [void]
256
+ # @see .call_close_callback
257
+ # @private
258
+ def call_input_callback(id, buffer, input)
259
+ buffer = Buffer.new(buffer)
260
+ return @callbacks[id.to_i][:input_callback].call(buffer, input)
261
+ end
262
+
263
+ # This method manages all close callbacks, resolving the
264
+ # callback to use by an ID which gets supplied by
265
+ # {Weechat::Helper#close_callback}. This shouldn't be called
266
+ # directly by the user.
267
+ #
268
+ # @return [void]
269
+ # @see .call_input_callback
270
+ # @private
271
+ def call_close_callback(id, buffer)
272
+ buffer = Buffer.new(buffer)
273
+ return @callbacks[id.to_i][:close_callback].call(buffer)
274
+ end
275
+
276
+ # Returns all callbacks
277
+ #
278
+ # @return [Array<Hash{Symbol => String, #call}>] An array of hashes containing
279
+ # the callbacks and pointers of the buffers to which the callbacks are assigned to
280
+ # @see #input_callback
281
+ # @see #close_callback
282
+ def callbacks
283
+ @callbacks
284
+ end
285
+
286
+ # Returns the current buffer.
287
+ #
288
+ # @return [Buffer] The current buffer
289
+ def current
290
+ Buffer.new(Weechat.current_buffer)
291
+ end
292
+
293
+ # Creates a new buffer.
294
+ #
295
+ # @param [#to_s] name The name of the new buffer
296
+ # @param [#call] input_callback The callback to be called when something
297
+ # is entered in the new buffer's input line
298
+ # @param [#call] close_callback The callback to be called when the new buffer
299
+ # is being closed
300
+ # @example
301
+ # Buffer.create("my buffer",
302
+ # lambda {|b, i|
303
+ # # work with input
304
+ # },
305
+ # lambda {|b|
306
+ # # respond to the closing of a buffer
307
+ # }
308
+ # )
309
+ # @return [Buffer] The new buffer
310
+ # @raise [Exception::DuplicateBufferName] In case a buffer with that name already exists
311
+ def create(name, input_callback, close_callback)
312
+ @callbacks << {
313
+ :input_callback => Callback.new(input_callback),
314
+ :close_callback => Callback.new(close_callback),
315
+ }
316
+ id = @callbacks.size - 1
317
+ ptr = Weechat.buffer_new(name.to_s, "input_callback", id.to_s, "close_callback", id.to_s)
318
+ if ptr.empty?
319
+ raise Exception::DuplicateBufferName(name.to_s)
320
+ else
321
+ @callbacks[-1][:ptr] = ptr
322
+ Buffer.new(ptr)
323
+ end
324
+ end
325
+ end
326
+
327
+ def initialize(ptr)
328
+ super
329
+ @input = Weechat::Input.new(self)
330
+ @keybinds = {}
331
+ end
332
+
333
+ def input=(val)
334
+ @input.text=(val)
335
+ end
336
+
337
+ # Displays the buffer in the current window.
338
+ #
339
+ # @param [Boolean] auto If set to true, the read marker of the currently visible
340
+ # buffer won't be reset
341
+ # @return [void]
342
+ def display(auto = false)
343
+ auto = auto ? "auto" : 1
344
+ set_property("display", auto)
345
+ end
346
+ alias_method :show, :display
347
+
348
+ # Checks if the buffer is valid, that is if the pointer represents an existing buffer.
349
+ #
350
+ # @return [Boolean]
351
+ def valid?
352
+ Buffer.buffers.map{|b|b.pointer}.include?(@ptr)
353
+ end
354
+ alias_method :exist?, :valid?
355
+
356
+ # Check if the buffer represents a channel.
357
+ #
358
+ # @return [Boolean]
359
+ def channel?
360
+ # get all servers
361
+ # get all channels of all servers
362
+ # return true of pointer equal
363
+ end
364
+
365
+ # Send a command to the current buffer.
366
+ #
367
+ # Note: If the given command does not start with a slash, one will be added.
368
+ #
369
+ # @param [Array<String>] *parts All parts of the command to send
370
+ # @return [String] The whole command as sent to the buffer
371
+ # @example
372
+ # my_buffer.command("/whois", "dominikh")
373
+ def command(*parts)
374
+ parts[0][0,0] = '/' unless parts[0][0..0] == '/'
375
+ line = parts.join(" ")
376
+ Weechat.exec(line, self)
377
+ line
378
+ end
379
+ alias_method :send_command, :command
380
+ alias_method :exec, :command
381
+ alias_method :execute, :command
382
+
383
+ # Send a text to the buffer. If the buffer represents a channel, the text
384
+ # will be send as a message to the channel.
385
+ #
386
+ # Note: this method will automatically escape a leading slash, if present.
387
+ #
388
+ # @param [Array<String>] *text All parts of the text to send
389
+ # @return [String] The whole string as sent to the buffer
390
+ def send(*text)
391
+ text[0][0,0] = '/' if text[0][0..0] == '/'
392
+ line = text.join(" ")
393
+ Weechat.exec(line)
394
+ line
395
+ end
396
+ alias_method :privmsg, :send
397
+ alias_method :say, :send
398
+
399
+ # Closes the buffer.
400
+ #
401
+ # Note: After a buffer has been closed, it shouldn't be used anymore as
402
+ # that might lead to segfaults.
403
+ #
404
+ # @return [void]
405
+ def close
406
+ # TODO add check if a buffer is closed, to all methods
407
+ Weechat.buffer_close(@ptr)
408
+ @closed = true
409
+ end
410
+
411
+ # Moves the buffer.
412
+ #
413
+ # @param [Number] move The position to move the buffer to
414
+ # @return [Number] The position the buffer was moved to
415
+ def move(n)
416
+ self.number = (n)
417
+ end
418
+ alias_method :move_to, :move
419
+
420
+ # Moves the read marker to the bottom
421
+ #
422
+ # @return [void]
423
+ def update_marker
424
+ self.unread = true
425
+ end
426
+ alias_method :update_read_marker, :update_marker
427
+
428
+ # Clears the buffer.
429
+ #
430
+ # @return [void]
431
+ def clear
432
+ Weechat.buffer_clear(@ptr)
433
+ end
434
+
435
+ # Returns the callbacks assigned to the buffer.
436
+ #
437
+ # @return (see Weechat::Buffer.callbacks)
438
+ # @private
439
+ def callbacks
440
+ self.class.callbacks.find {|c| c.ptr == @ptr}
441
+ end
442
+
443
+ # The input callback assigned to the buffer.
444
+ #
445
+ # @return [#call]
446
+ # @see #close_callback
447
+ # @see .call_input_callback
448
+ def input_callback
449
+ callbacks[:input_callback]
450
+ end
451
+
452
+ # The close callback assigned to the buffer.
453
+ #
454
+ # @return [#call]
455
+ # @see #input_callback
456
+ # @see .call_close_callback
457
+ def close_callback
458
+ callbacks[:close_callback]
459
+ end
460
+
461
+ # Writes to the buffer.
462
+ #
463
+ # @return [void]
464
+ def print(text)
465
+ Weechat.puts(text, @ptr)
466
+ end
467
+ alias_method :puts, :print
468
+
469
+ # Returns an array with all lines of the buffer.
470
+ #
471
+ # @param [Boolean] strip_colors Whether to strip out all color codes
472
+ # @return [Array<Line>] The lines
473
+ # @see #text
474
+ def lines(strip_colors = false)
475
+ lines = []
476
+ Weechat::Infolist.parse("buffer_lines", @ptr).each do |line|
477
+ line = Weechat::Line.from_hash(line)
478
+ if strip_colors
479
+ line.prefix.strip_colors!
480
+ line.message.strip_colors!
481
+ end
482
+ lines << line
483
+ end
484
+
485
+ lines
486
+ end
487
+
488
+ # Returns the content of the buffer.
489
+ #
490
+ # @param strip_colors (see Weechat::Buffer#lines)
491
+ # @return [String]
492
+ # @see #lines
493
+ def text(strip_colors = false)
494
+ lines(strip_colors).join("\n")
495
+ end
496
+ alias_method :content, :text
497
+
498
+ # Returns the number of lines in the buffer.
499
+ #
500
+ # @return [Number] The number of lines in the buffer
501
+ def size
502
+ # TODO check if there is a property for that
503
+ Weechat::Infolist.parse("buffer_lines", @ptr).size
504
+ end
505
+ alias_method :count, :size
506
+ alias_method :length, :size
507
+
508
+ # Bind keys to a command.
509
+ #
510
+ # @param [Array<String>] keys An array of keys which will be used to build a keychain
511
+ # @param [String, Command] command The command to execute when the keys are being pressed
512
+ # @return [String] The keychain
513
+ # @see #unbind_keys
514
+ def bind_keys(*args)
515
+ keys = args[0..-2]
516
+ command = args[-1]
517
+
518
+ keychain = keys.join("-")
519
+ if command.is_a? Command
520
+ command = command.command
521
+ end
522
+ set("key_bind_#{keychain}", command)
523
+ @keybinds[keys] = command
524
+ keychain
525
+ end
526
+
527
+ # Unbind keys.
528
+ #
529
+ # @param[Array<String>] keys An array of keys which will be used to build a keychain
530
+ # @return [String] The command that was assigned to the key bind
531
+ # @see #bind_keys
532
+ def unbind_keys(*keys)
533
+ keychain = keys.join("-")
534
+ set("key_unbind_#{keychain}", "")
535
+ @keybinds.delete keys
536
+ end
537
+
538
+ # Returns all key binds
539
+ #
540
+ # @return [Hash{String => String}] A hash with keychain => command assignments
541
+ def key_binds
542
+ @keybinds
543
+ end
544
+
545
+ # Returns all windows that are displaying this buffer.
546
+ #
547
+ # @return [Array<Window>]
548
+ def windows
549
+ Window.all.select {|window| window.buffer == self }
550
+ end
551
+
552
+ def plugin
553
+ Plugin.new(Weechat.buffer_get_pointer(@ptr, "plugin"))
554
+ end
555
+ end
556
+
557
+ # The core buffer
558
+ Core = Buffer.new("")
559
+ end