helpline 0.1.12 → 0.1.17

Sign up to get free protection for your applications and to get access to all the features.
data/Makefile CHANGED
@@ -1,4 +1,4 @@
1
- .PHONY: data.js glossary.js
1
+ .PHONY: data.js glossary.js test
2
2
 
3
3
  run: browserify
4
4
  npm start .
@@ -49,5 +49,8 @@ all: update build-mac
49
49
  release:
50
50
  rake release
51
51
 
52
-
53
-
52
+ #
53
+ # テスト
54
+ #
55
+ test:
56
+ ruby test/test.rb
@@ -20,74 +20,100 @@ class HelpLine
20
20
  end
21
21
 
22
22
  def initialize
23
- @pagedata = {}
24
- @project = Scrapbox::Project.new("HelpLine")
23
+ # @pagedata = {}
24
+ # @project = Scrapbox::Project.new("HelpLine")
25
25
  end
26
26
 
27
- def getdata
28
- #
29
- # ページデータ取得
30
- #
31
- puts "-----------------ページデータを取得"
32
- @project.pages.each { |title,page|
33
- puts "...#{title}"
34
- @pagedata[title] = page.text.split(/\n/)
35
- }
36
-
27
+ def update(sources) # sources = ['HelpLine', '~/ScrapboxData/masui.json', ...]
37
28
  dumpdata = {}
38
29
  dumpdata['codes'] = []
39
30
  dumpdata['defs'] = []
40
31
  dumpdata['pages'] = []
41
32
 
42
- #
43
- # 関数/定数を評価"
44
- #
45
- puts "-----------------関数/定数を取得"
46
- @pagedata.each { |title,pagedata|
47
- puts "...#{title}"
48
- pagedata. each { |line|
49
- if line =~ /code:(.*\.rb)$/ then
50
- src = $1
51
- puts "=========== #{src}"
52
- page = Scrapbox::Page.new(@project,title)
53
- dumpdata['codes'] << page.code(src)
33
+ sources.each { |source|
34
+ pagedata = {}
35
+ source = File.expand_path(source)
36
+ if File.exist?(source)
37
+ puts "-----------------ページデータをJSONデータ(#{source})から取得"
38
+ data = JSON.parse(File.read(source))
39
+ data['pages'].each { |page|
40
+ title = page['title']
41
+ puts "...#{title}"
42
+ pagedata[title] = page['lines']
43
+ }
44
+ elsif source =~ /^[a-zA-Z\-]+$/ # たぶんHelpLineプロジェクト
45
+ puts "-----------------ページデータをScrapbox(#{source})から取得"
46
+ project = Scrapbox::Project.new(source)
47
+ project.pages.each { |title,page|
48
+ puts "...#{title}"
49
+ pagedata[title] = page.text.split(/\n/)
50
+ }
51
+ else
52
+ next
53
+ end
54
+
55
+ #
56
+ # 関数/定数を評価"
57
+ #
58
+ puts "-----------------関数/定数を取得"
59
+ src = nil
60
+ indent = ''
61
+ code = []
62
+ pagedata.each { |title,lines|
63
+ puts "...#{title}"
64
+ lines.each { |line|
65
+ if src && line =~ /^#{indent}\s+/ then
66
+ code << line
67
+ elsif line =~ /^code:(.*\.rb)$/ then
68
+ src = $2
69
+ indent = $1
70
+ code = []
71
+ elsif src then
72
+ dumpdata['codes'] << code.join("\n")
73
+ src = nil
74
+ indent = ''
75
+ code = []
76
+ else
77
+ end
78
+ }
79
+ if code.length > 0
80
+ dumpdata['codes'] << code.join("\n")
54
81
  end
55
82
  }
56
- }
57
- puts "-----------------HelpLineデータを検出"
58
- @pagedata.each { |title,pagedata|
59
- puts "...#{title}"
60
- dumpdata['pages'] << title
61
- processing_defs = false
62
- codeindent = nil
63
- pagedata.each { |line|
64
- if !codeindent
65
- if line =~ /^(\s*)code:/
66
- codeindent = $1.length
67
- next
68
- end
69
- else
70
- line =~ /^(\s*)/
71
- if line.length < codeindent
72
- codeindent = nil
83
+ puts "-----------------HelpLineデータを検出"
84
+ pagedata.each { |title,pagedata|
85
+ puts "...#{title}"
86
+ dumpdata['pages'] << title
87
+ processing_defs = false
88
+ codeindent = nil
89
+ pagedata.each { |line|
90
+ if !codeindent
91
+ if line =~ /^code:/
92
+ codeindent = $1.length
93
+ next
94
+ end
73
95
  else
74
- next
96
+ line =~ /^(\s*)/
97
+ if line.length < codeindent
98
+ codeindent = nil
99
+ else
100
+ next
101
+ end
75
102
  end
76
- end
77
- if line =~ /^\s*[\$\%]/
78
- puts line
79
- if line =~ /^\%/ && !processing_defs
80
- puts "'$'で始まる用例定義なしでコマンドを定義しようとしています"
81
- exit
103
+ if line =~ /^\s*[\$\%\?]/
104
+ if line =~ /^\%/ && !processing_defs
105
+ puts "'$'で始まる用例定義なしでコマンドを定義しようとしています"
106
+ exit
107
+ end
108
+ dumpdata['defs'] << "#{line} {#{dumpdata['pages'].length-1}}"
109
+ processing_defs = true
110
+ else
111
+ processing_defs = false
82
112
  end
83
- dumpdata['defs'] << "#{line} {#{dumpdata['pages'].length-1}}"
84
- processing_defs = true
85
- else
86
- processing_defs = false
87
- end
113
+ }
88
114
  }
89
115
  }
90
-
116
+
91
117
  File.open(datafile,"w"){ |f|
92
118
  f.puts dumpdata.to_json
93
119
  }
@@ -98,23 +124,23 @@ class HelpLine
98
124
  lines = list.length
99
125
  lines = LINES if lines > LINES
100
126
  (0...lines).each { |i|
101
- Curses.move(i,0)
102
- s = "* #{list[i][0]}"
127
+ Curses.move(i*2,0)
128
+ s = "#{list[i][0]}"
103
129
  if i == sel
104
130
  Curses.print_inverse s
105
131
  else
106
- Curses.print s
132
+ Curses.print_bold s
107
133
  end
134
+ Curses.move(i*2+1,0)
135
+ Curses.print " % " + list[i][1]
108
136
  }
109
- Curses.move(sel,0)
110
- # Curses.down
111
- # Curses.tol
137
+ Curses.move(sel*2,0)
112
138
  end
113
139
 
114
- def helpline
140
+ def helpline(sources,test=nil,debug=nil)
115
141
  data = JSON.parse(File.read(datafile))
116
142
  unless data['pages'] # データ型式変換があったので
117
- getdata
143
+ update sources
118
144
  data = JSON.parse(File.read(datafile))
119
145
  end
120
146
 
@@ -130,27 +156,34 @@ class HelpLine
130
156
  #
131
157
  # HelpLineエントリ
132
158
  #
133
- entries = []
134
- data['defs'].each { |line|
135
- if line =~ /^\s*\$\s*(.*)$/ # $....
136
- entries << $1
137
- elsif line =~ /^\s*\%\s*(.*)$/ # %....
138
- cmd = $1
139
- entries.each { |l|
140
- desc = eval('"' + l + '"')
141
- g.add desc.force_encoding('utf-8'), cmd.force_encoding('utf-8')
142
- }
143
- entries = []
144
- end
159
+
160
+ logfile = (debug ? "/tmp/helpline-defs" : "/dev/null")
161
+ File.open(logfile,"w"){ |f| # ログを残す場合
162
+ entries = []
163
+ data['defs'].each { |line|
164
+ if line =~ /^\s*[\$\?]\s*(.*)$/ # $....
165
+ entries << $1
166
+ elsif line =~ /^\s*\%\s*(.*)$/ # %....
167
+ cmd = $1
168
+ entries.each { |l|
169
+ desc = eval('"' + l + '"')
170
+ f.puts "desc: #{desc}"
171
+ g.add desc.force_encoding('utf-8'), cmd.force_encoding('utf-8')
172
+ }
173
+ f.puts "cmd: #{cmd}"
174
+ entries = []
175
+ end
176
+ }
145
177
  }
146
178
 
147
179
  res = g.generate " #{ARGV.join(' ').sub(/\[/,'').sub(/\]/,'')} "
148
180
 
181
+ File.open("/tmp/helpline.cmd","w"){ |f|
182
+ f.puts ARGV.join(' ')
183
+ }
184
+
149
185
  if res[0].length == 0
150
186
  puts "ヘルプがみつかりません"
151
- File.open("/tmp/helpline.cmd","w"){ |f|
152
- f.puts ARGV.join(' ')
153
- }
154
187
  exit
155
188
  end
156
189
 
@@ -158,7 +191,9 @@ class HelpLine
158
191
  listed = {}
159
192
  list = res[0].find_all { |a| # 0 ambig
160
193
  # a = ["現在の状況を表示する {56}", "git status {56}"], etc.
161
- if a[0] =~ /^git:/ && !git_repository
194
+ if a[0] =~ /voidvoidvoid/
195
+ false
196
+ elsif a[0] =~ /^git:/ && !git_repository
162
197
  false
163
198
  else
164
199
  if listed[a[1]]
@@ -169,10 +204,15 @@ class HelpLine
169
204
  end
170
205
  }
171
206
 
207
+ # if options['t'] || options['test'] then
208
+ if test
209
+ puts list
210
+ exit
211
+ end
212
+
172
213
  #
173
214
  # HelpLineメニュー表示し、カーソル移動で選択
174
215
  #
175
-
176
216
  help_number = {}
177
217
  list.each_with_index { |entry,ind|
178
218
  entry[0].sub!(/\s*{(\d*)}$/,'')
@@ -225,36 +265,46 @@ class HelpLine
225
265
  desc = list[sel.to_i][0]
226
266
  cmd = list[sel][1]
227
267
 
228
- Curses.move(lines,0)
268
+ Curses.move(lines*2,0)
229
269
  Curses.tol
230
270
 
231
271
  #Curses.move(0,0)
232
272
  ##Curses.down
233
- Curses.print_inverse("「#{desc}」を実行")
234
- puts " (ソース: http://scrapbox.io/HelpLine/#{data['pages'][help_number[desc]]})"
273
+
274
+ # Curses.print_inverse("「#{desc}」を実行")
275
+ # puts " (ソース: http://scrapbox.io/HelpLine/#{data['pages'][help_number[desc]]})"
235
276
  File.open("/tmp/helpline.cmd","w"){ |f|
236
277
  f.puts cmd
237
278
  }
238
279
  end
239
280
  end
240
281
 
241
- # is_repository = system 'git rev-parse --git-dir > /dev/null >& /dev/null'
242
- # unless is_repository
243
- # STDERR.puts "Gitレポジトリで実行して下さい"
244
- # exit
245
- # end
246
-
247
- options = ARGV.getopts('u')
282
+ # アップデート
283
+ # % helpline -u
284
+ # データを指定してアップデート
285
+ # % helpline -u -s HelpLine,/Users/masui/ScrapboxData/masui-HelpLine.json
286
+ # テスト
287
+ # % helpline -t
288
+ #
248
289
 
249
290
  helpline = HelpLine.new
250
291
 
251
- if !File.exist?(helpline.datafile) && !options['u']
292
+ options = ARGV.getopts('utds:','update','test','source:','debug')
293
+ update = options['u'] || options['update']
294
+ test = options['t'] || options['test']
295
+ debug = options['d'] || options['debug']
296
+ sources = ['HelpLine']
297
+ if options['s'] || options['source']
298
+ sources = (options['s'] || options['source']).split(/,/)
299
+ end
300
+
301
+ if !File.exist?(helpline.datafile) && !update
252
302
  puts "#{helpline.datafile}を作成します..."
253
- helpline.getdata
303
+ helpline.update sources
254
304
  end
255
-
256
- if options['u'] then
257
- helpline.getdata
258
- else
259
- helpline.helpline
305
+
306
+ if update then
307
+ helpline.update sources
308
+ else
309
+ helpline.helpline sources, test, debug
260
310
  end
data/index.html CHANGED
@@ -20,16 +20,13 @@
20
20
  <section class="main-content">
21
21
 
22
22
  <center>
23
- <video src="https://s3-ap-northeast-1.amazonaws.com/masui.org/d/b/db555e8535ff111e794b95e6d3d7a8f5.mp4" width=600 controls></video>
23
+ <video src="https://s3-ap-northeast-1.amazonaws.com/masui.org/b/9/b9b2ae65a3a977857b5487f280785b47.mp4" width=600 controls></video>
24
24
  </center>
25
25
 
26
- <p>
27
- 以下、GitHelpのテキストをコピペしただけなのでHelpLineの説明になってません。すみません
28
- </p>
29
-
30
- <p>
31
-  Gitのような複雑なシステムは使い方が難しい。
32
- ある程度使い方を知っている場合でも、あまり一般的でない機能を使うのは難しい。
26
+ <p></p>
27
+
28
+  コマンドラインのオプションは難しいものが多い。
29
+ Gitのような複雑なシステムの場合、概念もオプションも難しい。
33
30
  たとえば以下のような場合はどういうコマンドを使えばいいだろうか?
34
31
  </p>
35
32
 
@@ -170,19 +167,19 @@
170
167
  誰でも情報を足したり修正したりできたら嬉しいだろう。
171
168
  </p>
172
169
 
173
- <h3>GitHelpのアプローチ</h3>
170
+ <h3>HelpLineのアプローチ</h3>
174
171
 
175
172
  <p>
176
-  GitHelpは、以下のような方針で上のような課題をすべて解決しようというものである。
173
+  HelpLineは、以下のような方針で上のような課題をすべて解決しようというものである。
177
174
 
178
175
  <ul>
179
176
  <li>ユーザのあらゆる曖昧な表現にマッチするようにヘルプ文字列を正規表現で表現し、
180
- Gitコマンドに変換する</li>
177
+ コマンドに変換する</li>
181
178
  - ExpandHelp(<a href="https://github.com/masui/expand-ruby">ソース</a> /
182
179
  <a href="http://www.interaction-ipsj.org/archives/paper2012/data/Interaction2012/oral/data/pdf/12INT012.pdf">論文</a>)を利用
183
180
  <li>データをすべてクラウド上に置いて編集可能にすることにより、
184
181
  誰でもデータを追加/修正できるようにする</li>
185
- - <a href="https://Scrapbox.io/GitHelp">Scrapbox</a>を利用
182
+ - <a href="https://Scrapbox.io/HelpLine">Scrapbox</a>を利用
186
183
  <li>ユーザが指定したパラメタはそのまま利用して実行に使う</li>
187
184
  - ユーザが「4」「時間」などと指定すると「時刻を4時にセットする」のようなものを提案して実行可能にする
188
185
  <li>多少の誤入力を許す</li>
@@ -193,43 +190,48 @@
193
190
 
194
191
  <h3>利用例</h3>
195
192
 
196
- Gitに関連するタスクのキーワードやパラメタを指定して
197
- <code>githelp</code>を起動すると
198
- 候補のリストが表示され、
193
+ タスクのキーワードやパラメタを指定してCtrl-Jを押すと
194
+ <code>helpline</code>が起動して候補のリストが表示され、
199
195
  カーソルで選択すると実行される。
200
196
 
201
197
  <ul>
202
- <li><code>$ githelp 2 README</code>のように引数を指定して起動すると以下のような候補リストが提示される</li>
203
-
204
- <img src="https://gyazo.com/6cc87cef5f28185199074b61716454de.png" width=500>
198
+ <li><code>$ 2 README</code>と入力してからCtrl-Jを押すと
199
+ 以下のような候補リストが提示される</li>
205
200
 
201
+ <img src="https://gyazo.com/806cb4c2c14781465949ec3aa85d563b.png" width=500>
206
202
  <p></p>
207
203
  <li>カーソルで選択してリターンを押すと実行される</li>
208
204
 
209
- <img src="https://gyazo.com/75c14885944c33f2671474b008120262.png" width=500>
205
+ <img src="https://gyazo.com/b72f97a2664d504c5465fd11bac92184.png" width=700>
210
206
  </ul>
211
207
 
212
208
  <a name="install"><h3>インストール</h3></a>
213
-
214
- <pre>
215
- % gem install githelp </pre>
216
-
209
+
217
210
  <ul>
218
- <li>対話的処理のために<a href="https://github.com/peco/peco">peco</a>が必要</li>
219
- <ul>
220
- <li>Macだと<code>% brew install peco</code>でインストール可能</li>
221
- <li>Linuxなどの場合<a href="https://github.com/peco/peco/releases">こちら</a>のファイルからインストール (yumなどでは入らない)</li>
222
- </ul>
211
+ <li> <code>gem</code>でHelpLineをインストール
212
+ <pre>
213
+ % gem install helpline</pre>
214
+ </li>
215
+ <li> <code>~/.zshrc</code>に以下の記述を追加
216
+ <pre>
217
+ function run-help() {
218
+ helpline "${BUFFER}" < $TTY
219
+ BUFFER=$(cat /tmp/helpline.cmd)
220
+ CURSOR=${#BUFFER}
221
+ zle redisplay
222
+ }
223
+ zle -N run-help
224
+ bindkey "^j" run-help</pre>
225
+ </li>
223
226
  </ul>
224
227
 
225
228
  <h3>実装</h3>
226
-
227
229
  <ul>
228
230
  <li><a href="https://github.com/masui/expand_ruby">re_expand</a>
229
231
  という正規表現展開ライブラリを利用</li>
230
232
  <li><a href="https://Scrapbox.io/GitHelp">Scrapbox</a>にあらゆる情報を書いておく</li>
231
233
  <br>
232
- <img src="https://gyazo.com/b4ba42a96617c65db32020eb1ea19bf3.png" width=450>
234
+ <img src="https://gyazo.com/cd1529fe082c57d4295e8660ba3cb932.png" width=550>
233
235
  <li>
234
236
  様々なタスクの説明と実際の操作を組にして記述しておき、
235
237
  ユーザが与えたキーワードやパラメタにマッチするものを
@@ -259,23 +261,11 @@
259
261
  翻訳作業があまり気にならないものなのかもしれないが、
260
262
  そういう「翻訳」は少ない方が良いのは確かだろう。
261
263
  </li>
262
- <li>そういえば先日「らくらくホン」画面に出てくる鬱陶しい「羊」を消す方法が全くわからなかったのだが、
263
- あれは「マチキャラ」と呼ばれるものなので
264
- 「マチキャラ」を消すという操作が必要だった。
265
- お前はMSのイルカか。
266
- 「羊 消す」とか「消す」とかで消せるべきだろう。
267
- githelpでは <code>$ githelp 削除</code> と入力すれば削除関連で何ができるのかわかるだろうし、
268
- <code>(鬱陶しい|不快な)羊を(消す|殺す)</code>
269
- のようなエントリをユーザが足すこともできるだろう。
270
- </li>
271
- <img src="http://service.smt.docomo.ne.jp/site/iconcier/img/iconcier_ptl_cha_img01.png" width=300>
272
- <li>というわけで<b>Gitは単なる適用例であり、広い範囲で使いたいと思っている。</b></li>
273
264
  </ul>
274
265
 
275
266
  <h3> 注意</h3>
276
267
 
277
268
  <ul>
278
- <li><code>githelp</code>コマンドはGitリポジトリのディレクトリで実行する必要がある</li>
279
269
  <li><a href="https://github.com/masui/expand_ruby">re_expand</a>の実装が富豪的なので
280
270
  大きなリポジトリだと不具合があるかも</li>
281
271
  <li>データが全然足りない... 特にリモートリポジトリ関連のデータは皆無だが、