xiki 0.5.0a
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.
- data/Gemfile +11 -0
- data/LICENSE +22 -0
- data/README.markdown +83 -0
- data/Rakefile +8 -0
- data/bin/xiki +46 -0
- data/etc/command/xiki_command.rb +203 -0
- data/etc/command/xiki_process.rb +52 -0
- data/etc/command/xiki_wrapper +2 -0
- data/etc/js/menu1.js +55 -0
- data/etc/js/xiki.js +259 -0
- data/etc/logo.png +0 -0
- data/etc/presentations/bootstrap.deck +5 -0
- data/etc/presentations/databases.deck +41 -0
- data/etc/presentations/diffs.deck +23 -0
- data/etc/presentations/documentation.deck +14 -0
- data/etc/presentations/effects.deck +5 -0
- data/etc/presentations/face.deck +297 -0
- data/etc/presentations/files.deck +79 -0
- data/etc/presentations/icons.deck +22 -0
- data/etc/presentations/images.deck +24 -0
- data/etc/presentations/key_shortcuts.deck +16 -0
- data/etc/presentations/macros.deck +18 -0
- data/etc/presentations/menu_classes.deck +44 -0
- data/etc/presentations/menu_directories.deck +30 -0
- data/etc/presentations/notes.deck +19 -0
- data/etc/presentations/other_languages.deck +55 -0
- data/etc/presentations/other_wiki_syntaxes.deck +4 -0
- data/etc/presentations/piano.deck +5 -0
- data/etc/presentations/potential/diffs.deck +38 -0
- data/etc/presentations/potential/evolution.deck +18 -0
- data/etc/presentations/potential/intro.deck +711 -0
- data/etc/presentations/potential/intro1.deck +711 -0
- data/etc/presentations/potential/intro2.deck +97 -0
- data/etc/presentations/potential/make_mysql_menu.deck +36 -0
- data/etc/presentations/potential/ruby_development.deck +17 -0
- data/etc/presentations/potential/ui_prototyping.deck +50 -0
- data/etc/presentations/potential/web_dev.deck +4 -0
- data/etc/presentations/potential/web_development.deck +10 -0
- data/etc/presentations/potential/wiki.deck +45 -0
- data/etc/presentations/presentations.deck +24 -0
- data/etc/presentations/rails_development.deck +29 -0
- data/etc/presentations/search_key_shortcuts.deck +37 -0
- data/etc/presentations/simplest_possible_ui.deck +37 -0
- data/etc/presentations/svg.deck +5 -0
- data/etc/presentations/testing.deck +28 -0
- data/etc/presentations/the_end.deck +13 -0
- data/etc/presentations/type_something_and_double_click.deck +57 -0
- data/etc/presentations/type_the_acronym.deck +144 -0
- data/etc/presentations/web_browser.deck +56 -0
- data/etc/presentations/xiki_command.deck +20 -0
- data/etc/presentations/xiki_url.deck +14 -0
- data/etc/shark.icns +0 -0
- data/etc/shark_script.icns +0 -0
- data/etc/snippets/html.notes +7 -0
- data/etc/snippets/notes.notes +20 -0
- data/etc/snippets/rb.notes +38 -0
- data/etc/templates/menu_template.menu +2 -0
- data/etc/templates/menu_template.rb +8 -0
- data/etc/templates/template.rb +5 -0
- data/etc/themes/Dark_Metal.notes +28 -0
- data/etc/themes/Orange_Path.notes +15 -0
- data/etc/themes/Shiny_Blue.notes +27 -0
- data/etc/themes/Shiny_Green.notes +27 -0
- data/etc/wrappers/wrapper.js +17 -0
- data/etc/wrappers/wrapper.py +20 -0
- data/etc/wrappers/wrapper.rb +25 -0
- data/lib/block.rb +72 -0
- data/lib/bookmarks.rb +352 -0
- data/lib/buffers.rb +170 -0
- data/lib/clipboard.rb +333 -0
- data/lib/code.rb +860 -0
- data/lib/code_tree.rb +476 -0
- data/lib/color.rb +274 -0
- data/lib/console.rb +557 -0
- data/lib/control_lock.rb +9 -0
- data/lib/control_tab.rb +176 -0
- data/lib/core_ext.rb +31 -0
- data/lib/cursor.rb +111 -0
- data/lib/deletes.rb +65 -0
- data/lib/diff_log.rb +297 -0
- data/lib/effects.rb +145 -0
- data/lib/environment.rb +5 -0
- data/lib/file_tree.rb +1875 -0
- data/lib/files.rb +334 -0
- data/lib/hide.rb +259 -0
- data/lib/history.rb +286 -0
- data/lib/image.rb +51 -0
- data/lib/incrementer.rb +15 -0
- data/lib/insert.rb +7 -0
- data/lib/irc.rb +22 -0
- data/lib/key_bindings.rb +658 -0
- data/lib/keys.rb +754 -0
- data/lib/launcher.rb +1351 -0
- data/lib/line.rb +429 -0
- data/lib/links.rb +6 -0
- data/lib/location.rb +175 -0
- data/lib/macros.rb +48 -0
- data/lib/man.rb +19 -0
- data/lib/menu.rb +708 -0
- data/lib/merb.rb +259 -0
- data/lib/message.rb +5 -0
- data/lib/meths.rb +56 -0
- data/lib/mode.rb +34 -0
- data/lib/move.rb +248 -0
- data/lib/notes.rb +1000 -0
- data/lib/numbers.rb +45 -0
- data/lib/ol.rb +203 -0
- data/lib/ol_helper.rb +44 -0
- data/lib/overlay.rb +167 -0
- data/lib/pause_means_space.rb +68 -0
- data/lib/php.rb +22 -0
- data/lib/projects.rb +21 -0
- data/lib/relinquish_exception.rb +2 -0
- data/lib/remote.rb +206 -0
- data/lib/requirer.rb +46 -0
- data/lib/rest_tree.rb +108 -0
- data/lib/ruby.rb +57 -0
- data/lib/ruby_console.rb +165 -0
- data/lib/search.rb +1572 -0
- data/lib/search_term.rb +40 -0
- data/lib/snippet.rb +68 -0
- data/lib/specs.rb +229 -0
- data/lib/styles.rb +274 -0
- data/lib/svn.rb +682 -0
- data/lib/text_util.rb +110 -0
- data/lib/tree.rb +1871 -0
- data/lib/tree_cursor.rb +87 -0
- data/lib/trouble_shooting.rb +27 -0
- data/lib/url_tree.rb +11 -0
- data/lib/view.rb +1474 -0
- data/lib/window.rb +133 -0
- data/lib/xiki.rb +404 -0
- data/menus/accounts.rb +5 -0
- data/menus/address_book.rb +21 -0
- data/menus/agenda.rb +28 -0
- data/menus/all.rb +5 -0
- data/menus/amazon.rb +16 -0
- data/menus/app.rb +16 -0
- data/menus/applescript.rb +46 -0
- data/menus/as.rb +15 -0
- data/menus/bookmarklet.rb +63 -0
- data/menus/bootstrap.rb +568 -0
- data/menus/browse.rb +13 -0
- data/menus/browser.rb +78 -0
- data/menus/cassandra_db.rb +36 -0
- data/menus/chmod.rb +27 -0
- data/menus/classes.rb +5 -0
- data/menus/coffee_script.rb +35 -0
- data/menus/computer.rb +24 -0
- data/menus/contacts.rb +5 -0
- data/menus/cookies.rb +25 -0
- data/menus/couch.rb +184 -0
- data/menus/crop.rb +45 -0
- data/menus/css.rb +55 -0
- data/menus/current.rb +5 -0
- data/menus/db.rb +12 -0
- data/menus/deck.rb +219 -0
- data/menus/dictionary.rb +9 -0
- data/menus/dir.rb +8 -0
- data/menus/disk.rb +5 -0
- data/menus/do.rb +13 -0
- data/menus/docs.rb +58 -0
- data/menus/dotsies.rb +107 -0
- data/menus/edited.rb +18 -0
- data/menus/emacs.rb +17 -0
- data/menus/enter.rb +13 -0
- data/menus/eval.rb +17 -0
- data/menus/executable.rb +16 -0
- data/menus/filter.rb +46 -0
- data/menus/firefox.rb +607 -0
- data/menus/foo.rb +30 -0
- data/menus/french.rb +7 -0
- data/menus/git.rb +185 -0
- data/menus/gito.rb +785 -0
- data/menus/google.rb +35 -0
- data/menus/google_images.rb +11 -0
- data/menus/google_patents.rb +10 -0
- data/menus/gutenberg.rb +13 -0
- data/menus/head.rb +10 -0
- data/menus/headings.rb +39 -0
- data/menus/html.rb +61 -0
- data/menus/icon.rb +40 -0
- data/menus/images.menu +2 -0
- data/menus/img.rb +15 -0
- data/menus/info.rb +9 -0
- data/menus/ip.rb +10 -0
- data/menus/iterm.rb +36 -0
- data/menus/itunes.rb +78 -0
- data/menus/javascript.rb +74 -0
- data/menus/layout.rb +18 -0
- data/menus/local_storage.rb +67 -0
- data/menus/ls.rb +19 -0
- data/menus/mac.rb +87 -0
- data/menus/maps.rb +18 -0
- data/menus/matches.rb +18 -0
- data/menus/memcache.rb +117 -0
- data/menus/mkdir.rb +23 -0
- data/menus/mongo.rb +83 -0
- data/menus/mysql.rb +294 -0
- data/menus/node.rb +88 -0
- data/menus/open.rb +19 -0
- data/menus/outline.rb +24 -0
- data/menus/piano.rb +746 -0
- data/menus/postgres.rb +34 -0
- data/menus/pre.rb +5 -0
- data/menus/python.rb +39 -0
- data/menus/rails.rb +160 -0
- data/menus/rake.rb +12 -0
- data/menus/redmine.rb +168 -0
- data/menus/riak_tree.rb +204 -0
- data/menus/rss.rb +15 -0
- data/menus/safari.rb +11 -0
- data/menus/sass.rb +15 -0
- data/menus/say.rb +6 -0
- data/menus/scale.rb +49 -0
- data/menus/serve.rb +78 -0
- data/menus/shuffle.rb +24 -0
- data/menus/spanish.rb +7 -0
- data/menus/standalone.rb +57 -0
- data/menus/tail.rb +41 -0
- data/menus/technologies.rb +19 -0
- data/menus/themes.rb +32 -0
- data/menus/thesaurus.rb +13 -0
- data/menus/to.rb +24 -0
- data/menus/twitter.rb +57 -0
- data/menus/wikipedia.rb +34 -0
- data/menus/words.rb +11 -0
- data/spec/code_tree_spec.rb +59 -0
- data/spec/diff_log_spec.rb +40 -0
- data/spec/file_tree_spec.rb +102 -0
- data/spec/keys_spec.rb +24 -0
- data/spec/line_spec.rb +68 -0
- data/spec/menu_spec.rb +50 -0
- data/spec/ol_spec.rb +98 -0
- data/spec/remote_spec.rb +43 -0
- data/spec/search_spec.rb +162 -0
- data/spec/text_util_spec.rb +119 -0
- data/spec/tree_cursor_spec.rb +91 -0
- data/spec/tree_spec.rb +955 -0
- data/tests/console_test.rb +11 -0
- data/tests/couch_db_test.rb +12 -0
- data/tests/diff_log_test.rb +43 -0
- data/tests/el_mixin.rb +16 -0
- data/tests/git_test.rb +95 -0
- data/tests/keys_test.rb +19 -0
- data/tests/line_test.rb +38 -0
- data/tests/merb_test.rb +11 -0
- data/tests/redmine_test.rb +50 -0
- data/tests/remote_test.rb +31 -0
- data/tests/rest_tree_test.rb +70 -0
- data/xiki.gemspec +37 -0
- metadata +332 -0
data/menus/postgres.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Postgres
|
|
2
|
+
|
|
3
|
+
def self.name= name
|
|
4
|
+
@@name = name
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.menu name=nil
|
|
8
|
+
|
|
9
|
+
# If no name, list all names
|
|
10
|
+
if name.nil?
|
|
11
|
+
return Console.run("psql -c '\\l'", :sync=>true).scan(/^ (\w+)/).map{|i| "- #{i}/"}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
puts "
|
|
15
|
+
- .tables/
|
|
16
|
+
- .create_db :foo
|
|
17
|
+
- .drop_db :foo
|
|
18
|
+
"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.create_db name
|
|
22
|
+
Console.run "createdb #{name}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.drop_db name
|
|
26
|
+
Console.run "dropdb #{name}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.tables db
|
|
30
|
+
db.sub! /\/$/, ''
|
|
31
|
+
txt = Console.run "psql #{db} -c '\\d'", :sync=>true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
data/menus/pre.rb
ADDED
data/menus/python.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class Python
|
|
2
|
+
def self.menu
|
|
3
|
+
"
|
|
4
|
+
> Pass python code to run
|
|
5
|
+
| print('hey')
|
|
6
|
+
"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.menu_after txt, *args
|
|
10
|
+
# Do nothing if .menu created output
|
|
11
|
+
return nil if txt
|
|
12
|
+
|
|
13
|
+
txt = ENV['txt']
|
|
14
|
+
return nil if txt.nil?
|
|
15
|
+
|
|
16
|
+
txt = Python.run_internal txt
|
|
17
|
+
txt
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.run_block
|
|
21
|
+
# Get block contents
|
|
22
|
+
txt, left, right = View.txt_per_prefix #:prefix=>Keys.prefix
|
|
23
|
+
|
|
24
|
+
result = self.run_internal txt
|
|
25
|
+
# Insert result at end of block
|
|
26
|
+
orig = Location.new
|
|
27
|
+
View.cursor = right
|
|
28
|
+
Line.to_left
|
|
29
|
+
View.insert result.gsub(/^/, ' ')
|
|
30
|
+
orig.go
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.run_internal txt
|
|
34
|
+
# Write to temp file
|
|
35
|
+
File.open("/tmp/tmp.py", "w") { |f| f << txt }
|
|
36
|
+
# Call js
|
|
37
|
+
Console.run "python /tmp/tmp.py", :sync=>true
|
|
38
|
+
end
|
|
39
|
+
end
|
data/menus/rails.rb
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
require "ruby_console"
|
|
2
|
+
|
|
3
|
+
class Rails
|
|
4
|
+
|
|
5
|
+
CODE_SAMPLES = %q<
|
|
6
|
+
# Show options to help create new rails app
|
|
7
|
+
- Show options: Rails.menu
|
|
8
|
+
>
|
|
9
|
+
|
|
10
|
+
def self.menu
|
|
11
|
+
"
|
|
12
|
+
- .start/
|
|
13
|
+
- .generate/
|
|
14
|
+
- app/
|
|
15
|
+
- model/
|
|
16
|
+
- resource/
|
|
17
|
+
- controller/
|
|
18
|
+
- scaffold/
|
|
19
|
+
- .interact/
|
|
20
|
+
- .rails console/
|
|
21
|
+
- .sqlite console/
|
|
22
|
+
- .models/
|
|
23
|
+
- .setup/
|
|
24
|
+
- .db/
|
|
25
|
+
- .migrate/
|
|
26
|
+
- .use rspec/
|
|
27
|
+
- .general/
|
|
28
|
+
- .rails version/
|
|
29
|
+
"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.menu_after txt, *args
|
|
33
|
+
txt
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.menu_before *path
|
|
37
|
+
|
|
38
|
+
dir = Projects.current # Returns dir in tree, or current project (top of projects.menu)
|
|
39
|
+
|
|
40
|
+
# Don't intercede if already rails app or trying to generate
|
|
41
|
+
return nil if ["generate", "general"].member?(path[0]) || File.exists?("#{dir}app")
|
|
42
|
+
|
|
43
|
+
# If not a rails dir, give option to generate
|
|
44
|
+
return "
|
|
45
|
+
| No rails app in #{dir} yet. Generate it?
|
|
46
|
+
- generate/app/
|
|
47
|
+
|
|
48
|
+
| Not project-specific
|
|
49
|
+
- general/
|
|
50
|
+
"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.rails_version
|
|
54
|
+
"| #{`rails --version`}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.use_rspec
|
|
58
|
+
dir = Projects.current
|
|
59
|
+
|
|
60
|
+
txt = "
|
|
61
|
+
@ #{dir}
|
|
62
|
+
- 1. Add these lines:
|
|
63
|
+
- Gemfile
|
|
64
|
+
|+group :development, :test do
|
|
65
|
+
|+ gem 'rspec-rails'
|
|
66
|
+
|+end
|
|
67
|
+
|
|
|
68
|
+
- 2. Run these commands:
|
|
69
|
+
% bundle
|
|
70
|
+
% rails g rspec:install
|
|
71
|
+
|
|
|
72
|
+
- 3. Delete the test/ dir:
|
|
73
|
+
% rm -r test/
|
|
74
|
+
"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def self.models
|
|
79
|
+
dir = Projects.current
|
|
80
|
+
dir = "#{dir}app/models/"
|
|
81
|
+
|
|
82
|
+
entries = Dir.new(dir).entries.select{|o| o =~ /^\w/}
|
|
83
|
+
entries.map{|o| "@r/#{TextUtil.camel_case o[/\w+/]}.first/"}.join("\n")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.sqlite_console
|
|
87
|
+
Console.run "sqlite3 db/development.sqlite3", :dir=>Projects.current, :buffer=>"sqlite console"
|
|
88
|
+
".flash - opened console!"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.rails_console
|
|
92
|
+
Console.run "rails c", :dir=>Projects.current, :buffer=>"rails console"
|
|
93
|
+
".flash - opened console!"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.generate what, name=nil, detail=nil
|
|
97
|
+
|
|
98
|
+
examples = "
|
|
99
|
+
> Example fields
|
|
100
|
+
| id:primary_key
|
|
101
|
+
| name:string
|
|
102
|
+
| description:text
|
|
103
|
+
| quantity:integer
|
|
104
|
+
| price:decimal
|
|
105
|
+
| purchased_at:datetime
|
|
106
|
+
| delivery:boolean
|
|
107
|
+
| user:references
|
|
108
|
+
".unindent
|
|
109
|
+
|
|
110
|
+
case what
|
|
111
|
+
when "app"
|
|
112
|
+
Console.run "rails new . --skip-bundle", :dir=>Projects.current
|
|
113
|
+
return "- generating rails app..."
|
|
114
|
+
when "model", "resource", "scaffold"
|
|
115
|
+
return View.prompt "Enter a name" if ! name
|
|
116
|
+
return examples if ! detail
|
|
117
|
+
fields = ENV['txt'].gsub("\n", ' ').strip
|
|
118
|
+
Console.run "rails g #{what} #{name} #{fields}", :dir=>Projects.current
|
|
119
|
+
return "- generating #{what}..."
|
|
120
|
+
when "controller"
|
|
121
|
+
return View.prompt "Enter a name" if ! name
|
|
122
|
+
return View.prompt "Enter an action" if ! detail
|
|
123
|
+
Console.run "rails g controller #{name} #{detail}", :dir=>Projects.current
|
|
124
|
+
return "- generating controller..."
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
"- Don't know how to generate a '#{what}'!"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def self.start *args
|
|
131
|
+
|
|
132
|
+
# If 1st arg is number, assume it's the port
|
|
133
|
+
port = args[0] =~ /^\d+$/ ? args.shift : nil
|
|
134
|
+
|
|
135
|
+
# If 'browse', just bring up in browser
|
|
136
|
+
if args == ['browse']
|
|
137
|
+
Firefox.url "http://localhost:#{port || 3000}/"
|
|
138
|
+
return ".flash - opened in browser!"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
command = "rails s"
|
|
142
|
+
command << " -p #{port}" if port
|
|
143
|
+
|
|
144
|
+
Console.run command, :dir=>Projects.current, :buffer=>"rails server"
|
|
145
|
+
|
|
146
|
+
# Check whether it's already running
|
|
147
|
+
"| Rails app was already running\n- browse/"
|
|
148
|
+
"| Starting rails app...\n- browse/"
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def self.command txt
|
|
153
|
+
Console.run txt, :dir=>Projects.current
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def self.migrate
|
|
157
|
+
self.command "rake db:migrate"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
data/menus/rake.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Rake
|
|
2
|
+
def self.menu task=nil
|
|
3
|
+
|
|
4
|
+
if task.nil? # If no task passed, show all
|
|
5
|
+
txt = Console.run 'rake -T', :sync=>true
|
|
6
|
+
return "- Error: no rake file." if txt =~ /^No Rakefile found/
|
|
7
|
+
return txt.scan(/^rake ([\w:]+)/).join("\n")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Console.run "rake #{task}" # If task passed, run it
|
|
11
|
+
end
|
|
12
|
+
end
|
data/menus/redmine.rb
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'uri'
|
|
3
|
+
require 'timeout'
|
|
4
|
+
require 'keys'
|
|
5
|
+
|
|
6
|
+
class Redmine
|
|
7
|
+
|
|
8
|
+
@@url ||= 'http://foo.com:80/wiki/1'
|
|
9
|
+
def self.url= to; @@url = to; end
|
|
10
|
+
def self.url; @@url; end
|
|
11
|
+
|
|
12
|
+
def self.menu
|
|
13
|
+
puts "
|
|
14
|
+
+ .pages/
|
|
15
|
+
- .start
|
|
16
|
+
- local: http://localhost:3401/wiki/gateway
|
|
17
|
+
- remote: http://rlitio.chase.com:3401/wiki/1
|
|
18
|
+
"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.pages page=nil
|
|
22
|
+
if page # If page was passed, open it
|
|
23
|
+
self.open page
|
|
24
|
+
return
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Otherwise, print list
|
|
28
|
+
t = self.http_get "#{@@url}/Page_index/special" rescue return
|
|
29
|
+
t.scan(/<a href="\/wiki\/1\/([\w-]+)"/) { |m| puts "- #{m[0]}" }
|
|
30
|
+
""
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.redmine_to_xiki txt
|
|
34
|
+
|
|
35
|
+
# Angle brackets
|
|
36
|
+
txt.gsub!('<', '<'); txt.gsub!('>', '>')
|
|
37
|
+
txt.gsub!('&', '&'); txt.gsub!('"', '"')
|
|
38
|
+
|
|
39
|
+
(1..7).to_a.reverse.each do |i| # Headers
|
|
40
|
+
txt.gsub!(/^#{'#' * i}/, "#{'|' * i} ")
|
|
41
|
+
end
|
|
42
|
+
(1..9).to_a.reverse.each do |i| # Bullets
|
|
43
|
+
txt.gsub!(/^#{'\\*' * i}/, "#{' ' * (i-1)}-")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
txt
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.xiki_to_redmine txt
|
|
50
|
+
# Headers (h1. etc)
|
|
51
|
+
(1..7).to_a.reverse.each { |i| txt.gsub!(/^#{'\\|' * i} /, "#{'#' * i}") }
|
|
52
|
+
(1..9).to_a.reverse.each { |i| txt.gsub!(/^#{' ' * (i-1)}-/, "#{'*' * i}") }
|
|
53
|
+
txt
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.open name
|
|
57
|
+
|
|
58
|
+
# TODO grab token into a buffer name
|
|
59
|
+
version = "no_version"
|
|
60
|
+
wiki, version = self.page_from_server name
|
|
61
|
+
self.redmine_to_xiki wiki
|
|
62
|
+
View.to_after_bar
|
|
63
|
+
View.to_buffer("redmine/#{name}/#{version}")
|
|
64
|
+
|
|
65
|
+
# Set mode and use relevant key shortcuts
|
|
66
|
+
Notes.mode; $el.use_local_map $el.elvar.redmine_mode_map
|
|
67
|
+
self.apply_styles
|
|
68
|
+
|
|
69
|
+
if View.empty? # If nothing there yet, insert
|
|
70
|
+
$el.insert wiki
|
|
71
|
+
end
|
|
72
|
+
Move.top
|
|
73
|
+
""
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.page_from_server name
|
|
77
|
+
|
|
78
|
+
t = self.http_get "#{@@url}/#{name}/edit" rescue
|
|
79
|
+
return
|
|
80
|
+
version = t[/<input id="content_version".+value="(\d+)"/, 1]
|
|
81
|
+
wiki = t[/<textarea.*?>(.+)<\/textarea>/m, 1]
|
|
82
|
+
wiki.gsub!("\C-m", '')
|
|
83
|
+
[wiki, version]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.save
|
|
87
|
+
name, version = View.buffer_name.split('/')[1..2]
|
|
88
|
+
txt = View.txt # Get text from buffer
|
|
89
|
+
return puts("- Not a redmine page!") unless txt
|
|
90
|
+
self.xiki_to_redmine txt
|
|
91
|
+
|
|
92
|
+
# Get text from server
|
|
93
|
+
server_txt, server_version = self.page_from_server name
|
|
94
|
+
|
|
95
|
+
# If version is same, save
|
|
96
|
+
if version == server_version
|
|
97
|
+
res = Net::HTTP.post_form(URI.parse("#{@@url}/#{name}/edit"), { # Save
|
|
98
|
+
'content[version]' => version, 'content[text]' => txt
|
|
99
|
+
})
|
|
100
|
+
message "- page saved"
|
|
101
|
+
$el.rename_buffer "redmine/#{name}/#{version.to_i + 1}" # Rename
|
|
102
|
+
else # Otherwise show diff
|
|
103
|
+
message "- wrong version, show diffs!"
|
|
104
|
+
View.to_buffer "*redmine_collision: #{name}/#{server_version}"
|
|
105
|
+
notes_mode; $el.use_local_map $el.elvar.redmine_mode_map
|
|
106
|
+
|
|
107
|
+
View.clear
|
|
108
|
+
$el.insert "- collision with #{name}/#{server_version}!\n\n"
|
|
109
|
+
$el.insert self.diff(server_txt, txt)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.http_get url
|
|
114
|
+
t = nil
|
|
115
|
+
begin
|
|
116
|
+
timeout(2) do
|
|
117
|
+
t = Net::HTTP.get URI.parse(url)
|
|
118
|
+
end
|
|
119
|
+
rescue Exception => e
|
|
120
|
+
puts "- Couldn't connect to url (#{url}): #{e.message}!"
|
|
121
|
+
raise e
|
|
122
|
+
end
|
|
123
|
+
t
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.init
|
|
127
|
+
unless $el.boundp :redmine_mode_map
|
|
128
|
+
# Create new map
|
|
129
|
+
$el.elvar.redmine_mode_map = $el.make_sparse_keymap
|
|
130
|
+
# Inherit notes_mode_map!
|
|
131
|
+
$el.set_keymap_parent $el.elvar.redmine_mode_map, $el.elvar.notes_mode_map
|
|
132
|
+
end
|
|
133
|
+
Keys.XS(:redmine_mode_map) { Redmine.save }
|
|
134
|
+
|
|
135
|
+
# Make C-. follow link
|
|
136
|
+
Launcher.add(/\[\[.+\]\]/) do |line| # Redmine wiki links
|
|
137
|
+
name = line[/\[\[(.+?)\]\]/, 1]
|
|
138
|
+
name.gsub!(/ /, "_")
|
|
139
|
+
Redmine.open(name)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def self.diff a, b
|
|
144
|
+
temp_path_a = "/tmp/diff_tmp_a.txt"
|
|
145
|
+
temp_path_b = "/tmp/diff_tmp_b.txt"
|
|
146
|
+
File.open(temp_path_a, "w") { |f| f << a }
|
|
147
|
+
File.open(temp_path_b, "w") { |f| f << b }
|
|
148
|
+
diff = $el.shell_command_to_string "diff -w -U 0 \"#{temp_path_a}\" \"#{temp_path_b}\""
|
|
149
|
+
DiffLog.format("server/", "diff/", diff)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def self.apply_styles
|
|
153
|
+
# Strikethrough
|
|
154
|
+
Styles.define(:strike, :strike => true)
|
|
155
|
+
Styles.apply("^ *- \\(-.+-\\)$", nil, :strike)
|
|
156
|
+
# _italic_
|
|
157
|
+
Styles.define(:redmine_green, :bold => true, :fg => "33dd33")
|
|
158
|
+
Styles.apply(" _[a-zA-Z0-9 ]+_ ", :redmine_green)
|
|
159
|
+
Styles.apply(" _[a-zA-Z0-9 ]+_$", :redmine_green)
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def self.start
|
|
164
|
+
Rails.start '$o/redmine/trunk', @@url[/\d+/]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
# Redmine.init
|
data/menus/riak_tree.rb
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
gem 'httparty'; require 'httparty'
|
|
2
|
+
gem 'json'; require 'json'
|
|
3
|
+
gem 'riak-client'; require 'riak'
|
|
4
|
+
|
|
5
|
+
module Riak
|
|
6
|
+
|
|
7
|
+
RIAK_URL = "http://127.0.0.1:8098"
|
|
8
|
+
|
|
9
|
+
def self.menu
|
|
10
|
+
[ ".buckets/",
|
|
11
|
+
".index/",
|
|
12
|
+
".filter/",
|
|
13
|
+
".get 'foo/bar'",
|
|
14
|
+
".help/",
|
|
15
|
+
".log/",
|
|
16
|
+
".ping/",
|
|
17
|
+
]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.buckets bucket=nil, key=nil, txt=nil
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if key
|
|
24
|
+
key.sub! /\/$/, ''
|
|
25
|
+
key.gsub! '/', '%2F'
|
|
26
|
+
key.sub! /^"(.*)"$/, "\\1"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
bucket.sub! /\/$/, '' if bucket
|
|
30
|
+
|
|
31
|
+
if txt
|
|
32
|
+
# If 0, delete
|
|
33
|
+
if Keys.prefix == 0
|
|
34
|
+
self.delete "#{bucket}/#{key}"
|
|
35
|
+
return "- deleted!"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Save text if txt passed
|
|
39
|
+
txt = Tree.siblings :string=>true
|
|
40
|
+
|
|
41
|
+
data = YAML::load(txt)
|
|
42
|
+
|
|
43
|
+
self.put "#{bucket}/#{key}", YAML::load(txt)
|
|
44
|
+
|
|
45
|
+
return "- saved!"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Show contents of object if passed
|
|
49
|
+
if key
|
|
50
|
+
Files.append "~/.emacs.d/riak_log.notes", "- Riak.buckets \"#{bucket}\", \"#{key}\"/"
|
|
51
|
+
|
|
52
|
+
key = "#{bucket}/#{key}"
|
|
53
|
+
|
|
54
|
+
begin
|
|
55
|
+
return self.get_hash(key).to_yaml.sub(/^--- \n/, '').gsub(/^/, '| ')
|
|
56
|
+
rescue Exception=>e
|
|
57
|
+
return self.get_hash(key, :raw=>true).gsub(/^/, '| ')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
# Show contents of bucket if passed
|
|
61
|
+
return self.get_hash("#{bucket}?keys=true")['keys'].sort.map{|o| "#{o}/"} if bucket
|
|
62
|
+
# Nothing passed, so list buckets
|
|
63
|
+
self.get_hash("?buckets=true")["buckets"].sort.map{|o| "#{o}/"}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.filter bucket=nil, *args
|
|
67
|
+
bucket.sub! /\/$/, '' if bucket
|
|
68
|
+
|
|
69
|
+
if args.any?
|
|
70
|
+
args = args.join(', ').sub(/\/$/, '')
|
|
71
|
+
|
|
72
|
+
Files.append "~/.emacs.d/riak_log.notes", "- Riak.filter \"#{bucket}\", #{args}/"
|
|
73
|
+
|
|
74
|
+
args = eval "[#{args}]"
|
|
75
|
+
|
|
76
|
+
results = Riak::MapReduce.new(Riak::Client.new).
|
|
77
|
+
add(bucket, args).
|
|
78
|
+
map("function(v){ return [v.key]; }", :keep => true).
|
|
79
|
+
run
|
|
80
|
+
|
|
81
|
+
return results.sort.reverse.to_yaml.sub(/\A--- \n/, '').gsub(/^/, '| ')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if bucket # Examples
|
|
85
|
+
return ["['matches', 'b']/", "['starts_with', 'a']/", "['between', 'a', 'b']/", "['or', [['eq', 'a']], [['less_than', 'g']]]/", "['tokenize', '-', 1], ['eq', 'basho']/"]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
self.buckets # Delegate to .buckets to list buckets
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def self.index bucket=nil, search=nil
|
|
93
|
+
|
|
94
|
+
if search
|
|
95
|
+
results = self.get_hash "#{bucket}/index/#{search}", :root=>'buckets'#, :raw=>'true'
|
|
96
|
+
return results.to_yaml.gsub(/^/, '| ')
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if bucket # Examples
|
|
100
|
+
return ["zip_bin/eq/43215/", "zip_bin/range/40000/49999/"]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
self.buckets # Delegate to .buckets to list buckets
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def self.get path, txt=nil
|
|
107
|
+
|
|
108
|
+
if txt
|
|
109
|
+
txt = Tree.siblings :string=>true
|
|
110
|
+
self.put path, YAML::load(txt)
|
|
111
|
+
return "- saved!"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
hash = self.get_hash(path).to_yaml.sub("--- \n", '').gsub(/^/, '| ')
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def self.get_hash path, options={}
|
|
119
|
+
begin
|
|
120
|
+
response = HTTParty.get("#{RIAK_URL}/#{options[:root]||'riak'}/#{path}")
|
|
121
|
+
rescue Exception=>e
|
|
122
|
+
raise "Riak not running?"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
return response.code if response.code.to_s !~ /^2/
|
|
126
|
+
if options[:raw]
|
|
127
|
+
response.body
|
|
128
|
+
else
|
|
129
|
+
result = ::JSON[response.body]
|
|
130
|
+
result['_link'] = response.headers['link'].split(', ') if Keys.prefix_u
|
|
131
|
+
result
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def self.post path, options={}
|
|
136
|
+
# If no body passed in, wrap necessary stuff around it
|
|
137
|
+
if options[:body].nil?
|
|
138
|
+
options = {
|
|
139
|
+
:body=>options.to_json,
|
|
140
|
+
:headers=>{'Content-Type'=>'application/json'},
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
HTTParty.post("#{RIAK_URL}/riak/#{path}", options)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def self.put path, options={}
|
|
148
|
+
# If no body passed in, wrap necessary stuff around it
|
|
149
|
+
if options[:body].nil?
|
|
150
|
+
options = {
|
|
151
|
+
:body=>options.to_json,
|
|
152
|
+
:headers=>{'Content-Type'=>'application/json'},
|
|
153
|
+
}
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
HTTParty.put("#{RIAK_URL}/riak/#{path}", options)
|
|
157
|
+
nil
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def self.delete path
|
|
161
|
+
HTTParty.delete "#{RIAK_URL}/riak/#{path}"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def self.help bucket=nil, key=nil
|
|
165
|
+
"
|
|
166
|
+
| To save
|
|
167
|
+
| - C-enter on object body
|
|
168
|
+
|
|
|
169
|
+
| To delete
|
|
170
|
+
| - C-0, C-enter on object body
|
|
171
|
+
".unindent
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def self.ping
|
|
175
|
+
`#{Bookmarks['$riak']}/bin/riak ping`
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def self.log
|
|
179
|
+
txt = File.read File.expand_path("~/.emacs.d/riak_log.notes")
|
|
180
|
+
txt = txt.split("\n").reverse.uniq.join("\n")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
Keys.enter_list_riak do
|
|
186
|
+
Launcher.insert '- Riak.menu/'
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
Keys.enter_list_buckets do
|
|
190
|
+
Launcher.insert '- buckets/'
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
Launcher.add("riak") do |path|
|
|
194
|
+
"
|
|
195
|
+
- @buckets/
|
|
196
|
+
"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
Launcher.add "buckets" do |path|
|
|
200
|
+
args = path.split('/')[1..-1]
|
|
201
|
+
Riak.buckets(*args)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
CodeTree.add_menu "Riak" # Force it, since we're a module
|