· 6 years ago · Oct 08, 2019, 04:56 AM
1# ***** BEGIN GPL LICENSE BLOCK *****
2#
3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License
6# as published by the Free Software Foundation; either version 2
7# of the License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software Foundation,
16# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17#
18# ***** END GPL LICENCE BLOCK *****
19
20bl_info = {
21 "name": "Intellisense for Text Editor",
22 "author": "Mackraken",
23 "version": (0, 3),
24 "blender": (2, 80, 0),
25 "api": 41851,
26 "location": "Ctrl + Space at Text Editor",
27 "description": "Adds intellense to the Text Editor",
28 "warning": "Only works with 2.57 intellisense",
29 "wiki_url": "",
30 "tracker_url": "",
31 "category": "Text Editor"}
32
33import bpy
34
35def enabled(self, context):
36 enable = context.scene.use_intellisense
37
38 if enable:
39 conf = context.window_manager.keyconfigs.active
40 map = conf.keymaps['Text']
41 found1 = False
42 found2 = False
43 for key in map.keymap_items:
44 if key.name == "Line Break" and key.type=="RET":
45 if key.idname != "text.test_line":
46 key.idname = "text.test_line"
47 found1 = True
48 if key.name == "Text Editor Intellisense":
49 found2 = True
50 if not found2:
51 key = map.keymap_items.new(idname = "text.intellisense", type = "i", ctrl=True, value = "PRESS")
52
53
54bpy.types.Scene.use_intellisense = bpy.props.BoolProperty(name= "Enabled", default = False, update = enabled)
55
56def complete(context):
57 from console import intellisense
58 from console_python import get_console
59
60 sc = context.space_data
61 text = sc.text
62
63 region = context.region
64 for area in context.screen.areas:
65 if area.type=="CONSOLE":
66 region = area.regions[1]
67 break
68
69 console = get_console(hash(region))[0]
70
71 line = text.current_line.body
72 cursor = text.current_character
73
74 result = intellisense.expand(line, cursor, console.locals, bpy.app.debug)
75
76 return result
77
78
79class TEXT_MT_intellimenu(bpy.types.Menu):
80 bl_label = ""
81 bl_idname = "intelliMenu"
82
83 text = ""
84
85 def draw(self, context):
86 layout = self.layout
87 #Very ugly see how can i fix this
88 options = complete(context)
89
90 options = options[2].split(" ")
91 for op in options:
92 layout.operator("text.intellioptions", text=op).text=op
93
94#This operator executes when hits Ctrl+Space at the text editor
95
96class Intellisense(bpy.types.Operator):
97 #'''Tooltip'''
98 bl_idname = "text.intellisense"
99 bl_label = "Text Editor Intellisense"
100
101 text = ""
102
103# @classmethod
104# def poll(cls, context):
105# return context.active_object is not None
106
107 def execute(self, context):
108 sc = context.space_data
109 text = sc.text
110
111 if text.current_character>0:
112 result = complete(context)
113
114 #print(result)
115
116 if result[2]=="":
117 text.current_line.body = result[0]
118 bpy.ops.text.move(type='LINE_END')
119 else:
120 bpy.ops.wm.call_menu(name=TEXT_MT_intellimenu.bl_idname)
121
122 return {'FINISHED'}
123
124#this operator completes the line with the options you choose from the menu
125class Intellioptions(bpy.types.Operator):
126 #'''Tooltip'''
127 bl_idname = "text.intellioptions"
128 bl_label = "Intellisense options"
129
130 text: bpy.props.StringProperty()
131
132 @classmethod
133 def poll(cls, context):
134 return context.active_object is not None
135
136 def execute(self, context):
137 sc = context.space_data
138 text = sc.text
139
140 comp = self.text
141 line = text.current_line.body
142
143 lline = len(line)
144 lcomp = len(comp)
145
146 #intersect text
147 intersect = [-1,-1]
148
149 for i in range(lcomp):
150 val1 = comp[0:i+1]
151
152 for j in range(lline):
153 val2 = line[lline-j-1::]
154 #print(" ",j, val2)
155
156 if val1==val2:
157 intersect = [i, j]
158 break
159
160 if intersect[0]>-1:
161 newline = line[0:lline-intersect[1]-1]+comp
162 else:
163 newline = line + comp
164
165 #print(newline)
166 text.current_line.body = newline
167
168 bpy.ops.text.move(type='LINE_END')
169
170
171 return {'FINISHED'}
172
173def send_console(context, all=0):
174
175 sc = context.space_data
176 text = sc.text
177
178 console = None
179
180 for area in bpy.context.screen.areas:
181 if area.type=="CONSOLE":
182 from console_python import get_console
183
184 console = get_console(hash(area.regions[1]))[0]
185
186 if console==None:
187 return {'FINISHED'}
188
189 lines = []
190
191 if all:
192 lines = text.lines
193 else:
194 lines = [text.current_line]
195
196 space = " "
197 tab = " "
198
199 for l in lines:
200 line = l.body
201 if "=" in line:
202 var = line.split("=")
203 if not "." in var[0] and var[1]!="":
204 print("push "+line)
205 while line[0]==space or line[0]==tab:
206 line = line[1::]
207
208 try:
209 console.push(line)
210 except:
211 pass
212 else:
213 print("not processed")
214 elif "import" in line:
215 console.push(line)
216 else:
217 print("not processed")
218
219
220
221
222class TestLine(bpy.types.Operator):
223 #'''Tooltip'''
224 bl_idname = "text.test_line"
225 bl_label = "Test line"
226
227 all: bpy.props.IntProperty(default = False)
228
229# @classmethod
230# def poll(cls, context):
231# return context.active_object is not None
232
233 def execute(self, context):
234 #print("test line")
235 all = self.all
236 if context.scene.use_intellisense:
237
238 sc = context.space_data
239 text = sc.text
240
241 send_console(context, all)
242
243 if not all:
244 bpy.ops.text.line_break()
245
246
247 return {'FINISHED'}
248
249
250class SetBreakPoint(bpy.types.Operator):
251 bl_idname = "text.set_breakpoint"
252 bl_label = "Set Breakpoint"
253
254 def execute(self, context):
255
256 sc = bpy.context.space_data
257 text = sc.text
258
259 line = text.current_line
260 br = " #breakpoint"
261 print(line.body.find(br))
262 if line.body.find(br)>-1:
263
264 line.body = line.body.replace(br, "")
265 else:
266
267 line.body += br
268
269 return {'FINISHED'}
270
271
272class Debug(bpy.types.Operator):
273 bl_idname = "text.debug"
274 bl_label = "Debug"
275
276 def execute(self, context):
277
278 binpath = bpy.app.binary_path
279
280 addonspath = binpath[0:binpath.rindex("\\")+1]+str(bpy.app.version[0])+"."+str(bpy.app.version[1])+"\\scripts\\addons\\"
281
282 print(addonspath)
283
284 sc = context.space_data
285 text = sc.text
286
287 br = " #breakpoint"
288
289 filepath = addonspath+"debug.py"
290 file = open(filepath, "w")
291 file.write("import pdb\n")
292
293 for line in text.lines:
294 l = line.body
295
296 if line.body.find(br)>-1:
297 indent = ""
298 for letter in line.body:
299
300 if not letter.isalpha():
301 indent+=letter
302 else:
303 break
304 file.write(l[0:-len(br)]+"\n")
305
306 file.write(indent+"pdb.set_trace()\n")
307
308 else:
309 file.write(line.body+"\n")
310
311
312
313 file.close()
314
315 import pdb
316 import debug
317
318 pdb.runcall("debug")
319
320
321 return {'FINISHED'}
322
323
324class IntellisensePanel(bpy.types.Panel):
325 bl_label = "Intellisense"
326 bl_idname = "text.test_line"
327 bl_space_type = "TEXT_EDITOR"
328 bl_region_type = "UI"
329 #bl_context = "object"
330
331 text: bpy.props.StringProperty()
332
333 def draw(self, context):
334 layout = self.layout
335 row = layout.row()
336 text = self.text
337
338 row = layout.row()
339 row.prop(context.scene, "use_intellisense")
340 layout.operator("text.intellisense", text ="Intellisense")
341 row = layout.row()
342 row.operator("text.debug", text ="Debug")
343 row = layout.row()
344 row.operator("text.set_breakpoint")
345 row = layout.row()
346 row.operator("text.test_line").all=False
347 row = layout.row()
348 row.operator("text.test_line", text ="Test All").all=True
349
350
351classes = [Intellisense, Intellioptions, TEXT_MT_intellimenu, IntellisensePanel, TestLine, SetBreakPoint, Debug]
352
353def register():
354
355 for c in classes:
356 bpy.utils.register_class(c)
357
358
359def unregister():
360 for c in classes:
361 bpy.utils.unregister_class(c)
362
363if __name__ == "__main__":
364 register()