vimmate 0.8.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/.autotest +10 -0
- data/CHANGELOG +108 -0
- data/COPYING +20 -0
- data/README +221 -0
- data/Rakefile +31 -0
- data/TODO +21 -0
- data/bin/vimmate +105 -0
- data/config/environment.rb +35 -0
- data/controllers/file_filter_controller.rb +101 -0
- data/controllers/file_popup_menu_controller.rb +40 -0
- data/controllers/vim_controller.rb +28 -0
- data/controllers/vim_mate_controller.rb +76 -0
- data/images/file.png +0 -0
- data/images/file_green.png +0 -0
- data/images/file_orange.png +0 -0
- data/images/file_red.png +0 -0
- data/images/folder.png +0 -0
- data/images/folder_green.png +0 -0
- data/images/folder_orange.png +0 -0
- data/images/folder_red.png +0 -0
- data/images/processing.png +0 -0
- data/images/svn_added.png +0 -0
- data/images/svn_conflict.png +0 -0
- data/images/svn_deleted.png +0 -0
- data/images/svn_locked.png +0 -0
- data/images/svn_modified.png +0 -0
- data/images/svn_normal.png +0 -0
- data/images/svn_readonly.png +0 -0
- data/images/vimmate16.png +0 -0
- data/images/vimmate32.png +0 -0
- data/images/vimmate48.png +0 -0
- data/lib/active_window/active_column.rb +218 -0
- data/lib/active_window/active_tree_store/columns.rb +88 -0
- data/lib/active_window/active_tree_store/extentions.rb +81 -0
- data/lib/active_window/active_tree_store/index.rb +53 -0
- data/lib/active_window/active_tree_store.rb +26 -0
- data/lib/active_window/application.rb +137 -0
- data/lib/active_window/controller.rb +58 -0
- data/lib/active_window/dot_file.rb +29 -0
- data/lib/active_window/filtered_active_tree_store.rb +113 -0
- data/lib/active_window/listed_item.rb +127 -0
- data/lib/active_window/signal.rb +46 -0
- data/lib/active_window.rb +8 -0
- data/lib/config_window.rb +90 -0
- data/lib/file_tree_store.rb +74 -0
- data/lib/filtered_file_tree_store.rb +34 -0
- data/lib/gtk_thread_helper.rb +73 -0
- data/lib/listed_directory.rb +45 -0
- data/lib/listed_file.rb +67 -0
- data/lib/try.rb +9 -0
- data/lib/vim/buffers.rb +18 -0
- data/lib/vim/integration.rb +38 -0
- data/lib/vim/netbeans.rb +154 -0
- data/lib/vim/source.vim +18 -0
- data/lib/vim_mate/config.rb +132 -0
- data/lib/vim_mate/dummy_window.rb +14 -0
- data/lib/vim_mate/files_menu.rb +110 -0
- data/lib/vim_mate/icons.rb +156 -0
- data/lib/vim_mate/nice_singleton.rb +53 -0
- data/lib/vim_mate/plugins/inotify/init.rb +4 -0
- data/lib/vim_mate/plugins/inotify/lib/INotify.rb +208 -0
- data/lib/vim_mate/plugins/inotify/lib/directory.rb +58 -0
- data/lib/vim_mate/plugins/subversion/init.rb +7 -0
- data/lib/vim_mate/plugins/subversion/lib/file.rb +59 -0
- data/lib/vim_mate/plugins/subversion/lib/menu.rb +96 -0
- data/lib/vim_mate/plugins/subversion/lib/subversion.rb +157 -0
- data/lib/vim_mate/plugins.rb +6 -0
- data/lib/vim_mate/requirer.rb +68 -0
- data/lib/vim_mate/search_window.rb +227 -0
- data/lib/vim_mate/tags_window.rb +167 -0
- data/lib/vim_mate/terminals_window.rb +163 -0
- data/lib/vim_mate/version.rb +29 -0
- data/lib/vim_mate/vim_widget.rb +143 -0
- data/spec/active_window/active_column_spec.rb +41 -0
- data/spec/active_window/active_tree_store_spec.rb +312 -0
- data/spec/active_window/controller_spec.rb +6 -0
- data/spec/lib/file_tree_store_spec.rb +40 -0
- data/spec/lib/listed_directory_spec.rb +26 -0
- data/spec/lib/listed_file_spec.rb +53 -0
- data/spec/nice_singleton_spec.rb +23 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +10 -0
- data/views/vim_mate.glade +500 -0
- data/vimmate.gemspec +138 -0
- metadata +146 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
class FilteredFileTreeStore < ActiveWindow::FilteredActiveTreeStore
|
2
|
+
# Fuzzy search by String
|
3
|
+
# 'foo' => matches la/lu/foo, f/lala/o/gaga/o
|
4
|
+
# 'foo/bar' => matches la/afoo/gnarz/barz, but not the above
|
5
|
+
def iter_visible?(iter)
|
6
|
+
case iter[OBJECT]
|
7
|
+
when ListedDirectory; false
|
8
|
+
when ListedFile
|
9
|
+
iter[filter_column] =~ filter_regexp
|
10
|
+
else
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def filter=(new_filter_string)
|
16
|
+
@filter_regexp = nil
|
17
|
+
@filter_column = nil
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def filter_regexp
|
23
|
+
@filter_regexp ||= Regexp.new(
|
24
|
+
filter_string.split('/').map { |t|
|
25
|
+
Regexp.escape(t).split(//).join('.*')
|
26
|
+
}.join('.*/.*')
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def filter_column
|
31
|
+
@filter_column ||= filter_string.index('/') ? FULL_PATH : NAME
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# From http://ruby-gnome2.sourceforge.jp/hiki.cgi?tips_threads
|
2
|
+
#
|
3
|
+
# This is a crucial "tip," and in fact qualifies, I believe, as a major warning
|
4
|
+
# or fix for using Ruby with the Gtk library.
|
5
|
+
#
|
6
|
+
# The warning is this: If you call Gtk methods from outside of Gtk's main thread,
|
7
|
+
# there is a chance that the Ruby interpreter (not merely your Ruby application!)
|
8
|
+
# will crash with a segmentation fault (seg fault) error, seemingly at random.
|
9
|
+
# This is not an exception you can catch. It is fatal and crippling, and very
|
10
|
+
# difficult to debug.
|
11
|
+
#
|
12
|
+
# You might be using Ruby threads even without knowing! For example, if you
|
13
|
+
# receive events or callbacks to your Ruby methods or blocks from another library
|
14
|
+
# or service, these calls may very well be occurring on other threads. If that's
|
15
|
+
# the case, and you call Gtk from within your callbacks, you risk a seg fault.
|
16
|
+
#
|
17
|
+
# Otherwise you might have your own worker thread in the background doing some
|
18
|
+
# work, which occasionally needs to call Gtk to update a widget.
|
19
|
+
#
|
20
|
+
# (Side note: If you are using Ruby threads, be sure to protect your
|
21
|
+
# thread-shared resources with either a Monitor or a Mutex! The difference:
|
22
|
+
# monitors are safer, in that they are re-entrable from the same thread;
|
23
|
+
# mutexes aren't, but perform better.)
|
24
|
+
#
|
25
|
+
# Usage is very simple:
|
26
|
+
|
27
|
+
# Start your Gtk application by calling Gtk.main_with_queue rather than
|
28
|
+
# Gtk.main. The "timeout" argument is in milliseconds, and it is the maximum
|
29
|
+
# time that can pass until queued blocks get called: 100 should be fine.
|
30
|
+
#
|
31
|
+
# Whenever you need to queue a call, use Gtk.queue. For example:
|
32
|
+
# def my_event_callback
|
33
|
+
# Gtk.queue do
|
34
|
+
# @image.pixbuf = Gdk::Pixbuf.new @image_path, width, height
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Issues:
|
39
|
+
# 1. Keep your queued blocks lean. Do all your CPU-intensive work outside of
|
40
|
+
# the queued block. This will help keep Gtk responsive.
|
41
|
+
|
42
|
+
require 'monitor'
|
43
|
+
module Gtk
|
44
|
+
GTK_PENDING_BLOCKS = []
|
45
|
+
GTK_PENDING_BLOCKS_LOCK = ::Monitor.new
|
46
|
+
|
47
|
+
GTK_MAX_PENDING_BLOCKS_PER_ITERATION = 42
|
48
|
+
|
49
|
+
def Gtk.queue &block
|
50
|
+
if Thread.current == Thread.main
|
51
|
+
block.call
|
52
|
+
else
|
53
|
+
GTK_PENDING_BLOCKS_LOCK.synchronize do
|
54
|
+
GTK_PENDING_BLOCKS << block
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def Gtk.main_with_queue timeout = 100
|
60
|
+
Gtk.timeout_add timeout do
|
61
|
+
GTK_PENDING_BLOCKS_LOCK.synchronize do
|
62
|
+
length = GTK_PENDING_BLOCKS.length
|
63
|
+
if length > GTK_MAX_PENDING_BLOCKS_PER_ITERATION
|
64
|
+
GTK_PENDING_BLOCKS.shift(GTK_MAX_PENDING_BLOCKS_PER_ITERATION).each(&:call)
|
65
|
+
elsif length > 0
|
66
|
+
GTK_PENDING_BLOCKS.each(&:call).clear
|
67
|
+
end
|
68
|
+
end
|
69
|
+
true
|
70
|
+
end
|
71
|
+
Gtk.main
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class ListedDirectory < ListedFile
|
2
|
+
def sort
|
3
|
+
"1-#{name}-1"
|
4
|
+
end
|
5
|
+
def icon_name
|
6
|
+
'folder'
|
7
|
+
end
|
8
|
+
def file?
|
9
|
+
false # yeah..!
|
10
|
+
end
|
11
|
+
def directory?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
def exists?
|
15
|
+
full_path && ::File.directory?(full_path)
|
16
|
+
end
|
17
|
+
def refresh
|
18
|
+
super
|
19
|
+
#remove_not_existing_files
|
20
|
+
add_new_files
|
21
|
+
end
|
22
|
+
|
23
|
+
def children_paths
|
24
|
+
children_names.map {|n| File.join(full_path, n)}
|
25
|
+
rescue Errno::ENOENT, Errno::EACCES
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
|
29
|
+
def children_names
|
30
|
+
Dir.entries(full_path).select {|p| p !~ /^\./ }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Find files to add
|
35
|
+
def add_new_files
|
36
|
+
begin
|
37
|
+
children_paths.each do |file_path|
|
38
|
+
tree << file_path
|
39
|
+
end
|
40
|
+
rescue Errno::ENOENT, Errno::EACCES
|
41
|
+
end
|
42
|
+
@traversed = true
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/listed_file.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class ListedFile < ActiveWindow::ListedItem
|
2
|
+
attr_accessor :full_path, :name, :status
|
3
|
+
|
4
|
+
def self.create(opts = {})
|
5
|
+
if fp = opts[:full_path]
|
6
|
+
if File.directory?(fp)
|
7
|
+
ListedDirectory.new opts
|
8
|
+
elsif File.file?(fp)
|
9
|
+
ListedFile.new opts
|
10
|
+
else
|
11
|
+
raise ArgumentError, "does not exist: #{fp}"
|
12
|
+
end
|
13
|
+
else
|
14
|
+
raise ArgumentError, "please give a :full_path, not only #{opts.inspect}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(opts = {})
|
19
|
+
super
|
20
|
+
if fp = opts[:full_path]
|
21
|
+
self.full_path = fp
|
22
|
+
self.status = "normal" if VimMate::Config[:files_show_status]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
def icon_name
|
26
|
+
'file'
|
27
|
+
end
|
28
|
+
def refresh
|
29
|
+
Gtk.queue do
|
30
|
+
self.icon = VimMate::Icons.by_name icon_name
|
31
|
+
self.status = "normal" if VimMate::Config[:files_show_status]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# sets #name AND #fullpath
|
36
|
+
def full_path=(new_full_path)
|
37
|
+
unless new_full_path.empty?
|
38
|
+
@full_path = File.expand_path new_full_path
|
39
|
+
self.name = File.basename new_full_path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
def sort
|
43
|
+
"2-#{name}-1"
|
44
|
+
end
|
45
|
+
def file?
|
46
|
+
true
|
47
|
+
end
|
48
|
+
def directory?
|
49
|
+
false
|
50
|
+
end
|
51
|
+
def exists?
|
52
|
+
full_path && ::File.file?(full_path)
|
53
|
+
end
|
54
|
+
def file_or_directory?
|
55
|
+
file? || directory?
|
56
|
+
end
|
57
|
+
|
58
|
+
def show!
|
59
|
+
i = iter
|
60
|
+
while i = i.parent
|
61
|
+
i[VISIBLE] = true
|
62
|
+
end
|
63
|
+
super
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
data/lib/try.rb
ADDED
data/lib/vim/buffers.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Vim
|
4
|
+
module Integration
|
5
|
+
|
6
|
+
Executable = 'gvim'
|
7
|
+
Password = 'donthasslethehoff'
|
8
|
+
|
9
|
+
include Buffers
|
10
|
+
include Netbeans
|
11
|
+
|
12
|
+
private
|
13
|
+
def listen
|
14
|
+
Thread.new do
|
15
|
+
while true
|
16
|
+
send_function(0, 'getCursor')
|
17
|
+
sleep 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
Thread.new do
|
21
|
+
while true
|
22
|
+
if data = vim.gets
|
23
|
+
interpret_message(data)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def exec_gvim(cmd)
|
30
|
+
command = %Q[#{Executable} --servername #{@vim_server_name} #{cmd}]
|
31
|
+
system(command)
|
32
|
+
end
|
33
|
+
|
34
|
+
def remote_send(command)
|
35
|
+
exec_gvim %Q~--remote-send '#{command.gsub(%q~'~,%q~\\'~)}'~
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/vim/netbeans.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
module Vim
|
2
|
+
module Netbeans
|
3
|
+
|
4
|
+
SERVER_MUTEX = Mutex.new
|
5
|
+
|
6
|
+
class Message
|
7
|
+
attr_reader :message
|
8
|
+
def initialize(message)
|
9
|
+
@message = message
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
@message
|
14
|
+
end
|
15
|
+
end
|
16
|
+
class Event < Message
|
17
|
+
attr_reader :buffer, :name, :value, :rest
|
18
|
+
def initialize(message)
|
19
|
+
super
|
20
|
+
if match = message.match(/^(\d+):(\w+)=(\d)\s*/)
|
21
|
+
@buffer = match[1].to_i
|
22
|
+
@name = match[2]
|
23
|
+
@value = match[3]
|
24
|
+
@rest = match.post_match.split(/\s/)
|
25
|
+
@rest = @rest.map do |arg|
|
26
|
+
case arg
|
27
|
+
when /^"(.*)"$/
|
28
|
+
$1
|
29
|
+
when 'T'
|
30
|
+
true
|
31
|
+
when 'F'
|
32
|
+
false
|
33
|
+
when /^\d+$/
|
34
|
+
arg.to_i
|
35
|
+
else
|
36
|
+
arg
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def to_s
|
42
|
+
%Q~#{@buffer}:#{@name}=#{@value} #{@rest.inspect}~
|
43
|
+
end
|
44
|
+
end
|
45
|
+
class Reply < Message
|
46
|
+
attr_reader :seqno, :value
|
47
|
+
def initialize(message)
|
48
|
+
super
|
49
|
+
@seqno, @value = message.split(/\s/)
|
50
|
+
@seqno = @seqno.to_i
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def replies
|
55
|
+
@replies ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def remember_reply(reply)
|
59
|
+
replies[reply.seqno] = reply
|
60
|
+
end
|
61
|
+
|
62
|
+
def interpret_message(mess)
|
63
|
+
if mess.index ':'
|
64
|
+
event = Event.new(mess)
|
65
|
+
case event.name
|
66
|
+
when 'fileOpened'
|
67
|
+
path = event.rest.first
|
68
|
+
if event.buffer == 0
|
69
|
+
send_command(new_buffer(path), 'putBufferNumber', path)
|
70
|
+
send_command(last_buffer, 'startDocumentListen')
|
71
|
+
else
|
72
|
+
@buffers[event.buffer] = path
|
73
|
+
send_command(event.buffer, 'startDocumentListen')
|
74
|
+
end
|
75
|
+
else
|
76
|
+
mess
|
77
|
+
end
|
78
|
+
event
|
79
|
+
else
|
80
|
+
reply = Reply.new(mess)
|
81
|
+
remember_reply reply
|
82
|
+
reply
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
attr_reader :port
|
87
|
+
def server
|
88
|
+
if @server
|
89
|
+
@server
|
90
|
+
else
|
91
|
+
@server = TCPServer.open('localhost', 0)
|
92
|
+
@port = @server.addr[1]
|
93
|
+
@server
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def vim
|
98
|
+
begin
|
99
|
+
@vim_session ||= server.accept_nonblock
|
100
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
|
101
|
+
IO.select([server])
|
102
|
+
retry
|
103
|
+
end
|
104
|
+
return @vim_session
|
105
|
+
end
|
106
|
+
|
107
|
+
attr_reader :seqno
|
108
|
+
def new_seqno
|
109
|
+
if @seqno
|
110
|
+
@seqno += 1
|
111
|
+
else
|
112
|
+
@seqno = 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
def send_command(buf,name,*args)
|
116
|
+
command = %Q~#{buf}:#{name}!#{new_seqno}~
|
117
|
+
unless args.empty?
|
118
|
+
command << ' ' + args.map do |arg|
|
119
|
+
case arg
|
120
|
+
when String
|
121
|
+
%Q~"#{arg.gsub('"','\\"')}"~
|
122
|
+
when Array # lnum/col
|
123
|
+
arg.length == 2 ? arg.join('/') : arg.join('-')
|
124
|
+
when true
|
125
|
+
'T'
|
126
|
+
when false
|
127
|
+
'F'
|
128
|
+
else
|
129
|
+
arg
|
130
|
+
end
|
131
|
+
end.join(' ')
|
132
|
+
end
|
133
|
+
send_message command
|
134
|
+
end
|
135
|
+
|
136
|
+
# TODO timeout
|
137
|
+
def send_function(buf,name)
|
138
|
+
seq = new_seqno
|
139
|
+
send_message %Q~#{buf}:#{name}/#{seq}~
|
140
|
+
while not reply = replies[seq]
|
141
|
+
sleep 0.005
|
142
|
+
end
|
143
|
+
replies.delete(seq)
|
144
|
+
reply
|
145
|
+
end
|
146
|
+
|
147
|
+
def send_message(message)
|
148
|
+
SERVER_MUTEX.synchronize do
|
149
|
+
vim.puts message
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
data/lib/vim/source.vim
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
function! GetOpenBufferPaths()
|
2
|
+
let tablist = []
|
3
|
+
let pathlist = []
|
4
|
+
let cwd = getcwd()
|
5
|
+
for i in range(tabpagenr('$'))
|
6
|
+
call extend(tablist, tabpagebuflist(i + 1))
|
7
|
+
endfor
|
8
|
+
for i in tablist
|
9
|
+
let bufn = bufname(i)
|
10
|
+
if (bufn =~ '^/')==0
|
11
|
+
call add(pathlist, cwd . '/' . bufn)
|
12
|
+
else
|
13
|
+
call add(pathlist, bufn)
|
14
|
+
end
|
15
|
+
endfor
|
16
|
+
call filter(pathlist, "v:val != cwd.'/'" )
|
17
|
+
return pathlist
|
18
|
+
endfunction
|
@@ -0,0 +1,132 @@
|
|
1
|
+
=begin
|
2
|
+
= VimMate: Vim graphical add-on
|
3
|
+
Copyright (c) 2006 Guillaume Benny
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
10
|
+
so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'yaml'
|
25
|
+
|
26
|
+
module VimMate
|
27
|
+
|
28
|
+
# Holds the configurations for VimMate. Also read and write this
|
29
|
+
# configuration so the user can change it.
|
30
|
+
class Config
|
31
|
+
include NiceSingleton
|
32
|
+
|
33
|
+
BASE_FILENAME = '.vimmaterc'
|
34
|
+
DEFAULT_CONFIG = {
|
35
|
+
:window_title => 'VimMate',
|
36
|
+
:window_width => 950,
|
37
|
+
:window_height => 600,
|
38
|
+
:layout_big_terminals => false,
|
39
|
+
:files_opened_width => 250,
|
40
|
+
:files_closed_width => 25,
|
41
|
+
:files_expanded => true,
|
42
|
+
:file_headers_visible => false,
|
43
|
+
:file_hover_selection => false,
|
44
|
+
:file_directory_separator => true,
|
45
|
+
:files_filter_active => true,
|
46
|
+
:files_auto_expand_on_filter => false,
|
47
|
+
:files_refresh_interval => 10,
|
48
|
+
:files_default_open_in_tabs => true,
|
49
|
+
:files_use_ellipsis => true,
|
50
|
+
:files_use_search => true,
|
51
|
+
:files_search_ignore_case => true,
|
52
|
+
:files_search_separator_position => 400,
|
53
|
+
:files_warn_too_many_files => 300,
|
54
|
+
:files_warn_too_many_files_each_step => true,
|
55
|
+
:files_show_status => true,
|
56
|
+
:tags_refresh_interval => 5,
|
57
|
+
:terminals_enabled => true,
|
58
|
+
:terminals_height => 50,
|
59
|
+
:terminals_font => "10",
|
60
|
+
:terminals_foreground_color => "#000000",
|
61
|
+
:terminals_background_color => "#FFFFDD",
|
62
|
+
:terminals_audible_bell => false,
|
63
|
+
:terminals_visible_bell => false,
|
64
|
+
:terminals_autoexec => "",
|
65
|
+
:terminals_login_shell => false,
|
66
|
+
:subversion_enabled => true,
|
67
|
+
}.freeze
|
68
|
+
|
69
|
+
# Create the Config class. Cannot be called directly
|
70
|
+
def initialize
|
71
|
+
# Set the full path to the configuration file. In the user's
|
72
|
+
# HOME or the current directory
|
73
|
+
if ENV['HOME']
|
74
|
+
self.class.const_set(:FILENAME, File.join(ENV['HOME'], BASE_FILENAME))
|
75
|
+
else
|
76
|
+
self.class.const_set(:FILENAME, BASE_FILENAME)
|
77
|
+
end
|
78
|
+
@config = DEFAULT_CONFIG.dup
|
79
|
+
end
|
80
|
+
|
81
|
+
# Access the configuration hash
|
82
|
+
def config
|
83
|
+
read_config
|
84
|
+
#@config.freeze
|
85
|
+
# Once read, we only need a simple reader
|
86
|
+
self.class.send(:attr_reader, :config)
|
87
|
+
config
|
88
|
+
end
|
89
|
+
|
90
|
+
# Easy access to the configuration hash
|
91
|
+
def [](symbol)
|
92
|
+
config[symbol.to_sym]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get the lib path
|
96
|
+
def lib_path
|
97
|
+
File.dirname(File.expand_path(__FILE__))
|
98
|
+
end
|
99
|
+
|
100
|
+
def images_path
|
101
|
+
File.expand_path(File.dirname(__FILE__) + '/../../images')
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# Read the configuration file
|
107
|
+
def read_config
|
108
|
+
# Write the default if it doesn't exist
|
109
|
+
unless File.exist? FILENAME
|
110
|
+
write_config
|
111
|
+
return
|
112
|
+
end
|
113
|
+
# Read the configuration file and merge it with the default
|
114
|
+
# so if the user doesn't specify an option, it's set to the default
|
115
|
+
@config.merge!(YAML.load_file(FILENAME))
|
116
|
+
write_config
|
117
|
+
rescue StandardError => e
|
118
|
+
$stderr.puts e.to_s
|
119
|
+
$stderr.puts "Problem reading config file #{FILENAME}, using default"
|
120
|
+
end
|
121
|
+
|
122
|
+
# Write the configuration file
|
123
|
+
def write_config
|
124
|
+
File.open(FILENAME, 'w') do |file|
|
125
|
+
YAML.dump(@config, file)
|
126
|
+
end
|
127
|
+
rescue StandardError => e
|
128
|
+
$stderr.puts e.to_s
|
129
|
+
$stderr.puts "Problem writing config file #{FILENAME}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|