niklas-vimmate 0.8.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/.autotest +10 -0
- data/CHANGELOG +108 -0
- data/COPYING +20 -0
- data/README +221 -0
- data/Rakefile +97 -0
- data/TODO +21 -0
- data/bin/vimmate +95 -0
- data/config/environment.rb +33 -0
- data/controllers/file_filter_controller.rb +85 -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.rb +8 -0
- data/lib/active_window/active_column.rb +218 -0
- data/lib/active_window/active_tree_store.rb +13 -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/application.rb +133 -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 +114 -0
- data/lib/active_window/listed_item.rb +127 -0
- data/lib/active_window/signal.rb +46 -0
- data/lib/config_window.rb +90 -0
- data/lib/file_tree_store.rb +73 -0
- data/lib/filtered_file_tree_store.rb +34 -0
- data/lib/gtk_thread_helper.rb +73 -0
- data/lib/listed_directory.rb +43 -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 +36 -0
- data/lib/vim/netbeans.rb +156 -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.rb +6 -0
- data/lib/vim_mate/plugins/inotify/init.rb +4 -0
- data/lib/vim_mate/plugins/inotify/lib/INotify.rb +206 -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/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 +150 -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 +308 -0
- data/vimmate.gemspec +131 -0
- metadata +168 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
module ActiveWindow
|
2
|
+
# This creates a TreeModel which supports filtering. Please give a block that "returns" boolean
|
3
|
+
#
|
4
|
+
# filtered_model = ActiveTreeStoreFilter.new model do |filter_string, model, path, iter|
|
5
|
+
# !iter[23].index(filter_string).nil?
|
6
|
+
# end
|
7
|
+
class FilteredActiveTreeStore < Gtk::TreeModelFilter
|
8
|
+
include TreeStoreExtentions
|
9
|
+
|
10
|
+
attr_reader :filter_string, :found_count
|
11
|
+
attr_reader :unfiltered_store
|
12
|
+
define_callbacks :before_filter_applied, :after_filter_applied
|
13
|
+
define_callbacks :before_clear_filter, :after_clear_filter
|
14
|
+
|
15
|
+
def self.inherited(child_class)
|
16
|
+
unfiltered_class_name = child_class.name.sub(/^Filtered/,'')
|
17
|
+
unfiltered_class = unfiltered_class_name.constantize
|
18
|
+
child_class.columns = unfiltered_class.columns
|
19
|
+
child_class.column_id = unfiltered_class.column_id
|
20
|
+
child_class.setup_column_id_constants
|
21
|
+
unfiltered_class.class_eval <<-EOCODE
|
22
|
+
def add_with_filter_visibility(file, *args)
|
23
|
+
iter = add_without_filter_visibility(file, *args)
|
24
|
+
filtered_model.set_visibility_for(iter)
|
25
|
+
filtered_model.refilter
|
26
|
+
iter
|
27
|
+
end
|
28
|
+
alias_method_chain :add, :filter_visibility
|
29
|
+
attr_accessor :filtered_model
|
30
|
+
EOCODE
|
31
|
+
rescue NameError => e
|
32
|
+
if e.message =~ /uninitialized constant #{unfiltered_class}/
|
33
|
+
raise "there is no class named #{unfiltered_class} to filter from"
|
34
|
+
else
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(child_model)
|
40
|
+
super(child_model)
|
41
|
+
setup_filter
|
42
|
+
end
|
43
|
+
|
44
|
+
def filter_string=(new_filter_string)
|
45
|
+
@filter_regexp = nil
|
46
|
+
if new_filter_string.empty?
|
47
|
+
clear_filter
|
48
|
+
else
|
49
|
+
@filter_string = new_filter_string
|
50
|
+
apply_filter
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def clear_filter
|
55
|
+
run_callbacks :before_clear_filter
|
56
|
+
@filter_string = ''
|
57
|
+
@found_count = -1
|
58
|
+
refilter
|
59
|
+
run_callbacks :after_clear_filter
|
60
|
+
end
|
61
|
+
|
62
|
+
# implement this to oyur own needs
|
63
|
+
def iter_visible?(iter)
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
# Iterate over child model and set visible column according to #iter_visible?
|
68
|
+
def apply_filter
|
69
|
+
run_callbacks :before_filter_applied
|
70
|
+
@found_count = 0
|
71
|
+
child_model.each do |model,path,iter|
|
72
|
+
set_visibility_for(iter)
|
73
|
+
end
|
74
|
+
refilter
|
75
|
+
run_callbacks :after_filter_applied
|
76
|
+
end
|
77
|
+
|
78
|
+
def filtered?
|
79
|
+
!filter_string.blank?
|
80
|
+
end
|
81
|
+
alias_method :filter, :filter_string
|
82
|
+
alias_method :filter=, :filter_string=
|
83
|
+
alias_method :filtering?, :filtered?
|
84
|
+
|
85
|
+
def set_visibility_for(iter)
|
86
|
+
visid = self.class.column_id[:visible]
|
87
|
+
unless filtering?
|
88
|
+
iter[ visid ] = true
|
89
|
+
else
|
90
|
+
if iter_visible?(iter) # iter matches - mark it and all parents as visible
|
91
|
+
@found_count += 1
|
92
|
+
iter[ visid ] = true
|
93
|
+
i = iter
|
94
|
+
while i = i.parent
|
95
|
+
i[ visid ] = true
|
96
|
+
end
|
97
|
+
else
|
98
|
+
iter[ visid ] = false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def setup_filter
|
106
|
+
set_visible_func do |model, iter|
|
107
|
+
!filtered? || iter[ self.class.column_id[:visible] ]
|
108
|
+
end
|
109
|
+
child_model.filtered_model = self
|
110
|
+
clear_filter
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module ActiveWindow
|
2
|
+
# The ListItem is created on the fly
|
3
|
+
# * to oo-abstract methods to its TreeIter
|
4
|
+
# * for iteration in TreeController
|
5
|
+
# * as object in ActiveTreeStore
|
6
|
+
class ListedItem
|
7
|
+
|
8
|
+
def initialize(opts = {})
|
9
|
+
@traversed = false
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def sort
|
14
|
+
"item-#{iter}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def icon_name
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def icon
|
22
|
+
VimMate::Icons.by_name icon_name
|
23
|
+
end
|
24
|
+
|
25
|
+
# New by Gtk::TreeRowReference
|
26
|
+
def self.new_by_reference(reference)
|
27
|
+
new(:iter => reference.iter)
|
28
|
+
end
|
29
|
+
|
30
|
+
# New by Gtk::TreeIter
|
31
|
+
def self.new_by_iter(iter)
|
32
|
+
new(:iter => iter)
|
33
|
+
end
|
34
|
+
|
35
|
+
def message?
|
36
|
+
referenced_type == 'VimMate::Message'
|
37
|
+
end
|
38
|
+
|
39
|
+
def separator?
|
40
|
+
referenced_type == 'VimMate::Separator'
|
41
|
+
end
|
42
|
+
|
43
|
+
def file?
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def directory?
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
def file_or_directory?
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
def show!
|
56
|
+
self.visible = true
|
57
|
+
# TODO hide seperator
|
58
|
+
#if directory? and Config[:file_directory_separator]
|
59
|
+
# if iter.next!
|
60
|
+
# tree.row_for_iter(iter).show!
|
61
|
+
# end
|
62
|
+
#end
|
63
|
+
end
|
64
|
+
def hide!
|
65
|
+
self.visible = false
|
66
|
+
# TODO hide seperator
|
67
|
+
#if directory? and Config[:file_directory_separator]
|
68
|
+
# if iter.next!
|
69
|
+
# tree.row_for_iter(iter).hide!
|
70
|
+
# end
|
71
|
+
#end
|
72
|
+
end
|
73
|
+
|
74
|
+
def visible?
|
75
|
+
visible
|
76
|
+
end
|
77
|
+
|
78
|
+
def matches?(str)
|
79
|
+
name.index(str)
|
80
|
+
end
|
81
|
+
|
82
|
+
def refresh
|
83
|
+
end
|
84
|
+
|
85
|
+
def reference
|
86
|
+
@reference ||= Gtk::TreeRowReference.new(tree.store, iter.path)
|
87
|
+
end
|
88
|
+
|
89
|
+
def reference=(new_ref)
|
90
|
+
if new_ref
|
91
|
+
@reference = new_ref
|
92
|
+
@iter = tree.store.get_iter(new_ref.path)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.build(attrs)
|
97
|
+
if full_path = attrs[:full_path]
|
98
|
+
if ::File.directory? full_path
|
99
|
+
'ListedDirectory'
|
100
|
+
elsif ::File.file? full_path
|
101
|
+
'ListedFile'
|
102
|
+
else
|
103
|
+
self
|
104
|
+
end
|
105
|
+
elsif iter = attrs[:iter] and !iter[REFERENCED_TYPE].nil?
|
106
|
+
iter[REFERENCED_TYPE]
|
107
|
+
else
|
108
|
+
self
|
109
|
+
end.constantize.new attrs
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_s
|
113
|
+
"#{self.class} [#{iter.path}]"
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.modify_icon(scope, &block)
|
117
|
+
with = "icon_name_with_#{scope}"
|
118
|
+
without = "icon_name_without_#{scope}"
|
119
|
+
define_method with do
|
120
|
+
block.call(self)
|
121
|
+
end
|
122
|
+
alias_method without, :icon_name
|
123
|
+
alias_method :icon_name, with
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ActiveWindow
|
2
|
+
class Signal
|
3
|
+
class UnknownSignalError < StandardError ; end
|
4
|
+
@@signals = {}
|
5
|
+
|
6
|
+
def self.on(name, &block)
|
7
|
+
@@signals[name] ||= []
|
8
|
+
@@signals[name] << block
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.emit(name, *args)
|
12
|
+
if @@signals[name].is_a?(Array)
|
13
|
+
@@signals[name].each do |block|
|
14
|
+
block.call(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.signals
|
20
|
+
@@signals
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.define name
|
24
|
+
class_eval <<-EOCODE
|
25
|
+
def self.emit_#{name}(*args)
|
26
|
+
self.emit(:#{name},*args)
|
27
|
+
end
|
28
|
+
def self.on_#{name}(&block)
|
29
|
+
self.on(:#{name}, &block)
|
30
|
+
end
|
31
|
+
EOCODE
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.method_missing(meth,*args,&block)
|
35
|
+
case meth.to_s
|
36
|
+
when /^emit_(.*)$/
|
37
|
+
raise UnknownSignalError, "cannot emit unknown signal '#{$1}'"
|
38
|
+
when /^on_(.*)$/
|
39
|
+
raise UnknownSignalError, "cannot connect to unknown signal '#{$1}'"
|
40
|
+
else
|
41
|
+
raise NoMethodError, "unknown method: #{meth}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module VimMate
|
2
|
+
class ConfigWindow
|
3
|
+
attr_reader :container
|
4
|
+
def initialize(main_window=nil)
|
5
|
+
@gtk_main_window = Gtk::Dialog.new("Configuration", main_window, Gtk::Dialog::MODAL,
|
6
|
+
[ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT ],
|
7
|
+
[ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT ]
|
8
|
+
)
|
9
|
+
gtk_window.set_default_size(400,300)
|
10
|
+
gtk_window.signal_connect('response') do |win,resp|
|
11
|
+
case resp
|
12
|
+
when Gtk::Dialog::RESPONSE_ACCEPT
|
13
|
+
save_settings
|
14
|
+
win.close
|
15
|
+
when Gtk::Dialog::RESPONSE_REJECT
|
16
|
+
win.close
|
17
|
+
when Gtk::Dialog::RESPONSE_NONE
|
18
|
+
puts "closing"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@container = gtk_window.vbox
|
22
|
+
fill_container
|
23
|
+
gtk_window.show_all
|
24
|
+
end
|
25
|
+
# The "window" for this object
|
26
|
+
def gtk_window
|
27
|
+
@gtk_main_window
|
28
|
+
end
|
29
|
+
|
30
|
+
def fill_container
|
31
|
+
@fields = {}
|
32
|
+
Config::DEFAULT_CONFIG.keys.sort {|a,b| a.to_s <=> b.to_s}.each do |key|
|
33
|
+
val = Config[key]
|
34
|
+
box = Gtk::HBox.new(true,10)
|
35
|
+
label = Gtk::Label.new(key.to_s.humanize)
|
36
|
+
label.xalign = 1
|
37
|
+
box.pack_start label, true, true
|
38
|
+
|
39
|
+
field = field_for val
|
40
|
+
@fields[key] = field
|
41
|
+
box.pack_start field, true, false
|
42
|
+
container.pack_start box
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def save_settings
|
47
|
+
Config::DEFAULT_CONFIG.keys.each do |key|
|
48
|
+
if new_val = val_of(key)
|
49
|
+
Config.config[key] = new_val
|
50
|
+
end
|
51
|
+
end
|
52
|
+
Config.write_config
|
53
|
+
end
|
54
|
+
|
55
|
+
def val_of(key)
|
56
|
+
field = @fields[key]
|
57
|
+
case Config::DEFAULT_CONFIG[key]
|
58
|
+
when String
|
59
|
+
field.text
|
60
|
+
when Fixnum
|
61
|
+
field.value.to_i
|
62
|
+
when Float
|
63
|
+
field.value.to_f
|
64
|
+
when FalseClass, TrueClass
|
65
|
+
field.active?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def field_for(val)
|
70
|
+
case val
|
71
|
+
when String
|
72
|
+
# TODO make "textarea" for more than 42 chars
|
73
|
+
e = Gtk::Entry.new
|
74
|
+
e.editable = true
|
75
|
+
e.text = val
|
76
|
+
e
|
77
|
+
when Fixnum, Float
|
78
|
+
Gtk::SpinButton.new(
|
79
|
+
Gtk::Adjustment.new(val,0,10000,1,10,1),
|
80
|
+
1,0)
|
81
|
+
when FalseClass, TrueClass
|
82
|
+
e = Gtk::ToggleButton.new
|
83
|
+
e.active = val
|
84
|
+
e
|
85
|
+
else
|
86
|
+
Gtk::Label.new(val.to_s)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class FileTreeStore < ActiveWindow::ActiveTreeStore
|
2
|
+
column :full_path, String, :visible => false
|
3
|
+
column :status, String, :visible => false
|
4
|
+
column :sort, String, :visible => false
|
5
|
+
|
6
|
+
composite_column 'Files' do |col|
|
7
|
+
col.add column(:icon, Gdk::Pixbuf), false
|
8
|
+
col.add column(:name, String)
|
9
|
+
end
|
10
|
+
|
11
|
+
index_by :full_path
|
12
|
+
|
13
|
+
attr_reader :excludes
|
14
|
+
def initialize
|
15
|
+
super
|
16
|
+
@excludes ||= []
|
17
|
+
set_sort_column_id self.class.column_id[:sort]
|
18
|
+
ActiveWindow::Signal.on_file_modified { |path| refresh_path(path) }
|
19
|
+
ActiveWindow::Signal.on_file_created { |path| add_path(path) }
|
20
|
+
ActiveWindow::Signal.on_file_deleted { |path| remove_path(path) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_path(path, parent=nil)
|
24
|
+
unless excludes?(File.expand_path(path))
|
25
|
+
file = ListedFile.create(:full_path => path)
|
26
|
+
iter = add file, parent || find_by_full_path( File.dirname(path) )
|
27
|
+
if file.directory?
|
28
|
+
file.children_paths.each do |child|
|
29
|
+
add_path child, iter
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
rescue ArgumentError => e
|
34
|
+
STDERR.puts e.message
|
35
|
+
end
|
36
|
+
|
37
|
+
def refresh_path(path)
|
38
|
+
if iter = find_by_full_path(path)
|
39
|
+
update_iter_from_object(iter, iter[OBJECT])
|
40
|
+
if iter[OBJECT].directory?
|
41
|
+
each do |iter|
|
42
|
+
if iter[FULL_PATH].start_with?(path)
|
43
|
+
refresh_path iter[FULL_PATH]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def remove_path(file_path)
|
51
|
+
if has_full_path?(file_path)
|
52
|
+
to_remove = []
|
53
|
+
each do |model,path,iter|
|
54
|
+
if iter[FULL_PATH].starts_with?(file_path)
|
55
|
+
to_remove << reference_for(iter)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
to_remove.each do |element|
|
59
|
+
remove(get_iter(element.path))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Path ends with a node name contained in the exclude list
|
65
|
+
def excludes?(path)
|
66
|
+
excludes.any? {|f| path[-(f.size+1)..-1] == "/#{f}" }
|
67
|
+
end
|
68
|
+
|
69
|
+
def exclude!(new_exclude)
|
70
|
+
excludes << new_exclude.chomp.strip
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|