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.
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