ver 2009.10.14 → 2009.11.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (318) hide show
  1. data/CHANGELOG +1094 -0
  2. data/MANIFEST +227 -25
  3. data/README.textile +185 -0
  4. data/bin/ver +96 -12
  5. data/config/detect.rb +73 -21
  6. data/config/keymap/emacs.rb +66 -0
  7. data/config/keymap/vim.rb +250 -140
  8. data/config/preferences/ANTLR.json +10 -0
  9. data/config/preferences/ASP vb.NET.json +3 -0
  10. data/config/preferences/ASP.json +15 -0
  11. data/config/preferences/ActionScript.json +755 -0
  12. data/config/preferences/Active4D.json +89 -0
  13. data/config/preferences/Ada.json +23 -0
  14. data/config/preferences/Ant.json +356 -0
  15. data/config/preferences/Apache.json +644 -0
  16. data/config/preferences/AppleScript.json +92 -0
  17. data/config/preferences/Bison.json +3 -0
  18. data/config/preferences/Blogging.json +3 -0
  19. data/config/preferences/C.json +127 -0
  20. data/config/preferences/CMake.json +41 -0
  21. data/config/preferences/CSS.json +461 -0
  22. data/config/preferences/CTags.json +3 -0
  23. data/config/preferences/CVS.json +3 -0
  24. data/config/preferences/ColdFusion.json +32 -0
  25. data/config/preferences/D.json +58 -0
  26. data/config/preferences/Darcs.json +3 -0
  27. data/config/preferences/Diff.json +67 -0
  28. data/config/preferences/DokuWiki.json +19 -0
  29. data/config/preferences/Doxygen.json +3 -0
  30. data/config/preferences/Dylan.json +3 -0
  31. data/config/preferences/Eiffel.json +59 -0
  32. data/config/preferences/Erlang.json +72 -0
  33. data/config/preferences/Experimental.json +1356 -0
  34. data/config/preferences/F-Script.json +87 -0
  35. data/config/preferences/FXScript.json +78 -0
  36. data/config/preferences/FileMerge.json +3 -0
  37. data/config/preferences/Fortran.json +158 -0
  38. data/config/preferences/GTD2.json +11 -0
  39. data/config/preferences/GTDAlt.json +20 -0
  40. data/config/preferences/GetBundle.json +3 -0
  41. data/config/preferences/Gettext.json +24 -0
  42. data/config/preferences/Graphviz.json +42 -0
  43. data/config/preferences/Greasemonkey.json +3 -0
  44. data/config/preferences/Gri.json +34 -0
  45. data/config/preferences/HTML.json +492 -0
  46. data/config/preferences/Haskell.json +72 -0
  47. data/config/preferences/Hotkey.json +3 -0
  48. data/config/preferences/ImageBrowser.json +3 -0
  49. data/config/preferences/Inform.json +3 -0
  50. data/config/preferences/Ini.json +60 -0
  51. data/config/preferences/Installer.json +3 -0
  52. data/config/preferences/Io.json +64 -0
  53. data/config/preferences/JSON.json +3 -0
  54. data/config/preferences/Java.json +86 -0
  55. data/config/preferences/JavaDoc.json +3 -0
  56. data/config/preferences/JavaScript.json +76 -0
  57. data/config/preferences/LaTeX.json +267 -0
  58. data/config/preferences/Lex/Flex.json +3 -0
  59. data/config/preferences/Lighttpd.json +3 -0
  60. data/config/preferences/LilyPond.json +77 -0
  61. data/config/preferences/Lisp.json +63 -0
  62. data/config/preferences/Logo.json +58 -0
  63. data/config/preferences/Logtalk.json +236 -0
  64. data/config/preferences/Lua.json +24 -0
  65. data/config/preferences/MEL.json +19 -0
  66. data/config/preferences/MIPS Assembler.json +26 -0
  67. data/config/preferences/MacPorts.json +3 -0
  68. data/config/preferences/Mail.json +3 -0
  69. data/config/preferences/Make.json +16 -0
  70. data/config/preferences/Markdown.json +102 -0
  71. data/config/preferences/Math.json +3 -0
  72. data/config/preferences/Matlab.json +128 -0
  73. data/config/preferences/Maven.json +308 -0
  74. data/config/preferences/Mediawiki.json +73 -0
  75. data/config/preferences/Mercurial.json +3 -0
  76. data/config/preferences/Modula.json +37 -0
  77. data/config/preferences/MoinMoin.json +52 -0
  78. data/config/preferences/Navigation.json +3 -0
  79. data/config/preferences/Nemerle.json +3 -0
  80. data/config/preferences/OCaml Code Completion.json +3 -0
  81. data/config/preferences/OCaml.json +163 -0
  82. data/config/preferences/ODCompletion.json +3 -0
  83. data/config/preferences/Objective-C.json +84 -0
  84. data/config/preferences/OpenGL.json +3331 -0
  85. data/config/preferences/Outlines.json +3 -0
  86. data/config/preferences/Pascal.json +60 -0
  87. data/config/preferences/Perforce.json +3 -0
  88. data/config/preferences/Perl.json +15 -0
  89. data/config/preferences/PmWiki.json +27 -0
  90. data/config/preferences/Postscript.json +15 -0
  91. data/config/preferences/Processing.json +32 -0
  92. data/config/preferences/Prolog.json +3 -0
  93. data/config/preferences/Propel.json +3 -0
  94. data/config/preferences/Python.json +38 -0
  95. data/config/preferences/Quake.json +15 -0
  96. data/config/preferences/R.json +33 -0
  97. data/config/preferences/Ragel.json +15 -0
  98. data/config/preferences/Regular Expressions.json +3 -0
  99. data/config/preferences/Remind.json +15 -0
  100. data/config/preferences/Rez.json +46 -0
  101. data/config/preferences/Ruby.json +98 -0
  102. data/config/preferences/S5 Slide Show.json +20 -0
  103. data/config/preferences/SCons.json +3 -0
  104. data/config/preferences/SQL.json +32 -0
  105. data/config/preferences/SSH Config.json +15 -0
  106. data/config/preferences/SVK.json +3 -0
  107. data/config/preferences/SWIG.json +3 -0
  108. data/config/preferences/SWeave.json +32 -0
  109. data/config/preferences/Scheme.json +35 -0
  110. data/config/preferences/Scilab.json +15 -0
  111. data/config/preferences/Setext.json +3 -0
  112. data/config/preferences/Shell Script.json +25 -0
  113. data/config/preferences/Slate.json +113 -0
  114. data/config/preferences/Source.json +132 -0
  115. data/config/preferences/Subversion.json +10 -0
  116. data/config/preferences/TODO.json +3 -0
  117. data/config/preferences/Tabular.json +3 -0
  118. data/config/preferences/Tcl.json +82 -0
  119. data/config/preferences/TerminalMate.json +112 -0
  120. data/config/preferences/Text.json +89 -0
  121. data/config/preferences/TextMate.json +38 -0
  122. data/config/preferences/Textile.json +76 -0
  123. data/config/preferences/Thrift.json +56 -0
  124. data/config/preferences/Transmit.json +3 -0
  125. data/config/preferences/Twiki.json +51 -0
  126. data/config/preferences/Txt2tags.json +81 -0
  127. data/config/preferences/Vectorscript.json +1280 -0
  128. data/config/preferences/XML.json +60 -0
  129. data/config/preferences/Xcode.json +3 -0
  130. data/config/preferences/YAML.json +24 -0
  131. data/config/preferences/iCalendar.json +10 -0
  132. data/config/preferences/iTerm.json +36 -0
  133. data/config/preferences/reStructuredText.json +48 -0
  134. data/config/rc.rb +49 -0
  135. data/config/syntax/ANTLR.json +5 -5
  136. data/config/syntax/{ASP VB.net.json → ASP vb.NET.json } +3 -3
  137. data/config/syntax/ASP.json +1 -1
  138. data/config/syntax/ActionScript.json +6 -6
  139. data/config/syntax/Active4D Config.json +86 -0
  140. data/config/syntax/Active4D Library.json +20 -0
  141. data/config/syntax/Active4D.json +418 -0
  142. data/config/syntax/Ada.json +3 -3
  143. data/config/syntax/Ant.json +196 -0
  144. data/config/syntax/Apache.json +7 -7
  145. data/config/syntax/AppleScript.json +3 -3
  146. data/config/syntax/{Bibtex.json → BibTeX.json} +1 -1
  147. data/config/syntax/Bison.json +59 -0
  148. data/config/syntax/{Blog (HTML).json → Blog - HTML.json } +2 -2
  149. data/config/syntax/{Blog (Markdown).json → Blog - Markdown.json } +2 -2
  150. data/config/syntax/Blog (Text).json b/data/config/syntax/Blog - → Text.json +0 -0
  151. data/config/syntax/Blog (Textile).json b/data/config/syntax/Blog - → Textile.json +0 -0
  152. data/config/syntax/C++.json +3 -3
  153. data/config/syntax/C.json +13 -13
  154. data/config/syntax/CMake Listfile.json +171 -0
  155. data/config/syntax/CSS.json +6 -6
  156. data/config/syntax/CSV.json +108 -0
  157. data/config/syntax/ColdFusion.json +204 -0
  158. data/config/syntax/D.json +560 -0
  159. data/config/syntax/Diff.json +1 -1
  160. data/config/syntax/DokuWiki.json +412 -0
  161. data/config/syntax/Doxygen.json +80 -0
  162. data/config/syntax/Dylan.json +4 -4
  163. data/config/syntax/Erlang.json +5 -5
  164. data/config/syntax/F-Script.json +1 -1
  165. data/config/syntax/FXScript.json +5 -5
  166. data/config/syntax/Fortran - Modern.json +221 -0
  167. data/config/syntax/Fortran - Punchcard.json +468 -0
  168. data/config/syntax/GTD.json +39 -0
  169. data/config/syntax/GTDalt.json +233 -0
  170. data/config/syntax/Gettext.json +118 -0
  171. data/config/syntax/Go.json +555 -0
  172. data/config/syntax/{DOT.json → Graphviz (DOT).json } +3 -3
  173. data/config/syntax/Greasemonkey.json +56 -0
  174. data/config/syntax/Gri.json +4 -4
  175. data/config/syntax/{HTML-ASP.json → HTML (ASP).json } +1 -1
  176. data/config/syntax/{HTML for ASP.net.json → HTML (ASP.net).json } +19 -19
  177. data/config/syntax/HTML (Active4D).json +540 -0
  178. data/config/syntax/HTML (Erlang).json +31 -0
  179. data/config/syntax/HTML (Tcl).json +1 -1
  180. data/config/syntax/HTML.json +20 -20
  181. data/config/syntax/Haskell.json +3 -3
  182. data/config/syntax/Installer Distribution Script.json +135 -0
  183. data/config/syntax/Io.json +6 -6
  184. data/config/syntax/JSON.json +151 -0
  185. data/config/syntax/{JavaProperties.json → Java Properties.json } +2 -2
  186. data/config/syntax/Java Server Page (JSP).json +163 -0
  187. data/config/syntax/Java.json +7 -7
  188. data/config/syntax/JavaDoc.json +435 -0
  189. data/config/syntax/JavaScript.json +8 -8
  190. data/config/syntax/LaTeX Log.json +3 -3
  191. data/config/syntax/LaTeX Memoir.json +101 -0
  192. data/config/syntax/LaTeX.json +2 -2
  193. data/config/syntax/Lex-Flex.json +396 -0
  194. data/config/syntax/LilyPond.json +608 -0
  195. data/config/syntax/Logo.json +48 -0
  196. data/config/syntax/Logtalk.json +6 -6
  197. data/config/syntax/Lua.json +1 -1
  198. data/config/syntax/{M.json → MATLAB.json} +3 -3
  199. data/config/syntax/MEL.json +7 -7
  200. data/config/syntax/MIPS.json b/data/config/syntax/MIPS → Assembler.json +0 -0
  201. data/config/syntax/MacPorts Portfile.json +298 -0
  202. data/config/syntax/Mail.json +1 -1
  203. data/config/syntax/Markdown.json +6 -6
  204. data/config/syntax/Maven POM.json +774 -0
  205. data/config/syntax/Mediawiki.json +736 -0
  206. data/config/syntax/MoinMoin.json +335 -0
  207. data/config/syntax/MultiMarkdown.json +41 -0
  208. data/config/syntax/Nemerle.json +128 -0
  209. data/config/syntax/OCaml.json +4 -4
  210. data/config/syntax/OCamllex.json +307 -0
  211. data/config/syntax/OCamlyacc.json +346 -0
  212. data/config/syntax/Objective-C++.json +2 -2
  213. data/config/syntax/Objective-C.json +979 -0
  214. data/config/syntax/Octave.json +417 -0
  215. data/config/syntax/PHP.json +32 -32
  216. data/config/syntax/Pascal.json +1 -1
  217. data/config/syntax/Perl.json +8 -8
  218. data/config/syntax/{Plain text.json → Plain Text.json } +1 -1
  219. data/config/syntax/PmWiki.json +241 -0
  220. data/config/syntax/Postscript.json +206 -0
  221. data/config/syntax/Processing.json +8 -8
  222. data/config/syntax/Prolog.json +70 -0
  223. data/config/syntax/Python.json +1934 -0
  224. data/config/syntax/{Quake3 Config.json → Quake Style .cfg.json } +1 -1
  225. data/config/syntax/R.json +2 -2
  226. data/config/syntax/Ragel.json +362 -0
  227. data/config/syntax/Rd (R Documentation).json +119 -0
  228. data/config/syntax/Regular Expressions (Oniguruma).json +186 -0
  229. data/config/syntax/Regular Expressions (Python).json +188 -0
  230. data/config/syntax/Release Notes.json +78 -0
  231. data/config/syntax/Remind.json +461 -0
  232. data/config/syntax/Rez.json +5 -5
  233. data/config/syntax/Ruby Sass.json +497 -0
  234. data/config/syntax/Ruby.json +13 -13
  235. data/config/syntax/S5 Slide Show.json +85 -0
  236. data/config/syntax/SQL.json +11 -11
  237. data/config/syntax/SSH Config.json +55 -0
  238. data/config/syntax/SWIG.json +2 -2
  239. data/config/syntax/SWeave.json +139 -0
  240. data/config/syntax/Scheme.json +8 -8
  241. data/config/syntax/Scilab.json +69 -0
  242. data/config/syntax/Setext.json +247 -0
  243. data/config/syntax/{Shell-Unix-Generic.json → Shell Script (Bash).json } +4 -4
  244. data/config/syntax/Slate.json +5 -5
  245. data/config/syntax/Strings File.json +53 -0
  246. data/config/syntax/TSV.json +83 -0
  247. data/config/syntax/Tcl.json +1 -1
  248. data/config/syntax/TeX Math.json +2 -2
  249. data/config/syntax/TeX.json +2 -2
  250. data/config/syntax/Textile.json +9 -9
  251. data/config/syntax/Thrift.json +641 -0
  252. data/config/syntax/Twiki.json +1 -1
  253. data/config/syntax/Txt2tags.json +154 -0
  254. data/config/syntax/XML strict.json +4 -4
  255. data/config/syntax/XML.json +6 -6
  256. data/config/syntax/XSL.json +2 -2
  257. data/config/syntax/camlp4.json +63 -0
  258. data/config/syntax/mod_perl.json +72 -0
  259. data/config/syntax/reStructuredText.json +1 -1
  260. data/config/syntax/{Subversion commit message.json → svn-commit.tmp.json} +0 -0
  261. data/config/tutorial +23 -19
  262. data/config/welcome +3 -3
  263. data/lib/ver.rb +273 -62
  264. data/lib/ver/entry.rb +142 -26
  265. data/lib/ver/font.rb +51 -0
  266. data/lib/ver/help.rb +16 -0
  267. data/lib/ver/help/describe_key.rb +82 -0
  268. data/lib/ver/help/help_for_help.rb +39 -0
  269. data/lib/ver/hover_completion.rb +129 -0
  270. data/lib/ver/keymap.rb +95 -24
  271. data/lib/ver/layout.rb +107 -43
  272. data/lib/ver/methods.rb +24 -8
  273. data/lib/ver/methods/clipboard.rb +91 -0
  274. data/lib/ver/methods/completion.rb +146 -71
  275. data/lib/ver/methods/control.rb +203 -222
  276. data/lib/ver/methods/ctags.rb +55 -0
  277. data/lib/ver/methods/delete.rb +30 -0
  278. data/lib/ver/methods/help.rb +7 -0
  279. data/lib/ver/methods/insert.rb +233 -1
  280. data/lib/ver/methods/move.rb +181 -32
  281. data/lib/ver/methods/open.rb +208 -0
  282. data/lib/ver/methods/preview.rb +14 -0
  283. data/lib/ver/methods/save.rb +111 -0
  284. data/lib/ver/methods/search.rb +57 -7
  285. data/lib/ver/methods/select.rb +97 -17
  286. data/lib/ver/methods/shortcuts.rb +21 -0
  287. data/lib/ver/methods/views.rb +56 -1
  288. data/lib/ver/mode.rb +60 -14
  289. data/lib/ver/status.rb +97 -19
  290. data/lib/ver/syntax.rb +14 -6
  291. data/lib/ver/syntax/detector.rb +16 -5
  292. data/lib/ver/syntax/processor.rb +9 -3
  293. data/lib/ver/text.rb +258 -199
  294. data/lib/ver/text/index.rb +103 -0
  295. data/lib/ver/theme.rb +27 -16
  296. data/lib/ver/tooltip.rb +59 -0
  297. data/lib/ver/vendor/binary_search.rb +61 -0
  298. data/lib/ver/vendor/levenshtein.rb +57 -0
  299. data/lib/ver/{textpow.rb → vendor/textpow.rb} +31 -29
  300. data/lib/ver/view.rb +65 -41
  301. data/lib/ver/view/console.rb +171 -0
  302. data/lib/ver/view/entry.rb +9 -5
  303. data/lib/ver/view/list.rb +44 -29
  304. data/lib/ver/view/list/ex.rb +71 -0
  305. data/lib/ver/view/list/grep.rb +42 -0
  306. data/lib/ver/view/list/methods.rb +159 -0
  307. data/lib/ver/view/term.rb +249 -0
  308. data/tasks/syntax_list.rake +3 -2
  309. data/ver.gemspec +4 -4
  310. metadata +230 -28
  311. data/config/syntax/Bulletin Board.json +0 -428
  312. data/config/syntax/HTML (Mason).json +0 -207
  313. data/config/syntax/HTML (Rails).json +0 -52
  314. data/config/syntax/Movable Type.json +0 -348
  315. data/config/syntax/Ruby on Rails.json +0 -170
  316. data/config/syntax/SQL (Rails).json +0 -31
  317. data/config/syntax/Smarty.json +0 -110
  318. data/config/syntax/Standard ML.json +0 -322
@@ -0,0 +1,208 @@
1
+ module VER
2
+ module Methods
3
+ module Open
4
+ # TODO:
5
+ # Binary files are still major fail.
6
+ # We could try to copy behaviour of Vim or Emacs.
7
+ # Some nice files for testing binary display are in /usr/share/terminfo
8
+ #
9
+ # About the nature of fail:
10
+ # First of all, just about no font is made to have binary glyphs, even if it
11
+ # would be nice to create a composite font, and would make editing a lot
12
+ # nicer, it's really no option.
13
+ #
14
+ # Next issue is that some bytes that occur in binary files "\0" for example,
15
+ # cause big problems for Tcl_EvalEx.
16
+ #
17
+ # I've tried sending the byte as:
18
+ # "\0", "\\0",
19
+ # "\x0", "\\x0",
20
+ # "\x00", "\\x00",
21
+ # "\u0000", "\\u0000"
22
+ #
23
+ # Tcl doesn't like that at all.
24
+ # The first obviously sends the original \0 byte directly on, the second
25
+ # displays in the widget as "\0", "\x0", and so on, which will lead to total
26
+ # corruption.
27
+ #
28
+ # I have no idea how to work around this issue, must be some convention?
29
+ # More important though, is to avoid sending those bytes at all, and it
30
+ # seems to be a huge amount of work to get support for binary editing going.
31
+ # There are much better tools for this around already, and maybe diluting
32
+ # the normal Text buffer for this purpose will just make problems.
33
+ #
34
+ # For now, VER will simply fail to open files that contain \0 bytes, and
35
+ # display binary files in a weird way.
36
+ def open_path(path, line = 1)
37
+ self.filename = path
38
+
39
+ begin
40
+ self.value = read_file(filename)
41
+ message "Opened #{short_filename}"
42
+ rescue Errno::ENOENT
43
+ delete '1.0', :end
44
+ message "Create #{short_filename}"
45
+ end
46
+
47
+ after_open(line)
48
+ end
49
+
50
+ # Read given file into memory and convert to @encoding
51
+ def read_file(path)
52
+ path = Pathname(path.to_s).expand_path
53
+ encoding_name = encoding.name
54
+ content = path.open("r:#{encoding_name}"){|io| io.read }
55
+
56
+ unless content.valid_encoding? # take a guess
57
+ @encoding = GUESS_ENCODING_ORDER.find{|enc|
58
+ content.force_encoding(enc)
59
+ content.valid_encoding?
60
+ }
61
+
62
+ # Now we have the source encoding, let's make it UTF-8 so Tcl can
63
+ # handle it.
64
+ content.force_encoding(@encoding)
65
+ content.encode!(Encoding::UTF_8)
66
+ end
67
+
68
+ content.chomp
69
+ end
70
+
71
+ def open_empty
72
+ delete '1.0', :end
73
+ message "[No File]"
74
+ after_open
75
+ end
76
+
77
+ def after_open(line = 1)
78
+ VER.opened_file(self)
79
+
80
+ edit_reset
81
+ mark_set :insert, "#{line.to_i}.0"
82
+ @pristine = false
83
+
84
+ bind('<Map>') do
85
+ defer do
86
+ setup_highlight
87
+ apply_modeline
88
+ end
89
+ bind('<Map>'){ see(:insert) }
90
+ end
91
+ end
92
+
93
+ MODELINES = {
94
+ /\s+(?:ver|vim?|ex):\s*.*$/ => /\s+(?:ver|vim?|ex):\s*(.*)$/,
95
+ /\s+(?:ver|vim?|ex):[^:]+:/ => /\s+(?:ver|vim?|ex):([^:]+):/,
96
+ /^(?:ver|vim?):[^:]+:/ => /^(?:ver|vim?):([^:]+):/,
97
+ }
98
+
99
+ def apply_modeline
100
+ MODELINES.each do |search_pattern, extract_pattern|
101
+ found = search(search_pattern, 1.0, :end, :count)
102
+
103
+ next if found.empty?
104
+
105
+ pos, count = found
106
+ p found: found, pos: pos, count: count
107
+
108
+ line = get(pos, "#{pos} + #{count} chars")
109
+ p line: line
110
+
111
+ line =~ extract_pattern
112
+ $1.scan(/[^:\s]+/) do |option|
113
+ apply_modeline_option(option)
114
+ end
115
+ end
116
+ end
117
+
118
+ def apply_modeline_option(option)
119
+ negative = option.gsub!(/^no/, '')
120
+ boolean = !negative
121
+
122
+ case option
123
+ when 'ai', 'autoindent'
124
+ set :autoindent, boolean
125
+ when 'et', 'expandtab'
126
+ set :expandtab, boolean
127
+ when /(?:tw|textwidth)=(\d+)/
128
+ set :textwidth, $1.to_i
129
+ when /(?:ts|tabstop)=(\d+)/
130
+ set :tabstop, $1.to_i
131
+ when /(?:sw|shiftwidth)=(\d+)/
132
+ set :shiftwidth, $1.to_i
133
+ when /(?:ft|filetype)=(\w+)/
134
+ set :filetype, $1
135
+ else
136
+ p unknown_modeline_option: option
137
+ end
138
+ end
139
+
140
+ attr_reader :options
141
+
142
+ def set(option, value)
143
+ method = "set_#{option}"
144
+
145
+ if respond_to?(method)
146
+ if block_given?
147
+ __send__(method, value, &Proc.new)
148
+ else
149
+ __send__(method, value)
150
+ end
151
+ else
152
+ options[option] = value
153
+ yield(value) if block_given?
154
+ end
155
+
156
+ require 'pp'
157
+ pp options
158
+ end
159
+
160
+ def set_filetype(type)
161
+ syntax = Syntax.from_filename(Pathname("foo.#{type}"))
162
+
163
+ if load_syntax(syntax)
164
+ options.filetype = type
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ =begin
172
+ There are two forms of modelines. The first form:
173
+ [text]{white}{vi:|vim:|ex:}[white]{options}
174
+
175
+ [text] any text or empty
176
+ {white} at least one blank character (<Space> or <Tab>)
177
+ {vi:|vim:|ex:} the string "vi:", "vim:" or "ex:"
178
+ [white] optional white space
179
+ {options} a list of option settings, separated with white space or ':',
180
+ where each part between ':' is the argument for a ":set"
181
+ command (can be empty)
182
+
183
+ Example:
184
+ vi:noai:sw=3 ts=6 ~
185
+
186
+ The second form (this is compatible with some versions of Vi):
187
+
188
+ [text]{white}{vi:|vim:|ex:}[white]se[t] {options}:[text]
189
+
190
+ [text] any text or empty
191
+ {white} at least one blank character (<Space> or <Tab>)
192
+ {vi:|vim:|ex:} the string "vi:", "vim:" or "ex:"
193
+ [white] optional white space
194
+ se[t] the string "set " or "se " (note the space)
195
+ {options} a list of options, separated with white space, which is the
196
+ argument for a ":set" command
197
+ : a colon
198
+ [text] any text or empty
199
+
200
+ Example:
201
+ /* vim: set ai tw=75: */ ~
202
+
203
+ The white space before {vi:|vim:|ex:} is required. This minimizes the chance
204
+ that a normal word like "lex:" is caught. There is one exception: "vi:" and
205
+ "vim:" can also be at the start of the line (for compatibility with version
206
+ 3.0). Using "ex:" at the start of the line will be ignored (this could be
207
+ short for "example:").
208
+ =end
@@ -0,0 +1,14 @@
1
+ module VER
2
+ module Methods
3
+ module Preview
4
+ def preview
5
+ return unless syntax
6
+
7
+ case syntax.name
8
+ when 'Ruby'
9
+ View::Console.new(self, 'ruby', filename)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,111 @@
1
+ module VER
2
+ module Methods
3
+ module Save
4
+ def may_close
5
+ return yield unless edit_modified?
6
+ return yield if persisted?
7
+
8
+ question = 'Save this buffer before closing? [y]es [n]o [c]ancel: '
9
+
10
+ status_ask question, take: 1 do |answer|
11
+ case answer[0]
12
+ when 'Y', 'y'
13
+ yield if file_save
14
+ :saved
15
+ when 'N', 'n'
16
+ yield
17
+ :close_without_saving
18
+ else
19
+ "Cancel closing"
20
+ end
21
+ end
22
+ end
23
+
24
+ def persisted?
25
+ return false unless filename && filename.file?
26
+ require 'digest/md5'
27
+
28
+ on_disk = Digest::MD5.hexdigest(filename.read)
29
+ in_memory = Digest::MD5.hexdigest(value)
30
+ on_disk == in_memory
31
+ end
32
+
33
+ def quit
34
+ VER.exit
35
+ end
36
+
37
+ def file_save(filename = self.filename)
38
+ save_to(filename)
39
+ end
40
+
41
+ def file_save_popup(options = {})
42
+ options = options.dup
43
+ options[:filetypes] ||= [
44
+ ['ALL Files', '*' ],
45
+ ['Text Files', '*.txt'],
46
+ ]
47
+
48
+ options[:filename] ||= ::File.basename(@filename)
49
+ options[:extension] ||= ::File.extname(@filename)
50
+ options[:directory] ||= ::File.dirname(@filename)
51
+
52
+ fpath = Tk.get_save_file(options)
53
+
54
+ return unless fpath
55
+
56
+ save_to(fpath)
57
+ end
58
+
59
+ # Some strategies are discussed at:
60
+ #
61
+ # http://bitworking.org/news/390/text-editor-saving-routines
62
+ #
63
+ # I try another, "wasteful" approach, copying the original file to a
64
+ # temporary location, overwriting the contents in the copy, then moving the
65
+ # file to the location of the original file.
66
+ #
67
+ # This way all permissions should be kept identical without any effort, but
68
+ # it will take up additional disk space.
69
+ #
70
+ # If there is some failure during the normal saving procedure, we will
71
+ # simply overwrite the original file in place, make sure you have good insurance ;)
72
+ def save_to(to)
73
+ save_atomic(filename, to)
74
+ rescue => exception
75
+ VER.error(exception)
76
+ save_dumb(to)
77
+ end
78
+
79
+ def save_atomic(from, to)
80
+ require 'tmpdir'
81
+ sha1 = Digest::SHA1.hexdigest([from, to].join)
82
+ temp_path = File.join(Dir.tmpdir, 'ver', sha1)
83
+ temp_dir = File.dirname(temp_path)
84
+
85
+ FileUtils.mkdir_p(temp_dir)
86
+ FileUtils.copy_file(from, temp_path, preserve = true)
87
+ File.open(temp_path, 'w+') do |io|
88
+ io.write(self.value)
89
+ end
90
+ FileUtils.mv(temp_path, to)
91
+
92
+ status.message "Saved to #{to}"
93
+ return true
94
+ rescue Errno::ENOENT
95
+ save_dumb(to)
96
+ end
97
+
98
+ def save_dumb(to)
99
+ File.open(to, 'w+') do |io|
100
+ io.write(self.value)
101
+ end
102
+
103
+ status.message "Saved to #{to}"
104
+ return true
105
+ rescue Exception => ex
106
+ VER.error(ex)
107
+ return false
108
+ end
109
+ end
110
+ end
111
+ end
@@ -1,9 +1,33 @@
1
1
  module VER
2
2
  module Methods
3
3
  module Search
4
- def status_search
5
- status_ask 'Search term: ' do |term|
6
- tag_all_matching(:search, Regexp.new(term))
4
+ SEARCH_HIGHLIGHT = {
5
+ foreground: '#000',
6
+ background: '#ff0',
7
+ }
8
+
9
+ def status_search_next
10
+ status_search_common('/') do
11
+ search_next
12
+ end
13
+ end
14
+
15
+ def status_search_prev
16
+ status_search_common('?') do
17
+ search_prev
18
+ end
19
+ end
20
+
21
+ def status_search_common(question)
22
+ status_ask question do |term|
23
+ begin
24
+ needle = Regexp.new(term)
25
+ rescue RegexpError
26
+ needle = Regexp.escape(term)
27
+ end
28
+
29
+ tag_all_matching(:search, needle, SEARCH_HIGHLIGHT)
30
+ yield
7
31
  end
8
32
  end
9
33
 
@@ -13,21 +37,47 @@ module VER
13
37
  end
14
38
 
15
39
  def search_prev
16
- from, to = tag_prevrange('search', 'insert - 1 chars', '0.0')
40
+ from, to = tag_prevrange('search', 'insert - 1 chars', '1.0')
17
41
  mark_set(:insert, from) if from
18
42
  end
19
43
 
20
44
  def search_next_word_under_cursor
21
45
  word = get('insert wordstart', 'insert wordend')
22
- tag_all_matching(:search, word)
46
+ return if word.squeeze == ' ' # we don't want to match space
47
+ tag_all_matching(:search, word, SEARCH_HIGHLIGHT)
23
48
  search_next
24
49
  end
25
50
 
26
51
  def search_prev_word_under_cursor
27
52
  word = get('insert wordstart', 'insert wordend')
28
- tag_all_matching(:search, word)
53
+ return if word.squeeze == ' ' # we don't want to match space
54
+ tag_all_matching(:search, word, SEARCH_HIGHLIGHT)
29
55
  search_prev
30
56
  end
57
+
58
+ def search_char_right
59
+ status_ask 'Search char right: ', take: 1 do |char|
60
+ from, to = 'insert', 'insert lineend'
61
+ regexp = Regexp.new(Regexp.escape(char))
62
+
63
+ search_all regexp, from, to do |match, pos, mark|
64
+ mark_set :insert, pos
65
+ break
66
+ end
67
+ end
68
+ end
69
+
70
+ def search_char_left
71
+ status_ask 'Search char left: ', take: 1 do |char|
72
+ from, to = 'insert', 'insert linestart'
73
+ regexp = Regexp.new(Regexp.escape(char))
74
+
75
+ rsearch_all regexp, from, to do |match, pos, mark|
76
+ mark_set :insert, pos
77
+ break
78
+ end
79
+ end
80
+ end
31
81
  end
32
82
  end
33
- end
83
+ end
@@ -1,14 +1,39 @@
1
1
  module VER
2
2
  module Methods
3
3
  module Select
4
+ def wrap_selection
5
+ queue = []
6
+ text = []
7
+
8
+ each_selected_line do |y, fx, tx|
9
+ queue << y
10
+ text << get("#{y}.0", "#{y}.0 lineend")
11
+ end
12
+
13
+ lines = wrap_lines_of(text.join(' '))
14
+ from, to = queue.first, queue.last
15
+ replace("#{from}.0", "#{to}.0 lineend", lines.join("\n"))
16
+
17
+ finish_selection
18
+ end
19
+
4
20
  def start_selection_mode(name)
5
21
  self.mode = name
6
- @selection_start = index(:insert).split('.').map(&:to_i)
7
- refresh_selection
22
+ start_selection(name)
8
23
  end
9
24
 
10
25
  def switch_selection_mode(name)
11
26
  self.mode = name
27
+ switch_selection(name)
28
+ end
29
+
30
+ def start_selection(name)
31
+ self.selection_start = index(:insert)
32
+ switch_selection(name)
33
+ end
34
+
35
+ def switch_selection(name)
36
+ self.selection_mode = name.to_sym
12
37
  refresh_selection
13
38
  end
14
39
 
@@ -28,15 +53,17 @@ module VER
28
53
  delete(*queue)
29
54
  mark_set(:insert, queue.first)
30
55
 
31
- clear_selection
32
- start_control_mode
56
+ finish_selection
33
57
  end
34
58
 
35
59
  def indent_selection
60
+ indent_size = VER.options.shiftwidth
61
+ indent = ' ' * indent_size
62
+
36
63
  each_selected_line do |y, fx, tx|
37
- tx = fx + 2
64
+ tx = fx + indent_size
38
65
  next if get("#{y}.#{fx}", "#{y}.#{tx}").empty?
39
- insert("#{y}.#{fx}", ' ')
66
+ insert("#{y}.#{fx}", indent)
40
67
  end
41
68
 
42
69
  edit_separator
@@ -44,12 +71,14 @@ module VER
44
71
  end
45
72
 
46
73
  def unindent_selection
74
+ indent_size = VER.options.shiftwidth
75
+ indent = ' ' * indent_size
47
76
  queue = []
48
77
 
49
78
  each_selected_line do |y, fx, tx|
50
- tx = fx + 2
79
+ tx = fx + indent_size
51
80
  left, right = "#{y}.#{fx}", "#{y}.#{tx}"
52
- next unless get(left, right) == ' '
81
+ next unless get(left, right) == indent
53
82
  queue << left << right
54
83
  end
55
84
 
@@ -62,27 +91,24 @@ module VER
62
91
  tag_ranges(:sel).each do |from, to|
63
92
  code = get(from, to)
64
93
 
65
- begin
66
- result = eval(code)
67
- insert("#{to} lineend", "\n%p" % [result])
68
- rescue => exception
69
- insert("#{to} lineend", "\n%p" % [exception])
94
+ stdout_capture_evaluate(code) do |res,out|
95
+ insert("#{to} lineend", "\n%s%p" % [out, res] )
70
96
  end
71
97
  end
98
+
99
+ finish_selection
72
100
  end
73
101
 
74
102
  def copy_selection
75
103
  chunks = tag_ranges(:sel).map{|sel| get(*sel) }
76
104
  copy(chunks.size == 1 ? chunks.first : chunks)
77
- clear_selection
78
- start_control_mode
105
+ finish_selection
79
106
  end
80
107
 
81
108
  def pipe_selection
82
109
  status_ask 'Pipe command: ' do |cmd|
83
110
  pipe_selection_execute(cmd)
84
- clear_selection
85
- start_control_mode
111
+ finish_selection
86
112
  end
87
113
  end
88
114
 
@@ -104,8 +130,62 @@ module VER
104
130
  refresh_selection
105
131
  end
106
132
 
133
+ def selection_replace_char
134
+ status_ask 'Replace selection with: ', take: 1 do |char|
135
+ if char.size == 1
136
+ replace_selection_with(char, full = true)
137
+ "replaced 1 char"
138
+ else
139
+ 'replace aborted'
140
+ end
141
+ end
142
+ end
143
+
144
+ def selection_replace_string
145
+ status_ask 'Replace selection with: ', do |string|
146
+ if string.size > 0
147
+ replace_selection_with(string, full = false)
148
+ "replaced #{string.size} chars"
149
+ else
150
+ 'replace aborted'
151
+ end
152
+ end
153
+ end
154
+
107
155
  private
108
156
 
157
+ # TODO: find better name for +full+
158
+ def replace_selection_with(string, full)
159
+ origin = index(:insert)
160
+
161
+ if full
162
+ each_selected_line do |y, fx, tx|
163
+ diff = tx - fx
164
+ replace("#{y}.#{fx}", "#{y}.#{tx}", string * diff)
165
+ end
166
+ else
167
+ string_size = string.size
168
+ each_selected_line do |y, fx, tx|
169
+ replace("#{y}.#{fx}", "#{y}.#{tx}", string)
170
+ end
171
+ end
172
+
173
+ edit_separator
174
+ mark_set :insert, origin
175
+ end
176
+
177
+ def finish_selection(mode = nil)
178
+ edit_separator
179
+ clear_selection
180
+ mode ? self.mode = mode : keymap.use_previous_mode
181
+ apply_mode_style(keymap.mode)
182
+ end
183
+
184
+ def clear_selection
185
+ self.selection_start = nil
186
+ tag_remove :sel, '1.0', 'end'
187
+ end
188
+
109
189
  def each_selection
110
190
  tag_ranges(:sel).each do |sel|
111
191
  (fy, fx), (ty, tx) = sel.map{|pos| pos.split('.').map(&:to_i) }