├── Default (Linux).sublime-keymap
├── Default (OSX).sublime-keymap
├── Default (Windows).sublime-keymap
├── Method.sublime-commands
├── commands.py
├── context.py
├── demo
└── demo.py
├── leave_only_current_test.sublime-macro
├── leave_only_current_test_go.sublime-macro
├── license.md
├── method.py
├── readme.md
├── snippets
├── coffee-method-call-null.sublime-snippet
├── coffee-method-call.sublime-snippet
├── coffee-method.sublime-snippet
├── go-method-call-null.sublime-snippet
├── go-method-call.sublime-snippet
├── go-method.sublime-snippet
├── js-method-call-null.sublime-snippet
├── js-method-call.sublime-snippet
├── js-method.sublime-snippet
├── php-method.sublime-snippet
├── python-method-call-null.sublime-snippet
├── python-method-call.sublime-snippet
├── python-method.sublime-snippet
├── ruby-method-call-null.sublime-snippet
├── ruby-method-call.sublime-snippet
└── ruby-method.sublime-snippet
└── uncomment_bookmarks.sublime-macro
/Default (Linux).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 |
3 | {
4 | "keys": ["ctrl+m", "ctrl+,"],
5 | "command": "create_method",
6 | "args": {
7 | "index": "current"
8 | },
9 | "context": [
10 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
11 | ]
12 | },
13 |
14 | {
15 | "keys": ["ctrl+m", "ctrl+."],
16 | "command": "create_method",
17 | "args": {
18 | "index": "current",
19 | "after": true
20 | },
21 | "context": [
22 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
23 | ]
24 | },
25 |
26 | {
27 | "keys": ["ctrl+alt+shift+n"],
28 | "command": "create_method",
29 | "args": {
30 | "index": "current",
31 | "after": true
32 | },
33 | "context": [
34 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
35 | ]
36 | },
37 |
38 | {
39 | "keys": ["ctrl+m", "ctrl+0"],
40 | "command": "create_method",
41 | "args": {
42 | "index": 1
43 | },
44 | "context": [
45 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
46 | ]
47 | },
48 |
49 | {
50 | "keys": ["ctrl+m", "ctrl+o"],
51 | "command": "create_method",
52 | "args": {
53 | "index": "protected"
54 | },
55 | "context": [
56 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
57 | ]
58 | },
59 |
60 | {
61 | "keys": ["ctrl+m", "ctrl+i"],
62 | "command": "create_method",
63 | "args": {
64 | "index": "private"
65 | },
66 | "context": [
67 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
68 | ]
69 | },
70 |
71 | {
72 | "keys": ["ctrl+m", "ctrl+l"],
73 | "command": "create_method",
74 | "args": {
75 | "index": "last",
76 | "after": true
77 | },
78 | "context": [
79 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
80 | ]
81 | },
82 |
83 | {
84 | "keys": ["ctrl+m", "0"],
85 | "command": "move_method",
86 | "args": {
87 | "index": 0,
88 | "after": true,
89 | },
90 | "context": [
91 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
92 | ]
93 | },
94 |
95 | {
96 | "keys": ["ctrl+m", "o"],
97 | "command": "move_method",
98 | "args": {
99 | "index": "protected"
100 | },
101 | "context": [
102 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
103 | ]
104 | },
105 |
106 | {
107 | "keys": ["ctrl+m", "i"],
108 | "command": "move_method",
109 | "args": {
110 | "index": "private"
111 | },
112 | "context": [
113 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
114 | ]
115 | },
116 |
117 | {
118 | "keys": ["ctrl+m", "l"],
119 | "command": "move_method",
120 | "args": {
121 | "index": "last",
122 | "after": true
123 | },
124 | "context": [
125 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
126 | ]
127 | },
128 |
129 | {
130 | "keys": ["alt+-"],
131 | "command": "move_method",
132 | "args": {
133 | "index": "-1"
134 | },
135 | "context": [
136 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
137 | ]
138 | },
139 |
140 | {
141 | "keys": ["alt+="],
142 | "command": "move_method",
143 | "args": {
144 | "index": "+1",
145 | "after": true
146 | },
147 | "context": [
148 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
149 | ]
150 | },
151 |
152 | {
153 | "keys": ["alt+n"],
154 | "command": "goto_method",
155 | "args": {
156 | "method": "+1"
157 | },
158 | "context": [
159 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
160 | ]
161 | },
162 |
163 | {
164 | "keys": ["alt+shift+n"],
165 | "command": "goto_method",
166 | "args": {
167 | "method": "-1"
168 | },
169 | "context": [
170 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
171 | ]
172 | },
173 |
174 | {
175 | "keys": ["alt+ctrl+n"],
176 | "command": "goto_method",
177 | "args": {
178 | "method": "current",
179 | "position": "swap"
180 | },
181 | "context": [
182 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
183 | ]
184 | },
185 |
186 | {
187 | "keys": ["ctrl+m", "ctrl+/"],
188 | "command": "goto_method",
189 | "args": {
190 | "method": "last"
191 | },
192 | "context": [
193 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
194 | ]
195 | },
196 |
197 | {
198 | "keys": ["ctrl+m", "ctrl+f"],
199 | "command": "goto_method",
200 | "args": {
201 | "method": "0"
202 | },
203 | "context": [
204 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
205 | ]
206 | },
207 |
208 | {
209 | "keys": ["ctrl+m", "ctrl+n"],
210 | "command": "create_method_space",
211 | "args": {
212 | "index": "current",
213 | "after": true
214 | },
215 | "context": [
216 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
217 | ]
218 | },
219 |
220 | {
221 | "keys": ["ctrl+m", "ctrl+d"],
222 | "command": "delete_method",
223 | "args": {
224 | "method": "current"
225 | },
226 | "context": [
227 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
228 | ]
229 | },
230 |
231 | {
232 | "keys": ["ctrl+m", "ctrl+c"],
233 | "command": "clone_method",
234 | "args": {
235 | "index": "current",
236 | "after": true
237 | },
238 | "context": [
239 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
240 | ]
241 | },
242 |
243 | {
244 | "keys": ["ctrl+m", "ctrl+m"],
245 | "command": "insert_method_name_to_mark",
246 | "args": {},
247 | "context": [
248 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
249 | ]
250 | },
251 |
252 | {
253 | "keys": ["ctrl+m", "ctrl+s"],
254 | "command": "select_methods",
255 | "args": {
256 | "methods": "current"
257 | },
258 | "context": [
259 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
260 | ]
261 | },
262 |
263 | {
264 | "keys": ["ctrl+m", "s"],
265 | "command": "select_methods",
266 | "args": {
267 | "methods": "current",
268 | "body": true
269 | },
270 | "context": [
271 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
272 | ]
273 | },
274 |
275 | {
276 | "keys": ["ctrl+m", "ctrl+q"],
277 | "command": "run_macro_file",
278 | "args": {
279 | "file": "res://Packages/Method/leave_only_current_test.sublime-macro"
280 | },
281 | "context": [
282 | {"key": "scope", "operator": "not_regex_contains", "operand": "source.go"},
283 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
284 | ]
285 | },
286 |
287 | {
288 | "keys": ["ctrl+m", "ctrl+q"],
289 | "command": "run_macro_file",
290 | "args": {
291 | "file": "res://Packages/Method/leave_only_current_test_go.sublime-macro"
292 | },
293 | "context": [
294 | {"key": "scope", "operator": "regex_contains", "operand": "source\\.go"},
295 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
296 | ]
297 | },
298 |
299 | {
300 | "keys": ["ctrl+m", "q"],
301 | "command": "run_macro_file",
302 | "args": {
303 | "file": "res://Packages/Method/uncomment_bookmarks.sublime-macro"
304 | },
305 | "context": [
306 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
307 | ]
308 | },
309 | ]
--------------------------------------------------------------------------------
/Default (OSX).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 |
3 | {
4 | "keys": ["ctrl+m", "ctrl+,"],
5 | "command": "create_method",
6 | "args": {
7 | "index": "current"
8 | },
9 | "context": [
10 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
11 | ]
12 | },
13 |
14 | {
15 | "keys": ["ctrl+m", "ctrl+."],
16 | "command": "create_method",
17 | "args": {
18 | "index": "current",
19 | "after": true
20 | },
21 | "context": [
22 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
23 | ]
24 | },
25 |
26 | {
27 | "keys": ["ctrl+alt+shift+n"],
28 | "command": "create_method",
29 | "args": {
30 | "index": "current",
31 | "after": true
32 | },
33 | "context": [
34 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
35 | ]
36 | },
37 |
38 | {
39 | "keys": ["ctrl+m", "ctrl+0"],
40 | "command": "create_method",
41 | "args": {
42 | "index": 1
43 | },
44 | "context": [
45 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
46 | ]
47 | },
48 |
49 | {
50 | "keys": ["ctrl+m", "ctrl+o"],
51 | "command": "create_method",
52 | "args": {
53 | "index": "protected"
54 | },
55 | "context": [
56 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
57 | ]
58 | },
59 |
60 | {
61 | "keys": ["ctrl+m", "ctrl+i"],
62 | "command": "create_method",
63 | "args": {
64 | "index": "private"
65 | },
66 | "context": [
67 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
68 | ]
69 | },
70 |
71 | {
72 | "keys": ["ctrl+m", "ctrl+l"],
73 | "command": "create_method",
74 | "args": {
75 | "index": "last",
76 | "after": true
77 | },
78 | "context": [
79 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
80 | ]
81 | },
82 |
83 | {
84 | "keys": ["ctrl+m", "0"],
85 | "command": "move_method",
86 | "args": {
87 | "index": 0,
88 | "after": true,
89 | },
90 | "context": [
91 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
92 | ]
93 | },
94 |
95 | {
96 | "keys": ["ctrl+m", "o"],
97 | "command": "move_method",
98 | "args": {
99 | "index": "protected"
100 | },
101 | "context": [
102 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
103 | ]
104 | },
105 |
106 | {
107 | "keys": ["ctrl+m", "i"],
108 | "command": "move_method",
109 | "args": {
110 | "index": "private"
111 | },
112 | "context": [
113 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
114 | ]
115 | },
116 |
117 | {
118 | "keys": ["ctrl+m", "l"],
119 | "command": "move_method",
120 | "args": {
121 | "index": "last",
122 | "after": true
123 | },
124 | "context": [
125 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
126 | ]
127 | },
128 |
129 | {
130 | "keys": ["alt+-"],
131 | "command": "move_method",
132 | "args": {
133 | "index": "-1"
134 | },
135 | "context": [
136 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
137 | ]
138 | },
139 |
140 | {
141 | "keys": ["alt+="],
142 | "command": "move_method",
143 | "args": {
144 | "index": "+1",
145 | "after": true
146 | },
147 | "context": [
148 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
149 | ]
150 | },
151 |
152 | {
153 | "keys": ["alt+n"],
154 | "command": "goto_method",
155 | "args": {
156 | "method": "+1"
157 | },
158 | "context": [
159 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
160 | ]
161 | },
162 |
163 | {
164 | "keys": ["alt+shift+n"],
165 | "command": "goto_method",
166 | "args": {
167 | "method": "-1"
168 | },
169 | "context": [
170 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
171 | ]
172 | },
173 |
174 | {
175 | "keys": ["alt+ctrl+n"],
176 | "command": "goto_method",
177 | "args": {
178 | "method": "current",
179 | "position": "swap"
180 | },
181 | "context": [
182 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
183 | ]
184 | },
185 |
186 | {
187 | "keys": ["ctrl+m", "ctrl+/"],
188 | "command": "goto_method",
189 | "args": {
190 | "method": "last"
191 | },
192 | "context": [
193 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
194 | ]
195 | },
196 |
197 | {
198 | "keys": ["ctrl+m", "ctrl+f"],
199 | "command": "goto_method",
200 | "args": {
201 | "method": "0"
202 | },
203 | "context": [
204 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
205 | ]
206 | },
207 |
208 | {
209 | "keys": ["ctrl+m", "ctrl+n"],
210 | "command": "create_method_space",
211 | "args": {
212 | "index": "current",
213 | "after": true
214 | },
215 | "context": [
216 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
217 | ]
218 | },
219 |
220 | {
221 | "keys": ["ctrl+m", "ctrl+d"],
222 | "command": "delete_method",
223 | "args": {
224 | "method": "current"
225 | },
226 | "context": [
227 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
228 | ]
229 | },
230 |
231 | {
232 | "keys": ["ctrl+m", "ctrl+c"],
233 | "command": "clone_method",
234 | "args": {
235 | "index": "current",
236 | "after": true
237 | },
238 | "context": [
239 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
240 | ]
241 | },
242 |
243 | {
244 | "keys": ["ctrl+m", "ctrl+m"],
245 | "command": "insert_method_name_to_mark",
246 | "args": {},
247 | "context": [
248 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
249 | ]
250 | },
251 |
252 | {
253 | "keys": ["ctrl+m", "ctrl+s"],
254 | "command": "select_methods",
255 | "args": {
256 | "methods": "current"
257 | },
258 | "context": [
259 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
260 | ]
261 | },
262 |
263 | {
264 | "keys": ["ctrl+m", "s"],
265 | "command": "select_methods",
266 | "args": {
267 | "methods": "current",
268 | "body": true
269 | },
270 | "context": [
271 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
272 | ]
273 | },
274 |
275 | {
276 | "keys": ["ctrl+m", "ctrl+q"],
277 | "command": "run_macro_file",
278 | "args": {
279 | "file": "res://Packages/Method/leave_only_current_test.sublime-macro"
280 | },
281 | "context": [
282 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
283 | ]
284 | },
285 |
286 | {
287 | "keys": ["ctrl+m", "q"],
288 | "command": "run_macro_file",
289 | "args": {
290 | "file": "res://Packages/Method/uncomment_bookmarks.sublime-macro"
291 | },
292 | "context": [
293 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
294 | ]
295 | },
296 | ]
--------------------------------------------------------------------------------
/Default (Windows).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 |
3 | {
4 | "keys": ["ctrl+m", "ctrl+,"],
5 | "command": "create_method",
6 | "args": {
7 | "index": "current"
8 | },
9 | "context": [
10 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
11 | ]
12 | },
13 |
14 | {
15 | "keys": ["ctrl+m", "ctrl+."],
16 | "command": "create_method",
17 | "args": {
18 | "index": "current",
19 | "after": true
20 | },
21 | "context": [
22 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
23 | ]
24 | },
25 |
26 | {
27 | "keys": ["ctrl+alt+shift+n"],
28 | "command": "create_method",
29 | "args": {
30 | "index": "current",
31 | "after": true
32 | },
33 | "context": [
34 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
35 | ]
36 | },
37 |
38 | {
39 | "keys": ["ctrl+m", "ctrl+0"],
40 | "command": "create_method",
41 | "args": {
42 | "index": 1
43 | },
44 | "context": [
45 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
46 | ]
47 | },
48 |
49 | {
50 | "keys": ["ctrl+m", "ctrl+o"],
51 | "command": "create_method",
52 | "args": {
53 | "index": "protected"
54 | },
55 | "context": [
56 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
57 | ]
58 | },
59 |
60 | {
61 | "keys": ["ctrl+m", "ctrl+i"],
62 | "command": "create_method",
63 | "args": {
64 | "index": "private"
65 | },
66 | "context": [
67 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
68 | ]
69 | },
70 |
71 | {
72 | "keys": ["ctrl+m", "ctrl+l"],
73 | "command": "create_method",
74 | "args": {
75 | "index": "last",
76 | "after": true
77 | },
78 | "context": [
79 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
80 | ]
81 | },
82 |
83 | {
84 | "keys": ["ctrl+m", "0"],
85 | "command": "move_method",
86 | "args": {
87 | "index": 0,
88 | "after": true,
89 | },
90 | "context": [
91 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
92 | ]
93 | },
94 |
95 | {
96 | "keys": ["ctrl+m", "o"],
97 | "command": "move_method",
98 | "args": {
99 | "index": "protected"
100 | },
101 | "context": [
102 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
103 | ]
104 | },
105 |
106 | {
107 | "keys": ["ctrl+m", "i"],
108 | "command": "move_method",
109 | "args": {
110 | "index": "private"
111 | },
112 | "context": [
113 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
114 | ]
115 | },
116 |
117 | {
118 | "keys": ["ctrl+m", "l"],
119 | "command": "move_method",
120 | "args": {
121 | "index": "last",
122 | "after": true
123 | },
124 | "context": [
125 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
126 | ]
127 | },
128 |
129 | {
130 | "keys": ["alt+-"],
131 | "command": "move_method",
132 | "args": {
133 | "index": "-1"
134 | },
135 | "context": [
136 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
137 | ]
138 | },
139 |
140 | {
141 | "keys": ["alt+="],
142 | "command": "move_method",
143 | "args": {
144 | "index": "+1",
145 | "after": true
146 | },
147 | "context": [
148 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
149 | ]
150 | },
151 |
152 | {
153 | "keys": ["alt+n"],
154 | "command": "goto_method",
155 | "args": {
156 | "method": "+1"
157 | },
158 | "context": [
159 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
160 | ]
161 | },
162 |
163 | {
164 | "keys": ["alt+shift+n"],
165 | "command": "goto_method",
166 | "args": {
167 | "method": "-1"
168 | },
169 | "context": [
170 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
171 | ]
172 | },
173 |
174 | {
175 | "keys": ["alt+ctrl+n"],
176 | "command": "goto_method",
177 | "args": {
178 | "method": "current",
179 | "position": "swap"
180 | },
181 | "context": [
182 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
183 | ]
184 | },
185 |
186 | {
187 | "keys": ["ctrl+m", "ctrl+/"],
188 | "command": "goto_method",
189 | "args": {
190 | "method": "last"
191 | },
192 | "context": [
193 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
194 | ]
195 | },
196 |
197 | {
198 | "keys": ["ctrl+m", "ctrl+f"],
199 | "command": "goto_method",
200 | "args": {
201 | "method": "0"
202 | },
203 | "context": [
204 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
205 | ]
206 | },
207 |
208 | {
209 | "keys": ["ctrl+m", "ctrl+n"],
210 | "command": "create_method_space",
211 | "args": {
212 | "index": "current",
213 | "after": true
214 | },
215 | "context": [
216 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
217 | ]
218 | },
219 |
220 | {
221 | "keys": ["ctrl+m", "ctrl+d"],
222 | "command": "delete_method",
223 | "args": {
224 | "method": "current"
225 | },
226 | "context": [
227 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
228 | ]
229 | },
230 |
231 | {
232 | "keys": ["ctrl+m", "ctrl+c"],
233 | "command": "clone_method",
234 | "args": {
235 | "index": "current",
236 | "after": true
237 | },
238 | "context": [
239 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
240 | ]
241 | },
242 |
243 | {
244 | "keys": ["ctrl+m", "ctrl+m"],
245 | "command": "insert_method_name_to_mark",
246 | "args": {},
247 | "context": [
248 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
249 | ]
250 | },
251 |
252 | {
253 | "keys": ["ctrl+m", "ctrl+s"],
254 | "command": "select_methods",
255 | "args": {
256 | "methods": "current"
257 | },
258 | "context": [
259 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
260 | ]
261 | },
262 |
263 | {
264 | "keys": ["ctrl+m", "s"],
265 | "command": "select_methods",
266 | "args": {
267 | "methods": "current",
268 | "body": true
269 | },
270 | "context": [
271 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
272 | ]
273 | },
274 |
275 | {
276 | "keys": ["ctrl+m", "ctrl+q"],
277 | "command": "run_macro_file",
278 | "args": {
279 | "file": "res://Packages/Method/leave_only_current_test.sublime-macro"
280 | },
281 | "context": [
282 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
283 | ]
284 | },
285 |
286 | {
287 | "keys": ["ctrl+m", "q"],
288 | "command": "run_macro_file",
289 | "args": {
290 | "file": "res://Packages/Method/uncomment_bookmarks.sublime-macro"
291 | },
292 | "context": [
293 | {"key": "setting.sublime_enhanced_keybindings", "operator": "equal", "operand": true}
294 | ]
295 | },
296 | ]
--------------------------------------------------------------------------------
/Method.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 |
3 | {
4 | "caption": "Method: Create method before current",
5 | "command": "create_method",
6 | "args": {
7 | "index": "current"
8 | }
9 | },
10 |
11 | {
12 | "caption": "Method: Create method after current",
13 | "command": "create_method",
14 | "args": {
15 | "index": "current",
16 | "after": true
17 | }
18 | },
19 |
20 | {
21 | "caption": "Method: Create method after current",
22 | "command": "create_method",
23 | "args": {
24 | "index": "current",
25 | "after": true
26 | }
27 | },
28 |
29 | {
30 | "caption": "Method: Create method after first",
31 | "command": "create_method",
32 | "args": {
33 | "index": 1
34 | }
35 | },
36 |
37 | {
38 | "caption": "Method: Create protected method",
39 | "command": "create_method",
40 | "args": {
41 | "index": "protected"
42 | }
43 | },
44 |
45 | {
46 | "caption": "Method: Create private method",
47 | "command": "create_method",
48 | "args": {
49 | "index": "private"
50 | }
51 | },
52 |
53 | {
54 | "caption": "Method: Create method after last",
55 | "command": "create_method",
56 | "args": {
57 | "index": "last",
58 | "after": true
59 | }
60 | },
61 |
62 | {
63 | "caption": "Method: Move method after first",
64 | "command": "move_method",
65 | "args": {
66 | "index": 0,
67 | "after": true,
68 | }
69 | },
70 |
71 | {
72 | "caption": "Method: Move method to protected",
73 | "command": "move_method",
74 | "args": {
75 | "index": "protected"
76 | }
77 | },
78 |
79 | {
80 | "caption": "Method: Move method to private",
81 | "command": "move_method",
82 | "args": {
83 | "index": "private"
84 | }
85 | },
86 |
87 | {
88 | "caption": "Method: Move method to last",
89 | "command": "move_method",
90 | "args": {
91 | "index": "last",
92 | "after": true
93 | }
94 | },
95 |
96 | {
97 | "caption": "Method: Move method up",
98 | "command": "move_method",
99 | "args": {
100 | "index": "-1"
101 | }
102 | },
103 |
104 | {
105 | "caption": "Method: Move method down",
106 | "command": "move_method",
107 | "args": {
108 | "index": "+1",
109 | "after": true
110 | }
111 | },
112 |
113 | {
114 | "caption": "Method: Go to next method",
115 | "command": "goto_method",
116 | "args": {
117 | "method": "+1"
118 | }
119 | },
120 |
121 | {
122 | "caption": "Method: Go to previous method",
123 | "command": "goto_method",
124 | "args": {
125 | "method": "-1"
126 | }
127 | },
128 |
129 | {
130 | "caption": "Method: Swap method start/end",
131 | "command": "goto_method",
132 | "args": {
133 | "method": "current",
134 | "position": "swap"
135 | }
136 | },
137 |
138 | {
139 | "caption": "Method: Go to last method",
140 | "command": "goto_method",
141 | "args": {
142 | "method": "last"
143 | }
144 | },
145 |
146 | {
147 | "caption": "Method: Go to first method",
148 | "command": "goto_method",
149 | "args": {
150 | "method": "0"
151 | }
152 | },
153 |
154 | {
155 | "caption": "Method: Create method space",
156 | "command": "create_method_space",
157 | "args": {
158 | "index": "current",
159 | "after": true
160 | }
161 | },
162 |
163 | {
164 | "caption": "Method: Delete method",
165 | "command": "delete_method",
166 | "args": {
167 | "method": "current"
168 | }
169 | },
170 |
171 | {
172 | "caption": "Method: Clone method",
173 | "command": "clone_method",
174 | "args": {
175 | "index": "current",
176 | "after": true
177 | }
178 | },
179 |
180 | {
181 | "caption": "Method: Insert method name to mark",
182 | "command": "insert_method_name_to_mark",
183 | "args": {}
184 | },
185 |
186 | {
187 | "caption": "Method: Select current method",
188 | "command": "select_methods",
189 | "args": {
190 | "methods": "current"
191 | }
192 | },
193 |
194 | {
195 | "caption": "Method: Select current method body",
196 | "command": "select_methods",
197 | "args": {
198 | "methods": "current",
199 | "body": true
200 | }
201 | },
202 |
203 | {
204 | "caption": "Method: Comment all except current",
205 | "command": "run_macro_file",
206 | "args":
207 | {
208 | "file": "res://Packages/Method/leave_only_current_test.sublime-macro"
209 | }
210 | },
211 |
212 | {
213 | "caption": "Method: Uncomment all",
214 | "command": "run_macro_file",
215 | "args":
216 | {
217 | "file": "res://Packages/Method/uncomment_bookmarks.sublime-macro"
218 | }
219 | },
220 | ]
--------------------------------------------------------------------------------
/commands.py:
--------------------------------------------------------------------------------
1 | import sublime
2 | import sublime_plugin
3 | import re
4 |
5 | from Method import method as parser
6 |
7 | try:
8 | from Statement import statement
9 | from Expression import expression
10 | from LocalVariable import local_variable
11 | except ImportError as error:
12 | sublime.error_message("Dependency import failed; please read readme for " +
13 | "Method plugin for installation instructions; to disable this " +
14 | "message remove this plugin; message: " + str(error))
15 | raise error
16 |
17 | class MethodBase(sublime_plugin.TextCommand):
18 |
19 | def _get_language(self):
20 | if len(self.view.sel()) == 0:
21 | return None
22 |
23 | sel = self.view.sel()[0]
24 |
25 | match = re.search(r'source\.(\w+)', self.view.scope_name(sel.a))
26 | if match == None:
27 | return None
28 |
29 | return match.group(1)
30 |
31 | def _get_methods(self):
32 | methods = parser.extract_methods(self.view)
33 | return methods
34 |
35 | def _get_method_regions(self, methods, index):
36 | return parser.get_regions(self.view, methods[index])
37 |
38 | def _get_insert_info(self, region, target, after):
39 | text = self.view.substr(region)
40 | shift = [self.view.sel()[0].a - region.a, self.view.sel()[0].b - region.a]
41 |
42 | if after:
43 | text = "\n\n" + text
44 | point = target.b
45 | shift[0] += 2
46 | shift[1] += 2
47 | else:
48 | text += "\n\n"
49 | point = target.a
50 |
51 | return text, shift, point
52 |
53 | def _save_regions(self):
54 | self.view.erase_regions('Method')
55 | regions = []
56 | for sel in self.view.sel():
57 | regions.append(sublime.Region(sel.a, sel.b))
58 | self.view.add_regions('Method', regions, 'method', '')
59 |
60 | def _restore_regions(self):
61 | self.view.sel().clear()
62 | regions = []
63 | for region in self.view.get_regions('Method'):
64 | regions.append(sublime.Region(region.a, region.b))
65 | self.view.sel().add_all(regions)
66 |
67 | def _get_cursor_position(self, method_info, after):
68 | if after:
69 | position = method_info["end"]
70 | else:
71 | position = method_info["start"]
72 |
73 | selection = sublime.Region(position, position)
74 | return selection
75 |
76 | def _set_cursor_position(self, method_info, after):
77 | selection = self._get_cursor_position(method_info, after)
78 | self.view.sel().clear()
79 | self.view.sel().add(selection)
80 |
81 | def _get_name_position(self, method_info):
82 | start = method_info["start"]
83 | text = self.view.substr(sublime.Region(start, start + 255))
84 | name_start = start + text.index(method_info["name"])
85 | name_end = name_start + len(method_info["name"])
86 | return name_start, name_end
87 |
88 | def _insert_method_space(self, after):
89 | self.view.run_command('insert', {'characters': '\n\n'})
90 | if not after:
91 | self.view.run_command('move', {'by': 'lines', 'forward': False})
92 | self.view.run_command('move', {'by': 'lines', 'forward': False})
93 |
94 | def _insert_method(self, edit, indent, snippet):
95 | selection = self.view.sel()[0]
96 | line = self.view.line(selection.b)
97 | indent_value = self._get_indent(indent)
98 |
99 | self.view.replace(edit, sublime.Region(line.a, selection.b), indent_value)
100 | self.view.run_command('insert_snippet', {'contents': snippet})
101 |
102 | def _get_indent(self, indent):
103 | if self.view.settings().get('translate_tabs_to_spaces', False):
104 | tab = ' '
105 | else:
106 | tab = "\t"
107 |
108 | return tab * indent
109 |
110 | def _prepare_index(self, methods, index):
111 | if index == None:
112 | return []
113 |
114 | result = []
115 | if isinstance(index, list):
116 | for index_item in index:
117 | result += self._prepare_index(methods, index_item)
118 | return result
119 |
120 | current = self._get_current_index(methods)
121 |
122 | match = None
123 | if isinstance(index, str):
124 | match = re.match(r"^(\+|\-|)(\d+)$", index)
125 |
126 | if current != None and match != None:
127 | if match.group(1) == '+':
128 | index = current + int(match.group(2))
129 | if index > len(methods) - 1:
130 | index = len(methods) - 1
131 | elif match.group(1) == '-':
132 | index = current - int(match.group(2))
133 | if index < 0:
134 | index = 0
135 | else:
136 | index = int(match.group(2))
137 |
138 | result = [index]
139 |
140 | elif isinstance(index, str) and index[0] == '/':
141 | regexp = index[1 : - 1]
142 | index = None
143 | for method_index, method in enumerate(methods):
144 | if re.search(regexp, method["name"]):
145 | result.append(method_index)
146 |
147 | elif isinstance(index, str) and index[0] == ':':
148 | name = index[1 :]
149 | index = None
150 | for method_index, method in enumerate(methods):
151 | if name == method["name"]:
152 | index = method_index
153 | indexes.append(index)
154 | break
155 |
156 | elif index == 'current':
157 | result = [current]
158 |
159 | elif index == 'private':
160 | index = None
161 | for method_index, method in enumerate(methods):
162 | if method['privacy'] == 'private':
163 | result.append(method_index)
164 |
165 | elif index == 'last_private':
166 | index = None
167 | for method_index, method in reversed(enumerate(methods)):
168 | if method['privacy'] == 'private':
169 | result.append(method_index)
170 |
171 | elif index == 'protected':
172 | index = None
173 | for method_index, method in enumerate(methods):
174 | if method['privacy'] == 'protected':
175 | result.append(method_index)
176 |
177 | elif index == 'last_protected':
178 | index = None
179 | for method_index, method in reversed(enumerate(methods)):
180 | if method['privacy'] == 'protected':
181 | result.append(method_index)
182 |
183 | elif index == 'last':
184 | result = [len(methods) - 1]
185 |
186 | elif isinstance(index, int):
187 | result = [index]
188 |
189 | return result
190 |
191 | def _get_current_index(self, methods):
192 | cursor = self.view.sel()[0].b
193 | index = None
194 |
195 | max_cursor = 0
196 | for method_index, method in enumerate(methods):
197 | if cursor <= method["end"] and cursor > max_cursor:
198 | max_cursor = method["end"]
199 | index = method_index
200 |
201 | if index == None:
202 | index = len(methods) - 1
203 |
204 | return index
205 |
206 | def _get_definition(self, name, args, body, result, snippet):
207 | info = self._get_snippet_args(name, args, body, result)
208 | if info == None:
209 | return None
210 |
211 | name, args, body, result = info
212 |
213 | snippet = self._get_snippet_content(snippet)
214 | if snippet == None:
215 | return None
216 |
217 | snippet = self._set_args_to_snippet(snippet, name, args, body, result)
218 | return snippet
219 |
220 | def _get_snippet_content(self, snippet):
221 | language = self._get_language()
222 | if language == None:
223 | return None
224 |
225 | return parser.get_method_snippet(language, snippet)
226 |
227 | def _get_snippet_args(self, name, args, body, result):
228 | definition_info = self._get_definition_info()
229 | if definition_info == None:
230 | return
231 |
232 | definition_type, definition_region = definition_info
233 | if definition_type == 'name':
234 | if definition_region != None:
235 | new_name, new_args = self._extract_name(definition_region)
236 | else:
237 | new_name, new_args = None, ['']
238 |
239 | new_body, new_result = None, None
240 | else:
241 | new_body, new_args, new_result = self._extract_body(definition_region)
242 | new_name = None
243 |
244 | if name == None:
245 | name = new_name
246 |
247 | if args == None:
248 | args = new_args
249 |
250 | if body == None:
251 | body = new_body
252 |
253 | if result == None:
254 | result = new_result
255 |
256 | # fucking self
257 | scope_name = self.view.scope_name(self.view.sel()[0].a)
258 | if 'self' in args and 'python' in scope_name:
259 | args.remove('self')
260 |
261 | return name, args, body, result
262 |
263 | def _set_args_to_snippet(self, snippet, name, args, body, result):
264 | index = 1
265 |
266 | snippet = snippet.replace('$name', (name or '') + '$' + str(index))
267 | index += 1
268 |
269 | args_value = []
270 | for arg in args:
271 | arg = self._escape_snippet_value(arg)
272 | args_value.append('${' + str(index) + ':' + arg + '}')
273 | index += 1
274 |
275 | snippet = snippet.replace('$args', ', '.join(args_value))
276 |
277 | if body != None:
278 | body = self._escape_snippet_value(body)
279 | if result != None and len(result) != 0:
280 | result_args = []
281 | for result_arg in result:
282 | result_arg = self._escape_snippet_value(result_arg)
283 | result_args.append('${' + str(index) + ':' + result_arg + '}')
284 | index += 1
285 |
286 | body += '$' + str(index) + "\n\nreturn " + ', '.join(result_args)
287 | index += 1
288 |
289 | body_indent = re.search(r'\n(\s*)\$body', snippet)
290 | if body_indent != None:
291 | body = re.sub('(\n)', '\\1' + body_indent.group(1), body)
292 | snippet = snippet.replace('$body', (body or '') + '$' + str(index))
293 | index += 1
294 |
295 | return snippet
296 |
297 | def _escape_snippet_value(self, value):
298 | return(
299 | value.
300 | replace('\\', '\\\\').
301 | replace('$', '\\$').
302 | replace('{', '\\{').
303 | replace('}', '\\}')
304 | )
305 |
306 | def _extract_name(self, region):
307 | token_value = self.view.substr(sublime.Region(*region))
308 | parethesis = re.search(r'\(', token_value)
309 | if parethesis == None:
310 | name, args = token_value, []
311 | else:
312 | name = token_value[: parethesis.start(0)]
313 | args_point = region[0] + parethesis.end(0)
314 | args_tokens = statement.get_tokens(self.view, args_point) or []
315 | args = []
316 | for arg in args_tokens:
317 | args.append(self.view.substr(sublime.Region(*arg)))
318 |
319 | name_match = re.search(r'[\w\?\!]+$', name)
320 | if name_match != None:
321 | name = name_match.group(0)
322 |
323 | return name, args
324 |
325 | def _extract_body(self, region):
326 | variables = local_variable.find_variables(self.view, region[0], False)
327 |
328 | assignments = []
329 | for assignment in local_variable.find_all_assignments(self.view, region[0]):
330 | assignments.append(assignment['variable'])
331 |
332 | inner, following = [], []
333 | for variable in variables:
334 | if region[0] <= variable[0] and variable[1] <= region[1]:
335 | value = self.view.substr(sublime.Region(*variable))
336 | inner.append(value)
337 | elif region[1] <= variable[0]:
338 | value = self.view.substr(sublime.Region(*variable))
339 | following.append(value)
340 |
341 | preceding_assignments, inner_assignments = [], []
342 | for assignment in assignments:
343 | if assignment[1] <= region[0]:
344 | value = self.view.substr(sublime.Region(*assignment))
345 | if value not in preceding_assignments:
346 | preceding_assignments.append(value)
347 | elif region[0] <= assignment[0] and assignment[1] <= region[1]:
348 | value = self.view.substr(sublime.Region(*assignment))
349 | if value not in inner_assignments:
350 | inner_assignments.append(value)
351 |
352 | body = self._extract_indented_body(region)
353 | args = self._get_list_intersection(preceding_assignments, inner)
354 | result = self._get_list_intersection(inner_assignments, following)
355 |
356 | return body, args, result
357 |
358 | def _get_list_intersection(self, list1, list2):
359 | result = []
360 | for item in list1:
361 | if item in list2:
362 | result.append(item)
363 | return result
364 |
365 | def _get_definition_info(self):
366 | selection = self.view.sel()[0]
367 | if selection.empty():
368 | token_info = statement.get_token(self.view, selection.b)
369 | token = None
370 | if token_info != None:
371 | _, token = token_info
372 |
373 | if token == None or '(' not in self.view.substr(sublime.Region(*token)):
374 | token = statement.get_parent_token(self.view, selection.b, r'\(')
375 |
376 | if token == None:
377 | return 'name', None
378 |
379 | return 'name', token
380 | else:
381 | statement_1 = statement.get_statement(self.view, selection.begin())
382 | statement_2 = statement.get_statement(self.view, selection.end())
383 |
384 | if statement_1 == None or statement_2 == None:
385 | return None
386 | if statement_1 != statement_2 or expression.find_match(self.view,
387 | statement_1[0], r'\{', {'range': statement_1, 'string': False}) != None:
388 | return 'body', [statement_1[0], statement_2[1]]
389 | else:
390 | return 'name', statement_1
391 |
392 | def _extract_method_definition(self, cursor):
393 | _, token = statement.get_token(self.view, self.view.sel()[0].b)
394 | if token == None:
395 | return None
396 |
397 | if self.view.substr(sublime.Region(token[1] - 1, token[1])) != ')':
398 | token = statement.get_parent_token(self.view, cursor, r'\(')
399 | if token == None:
400 | return None
401 |
402 | return self.view.substr(sublime.Region(*token))
403 |
404 | def _prepare_name(self, selection):
405 | return re.sub(r'^(self|\$?this)(\.|->)', '', selection)
406 |
407 | # this method copied from SnippetCaller _get_indented_region
408 | def _extract_indented_body(self, region):
409 | sel = sublime.Region(*region)
410 |
411 | region = sublime.Region(self.view.line(sel.begin()).a, sel.end())
412 | text = re.sub(r'^([\n\s]*)\n', '', self.view.substr(region))
413 | original_text = re.sub(r'^([\n\s]*)\n', '', self.view.substr(sel))
414 |
415 | ignore_first_line = False
416 | if text.strip() != original_text.strip():
417 | text = original_text
418 | ignore_first_line = True
419 |
420 | lines = text.split("\n")
421 | min = None
422 | source_indentation = ''
423 | for index, line in enumerate(lines):
424 | if ignore_first_line and index == 0:
425 | continue
426 |
427 | match = re.search(r'^(\s*)\S', line)
428 |
429 | if match == None:
430 | continue
431 |
432 | if min == None or min > len(match.group(1)):
433 | min = len(match.group(1))
434 | source_indentation = match.group(1)
435 |
436 | result = re.sub(r'(^|\n)' + source_indentation, '\\1', text)
437 | result = result.rstrip()
438 |
439 | return result
440 |
441 | class SelectMethods(MethodBase):
442 | def run(self, edit, methods = 'current', excepts = None, body = False):
443 | current_methods = self._get_methods()
444 |
445 | methods_indexes = self._prepare_index(current_methods, methods)
446 | excepts_indexes = self._prepare_index(current_methods, excepts)
447 |
448 | self.view.sel().clear()
449 | for index in methods_indexes:
450 | if index in excepts_indexes:
451 | continue
452 |
453 | method = current_methods[index]
454 |
455 | if body:
456 | start, end = method['body_start'], method['body_end']
457 |
458 | else:
459 | start, end = method["start"], method["end"]
460 |
461 | region = sublime.Region(start, end)
462 | if not body:
463 | region = self.view.line(region)
464 |
465 | self.view.sel().add(region)
466 |
467 | class GotoMethod(MethodBase):
468 | def run(self, edit, method = 'current', position = None):
469 | methods = self._get_methods()
470 | method = self._prepare_index(methods, method)[0]
471 | info = methods[method]
472 |
473 | cursor = info["start"]
474 | region = sublime.Region(cursor, self.view.size())
475 | cursor += self.view.substr(region).index(info["name"]) + len(info["name"])
476 | if position == 'swap':
477 | if self.view.sel()[0].b == cursor:
478 | cursor = info["end"]
479 | elif position != None:
480 | cursor = info[position]
481 |
482 | self.view.sel().clear()
483 | self.view.sel().add(sublime.Region(cursor, cursor))
484 | self.view.show(sublime.Region(cursor, cursor))
485 |
486 | class CloneMethod(MethodBase):
487 | def run(self, edit, method = 'current', index = 0, after = False):
488 | methods = self._get_methods()
489 | method = self._prepare_index(methods, method)[0]
490 | index = self._prepare_index(methods, index)[0]
491 |
492 | is_clone_invalid = (
493 | (index < 0 or index > len(methods) - 1)
494 | )
495 |
496 | if is_clone_invalid:
497 | return
498 |
499 | region, _, _ = self._get_method_regions(methods, method)
500 | target, _, _ = self._get_method_regions(methods, index)
501 |
502 | text, shift, point = self._get_insert_info(region, target, after)
503 |
504 | self.view.insert(edit, point, text)
505 | self.view.sel().clear()
506 | self.view.sel().add(sublime.Region(point + shift[0], point + shift[1]))
507 |
508 | class MoveMethod(MethodBase):
509 | def run(self, edit, method = 'current', index = 0, after = False):
510 | methods = self._get_methods()
511 | method = self._prepare_index(methods, method)[0]
512 | index = self._prepare_index(methods, index)[0]
513 |
514 | is_move_invalid = (
515 | (method == index and after == True) or
516 | (index < 0 or index > len(methods) - 1)
517 | )
518 |
519 | if is_move_invalid:
520 | return
521 |
522 | old, old_delete, lines = self._get_method_regions(methods, method)
523 | text = self.view.substr(old)
524 | shift = [self.view.sel()[0].a - old.a, self.view.sel()[0].b - old.a]
525 |
526 | self.view.replace(edit, old_delete, lines)
527 | methods = self._get_methods()
528 |
529 | if method < index:
530 | index -= 1
531 |
532 | new, _, _ = self._get_method_regions(methods, index)
533 |
534 | if after:
535 | text = "\n\n" + text
536 | point = new.b
537 | shift[0] += 2
538 | shift[1] += 2
539 | else:
540 | text += "\n\n"
541 | point = new.a
542 |
543 | self.view.insert(edit, point, text)
544 | self.view.sel().clear()
545 | self.view.sel().add(sublime.Region(point + shift[0], point + shift[1]))
546 |
547 | class DeleteMethod(MethodBase):
548 | def run(self, edit, method = 'current'):
549 | methods = self._get_methods()
550 | method = self._prepare_index(methods, method)[0]
551 | _, region, lines = self._get_method_regions(methods, method)
552 | self.view.replace(edit, region, lines)
553 |
554 | class InsertMethodNameToMark(MethodBase):
555 | def run(self, edit, method = 'current', snippets = []):
556 | methods = self._get_methods()
557 | method_index = self._prepare_index(methods, method)[0]
558 |
559 | snippet = self._get_snippet(snippets, methods[method_index])
560 |
561 | self.view.run_command('goto_named_mark', {'name': 'method'})
562 | self.view.run_command('insert_snippet', {'contents': snippet})
563 |
564 | def _get_snippet(self, snippets, method):
565 | result_args, is_regular_snippet = self._get_result_args(method)
566 | snippet = self._get_snippet_value(snippets, is_regular_snippet)
567 |
568 | snippet_index = 1
569 | snippet_index, result_args_str = self._prepare_result_args(snippet_index,
570 | result_args, is_regular_snippet)
571 |
572 | args_prepared = self._get_args(method, snippet_index)
573 |
574 | snippet = (snippet.
575 | replace('${result}', result_args_str).
576 | replace('$name', method['name']).
577 | replace('$args', ', '.join(args_prepared)))
578 |
579 | return snippet
580 |
581 | def _get_args(self, method, snippet_index):
582 | match_options = {
583 | 'range': [method['start'], method['end']],
584 | 'nesting': True,
585 | }
586 |
587 | args_point = expression.find_match(self.view, method['start'], r'(?:\()',
588 | match_options)
589 |
590 | args = []
591 | if args_point != None:
592 | tokens_point = method['start'] + args_point.end(0)
593 | tokens = statement.get_tokens(self.view, tokens_point)
594 | for token in tokens:
595 | args.append(self.view.substr(sublime.Region(*token)))
596 |
597 | # fucking self
598 | if 'python' in self.view.scope_name(method['start']) and 'self' in args:
599 | args.remove('self')
600 |
601 | args_prepared = []
602 | for arg in args:
603 | snippet_index += 1
604 | args_prepared.append('${' + str(snippet_index) + ':' +
605 | re.search(r'^\S*', arg).group(0) + '}')
606 |
607 | return args_prepared
608 |
609 | def _prepare_result_args(self, snippet_index, result_args, is_regular):
610 | result_args_prepared = []
611 | if result_args != None:
612 | for arg in result_args:
613 | arg_value = self.view.substr(sublime.Region(*arg))
614 | snippet_index += 1
615 | result_args_prepared.append('${' + str(snippet_index) + ':' +
616 | self._escape_snippet_value(arg_value) + '}')
617 |
618 | result_args_str = ', '.join(result_args_prepared)
619 | if len(result_args_str) > 0 and is_regular:
620 | result_args_str += ' = '
621 |
622 | return snippet_index, result_args_str
623 |
624 | def _get_snippet_value(self, snippets, is_regular_snippet):
625 | if len(snippets) != 0:
626 | if is_regular_snippet:
627 | snippet_file = snippets[0]
628 | else:
629 | snippet_file = snippets[1]
630 |
631 | snippet = parser.get_method_insert_snippet(self._get_language(), None,
632 | snippet_file)
633 | else:
634 | snippet = parser.get_method_insert_snippet(self._get_language(),
635 | not is_regular_snippet)
636 |
637 | return snippet
638 |
639 | def _get_result_args(self, method):
640 | returns = expression.find_matches(self.view, method['body_start'],
641 | r'(?:\n|^).*?return', {'range': [method['body_start'],
642 | method['body_end']], 'nesting': True})
643 |
644 | null, result_args = None, None
645 | nulls = ['None', 'null', 'nil', 'undefined']
646 | for return_match in returns:
647 | tokens = statement.get_tokens(self.view, method['body_start'] +
648 | return_match.end(0))
649 |
650 | first_token = self.view.substr(sublime.Region(*tokens[0]))
651 | if len(tokens) == 1 and first_token in nulls:
652 | null = tokens[0]
653 | else:
654 | result_args = tokens
655 |
656 | is_regular_snippet = (
657 | null == None or
658 | result_args == None or
659 | len(result_args) <= 1
660 | )
661 |
662 | return result_args, is_regular_snippet
663 |
664 | class CreateMethodSpace(MethodBase):
665 | def run(self, edit, index = 0, after = False):
666 | methods = self._get_methods()
667 | index = self._prepare_index(methods, index)[0]
668 | self._set_cursor_position(methods[index], after)
669 | self._insert_method_space(after)
670 |
671 | class CreateMethod(MethodBase):
672 | def run(self, edit,
673 | index = 0,
674 | after = False,
675 | restore = False,
676 | name = None,
677 | args = None,
678 | body = None,
679 | result = None,
680 | snippet = None,
681 | cursor = '$auto',
682 | delete = '$auto',
683 | mark = True,
684 | ):
685 | if restore:
686 | self._save_regions()
687 |
688 | methods = self._get_methods()
689 | index = self._prepare_index(methods, index)[0]
690 | method_info = methods[index]
691 | indent = self._get_method_indent(method_info)
692 |
693 | snippet = self._get_definition(name, args, body, result, snippet)
694 | if snippet == None:
695 | raise Exception('Snippet for method not found')
696 |
697 | if mark and not restore:
698 | self.view.run_command('set_named_mark', {'name': 'method', 'icon': ''})
699 |
700 | if delete:
701 | self.view.erase_regions('method_delete')
702 | self.view.add_regions('method_delete', [self.view.sel()[0]])
703 |
704 | self._set_cursor_position(method_info, after)
705 |
706 | self._insert_method_space(after)
707 | self._insert_method(edit, indent, snippet)
708 |
709 | if restore:
710 | self._restore_regions()
711 |
712 | if mark and restore:
713 | self.view.run_command('set_named_mark', {'name': 'method', 'icon': ''})
714 |
715 | deleted = self.view.get_regions('method_delete')
716 | if len(deleted) > 0:
717 | indent_match = re.search(r'(^|\n)([^\S\n]*)\S', self.view.substr(deleted[0]))
718 | if indent_match == None:
719 | indent = ''
720 | else:
721 | indent = indent_match.group(2)
722 |
723 | self.view.replace(edit, deleted[0], '')
724 | self.view.insert(edit, deleted[0].begin(), indent)
725 |
726 | def _get_method_indent(self, method):
727 | line = self.view.full_line(sublime.Region(method["start"], method["end"]))
728 | text = self.view.substr(line)
729 | match = re.match(r"^([ \t]*)[^\s]+", text)
730 | if match == None:
731 | return 0
732 |
733 | return len(match.group(1))
734 |
--------------------------------------------------------------------------------
/context.py:
--------------------------------------------------------------------------------
1 | import sublime
2 | import sublime_plugin
3 |
4 | from Context.base import Base
5 | from . import method
6 |
7 | class InMethodDefinition(Base):
8 |
9 | def on_query_context(self, view, *args):
10 | return self._check_sel('in_method_definition', self._check_point, view,
11 | *args)
12 |
13 | def _check_point(self, view, sel):
14 | info = method.extract_method(view, sel.a)
15 | if info == None:
16 | return False
17 |
18 | start = info['start']
19 | value = view.substr(sublime.Region(start, info['body_start'])).strip()
20 | return start < sel.a and sel.b < start + len(value)
21 |
22 | class InMethod(Base):
23 | def on_query_context(self, view, *args):
24 | return self._check_sel('in_method', self._check_point, view, *args)
25 |
26 | def _check_point(self, view, sel):
27 | info = method.extract_method(view, sel.a)
28 | if info == None:
29 | return False
30 |
31 | return info['start'] < sel.a and sel.b < info['end']
32 |
33 | class MethodName(Base):
34 | def on_query_context(self, view, *args):
35 | return self._check_sel('method_name', self._get_method_name, view, *args)
36 |
37 | def _get_method_name(self, view, sel):
38 | info = method.extract_method(view, sel.a)
39 | if info == None:
40 | return None
41 |
42 | return info['name']
--------------------------------------------------------------------------------
/demo/demo.py:
--------------------------------------------------------------------------------
1 | # some python code
2 |
3 | class MethodBase(sublime_plugin.TextCommand):
4 |
5 | def _process(self, result):
6 | # do stuff here...
7 | return result # method was moved
8 |
9 | def _prepare_index(self, methods, index):
10 | if index == None:
11 | return []
12 |
13 | result = []
14 | if isinstance(index, list):
15 | for index_item in index:
16 | result += self._prepare_index(methods, index_item)
17 | return result
18 |
19 | # done
20 | result = self._call(methods, index, result)
21 |
22 | # new method will be added
23 | result = self._process(result)
24 |
25 | return result
26 |
27 | def _call(self, methods, index, result):
28 | if current != None and match != None:
29 | if match.group(1) == '+':
30 | index = current + int(match.group(2))
31 | if index > len(methods) - 1:
32 | index = len(methods) - 1
33 |
34 | result = [index]
35 |
36 | return result
--------------------------------------------------------------------------------
/leave_only_current_test.sublime-macro:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "args": null,
4 | "command": "set_mark"
5 | },
6 | {
7 | "args": {
8 | "excepts": ["current"],
9 | "methods": "/^(t|T)est/"
10 | },
11 | "command": "select_methods"
12 | },
13 | {
14 | "args": {"block": false},
15 | "command": "toggle_comment"
16 | },
17 | {
18 | "args": {"block": false},
19 | "command": "toggle_bookmark"
20 | },
21 | {
22 | "command": "next_bookmark",
23 | "args": {"name": "mark"},
24 | },
25 | {
26 | "command": "clear_bookmarks",
27 | "args": {"name": "mark"}
28 | }
29 | ]
30 |
--------------------------------------------------------------------------------
/leave_only_current_test_go.sublime-macro:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "args": null,
4 | "command": "set_mark"
5 | },
6 | {
7 | "args": {
8 | "excepts": ["current"],
9 | "methods": "/^Test/"
10 | },
11 | "command": "select_methods"
12 | },
13 | {
14 | "args": {"block": false},
15 | "command": "toggle_comment"
16 | },
17 | {
18 | "args": {"block": false},
19 | "command": "toggle_bookmark"
20 | },
21 | {
22 | "command": "next_bookmark",
23 | "args": {"name": "mark"},
24 | },
25 | {
26 | "command": "clear_bookmarks",
27 | "args": {"name": "mark"}
28 | }
29 | ]
30 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | The MIT License (MIT)
4 |
5 | Copyright (c) 2014 Leonid Shagabutdinov
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
--------------------------------------------------------------------------------
/method.py:
--------------------------------------------------------------------------------
1 | import sublime
2 | import sublime_plugin
3 | import re
4 |
5 | from xml.dom import minidom
6 |
7 | try:
8 | from Expression import expression
9 | except ImportError as error:
10 | sublime.error_message("Dependency import failed; please read readme for " +
11 | "Method plugin for installation instructions; to disable this " +
12 | "message remove this plugin; message: " + str(error))
13 | raise error
14 |
15 | indented_languages = ['python', 'coffee', 'saas']
16 |
17 | def extract_method(view, point = None):
18 | if point == None:
19 | point = view.sel()[0].begin()
20 |
21 | result = None
22 | for index, method in enumerate(extract_methods(view)):
23 | if point > method['start']:
24 | result = method
25 |
26 | return result
27 |
28 | def extract_methods(view):
29 | methods = []
30 | text = view.substr(sublime.Region(0, view.size()))
31 | lines = text.split("\n")
32 |
33 | for index, word in enumerate(view.find_by_selector('entity.name.function')):
34 | start, body_start, privacy = _get_method_start(view, lines, word)
35 | end, body_end = _get_method_end(view, lines, start, body_start)
36 |
37 | methods.append({
38 | 'index': index,
39 | 'name': view.substr(word),
40 | 'start': start,
41 | 'end': end,
42 | 'body_start': body_start,
43 | 'body_end': body_end,
44 | 'privacy': privacy,
45 | })
46 |
47 | return methods
48 |
49 | def get_regions(view, method):
50 | start_line = view.line(method['start'])
51 | comment_point = start_line.a - 2
52 | if 'comment' in view.scope_name(comment_point):
53 | comment_start_point = view.extract_scope(comment_point).a
54 | start_line.a = view.line(comment_start_point).a
55 |
56 | region = sublime.Region(start_line.a, method['end'])
57 | delete = sublime.Region(region.a, region.b + 1)
58 | while True:
59 | if delete.a <= 0:
60 | break
61 |
62 | previous = view.line(delete.a - 1)
63 | if view.substr(previous).strip() == '':
64 | delete.a = previous.a
65 | else:
66 | break
67 |
68 | view_size = view.size()
69 | while True:
70 | if delete.b >= view_size:
71 | delete.b = view_size
72 | break
73 |
74 | next = view.line(delete.b)
75 | if view.substr(next).strip() == '':
76 | delete.b = next.b + 1
77 | else:
78 | break
79 |
80 | # delete.b += 1
81 | lines = ''
82 |
83 | # if index != 0 and index != len(methods) - 1:
84 | lines += "\n"
85 |
86 | return region, delete, lines
87 |
88 | def _get_method_start(view, lines, name_range):
89 | start_line, _ = view.rowcol(name_range.a)
90 | start_col = re.search(r'^(\s*)', lines[start_line]).end(1)
91 |
92 | start = view.text_point(start_line, start_col)
93 | body_start = name_range.b
94 | if '(' in lines[start_line]:
95 | body_start = _skip_parenthesis_or_return_args(view, body_start)
96 |
97 | # check { or : right after body_start
98 | body_start_match = re.search(r'^\s*[{:]', view.substr(
99 | sublime.Region(body_start, body_start + 64)))
100 |
101 | if body_start_match != None:
102 | body_start += body_start_match.end(0)
103 |
104 | # strip whitespaces
105 | body_start += re.search(r'^\s*', view.substr(sublime.Region(body_start,
106 | body_start + 64))).end(0)
107 |
108 | return start, body_start, _get_method_privacy(lines, start_line)
109 |
110 | def _skip_parenthesis_or_return_args(view, point):
111 | new_point = point
112 | while True:
113 | new_point = _skip_parenthesis(view, point)
114 | if new_point == point:
115 | break
116 |
117 | point = new_point
118 |
119 | if 'source.go' in view.scope_name(point):
120 | match = expression.find_match(view, point, r'{',
121 | {'range': [point, point + 128]})
122 | if match != None:
123 | new_point += match.end(0)
124 |
125 | return new_point
126 |
127 | def _skip_parenthesis(view, point):
128 | if '(' not in view.substr(sublime.Region(point, view.line(point).b)):
129 | return point
130 |
131 | match = expression.find_match(view, point, r'\)',
132 | {'range': [point, point + 512], 'nesting': 'end'})
133 |
134 | if match == None:
135 | return point
136 |
137 | return match.end(0) + point
138 |
139 | def _get_method_end(view, lines, start, body_start):
140 | empty = re.search(r'^\s*(\}|end)', view.substr(sublime.Region(body_start,
141 | body_start + 64)))
142 |
143 | if empty:
144 | return body_start + empty.end(0), body_start + empty.start(0)
145 |
146 | start_line, _ = view.rowcol(body_start)
147 | end_line = _method_method_end_line(view, lines, start_line)
148 | end = view.text_point(end_line, len(lines[end_line]))
149 |
150 | if _is_indented(view, start):
151 | body_end = end
152 | else:
153 | point = view.text_point(end_line, 0)
154 | end_line_range = view.line(point)
155 | body_end = end_line_range.a + re.search(r'^\s*', lines[end_line]).end(0)
156 |
157 | # stip body end
158 | body_end -= len(re.search(r'(\s*)$', view.substr(sublime.Region(body_end - 64,
159 | body_end))).group(0))
160 |
161 | return end, body_end
162 |
163 | def _method_method_end_line(view, lines, start_line):
164 | previous_line_index, end_line = None, None
165 | source_indentation = len(re.match(r'^(\s*)', lines[start_line]).group(0))
166 |
167 | for line_index in range(start_line, len(lines)):
168 | line = lines[line_index]
169 | if line.strip() == '':
170 | continue
171 |
172 | current_indentation = len(re.match(r'^(\s*)', line).group(0))
173 |
174 | scope_name = view.scope_name(view.text_point(line_index, 0))
175 | if 'string' in scope_name or 'comment' in scope_name:
176 | continue
177 |
178 | end_found = (current_indentation < source_indentation and
179 | not line.strip().startswith('rescue')) # ruby rescue hack
180 |
181 | if end_found:
182 | end_line_token = line.strip()
183 | if end_line_token == 'end' or end_line_token[0] == '}':
184 | end_line = line_index
185 | else:
186 | end_line = previous_line_index
187 | break
188 |
189 | previous_line_index = line_index
190 |
191 | if end_line == None:
192 | end_line = len(lines) - 1
193 |
194 | return end_line
195 |
196 | def _is_indented(view, point):
197 | scope = view.scope_name(point)
198 | for language in indented_languages:
199 | if language in scope:
200 | return True
201 |
202 | return False
203 |
204 | def _get_method_privacy(lines, line):
205 | if 'public' in lines[line]:
206 | return 'public'
207 |
208 | if 'protected' in lines[line]:
209 | return 'protected'
210 |
211 | if 'private' in lines[line]:
212 | return 'private'
213 |
214 | privacies = ['public', 'protected', 'private']
215 | for index in reversed(range(0, line)):
216 | stripped = lines[index].strip()
217 | if stripped in privacies:
218 | return stripped
219 |
220 | return 'public'
221 |
222 | def get_method_insert_snippet(language, null = False, filename = None):
223 | if filename == None:
224 | if null:
225 | filename = language + '-method-call-null.sublime-snippet'
226 | else:
227 | filename = language + '-method-call.sublime-snippet'
228 |
229 | return _get_snippet_body(filename)
230 |
231 | def get_method_snippet(language, filename = None):
232 | if filename == None:
233 | filename = language + '-method.sublime-snippet'
234 |
235 | return _get_snippet_body(filename)
236 |
237 | def _get_snippet_body(filename):
238 | snippets = sublime.find_resources(filename)
239 | if len(snippets) == 0:
240 | raise Exception('Snippet "' + filename + '" not found')
241 |
242 | snippet = sublime.load_resource(snippets[0])
243 | if snippet.strip() == '':
244 | return None
245 |
246 | xml = minidom.parseString(snippet).firstChild
247 | if xml == None:
248 | return None
249 |
250 | snippet = {}
251 | for node in xml.childNodes:
252 | if node.nodeType == node.ELEMENT_NODE:
253 | value_node = node.firstChild
254 | if value_node == None:
255 | continue
256 |
257 | if node.tagName == 'content':
258 | return value_node.data.strip()
259 |
260 | raise Exception('Snippet "' + name + '" is empty')
261 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Sublime Method plugin
2 |
3 | The glorious plugin that allows (almost) language independent methods
4 | manipulation in file.
5 |
6 | ### Demo
7 |
8 | 
9 |
10 |
11 | ### Installation
12 |
13 | This plugin is part of [sublime-enhanced](http://github.com/shagabutdinov/sublime-enhanced)
14 | plugin set. You can install sublime-enhanced and this plugin will be installed
15 | automatically.
16 |
17 | If you would like to install this package separately check "Installing packages
18 | separately" section of [sublime-enhanced](http://github.com/shagabutdinov/sublime-enhanced)
19 | package.
20 |
21 |
22 | ### WARNING
23 |
24 | This plugin does not works with multicursors. The reason is that I'm too lazy
25 | and the plugin is too complext to refactor it and add multicursors support.
26 |
27 | At least one method should be defined in current file before you can start using
28 | this plugin. At least one private or protected method should be defined if
29 | you want to work with private/protected methods.
30 |
31 | It relies heavely on source code indentation. If your file is poorly indented
32 | then this plugin will not work properly.
33 |
34 | E.g.:
35 |
36 | ```
37 | # good
38 | def a()
39 | test()
40 | end
41 |
42 | # bad
43 | def a()
44 | test()
45 | end
46 | ```
47 |
48 | There is default support for languages: ruby, python, php, js, coffee. If you
49 | want to provide other language supporting, you should create three files in
50 | "User" plugins directory:
51 |
52 | - [language]-method.sublime-snippet
53 | - [language]-method-call.sublime-snippet
54 | - [language]-method-call-null.sublime-snippet
55 |
56 | Where [language] is your language as it defined in sublime (to find out right
57 | name use "ctrl+u, ctrl+\" hotkey).
58 |
59 | See "snippets" directory for examples. You can also make pull request to make
60 | your language support available for everybody.
61 |
62 | ### Features
63 |
64 | 1. Create (extract) method - creates new method. It tries to detect method name,
65 | args, body and return value based on current cursor position. There is also
66 | bindings to show where to create method (in beginning of method list, in
67 | "private" section and etc.)
68 |
69 | 2. Move method - moves current method under cursor to new position (begin of
70 | methods list, to private)
71 |
72 | 3. Goto method - allows bind shortcuts to goto first/last method, first/last
73 | private method, next/previous method and method by name (e.g. "__init__")
74 |
75 | 4. Create method space - creates space for method so your preferred snippet can
76 | be executed here. Especeally good for defining tests.
77 |
78 | 5. Delete method - deletes current method. Especeally good when working with
79 | tests.
80 |
81 | 6. Clone method - clones current method. Especeally good when working with
82 | tests.
83 |
84 | 7. Insert method name to mark - inserts current method name, arguments and
85 | result to mark.
86 |
87 | 8. Select methods - select specified methods name or methods body.
88 |
89 | 9. Comment/uncomment all except current - usefull when you want to run only
90 | current test; hotkey is faster than specifying "--name test_my_feature" in
91 | command line.
92 |
93 | ### Usage
94 |
95 | Only few usecases displayed here. Please see "Commands" section to receive
96 | complete command list.
97 |
98 | ##### Create method (by name)
99 |
100 | ```
101 | # before
102 | def a(a)
103 | b(a)| # <- cursor is here
104 | end
105 |
106 | # after
107 | def a(a)
108 | b(a)
109 | end
110 |
111 | def b|(a) # <- cursor is here
112 |
113 | end
114 | ```
115 |
116 | ##### Create method (by body)
117 |
118 | ```
119 | # before
120 | def a(a)
121 | {a = b(a)
122 | a = c(a)}| # <- selection is here
123 | d(a)
124 | end
125 |
126 | # after
127 | def a(a)
128 |
129 | end
130 |
131 | def |(a) # <- cursor is here
132 | a = b(a)
133 | a = c(a)
134 | return a
135 | end
136 | ```
137 |
138 | ##### Move method down
139 | ```
140 | # before
141 | def first()
142 | | # <- cursor is here
143 | end
144 |
145 | def second()
146 |
147 | end
148 |
149 | # after
150 | def second()
151 |
152 | end
153 |
154 | def first()
155 | | # <- cursor is here
156 | end
157 | ```
158 |
159 | ### Commands
160 |
161 | | Description | Keyboard shortcut | Command palette |
162 | |------------------------------|-------------------|--------------------------------------|
163 | | Create method before current | ctrl+m, ctrl+, | Method: Create method before current |
164 | | Create method after current | ctrl+m, ctrl+. | Method: Create method after current |
165 | | Create method after current | ctrl+alt+shift+n | Method: Create method after current |
166 | | Create method after first | ctrl+m, ctrl+0 | Method: Create method after first |
167 | | Create protected method | ctrl+m, ctrl+o | Method: Create protected method |
168 | | Create private method | ctrl+m, ctrl+i | Method: Create private method |
169 | | Create method after last | ctrl+m, ctrl+l | Method: Create method after last |
170 | | Move method after first | ctrl+m, 0 | Method: Move method after first |
171 | | Move method to protected | ctrl+m, o | Method: Move method to protected |
172 | | Move method to private | ctrl+m, i | Method: Move method to private |
173 | | Move method to last | ctrl+m, l | Method: Move method to last |
174 | | Move method up | alt+- | Method: Move method up |
175 | | Move method down | alt+= | Method: Move method down |
176 | | Go to next method | alt+n | Method: Go to next method |
177 | | Go to previous method | alt+shift+n | Method: Go to previous method |
178 | | Swap method start/end | alt+ctrl+n | Method: Swap method start/end |
179 | | Go to last method | ctrl+m, ctrl+/ | Method: Go to last method |
180 | | Go to first method | ctrl+m, ctrl+f | Method: Go to first method |
181 | | Create method space | ctrl+m, ctrl+n | Method: Create method space |
182 | | Delete method | ctrl+m, ctrl+d | Method: Delete method |
183 | | Clone method | ctrl+m, ctrl+c | Method: Clone method |
184 | | Insert method name to mark | ctrl+m, ctrl+m | Method: Insert method name to mark |
185 | | Select current method | ctrl+m, ctrl+s | Method: Select current method |
186 | | Select current method body | ctrl+m, s | Method: Select current method body |
187 | | Comment all except current | ctrl+m, ctrl+q | Method: Comment all except current |
188 | | Uncomment all | ctrl+m, q | Method: Uncomment all |
189 |
190 |
191 | ### Dependencies
192 |
193 | * [Statement](https://github.com/shagabutdinov/sublime-statement)
194 | * [Expression](https://github.com/shagabutdinov/sublime-expression)
195 | * [LocalVariable](https://github.com/shagabutdinov/sublime-local-variable)
--------------------------------------------------------------------------------
/snippets/coffee-method-call-null.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.coffee
8 | Call coffee method (with null)
9 |
--------------------------------------------------------------------------------
/snippets/coffee-method-call.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
5 | source.coffee
6 | Call coffee method
7 |
--------------------------------------------------------------------------------
/snippets/coffee-method.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
4 | $body$0
5 | ]]>
6 | source.coffee
7 | Define method
8 |
--------------------------------------------------------------------------------
/snippets/go-method-call-null.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.go
8 | Call go method (with null)
9 |
--------------------------------------------------------------------------------
/snippets/go-method-call.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
5 | source.go
6 | Call go method
7 |
--------------------------------------------------------------------------------
/snippets/go-method.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.go
8 | Define go method
9 |
--------------------------------------------------------------------------------
/snippets/js-method-call-null.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.js
8 | Call js method (with null)
9 |
--------------------------------------------------------------------------------
/snippets/js-method-call.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
5 | source.js
6 | Call js method
7 |
--------------------------------------------------------------------------------
/snippets/js-method.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.js
8 | Define method
9 |
--------------------------------------------------------------------------------
/snippets/php-method.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.php
8 | Define method
9 |
--------------------------------------------------------------------------------
/snippets/python-method-call-null.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.python
8 | Call python method (with null)
9 |
--------------------------------------------------------------------------------
/snippets/python-method-call.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
5 | source.python
6 | Call python method
7 |
--------------------------------------------------------------------------------
/snippets/python-method.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
6 | source.python
7 | Define python method
8 |
--------------------------------------------------------------------------------
/snippets/ruby-method-call-null.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.ruby
8 | Call ruby method (null result)
9 |
--------------------------------------------------------------------------------
/snippets/ruby-method-call.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
5 | source.ruby
6 | Call ruby method
7 |
--------------------------------------------------------------------------------
/snippets/ruby-method.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | source.ruby
8 | Define ruby method
9 |
--------------------------------------------------------------------------------
/uncomment_bookmarks.sublime-macro:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "args": null,
4 | "command": "set_mark"
5 | },
6 | {
7 | "args": null,
8 | "command": "select_all_bookmarks"
9 | },
10 | {
11 | "args": {"block": false},
12 | "command": "toggle_comment"
13 | },
14 | {
15 | "args": {"block": false},
16 | "command": "toggle_bookmark"
17 | },
18 | {
19 | "command": "next_bookmark",
20 | "args": {"name": "mark"},
21 | },
22 | {
23 | "command": "clear_bookmarks",
24 | "args": {"name": "mark"}
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------