143 lines
2.9 KiB
Python
143 lines
2.9 KiB
Python
#!BPY
|
|
"""
|
|
Name: 'Code Outline | Ctrl T'
|
|
Blender: 246
|
|
Group: 'TextPlugin'
|
|
Shortcut: 'Ctrl+T'
|
|
Tooltip: 'Provides a menu for jumping to class and functions definitions.'
|
|
"""
|
|
|
|
# Only run if we have the required modules
|
|
try:
|
|
import bpy
|
|
from BPyTextPlugin import *
|
|
from Blender import Draw
|
|
except ImportError:
|
|
OK = False
|
|
else:
|
|
OK = True
|
|
|
|
def make_menu(items, eventoffs):
|
|
n = len(items)
|
|
if n < 20:
|
|
return [(items[i], i+1+eventoffs) for i in range(len(items))]
|
|
|
|
letters = []
|
|
check = 'abcdefghijklmnopqrstuvwxyz_' # Names cannot start 0-9
|
|
for c in check:
|
|
for item in items:
|
|
if item[0].lower() == c:
|
|
letters.append(c)
|
|
break
|
|
|
|
entries = {}
|
|
i = 0
|
|
for item in items:
|
|
i += 1
|
|
c = item[0].lower()
|
|
entries.setdefault(c, []).append((item, i+eventoffs))
|
|
|
|
subs = []
|
|
for c in letters:
|
|
subs.append((c, entries[c]))
|
|
|
|
return subs
|
|
|
|
def find_word(txt, word):
|
|
i = 0
|
|
txt.reset()
|
|
while True:
|
|
try:
|
|
line = txt.readline()
|
|
except StopIteration:
|
|
break
|
|
c = line.find(word)
|
|
if c != -1:
|
|
txt.setCursorPos(i, c)
|
|
break
|
|
i += 1
|
|
|
|
def main():
|
|
txt = bpy.data.texts.active
|
|
if not txt:
|
|
return
|
|
|
|
# Identify word under cursor
|
|
if get_context(txt) == CTX_NORMAL:
|
|
line, c = current_line(txt)
|
|
start = c-1
|
|
end = c
|
|
while start >= 0:
|
|
if not line[start].lower() in 'abcdefghijklmnopqrstuvwxyz0123456789_':
|
|
break
|
|
start -= 1
|
|
while end < len(line):
|
|
if not line[end].lower() in 'abcdefghijklmnopqrstuvwxyz0123456789_':
|
|
break
|
|
end += 1
|
|
word = line[start+1:end]
|
|
if word in KEYWORDS:
|
|
word = None
|
|
else:
|
|
word = None
|
|
|
|
script = get_cached_descriptor(txt)
|
|
items = []
|
|
desc = None
|
|
|
|
tmp = script.classes.keys()
|
|
tmp.sort(cmp = suggest_cmp)
|
|
class_menu = make_menu(tmp, len(items))
|
|
class_menu_length = len(tmp)
|
|
items.extend(tmp)
|
|
|
|
tmp = script.defs.keys()
|
|
tmp.sort(cmp = suggest_cmp)
|
|
defs_menu = make_menu(tmp, len(items))
|
|
defs_menu_length = len(tmp)
|
|
items.extend(tmp)
|
|
|
|
tmp = script.vars.keys()
|
|
tmp.sort(cmp = suggest_cmp)
|
|
vars_menu = make_menu(tmp, len(items))
|
|
vars_menu_length = len(tmp)
|
|
items.extend(tmp)
|
|
|
|
menu = [('Script %t', 0),
|
|
('Classes', class_menu),
|
|
('Functions', defs_menu),
|
|
('Variables', vars_menu)]
|
|
if word:
|
|
menu.extend([None, ('Locate', [(word, -10)])])
|
|
|
|
i = Draw.PupTreeMenu(menu)
|
|
if i == -1:
|
|
return
|
|
|
|
# Chosen to search for word under cursor
|
|
if i == -10:
|
|
if script.classes.has_key(word):
|
|
desc = script.classes[word]
|
|
elif script.defs.has_key(word):
|
|
desc = script.defs[word]
|
|
elif script.vars.has_key(word):
|
|
desc = script.vars[word]
|
|
else:
|
|
find_word(txt, word)
|
|
return
|
|
else:
|
|
i -= 1
|
|
if i < class_menu_length:
|
|
desc = script.classes[items[i]]
|
|
elif i < class_menu_length + defs_menu_length:
|
|
desc = script.defs[items[i]]
|
|
elif i < class_menu_length + defs_menu_length + vars_menu_length:
|
|
desc = script.vars[items[i]]
|
|
|
|
if desc:
|
|
txt.setCursorPos(desc.lineno-1, 0)
|
|
|
|
# Check we are running as a script and not imported as a module
|
|
if __name__ == "__main__" and OK:
|
|
main()
|