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$ Commented Nov 6, 2015 at 16:51
  • 1
    $\begingroup$ Well, it seems it does.. $\endgroup$ Commented Nov 6, 2015 at 21:12
  • $\begingroup$ @pinkvertex That looks perfect! Do you plan on submitting this for inclusion in master? $\endgroup$
    – gandalf3
    Commented Nov 7, 2015 at 1:56
  • $\begingroup$ I submitted a diff. $\endgroup$ Commented Nov 9, 2015 at 10:57

1 Answer 1


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
    Commented Nov 6, 2015 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
    Commented Nov 6, 2015 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
    Commented Nov 6, 2015 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
    Commented Nov 6, 2015 at 20:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .