For years I've been using the following AppleScript to open txt files in vim in iTerm2, but since iTerm 2.9.2 (aka iTerm3) it's broken. Could anyone advise how to update this AppleScript so it works again?
on run {input, parameters}
if (count of input) > 0 then
tell application "System Events"
set runs to false
try
set p to application process "iTerm"
set runs to true
end try
end tell
tell application "iTerm"
activate
if (count of terminals) = 0 then
set t to (make new terminal)
else
set t to current terminal
end if
tell t
tell (make new session at the end of sessions)
exec command ("vim \"" & POSIX path of first item of input as text) & "\""
end tell
if not runs then
terminate first session
end if
end tell
end tell
end if
end run
I originally copied the script from http://earthwithsun.com/questions/283418/how-can-i-make-terminal-vim-my-default-editor-application-in-mac-os-x but I have no AppleScript experience whatsoever.
Any help most appreciated!
B
Using #dusty's link, I recommend that you change the entire code section of your Run AppleScript Action to this:
on run {input, parameters}
tell application "iTerm"
activate
if (count of windows) = 0 then
set t to (create window with default profile)
else
set t to current window
end if
tell t
tell current session
write text ("vim \"" & POSIX path of first item of input as text) & "\""
end tell
end tell
end tell
end run
It seems to work on my machine, but I never use vim, so I am not sure if this will give you precisely what you want.
Good luck,
The new Applescript syntax doesn't have terminal as a top-level object like before. It has been changed to reflect more of the common pattern used throughout the OS for other scriptable applications: the top-level objects of the application are called windows, not terminals.
So the hierarchy is now something like this:
the application containing one or more
windows containing one or more
tabs containing a
session
https://iterm2.com/applescript.html has been updated with examples of the new syntax.
I adopted the code snippet of Craig Smith (great answer!) and tweaked it a little to open a new tab if there is already an open window. This way, you don't get any trouble if you have already something like vim opened in your iTerm. Also, this code changes the directory to the directory of the file to make NerdTREE and fuzzy finders like fzf.vim happy.
on run {input, parameters}
set filename to POSIX path of input
set cmd to "clear; pushd " & quote & "$(dirname " & filename & ")" & quote & " > /dev/null; nvim " & quote & "$(basename " & filename & ")" & quote & "; popd > /dev/null"
tell application "iTerm"
activate
if (count of windows) = 0 then
set t to (create window with default profile)
else
set t to current window
tell t
create tab with default profile
end tell
end if
tell t
tell current session
write text cmd
end tell
end tell
end tell
end run
I took inspiration in the previous anwers and made a few extensions.
My solution accepts multiple input files (e.g. from a selection).
If there is an active window, the script searches for open vim sessions in any of the tabs and opens the files inside of that vim instance. If there are none, it creates a new iTerm tab or window.
on run {input, parameters}
set vimCommand to "nvim -p "
tell application "iTerm"
activate
if (count of windows) = 0 then
set w to (create window with default profile)
else
set w to current window
try
# raises error when all windows are minimized
tell w
# look for tab with open vim session
repeat with t in tabs
tell t
if name of current session contains "vim" then
# open files in current vim session
set esc to character id 27
tell current session
write text (esc & esc & ":silent! tablast")
repeat with filename in input
set filePath to quoted form of POSIX path of filename
write text (":execute 'tabedit '.fnameescape(" & filePath & ")")
end repeat
select
end tell
select
return
end if
end tell
end repeat
# no existing session
create tab with default profile
end tell
on error msg
set w to (create window with default profile)
end try
end if
# open in new tab or window
tell w
tell current session
set launchPaths to ""
repeat with filename in input
set filePath to quoted form of POSIX path of filename
set launchPaths to launchPaths & " " & filePath
end repeat
write text (vimCommand & launchPaths)
end tell
end tell
end tell
end run
Something like this in Automator:
on run {input, parameters}
set vim_par to POSIX path of input
set cmd to "/usr/local/bin/vim " & quote & vim_par & quote
tell application "iTerm"
tell current window
create tab with default profile command cmd
end tell
end tell
end run
Save as .app, and then open files via it -- probably, make that .app a default "Open with" app.
Related
Making a small script to connect me to the console on some cisco equipment via a usb to serial connection in terminal.
However I am finding it impossible to put line breaks or returns in between the text and Variables (like using <br> in HTML).
So in the display dialog line all the text comes out all mashed together.
I have tried using \n , \ \n, changing the preferences to Formatting > escape tabs and line Breaks in strings > Checked.
So any help would be much appreciated.
set theFind to "ls /dev/tty.*"
set theResult to do shell script theFind
set theConnection to text returned of (display dialog "Serial interface to availble:" & theResult & "Interface to use:" default answer "/dev/tty.usbserial")
tell application "Terminal"
activate
tell application "System Events"
delay 1
keystroke "screen " & theConnection & " 9600"
keystroke return
beep
end tell
end tell
AppleScript doesn't use linefeeds as line breaks (as unix generally does), it uses carriage returns. You can translate them with tr '\n' '\r' (suitably escaped, of course). Also, you'll need to manually add returns before & after the included output; for some bizarre reason, AppleScript uses \n for that instead of \r. Here's the net result:
set theFind to "ls /dev/tty.* | tr '\\n' '\\r'"
set theResult to do shell script theFind
set theConnection to text returned of (display dialog "Serial interface to availble:\n" & theResult & "\nInterface to use:" default answer "/dev/tty.usbserial")
tell application "Terminal"
activate
tell application "System Events"
delay 1
keystroke "screen " & theConnection & " 9600"
keystroke return
beep
end tell
end tell
I am an applescript noob and i need help getting a certain log file that has a long string of numbers in its title. The number changes and the filename before the number string is unique to the folder it is in. Is there some way i can use the "starts with" to retrieve the file with only using part of the filename and make a variable to work with it?
This is best done with shell script. Use "do shell script" if you must do it in AppleScript. You can concatenate the string part of do shell script with whatever you want, for example:
set file_start to "file_start"
set file_ext to ".txt"
do shell script "mdfind -name " & quoted form of file_start & "|grep " & quoted form of (file_start & "[0-9]*" & file_ext & "$")
replace file_start in quotations with your file's non-changing beginning, and replace the extension with whatever you're using.
do shell command "find ~/some/directory -iname *somefile*"
This actually ended up working a little better.
I'm really confused with this one. All I want is the files in the list to open. Here's my codes
set FilesList to {"Users/XXXXXX/Documents/07PictureArt-Related/THINGS THAT HELP/Tutorials/artNotesfromFeng.rtf", "Users/XXXXXXXX/Documents/07PictureArt-Related/THINGS THAT HELP"}
repeat with theFiles in FilesList
delay 0.1
tell application "Finder" to open POSIX file (theFiles)
end repeat
So, how come THAT won't work, but this will???
tell application "Finder" to open POSIX file "Users/XXXXXX/Documents/07PictureArt-Related/THINGS THAT HELP/Tutorials/artNotesfromFeng.rtf"
I'm thinking it might have to do with maybe the list is making it a string, and when I plug it directly into the open command, it LOOKS like a string, but it's not really...I don't know
For now I guess I just have to brute force it, and make a new statement for each file.
Thanks
Not sure what is going on there, i agree it's confusing.
An alternate is to use the shell 'open' command instead.
repeat with filePath in FilesList
do shell script "open " & quoted form of filePath
end repeat
The shell seems more happy with POSIX paths, the trick is to send in the 'quoted form' of your POSIX paths.
--
EDIT:
Putting into a var first works too.
repeat with theFiles in FilesList
set f to POSIX file theFiles
tell application "Finder" to open f
end repeat
It seems the Finder is causing the coercion to POSIX file problem.
Either of these works:
set l to {"/bin", "/etc"}
repeat with f in l
tell application "Finder" to open (POSIX file (contents of f) as alias)
end repeat
set l to {"/bin", "/etc"}
repeat with f in l
POSIX file f
tell application "Finder" to open result
end repeat
Try running this script:
set l to {"/bin", "/etc"}
repeat with f in l
f
end repeat
The result at the end is item 2 of {"/bin", "/etc"}. contents of returns the target of the reference object.
I don't know why POSIX file f doesn't work inside a tell application "Finder" block, or why POSIX file f as alias does work.
In the below script I use an Application other than Finder to launch an "Open" browser and perform a search in it.
I've got the window into the state I want, but whatever I try can't access the list of files to repeat over.
If anyone can help by adding the code to repeat over that file list and log out the file path of each file it'd be a huge help.
Thanks a lot.
tell application "Preview"
-- start the app
activate
-- let it boot up
delay 3
-- ensure it still has focus
activate
end tell
tell application "System Events"
tell process "Preview"
-- spawn "Open" window
keystroke "o" using {command down}
delay 0.5
-- spawn "Go to" window
keystroke "g" using {command down, shift down}
delay 0.5
-- expand scope of search to all of this mac
keystroke "/"
keystroke return
delay 0.5
-- spawn search field
keystroke "f" using {command down}
delay 0.5
-- perform search
keystroke ".jpg OR .jpeg"
keystroke return
end tell
end tell
Could you use mdfind or choose file instead?
mdfind kMDItemContentType=public.jpeg -onlyin /
osascript -e 'tell app "SystemUIServer"
choose file default location "/" with multiple selections allowed
end' &
sleep 1
osascript -e 'tell app "System Events"
keystroke "f" using command down
keystroke "kind:JPEG image"
keystroke tab & tab & tab & tab & tab & tab
delay 1
key code 125
delay 0.1
keystroke "a" using command down
keystroke return
end'
I have a VBA userform to open a text file in TextPad with the following:
Call Shell("C:\Program Files\TextPad 5\TextPad.exe " & "C:\testfile.txt", vbNormalFocus)
I'd like the text file to be displayed at a specific line number.
Is there a way to pass the line number as an argument to this Shell call?
You can accomplish this using WScript.Shell.SendKeys to trigger the goto line shortcut within TextPad (ctrl-G)
Dim wshshell
Set wshshell = CreateObject("WScript.Shell")
Call Shell("C:\Program Files\TextPad 5\TextPad.exe " & "C:\testfile.txt", vbNormalFocus)
Application.Wait (10)
wshshell.SendKeys "^g" 'ctrl-G
Application.Wait (10)
wshshell.SendKeys "15" 'desired line number
Application.Wait (10)
wshshell.SendKeys "{ENTER}" 'enter
You might have to mess with the Wait lines to add or remove delays between commands, but I tested this from within a VBA module in Excel and it worked.
I am aware that SendKeys that can be called directly from VBA, but when I tried to use that, it seems to be bound to the vba editor window.
You can also call notepad++ with the "-n" argument for the same effect,
Sending keys (specially with delays) might be a dangerous thing if you switch screens or a popup window appears while the command is executing you might lose data or inadvertly execute a dangerous action in that other application.