Skip to content

Conversation

@d12frosted
Copy link
Owner

this is mostly for testing
if it goes well, I will provide Emacs Client.app for other versions of Emacs.

@d12frosted
Copy link
Owner Author

It works, but I can't figure out how to capture file path when you open a file from Finder. If someone knows - please let me know :)

@d12frosted
Copy link
Owner Author

Ok, shell scripts is not the right approach as it seems. Turns out macos sends filename via system events, not via arguments. Will explore two directions - a simple cocoa application or a simple apple script application.

@danielboston38
Copy link

if you create a AppleScript or automator app it works fine. I am using it this way.

@danielboston38
Copy link

unfortunately brew services does not run the daemon. I guess it's just keeping emacs alive? which six of one half dozen of the other I guess. I guess emacs is looking for the daemon to run in client mode? so maybe it doesn't know what's going on with this service that's just keeping emacs running?

@mbhutton
Copy link

mbhutton commented Feb 26, 2025

I'm curious about what this is for?

If the idea is to support opening files via finder interactions or via open -an Emacs, the existing Emacs.app already handles this well (once the app is already running).

If it's to support opening via org-capture, isn't that better done in the existing Emacs.app, ie issue #285 .

Or is it to have an app to call that can ensure the main Emacs is alive and route file args to it?

In my current workflow, restarting Emacs looks like
brew services restart emacs-plus@30 ; sleep 4; emacsclient -c -n ; sleep 2; open -a Emacs.

Once that's up, I can treat the Emacs.app like most other apps using activation/open/drag files etc. It'd be nice to have stop/start/restart/daemon handling less of a thing I need to worry about, as depending on the timing I can end up with extra processes, or a foreground daemon app instead.

I think ideally the one Emacs.app would act as the app to:

Is there benefit to handling these cases in different applications, or is it more about what's feasible?

@mbhutton
Copy link

mbhutton commented Feb 27, 2025

unfortunately brew services does not run the daemon

@danielboston38 I'm running emacs-plus via brew services restart emacs-plus@30 which runs Emacs as a daemon:

$ ps aux  | grep emacs
[...] /opt/homebrew/Cellar/emacs-plus@30/30.1/Emacs.app/Contents/MacOS/Emacs --fg-daemon

@d12frosted
Copy link
Owner Author

unfortunately brew services does not run the daemon.

Any proof? I just did it and it works. Keep in mind that TCP is not supported (not sure why).

if you create a AppleScript or automator app it works fine. I am using it this way.

Yes, but every user needs to create it. Wouldn't it be nice if we had it OOTB?

I'm curious about what this is for?

To have ability to open files from Finder in Emacs Client. And I just realised that you are correct for cases when Emacs is already open, because Finder doesn't create a new instance of Emacs. But if you start Emacs server via brew, then things break. When I try to open a file in Emacs via Finder when the service is running, Emacs is opened, but the window is not created 🤷 So I actually have to use CLI to open a new window. And maybe this is what needs to be fixed actually.

@mbhutton thanks a lot for your insights! 🙏

@mbhutton
Copy link

mbhutton commented Feb 27, 2025

True! Activation and file opening via Finder work well when the service is running and at least one frame is active. But when there's no active frame then usually something surprising happens like an extra process, or no window opening, and I need to figure out what went wrong and fix it.

It would be amazing to have an app, Emacs.app itself or a companion app, "do what I mean", for activation, finder files, and org-protocol.

My dream would be for it to:

  • ensure the brew Emacs service is running, waiting until ready to...
  • create a frame if necessary, waiting until ready to...
  • Do The Thing (open file or org-protocol link then activate)

A tool that was able to do all that would also be just as useful from the command line.

emacsclient-dwim and Emacs Client DWIM.app for "do what I mean"?

@mbhutton
Copy link

mbhutton commented Feb 27, 2025

Maybe there are some extractable, composable commands in there that could be useful as their own command.

Eg:

  • emacsclient-dwim ensure-daemon-ready
  • emacsclient-dwim ensure-frame
  • emacsclient-dwim focus-frame
  • emacsclient-dwim open-files
  • emacsclient-dwim open-org-protocol-link

Btw I know this is crazy out of scope for this PR (!), just trying to capture what the scope of the problem is. Kinda sounds like a project in itself to cover all the above.

@mbhutton
Copy link

Oh and (to add to the list of wishes!) ideally the app would also act as a share target to invoke the command org-protocol convention of url, title, and text.

If all of that aligns with what most users want, I could definitely contribute, or possibly write it directly in a different project, as it could potentially be useful across all the macOS Emacs flavours.

I think that solving all those problems probably does require one tool that's able to coordinate all those aspects, otherwise it's easy to end up with a patchwork of apps/tools that only work in some cases.

@mbhutton
Copy link

mbhutton commented Mar 7, 2025

Hi @d12frosted, I essentially added a giant wish list above for all the things I wish such an app would do, which I know is unrealistic and out of scope for a single PR!

Since I have so many wishes for such an app, I've started a project at https://github.com/mbhutton/EmacsOpen to capture all that scope and eventually do all those things above.

The initial scope is to get it to work with Emacs-plus v30 when running Emacs daemon via brew service, but should also be compatible for all the other similar Emacs formulas which use emacsclient and brew service.

It's very pre-pre-alpha, just getting started, not close to functional yet. Very happy to collaborate if you're interested, otherwise happy to implement it solo.

@jsperger
Copy link

This patch that just got merged might be relevant (savannah link, github mirror link)

@mcmehrtens
Copy link

@d12frosted What work is still remaining before you'd merge this PR?

@elken
Copy link
Contributor

elken commented Nov 23, 2025

Bump again @d12frosted, what's left here? This would be really cool to get in 😄

If it helps I just did a rebase locally and it pretty much applies cleanly from current master, just need to add it to all versions not just 30.

@d12frosted
Copy link
Owner Author

@mcmehrtens @elken
oh thanks for the interest! this PR slipped out of my mind.

in short, I need to figure out how to make Emacs Client.app to behave - i.e. properly open new window (frame) when it is used from Finder, otherwise there is little reason to have this. basically, this is the issue:

To have ability to open files from Finder in Emacs Client. And I just realised that you are correct for cases when Emacs is already open, because Finder doesn't create a new instance of Emacs. But if you start Emacs server via brew, then things break. When I try to open a file in Emacs via Finder when the service is running, Emacs is opened, but the window is not created 🤷 So I actually have to use CLI to open a new window. And maybe this is what needs to be fixed actually.

I just need find some time and motivation to finish it :) but maybe I will tackle it this month. seeing interest and this PR increases my motivation 😅

@elken
Copy link
Contributor

elken commented Nov 23, 2025

Thanks for the update! No rush of course 😄

this commit replaces the initial naive shell script implementation with a robust AppleScript-based solution that
properly handles file opening from Finder.

**problem with initial approach**

the original shell script wrapper could not receive files opened via Finder's "Open With" menu or drag-and-drop. this is because shell scripts cannot handle `AppleEvents` - when macOS opens files from Finder, it sends `application:openFiles:` events, not command-line arguments.

**solution**

implement `Emacs Client.app` using AppleScript compiled with `osacompile`, which:

- handles file opening from Finder via on open handler
- supports drag-and-drop onto app icon
- works from Spotlight/Dock via on run handler
- includes `PATH` injection (respects `EMACS_PLUS_NO_PATH_INJECTION`)
- auto-starts daemon using `emacsclient -a ''`
- proper macOS integration with bundle identifier, file type associations, and custom icon
@d12frosted
Copy link
Owner Author

ok, I think I have some progress - I've pushed a commit that implements Emacs Client.app using AppleScript

TL;DR - there is some progress, I need your help with testing and if everything is fine, I'll update documentation and will merge this PR.


this commit replaces the initial naive shell script implementation with a robust AppleScript-based solution that properly handles file opening from Finder.

problem with initial approach

the original shell script wrapper could not receive files opened via Finder's "Open With" menu or drag-and-drop. this is because shell scripts cannot handle AppleEvents - when macOS opens files from Finder, it sends application:openFiles: events, not command-line arguments.

solution

implement Emacs Client.app using AppleScript compiled with osacompile, which:

  • handles file opening from Finder via on open handler
  • supports drag-and-drop onto app icon
  • works from Spotlight/Dock via on run handler
  • includes PATH injection (respects EMACS_PLUS_NO_PATH_INJECTION)
  • auto-starts daemon using emacsclient -a ''
  • proper macOS integration with bundle identifier, file type associations, and custom icon

I would really love to get some proper testing of this solution (works only with Emacs 30 for now), specifically the following test cases:

  • opening files from Finder (right-click "Open With")
  • drag-and-drop onto app icon
  • launching from Spotlight/Dock
  • files with spaces and special characters
  • PATH injection and daemon auto-start

one thing that I have noticed so far - yabai behaves strangely when I toy with Emacs Client.app, but I have lots of migrations and builds happening in the background, so I don't understand if something is causing these issues 🤷

@d12frosted
Copy link
Owner Author

ok, in general it does look promising 🤞

@d12frosted
Copy link
Owner Author

@mbhutton I am also curious to hear your feedback since you spent some time figuring these things out 🙏

@elken
Copy link
Contributor

elken commented Nov 24, 2025

I don't use anything like yabai but I will endeavour to test this today 👍

@elken
Copy link
Contributor

elken commented Nov 24, 2025

The only thing that doesn't work for me is the dock :/ I can do new frame but that's it, no new client.

Because the osascript calls emacsclient inside Emacs.app the process uses the same icon.

Emacs Client.app also has no icon, if possible it should inherit from the icon you set, eg I use the doom icon

@d12frosted
Copy link
Owner Author

@elken thanks for checking! ❤️

The only thing that doesn't work for me is the dock :/ I can do new frame but that's it, no new client.

why do you want a new client? that's the point of Emacs Client.app - it connects to existing service or creates new one if none exist; so not sure what you did and what you expected - can you pls elaborate? 🙏

Because the osascript calls emacsclient inside Emacs.app the process uses the same icon.

not sure I understand this bit - we copy icon; though I need to check if we copy the user prefer icon or the stock one 😅

I will check it a bit later 🙏

@elken
Copy link
Contributor

elken commented Nov 24, 2025

why do you want a new client?

No reason inherently, just reporting what I see 😄

not sure I understand this bit - we copy icon; though I need to check if we copy the user prefer icon or the stock one 😅

image

It could be a Tahoe thing maybe, but this is what I see for it

@d12frosted
Copy link
Owner Author

No reason inherently, just reporting what I see 😄

Ah good, I wanted to double check if it's something I didn't understood in the expected user flow or something else 😅

It could be a Tahoe thing maybe, but this is what I see for it

oops, I have just realised that I am using an older Sequoia 😅 I tried building with dragon icon and this is what I get:

image

I see you have an alias. Can you check of original Emacs Client.app (the one that brew info emacs-plus@30 instructs to copy) has a proper icon? Although even after copying using osascript -e 'tell application "Finder" to make alias ... I have correct icon 🤔

@elken
Copy link
Contributor

elken commented Nov 24, 2025

image

The original has the same icon, icons in general have been drastically changed for Tahoe (see #815) so possibly related, I'm far from an expert though 😅

@d12frosted
Copy link
Owner Author

hm... maybe you are right; does Emacs.app have proper icon on your machine?

@elken
Copy link
Contributor

elken commented Nov 24, 2025

Yep Emacs.app is fine as is the symlink but you can also see the impact of #815 (the white background, previously it was transparent)

image

@d12frosted
Copy link
Owner Author

@elken that's actually strange as both icons should be treated the same 🤔 maybe there is actually an issue with icon setting, cause I see the following files under /opt/homebrew/opt/emacs-plus@30/Emacs Client.app/Contents/Resources/:

ll "/opt/homebrew/opt/emacs-plus-local/Emacs Client.app/Contents/Resources/"
total 1264
-rw-r--r--  1 d12frosted  admin   551K Nov 24 14:16 Emacs Client.icns
drwxr-xr-x  3 d12frosted  admin    96B Nov 24 14:16 Scripts/
-rw-r--r--  1 d12frosted  admin    72K Nov 24 14:16 droplet.icns
-rw-r--r--  1 d12frosted  admin   362B Nov 24 14:16 droplet.rsrc
image

let me investigate, cause it might be a misconfiguration on formula side

@elken
Copy link
Contributor

elken commented Nov 24, 2025

image

Yep I see the same thing here 😄

I assume Assets.car is some Tahoe thing, file portains it to be a Mac OS X bill of materials (BOM) file

@d12frosted
Copy link
Owner Author

pushed potential fix, will appreciate if you can test it @elken 🙏

@d12frosted
Copy link
Owner Author

Assets.car

regarding this file, it seems that I need to delete it as well; can you manually delete it and see if it helps?

@elken
Copy link
Contributor

elken commented Nov 24, 2025

image

No change, just finished building

@elken
Copy link
Contributor

elken commented Nov 24, 2025

Assets.car

regarding this file, it seems that I need to delete it as well; can you manually delete it and see if it helps?

Also no change :/

@d12frosted
Copy link
Owner Author

well, if everything else works, I am inclined to merge this PR and then I will fix the icon discrepancy issue once I upgrade to Tahoe on one of my machines (possibly closer to end of week)

@d12frosted
Copy link
Owner Author

@elken thanks for testing though 🙏

@elken
Copy link
Contributor

elken commented Nov 24, 2025

No worries! It's a minor annoyance at best, just means it's not obvious that a file is marked to open with Emacs Client by default, but it's a good start 😄

@d12frosted
Copy link
Owner Author

ok, so I am merging; hope to get more feedback - having it in master should make the feature more discoverable 😅

@d12frosted d12frosted merged commit 55de41e into master Nov 24, 2025
10 of 16 checks passed
@d12frosted d12frosted deleted the feature/emacs-client branch November 24, 2025 16:00
@d12frosted
Copy link
Owner Author

oh, I had a laptop where I don't care about macos version, so upgraded and pushed a fix for icons in macOS 26 - caae572, already in master

but we really need to figure out the situation with icons in Tahoe - they are ugly lol

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants