iTerm2 and tmux: open new tab in working directory of current tab - macos

When I open a new tab (via ⌘T) on a remote shell using iTerm2 and tmux, I almost always want the new tab to have the same working directory as the current tab. The best I can do is make iTerm2 open up the new tab in the same directory in which I ran tmux -CC or tmux -CC attach. (This behavior can be configured by navigating to Preferences → Profiles → General → Working Directory.)
This directory will not necessarily be the working directory of the current tab. Is there any way to get the behavior I'm looking for? I searched online for a while but could not find any helpful information.

When using Iterm2, if you want a new tab to open in the same directory as the current tab via ⌘T, there is an option available in your profile under preferences.
From the iTerm2 main menu:
Iterm2 -> Preferences -> Profiles -> General -> Working Directory -> Reuse previous session's directory

If you're using ZSH you could try something like this;
function tab() {
local command="cd \\\"$PWD\\\"; clear; "
(( $# > 0 )) && command="${command}; $*"
}
If you're using bash I'm not sure what the equivalent would be. Also if you're using prezto or Oh-My-ZSH the tab function is already built in.
UPDATE
Having had a look at how prezto does it, this should be the full solution
local command="cd \\\"$PWD\\\""
(( $# > 0 )) && command="${command}; $*"
the_app=$(
osascript 2>/dev/null <<EOF
tell application "System Events"
name of first item of (every process whose frontmost is true)
end tell
EOF
)
[[ "$the_app" == 'iTerm' ]] && {
osascript 2>/dev/null <<EOF
tell application "iTerm"
set current_terminal to current terminal
tell current_terminal
launch session "Default Session"
set current_session to current session
tell current_session
write text "${command}"
end tell
end tell
end tell
EOF
}
It uses the CLI for AppleScript and seems to work fine for me.

With tmux, one solution is to set alias itab='open . -a iterm' in your .bash_alias.

Related

How can I open a new z shell in a tab and run a command?

I'm on macOS which is currently using the zshell.
I would like to run a command in one shell which opens another shell preferably in another tab in the same window and then runs a given command. For example:
> openTab
would open another tab and run a basic command like ls.
Is this possible to do?
It appears that the open command will open new window, but I want it to be opened as a new tab in the current window. See here
Osascript appears a bit messy, is there way to do this natively with zshell?
You can use AppleScript, via osascript to do exactly that:
function runInNewTab() {
osascript >/dev/null <<EOF
tell application "System Events"
tell process "Terminal" to keystroke "t" using command down
end tell
tell application "Terminal" to do script "$*" in front window
EOF
}
Run it like this:
runInNewTab ls -l ~

Launch Emacsclient with GUI (from Dock) on Mac OS X

How can I launch Emacsclient with GUI from the Dock (or maybe also from the terminal) on Mac OS X?
The EmacsWiki describes how to create an "Emacs from Dock" app using Automator. It worked for me but I don't want to launch Emacs but Emacsclient. So, I tried replacing /Applications/Emacs.app/Contents/MacOS/Emacs with both /Applications/Emacs.app/Contents/MacOS/bin/emacsclient and /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c but both didn't work.
From the terminal
You can find the appropriate path to emacsclient using type in your shell (assuming emacsclient -c works from said shell):
$ type emacsclient
emacsclient is /usr/local/bin/emacsclient
Then we can add the appropriate emacsclient flags (see $ man emacsclient for details) to open the GUI:
/usr/local/bin/emacsclient -n -c -a ""
From macOS GUI
To launch emacsclient from eg the Dock or Spotlight, it's easy to use Automator. Automator is built in to macOS.
Choose to make an "Application", then choose "Run Shell Script", and add a modified version of the above call to emacsclient:
/usr/local/bin/emacsclient -n -c -a "" -- "$#"
Then change "Pass input": use "as arguments" instead of "to stdin".
The added "$#" is where any optional arguments passed to this shell script will be placed. Here, this allows you to pass a filename to open with emacsclient. Automator automates passing this filename in when, eg, you click to open a file with the application we've just made. This also allows you to set the application to be the default application for certain file types.
From anywhere, flexibly
Another way to run the above shell command is with skhd (link). skhd is far more involved to learn, but ultimately makes it much easier to set up a large number of shell commands with rapid access.
For example, you could make "Ctrl-o" from anywhere in macOS enter a mode you name open_app, from which you could press "e" to open emacsclient, "d" to open emacs --debug-init, "t" to run emacs --adv-timers, "f" to open Firefox, "F" to open a second Firefox profile, etc.
One idea would be to create an applescript that does whatever the original poster desires, and wrap it up in an application using something like platypus or automator. See https://superuser.com/questions/685111/basic-setup-of-emacs-server-under-osx for additional ideas such as using the --daemon command-line argument instead of placing (server-start) within the user-configuration file.
Here is an example applescript:
# (server-start) must be inside `init.el` or `.emacs` file.
#
# This script can also be used in the terimal: osascript path-to-script arguments
# Terminal Example:
# osascript /absolute/path/to/applescript/file "-e '(progn (dired \"/Applications\") (message \"Hello-World\!\"))'"
on run argv
set arg to item 1 of argv
set emacs to application "Emacs"
set appIsRunning to emacs is running
if appIsRunning then
say "Emacs is already running."
do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient " & arg
else
tell application "/Applications/Emacs.app/Contents/MacOS/Emacs" to activate
say "Please wait five seconds for Emacs to load."
delay 5
do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient " & arg
end if
end run

how can i find out the current osx-terminal theme from within a bash script

Inside a bash script, I need to know what the current OS X terminal theme is. How can this be done?
I check the output of the env command, but didn't find anything.
We can use an AppleScript to retrieve the name of the profile of the foremost Terminal window from within a bash shell:
echo 'tell application "Terminal" to return name of current settings of first window' | osascript
We can similarly set the profile:
echo 'tell application "Terminal" to set current settings of first window to settings set "Basic"' | osascript
Replace "Basic" with the name of the profile you wish to adopt.
These commands will apply to the current/foremost tab or window of Terminal.app
I've also written a script that will get/set the profile depending on whether a profile name is provided: https://github.com/starbase527/dotfiles/blob/master/local/bin/term-profile . Example usage:
# Gets profile name
> term-profile
Basic
# Sets profile to Basic
> term-profile Basic
>
On a per-shell basis, you can't. You can get the default setting:
defaults read com.apple.Terminal "Default Window Settings"
Or the new window setting:
defaults read com.apple.Terminal "Startup Window Settings"
Directly in zsh, you can get the current Terminal.app theme like this:
CURRENT_THEME=$(osascript -e 'tell application "Terminal" to return name of current settings of first window')
echo $CURRENT_THEME
From that, and with some AppleScript knowledge, you can get some of the details of the Terminal.app
Happy coding 🖖

Applescript to open Terminal window without sourcing ~/.bash_profile

I am trying to use Platypus to create an app launcher for an interactive command-line program on OSX 10.8. I want to be able to double-click on my application, and have a Terminal window open, running my program. The problem is that my Applescript, (borrowed from Octave, and adapted for Julia) launches a Terminal window and attempts to spit some commands into it, however I have a rather hefty ~/.bash_profile that interferes with this. Is there a way to get my Applescript to open a non-login shell, or not source ~/.bash_profile, etc?
Here's the script that Platypus runs:
# This is the startup procedure written as AppleScript to open a
# Terminal.app (if the Terminal.app is not already running) and start
# the Julia program.
# 20071007 removed: open -a /Applications/Utilities/Terminal.app
osascript 2>&1>/dev/null <<EOF
tell application "System Events" to set ProcessList to get name of every process
tell application "Terminal"
activate
if (ProcessList contains "Terminal") or ((count of every window) is less than 1) then
tell application "System Events" to tell process "Terminal" to keystroke "n" using command down
end if
do script ("exec bash -c \"PATH=${ROOT}/julia/bin:${PATH} OPENBLAS_NUM_THREADS=1 FONTCONFIG_PATH=${ROOT}/julia/etc/fonts GIT_EXEC_PATH=${ROOT}/julia/libexec/git-core GIT_TEMPLATE_DIR=${ROOT}/julia/share/git-core exec '${ROOT}/julia/bin/julia'\"") in front window
end tell
EOF
# Quit the Julia.application immediately after startup (ie. quitting
# it in the taskbar) because once it is started it cannot be restarted
# a second time. If Julia.app stays (eg. because of a crash) opened
# then restarting is not possible.
osascript 2>&1>/dev/null <<EOF
tell application "julia"
quit
end tell
EOF
In general, you don't need a Terminal window to execute command line stuff. You would only use the Terminal if there was information you need to manually type in by hand. So you can probably just run the command using "do shell script" instead of "do script" in a Terminal window. Note that doing it this way won't use your bash profile file. So try this command all by itself in the applescript...
do shell script ("exec bash -c \"PATH=${ROOT}/julia/bin:${PATH} OPENBLAS_NUM_THREADS=1 FONTCONFIG_PATH=${ROOT}/julia/etc/fonts GIT_EXEC_PATH=${ROOT}/julia/libexec/git-core GIT_TEMPLATE_DIR=${ROOT}/julia/share/git-core exec '${ROOT}/julia/bin/julia'\"")
Then you can add your other applescript commands as needed, just don't use the Terminal and thus your bash profile won't be used.

How do I get a Mac ".command" file to automatically quit after running a shell script?

In my shell script, my last lines are:
...
echo "$l" done
done
exit
I have Terminal preference set to "When the shell exits: Close the window". In all other cases, when I type "exit" or "logout", in Terminal, the window closes, but for this ".command" file (I can double-click on my shell script file, and the script runs), instead of closing the window, while the file's code says "exit", what shows on the screen is:
...
$l done
logout
[Process completed]
...and the window remains open. Does anyone know how to get a shell script to run, and then just automatically quit the Terminal window on completion?
Thanks!
I was finally able to track down an answer to this. Similar to cobbal's answer, it invokes AppleScript, but since it's the only window that I'd have open, and I want to run my script as a quick open-and-close operation, this more brutish approach, works great for me.
Within the ".command" script itself, "...add this line to your script at the end"
osascript -e 'tell application "Terminal" to quit' &
exit
SOURCE: http://forums.macosxhints.com/archive/index.php/t-2538.html
This worked perfectly for me.. it just closes that execution window leaving other terminal windows open
Just open Terminal and go to Terminal > Preferences > Settings > Shell: > When the shell exits: -> Close if the shell exited cleanly
Then just add exit; at the end of your file.
Use the 'Terminal > Preferences > Settings > Shell: > When the shell exits: -> Close if the shell exited cleanly' option mentioned above, but put
exit 0
as the last line of your command file. That ensures the script really does 'exit cleanly' - otherwise if the previous command doesn't return success then the window won't close.
Short of having to use the AppleScript solutions above, this is the only shell script solution that worked (exit didn't), even if abruptly, for me (tested in OS X 10.9):
...
echo "$l" done
done
killall Terminal
Of course this will kill all running Terminal instances, so if you were working on a Terminal window before launching the script, it will be terminated as well. Luckily, relaunching Terminal gets you to a "Restored" state but, nevertheless, this must be considered only for edge cases and not as a clean solution.
There is a setting for this in the Terminal application. Unfortunately, it is relative to all Terminal windows, not only those launched via .command file.
you could use some applescript hacking for this:
tell application "Terminal"
repeat with i from 1 to number of windows
if (number of (tabs of (item i of windows) whose tty is "/dev/ttys002")) is not 0 then
close item i of windows
exit repeat
end if
end repeat
end tell
replacing /dev/ttys002 with your tty
I'm using the following command in my script
quit -n terminal
Of course you have to have the terminal set to never prompt before closing.

Resources