-
Notifications
You must be signed in to change notification settings - Fork 2
/
ReactIDE.py
131 lines (99 loc) · 3.47 KB
/
ReactIDE.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import os
import re
import shutil
import sublime
from collections import defaultdict
from sublime import Region
from sublime_plugin import TextCommand, WindowCommand
from threading import Timer
from distutils.dir_util import mkpath
class Config:
def __init__(self, settings):
self.src = settings.get('src')
self.extensions = ["js", "jsx"]
settings = sublime.load_settings('ReactIDE.sublime-settings')
config = Config(settings)
def remove_src_root(filename):
if filename.find(config.src) == 0:
return filename[len(config.src):]
return filename
def attempt_lazyspec(asset):
cmd_exists = lambda x: shutil.which('lazyspec') is not None
if cmd_exists:
abs_path = os.path.join(config.src, asset['path'])
os.system('lazyspec %s' % abs_path)
def asset_info(abs_path):
rel_path = remove_src_root(abs_path)
(asset_dir, asset_filename) = os.path.split(rel_path)
(basename, ext) = os.path.splitext(asset_filename)
name = re.sub('-test$', '', basename)
require_path = os.path.join(asset_dir, basename)
return {
'path': rel_path,
'dir': asset_dir,
'filename': asset_filename,
'name': name,
'ext': ext,
'require_path': require_path,
}
class SwitchComponentStylesheet(TextCommand):
"""
Cycle between:
- React component (components/Foo.jsx)
- Stylesheet for component (components/styles/Foo.scss)
Makes any file that doesn't yet exist.
"""
def run(self, edit):
asset = asset_info(self.view.file_name())
next_filepath = ""
if asset['ext'] == '.jsx':
# go to stylesheet
styles_dir = os.path.join(config.src, asset['dir'], 'styles')
mkpath(styles_dir) # ensure it exists
next_filepath = os.path.join(styles_dir, asset['name'] + '.scss')
elif asset['ext'] == '.scss':
# go to component
component_dir = os.path.join(config.src, asset['dir'], '..')
mkpath(component_dir) # ensure it exists
next_filepath = os.path.join(component_dir, asset['name'] + '.jsx')
else:
sublime.error_message("Unprocessable file type %s" % asset['ext'])
self.view.window().run_command('open_file', {
'file': next_filepath
})
class SwitchComponentTest(TextCommand):
"""
Cycle between:
- React component (components/Foo.jsx)
- Test of component (components/__tests__/Foo-test.js)
Makes any file that doesn't yet exist.
"""
def run(self, edit):
next_filepath = ""
asset = asset_info(self.view.file_name())
if asset['ext'] == '.jsx':
# go to test
component_dir = os.path.dirname(asset['path'])
tests_dir = os.path.join(config.src, component_dir, '__tests__')
mkpath(tests_dir) # ensure it exists
next_filepath = os.path.join(tests_dir, asset['name'] + '-test.js')
if not os.path.exists(next_filepath):
attempt_lazyspec(asset)
elif asset['ext'] == '.js':
# go to component
component_dir = os.path.join(config.src, asset['dir'], '..')
mkpath(component_dir) # ensure it exists
next_filepath = os.path.join(component_dir, asset['name'] + '.jsx')
else:
sublime.error_message("Unprocessable file type %s" % asset['ext'])
self.view.window().run_command('open_file', {
'file': next_filepath
})
class MakeImport(TextCommand):
"""
Make an import statement for the current file, and copy to the clipboard
"""
def run(self, edit):
asset = asset_info(self.view.file_name())
line = "import %s from '%s';\n" % (asset['name'], asset['require_path'])
sublime.set_clipboard(line)