weechat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,296 @@
1
+ What this library is about
2
+ ==========================
3
+
4
+ The idea behind this library is to provide a clean way of writing
5
+ scripts for WeeChat, giving the programmer the usual Ruby experience.
6
+
7
+ While WeeChat already provides an extensive API which allows to modify
8
+ and control many parts of the client, that API is only providing the
9
+ plain C functions, making it very unintuitive for Ruby users (or
10
+ actually every other scripting/programming language, too). That also
11
+ means that writing Ruby scripts usually comes with a lot of repetitive
12
+ tasks, like converting C booleans to Ruby, handling string
13
+ representations of C pointers or having to free objects. Also the
14
+ approach of simply exposing the C API leaves us with absolutely no
15
+ object orientation.
16
+
17
+ And that's what this library is supposed to check. About every
18
+ function is wrapped into classes, conversions are done under the hood
19
+ and writing scripts in general becomes way more intuitive. No more
20
+ pointers or callbacks in the form of strings, no more freeing of
21
+ objects and a more appealing interface in general.
22
+
23
+
24
+ Working with properties
25
+ =======================
26
+
27
+ The WeeChat API has multiple means of returning and setting properties.
28
+ On the one side, some properties of windows and buffers are exposed by
29
+ (window|buffer)\_get\_(string|integer) methods, but on the other side
30
+ some properties are also only available through infolists. Both ways
31
+ of receiving properties got the downside of returning C'ish values (0
32
+ for false, 1 for true, "" for nil/empty arrays).
33
+
34
+ Setting properties is even more unnatural to Ruby programmers, because
35
+ it always expects string arguments, again C'ish values ("0" for false
36
+ and so on) and sometimes the setter methods are even used for invoking
37
+ actions, like moving a buffer or resetting the read marker.
38
+
39
+ Because of this, the WeeChat gem provides an abstractional layer
40
+ around the whole concept of properties, exposing all properties as
41
+ instance attributes (that is, as getter and setter methods), providing
42
+ methods for actions like resetting the read marker, and applying
43
+ transformations to turn C'ish values into real Ruby classes and vice
44
+ versa. Also, while using the traditional API only returned duplicates
45
+ of values, the abstractional layer returns references to objects. That
46
+ means, if two variables point to the same property, none of them will
47
+ be outdated if the other one is being changed in place.
48
+
49
+ buffer = Weechat::Buffer.current
50
+ buffer.highlight_words = ["word1", "word2"]
51
+ buffer.highlight_words # => ["word1", "word2"]
52
+
53
+ buffer = Weechat::Buffer.all.last
54
+ buffer.lines_hidden? # => false
55
+ buffer.show # displays the buffer in the current window
56
+
57
+ buffer = Weechat::Buffer.current
58
+ a = buffer.short_name # => "weechat"
59
+ b = buffer.short_name # => "weechat"
60
+ a.replace("new name") # => "new name"
61
+ buffer.short_name # => "new name"
62
+ b # => "new name"
63
+
64
+ References, however, won't be updated once an assignment was made
65
+ to the property, just like with real Ruby objects:
66
+
67
+ buffer = Weechat::Buffer.current
68
+ a = buffer.short_name # => "weechat"
69
+ buffer.short_name = "new name" # => "new name"
70
+ a # => "weechat"
71
+
72
+ Programatically accessing properties
73
+ ------------------------------------
74
+
75
+ If you have to access properties in a metaprogrammed fashion but do
76
+ not want to use the low level methods, feel free to use
77
+ {Weechat::Properties::InstanceMethods#get_property} and
78
+ {Weechat::Properties::InstanceMethods#set_property}, which provide all
79
+ of the added functionality mentioned above (note, however, that
80
+ properties returning true/false won't have an appended question mark
81
+ to their name if using
82
+ {Weechat::Properties::InstanceMethods#get_property #get_property} and
83
+ {Weechat::Properties::InstanceMethods#set_property #set_property}.
84
+
85
+ Note regarding the documentation
86
+ --------------------------------
87
+
88
+ Because most getters and setters for properties are being generated
89
+ using metaprogramming, they won't show up in the attribute or method
90
+ lists in the documentation. Instead you can find a list of those
91
+ properties and their return values in the introductional description
92
+ of each class (if suitable).
93
+
94
+ Low level access
95
+ ----------------
96
+
97
+ The WeeChat gem provides several methods for low level access to
98
+ properties (which are still better than directly using the WeeChat
99
+ API), in varying degress. Using those, however, should never be
100
+ necessary nor should it give any advantages over the abstractional
101
+ layer. If you ever get into a situation where you have to use the low
102
+ level API, please [inform me][issues], providing a sample of what you
103
+ are doing and your intentions and I will try to update the layer.
104
+
105
+ If you, for whatever reason, feel attached to the low level API
106
+ though, please consult the [official API documentation][weechat_doc] regarding
107
+ property names and {Weechat::Properties} regarding available methods.
108
+
109
+
110
+ Buffers
111
+ =======
112
+
113
+ See {Weechat::Buffer}
114
+
115
+
116
+ Windows
117
+ =======
118
+
119
+ See {Weechat::Window}
120
+
121
+
122
+ Infolists
123
+ =========
124
+
125
+ Infolists do represent a lower level aspect, are an exception to the
126
+ general "you shouldn't use the low level calls" though, as it might be
127
+ necessary to use them directly from time to time.
128
+
129
+ See {Weechat::Infolist}
130
+
131
+
132
+ Sorted lists
133
+ ============
134
+
135
+ While the WeeChat API exposes a few functions for creating and working
136
+ with sorted lists, I've decided not to implement any of those because
137
+ Ruby provides own means of lists. If you think this is a missing
138
+ feature, [inform me][issues] and I might add them to the library.
139
+
140
+
141
+ Writing scripts
142
+ ===============
143
+
144
+ Initializing
145
+ ------------
146
+
147
+ A common practice when writing scripts for WeeChat is to have a bunch
148
+ of constants which contain script name, description and so on. Those
149
+ constants then will be used in the weechat_init and weechat_register
150
+ functions.
151
+
152
+ This library is taking it a step further, expecting the user to create
153
+ a hash called `@script` with those information (where missing
154
+ information will be filled with default values by the library). An
155
+ included weechat_init method will then automatically use that hash to
156
+ register the script. After that, it will, if existing, call the
157
+ `setup` method defined by the script writer, in which one can do
158
+ additional things when loading the script, like creating commands.
159
+
160
+ A similar hook, `teardown`, will be called when the script is
161
+ unloaded.
162
+
163
+ require 'weechat'
164
+ include Weechat
165
+ include Script::Skeleton
166
+
167
+ @script = {
168
+ :name => "testscript", # must not be empty
169
+ :author => "Dominik Honnef <dominikho@gmx.net>", # defaults to "Anonymous"
170
+ :version => "0.0.1", # defaults to "0.0.1"
171
+ :license => 'GPL3', # defaults to "unlicensed"
172
+ :gem_version => '0.0.1', # defaults to "0.0.1" and specifies the
173
+ # the minimum required version of the gem
174
+ :description => "this serves as a test suite and example file for the weechat gem",
175
+ # defaults to "Empty script description
176
+ }
177
+
178
+ def setup
179
+ # do custom stuff when the script is being loaded
180
+ end
181
+
182
+ def teardown
183
+ # do custom stuff when the script is being unloaded
184
+ end
185
+
186
+ Commands
187
+ --------
188
+
189
+ * String#split_shell
190
+ * Hash
191
+ * Two arguments
192
+
193
+ Configs
194
+ -------
195
+
196
+ We provide an abstraction around plugin specific configs, including
197
+ automatic typecasting and default values, getting and setting of
198
+ values (also in place [see "Working with Properties"]).
199
+
200
+ While some objects like Strings, Arrays and Booleans can be converted
201
+ directly to and from a weechat config string, other objects can, too,
202
+ be stored in Weechat's per-plugin config system using YAML for the
203
+ internal representation. While this allows one to store any kind of
204
+ objects, it is more than unlikely that a user is willing to change
205
+ those settings using /set, so use those objects sparingly.
206
+
207
+ # ...
208
+ @config = Script::Config.new(
209
+ 'some_list' => [Array, []],
210
+ 'some_boolean' => [Boolean, true],
211
+ 'some_color' => [Color, 'red'],
212
+ )
213
+ def setup
214
+ @config.some_list # returns an array (either [] if the option
215
+ # is not set yet or whatever has been set by the user)
216
+
217
+ @config.some_list << "new item" # automatically converts the new array
218
+ # to a string and store it in the config
219
+ end
220
+
221
+ ### Implementing own objects
222
+
223
+ If you want to implement your own conversion for objects (instead of
224
+ using YAML), define an instance method `to_weechat_config` and a class
225
+ method `from_weechat_config(value)` on the class of your object.
226
+
227
+ ### Own configuration files
228
+
229
+ Currently there are no plans on implementing the more general
230
+ configurations.
231
+
232
+ Return values
233
+ -------------
234
+
235
+ While the original API expects you to return constants denoting
236
+ success/failure, this library expects you to raise certain exceptions.
237
+ The idea behind this is that the original constants had the values `0`,
238
+ `1` and `-1`; values which might well be implicitly returned by any ruby
239
+ code that was executed last in a callback. A raised exception, on the
240
+ other side, is unambiguous. Those exceptions live in the
241
+ {Weechat::Exception} namespace and got the same name as the old
242
+ constants.
243
+
244
+
245
+ Updating the gem
246
+ ================
247
+
248
+ The easiest way of updating the gem is to run `gem update weechat` and
249
+ then, in WeeChat, `/upgrade`.
250
+
251
+
252
+ Contributing to the project
253
+ ===========================
254
+
255
+ In case you want to contribute to this lovely project: Don't worry,
256
+ you will have plenty of chances for doing so!
257
+
258
+ Sending me gifts
259
+ ----------------
260
+
261
+ While sending me gifts won't fix any bugs or add any new features, it
262
+ will postively affect my mood, and some people say that good temper
263
+ equals many bugfixes, so give it a try!
264
+
265
+ I accept things like new hardware, gadgets, beer, women, plain money
266
+ and whatever else you can think of. But please DO NOT send me your
267
+ first born child, even if you really want to, thanks.
268
+
269
+ Reporting bugs / requesting features
270
+ -------------------------------------
271
+
272
+ In case you found a bug in my
273
+ library or miss an important feature, feel free to
274
+ [create a ticket][issues].
275
+
276
+ Contributing code
277
+ -----------------
278
+
279
+ Do you belong to those that don't want to only report bugs but who
280
+ also fix them on your own? Great! Fork my repository at github, create
281
+ a feature branch, do your stuff and then send me a pull request. If
282
+ your code does what it is supposed to do, I will merge in your
283
+ changes.
284
+
285
+ Write documentation
286
+ -------------------
287
+
288
+ While this library provides a basic documentation, it lacks examples
289
+ and guides. I would really appreciate enhancements.
290
+
291
+ Telling me how great I am
292
+ -------------------------
293
+ No, really, feel free to tell me.
294
+
295
+ [issues]: http://github.com/dominikh/weechat-ruby/issues
296
+ [weechat_doc]: http://www.weechat.org/files/doc/stable/weechat_plugin_api.en.html
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ VERSION = "0.0.1"
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = "weechat"
8
+ s.summary = "An abstraction layer on top of the WeeChat API."
9
+ s.description = "An abstraction layer on top of the WeeChat API, allowing a cleaner and more intuitive way of writing Ruby scripts for WeeChat."
10
+ s.version = VERSION
11
+ s.author = "Dominik Honnef"
12
+ s.email = "dominikho@gmx.net"
13
+ s.date = Time.now.strftime "%Y-%m-%d"
14
+ s.require_path = "lib"
15
+ s.homepage = "http://dominikh.fork-bomb.de"
16
+ s.rubyforge_project = ""
17
+
18
+ s.has_rdoc = 'yard'
19
+
20
+ # s.required_ruby_version = '>= 1.9.1'
21
+
22
+ # s.add_dependency "keyword_arguments"
23
+
24
+ # s.add_development_dependency "baretest"
25
+ # s.add_development_dependency "mocha"
26
+
27
+ s.files = FileList["bin/*", "lib/**/*.rb", "[A-Z]*", "examples/**/*"].to_a
28
+ s.executables = [""]
29
+ end
30
+
31
+ Rake::GemPackageTask.new(spec)do |pkg|
32
+ end
33
+
34
+ begin
35
+ require 'yard'
36
+ YARD::Rake::YardocTask.new do |t|
37
+ end
38
+ rescue LoadError
39
+ end
40
+
41
+ task :test do
42
+ begin
43
+ require "baretest"
44
+ rescue LoadError => e
45
+ puts "Could not run tests: #{e}"
46
+ end
47
+
48
+ BareTest.load_standard_test_files(
49
+ :verbose => false,
50
+ :setup_file => 'test/setup.rb',
51
+ :chdir => File.absolute_path("#{__FILE__}/../")
52
+ )
53
+
54
+ BareTest.run(:format => "cli", :interactive => false)
55
+ end
data/TODO ADDED
@@ -0,0 +1,188 @@
1
+ [x] - implemented
2
+ [-] - indirectly implemented
3
+ [/] - won't be implemented
4
+ [ ] - not touched yet
5
+
6
+ scripts:
7
+ [x] register
8
+
9
+ plugins:
10
+ [x] plugin_get_name
11
+
12
+ strings:
13
+ [/] charset_set
14
+ [/] iconv_to_internal
15
+ [/] iconv_from_internal
16
+ [/] gettext
17
+ [/] ngettext
18
+ [x] string_remove_color
19
+
20
+ directories:
21
+ [-] mkdir_home
22
+ [-] mkdir
23
+ [-] mkdir_parents
24
+
25
+ [/] sorted lists:
26
+ [/] list_new
27
+ [/] list_add
28
+ [/] list_search
29
+ [/] list_casesearch
30
+ [/] list_get
31
+ [/] list_set
32
+ [/] list_next
33
+ [/] list_prev
34
+ [/] list_string
35
+ [/] list_size
36
+ [/] list_remove
37
+ [/] list_remove_all
38
+ [/] list_free
39
+
40
+ configuration files:
41
+ [/] config_new
42
+ [/] config_new_section
43
+ [/] config_search_section
44
+ [/] config_new_option
45
+ [/] config_search_option
46
+ [x] config_string_to_boolean
47
+ [/] config_option_reset
48
+ [/] config_option_set
49
+ [/] config_option_set_null
50
+ [/] config_option_unset
51
+ [/] config_option_rename
52
+ [/] config_option_is_null
53
+ [/] config_option_default_is_null
54
+ [/] config_boolean
55
+ [/] config_boolean_default
56
+ [/] config_integer
57
+ [/] config_integer_default
58
+ [/] config_string
59
+ [/] config_string_default
60
+ [/] config_color
61
+ [/] config_color_default
62
+ [/] config_write_option
63
+ [/] config_write_line
64
+ [/] config_write
65
+ [/] config_read
66
+ [/] config_reload
67
+ [/] config_option_free
68
+ [/] config_section_free_options
69
+ [/] config_section_free
70
+ [/] config_free
71
+ [/] config_get
72
+ [x] config_get_plugin
73
+ [x] config_is_set_plugin
74
+ [x] config_set_plugin
75
+ [x] config_unset_plugin
76
+
77
+ display:
78
+ [/] prefix
79
+ [x] color
80
+ [x] print
81
+ [ ] print_date_tags
82
+ [ ] print_y
83
+ [x] log_print
84
+
85
+ hooks:
86
+ [x] hook_command
87
+ [x] hook_command_run
88
+ [x] hook_timer
89
+ [ ] hook_fd
90
+ [x] hook_process
91
+ [ ] hook_connect
92
+ [x] hook_print
93
+ [ ] hook_signal
94
+ [ ] hook_signal_send
95
+ [x] hook_config
96
+ [ ] hook_completion
97
+ [ ] hook_completion_list_add
98
+ [x] hook_modifier
99
+ [x] hook_modifier_exec
100
+ [x] hook_info
101
+ [ ] hook_infolist
102
+ [x] unhook
103
+ [x] unhook_all
104
+
105
+ buffers:
106
+ [x] buffer_new
107
+ [x] buffer_search
108
+ [x] current_buffer
109
+ [x] buffer_clear
110
+ [x] buffer_close
111
+ [x] buffer_get_integer
112
+ [x] buffer_get_string
113
+ [x] buffer_get_pointer
114
+ [x] buffer_set
115
+
116
+ windows:
117
+ [x] current_window
118
+ [x] window_get_integer
119
+ [x] window_get_string
120
+ [x] window_get_pointer
121
+ [x] window_set_title
122
+
123
+ nicklist:
124
+ [ ] nicklist_add_group
125
+ [ ] nicklist_search_group
126
+ [ ] nicklist_add_nick
127
+ [ ] nicklist_search_nick
128
+ [ ] nicklist_remove_group
129
+ [ ] nicklist_remove_nick
130
+ [ ] nicklist_remove_all
131
+
132
+ bars:
133
+ [ ] bar_item_search
134
+ [ ] bar_item_new
135
+ [ ] bar_item_update
136
+ [ ] bar_item_remove
137
+ [ ] bar_search
138
+ [ ] bar_new
139
+ [ ] bar_set
140
+ [ ] bar_update
141
+ [ ] bar_remove
142
+
143
+ commands:
144
+ [x] command
145
+
146
+ infos:
147
+ info_get
148
+ [x] fifo_filename
149
+ [/] irc_buffer
150
+ [x] irc_is_channel
151
+ [/] irc_nick
152
+ [x] irc_nick_from_host
153
+ [x] charset_internal
154
+ [x] charset_terminal
155
+ [x] date
156
+ [x] dir_separator
157
+ [x] filters_enabled
158
+ [x] inactivity
159
+ [x] version
160
+ [x] weechat_dir
161
+ [x] weechat_libdir
162
+ [x] weechat_localedir
163
+ [x] weechat_sharedir
164
+
165
+ infolists:
166
+ [ ] infolist_new
167
+ [ ] infolist_new_var_integer
168
+ [ ] infolist_new_var_string
169
+ [ ] infolist_new_var_pointer
170
+ [ ] infolist_new_var_time
171
+ [x] infolist_get
172
+ [x] infolist_next
173
+ [-] infolist_prev
174
+ [x] infolist_fields
175
+ [x] infolist_integer
176
+ [x] infolist_string
177
+ [x] infolist_pointer
178
+ [x] infolist_time
179
+ [x] infolist_free
180
+
181
+ upgrade:
182
+ [ ] upgrade_new
183
+ [ ] upgrade_write_object
184
+ [ ] upgrade_read
185
+ [ ] upgrade_close
186
+
187
+ Functionality:
188
+ [ ] if a buffer is a channel, get nicks, usercount, topic, etc