# Global keyboard shortcut to execute text editor script

How do I create a global keyboard shortcut that executes the script currently in the text editor?

I say global because I would like to be working in the default 3D View (no text editor displayed) and simply press a key to execute the script. This would avoid me needing to change to the script layout, run the script, return to 3d View every time.

Alt + P only seems to work when the text editor is focused.

In User preferences->Input, I tried adding a new "Run Script" event ('text.run_script') to the Window (Global) section and assigned it a key, but the console reports 'event has invalid window'.

• i think it's possible to set global keyboard shortcuts, and also write an operator that can run a script, but the problem could be that if you have multiple text blocks, how is it going to choose which to execute if no text editors are open? -- unless the operator always looks for Textblocks with a certain name or prefix – zeffii Jul 29 '15 at 6:18
• you wouldn't need to set up a global shortcut for this, an operator bound to a shortcut for 3d view might make more sense. – zeffii Jul 29 '15 at 6:40
• there is an addon called script runner you load multiple files and run the one you want – Chebhou Jul 29 '15 at 6:55
• I wasn't aware of script runner addon, but it totally makes sense if that exists already! – zeffii Jul 29 '15 at 7:03

If you are only going to re-executing this script when 3D View is open you might add the shortcut to 3D View (global). I propose a different shortcut as alt+p is for showing the 'clear parent' menu, but it's up to you.

At the end of this list..

generic_executor.py

# something to test with..
import bpy
import random

x = random.randint(-6, 6)
y = random.randint(-6, 6)
z = random.randint(-6, 6)



operator.py

import bpy

class GlobalScriptRunner(bpy.types.Operator):
"""Tooltip"""
bl_idname = "view3d.global_script_runner"
bl_label = "Global Script Runner"

#@classmethod
#def poll(cls, context):
#    return context.active_object is not None

def execute(self, context):
print('i get called')
textblock_name = 'generic_executor.py'
textblock_as_string = bpy.data.texts[textblock_name].as_string()
exec(textblock_as_string)
return {'FINISHED'}

def register():
bpy.utils.register_class(GlobalScriptRunner)

def unregister():
bpy.utils.unregister_class(GlobalScriptRunner)

if __name__ == "__main__":
register()


To wrap this into a reusable add-on requires more time than I have, but it's not the purpose of this answer. The benefit of having this as an addon would be that you could create a panel for 3dview in which you can type or select a textblock to be executed when the shortcut is triggered, rather than this hard coded suggestion, where it only executes a textblock named generic_executor.py

edit:

Here's something you could use as a starting point, it creates a panel in 3dview (right side panel) and allows you to pick a textblock. Whenever you trigger the operator view3d.global_script_runner , it would look at the name of the selected file and execute it.

https://gist.github.com/zeffii/2b488961226ee1ecefcf

• I have the time can I try to write this ? – Chebhou Jul 29 '15 at 6:57
• @zeffii Thanks for such a comprehensive answer. I haven't had a chance to try it out yet. I'll let you know how I get on. – Ash Jul 29 '15 at 8:14
• this eliminates the need for overriding the context ! – Chebhou Jul 29 '15 at 11:11
• yeah, but exec might be slower on complex scripts ( i vaguely recall reading about this..but can't pinpoint where) -- unless that's exactly what's called behind the run operator... :) – zeffii Jul 30 '15 at 12:39
• – Samoth Feb 26 '16 at 10:07