Last active
September 19, 2019 14:36
-
-
Save tin2tin/7c5859e60f2d6ce1274c68822ef9d57c to your computer and use it in GitHub Desktop.
Intellisense for Blender Text Editor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ***** BEGIN GPL LICENSE BLOCK ***** | |
# | |
# | |
# This program is free software; you can redistribute it and/or | |
# modify it under the terms of the GNU General Public License | |
# as published by the Free Software Foundation; either version 2 | |
# of the License, or (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software Foundation, | |
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
# | |
# ***** END GPL LICENCE BLOCK ***** | |
bl_info = { | |
"name": "Intellisense for Text Editor", | |
"author": "Mackraken", | |
"version": (0, 3), | |
"blender": (2, 80, 0), | |
"api": 41851, | |
"location": "Ctrl + Space at Text Editor", | |
"description": "Adds intellense to the Text Editor", | |
"warning": "Only works with 2.57 intellisense", | |
"wiki_url": "", | |
"tracker_url": "", | |
"category": "Text Editor"} | |
import bpy | |
def enabled(self, context): | |
enable = context.scene.use_intellisense | |
if enable: | |
conf = context.window_manager.keyconfigs.active | |
map = conf.keymaps['Text'] | |
found1 = False | |
found2 = False | |
for key in map.keymap_items: | |
if key.name == "Line Break" and key.type=="RET": | |
if key.idname != "text.test_line": | |
key.idname = "text.test_line" | |
found1 = True | |
if key.name == "Text Editor Intellisense": | |
found2 = True | |
if not found2: | |
key = map.keymap_items.new(idname = "text.intellisense", type = "i", ctrl=True, value = "PRESS") | |
bpy.types.Scene.use_intellisense = bpy.props.BoolProperty(name= "Enabled", default = False, update = enabled) | |
def complete(context): | |
from console import intellisense | |
from console_python import get_console | |
sc = context.space_data | |
text = sc.text | |
region = context.region | |
for area in context.screen.areas: | |
if area.type=="CONSOLE": | |
region = area.regions[1] | |
break | |
console = get_console(hash(region))[0] | |
line = text.current_line.body | |
cursor = text.current_character | |
result = intellisense.expand(line, cursor, console.locals, bpy.app.debug) | |
return result | |
class TEXT_MT_intellimenu(bpy.types.Menu): | |
bl_label = "" | |
bl_idname = "intelliMenu" | |
text = "" | |
def draw(self, context): | |
layout = self.layout | |
#Very ugly see how can i fix this | |
options = complete(context) | |
options = options[2].split(" ") | |
for op in options: | |
layout.operator("text.intellioptions", text=op).text=op | |
#This operator executes when hits Ctrl+Space at the text editor | |
class Intellisense(bpy.types.Operator): | |
#'''Tooltip''' | |
bl_idname = "text.intellisense" | |
bl_label = "Text Editor Intellisense" | |
text = "" | |
# @classmethod | |
# def poll(cls, context): | |
# return context.active_object is not None | |
def execute(self, context): | |
sc = context.space_data | |
text = sc.text | |
if text.current_character>0: | |
result = complete(context) | |
#print(result) | |
if result[2]=="": | |
text.current_line.body = result[0] | |
bpy.ops.text.move(type='LINE_END') | |
else: | |
bpy.ops.wm.call_menu(name=TEXT_MT_intellimenu.bl_idname) | |
return {'FINISHED'} | |
#this operator completes the line with the options you choose from the menu | |
class Intellioptions(bpy.types.Operator): | |
#'''Tooltip''' | |
bl_idname = "text.intellioptions" | |
bl_label = "Intellisense options" | |
text: bpy.props.StringProperty() | |
@classmethod | |
def poll(cls, context): | |
return context.active_object is not None | |
def execute(self, context): | |
sc = context.space_data | |
text = sc.text | |
comp = self.text | |
line = text.current_line.body | |
lline = len(line) | |
lcomp = len(comp) | |
#intersect text | |
intersect = [-1,-1] | |
for i in range(lcomp): | |
val1 = comp[0:i+1] | |
for j in range(lline): | |
val2 = line[lline-j-1::] | |
#print(" ",j, val2) | |
if val1==val2: | |
intersect = [i, j] | |
break | |
if intersect[0]>-1: | |
newline = line[0:lline-intersect[1]-1]+comp | |
else: | |
newline = line + comp | |
#print(newline) | |
text.current_line.body = newline | |
bpy.ops.text.move(type='LINE_END') | |
return {'FINISHED'} | |
def send_console(context, all=0): | |
sc = context.space_data | |
text = sc.text | |
console = None | |
for area in bpy.context.screen.areas: | |
if area.type=="CONSOLE": | |
from console_python import get_console | |
console = get_console(hash(area.regions[1]))[0] | |
if console==None: | |
return {'FINISHED'} | |
lines = [] | |
if all: | |
lines = text.lines | |
else: | |
lines = [text.current_line] | |
space = " " | |
tab = " " | |
for l in lines: | |
line = l.body | |
if "=" in line: | |
var = line.split("=") | |
if not "." in var[0] and var[1]!="": | |
print("push "+line) | |
while line[0]==space or line[0]==tab: | |
line = line[1::] | |
try: | |
console.push(line) | |
except: | |
pass | |
else: | |
print("not processed") | |
elif "import" in line: | |
console.push(line) | |
else: | |
print("not processed") | |
class TestLine(bpy.types.Operator): | |
#'''Tooltip''' | |
bl_idname = "text.test_line" | |
bl_label = "Test line" | |
all: bpy.props.IntProperty(default = False) | |
# @classmethod | |
# def poll(cls, context): | |
# return context.active_object is not None | |
def execute(self, context): | |
#print("test line") | |
all = self.all | |
if context.scene.use_intellisense: | |
sc = context.space_data | |
text = sc.text | |
send_console(context, all) | |
if not all: | |
bpy.ops.text.line_break() | |
return {'FINISHED'} | |
class SetBreakPoint(bpy.types.Operator): | |
bl_idname = "text.set_breakpoint" | |
bl_label = "Set Breakpoint" | |
def execute(self, context): | |
sc = bpy.context.space_data | |
text = sc.text | |
line = text.current_line | |
br = " #breakpoint" | |
print(line.body.find(br)) | |
if line.body.find(br)>-1: | |
line.body = line.body.replace(br, "") | |
else: | |
line.body += br | |
return {'FINISHED'} | |
class Debug(bpy.types.Operator): | |
bl_idname = "text.debug" | |
bl_label = "Debug" | |
def execute(self, context): | |
binpath = bpy.app.binary_path | |
addonspath = binpath[0:binpath.rindex("\\")+1]+str(bpy.app.version[0])+"."+str(bpy.app.version[1])+"\\scripts\\addons\\" | |
print(addonspath) | |
sc = context.space_data | |
text = sc.text | |
br = " #breakpoint" | |
filepath = addonspath+"debug.py" | |
file = open(filepath, "w") | |
file.write("import pdb\n") | |
for line in text.lines: | |
l = line.body | |
if line.body.find(br)>-1: | |
indent = "" | |
for letter in line.body: | |
if not letter.isalpha(): | |
indent+=letter | |
else: | |
break | |
file.write(l[0:-len(br)]+"\n") | |
file.write(indent+"pdb.set_trace()\n") | |
else: | |
file.write(line.body+"\n") | |
file.close() | |
import pdb | |
import debug | |
pdb.runcall("debug") | |
return {'FINISHED'} | |
class IntellisensePanel(bpy.types.Panel): | |
bl_label = "Intellisense" | |
bl_idname = "text.test_line" | |
bl_space_type = "TEXT_EDITOR" | |
bl_region_type = "UI" | |
#bl_context = "object" | |
text: bpy.props.StringProperty() | |
def draw(self, context): | |
layout = self.layout | |
row = layout.row() | |
text = self.text | |
row = layout.row() | |
row.prop(context.scene, "use_intellisense") | |
layout.operator("text.intellisense", text ="Intellisense") | |
row = layout.row() | |
row.operator("text.debug", text ="Debug") | |
row = layout.row() | |
row.operator("text.set_breakpoint") | |
row = layout.row() | |
row.operator("text.test_line").all=False | |
row = layout.row() | |
row.operator("text.test_line", text ="Test All").all=True | |
classes = [Intellisense, Intellioptions, TEXT_MT_intellimenu, IntellisensePanel, TestLine, SetBreakPoint, Debug] | |
def register(): | |
for c in classes: | |
bpy.utils.register_class(c) | |
def unregister(): | |
for c in classes: | |
bpy.utils.unregister_class(c) | |
if __name__ == "__main__": | |
register() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment