soywiki 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.
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +25 -0
- data/README.md +3 -0
- data/Rakefile +25 -0
- data/bin/soywiki +9 -0
- data/bin/soywiki-pages-linking-in +29 -0
- data/bin/soywiki-rename +53 -0
- data/bin/soywiki-unfurl +36 -0
- data/lib/soywiki.rb +8 -0
- data/lib/soywiki.vim +455 -0
- data/soywiki.gemspec +22 -0
- metadata +91 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
couchrest (1.0.1)
|
5
|
+
json (>= 1.4.6)
|
6
|
+
mime-types (>= 1.15)
|
7
|
+
rest-client (>= 1.5.1)
|
8
|
+
haml (3.0.25)
|
9
|
+
json (1.5.1)
|
10
|
+
mime-types (1.16)
|
11
|
+
rack (1.2.1)
|
12
|
+
rest-client (1.6.1)
|
13
|
+
mime-types (>= 1.16)
|
14
|
+
sinatra (1.1.2)
|
15
|
+
rack (~> 1.1)
|
16
|
+
tilt (~> 1.2)
|
17
|
+
tilt (1.2.2)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
couchrest
|
24
|
+
haml
|
25
|
+
sinatra
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
require 'couchrest'
|
3
|
+
require 'yaml'
|
4
|
+
require 'json'
|
5
|
+
require 'rake'
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'bundler'
|
8
|
+
# require 'soywiki'
|
9
|
+
|
10
|
+
Bundler::GemHelper.install_tasks
|
11
|
+
|
12
|
+
desc "Start Sinatra webapp"
|
13
|
+
task :sinatra do
|
14
|
+
# TODO
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run tests"
|
18
|
+
task :test do
|
19
|
+
$:.unshift File.expand_path("test")
|
20
|
+
MiniTest::Unit.autorun
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :test
|
24
|
+
|
25
|
+
|
data/bin/soywiki
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
class String
|
5
|
+
def is_namespaced?
|
6
|
+
self.split(".").size == 2
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def inbound_links_to?(file, page_title)
|
11
|
+
return false unless File.file?(file)
|
12
|
+
return false if (file =~ /(\.swo|\.swp)$/ || file =~ /^\./)
|
13
|
+
body = File.read(file)
|
14
|
+
body =~ /[\A\s\n\b]#{page_title}\b/
|
15
|
+
end
|
16
|
+
|
17
|
+
target_page = ARGV.first
|
18
|
+
|
19
|
+
if target_page.is_namespaced?
|
20
|
+
namespace, page = *target_page.split(".")
|
21
|
+
# find all files in this name space
|
22
|
+
Dir.glob("#{namespace}.*").select do |file|
|
23
|
+
inbound_links_to?(file, target_page) || inbound_links_to?(file, ".#{page}")
|
24
|
+
end.each {|file| puts file}
|
25
|
+
else
|
26
|
+
Dir.glob("*").select do |file|
|
27
|
+
inbound_links_to?(file, target_page)
|
28
|
+
end.each {|file| puts file}
|
29
|
+
end
|
data/bin/soywiki-rename
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
oldname, newname = *ARGV
|
3
|
+
|
4
|
+
class String
|
5
|
+
def is_namespaced?
|
6
|
+
self.split(".").size == 2
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
target_files = `grep -lF '#{oldname}' *`.strip.split(/\n/)
|
11
|
+
target_files.each do |file|
|
12
|
+
text = File.read(file)
|
13
|
+
text.gsub!(/\b#{oldname}\b/, newname)
|
14
|
+
File.open(file, 'w') {|f| f.puts text}
|
15
|
+
end
|
16
|
+
|
17
|
+
# deal with links without namespace
|
18
|
+
|
19
|
+
old_short = oldname.split(".")[1]
|
20
|
+
new_short = newname.split(".")[1]
|
21
|
+
|
22
|
+
if old_short && !new_short
|
23
|
+
# where going from a namespaced name to a top-level name
|
24
|
+
old_namespace = oldname.split(".")[0]
|
25
|
+
target_files = `grep -lF '\<#{old_short}\>' *`.strip.split(/\n/)
|
26
|
+
target_files.each do |file|
|
27
|
+
text = File.read(file)
|
28
|
+
text.gsub!(/\b#{old_short}\b/, newname)
|
29
|
+
File.open(file, 'w') {|f| f.puts text}
|
30
|
+
end
|
31
|
+
# change all the .Wikiwords in the newname file to fully namespaced
|
32
|
+
# links with namespace of newname.downcase
|
33
|
+
if File.exist?(newname)
|
34
|
+
text = File.read(newname)
|
35
|
+
#text.gsub!(relative_wiki_word, "#{newname.downcase}.#{$1}")
|
36
|
+
# ".Pear".gsub!(/\A\.([A-Z][a-z]+[A-Z]\w*)/, "TEST.#{$1}")
|
37
|
+
text.gsub!(/([\A\s\n\b])\.([A-Z][a-z]+[A-Z]\w*)/, '\1' + newname.downcase + '.\2')
|
38
|
+
File.open(newname, 'w') {|f| f.puts text}
|
39
|
+
end
|
40
|
+
elsif !old_short && new_short
|
41
|
+
# where going from a top-level name to a namespaced one
|
42
|
+
# no action needed
|
43
|
+
elsif !old_short && !new_short
|
44
|
+
# no action needed
|
45
|
+
elsif old_short && new_short
|
46
|
+
target_files = `grep -lF '#{old_short}' *`.strip.split(/\n/)
|
47
|
+
puts target_files.inspect
|
48
|
+
target_files.each do |file|
|
49
|
+
text = File.read(file)
|
50
|
+
text.gsub!(/\b#{old_short}\b/, new_short)
|
51
|
+
File.open(file, 'w') {|f| f.puts text}
|
52
|
+
end
|
53
|
+
end
|
data/bin/soywiki-unfurl
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# takes any wiki link that stands alone on a line and expands it
|
4
|
+
#
|
5
|
+
WIKI_LINK_PATTERN = /^\s*(([a-z]+\.)?[A-Z][a-z]+[A-Z]\w*|\.[A-Z][a-z]+[A-Z]\w*)\s*$/
|
6
|
+
|
7
|
+
PROCESSED_FILES = []
|
8
|
+
def unfurl(file)
|
9
|
+
PROCESSED_FILES << file
|
10
|
+
lines = File.readlines(file)
|
11
|
+
lines.shift 2
|
12
|
+
lines = lines.join.strip.split("\n")
|
13
|
+
lines.each do |line|
|
14
|
+
if line =~ WIKI_LINK_PATTERN
|
15
|
+
link = line.strip
|
16
|
+
if link =~ /^\./ # short link in namespace (relative link)
|
17
|
+
namespace = file.split(".")[0]
|
18
|
+
link = [namespace, link].join
|
19
|
+
end
|
20
|
+
if File.file?(link) && !PROCESSED_FILES.include?(link)
|
21
|
+
unfurl link # recursive
|
22
|
+
elsif PROCESSED_FILES.include?(link)
|
23
|
+
puts "#{link} [already expanded]"
|
24
|
+
else
|
25
|
+
puts "#{link} [no file found]"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
puts line
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
ARGV.each do |file|
|
34
|
+
unfurl(file)
|
35
|
+
end
|
36
|
+
|
data/lib/soywiki.rb
ADDED
data/lib/soywiki.vim
ADDED
@@ -0,0 +1,455 @@
|
|
1
|
+
" Vim script that turns Vim into a personal wiki
|
2
|
+
" Maintainer: Daniel Choi <dhchoi@gmail.com>
|
3
|
+
" License: MIT License (c) 2011 Daniel Choi
|
4
|
+
|
5
|
+
" this matched namedspaced WikiWords, top-level WikiWords, and relative .WikiWords in a
|
6
|
+
" namespace
|
7
|
+
let s:wiki_link_pattern = '\C\<\([a-z]\+\.\)\?[A-Z][a-z]\+[A-Z]\w*\>\|\.[A-Z][a-z]\+[A-Z]\w*\>'
|
8
|
+
|
9
|
+
let s:rename_links_command = 'soywiki-rename '
|
10
|
+
let s:find_pages_linking_in_command = 'soywiki-pages-linking-in '
|
11
|
+
let s:search_for_link = ""
|
12
|
+
|
13
|
+
|
14
|
+
func! s:trimString(string)
|
15
|
+
let string = substitute(a:string, '\s\+$', '', '')
|
16
|
+
return substitute(string, '^\s\+', '', '')
|
17
|
+
endfunc
|
18
|
+
|
19
|
+
func! s:page_title()
|
20
|
+
let title_line = getline(1)
|
21
|
+
return s:trimString(title_line)
|
22
|
+
endfunc
|
23
|
+
|
24
|
+
func! s:page_namespace()
|
25
|
+
let segments = split(s:page_title(), '\.')
|
26
|
+
return get(segments, 0)
|
27
|
+
endfunc
|
28
|
+
|
29
|
+
func! s:title_without_namespace(page_title)
|
30
|
+
if len(split(a:page_title, '\.')) == 2
|
31
|
+
return "." . get(split(a:page_title, '\.'), 1)
|
32
|
+
else
|
33
|
+
return a:page_title
|
34
|
+
endif
|
35
|
+
endfunc
|
36
|
+
|
37
|
+
func! s:is_wiki_page()
|
38
|
+
let title_line = getline(1)
|
39
|
+
return (match(title_line, s:wiki_link_pattern) == 0)
|
40
|
+
endfunc
|
41
|
+
func! s:save_page()
|
42
|
+
" write
|
43
|
+
endfunc
|
44
|
+
|
45
|
+
func! s:list_pages()
|
46
|
+
let s:search_for_link = ""
|
47
|
+
call s:get_page_list()
|
48
|
+
call s:page_list_window("CompletePageInSelectionWindow", "Select page: ")
|
49
|
+
endfunc
|
50
|
+
|
51
|
+
func! s:link_under_cursor()
|
52
|
+
let link = expand("<cWORD>")
|
53
|
+
let link = substitute(link, '[^[:alnum:]]*$', '', '')
|
54
|
+
" see if he have a namespaced link
|
55
|
+
if (match(link, '^\.')) == 0
|
56
|
+
" find the namespace from the page title
|
57
|
+
let link = s:page_namespace() . link
|
58
|
+
endif
|
59
|
+
|
60
|
+
let link = substitute(link, '^[^\.[:alnum:]]', '', '') " link may begin with period
|
61
|
+
return link
|
62
|
+
endfunc
|
63
|
+
|
64
|
+
" follows a camel case link to a new page
|
65
|
+
func! s:follow_link(split)
|
66
|
+
let link = s:link_under_cursor()
|
67
|
+
if match(link, s:wiki_link_pattern) == -1
|
68
|
+
let link = s:find_next_wiki_link(0)
|
69
|
+
endif
|
70
|
+
call s:load_page(link, a:split)
|
71
|
+
endfunc
|
72
|
+
|
73
|
+
func! s:follow_link_under_cursor(split)
|
74
|
+
let link = s:link_under_cursor()
|
75
|
+
if match(link, s:wiki_link_pattern) == -1
|
76
|
+
echom "Not a wiki link"
|
77
|
+
return
|
78
|
+
endif
|
79
|
+
call s:load_page(link, a:split)
|
80
|
+
endfunc
|
81
|
+
|
82
|
+
func! s:find_next_wiki_link(backward)
|
83
|
+
let n = 0
|
84
|
+
let result = search(s:wiki_link_pattern, 'w' . (a:backward == 1 ? 'b' : ''))
|
85
|
+
if (result == 0)
|
86
|
+
return
|
87
|
+
end
|
88
|
+
return s:link_under_cursor()
|
89
|
+
endfunc
|
90
|
+
|
91
|
+
func! s:load_page(page, split)
|
92
|
+
let page = a:page
|
93
|
+
if (s:is_wiki_page())
|
94
|
+
write
|
95
|
+
endif
|
96
|
+
if (!filereadable(page))
|
97
|
+
" create the file
|
98
|
+
call writefile([a:page, '', ''], page)
|
99
|
+
endif
|
100
|
+
if (a:split == 2)
|
101
|
+
exec "vsplit ". page
|
102
|
+
else
|
103
|
+
exec "split ". page
|
104
|
+
endif
|
105
|
+
if (a:split == 0)
|
106
|
+
wincmd p
|
107
|
+
close
|
108
|
+
endif
|
109
|
+
endfunc
|
110
|
+
|
111
|
+
func! s:delete_page()
|
112
|
+
let file = bufname('%')
|
113
|
+
let bufnr = bufnr('%')
|
114
|
+
call delete(file)
|
115
|
+
call system("git commit " . bufname('%') . " -m 'deletion'")
|
116
|
+
" go to most recently saved
|
117
|
+
" call feedkeys("\<C-o>")
|
118
|
+
let target = s:trimString(system("ls -t | head -1"))
|
119
|
+
exec "e " . target
|
120
|
+
exec "bdelete " . bufnr
|
121
|
+
redraw
|
122
|
+
echom "Deleted " . file
|
123
|
+
endfunc
|
124
|
+
|
125
|
+
func! s:prompt_for_wiki_word(prompt, default)
|
126
|
+
let input = s:trimString(input(a:prompt, a:default))
|
127
|
+
while match(input, s:wiki_link_pattern) == -1
|
128
|
+
let input = s:trimString(input("Must be a WikiWord! Press CTRL-c to cancel. " . a:prompt , a:default))
|
129
|
+
endwhile
|
130
|
+
return input
|
131
|
+
endfunc
|
132
|
+
|
133
|
+
func! s:rename_page()
|
134
|
+
let file = bufname('%')
|
135
|
+
let newname = s:prompt_for_wiki_word("Rename file: ", l:file)
|
136
|
+
if (filereadable(newname))
|
137
|
+
exe "echom '" . newname . " already exists!'"
|
138
|
+
return
|
139
|
+
endif
|
140
|
+
call system("git mv " . l:file . " " . newname)
|
141
|
+
exec "e ". newname
|
142
|
+
" replace all existing inbound links
|
143
|
+
" TODO replace this with a ruby script
|
144
|
+
call system(s:rename_links_command . file . " " . newname)
|
145
|
+
call system("git commit -am 'rename wiki page'")
|
146
|
+
e!
|
147
|
+
endfunc
|
148
|
+
|
149
|
+
func! s:create_page()
|
150
|
+
let newname = s:prompt_for_wiki_word("New page title: ", "")
|
151
|
+
if (filereadable(newname))
|
152
|
+
exe "echom '" . newname . " already exists!'"
|
153
|
+
return
|
154
|
+
endif
|
155
|
+
call writefile([newname, '', ''], newname)
|
156
|
+
exec "e ". newname
|
157
|
+
endfunc
|
158
|
+
|
159
|
+
func! s:save_revision()
|
160
|
+
call system("git add " . bufname('%'))
|
161
|
+
call system("git commit " . bufname('%') . " -m 'edit'")
|
162
|
+
endfunc
|
163
|
+
|
164
|
+
func! s:show_revision_history(stat)
|
165
|
+
" maybe later allow --stat
|
166
|
+
if (a:stat)
|
167
|
+
exec ":!git log --stat " . bufname('%')
|
168
|
+
else
|
169
|
+
exec ":!git log --color-words -p " . bufname('%')
|
170
|
+
end
|
171
|
+
endfunc
|
172
|
+
|
173
|
+
func! s:show_blame()
|
174
|
+
exec ":!git blame " . bufname('%')
|
175
|
+
endfunc
|
176
|
+
|
177
|
+
|
178
|
+
" -------------------------------------------------------------------------------
|
179
|
+
" select Page
|
180
|
+
|
181
|
+
func! s:get_page_list()
|
182
|
+
if len(bufname('%')) == 0
|
183
|
+
let s:page_list = split(system("ls -t"), "\n")
|
184
|
+
else
|
185
|
+
let s:page_list = split(system("ls -t | grep -vF '" . bufname('%') . "'" ), "\n")
|
186
|
+
endif
|
187
|
+
endfunction
|
188
|
+
|
189
|
+
func! s:pages_in_this_namespace(pages)
|
190
|
+
let namespace = s:page_namespace()
|
191
|
+
let pages = filter( a:pages, 'v:val =~ "^' . namespace . '"')
|
192
|
+
" strip leading namespace
|
193
|
+
let pages = map( pages, "substitute(v:val, '^" . namespace . "\.', '', '') " )
|
194
|
+
return pages
|
195
|
+
endfunc
|
196
|
+
|
197
|
+
func! s:reduce_matches()
|
198
|
+
if (!exists("s:matching_pages"))
|
199
|
+
return
|
200
|
+
endif
|
201
|
+
let fragment = expand("<cWORD>")
|
202
|
+
let reduced_pages = filter( s:matching_pages, 'v:val =~ "^' . fragment . '"')
|
203
|
+
" find the first namespace in the list
|
204
|
+
let namespaced_matches = filter( s:matching_pages, 'v:val =~ "^' . fragment . '\."')
|
205
|
+
if (len(namespaced_matches) == 0)
|
206
|
+
return
|
207
|
+
elseif match(fragment, '^[A-Z]') == -1 && match(fragment, '\.' == -1)
|
208
|
+
" we're beginning to type a namespace
|
209
|
+
let namespace = get(split(get(namespaced_matches, 0), '\.'), 0)
|
210
|
+
let namespace .= "."
|
211
|
+
call feedkeys( "BcW". namespace. "\<C-x>\<C-u>\<C-p>" , "t")
|
212
|
+
else
|
213
|
+
" we're tabbing to auto complete the term, not find a namespace
|
214
|
+
return
|
215
|
+
endif
|
216
|
+
endfunc
|
217
|
+
|
218
|
+
function! s:page_list_window(complete_function, prompt)
|
219
|
+
topleft split page-list-buffer
|
220
|
+
setlocal buftype=nofile
|
221
|
+
setlocal noswapfile
|
222
|
+
setlocal modifiable
|
223
|
+
resize 1
|
224
|
+
inoremap <silent> <buffer> <cr> <Esc>:call <SID>select_page()<CR>
|
225
|
+
inoremap <buffer> <Tab> <Esc>:call <SID>reduce_matches()<cr>
|
226
|
+
noremap <buffer> q <Esc>:close<cr>
|
227
|
+
exec "setlocal completefunc=" . a:complete_function
|
228
|
+
" c-p clears the line
|
229
|
+
call setline(1, a:prompt)
|
230
|
+
normal $
|
231
|
+
call feedkeys("a\<c-x>\<c-u>\<c-p>", 't')
|
232
|
+
" call feedkeys("a", 't')
|
233
|
+
endfunction
|
234
|
+
|
235
|
+
function! CompletePage(findstart, base)
|
236
|
+
let s:matching_pages = s:page_list[:]
|
237
|
+
let possible_period = getline('.')[col('.') - 2]
|
238
|
+
if (possible_period == '.')
|
239
|
+
" filter to pages in this namespace
|
240
|
+
let s:matching_pages = s:pages_in_this_namespace(s:matching_pages)
|
241
|
+
endif
|
242
|
+
if a:findstart
|
243
|
+
" locate the start of the word
|
244
|
+
let line = getline('.')
|
245
|
+
let start = col('.') - 1
|
246
|
+
while start > 0 && line[start - 1] =~ '[[:alnum:]]'
|
247
|
+
let start -= 1
|
248
|
+
endwhile
|
249
|
+
return start
|
250
|
+
else
|
251
|
+
let base = s:trimString(a:base)
|
252
|
+
if (base == '')
|
253
|
+
return s:matching_pages
|
254
|
+
else
|
255
|
+
let res = []
|
256
|
+
for m in s:matching_pages
|
257
|
+
if m =~ '\c' . base
|
258
|
+
call add(res, m)
|
259
|
+
endif
|
260
|
+
endfor
|
261
|
+
return res
|
262
|
+
endif
|
263
|
+
endif
|
264
|
+
endfun
|
265
|
+
|
266
|
+
function! CompletePageInSelectionWindow(findstart, base)
|
267
|
+
let s:matching_pages = s:page_list[:]
|
268
|
+
if a:findstart
|
269
|
+
" locate the start of the word
|
270
|
+
let line = getline('.')
|
271
|
+
let start = col('.') - 1
|
272
|
+
while start > 0 && line[start - 1] =~ '[[:alnum:]\.]'
|
273
|
+
let start -= 1
|
274
|
+
endwhile
|
275
|
+
return start
|
276
|
+
else
|
277
|
+
let base = s:trimString(a:base)
|
278
|
+
if (base == '')
|
279
|
+
return s:matching_pages
|
280
|
+
else
|
281
|
+
let res = []
|
282
|
+
for m in s:matching_pages
|
283
|
+
if m =~ '\c' . base
|
284
|
+
call add(res, m)
|
285
|
+
endif
|
286
|
+
endfor
|
287
|
+
return res
|
288
|
+
endif
|
289
|
+
endif
|
290
|
+
endfun
|
291
|
+
|
292
|
+
function! s:select_page()
|
293
|
+
let page = s:trimString( get(split(getline(line('.')), ": "), 1) )
|
294
|
+
close
|
295
|
+
if (page == '0' || page == '') " no selection
|
296
|
+
return
|
297
|
+
end
|
298
|
+
let match = ""
|
299
|
+
for item in s:matching_pages
|
300
|
+
if (item == page)
|
301
|
+
call s:load_page(page, 0)
|
302
|
+
|
303
|
+
break
|
304
|
+
end
|
305
|
+
endfor
|
306
|
+
echo s:search_for_link
|
307
|
+
if len(s:search_for_link) > 0
|
308
|
+
call search('\<' . s:search_for_link . '\>')
|
309
|
+
endif
|
310
|
+
endfunction
|
311
|
+
|
312
|
+
"------------------------------------------------------------------------
|
313
|
+
" PAGES LINKING IN
|
314
|
+
"
|
315
|
+
" this logic could be more precise, in cases where pages have same name
|
316
|
+
" in different namespaces
|
317
|
+
|
318
|
+
func! s:list_pages_linking_in()
|
319
|
+
let s:pages_linking_in = split(system(s:find_pages_linking_in_command . s:page_title()), "\n")
|
320
|
+
let s:search_for_link = s:title_without_namespace( s:page_title())
|
321
|
+
if len(s:pages_linking_in) == 1
|
322
|
+
let file = get(s:pages_linking_in, 0)
|
323
|
+
write
|
324
|
+
exec "e " . file
|
325
|
+
" not perfectly targeted but OK for now
|
326
|
+
call search(s:search_for_link)
|
327
|
+
elseif len(s:pages_linking_in) == 0
|
328
|
+
echom "No pages link to " . s:page_title() . "!"
|
329
|
+
else
|
330
|
+
call s:page_list_window("CompletePagesLinkingIn_InSelectionWindow", "Pages that link to " . s:page_title() . ": ")
|
331
|
+
endif
|
332
|
+
endfunc
|
333
|
+
|
334
|
+
function! CompletePagesLinkingIn_InSelectionWindow(findstart, base)
|
335
|
+
" todo, this must be smarter, deal with different namespaces
|
336
|
+
let s:matching_pages = s:pages_linking_in[:]
|
337
|
+
if a:findstart
|
338
|
+
" locate the start of the word
|
339
|
+
let line = getline('.')
|
340
|
+
let start = col('.') - 1
|
341
|
+
while start > 0 && line[start - 1] =~ '[[:alnum:]\.]'
|
342
|
+
let start -= 1
|
343
|
+
endwhile
|
344
|
+
return start
|
345
|
+
else
|
346
|
+
let base = s:trimString(a:base)
|
347
|
+
if (base == '')
|
348
|
+
return s:matching_pages
|
349
|
+
else
|
350
|
+
let res = []
|
351
|
+
for m in s:matching_pages
|
352
|
+
if m =~ '\c' . base
|
353
|
+
call add(res, m)
|
354
|
+
endif
|
355
|
+
endfor
|
356
|
+
return res
|
357
|
+
endif
|
358
|
+
endif
|
359
|
+
endfun
|
360
|
+
|
361
|
+
"------------------------------------------------------------------------
|
362
|
+
" This opens a new buffer with all the lines with just WikiLinks on them
|
363
|
+
" expanded (recursively). This is not a wiki buffer but a text buffer
|
364
|
+
|
365
|
+
func! s:unfurl()
|
366
|
+
let res = system("soywiki-unfurl " . bufname('%'))
|
367
|
+
vertical botright new
|
368
|
+
setlocal buftype=nofile "scratch buffer for viewing; user can write
|
369
|
+
put =res
|
370
|
+
1delete
|
371
|
+
normal 1G
|
372
|
+
endfunc
|
373
|
+
|
374
|
+
"------------------------------------------------------------------------
|
375
|
+
|
376
|
+
func! s:open_href()
|
377
|
+
let pattern = 'https\?:[^ >)\]]\+'
|
378
|
+
let line = search(pattern, 'cw')
|
379
|
+
let href = matchstr(getline(line('.')), pattern)
|
380
|
+
let command = g:SoyWiki#browser_command . " '" . href . "' "
|
381
|
+
call system(command)
|
382
|
+
echom command
|
383
|
+
endfunc
|
384
|
+
|
385
|
+
"------------------------------------------------------------------------
|
386
|
+
|
387
|
+
func! s:global_mappings()
|
388
|
+
noremap <leader>m :call <SID>list_pages()<CR>
|
389
|
+
noremap <leader>M :call <SID>list_pages_linking_in()<CR>
|
390
|
+
noremap <silent> <leader>o :call <SID>open_href()<cr>
|
391
|
+
endfunc
|
392
|
+
|
393
|
+
" this checks if the buffer is a SoyWiki file (from firstline)
|
394
|
+
" and then turns on syntax coloring and mappings as necessary
|
395
|
+
func! s:prep_buffer()
|
396
|
+
if (s:is_wiki_page())
|
397
|
+
set textwidth=72
|
398
|
+
nnoremap <buffer> <cr> :call <SID>follow_link_under_cursor(0)<cr>
|
399
|
+
nnoremap <buffer> - :call <SID>follow_link_under_cursor(1)<cr>
|
400
|
+
nnoremap <buffer> \| :call <SID>follow_link_under_cursor(2)<cr>
|
401
|
+
noremap <buffer> <leader>f :call <SID>follow_link(0)<CR>
|
402
|
+
noremap <buffer> <leader>n :call <SID>find_next_wiki_link(0)<CR>
|
403
|
+
noremap <buffer> <leader>p :call <SID>find_next_wiki_link(1)<CR>
|
404
|
+
noremap <leader>c :call <SID>create_page()<CR>
|
405
|
+
command! -buffer SWDelete :call s:delete_page()
|
406
|
+
command! -buffer SWRename :call s:rename_page()
|
407
|
+
command! -buffer SWLog :call s:show_revision_history(0)
|
408
|
+
noremap <buffer> <leader>l :call <SID>show_revision_history(0)<CR>
|
409
|
+
command! -buffer SWLogStat :call s:show_revision_history(1)
|
410
|
+
command! -buffer SWBlame :call s:show_blame()
|
411
|
+
noremap <buffer> <leader>x :call <SID>unfurl()<CR>
|
412
|
+
set nu
|
413
|
+
setlocal completefunc=CompletePage
|
414
|
+
augroup <buffer>
|
415
|
+
au!
|
416
|
+
autocmd BufWritePost <buffer> call s:save_revision()
|
417
|
+
augroup END
|
418
|
+
endif
|
419
|
+
endfunc
|
420
|
+
|
421
|
+
func! s:highlight_wikiwords()
|
422
|
+
if (s:is_wiki_page())
|
423
|
+
exe "match Comment /". s:wiki_link_pattern. "/"
|
424
|
+
else
|
425
|
+
match none " not sure if this works
|
426
|
+
endif
|
427
|
+
endfunc
|
428
|
+
|
429
|
+
call s:global_mappings()
|
430
|
+
|
431
|
+
autocmd WinEnter * call s:highlight_wikiwords()
|
432
|
+
autocmd BufEnter * call s:prep_buffer()
|
433
|
+
|
434
|
+
" load most recent page
|
435
|
+
let pages = split(system("ls -t" ), "\n")
|
436
|
+
let start_page = len(pages) > 0 ? get(pages, 0) : "HomePage"
|
437
|
+
call s:load_page(start_page, 0)
|
438
|
+
|
439
|
+
if (!isdirectory(".git"))
|
440
|
+
call system("git init")
|
441
|
+
echom "Created .git repository to store revisions"
|
442
|
+
endif
|
443
|
+
|
444
|
+
if !exists("g:SoyWiki#browser_command")
|
445
|
+
for cmd in ["gnome-open", "open"]
|
446
|
+
if executable(cmd)
|
447
|
+
let g:SoyWiki#browser_command = cmd
|
448
|
+
break
|
449
|
+
endif
|
450
|
+
endfor
|
451
|
+
if !exists("g:SoyWiki#browser_command")
|
452
|
+
echom "Can't find the to open your web browser."
|
453
|
+
endif
|
454
|
+
endif
|
455
|
+
|
data/soywiki.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "soywiki"
|
6
|
+
s.version = "0.0.1"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Daniel Choi"]
|
9
|
+
s.email = ["dhchoi@gmail.com"]
|
10
|
+
s.homepage = "http://danielchoi.com/software/soywiki.html"
|
11
|
+
s.summary = %q{Wiki with Vim interface and Git repo}
|
12
|
+
s.description = %q{A personal and collaborative wiki for Vim users}
|
13
|
+
|
14
|
+
s.rubyforge_project = "soywiki"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'couchrest'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soywiki
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Daniel Choi
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-02-07 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: couchrest
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
description: A personal and collaborative wiki for Vim users
|
34
|
+
email:
|
35
|
+
- dhchoi@gmail.com
|
36
|
+
executables:
|
37
|
+
- soywiki
|
38
|
+
- soywiki-pages-linking-in
|
39
|
+
- soywiki-rename
|
40
|
+
- soywiki-unfurl
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- .gitignore
|
47
|
+
- Gemfile
|
48
|
+
- Gemfile.lock
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- bin/soywiki
|
52
|
+
- bin/soywiki-pages-linking-in
|
53
|
+
- bin/soywiki-rename
|
54
|
+
- bin/soywiki-unfurl
|
55
|
+
- lib/soywiki.rb
|
56
|
+
- lib/soywiki.vim
|
57
|
+
- soywiki.gemspec
|
58
|
+
has_rdoc: true
|
59
|
+
homepage: http://danielchoi.com/software/soywiki.html
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: soywiki
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Wiki with Vim interface and Git repo
|
90
|
+
test_files: []
|
91
|
+
|