Execute Text in Terminal
22 May 2006
Most of the code I've written in the last few years has either been in MATLAB or Python, and both languages have interactive shells. As a result, the way I typically work is to write a few lines of code in my editor and then execute them in the shell to check the results. This is a great way to work if you're doing scientific computing because it's important to know what your data looks like at every stage. But I find myself copying and pasting between my editor and the shell all day long, which takes 3 keystrokes for every text selection: command-c, command-tab, command-v. Using the scripts here, this process can be streamlined.
Updated for OS X 10.5 (3/2009)
TextWrangler has great scripting capabilities with its UNIX filter, UNIX script, and AppleScript support. In addition, you can assign keystrokes that will execute a script on the current selection. That is the mechanism I will use to get my code from TextWrangler to the Terminal.
In OS X 10.5 Leopard, I can send text to the Terminal by invoking the “do script” command in Applescript. Here is the script, which you can save as “Execute Text.scpt” in ~/Library/Application Support/TextWrangler/Scripts:
(* Execute text script *) to replaceTabs(this_text, new_tab) set AppleScript's text item delimiters to " " set the item_list to every text item of this_text set AppleScript's text item delimiters to the new_tab set this_text to the item_list as string set AppleScript's text item delimiters to "" return this_text end replaceTabs set current_text to "" tell application "TextWrangler" set current_text to get selection as text end tell set split_text to replaceTabs(current_text, " ") if length of split_text > 0 then tell application "Terminal" do script split_text in window 1 end tell end if (* End of script *)
Since I mostly use MacVim these days, I wrote a similar python script that can be called from Vim. This script also uses new features in Leopard; in particular, the Scripting Bridge which allows Applescript commands to be called from other languages such as Python and Ruby.
import fileinput from Foundation import * from ScriptingBridge import * Term = SBApplication.applicationWithBundleIdentifier_("com.apple.Terminal") # Strip tabs for line in fileinput.input(): notabs = line.strip().replace('\t',' ') Term.doScript_in_(notabs, Term.windows()[0]) print line,
This script can be run using a vim macro. I assigned the keystroke “,mt” to this script in my vimrc
nmap ,mt :.!/ToTerminal.py vmap ,mt ! /ToTerminal.py ### Original post from 2006 Unfortunately, the Terminal that Apple ships with OS X does not have adequate AppleScript support for what I'm trying to do. Instead, I will use iTerm, which has much better AppleScript support (and tabs). Here is the script, which you can save as "Execute Text.scpt" in ~/Library/Application Support/TextWrangler/Scripts: (* Execute Text script *) to replaceTabs(this_text, new_tab) set AppleScript's text item delimiters to "\t" (* that should be a tab character *) set the item_list to every text item of this_text set AppleScript's text item delimiters to the new_tab set this_text to the item_list as string set AppleScript's text item delimiters to "" return this_text end replaceTabs set current_text to "" tell application "TextWrangler" set current_text to get selection as text end tell set split_text to replaceTabs(current_text, " ") if length of split_text > 0 then tell application "iTerm" tell current session of current terminal write text split_text end tell end tell end if (* End of script *)The first function replaces tabs with another string (in this case 3 spaces). I need this because MATLAB has tab completion in the shell, and entering tabs will cause it to attempt a completion and then beep when it can't find one. I can't just strip the tabs off because I also work in python and whitespace is important to the language. So I replace the tabs with three spaces. The rest of the code is self-explanatory and I find that it works quite well. You will need to assign the shortcut in TextWrangler (Window->Palettes->Scripts, Set Key...) and then it should work. I expect it will work with other interpreted languages with few or no modifications.