Skip to content

Commit 1bb398e

Browse files
authored
Merge pull request #31 from mg979/master
more options for multi_find_all
2 parents fa198ad + ee4b1d0 commit 1bb398e

6 files changed

Lines changed: 194 additions & 8 deletions

Default (Linux).sublime-keymap

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,25 @@
1010
{"key": "setting.is_widget", "operator": "equal", "operand": false}
1111
]
1212
},
13-
{ "keys": ["ctrl+alt+f"], "command": "multi_find_all" },
13+
14+
// Multi Find All example keybindings, uncomment to activate
15+
16+
// // main keybinding, set the search type you're most comfortable with, default is Case+Word
17+
// { "keys": ["ctrl+alt+f", "ctrl+alt+f"], "command": "multi_find_all", "args": {"case": true, "word": true}},
18+
19+
// { "keys": ["ctrl+alt+f", "ctrl+c"], "command": "multi_find_all", "args": {"case": false}},
20+
// { "keys": ["ctrl+alt+f", "c"], "command": "multi_find_all", "args": {"case": true}},
21+
// { "keys": ["ctrl+alt+f", "ctrl+w"], "command": "multi_find_all", "args": {"case": false, "word": true}},
22+
// { "keys": ["ctrl+alt+f", "w"], "command": "multi_find_all", "args": {"case": true, "word": true}},
23+
// { "keys": ["ctrl+alt+f", "q"], "command": "multi_find_all", "args": {"case": true, "word": true, "ignore_comments": true}},
24+
25+
// // find all with regex search, additive(on top of current selection) or subtractive
26+
// { "keys": ["ctrl+alt+f", "r"], "command": "multi_find_all_regex"},
27+
// { "keys": ["ctrl+alt+f", "ctrl+alt+r"], "command": "multi_find_all_regex", "args": {"subtract": true}},
28+
// { "keys": ["ctrl+alt+f", "ctrl+r"], "command": "multi_find_all_regex", "args": {"case": false}},
29+
// { "keys": ["ctrl+alt+f", "ctrl+alt+shift+r"], "command": "multi_find_all_regex", "args": {"subtract": true, "case": false}},
30+
31+
1432
{ "keys": ["ctrl+alt+d"], "command": "selection_fields", "args": {"mode": "smart"} },
1533
{ "keys": ["escape"], "command": "selection_fields",
1634
"args": {"mode": "pop"},

Default (OSX).sublime-keymap

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,25 @@
1010
{"key": "setting.is_widget", "operator": "equal", "operand": false}
1111
]
1212
},
13-
{ "keys": ["super+alt+j"], "command": "multi_find_all" },
13+
14+
// Multi Find All example keybindings, uncomment to activate
15+
16+
// // main keybinding, set the search type you're most comfortable with, default is Case+Word
17+
// { "keys": ["ctrl+super+g", "ctrl+super+g"], "command": "multi_find_all", "args": {"case": true, "word": true}},
18+
19+
// { "keys": ["ctrl+super+g", "ctrl+c"], "command": "multi_find_all", "args": {"case": false}},
20+
// { "keys": ["ctrl+super+g", "c"], "command": "multi_find_all", "args": {"case": true}},
21+
// { "keys": ["ctrl+super+g", "ctrl+w"], "command": "multi_find_all", "args": {"case": false, "word": true}},
22+
// { "keys": ["ctrl+super+g", "w"], "command": "multi_find_all", "args": {"case": true, "word": true}},
23+
// { "keys": ["ctrl+super+g", "q"], "command": "multi_find_all", "args": {"case": true, "word": true, "ignore_comments": true}},
24+
25+
// // find all with regex search, additive(on top of current selection) or subtractive
26+
// { "keys": ["ctrl+super+g", "r"], "command": "multi_find_all_regex"},
27+
// { "keys": ["ctrl+super+g", "ctrl+alt+r"], "command": "multi_find_all_regex", "args": {"subtract": true}},
28+
// { "keys": ["ctrl+super+g", "ctrl+r"], "command": "multi_find_all_regex", "args": {"case": false}},
29+
// { "keys": ["ctrl+super+g", "ctrl+alt+shift+r"], "command": "multi_find_all_regex", "args": {"subtract": true, "case": false}},
30+
31+
1432
{ "keys": ["super+alt+d"], "command": "selection_fields", "args": {"mode": "smart"} },
1533
{ "keys": ["escape"], "command": "selection_fields",
1634
"args": {"mode": "pop"},

Default (Windows).sublime-keymap

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,25 @@
1010
{"key": "setting.is_widget", "operator": "equal", "operand": false}
1111
]
1212
},
13-
{ "keys": ["ctrl+alt+f"], "command": "multi_find_all" },
13+
14+
// Multi Find All example keybindings, uncomment to activate
15+
16+
// // main keybinding, set the search type you're most comfortable with, default is Case+Word
17+
// { "keys": ["ctrl+alt+f", "ctrl+alt+f"], "command": "multi_find_all", "args": {"case": true, "word": true}},
18+
19+
// { "keys": ["ctrl+alt+f", "ctrl+c"], "command": "multi_find_all", "args": {"case": false}},
20+
// { "keys": ["ctrl+alt+f", "c"], "command": "multi_find_all", "args": {"case": true}},
21+
// { "keys": ["ctrl+alt+f", "ctrl+w"], "command": "multi_find_all", "args": {"case": false, "word": true}},
22+
// { "keys": ["ctrl+alt+f", "w"], "command": "multi_find_all", "args": {"case": true, "word": true}},
23+
// { "keys": ["ctrl+alt+f", "q"], "command": "multi_find_all", "args": {"case": true, "word": true, "ignore_comments": true}},
24+
25+
// // find all with regex search, additive(on top of current selection) or subtractive
26+
// { "keys": ["ctrl+alt+f", "r"], "command": "multi_find_all_regex"},
27+
// { "keys": ["ctrl+alt+f", "ctrl+alt+r"], "command": "multi_find_all_regex", "args": {"subtract": true}},
28+
// { "keys": ["ctrl+alt+f", "ctrl+r"], "command": "multi_find_all_regex", "args": {"case": false}},
29+
// { "keys": ["ctrl+alt+f", "ctrl+alt+shift+r"], "command": "multi_find_all_regex", "args": {"subtract": true, "case": false}},
30+
31+
1432
{ "keys": ["ctrl+alt+d"], "command": "selection_fields", "args": {"mode": "smart"} },
1533
{ "keys": ["escape"], "command": "selection_fields",
1634
"args": {"mode": "pop"},

Default.sublime-commands

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
{ "command": "split_selection", "caption" : "MultiEditUtils: Split selection" },
99
{ "command": "strip_selection", "caption" : "MultiEditUtils: Strip Selection" },
1010
{ "command": "remove_empty_regions", "caption" : "MultiEditUtils: Remove Empty Regions" },
11-
{ "command": "multi_find_all", "caption" : "MultiEditUtils: Multi FindAll" },
11+
{ "command": "multi_find_menu", "caption" : "MultiEditUtils: Multi FindAll" },
1212
{ "command": "preserve_case", "caption" : "MultiEditUtils: Preserve Case" }
1313
]

MultiEditUtils.py

Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,130 @@
44

55
class MultiFindAllCommand(sublime_plugin.TextCommand):
66

7-
def run(self, edit):
7+
def run(self, edit, case=True, word=False, ignore_comments=False, expand=True):
88

99
view = self.view
1010
newRegions = []
1111

12+
# filter selections in order to exclude duplicates since it can hang
13+
# Sublime if search is performed on dozens of selections, this doesn't
14+
# happen with built-in command because it works on a single selection
15+
initial = [sel for sel in view.sel()]
16+
regions, substrings = [], []
17+
for region in view.sel():
18+
if expand and region.empty():
19+
# if expanding substring will be the word
20+
region = view.word(region.a)
21+
# add the region since nothing is selected yet
22+
view.sel().add(region)
23+
# filter by substring (word or not)
24+
substr = view.substr(region)
25+
if substr and substr not in substrings:
26+
regions.append(region)
27+
substrings.append(substr)
28+
view.sel().clear()
29+
if regions:
30+
for region in regions:
31+
view.sel().add(region)
32+
else:
33+
view.window().status_message("Multi Find All: nothing selected")
34+
for sel in initial:
35+
view.sel().add(sel)
36+
return
37+
38+
selected_words = [view.substr(view.word(sel)).lower() for sel in view.sel()]
39+
1240
for region in view.sel():
1341
substr = view.substr(region)
14-
for region in view.find_all(substr, sublime.LITERAL):
15-
newRegions.append(region)
42+
43+
if case:
44+
for region in view.find_all(substr, sublime.LITERAL):
45+
newRegions.append(region)
46+
else:
47+
for region in view.find_all(substr, sublime.LITERAL | sublime.IGNORECASE):
48+
newRegions.append(region)
49+
50+
if word:
51+
deleted = [region for region in newRegions
52+
if view.substr(view.word(region)).lower() not in selected_words]
53+
newRegions = [region for region in newRegions if region not in deleted]
54+
55+
if ignore_comments:
56+
deleted = [region for region in newRegions
57+
if re.search(r'\bcomment\b', view.scope_name(region.a))]
58+
newRegions = [region for region in newRegions if region not in deleted]
1659

1760
for region in newRegions:
1861
view.sel().add(region)
1962

63+
class MultiFindAllRegexCommand(sublime_plugin.TextCommand):
64+
65+
def on_done(self, regex):
66+
67+
case = sublime.IGNORECASE if not self.case else 0
68+
regions = self.view.find_all(regex, case)
69+
70+
# we don't clear the selection so it's additive, it's nice to just add a
71+
# regex search on top of a previous search
72+
if not self.subtract:
73+
for region in regions:
74+
self.view.sel().add(region)
75+
76+
# the resulting regions will be subtracted instead
77+
else:
78+
for region in regions:
79+
self.view.sel().subtract(region)
80+
81+
# remove empty selections in both cases, so there aren't loose cursors
82+
regions = [r for r in self.view.sel() if not r.empty()]
83+
self.view.sel().clear()
84+
for region in regions:
85+
self.view.sel().add(region)
86+
for region in self.view.sel():
87+
print(region)
88+
89+
def run(self, edit, case=True, subtract=False):
90+
91+
self.edit = edit
92+
self.case = case
93+
self.subtract = subtract
94+
c = "Additive regex search:" if not subtract else "Subtractive regex search:"
95+
sublime.active_window().show_input_panel(c, "", self.on_done, None, None)
96+
97+
class MultiFindMenuCommand(sublime_plugin.TextCommand):
98+
99+
def run(self, edit):
100+
101+
choice = [
102+
"Find All Case + Word +",
103+
"Find All Case + Word -",
104+
"Find All Case - Word +",
105+
"Find All Case - Word -",
106+
"Find All Case + Word + (Ignore Comments)",
107+
"Find Regex (Additive)",
108+
"Find Regex (Subtractive)"
109+
]
110+
111+
def on_done(index):
112+
113+
if index == -1:
114+
return
115+
if index == 0:
116+
self.view.run_command('multi_find_all', {"case": True, "word": True})
117+
elif index == 1:
118+
self.view.run_command('multi_find_all', {"case": True})
119+
elif index == 2:
120+
self.view.run_command('multi_find_all', {"case": False, "word": True})
121+
elif index == 3:
122+
self.view.run_command('multi_find_all', {"case": False})
123+
elif index == 4:
124+
self.view.run_command('multi_find_all', {"case": True, "word": True, "ignore_comments": True})
125+
elif index == 5:
126+
self.view.run_command('multi_find_all_regex')
127+
elif index == 6:
128+
self.view.run_command('multi_find_all_regex', {"subtract": True})
129+
130+
self.view.window().show_quick_panel(choice, on_done, 1, 0, None)
20131

21132
class JumpToLastRegionCommand(sublime_plugin.TextCommand):
22133

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,28 @@ When splitting your selection or performing other actions on your selection, it
6767

6868
### Quick Find All for multiple selections
6969

70-
Similar to the built-in "Quick Find All" functionality, MultiEditUtils provides a functionality which selects all occurrences of all active selections. The default keybinding of the ```multi_find_all``` command is **ctrl+alt+f** (on Mac it's **cmd+alt+j**).
70+
Similar to the built-in "Quick Find All" functionality, MultiEditUtils provides a functionality which selects all occurrences of all active selections. By default, it will select the word the cursor is on, if the selection is empty, just like `find_all_under` command. If you don't like this behaviour, add the argument `"expand": false`
71+
72+
These are just suggested keybindings, but you'll have to activate them in your keymap file first. Here shown for Windows/Linux:
73+
74+
```
75+
ctrl+alt+f, ctrl+alt+f case: true word: true
76+
77+
ctrl+alt+f, c case: true
78+
ctrl+alt+f, ctrl+c case: false
79+
ctrl+alt+f, w case: true word: true
80+
ctrl+alt+f, ctrl+w case: false word: true
81+
ctrl+alt+f, q case: true word: true ignore_comments: true
82+
```
83+
84+
Additionally, you can perform a regex search that finds all occurrences of the entered regex. It can be **additive** (applied on top of your current selection) or **subtractive** (removes the results of the search instead). Example keybindings:
85+
86+
```
87+
ctrl+alt+f, r
88+
ctrl+alt+f, ctrl+alt+r subtract: true
89+
ctrl+alt+f, ctrl+r case : false
90+
ctrl+alt+f, ctrl+alt+shift+r subtract: true case: false
91+
```
7192

7293
![](http://philippotto.github.io/Sublime-MultiEditUtils/screens/08%20multi%20find%20all.gif)
7394

0 commit comments

Comments
 (0)