Skip to content

Commit 9c4f0f0

Browse files
authored
Updated to version 1.7.0
1 parent c170415 commit 9c4f0f0

14 files changed

Lines changed: 884 additions & 258 deletions

__init__.py

Lines changed: 273 additions & 148 deletions
Large diffs are not rendered by default.

blender_manifest.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tagline = "Streamline and Enhance Blender’s Text Editor"
77
maintainer = "Jishnu, kaio <jishnukv661@gmail.com>"
88
type = "add-on"
99

10-
website = "https://github.com/DesignLipsx/Textify/"
10+
website = "https://discord.com/channels/1356442907338608640/1356442907812298752"
1111

1212
tags = ["Text Editor", "Development"]
1313

@@ -27,6 +27,5 @@ wheels = [
2727
]
2828

2929
[permissions]
30-
network = "Download and install Python modules for script formatting"
3130
files = "Read/write settings, and manage scripts on disk"
3231
clipboard = "Copy class bl_idname and identifiers to clipboard"

default_preferences.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"show_code_filters": true,
2020
"code_map_popup_width": 320,
2121
"auto_activate_find": false,
22+
"use_textify_find_replace": true,
23+
"realtime_search": true,
24+
"enable_find_on_enter": true,
2225
"highlight_mode": "FIND_TEXT",
2326
"case_sensitive": false,
2427
"show_in_scroll": true,
@@ -43,7 +46,7 @@
4346
],
4447
"scroll_horiz_pos": 0.0,
4548
"scroll_marker_length": 6.0,
46-
"recent_data_path": "C:\\Users\\Jithu\\AppData\\Roaming\\Blender Foundation\\Blender\\4.3\\config",
49+
"recent_data_path": "C:\\Users\\jishn\\AppData\\Roaming\\Blender Foundation\\Blender\\4.3\\config",
4750
"show_open_recent_panel": true,
4851
"show_folder_name": true,
4952
"max_entries": 30,
@@ -207,4 +210,4 @@
207210
]
208211
}
209212
]
210-
}
213+
}

icons/gumroad.png

3.85 KB
Loading

keymap.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,11 @@ def unregister_keymap():
208208
for km, kmi in keys:
209209
km.keymap_items.remove(kmi)
210210
keys.clear()
211+
212+
213+
def register():
214+
register_keymap()
215+
216+
217+
def unregister():
218+
unregister_keymap()

textify_icons.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1+
import atexit
12
from pathlib import Path
23
from bpy.utils import previews
34

45
_custom_icons = None
56

7+
68
def load_icons():
79
global _custom_icons
810
if _custom_icons is None:
911
_custom_icons = previews.new()
1012

1113
icons_dir = Path(__file__).resolve().parent / "icons"
1214
for icon_file in icons_dir.glob("*.png"):
13-
icon_name = icon_file.stem # filename without extension
15+
icon_name = icon_file.stem
1416
if icon_name not in _custom_icons:
1517
_custom_icons.load(icon_name, str(icon_file), 'IMAGE')
1618

@@ -24,5 +26,17 @@ def unload_icons():
2426

2527
def get_icon(name):
2628
if _custom_icons is None:
27-
load_icons()
28-
return _custom_icons.get(name)
29+
return None
30+
icon = _custom_icons.get(name)
31+
return icon.icon_id if icon else None
32+
33+
34+
atexit.register(unload_icons)
35+
36+
37+
def register():
38+
load_icons()
39+
40+
41+
def unregister():
42+
load_icons()

tools/__init__.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,51 @@
11
if "bpy" in locals():
22
import importlib
3-
importlib.reload(addon_installer)
43
importlib.reload(bookmark_line)
54
importlib.reload(convert_case)
65
importlib.reload(character_count)
76
importlib.reload(code_map)
87
importlib.reload(find_replace)
8+
importlib.reload(go_to_definition)
99
importlib.reload(highlight_occurrences)
1010
importlib.reload(jump_to_line)
1111
importlib.reload(reveal_in_explorer)
1212
importlib.reload(trim_whitespace)
1313
importlib.reload(script_formatter)
14+
importlib.reload(script_switcher)
1415
importlib.reload(open_recent)
16+
importlib.reload(addon_installer)
1517
else:
16-
from . import addon_installer
1718
from . import bookmark_line
1819
from . import convert_case
1920
from . import character_count
2021
from . import code_map
2122
from . import find_replace
23+
from . import go_to_definition
2224
from . import highlight_occurrences
2325
from . import jump_to_line
2426
from . import reveal_in_explorer
2527
from . import trim_whitespace
2628
from . import script_formatter
29+
from . import script_switcher
2730
from . import open_recent
28-
import bpy
31+
from . import addon_installer
2932

3033

3134
submodules = [
32-
open_recent,
33-
addon_installer,
3435
bookmark_line,
3536
convert_case,
3637
character_count,
3738
code_map,
3839
find_replace,
40+
go_to_definition,
3941
highlight_occurrences,
4042
jump_to_line,
43+
open_recent,
4144
reveal_in_explorer,
4245
script_formatter,
46+
script_switcher,
4347
trim_whitespace,
48+
addon_installer,
4449
]
4550

4651

tools/addon_installer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ def draw_menu(self, context):
739739

740740
layout = self.layout
741741
layout.separator()
742-
layout.operator("textify.install_addon_popup", text=label)
742+
layout.operator("textify.install_addon_popup", text=label, icon='IMPORT')
743743

744744

745745
# -------------------------------------------------------------

tools/code_map.py

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def __init__(self):
5858
self.CLASS_PATTERN = re.compile(r'^\s*class\s+(\w+)\s*[\(:]')
5959
self.FUNCTION_PATTERN = re.compile(r'^\s*def\s+(\w+)\s*\(')
6060
self.PROPERTY_PATTERN = re.compile(r'^\s*([\w]+)\s*:\s*[\w\[\]]+')
61+
self.BLENDER_PROPERTY_PATTERN = re.compile(r'^\s*(\w+)\s*:\s*\w*Property\s*\(')
6162
self.VARIABLE_PATTERN = re.compile(
6263
r'^\s*([A-Z_][A-Z0-9_]*|[a-zA-Z_]\w*)\s*=\s*')
6364
self.CONSTANT_PATTERN = re.compile(r'^\s*([A-Z_][A-Z0-9_]*)\s*=')
@@ -238,7 +239,12 @@ def _parse_line(self, line, line_num, indent, parent_type=None, full_line=""):
238239
'class', 'function'} else 'function'
239240
return CodeItem(m.group(1), kind, line_num, indent)
240241

241-
# Property parsing
242+
# Property parsing - Check for Blender properties first
243+
m = self.patterns.BLENDER_PROPERTY_PATTERN.match(line)
244+
if m:
245+
return CodeItem(m.group(1), 'property', line_num, indent)
246+
247+
# Standard property parsing (type annotations)
242248
m = self.patterns.PROPERTY_PATTERN.match(line)
243249
if m and ':' in line and not line.startswith('#') and '=' not in line:
244250
return CodeItem(m.group(1), 'property', line_num, indent)
@@ -329,7 +335,6 @@ class CODE_MAP_OT_jump_to_line(Operator):
329335

330336
def invoke(self, context, event):
331337
clipboard_helper = ClipboardHelper()
332-
333338
if event.ctrl:
334339
if self.item_type == 'class' and self.item_bl_idname:
335340
clipboard_helper.copy_to_clipboard(self.item_bl_idname)
@@ -362,27 +367,63 @@ def _select_code_block(self, context):
362367
if not text:
363368
return
364369

370+
# Jump to the starting line
365371
bpy.ops.text.jump(line=self.line_number)
366372
bpy.ops.text.move(type='LINE_BEGIN')
367373

368374
start_line_index = self.line_number - 1
369-
end_line_index = min(self.item_end_line - 1, len(text.lines) - 1)
370-
375+
end_line_index = self.item_end_line - 1 if self.item_end_line else start_line_index
376+
377+
# If no end line was provided, try to find the end of the block automatically
378+
if not self.item_end_line:
379+
start_line = text.lines[start_line_index].body
380+
# Check for opening brackets
381+
if '{' in start_line or '[' in start_line:
382+
open_char = '{' if '{' in start_line else '['
383+
close_char = '}' if open_char == '{' else ']'
384+
open_count = start_line.count(open_char) - start_line.count(close_char)
385+
386+
# Search forward for matching closing bracket
387+
end_line_index = start_line_index
388+
while end_line_index < len(text.lines) and open_count > 0:
389+
end_line_index += 1
390+
if end_line_index < len(text.lines):
391+
line = text.lines[end_line_index].body
392+
open_count += line.count(open_char) - line.count(close_char)
393+
394+
# If we found a matching closing bracket, use that as the end
395+
if open_count == 0 and end_line_index < len(text.lines):
396+
self.item_end_line = end_line_index + 1
397+
else:
398+
end_line_index = start_line_index
399+
400+
# Clamp the end line index to valid range
401+
end_line_index = min(end_line_index, len(text.lines) - 1)
402+
403+
# Find the actual last non-empty line in the block
404+
actual_end_line = end_line_index
405+
while actual_end_line > start_line_index:
406+
line_content = text.lines[actual_end_line].body.strip()
407+
if line_content: # Found non-empty line
408+
break
409+
actual_end_line -= 1
410+
411+
# Calculate selection columns
371412
if start_line_index < len(text.lines):
372413
start_line_body = text.lines[start_line_index].body
373414
start_column = len(start_line_body) - len(start_line_body.lstrip())
374415
else:
375416
start_column = 0
376417

377-
end_column = len(text.lines[end_line_index].body) if end_line_index < len(
378-
text.lines) else 0
418+
end_column = len(text.lines[actual_end_line].body) if actual_end_line < len(text.lines) else 0
379419

380-
if self.line_number == self.item_end_line:
381-
text.select_set(start_line_index, start_column, start_line_index, len(
382-
text.lines[start_line_index].body))
420+
# Set the selection
421+
if start_line_index == actual_end_line:
422+
text.select_set(start_line_index, start_column,
423+
start_line_index, len(text.lines[start_line_index].body))
383424
else:
384425
text.select_set(start_line_index, start_column,
385-
end_line_index, end_column)
426+
actual_end_line, end_column)
386427

387428
context.area.tag_redraw()
388429

@@ -494,8 +535,7 @@ def draw_code_item(self, layout, item, level=0, nav_state=None, active_class=Non
494535

495536
# Icon + operator
496537
icon_name = 'constant' if item.item_type == 'constant' else item.item_type
497-
icon = textify_icons.get_icon(icon_name)
498-
icon_id = icon.icon_id if icon else 0
538+
icon_id = textify_icons.get_icon(icon_name) or 0
499539
sub = row.row(align=True)
500540
sub.alignment = 'LEFT'
501541

@@ -582,8 +622,9 @@ def _draw_toggle_filter_row(layout, nav_data):
582622
"show_properties", "show_variables", "show_constants"]
583623

584624
for prop, icon_name in zip(props, icons):
585-
icon = textify_icons.get_icon(icon_name)
586-
icon_id = icon.icon_id if icon else 0
625+
icon_id = textify_icons.get_icon(icon_name)
626+
if icon_id is None:
627+
icon_id = 0
587628
row.prop(nav_data, prop, toggle=True, text="", icon_value=icon_id)
588629

589630

0 commit comments

Comments
 (0)