I want to insert some text according to a multiline selection in the text editor .
There are some handy attribute that could help, but there’s a critical one missing ! (maybe I dont see something obvious…)
Here is a list if these attributes (in a text datablock D.texts['Text']) :
current_character # character position (at selection character start)
current_line # line object where cursor is (at selection start)
current_line_index # index where cursor is (at selection start)
select_end_character # character position at selection end
select_end_line # line object where selection end
#!! MISSING !! : select_end_line_index (impossible to know where the selection end !)
So it’s Impossible to determine where the selection has stopped at line level.
The only super ugly workaround I see is using bpy.ops.text.copy() and count the ‘\n’ in the clipboard to know how many line were selected…
Is there another way to get this ?
Also, is there a way to set cursor position on line and character ? current_character and such are read_only and the only things I found is moving to the very start/end of line with some ops (bpy.ops.text.move(override, type='LINE_END') but not at specific character position.
def sell_idx(text):
for idx, line in enumerate(text.lines):
if line == text.select_end_line:
return idx
select_end_line_index = sell_idx(text)
If you don’t want to deal with a function: select_end_line_index = text.lines[:].index(text.select_end_line)
Setting cursor can be done by either
bpy.ops.text.cursor_set() or bpy.ops.text.move().
The former takes pixel coordinates and is meant to be used in conjunction with context.space_data.region_location_from_cursor(line, column), the latter requires that you write your own function that moves the cursor to a given position.
I used the latter one because I need the ability to set multi-line selections as well. You can see how I set the cursor and selection in text_toggle_comment.py.
If you just need to set the caret position (no selection), the former involves less code.
import bpy
def run():
st = bpy.context.space_data
index = st.text.lines[:].index
line_index = index(st.text.select_end_line)
x, y = st.region_location_from_cursor(line_index, 0)
# add 10 to y, since there's some misalignment
bpy.ops.text.cursor_set(x=x, y=y + 10)
if __name__ == '__main__':
run()