hsume2-hirb 0.6.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gemspec +21 -0
  2. data/CHANGELOG.rdoc +144 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.rdoc +194 -0
  5. data/Rakefile +35 -0
  6. data/lib/bond/completions/hirb.rb +15 -0
  7. data/lib/hirb/console.rb +43 -0
  8. data/lib/hirb/dynamic_view.rb +113 -0
  9. data/lib/hirb/formatter.rb +126 -0
  10. data/lib/hirb/helpers/auto_table.rb +24 -0
  11. data/lib/hirb/helpers/object_table.rb +14 -0
  12. data/lib/hirb/helpers/parent_child_tree.rb +24 -0
  13. data/lib/hirb/helpers/tab_table.rb +24 -0
  14. data/lib/hirb/helpers/table/filters.rb +10 -0
  15. data/lib/hirb/helpers/table/resizer.rb +82 -0
  16. data/lib/hirb/helpers/table.rb +349 -0
  17. data/lib/hirb/helpers/tree.rb +181 -0
  18. data/lib/hirb/helpers/unicode_table.rb +15 -0
  19. data/lib/hirb/helpers/vertical_table.rb +37 -0
  20. data/lib/hirb/helpers.rb +18 -0
  21. data/lib/hirb/import_object.rb +10 -0
  22. data/lib/hirb/menu.rb +238 -0
  23. data/lib/hirb/pager.rb +105 -0
  24. data/lib/hirb/string.rb +44 -0
  25. data/lib/hirb/util.rb +96 -0
  26. data/lib/hirb/version.rb +3 -0
  27. data/lib/hirb/view.rb +270 -0
  28. data/lib/hirb/views/couch_db.rb +11 -0
  29. data/lib/hirb/views/misc_db.rb +15 -0
  30. data/lib/hirb/views/mongo_db.rb +14 -0
  31. data/lib/hirb/views/orm.rb +11 -0
  32. data/lib/hirb/views/rails.rb +19 -0
  33. data/lib/hirb/views.rb +8 -0
  34. data/lib/hirb.rb +82 -0
  35. data/lib/ripl/hirb.rb +15 -0
  36. data/test/auto_table_test.rb +30 -0
  37. data/test/console_test.rb +27 -0
  38. data/test/deps.rip +4 -0
  39. data/test/dynamic_view_test.rb +94 -0
  40. data/test/formatter_test.rb +176 -0
  41. data/test/hirb_test.rb +39 -0
  42. data/test/import_test.rb +9 -0
  43. data/test/menu_test.rb +255 -0
  44. data/test/object_table_test.rb +79 -0
  45. data/test/pager_test.rb +162 -0
  46. data/test/resizer_test.rb +62 -0
  47. data/test/table_test.rb +630 -0
  48. data/test/test_helper.rb +61 -0
  49. data/test/tree_test.rb +184 -0
  50. data/test/util_test.rb +59 -0
  51. data/test/view_test.rb +165 -0
  52. data/test/views_test.rb +13 -0
  53. metadata +184 -0
data/.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'rubygems' unless Object.const_defined?(:Gem)
3
+ require File.dirname(__FILE__) + "/lib/hirb/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "hsume2-hirb"
7
+ s.version = Hirb::VERSION
8
+ s.authors = ["Gabriel Horner"]
9
+ s.email = "gabriel.horner@gmail.com"
10
+ s.homepage = "http://tagaholic.me/hirb/"
11
+ s.summary = "A mini view framework for console/irb that's easy to use, even while under its influence."
12
+ s.description = "Hirb provides a mini view framework for console applications and uses it to improve ripl(irb)'s default inspect output. Given an object or array of objects, hirb renders a view based on the object's class and/or ancestry. Hirb offers reusable views in the form of helper classes. The two main helpers, Hirb::Helpers::Table and Hirb::Helpers::Tree, provide several options for generating ascii tables and trees. Using Hirb::Helpers::AutoTable, hirb has useful default views for at least ten popular database gems i.e. Rails' ActiveRecord::Base. Other than views, hirb offers a smart pager and a console menu. The smart pager only pages when the output exceeds the current screen size. The menu is used in conjunction with tables to offer two dimensional menus."
13
+ s.required_rubygems_version = ">= 1.3.5"
14
+ s.add_development_dependency 'bacon', '>= 1.1.0'
15
+ s.add_development_dependency 'mocha', '>= 0.9.8'
16
+ s.add_development_dependency 'mocha-on-bacon', '>= 0.1.1'
17
+ s.add_development_dependency 'bacon-bits'
18
+ s.files = Dir.glob(%w[{lib,test}/**/*.rb bin/* [A-Z]*.{txt,rdoc} ext/**/*.{rb,c} **/deps.rip]) + %w{Rakefile .gemspec}
19
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
20
+ s.license = 'MIT'
21
+ end
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,144 @@
1
+ == 0.6.0
2
+ * Add tab table
3
+ * Tests pass in 1.9.3
4
+
5
+ == 0.5.0
6
+ * Add :grep_fields option to Table
7
+
8
+ == 0.4.5
9
+ * Fix the fix
10
+
11
+ == 0.4.4
12
+ * Fix bundler messing with ripl plugin
13
+
14
+ == 0.4.3
15
+ * Remove Formatter::TO_A_EXCEPTIONS and replace with Formatter.to_a_classes
16
+
17
+ == 0.4.2
18
+ * Fix bug with Tempfile and to_a_exceptions
19
+
20
+ == 0.4.1
21
+ * Fix bug with rendering empty hash
22
+ * Add missing yaml require
23
+
24
+ == 0.4.0
25
+ * Add unicode table helper thanks to janlelis
26
+ * Make pager compatible with full width characters
27
+
28
+ == 0.3.6
29
+ * Tweak ripl support
30
+ * Allow override of :hirb_number thanks to asanghi.
31
+ * Fix Hirb.add_view to work with class which inherits Hash
32
+
33
+ == 0.3.5
34
+ * Add ripl support
35
+ * Fix Formatter#determine_output_class for IO and Hash
36
+ * Remove :output_method option for Hirb.enable
37
+ * Allow rubygems 1.3.5
38
+
39
+ == 0.3.4
40
+ * Added auto format of array-like objects i.e. ActiveRecord::Relation and Set.
41
+ * Fixed bug when Hirb::Console#table is used without Hirb enabled.
42
+ * Fixed bug when hirb is running within cron and uses tput.
43
+
44
+ == 0.3.3
45
+ * Added ignore_errors option to ignore view errors and continue with original view.
46
+ * Added support for array menu items.
47
+ * Added support to ObjectTable for objects with an undefined :send method.
48
+
49
+ == 0.3.2
50
+ * Added irb autocompletions for bond.
51
+ * Fixed tests for ruby 1.9.
52
+ * Changed tests to use bacon.
53
+ * Removed jeweler in Rakefile and pointless $LOAD_PATH manipulation.
54
+
55
+ == 0.3.1
56
+ * Bug fix on DynamicView.class_to_method to allow overrides of default views.
57
+ * Modified mongo_mapper view to have _id first.
58
+
59
+ == 0.3.0
60
+ * Added dynamic views.
61
+ * Added default table views for the following database classes/modules:
62
+ CouchFoo::Base, CouchPotato::Persistence, CouchRest::ExtendedDocument,
63
+ DBI::Row, DataMapper::Resource, Friendly::Document, MongoMapper::Document, MongoMapper::EmbeddedDocument,
64
+ Mongoid::Document, Ripple::Document and Sequel::Model.
65
+ * Added Hirb.add_view and Hirb.add_dynamic_view for easier view manipulation.
66
+ * Added :multi_line_nodes option for Tree.
67
+ * Fixed :change_fields option bug in Table.
68
+ * Fixed no headers and nil fields bug in Table.
69
+ * Removed deprecations in Hirb.config_file + View.enable.
70
+ * Removed Views classes and View.format_class.
71
+ * Removed :return_rows option for Table.
72
+
73
+ == 0.2.10
74
+ * Added multiple options to Menu, most importantly :two_d and :action.
75
+ * Improved table resizing algorithm.
76
+ * Added merging of configs for multiple Hirb.enable calls.
77
+ * Added :max_fields, :hide_empty, :delete_callbacks, :resize, :header_filter
78
+ and :return_rows options to Table.
79
+ * Added escaping for \t and \r in Table.
80
+ * Renamed Table's :no_newlines option to :escape_special_chars.
81
+ * Removed Table's :field_lengths option.
82
+ * Removed Menu's :validate_one option.
83
+ * Bug fix for table header of a basic array.
84
+ * Deprecating Hirb.config_file + View.enable in next release.
85
+
86
+ == 0.2.9
87
+ * Added newline filtering and :no_newlines option for table helper.
88
+ * Added default filters for hashes that have hash values.
89
+ * Bug fix for deprecated to_a call.
90
+
91
+ == 0.2.8
92
+ * Added callbacks to Hirb::Helpers::Table.
93
+ * Added :change_fields option to Hirb::Helpers::Table.
94
+ * Added terminal size detection for jruby.
95
+ * Bug fix for paging long outputs.
96
+ * Bug fix to make unexpected hirb rendering errors more clear.
97
+
98
+ == 0.2.7
99
+ * 2 ruby 1.9 bug fixes.
100
+ * Bug fix in :fields of Hirb::Helpers::ObjectTable.
101
+ * Made :class option in Hirb::Formatter friendlier to external apps.
102
+
103
+ == 0.2.6
104
+ * Added :description option and added proc ability to :children_method option for helpers.
105
+ * Bug fix for no ENV['HOME'] on Windows.
106
+ * Bug fix on unaliasing output_method.
107
+ * Bug fix on multiple renders of vertical table.
108
+
109
+ == 0.2.5
110
+ * Added ability to use Hirb.enable with non-irb ruby shells.
111
+ * Helper configs now recursively merge when inheriting from others via :ancestor option.
112
+
113
+ == 0.2.4
114
+ * Bug fix on UTF-8 support.
115
+
116
+ == 0.2.3
117
+ * Added UTF-8 support for Ruby 1.8.x
118
+ * Added :all_fields option to Table helper.
119
+
120
+ == 0.2.2
121
+ * Added a friendlier default (a vertical table) to incorrectly configured tables.
122
+ * Added vertical table helper thanks to chrononaut.
123
+ * Added detection of :select option from ActiveRecord queries in ActiveRecordTable helper.
124
+ * Added handling anything that responds to :to_a in AutoTable helper.
125
+
126
+ == 0.2.1
127
+ * Fixed typo in Hirb::Console.view
128
+
129
+ == 0.2.0
130
+ * Major refactoring with bug fixes and better tests.
131
+ * Improved table algorithm to ensure that tables don't wrap.
132
+ * Added a pager which detects if output should be paged, Hirb::Pager.
133
+ * Added a selection menu, Hirb::Menu
134
+ * Following API changes: Hirb::Helpers::Table.max_width removed and config files don't use
135
+ the :view key anymore.
136
+ == 0.1.2
137
+ * Added tree views.
138
+ * Added output_method option to Hirb::View.render_output.
139
+
140
+ == 0.1.1
141
+ * Fixed bug when rendering table with many fields.
142
+
143
+ == 0.1.0
144
+ * Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT LICENSE
2
+
3
+ Copyright (c) 2010 Gabriel Horner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,194 @@
1
+ To read a linked version of this README, {click here}[http://tagaholic.me/hirb/doc/].
2
+
3
+ == Description
4
+
5
+ Hirb provides a mini view framework for console applications and uses it to improve ripl(irb)'s default inspect output.
6
+ Given an object or array of objects, hirb renders a view based on the object's class and/or ancestry. Hirb offers reusable
7
+ views in the form of helper classes. The two main helpers, Hirb::Helpers::Table and Hirb::Helpers::Tree, provide several options
8
+ for generating ascii tables and trees. Using Hirb::Helpers::AutoTable, hirb has useful default views for at least ten popular database gems
9
+ i.e. Rails' ActiveRecord::Base. Other than views, hirb offers a smart pager and a console menu. The smart pager
10
+ only pages when the output exceeds the current screen size. The menu is used in conjunction with tables to offer
11
+ {two dimensional menus}[http://tagaholic.me/2010/02/16/two-dimensional-console-menus-with-hirb.html].
12
+
13
+ == Install
14
+
15
+ Install the gem with:
16
+
17
+ gem install hirb
18
+
19
+ For people using full-width unicode characters, install {hirb-unicode}[https://github.com/miaout17/hirb-unicode]:
20
+
21
+ gem install hirb-unicode
22
+
23
+ == View Tutorials
24
+
25
+ * To create and configure views, see Hirb::View or {here if on the web}[http://tagaholic.me/hirb/doc/classes/Hirb/View.html].
26
+ * To create dynamic views, see Hirb::DynamicView or {here if on the web}[http://tagaholic.me/hirb/doc/classes/Hirb/DynamicView.html].
27
+
28
+ == Printing Ascii Tables
29
+
30
+ To print ascii tables from an array of arrays, hashes or any objects:
31
+
32
+ puts Hirb::Helpers::AutoTable.render(ARRAY_OF_OBJECTS)
33
+
34
+ Hirb will intelligently pick up on field names from an array of hashes and create properly-aligned
35
+ fields from an array of arrays. See
36
+ {here}[http://tagaholic.me/2009/10/15/boson-and-hirb-interactions.html#hirbs_handy_tables] for examples.
37
+
38
+ == Rails Example
39
+
40
+ Let's load and enable the view framework:
41
+ $ rails console
42
+ Loading local environment (Rails 3.0.3)
43
+ >> require 'hirb'
44
+ => true
45
+ >> Hirb.enable
46
+ => nil
47
+
48
+ The default configuration provides table views for ActiveRecord::Base descendants.
49
+ If a class isn't configured, Hirb reverts to irb's default echo mode.
50
+ >> Hirb::Formatter.dynamic_config['ActiveRecord::Base']
51
+ => {:class=>Hirb::Helpers::AutoTable, :ancestor=>true}
52
+
53
+ # Tag is a model class and descendant of ActiveRecord::Base
54
+ >> Tag.last
55
+ +-----+-------------------------+-------------+---------------+-----------+-----------+-------+
56
+ | id | created_at | description | name | namespace | predicate | value |
57
+ +-----+-------------------------+-------------+---------------+-----------+-----------+-------+
58
+ | 907 | 2009-03-06 21:10:41 UTC | | gem:tags=yaml | gem | tags | yaml |
59
+ +-----+-------------------------+-------------+---------------+-----------+-----------+-------+
60
+ 1 row in set
61
+
62
+ >> Hirb::Formatter.dynamic_config['String']
63
+ => nil
64
+ >> 'plain ol irb'
65
+ => 'plain ol irb'
66
+ >> Hirb::Formatter.dynamic_config['Symbol']
67
+ => nil
68
+ >> :blah
69
+ => :blah
70
+
71
+ From above you can see there are no views configured for a String or a Symbol so Hirb defaults to
72
+ irb's echo mode. On the other hand, Tag has a view thanks to being a descendant of ActiveRecord::Base
73
+ and there being an :ancestor option.
74
+
75
+ Having seen hirb display views based on an output object's class, let's see it handle an array of objects:
76
+
77
+ >> Tag.all :limit=>3, :order=>"id DESC"
78
+ +-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
79
+ | id | created_at | description | name | namespace | predicate | value |
80
+ +-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
81
+ | 907 | 2009-03-06 21:10:41 UTC | | gem:tags=yaml | gem | tags | yaml |
82
+ | 906 | 2009-03-06 08:47:04 UTC | | gem:tags=nomonkey | gem | tags | nomonkey |
83
+ | 905 | 2009-03-04 00:30:10 UTC | | article:tags=ruby | article | tags | ruby |
84
+ +-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
85
+ 3 rows in set
86
+
87
+ At any time you can disable Hirb if you really like irb's lovely echo mode:
88
+ >> Hirb.disable
89
+ => nil
90
+ >> Tag.all :limit=>3, :order=>"id DESC"
91
+ => [#<Tag id: 907, name: "gem:tags=yaml", description: nil, created_at: "2009-03-06 21:10:41",
92
+ namespace: "gem", predicate: "tags", value: "yaml">, #<Tag id: 906, name: "gem:tags=nomonkey",
93
+ description: nil, created_at: "2009-03-06 08:47:04", namespace: "gem", predicate: "tags", value:
94
+ "nomonkey">, #<Tag id: 905, name: "article:tags=ruby", description: nil, created_at: "2009-03-04
95
+ 00:30:10", namespace: "article", predicate: "tags", value: "ruby">]
96
+
97
+ == Views: Anytime, Anywhere
98
+ While preconfigured tables are great for database records, sometimes you just want to create
99
+ tables/views for any output object:
100
+
101
+ #These examples don't need to have Hirb::View enabled.
102
+ >> Hirb.disable
103
+ => nil
104
+
105
+ # Imports table() and view()
106
+ >> extend Hirb::Console
107
+ => main
108
+
109
+ # Create a unicode table
110
+ >> table [[:a, :b, :c]], :unicode => true
111
+ ┌───┬───┬───┐
112
+ │ 0 │ 1 │ 2 │
113
+ ├───┼───┼───┤
114
+ │ a ╎ b ╎ c │
115
+ └───┴───┴───┘
116
+ 1 row in set
117
+
118
+ # Create a table of Dates comparing them with different formats.
119
+ >> table [Date.today, Date.today.next_month], :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
120
+ +------------+--------+-----------+-------+--------------------------+
121
+ | to_s | ld | ajd | amjd | asctime |
122
+ +------------+--------+-----------+-------+--------------------------+
123
+ | 2009-03-11 | 155742 | 4909803/2 | 54901 | Wed Mar 11 00:00:00 2009 |
124
+ | 2009-04-11 | 155773 | 4909865/2 | 54932 | Sat Apr 11 00:00:00 2009 |
125
+ +------------+--------+-----------+-------+--------------------------+
126
+ 2 rows in set
127
+
128
+ # Same table as the previous method. However view() will be able to call any helper.
129
+ >> view [Date.today, Date.today.next_month], :class=>:object_table,
130
+ :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
131
+
132
+ If these console methods weren't convenient enough, try:
133
+
134
+ # Imports view() to all objects.
135
+ >> require 'hirb/import_object'
136
+ => true
137
+ # Yields same table as above examples.
138
+ >> [Date.today, Date.today.next_month].view :class=>:object_table,
139
+ :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
140
+
141
+ Although views by default are printed to STDOUT, they can be easily modified to write anywhere:
142
+ # Setup views to write to file 'console.log'.
143
+ >> Hirb::View.render_method = lambda {|output| File.open("console.log", 'w') {|f| f.write(output) } }
144
+
145
+ # Writes to file with same table output as above example.
146
+ >> view [Date.today, Date.today.next_month], :class=>:object_table,
147
+ :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
148
+
149
+ # Doesn't write to file because Symbol doesn't have a view and thus defaults to irb's echo mode.
150
+ >> :blah
151
+ => :blah
152
+
153
+ # Go back to printing Hirb views to STDOUT.
154
+ >> Hirb::View.reset_render_method
155
+
156
+ == Pager
157
+
158
+ Hirb has both pager and formatter functionality enabled by default.
159
+ If you want to turn off the functionality of either you can pass that in at startup:
160
+
161
+ Hirb.enable :pager=>false
162
+ Hirb.enable :formatter=>false
163
+
164
+ or toggle their state at runtime:
165
+
166
+ Hirb::View.toggle_pager
167
+ Hirb::View.toggle_formatter
168
+
169
+ == Sharing Helpers and Views
170
+ If you have tested helpers you'd like to share, fork Hirb and put them under lib/hirb/helpers. To share
171
+ views for certain classes, put them under lib/hirb/views. Please submit views for gems that have a nontrivial
172
+ number of users.
173
+
174
+ == Limitations
175
+ If using Wirble and irb, you should call Hirb after it since they both override irb's default output.
176
+
177
+ == Motivation
178
+ Table code from http://gist.github.com/72234 and {my console app's needs}[http://github.com/cldwalker/tag-tree].
179
+
180
+ == Credits
181
+ * Chrononaut for vertical table helper.
182
+ * janlelis for unicode table helper.
183
+ * crafterm, spastorino, xaviershay, bogdan, asanghi and joshua for patches.
184
+
185
+ == Bugs/Issues
186
+ Please report them {on github}[http://github.com/cldwalker/hirb/issues].
187
+
188
+ == Contributing
189
+ {See here}[http://tagaholic.me/contributing.html]
190
+
191
+ == Links
192
+ * http://tagaholic.me/2009/03/13/hirb-irb-on-the-good-stuff.html
193
+ * http://tagaholic.me/2009/03/18/ruby-class-trees-rails-plugin-trees-with-hirb.html
194
+ * http://tagaholic.me/2009/06/19/page-irb-output-and-improve-ri-with-hirb.html
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rake'
2
+ require 'fileutils'
3
+
4
+ def gemspec
5
+ @gemspec ||= eval(File.read('.gemspec'), binding, '.gemspec')
6
+ end
7
+
8
+ desc "Build the gem"
9
+ task :gem=>:gemspec do
10
+ sh "gem build .gemspec"
11
+ FileUtils.mkdir_p 'pkg'
12
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
13
+ end
14
+
15
+ desc "Install the gem locally"
16
+ task :install => :gem do
17
+ sh %{gem install pkg/#{gemspec.name}-#{gemspec.version}}
18
+ end
19
+
20
+ desc "Generate the gemspec"
21
+ task :generate do
22
+ puts gemspec.to_ruby
23
+ end
24
+
25
+ desc "Validate the gemspec"
26
+ task :gemspec do
27
+ gemspec.validate
28
+ end
29
+
30
+ desc 'Run tests'
31
+ task :test do |t|
32
+ sh 'bacon -q -Ilib -I. test/*_test.rb'
33
+ end
34
+
35
+ task :default => :test
@@ -0,0 +1,15 @@
1
+ complete(:methods=>%w{Hirb::View.enable Hirb.enable}) {
2
+ %w{config_file output_method output width height formatter pager pager_command}
3
+ }
4
+ complete(:methods=>%w{Hirb::Helpers::Table.render table}) {
5
+ %w{fields headers max_fields max_width resize number change_fields}+
6
+ %w{filters header_filter filter_any filter_classes vertical all_fields}+
7
+ %w{description escape_special_chars table_class hide_empty unicode grep_fields}
8
+ }
9
+ complete(:method=>"Hirb::Helpers::Tree.render") {
10
+ %w{type validate indent limit description multi_line_nodes value_method children_method}
11
+ }
12
+ complete(:methods=>%w{Hirb::Menu.render menu}) {
13
+ %w{helper_class prompt ask directions readline two_d default_field action multi_action} +
14
+ %w{action_object command reopen}
15
+ }
@@ -0,0 +1,43 @@
1
+ module Hirb
2
+ # This module is meant to be extended to provide methods for use in a console/irb shell.
3
+ # For example:
4
+ # >> extend Hirb::Console
5
+ # >> view 'some string', :class=>Some::String::Formatter
6
+ # >> table [[:row1], [:row2]]
7
+ module Console
8
+ class<<self
9
+ # A console version of render_output() which takes its same options but allows for shorthand. All options are passed to
10
+ # the helper except for the formatter options. Formatter options are :class, :method and :output_method.
11
+ # Examples:
12
+ # render_output output, :class=>:tree :type=>:directory
13
+ # # is the same as:
14
+ # render_output output, :class=>:tree, :options=> {:type=>:directory}
15
+ #
16
+ def render_output(output, options={})
17
+ View.load_config unless View.config_loaded?
18
+ View.render_output(output, options.merge(:console=>true))
19
+ end
20
+
21
+ # Takes same arguments and options as render_output() but returns formatted output instead of rendering it.
22
+ def format_output(output, options={}, &block)
23
+ View.load_config unless View.config_loaded?
24
+ View.formatter.format_output(output, options.merge(:console=>true), &block)
25
+ end
26
+ end
27
+
28
+ # Renders a table for the given object. Takes same options as Hirb::Helpers::Table.render.
29
+ def table(output, options={})
30
+ Console.render_output(output, options.merge(:class=>"Hirb::Helpers::AutoTable"))
31
+ end
32
+
33
+ # Renders any specified view for the given object. Takes same options as Hirb::View.render_output.
34
+ def view(output, options={})
35
+ Console.render_output(output, options)
36
+ end
37
+
38
+ # Renders a menu given an array using Hirb::Menu.render.
39
+ def menu(output, options={}, &block)
40
+ Console.format_output(output, options.merge(:class=>"Hirb::Menu"), &block)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,113 @@
1
+ module Hirb
2
+ # This module extends a Helper with the ability to have dynamic views for configured output classes.
3
+ # After a Helper has extended this module, it can use it within a render() by calling
4
+ # dynamic_options() to get dynamically generated options for the object it's rendering. See Hirb::Helpers::AutoTable as an example.
5
+ #
6
+ # == Dynamic Views
7
+ # Whereas normal views are generated from helpers with static helper options, dynamic views are generated from helpers and
8
+ # dynamically generated helper options. Let's look at an example for Rails' ActiveRecord classes:
9
+ #
10
+ # Hirb.add_dynamic_view("ActiveRecord::Base", :helper=>:auto_table) {|obj|
11
+ # {:fields=>obj.class.column_names} }
12
+ #
13
+ # From this dynamic view definition, _any_ ActiveRecord model class will render a table with the correct fields, since the fields
14
+ # are extracted from the output object's class at runtime. Note that dynamic view definitions should return a hash of helper options.
15
+ #
16
+ # To define multiple dynamic views, create a Views module where each method ending in '\_view' maps to a class/module:
17
+ #
18
+ # module Hirb::Views::ORM
19
+ # def data_mapper__resource_view(obj)
20
+ # {:fields=>obj.class.properties.map {|e| e.name }}
21
+ # end
22
+ #
23
+ # def sequel__model_view(obj)
24
+ # {:fields=>obj.class.columns}
25
+ # end
26
+ # end
27
+ #
28
+ # Hirb.add_dynamic_view Hirb::Views::ORM, :helper=>:auto_table
29
+ #
30
+ # In this example, 'data_mapper__resource_view' maps to DataMapper::Resource and 'sequel__model_view' maps to Sequel::Model.
31
+ # Note that when mapping method names to class names, '__' maps to '::' and '_' signals the next letter to be capitalized.
32
+ module DynamicView
33
+ # Add dynamic views to output class(es) for a given helper. If defining one view, the first argument is the output class
34
+ # and a block defines the dynamic view. If defining multiple views, the first argument should be a Views::* module where
35
+ # each method in the module ending in _view defines a view for an output class. To map output classes to method names in
36
+ # a Views module, translate'::' to '__' and a capital letter translates to a '_' and a lowercase letter.
37
+ # ==== Options:
38
+ # [*:helper*] Required option. Helper class that view(s) use to format. Hirb::Helpers::AutoTable is the only valid
39
+ # helper among default helpers. Can be given in aliased form i.e. :auto_table -> Hirb::Helpers::AutoTable.
40
+ #
41
+ # Examples:
42
+ # Hirb.add_dynamic_view Hirb::Views::ORM, :helper=>:auto_table
43
+ # Hirb.add_dynamic_view("ActiveRecord::Base", :helper=>:auto_table) {|obj| {:fields=>obj.class.column_names} }
44
+ def self.add(view, options, &block)
45
+ raise ArgumentError, ":helper option is required" unless options[:helper]
46
+ helper = Helpers.helper_class options[:helper]
47
+ unless helper.is_a?(Module) && class << helper; self.ancestors; end.include?(self)
48
+ raise ArgumentError, ":helper option must be a helper that has extended DynamicView"
49
+ end
50
+ mod = block ? generate_single_view_module(view, &block) : view
51
+ raise ArgumentError, "'#{mod}' must be a module" unless mod.is_a?(Module)
52
+ helper.add_module mod
53
+ end
54
+
55
+ def self.generate_single_view_module(output_mod, &block) #:nodoc:
56
+ meth = class_to_method output_mod.to_s
57
+ view_mod = meth.capitalize
58
+ Views::Single.send(:remove_const, view_mod) if Views::Single.const_defined?(view_mod)
59
+ mod = Views::Single.const_set(view_mod, Module.new)
60
+ mod.send(:define_method, meth, block)
61
+ mod
62
+ end
63
+
64
+ def self.class_to_method(mod) #:nodoc:
65
+ mod.gsub(/(?!^)([A-Z])/) {|e| '_'+e }.gsub('::_', '__').downcase + '_view'
66
+ end
67
+
68
+ # Returns a hash of options based on dynamic views defined for the object's ancestry. If no config is found returns nil.
69
+ def dynamic_options(obj)
70
+ view_methods.each do |meth|
71
+ if obj.class.ancestors.map {|e| e.to_s }.include?(method_to_class(meth))
72
+ begin
73
+ return send(meth, obj)
74
+ rescue
75
+ raise "View failed to generate for '#{method_to_class(meth)}' "+
76
+ "while in '#{meth}' with error:\n#{$!.message}"
77
+ end
78
+ end
79
+ end
80
+ nil
81
+ end
82
+
83
+ #:stopdoc:
84
+ def add_module(mod)
85
+ new_methods = mod.instance_methods.select {|e| e.to_s =~ /_view$/ }.map {|e| e.to_s}
86
+ return if new_methods.empty?
87
+ extend mod
88
+ view_methods.replace(view_methods + new_methods).uniq!
89
+ update_config(new_methods)
90
+ end
91
+
92
+ def update_config(meths)
93
+ output_config = meths.inject({}) {|t,e|
94
+ t[method_to_class(e)] = {:class=>self, :ancestor=>true}; t
95
+ }
96
+ Formatter.dynamic_config.merge! output_config
97
+ end
98
+
99
+ def method_to_class(meth)
100
+ view_method_classes[meth] ||= Util.camelize meth.sub(/_view$/, '').gsub('__', '/')
101
+ end
102
+
103
+ def view_method_classes
104
+ @view_method_classes ||= {}
105
+ end
106
+ #:startdoc:
107
+
108
+ # Stores view methods that a Helper has been given via DynamicView.add
109
+ def view_methods
110
+ @view_methods ||= []
111
+ end
112
+ end
113
+ end