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

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

Related

open -a Terminal filename argument doesn't work at all, on mac osx

I'm trying to open a C file already compiled using
open -a Terminal filename argument
It's actually a simple server.c file.
I need also to pass the port as argument, but i can't find out how to do it.
"open -a Terminal proxy 8000"
it returns: "The file /Users/...../8000 does not exist."
So i've tried:
"open -a Terminal proxy\ 8000"
it returns: "The file /Users/...../proxy 8000 does not exist."
Of course if i do "./proxy 8000"
It works.
So i definitely need to pass di parameter as argument in command line, but i can't find out any help even in stackoverflow.
Any help?
Thanks!
The open command is meant to open simple files, it doesn't really support your use case. There's an --args option that passes arguments to the application it uses to open the file (i.e. Terminal), but it doesn't look like Terminal passes those on.
AppleScript might work for you though, e.g. from the shell:
osascript -e 'tell application "Terminal" to do script "/path/to/proxy 8000"'

Is there a command for macOSX terminal(CMD) to pause a script, open a NEW terminal, and resume?

I am trying to find a method to combine two scripts so that they can be run in one go. However, it would be useful if both scripts still ran in separate windows as I need to look through the logs for certain bits of information. Any help would be much appreciated!
If you have X11 installed (e.g. XQuartz), you can run your scripts in new xterm windows:
xterm -e ./scriptA.sh & xterm -e ./scriptB.sh &
But if you want to use the default OSX Terminal.app, this should work:
open -a Terminal.app ./scriptA.sh; open -a Terminal.app ./scriptB.sh
I tried passing arguments to the scripts using the --args parameter to open, but for some reason it didn't work for me.
Update
The more OSX idiomatic way to do this is seems to be to start Terminal.app from an Applescript snippet with the osascript command:
osascript -e "tell application \"Terminal\" to do script \"scriptA.sh <args>\""
osascript -e "tell application \"Terminal\" to do script \"scriptB.sh <args>\""
The quotes are escaped so you can e.g. do variable expansions from the calling bash for the script args.

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 to launch GUI Emacs from command line in OSX?

How do I launch GUI Emacs from the command line in OSX?
I have downloaded and installed Emacs from http://emacsformacosx.com/.
I'll accept an answer fulfilling all of the following criteria:
The emacs window opens in front of my terminal window.
Typing "emacs" launches a GUI Emacs window. Finding files in that window will default to looking in the directory from where I started Emacs.
Typing "emacs foo.txt" when foo.txt exists launches a GUI Emacs window with foo.txt loaded.
Typing "emacs foo.txt" when foo.txt does not exist launches a GUI Emacs window with an empty text buffer named "foo.txt". Doing ^X^S in that buffer will save foo.txt in the directory from where I started Emacs.
Call the following script "emacs" and put it in your PATH somewhere:
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$#"
That covers #2, #3, and #4.
For #1, put this somewhere in your .emacs file:
(x-focus-frame nil)
The emacsformacosx.com site now has a How-To page, which is where the top snippet came from. There's more info there about running emacsclient and hooking Emacs up to git mergetool.
In your shell, alias the command 'emacs' to point to the OSX emacs application
In my shell (running the default bash), I have the following (in my .bashrc)
alias emacs='open -a /Applications/Emacs.app $1'
Then, typing emacs on the command line starts the emacs application.
I would, however, recommend that you open a copy of emacs and just keep it up and running. If that's the case, and you want to load a file into an existing copy of emacs, you can use the emacsclient by placing the following in your .bashrc:
alias ec='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'
Then add the following to your .emacs file to start the emacs server (which receives the emacsclient calls)
;;========================================
;; start the emacsserver that listens to emacsclient
(server-start)
Then you can type
ec .bashrc
to load a copy of .bashrc into an existing emacs session!
This improves on David Caldwell's answer by starting Emacs in the background:
#!/bin/sh
$(/Applications/Emacs.app/Contents/MacOS/Emacs "$#") &
As stated in the other answer, this covers #2, #3, and #4. For #1, put this somewhere in your .emacs file: (x-focus-frame nil).
Note that the following does not work for me -- it does not start Emacs in a directory specified on the command line (e.g. emacs .)
# NOT RECOMMENDED
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$#" &
I assume you either:
Start the emacs daemon on login
Have (server-start) in your .emacs
Don't mind having lots of separate copies of emacs running
If so, then I think this satisfies the original four criteria, plus one more:
The emacs window opens in front of my terminal window.
it will always open to the foreground (with x-focus-frame).
Typing "emacs" launches a GUI Emacs window. Finding files in that window will default to looking in the directory from where I started Emacs.
It will open an existing emacs window in dired mode.
Typing "emacs foo.txt" when foo.txt exists launches a GUI Emacs window with foo.txt loaded.
If emacs is already running and has a server, then it will open in the existing window and come to the foreground.
Typing "emacs foo.txt" when foo.txt does not exist launches a GUI Emacs window with an empty text buffer named "foo.txt". Doing ^X^S in that buffer will save foo.txt in the directory from where I started Emacs.
Correct.
One extra:
Control returns to the terminal session immediately after typing the command.
~/bin/emacs
#!/bin/bash
EMACSPATH=/Applications/Emacs.app/Contents/MacOS
# Check if an emacs server is available
# (by checking to see if it will evaluate a lisp statement)
if ! (${EMACSPATH}/bin/emacsclient --eval "t" 2> /dev/null > /dev/null )
then
# There is no server available so,
# Start Emacs.app detached from the terminal
# and change Emac's directory to PWD
nohup ${EMACSPATH}/Emacs --chdir "${PWD}" "${#}" 2>&1 > /dev/null &
else
# The emacs server is available so use emacsclient
if [ -z "${#}" ]
then
# There are no arguments, so
# tell emacs to open a new window
${EMACSPATH}/bin/emacsclient --eval "(list-directory \"${PWD}\")"
else
# There are arguments, so
# tell emacs to open them
${EMACSPATH}/bin/emacsclient --no-wait "${#}"
fi
# Bring emacs to the foreground
${EMACSPATH}/bin/emacsclient --eval "(x-focus-frame nil)"
fi
On Mountain Lion, I am using Yamamoto Mitsuharu's port https://github.com/railwaycat/emacs-mac-port with the following alias:
alias emacs=/Applications/Emacs.app/Contents/MacOS/Emacs
and it satisfies all of your criteria.
Just built emacs with homebrew package manager according to this guide:
http://www.emacswiki.org/emacs/EmacsForMacOS
with brew install --cocoa emacs
After that one should launch the .app version to get gui, which in my case was /usr/local/Cellar/emacs/24.3/Emacs.app/Contents/MacOS/Emacs
Further improving on David James' response the following works for me:
Per instructions to open a file from a terminal found at http://www.emacswiki.org/emacs/EmacsForMacOS#toc20
open -a /Applications/Emacs.app <file-name>
combining this with David Jame's response I've created the following emax bash script and placed it in my path at ~/bin
#!/bin/bash
(open -a /Applications/Emacs.app "$#") &
Caveat: in order to get emacs to open the current directory in Dired by name mode, you need to use
emax .
Environment:
OS X Yosemite Version 10.10.2
GNU Emacs 24.4.2 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343.14)
of 2014-11-13
Simple solution...
A lot of very complex solutions to this problem are posted here. That's fair because it seems non-trivial.
However, this solution works really well for me.
ec() {
emacsclient -n $# 2> /dev/null
if [[ $? == 1 ]]; then
open -a Emacs.app -- $#
fi
}
Usage
ec file [...]
Let's unpack what's happening:
pass all the ec arguments to emacsclient and don't (-n) wait for emacs before continuing.
If Emacs is already running, we're all done and you're editing.
swallow up the error message posted by emacsclient when there's no emacs running. (2> /dev/null)
Manually handle the exit code 1 ([[ $? == 1 ]])
open Emacs.app and pass file arguments to it (paths will be correctly opened.)
You're all done, and Emacs has opened your files.
The other answers here didn't quite work for me. In particular, on my machine, the bash script
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$#"
always opens emacs in the home directory. To get it to open in the current working directory, I had to do
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$PWD/$#"
instead.
Compile Emacs according to the following steps:
./configure --with-x --prefix=/usr
make
sudo make install
And your done! It may help to download and install XQuartz, but that's just my opinion.
This is my script for open emacs/emacsclient on osx.
#!/bin/bash
# Ensure (server-start) is added in your emacs init script.
EMACS=/Applications/MacPorts/Emacs.app/Contents/MacOS/Emacs
EMACSCLIENT=/Applications/Macports/Emacs.app/\
Contents/MacOS/bin/emacsclient
# test if client already exsit.
$EMACSCLIENT -e "(frames-on-display-list)" &>/dev/null
# use emacsclient to connect existing server.
if [ $? -eq 0 ]; then
$EMACSCLIENT -n "$#"
# open emacs.app instead.
else
`$EMACS "$#"` &
fi
In all of the above when using "open" - make sure you use the "--args" option
Do not do this:
alias emacs='open -a /Applications/Emacs.app $1'
Instead this:
alias emacs='open -a /Applications/Emacs.app --args $1'
the --args option prevents "open" from consuming various options intended for Emacs.
The top answer is good, but I wanted the emacs process to run in the background so I could still use my shell. This answer appeared to do what I wanted, but didn't start emacs in the right directory, meaning absolute paths were required (or hacks to append pwd to the paths which wouldn't work in all cases). Furthermore, simply using & meant that if I killed the terminal, emacs would also be killed.
I decided to use screen and a bash function, and the following solution works for me on macOS 10.15.6 and emacs 26.2 installed with brew:
function emacs() {
screen -d -m /Applications/Emacs.app/Contents/MacOS/Emacs "$#"
}
For the meaning of the -d -m command line flags, they have a special meaning when used together and so can essentially be thought of as one command line flag. The explanation is in the manpage:
Start screen in "detached" mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts.
open_emacs() {
num=$(ps aux | grep -E "[E]macs-x86_64-10_14 --|[e]macs --" | wc -l)
if [ $num -eq 0 ]; then
echo "## starting emacs"
# Run in a subshell to remove notifications and close STDOUT and STDERR:
(&>/dev/null emacsclient -t -q &)
fi
}
alias e="open_emacs"
Following line (&>/dev/null emacsclient -t -q &) will start the emacs daemon if it is not running on the background.
macOS may have defined the app name starting with E (ex: Emacs-x86_64-10_14.app), based on that you can check whether the emacs daemon running on the background or not.
Just want to update a response to this question. Since it is still a relevant question, but now there is an easier solution:
brew install --cask emacs
When this installs Emacs, it does the behavior you requested, without further intervention. It even runs the Emacs Server on startup.
Files installed/linked by default:
ebrowse -> /Applications/Emacs.app/Contents/MacOS/bin/ebrowse
emacs -> /Applications/Emacs.app/Contents/MacOS/Emacs
emacsclient -> /Applications/Emacs.app/Contents/MacOS/bin/emacsclient
etags -> /Applications/Emacs.app/Contents/MacOS/bin/etags
BTW, this is now a recommended way of installing Emacs on MacOS:
https://www.gnu.org/software/emacs/download.html#nonfree

How do I autorun an application in a terminal in Ubuntu?

I've created a few autorun script files on various USB devices that run bash scripts when they mount. These scripts run "in the background", how do I get them to run in a terminal window? (Like the "Application in Terminal" gnome Launcher type.)
Run them as a two stage process with your "autorun" script calling the second script in a new terminal eg
gnome-terminal -e top --title Testing
Would run the program "top" in a new gnome terminal window with the title "Testing" You can add additional arguments like setting the geometry to determine the size and location of the window checkout the man page for gnome-terminal and the "X" man page for more details
xterm -e shellscript.sh
or (if xterm isn't installed)
gnome-terminal -e shellscript.sh
or (if you're using kubuntu / kde)
konsole -e shellscript.sh

Resources