Created
March 6, 2014 18:08
-
-
Save oggy/9395830 to your computer and use it in GitHub Desktop.
Command line program for Aquamacs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
###################################################################### | |
# | |
# Open the given file names in Aquamacs. | |
# | |
# If the user already has an Aquamacs process open, use it. | |
# Otherwise, fire up a new one. Only Aquamacs instances without a | |
# controlling terminal (i.e., those running in a window) will be | |
# selected. | |
# | |
# Note: We assume the server socket lives in the standard location: | |
# /tmp/emacs<uid>/server. | |
# | |
###################################################################### | |
require 'optparse' | |
require 'tmpdir' | |
class App | |
def initialize | |
@emacs = find_emacs | |
@socket = find_socket | |
@verbose = false | |
end | |
attr_reader :emacs, :socket, :verbose | |
def run(args) | |
parse_args(args) | |
emacs or | |
abort "Cannot find emacs. Set EMACS, or use -e option." | |
puts "Using emacs: #{emacs}" if verbose | |
if aquamacs_running? | |
exec emacs_path('bin/emacsclient'), '--no-wait', "--socket-name=#{socket}", *args | |
else | |
puts 'Starting Aquamacs...' | |
# We can't just use the open command, as it will always open | |
# Aquamacs as the logged-in user, and we want to run as the user who | |
# ran this program (e.g., for sudo). | |
# Fork so it runs in the background. | |
fork do | |
# Lose the controlling terminal. | |
Process.setsid | |
# Silence errors. If we run this as someone other than the | |
# logged-in user, Aquamacs gets a permissions error trying to | |
# register itself as a service and cries loudly. | |
STDERR.reopen('/dev/null') unless verbose | |
exec emacs_path('Aquamacs', 'Aquamacs Emacs'), *args | |
end | |
end | |
end | |
def parse_args(args) | |
parser = OptionParser.new do |parser| | |
parser.on('-e', '--emacs=PATH', "Path to Aquamacs. Default: #{emacs}") { |path| @emacs = path } | |
parser.on('-s', '--socket=PATH', "Path to server socket. Default: #{socket}") { |path| @socket = path } | |
parser.on('-v', '--verbose', "Show all errors.") { |path| @verbose = true } | |
end | |
parser.parse!(args) | |
args.size >= 1 or | |
abort 'No files given.' | |
end | |
def find_emacs | |
emacs = ENV['EMACS'] and | |
return emacs | |
['Aquamacs.app', 'Aquamacs Emacs.app'].each do |app_name| | |
['~/Applications', '/Applications'].each do |app_path| | |
path = File.expand_path("#{app_path}/#{app_name}") | |
return path if File.exist?(path) | |
end | |
end | |
nil | |
end | |
def find_socket | |
tmp_dir = Dir.tmpdir | |
"#{tmp_dir}/emacs#{Process.uid}/server" | |
end | |
def emacs_path(*names) | |
names.each do |name| | |
path = "#{emacs}/Contents/MacOS/#{name}" | |
return path if File.exist?(path) | |
end | |
nil | |
end | |
def aquamacs_running? | |
`ps -U #{ENV['USER']} -xwwo tpgid,command`.each_line do |line| | |
tpgid, command = *line.split(nil, 2) | |
# Assume Aquamacs instances with a controlling terminal are | |
# running inside a terminal window. Any instances we launch will | |
# have no controlling terminal. | |
return true if command =~ /\A#{Regexp.escape emacs}/ && tpgid == '0' | |
end | |
false | |
end | |
end | |
App.new.run(ARGV) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment