Was getting rather annoyed that I can’t highlight multiple lines of text and indent/unindent them all at once like you can in Visual Studio Code. Wrote a couple operators that do that, added in some keymaps too so it’s easy to use from the get-go. Ctrl + ] indents the highlighted block, Ctrl + [ unindents it.
Feel free to copy and paste this code
bl_info = {
"name": "Indent Block",
"author": "Fez_Master",
"version": (1, 0),
"blender": (3, 1, 2),
"location": "Text Editor",
"description": "Indent and unindent highlighted block",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "MyAddons"}
import bpy
from bpy_extras import keyconfig_utils
class TEXT_EDITOR_OT_indent_block(bpy.types.Operator):
bl_idname = 'text.indent_block'
bl_label = 'Indent Highlighted Block'
bl_options = {'REGISTER', 'UNDO_GROUPED'}
@classmethod
def poll(cls, context):
return context.area.type == 'TEXT_EDITOR'
def execute(self, context):
ct = bpy.context.edit_text
line_range = [int(ct.current_line_index), int(ct.select_end_line_index)]
charindex = [int(ct.current_character), int(ct.select_end_character)]
if line_range[0] > line_range[1]:
line_range.sort()
charindex.append(charindex[0])
charindex.pop(0)
for i in range(line_range[0], line_range[1] + 1):
ct.cursor_set(i)
ct.write(' ')
ct.cursor_set(line_range[0], character=charindex[0] + 4)
ct.cursor_set(line_range[1], character=charindex[1] + 4, select=True)
return {'FINISHED'}
class TEXT_EDITOR_OT_unindent_block(bpy.types.Operator):
bl_idname = 'text.unindent_block'
bl_label = 'Unindent Highlighted block'
bl_options = {'REGISTER', 'UNDO_GROUPED'}
@classmethod
def poll(cls, context):
return context.area.type == 'TEXT_EDITOR'
def execute(self, context):
ct = bpy.context.edit_text
line_range = [int(ct.current_line_index), int(ct.select_end_line_index)]
charindex = [int(ct.current_character), int(ct.select_end_character)]
if line_range[0] > line_range[1]:
line_range.sort()
charindex.append(charindex[0])
charindex.pop(0)
for i in range(line_range[0], line_range[1] + 1):
if ct.lines[i].body.startswith(' '):
if (i in line_range) and (charindex[line_range.index(i)] < 4):
charindex[line_range.index(i)] = 4
ct.cursor_set(i)
ct.cursor_set(i, character=4, select=True)
ct.write('')
elif (i in line_range) and (charindex[line_range.index(i)] < 4):
charindex[line_range.index(i)] += 4
ct.cursor_set(line_range[0], character=charindex[0] - 4)
ct.cursor_set(line_range[1], character=charindex[1] - 4, select=True)
return {'FINISHED'}
keymap_set = [(
"Text",
{"space_type": 'TEXT_EDITOR', "region_type": 'WINDOW'},
{"items": [
("text.indent_block", {'type': 'RIGHT_BRACKET', 'value': 'PRESS', 'ctrl': True}, None),
("text.unindent_block", {'type': 'LEFT_BRACKET', 'value': 'PRESS', 'ctrl': True}, None),
]})]
def register():
bpy.utils.register_class(TEXT_EDITOR_OT_indent_block)
bpy.utils.register_class(TEXT_EDITOR_OT_unindent_block)
keyconfig_utils.addon_keymap_register(keymap_set)
def unregister():
keyconfig_utils.addon_keymap_unregister(keymap_set)
bpy.utils.unregister_class(TEXT_EDITOR_OT_indent_block)
bpy.utils.unregister_class(TEXT_EDITOR_OT_unindent_block)
if __name__ == '__main__':
register()