Module: VER

Defined in:
lib/ver.rb,
lib/ver/font.rb,
lib/ver/help.rb,
lib/ver/text.rb,
lib/ver/undo.rb,
lib/ver/entry.rb,
lib/ver/plist.rb,
lib/ver/theme.rb,
lib/ver/action.rb,
lib/ver/buffer.rb,
lib/ver/keymap.rb,
lib/ver/status.rb,
lib/ver/syntax.rb,
lib/ver/keysyms.rb,
lib/ver/methods.rb,
lib/ver/options.rb,
lib/ver/version.rb,
lib/ver/executor.rb,
lib/ver/treeview.rb,
lib/ver/major_mode.rb,
lib/ver/minibuffer.rb,
lib/ver/minor_mode.rb,
lib/ver/text/index.rb,
lib/ver/status/mode.rb,
lib/ver/layout/paned.rb,
lib/ver/methods/help.rb,
lib/ver/methods/move.rb,
lib/ver/methods/nano.rb,
lib/ver/methods/open.rb,
lib/ver/methods/save.rb,
lib/ver/methods/undo.rb,
lib/ver/status/label.rb,
lib/ver/widget_event.rb,
lib/ver/executor/grep.rb,
lib/ver/executor/path.rb,
lib/ver/layout/tiling.rb,
lib/ver/methods/basic.rb,
lib/ver/methods/ctags.rb,
lib/ver/status/syntax.rb,
lib/ver/buffer/console.rb,
lib/ver/exception_view.rb,
lib/ver/executor/entry.rb,
lib/ver/executor/label.rb,
lib/ver/executor/theme.rb,
lib/ver/methods/delete.rb,
lib/ver/methods/insert.rb,
lib/ver/methods/layout.rb,
lib/ver/methods/search.rb,
lib/ver/status/battery.rb,
lib/ver/status/percent.rb,
lib/ver/executor/buffer.rb,
lib/ver/executor/locate.rb,
lib/ver/executor/method.rb,
lib/ver/executor/syntax.rb,
lib/ver/layout/notebook.rb,
lib/ver/methods/control.rb,
lib/ver/methods/preview.rb,
lib/ver/methods/snippet.rb,
lib/ver/status/encoding.rb,
lib/ver/status/filename.rb,
lib/ver/status/position.rb,
lib/ver/syntax/detector.rb,
lib/ver/hover_completion.rb,
lib/ver/keymap/keymapped.rb,
lib/ver/methods/autofill.rb,
lib/ver/methods/bookmark.rb,
lib/ver/status/nano_help.rb,
lib/ver/status/separator.rb,
lib/ver/syntax/processor.rb,
lib/ver/help/describe_key.rb,
lib/ver/methods/clipboard.rb,
lib/ver/widget_major_mode.rb,
lib/ver/help/help_for_help.rb,
lib/ver/methods/completion.rb,
lib/ver/vendor/levenshtein.rb,
lib/ver/layout/tiling/common.rb,
lib/ver/status/nano_position.rb,
lib/ver/vendor/binary_search.rb,
lib/ver/status/short_filename.rb,
lib/ver/layout/tiling/vertical.rb,
lib/ver/status/buffer_position.rb,
lib/ver/layout/tiling/horizontal.rb,
lib/ver/status/diakonos_position.rb,
lib/ver/executor/fuzzy_file_finder.rb,
lib/ver/methods/search_and_replace.rb,
config/plugin/git.rb,
config/plugin/soma.rb,
config/plugin/animated_tiling.rb,
config/plugin/smart_autoindent.rb

Overview

Copyright © 2009 Michael Fellinger <[email protected]>

Description:

Shortcuts to use git within VER. This simply opens an urxvt console and embeds it into VER until you finish interacting with git.

Usage:

Put following line into your rc.rb

VER.plugin :git

Defined Under Namespace

Modules: Font, Help, Keymapped, Levenshtein, Methods, Optioned, Plist, Undo Classes: Action, BinarySearch, Bookmarks, Buffer, Entry, ExceptionView, Executor, HoverCompletion, Keymap, MajorMode, MiniBuffer, MinorMode, NotebookLayout, Options, PanedLayout, Snippet, Status, Syntax, Text, Theme, TilingLayout, Treeview, WidgetEvent, WidgetMajorMode

Constant Summary collapse

KEYSYMS =

A Hash containing the Tk keysyms. The key is the ascii character, the value is the name as used in tk binds.

{
  " "  => "<space>",
  "!"  => "<exclam>",
  "#"  => "<numbersign>",
  "$"  => "<dollar>",
  "%"  => "<percent>",
  "&"  => "<ampersand>",
  "'"  => "<quoteright>",
  "("  => "<parenleft>",
  ")"  => "<parenright>",
  "*"  => "<asterisk>",
  "+"  => "<plus>",
  ","  => "<comma>",
  "-"  => "<minus>",
  "."  => "<period>",
  "/"  => "<slash>",
  ":"  => "<colon>",
  ";"  => "<semicolon>",
  "<"  => "<less>",
  "="  => "<equal>",
  ">"  => "<greater>",
  "?"  => "<question>",
  "@"  => "<at>",
  "["  => "<bracketleft>",
  "\\" => "<backslash>",
  "]"  => "<bracketright>",
  "^"  => "<asciicircum>",
  "_"  => "<underscore>",
  "`"  => "<quoteleft>",
  "{"  => "<braceleft>",
  "|"  => "<bar>",
  "}"  => "<braceright>",
  "~"  => "<asciitilde>",
  '"'  => "<quotedbl>",
  '0' => '0',
  '1' => '1',
  '2' => '2',
  '3' => '3',
  '4' => '4',
  '5' => '5',
  '6' => '6',
  '7' => '7',
  '8' => '8',
  '9' => '9',
  'A' => 'A',
  'B' => 'B',
  'C' => 'C',
  'D' => 'D',
  'E' => 'E',
  'F' => 'F',
  'G' => 'G',
  'H' => 'H',
  'I' => 'I',
  'J' => 'J',
  'K' => 'K',
  'L' => 'L',
  'M' => 'M',
  'N' => 'N',
  'O' => 'O',
  'P' => 'P',
  'Q' => 'Q',
  'R' => 'R',
  'S' => 'S',
  'T' => 'T',
  'U' => 'U',
  'V' => 'V',
  'W' => 'W',
  'X' => 'X',
  'Y' => 'Y',
  'Z' => 'Z',
  'a' => 'a',
  'b' => 'b',
  'c' => 'c',
  'd' => 'd',
  'e' => 'e',
  'f' => 'f',
  'g' => 'g',
  'h' => 'h',
  'i' => 'i',
  'j' => 'j',
  'k' => 'k',
  'l' => 'l',
  'm' => 'm',
  'n' => 'n',
  'o' => 'o',
  'p' => 'p',
  'q' => 'q',
  'r' => 'r',
  's' => 's',
  't' => 't',
  'u' => 'u',
  'v' => 'v',
  'w' => 'w',
  'x' => 'x',
  'y' => 'y',
  'z' => 'z',
}
SYMKEYS =

Inversion of KEYSYMS for fast lookup in WidgetMajorMode

KEYSYMS.invert
VERSION =
"2010.02"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.bookmarksObject (readonly)

Returns the value of attribute bookmarks.



55
56
57
# File 'lib/ver.rb', line 55

def bookmarks
  @bookmarks
end

.buffersObject (readonly)

Returns the value of attribute buffers.



55
56
57
# File 'lib/ver.rb', line 55

def buffers
  @buffers
end

.ctag_stackObject (readonly)

Returns the value of attribute ctag_stack.



55
56
57
# File 'lib/ver.rb', line 55

def ctag_stack
  @ctag_stack
end

.keymapObject (readonly)

Returns the value of attribute keymap.



55
56
57
# File 'lib/ver.rb', line 55

def keymap
  @keymap
end

.layoutObject (readonly)

Returns the value of attribute layout.



55
56
57
# File 'lib/ver.rb', line 55

def layout
  @layout
end

.layout_classObject

Returns the value of attribute layout_class.



58
59
60
# File 'lib/ver.rb', line 58

def layout_class
  @layout_class
end

.minibufObject (readonly)

Returns the value of attribute minibuf.



55
56
57
# File 'lib/ver.rb', line 55

def minibuf
  @minibuf
end

.optionsObject (readonly)

Returns the value of attribute options.



55
56
57
# File 'lib/ver.rb', line 55

def options
  @options
end

.pathsObject (readonly)

Returns the value of attribute paths.



55
56
57
# File 'lib/ver.rb', line 55

def paths
  @paths
end

.rootObject (readonly)

Returns the value of attribute root.



55
56
57
# File 'lib/ver.rb', line 55

def root
  @root
end

.statusObject (readonly)

Returns the value of attribute status.



55
56
57
# File 'lib/ver.rb', line 55

def status
  @status
end

.style_name_poolsObject (readonly)

Returns the value of attribute style_name_pools.



55
56
57
# File 'lib/ver.rb', line 55

def style_name_pools
  @style_name_pools
end

.style_name_registerObject (readonly)

Returns the value of attribute style_name_register.



55
56
57
# File 'lib/ver.rb', line 55

def style_name_register
  @style_name_register
end

Class Method Details

.cancel_block(block) ⇒ Object



205
206
207
# File 'lib/ver.rb', line 205

def cancel_block(block)
  @cancel_blocks[block] = true
end

.deferObject



195
196
197
198
199
200
201
202
203
# File 'lib/ver.rb', line 195

def defer
  Tk::After.idle do
    begin
      yield
    rescue Exception => ex
      VER.error(ex)
    end
  end
end

.dump_optionsObject



476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# File 'lib/ver.rb', line 476

def dump_options
  out = []

  options.each_pair do |key, value|
    out << [key,
      case value
      when Tk::Font
        "VER::Font[%p]" % [value.actual_hash]
      when Pathname
        value.to_s
      else
        value
      end
      ]
  end

  out.each do |pair|
    puts("VER.options.%s = %p" % pair)
  end
end

.emergency_bindingsObject



437
438
439
# File 'lib/ver.rb', line 437

def emergency_bindings
  Tk::Bind.bind(:all, options.emergency_exit){ exit }
end

.error(exception) ⇒ Object



497
498
499
500
501
502
503
504
505
506
507
508
# File 'lib/ver.rb', line 497

def error(exception)
  @status.value = exception.message if @status
  exception_view(exception) if @root
  $stderr.puts("#{exception.class}: #{exception}", *exception.backtrace)
rescue Errno::EIO
  # The original terminal has disappeared, the $stderr pipe was closed on the
  # other side.
  [$stderr, $stdout, $stdin].each(&:close)
rescue IOError
  # Our pipes are closed, maybe put some output to a file logger here, or display
  # in a nicer way, maybe let it bubble up to Tk handling.
end

.exception_view(exception) ⇒ Object



510
511
512
513
# File 'lib/ver.rb', line 510

def exception_view(exception)
  @exception_view ||= ExceptionView.new(root)
  @exception_view.show(exception)
end

.exitObject



326
327
328
329
330
331
332
# File 'lib/ver.rb', line 326

def exit
  store_session
  @cancel_blocks.keys.each{|key| @cancel_blocks[key] = true }
  Tk.exit rescue nil
  EM.stop rescue nil
  Kernel.exit
end

.find_in_loadpath(basename) ⇒ Object



347
348
349
350
351
352
353
354
# File 'lib/ver.rb', line 347

def find_in_loadpath(basename)
  loadpath.each do |dirname|
    file = dirname/basename
    return file if file.file?
  end

  nil
end

.find_or_create_buffer(file, line = nil, column = nil, &block) ⇒ Object



433
434
435
# File 'lib/ver.rb', line 433

def find_or_create_buffer(file, line = nil, column = nil, &block)
  Buffer.find_or_create(file, line, column, &block)
end

.first_startupObject



316
317
318
319
320
321
322
323
324
# File 'lib/ver.rb', line 316

def first_startup
  home, core = options.home_conf_dir, options.core_conf_dir
  home.mkpath

  (core/'rc.rb').cp(home/'rc.rb')
  (core/'scratch').cp(home/'scratch')
  (core/'tutorial').cp(home/'tutorial')
  (core/'welcome').cp(home/'welcome')
end

.load(name) ⇒ Object



334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/ver.rb', line 334

def load(name)
  loadpath.each do |path|
    file = File.join(path, name)

    begin
      require(file)
      return
    rescue LoadError, TypeError => ex
      # TypeError happens on JRuby sometimes...
    end
  end
end

.load_all_pluginsObject



238
239
240
241
242
243
244
245
246
# File 'lib/ver.rb', line 238

def load_all_plugins
  loadpath.each do |dirname|
    (dirname/'plugin/*.rb').glob do |rb|
      require rb
    end
  end
rescue => ex
  error(ex)
end

.load_plugin(name) ⇒ Object



228
229
230
231
232
233
234
235
236
# File 'lib/ver.rb', line 228

def load_plugin(name)
  loadpath.each do |dirname|
    (dirname/"plugin/#{name}.rb").glob do |rb|
      return require(rb.to_s)
    end
  end
rescue => ex
  error(ex)
end

.load_pluginsObject



221
222
223
224
225
226
# File 'lib/ver.rb', line 221

def load_plugins
  @load_plugins.each do |plugin|
    load_plugin(plugin)
    Tk::Event.generate(root, '<<PluginLoaded>>', data: plugin.to_s)
  end
end

.loadpathObject



96
97
98
# File 'lib/ver.rb', line 96

def loadpath
  options.loadpath
end

.major_mode(name, &block) ⇒ Object



2
3
4
5
6
# File 'lib/ver/major_mode.rb', line 2

def self.major_mode(name, &block)
  major = MajorMode[name]
  major.instance_eval(&block)
  major
end

.message(*args) ⇒ Object



445
446
447
# File 'lib/ver.rb', line 445

def message(*args)
  minibuf.message(*args)
end

.minor_mode(name, &block) ⇒ Object



2
3
4
5
6
# File 'lib/ver/minor_mode.rb', line 2

def self.minor_mode(name, &block)
  minor = MinorMode[name]
  minor.instance_eval(&block)
  minor
end

.obtain_style_name(widget_name, widget_class) ⇒ Object



453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/ver.rb', line 453

def obtain_style_name(widget_name, widget_class)
  suffix = "#{widget_name}.#{widget_class}"
  pool = style_name_pools[suffix] ||= []
  register = style_name_register

  unless name = pool.shift
    begin
      id = SecureRandom.hex
      name = "#{id}.#{suffix}"
    end while register.include?(name)

    register << name
  end

  return name
end

.open_argvObject



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/ver.rb', line 356

def open_argv
  argv = ARGV.dup
  openend_any = false

  while arg = argv.shift
    if argv.first =~ /\+\d+/
      line = argv.shift.to_i
      find_or_create_buffer(arg, line)
    else
      find_or_create_buffer(arg)
    end

    opened_any = true
  end

  opened_any
end

.open_sessionObject



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/ver.rb', line 381

def open_session
  return unless session_base = options.session
  basename = "#{session_base}.session.rb"
  return unless file = find_in_loadpath(basename)

  begin
    session = eval(File.read(file))
  rescue SyntaxError => ex
    puts "#{ex.class}: #{ex}", *ex.backtrace
    return
  end

  session[:bookmarks].each do |raw_bm|
    bm = Bookmarks::Bookmark.new
    bm.name = raw_bm[:name]
    bm.file = Pathname(raw_bm[:file])
    bm.index = raw_bm[:index]
    bookmarks << bm
  end

  session[:buffers].each do |buffer|
    find_or_create_buffer(buffer[:filename], *buffer[:insert])
  end
end

.open_welcomeObject



374
375
376
377
378
379
# File 'lib/ver.rb', line 374

def open_welcome
  if welcome = find_in_loadpath('welcome')
    find_or_create_buffer(welcome)
    true
  end
end

.opened_file(text) ⇒ Object



441
442
443
# File 'lib/ver.rb', line 441

def opened_file(text)
  @paths << text.filename
end

.plugin(name) ⇒ Object



217
218
219
# File 'lib/ver.rb', line 217

def plugin(name)
  @load_plugins << name.to_s
end

.return_style_name(style_name) ⇒ Object



470
471
472
473
474
# File 'lib/ver.rb', line 470

def return_style_name(style_name)
  id, widget_name, widget_class = style_name.split('.')
  suffix = "#{widget_name}.#{widget_class}"
  style_name_pools[suffix] << style_name
end

.run(given_options = {}, &block) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ver.rb', line 100

def run(given_options = {}, &block)
  setup_tk
  run_startup(given_options)
  pp options if $DEBUG

  run_maybe_forking do
    options.eventmachine ? run_em(&block) : run_noem(&block)
  end
rescue => exception
  VER.error(exception)
  exit
end

.run_coreObject



164
165
166
167
168
169
170
171
172
# File 'lib/ver.rb', line 164

def run_core
  sanitize_options
  setup_widgets
  open_argv || open_welcome
  open_session
  emergency_bindings
  load_plugins
  run_startup_hooks
end

.run_em(&block) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/ver.rb', line 122

def run_em(&block)
  require 'eventmachine'

  EM.run do
    if Tk::RUN_EVENTLOOP_ON_MAIN_THREAD
      run_core
      EM.defer(&block) if block
      Tk.mainloop
    else
      EM.defer do
        run_core
        EM.defer(&block) if block
        Tk.mainloop
      end
    end
  end
end

.run_maybe_forking(&block) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/ver.rb', line 113

def run_maybe_forking(&block)
  return yield unless options.fork

  fork do
    trap(:HUP){ 'terminal disconnected' }
    yield
  end
end

.run_noem(&block) ⇒ Object



140
141
142
143
144
# File 'lib/ver.rb', line 140

def run_noem(&block)
  run_core
  yield if block
  Tk.mainloop
end

.run_startup(given_options) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ver.rb', line 146

def run_startup(given_options)
  first_startup unless options.home_conf_dir.directory?

  @startup_hooks = []
  @paths = Set.new
  @cancel_blocks = {}
  @load_plugins = Set.new
  @exception_view = nil
  @bookmarks = Bookmarks.new
  @ctag_stack = []
  @style_name_register = []
  @style_name_pools = {}
  @buffers = {}

  load 'rc'
  @options.merge!(given_options)
end

.run_startup_hooksObject



209
210
211
# File 'lib/ver.rb', line 209

def run_startup_hooks
  @startup_hooks.each(&:call)
end

.sanitize_optionsObject



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/ver.rb', line 281

def sanitize_options
  font = options.font

  unless font.respond_to?(:measure)
    font = Tk::Font.new(font)
    actual_hash = font.actual_hash
    options.font = Font.cache[actual_hash] = font
  end

  tabs = font.measure('0') * options.tabstop
  options.tabs = tabs

  encoding = options[:encoding]
  unless encoding.is_a?(Encoding)
    external, internal = encoding.to_s.split(':', 2)

    Encoding.default_external = Encoding.find(external) if external
    Encoding.default_internal = Encoding.find(internal) if internal
  end

  # We supply a reasonable default in case the platform doesn't have the theme
  # wished for.
  unless Tk::Tile::Style.theme_names.include?(options.tk_theme)
    options.tk_theme = 'default'
  end

  letter = /[\w\n.-]/
  space = /[^\w.-]/

  # make sure Tcl already has the vars set
  Tk.interp.eval('catch {tcl_endOfWord}')
  Tk.execute('set', 'tcl_wordchars', letter)
  Tk.execute('set', 'tcl_nonwordchars', space)
end

.setup_layoutObject



277
278
279
# File 'lib/ver.rb', line 277

def setup_layout
  @layout = (layout_class || PanedLayout).new(root)
end

.setup_tkObject



248
249
250
251
# File 'lib/ver.rb', line 248

def setup_tk
  require 'ffi-tk'
  Thread.abort_on_exception = true
end

.setup_widgetsObject



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/ver.rb', line 253

def setup_widgets
  Tk::Tile.set_theme options.tk_theme

  @root = Tk.root
  @root.wm_geometry = '160x80'

  Tk::Tile::Style.configure('Label', font: options.font, sticky: :sw)
  # Tk::Tile::Style.configure('TLabelframe', background: '#f00')

  setup_layout

  load("keymap/#{options.keymap}.rb")

  @minibuf = MiniBuffer.new(@layout)
  @layout.configure(
    labelwidget: minibuf,
    labelanchor: :sw
  )

  [:Messages, :Scratch].each do |name|
    defer{ Buffer[name].hide }
  end
end

.startup_hook(&block) ⇒ Object



213
214
215
# File 'lib/ver.rb', line 213

def startup_hook(&block)
  @startup_hooks << block
end

.store_sessionObject



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/ver.rb', line 406

def store_session
  return unless session_base = VER.options.session
  basename = "#{session_base}.session.rb"
  session_path = loadpath.first/basename

  session = {buffers: [], bookmarks: []}
  buffers.each do |name, buffer|
    session[:buffers] << {
      name: name.to_s,
      filename: buffer.filename.to_s,
      insert: buffer.text.index(:insert).split,
    }
  end

  bookmarks.each do |bm|
    session[:bookmarks] << {
      name:  bm.name,
      file:  bm.file.to_s,
      index: bm.index,
    }
  end

  session_path.open('w+:UTF-8') do |io|
    io.write(session.pretty_inspect)
  end
end

.warn(*args) ⇒ Object



449
450
451
# File 'lib/ver.rb', line 449

def warn(*args)
  minibuf.warn(*args)
end

.when_inactive_for(ms) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/ver.rb', line 174

def when_inactive_for(ms)
  block = lambda{
    if @cancel_blocks[block]
      @cancel_blocks.delete(block)
    else

      if Tk.root.tk_inactive > ms
        yield
        Tk.root.tk_inactive('reset')
        Tk::After.ms(ms, &block)
      else
        Tk::After.ms(ms, &block)
      end
    end
  }

  @cancel_blocks[block] = false
  Tk::After.idle(&block)
  block
end