Using a draw callback
Investigated a few ways to do this for an edit with vim addon I put togeter. In the end didn't go with any,
My first choice would be using the loophole in the draw callback that lets us manipulate properties, which you cannot do from a draw method. The red lifesaver on text editor header is drawn when text and text.is_modified
. I have left in the reload method I use, however it doesn't update the text.is_modified
. I've used the reload operator instead for this question. (intead I use os
to keep tabs on file modified time)
If the test script below is run from blender text editor it will add the draw callback. To use from an addon or such, would import the class and instance it, that way it can be removed, or stopped by calling instance.remove_handle()
. An update on a boolean property to turn on and off could be another alternative
The script.
import bpy
def reload(text):
fp = bpy.path.abspath(text.filepath)
text.clear()
with open(fp) as f:
text.write(f.read())
return False
class DrawingClass:
lock = False
def __init__(self, context, prop):
self.prop = prop
self.handle = bpy.types.SpaceTextEditor.draw_handler_add(
self.draw_text_callback,(context,),
'WINDOW', 'POST_PIXEL')
def draw_text_callback(self, context):
if self.lock:
return
space = context.space_data
text = space.text
if text and text.is_modified: # if is_modified(text):
print("reloading text")
bpy.ops.text.reload()
'''
self.lock + True
self.lock = reload(text)
'''
def remove_handle(self):
bpy.types.SpaceTextEditor.draw_handler_remove(self.handle, 'WINDOW')
if __name__ == "__main__":
context = bpy.context
dc = DrawingClass(context, "Draw This On Screen")
Other approaches worth considering:
A modal timer operator. See text editor > templates > python > Operator Modal Timer
. The issue here is that while a modal timer is running, you may be turning off auto-save.
A scene update handler. (IMO a pita, as it runs toooooo often)