Permalink
Browse files

Allow multiple opening multiple files at once

Closes #2
  • Loading branch information...
1 parent cd87803 commit c3b438a4906e3f93f680933a66099e51974d7438 @vojtajina committed Mar 16, 2012
Showing with 57 additions and 42 deletions.
  1. +24 −19 converter.py
  2. +24 −16 converter_test.py
  3. +9 −7 open_related.py
View
@@ -2,25 +2,30 @@
class Converter(object):
- def __init__(self, from_exp, to_exp):
- self.from_re = [self._pattern_to_re(from_exp)]
+ def __init__(self, patterns):
+ self.from_re = []
self.to_exp = []
- if self._is_formatter(to_exp):
- self.from_re.append(self._pattern_to_re(to_exp))
- self.to_exp.append(self._pattern_to_formatter(to_exp))
- self.to_exp.append(self._pattern_to_formatter(from_exp))
- else:
- self.to_exp.append(to_exp)
+ for pattern in patterns:
+ self.from_re.append(self._pattern_to_re(pattern))
+ self.to_exp.append(self._pattern_to_formatter(pattern))
def convert(self, path):
- idx = 0
- while idx < len(self.from_re):
- match = self.from_re[idx].match(path)
- if match: return self.to_exp[idx].format(*match.groups())
- idx += 1
+ results = []
+ lenght = len(self.from_re)
- return None
+ for i in range(lenght):
+ match = self.from_re[i].match(path)
+ if not match: continue
+
+ j = (i + 1) % lenght
+ while (j is not i):
+ results.append(self.to_exp[j].format(*match.groups()))
+ j = (j + 1) % lenght
+
+ break
+
+ return results
def _pattern_to_re(self, pattern):
return re.compile(re.escape(pattern).replace("\\*", "(.*)"))
@@ -38,13 +43,13 @@ def _is_formatter(self, exp):
class WindowsConverter(Converter):
- def __init__(self, from_exp, to_exp):
- super(WindowsConverter, self).__init__(self._normalize(from_exp), self._normalize(to_exp))
+ def __init__(self, patterns):
+ super(WindowsConverter, self).__init__(map(self._normalize, patterns))
def _normalize(self, path):
return path.replace("/", "\\")
-def create(from_exp, to_exp, platform):
- if platform is "windows": return WindowsConverter(from_exp, to_exp)
- else: return Converter(from_exp, to_exp)
+def create(patterns, platform):
+ if platform is "windows": return WindowsConverter(patterns)
+ else: return Converter(patterns)
View
@@ -5,35 +5,43 @@
class ConverterTest(unittest.TestCase):
def test_none_if_not_match(self):
- # should return None if given path does not match from pattern
- c = Converter("^abc", "{1}")
- self.assertEqual(c.convert("aaa"), None)
-
- def test_convert_basic(self):
- # should convert basic expression
- c = Converter("*/test/*Spec.js", "{0}/src/{1}.js")
- self.assertEqual(c.convert("some/path/test/oneSpec.js"), "some/path/src/one.js")
+ # should return empty list if given path does not match from pattern
+ c = Converter(["^abc", "{1}"])
+ self.assertEqual(c.convert("aaa"), [])
def test_pattern_to_formatter(self):
# should convert pattern (i.e. */test/*.js) to formatter
- c = Converter("", "")
+ c = Converter([])
self.assertEqual(c._pattern_to_formatter("*/test.js"), "{0}/test.js")
self.assertEqual(c._pattern_to_formatter("*/test/*.js"), "{0}/test/{1}.js")
- def test_double_pattern(self):
+ def test_basic_pattern(self):
# should allow double patterns
- c = Converter("*/test/unit/*.spec.coffee", "*/lib/*.js")
- self.assertEqual(c.convert("/some/test/unit/aaa/b.spec.coffee"), "/some/lib/aaa/b.js")
- self.assertEqual(c.convert("/other/lib/abc.js"), "/other/test/unit/abc.spec.coffee")
-
+ c = Converter(["*/test/unit/*.spec.coffee", "*/lib/*.js"])
+ self.assertEqual(c.convert("/some/test/unit/aaa/b.spec.coffee"), ["/some/lib/aaa/b.js"])
+ self.assertEqual(c.convert("/other/lib/abc.js"), ["/other/test/unit/abc.spec.coffee"])
+
+ def test_multiple_patterns(self):
+ # should match all patterns
+ c = Converter(["*/some/*.js", "*/css/*.css", "*/more/deep/*.yml"])
+ self.assertEqual(c.convert("/fake/some/one.js"), \
+ ["/fake/css/one.css", "/fake/more/deep/one.yml"])
+ self.assertEqual(c.convert("/fake/more/deep/two.yml"), \
+ ["/fake/some/two.js", "/fake/css/two.css"])
+
+ def test_right_order_with_multiple(self):
+ # should always start on current file, so that you can keep switching between multiple files
+ c = Converter(["*/some/*.js", "*/css/*.css", "*/more/deep/*.yml"])
+ self.assertEqual(c.convert("/project/css/my.css"), \
+ ["/project/more/deep/my.yml", "/project/some/my.js"])
class WindowsConverterTest(unittest.TestCase):
def test_windows_path(self):
# should handle backslash
- c = WindowsConverter("*/functions/*.pm", "*/standard/css/*.css")
+ c = WindowsConverter(["*/functions/*.pm", "*/standard/css/*.css"])
self.assertEquals(c.convert("C:\\Users\\functions\\admin_open.pm"), \
- "C:\\Users\\standard\\css\\admin_open.css")
+ ["C:\\Users\\standard\\css\\admin_open.css"])
if __name__ == '__main__':
View
@@ -7,14 +7,16 @@ def run(self):
win = self.window
view = win.active_view()
current_file = view.file_name()
+ found = False
- for pattern in view.settings().get('open_related_patterns', []):
- file = converter.create(pattern[0], pattern[1], sublime.platform()).convert(current_file)
- if file and os.path.exists(file):
- if win.num_groups() > 1:
- win.focus_group((win.active_group() + 1) % win.num_groups())
- self.window.open_file(file)
- return
+ for patterns in view.settings().get('open_related_patterns', []):
+ for file in converter.create(patterns, sublime.platform()).convert(current_file):
+ if os.path.exists(file):
+ if win.num_groups() > 1:
+ win.focus_group((win.active_group() + 1) % win.num_groups())
+ self.window.open_file(file)
+ found = True
+ if found: return
sublime.status_message("Cannot find related file !")

0 comments on commit c3b438a

Please sign in to comment.