Class: Redcar::FilterListDialog
- Inherits:
-
Object
- Object
- Redcar::FilterListDialog
- Includes:
- Model, Observable
- Defined in:
- plugins/application/lib/application/dialogs/filter_list_dialog.rb
Overview
A type of dialog containing a textbox and a list, where the list can be updated based on the contents of the textbox. For example, the Find File dialog box in the Project plugin.
Subclasses should implement the 'update_list' method and the 'selected' method.
Direct Known Subclasses
Application::OpenTreeFinderCommand::TreeFuzzyFilter, Declarations::OutlineViewDialog, Declarations::ProjectOutlineViewDialog, Declarations::SelectTagDialog, EditView::ChangeLanguageCommand::ChangeLanguageDialog, EditView::SelectFontDialog, EditView::SelectThemeDialog, Project::FindFileDialog, Project::FindRecentDialog, Snippets::Explorer
Constant Summary
Constant Summary
Constants included from Observable
Instance Attribute Summary
Attributes included from Model
Instance Method Summary (collapse)
- - (Object) close
-
- (Object) filter_and_rank_by(list, query, max_length = 20)
Helper method for fuzzily filtering a list.
-
- (FilterListDialog) initialize
constructor
A new instance of FilterListDialog.
-
- (Object) moved_to(item, ix)
Called by the controller when the user moves through the list.
- - (Object) open
-
- (Object) selected(item, ix)
Called by the controller when the user selects a row in the list.
- - (Boolean) step?
-
- (Object) step_time
The time interval in seconds in which moved_to events are ignored Override to select different interval.
-
- (Array<String> or Array<Hash>) update_list(filter)
Called by the controller when the user changes the filter.
Methods included from Observable
#add_listener, #notify_listeners, #remove_listener
Methods included from ReentryHelpers
Constructor Details
- (FilterListDialog) initialize
A new instance of FilterListDialog
11 12 13 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 11 def initialize self.controller = Redcar.gui.controller_for(self).new(self) end |
Instance Method Details
- (Object) close
19 20 21 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 19 def close notify_listeners(:close) end |
- (Object) filter_and_rank_by(list, query, max_length = 20)
Helper method for fuzzily filtering a list
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 67 def filter_and_rank_by(list, query, max_length=20) re = make_regex(query) ranked_list = [] cutoff = 100000000 results = list.each do |element| begin match_data = (block_given? ? yield(element) : element).match(re) if match_data captures = [] match_data.captures.each_with_index do |_, i| i += 1 # Match group 0 is actually the complete regex, we are interested in the subgroups previous_capture = captures.last if previous_capture and match_data.begin(i) - previous_capture[:end] <= 1 # If the the current match starts where the previous match ended, or they even overlap, merge the matches captures.last[:end] = match_data.end(i) else # Record the match captures << {:begin => match_data.begin(i), :end => match_data.end(i)} end end if captures.first[:begin] < cutoff # The penalty is calculated as such: The values of the beginnings of matches are penalty, the lengths are bonuses # This way, matching early and continiously is rewarded. Matching late in a word or only at intervals is punished. penalty = captures.inject(0) {|p,c| p + c[:begin] - (c[:end] - c[:begin]) } ranked_list << {:penalty => penalty, :first_match => captures.first[:begin], :element => element} ranked_list = ranked_list.sort_by {|a| a[:penalty] } # Performance optimization: Once we reach the maximum length, remove elements (saves later sorting) # Set the new cutoff to the beginning of the previously last element, to avoid later elements getting # into the list which would have an even worse rank. if ranked_list.length > max_length cutoff = ranked_list.last[:first_match] ranked_list.pop end end end rescue Errno::ENOENT # File.directory? can throw no such file or directory even if File.exist? # has returned true. For example this happens on some awful textmate filenames # unicode in them. end end ranked_list.map {|a| a[:element] } end |
- (Object) moved_to(item, ix)
Called by the controller when the user moves through the list.
57 58 59 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 57 def moved_to(item, ix) # Override with the code you wish you had end |
- (Object) open
15 16 17 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 15 def open notify_listeners(:open) end |
- (Object) selected(item, ix)
Called by the controller when the user selects a row in the list.
49 50 51 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 49 def selected(item, ix) puts "Hooray! You selected #{text} at index #{ix}" end |
- (Boolean) step?
118 119 120 121 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 118 def step? @last_step ||= Time.now - step_time @last_step + step_time <= Time.now end |
- (Object) step_time
The time interval in seconds in which moved_to events are ignored Override to select different interval
114 115 116 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 114 def step_time 1 end |
- (Array<String> or Array<Hash>) update_list(filter)
Called by the controller when the user changes the filter.
Should return either a list of strings, or a list of hashes, which must have at least the key :name set, and may also have the key :image.
E.g. it returns [“feed.rb”, “application_controller.rb”] or it returns [=> “feed.rb”, => “application_controller.rb”]
The methods selected and moved_to will be called with items from this list.
35 36 37 38 39 40 41 42 43 |
# File 'plugins/application/lib/application/dialogs/filter_list_dialog.rb', line 35 def update_list(filter) if filter == "" %w(foo bar baz qux quux corge) else a = [] 5.times {|i| a << filter + " " + i.to_s } a end end |