I found bpy.ops.text.set_cursor(), which looks like what I want, however it always sets the cursor to the end of the file.

import bpy

class CommentLineOperator(bpy.types.Operator):
    bl_idname = 'text.comment_line'
    bl_label = 'Comment a line'

    def execute(self, context):
        t = bpy.context.space_data.text
        cursor_x = t.current_character
        cursor_y = t.current_line_index

        if t.select_end_line != t.current_line:
            # if there is a selection already, use default behavior:

            print(cursor_x, cursor_y)
#            bpy.ops.text.cursor_set(x=cursor_x, y=cursor_y)
            bpy.ops.text.cursor_set(x=0, y=0)

        return {'FINISHED'}

def register():

def unregister():

if __name__ == "__main__":

Running the above in the text editor and assigning the newly created text.comment_line operator to a shortcut and subsequently using that shortcut in the text editor will comment the line, then move the cursor to the end of the file even when I manually specify position 0,0.

How can I move the cursor in the text editor properly?

  • 1
    $\begingroup$ cursor_set is used on mouse clicks and invoked with region xy coordinates not line/character - i think there is no operator or api function to do that - the functions are already there. You might ask a blender dev to add it. Btw this is a (incomplete?) patch i wrote in july. Don't know if it works. $\endgroup$ – pink vertex Nov 6 '15 at 16:51
  • 1
    $\begingroup$ Well, it seems it does.. $\endgroup$ – pink vertex Nov 6 '15 at 21:12
  • $\begingroup$ @pinkvertex That looks perfect! Do you plan on submitting this for inclusion in master? $\endgroup$ – gandalf3 Nov 7 '15 at 1:56
  • $\begingroup$ I submitted a diff. $\endgroup$ – pink vertex Nov 9 '15 at 10:57

Yep, cursor_set appears to use a mix of 'space_data.top' and 'space_data.visible_lines' and is a might confusing. However you can use


Will move the cursor to the beginning of line 1


moves to the first word in in line 10, where you would add a comment #

  • $\begingroup$ I'm attempting to put the cursor back were it was before the operator was called. Repeatedly calling text.move(type='NEXT_CHARACTER') seems to work when commenting, but oddly enough not when uncommenting..? (code). Do you know how to properly use set_cursor()? Or perhaps why text.move(type='NEXT_CHARACTER') doesn't work as expected? $\endgroup$ – gandalf3 Nov 6 '15 at 8:17
  • $\begingroup$ I'd work with 'FIRST_WORD' as a starting point, and then work with x as though python wasn't indented. You know the cursor location where you were before operation, and you've either added one or removed one. Move by words until you find the range, then by characters. Will do a grep on set_cursor to try and find how it works. It appears to jump to top + visible_lines and takes no notice of x and y. I recall something similar on BA in the deep recess of the back of my mind. $\endgroup$ – batFINGER Nov 6 '15 at 12:12
  • $\begingroup$ ie index by line, word, character in most cases the cursor will be at, for instance, line 3, word 3, character 4 after the operation too. $\endgroup$ – batFINGER Nov 6 '15 at 12:21
  • $\begingroup$ In some cases 'NEXT_CHARACTER' seems to jump 10 extra characters, but it's not consistent. Sometimes it doesn't jump any extra, and sometimes it only jumps a few extra. It works without issue in in the comment_line operator, but does all kinds of weirdness in the uncomment_line operator. I can't see what the difference is.. $\endgroup$ – gandalf3 Nov 6 '15 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.