Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

emacsclient doesn't work with emacs daemon active #10145

Closed
2 tasks done
Doc73 opened this issue Aug 7, 2023 · 31 comments
Closed
2 tasks done

emacsclient doesn't work with emacs daemon active #10145

Doc73 opened this issue Aug 7, 2023 · 31 comments

Comments

@Doc73
Copy link
Contributor

Doc73 commented Aug 7, 2023

JabRef version

5.9 (latest release)

Operating system

GNU / Linux

Details on version and operating system

Debian Sid Gnome (but perhaps also on Bookworm)

Checked with the latest development build

  • I made a backup of my libraries before testing the latest development version.
  • I have tested the latest development version and the problem persists

Steps to reproduce the behaviour

  1. Open a TeX file with Emacs
  2. Open JabRef
  3. Select a bibitem and click on the send to Emacs button
  4. Nothing appens on Emacs

Appendix

This issue is related with /usr/lib/systemd/user/emacs.service active, wich conflicts with (server-start) active on ~/.emacs.d/init.el.

On my part, I could alternatively:

  1. disable /usr/lib/systemd/user/emacs.service with systemctl
  2. kill emacs.service and start the server whenever I need it

Some link on emacs:

But, my quaestion is: is it possible to adapt JabRef to communicate with the daemon instead of emacsclient?

I'm sorry for the difficult question, perhaps not solvable, and thank you very much in advance.
Domenico

@Doc73 Doc73 changed the title emacsclient doesn't work with emacsclient doesn't work with emacs daemon active Aug 7, 2023
@Siedlerchr
Copy link
Member

I have no idea of how emacs works, but in JabRef you can specify extra command line arguments for emacs:
grafik

When I interpret that here right passing -q. should avoid loading the init config
https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 9, 2023

Unfortunately, I don't quite know how emacs works either.
Surely the problem is on the side of emacs: if I start the server by setting (server-start) to init.el, the program gives lots of errors, but without (server-start) JabRef doesn't send any citation.

Option -q doesn't load init file, but I need to load it also for other packages, for example auctex. 😢

@bahmanm
Copy link

bahmanm commented Aug 17, 2023

I've got no idea what is jabref (saw your call for help on Mastodon), though i noticed something suspicious in the your original post:

You mentioned /usr/lib/systemd/user/emacs.service is active. That probably means that the daemon is active for the superuser/root and not you. If you systemctl enable --user emacs.service the daemon will be started w/ a socket accessible to your user (and the unit will be potentially located at ~/.config/systemd/user/emacs.service)

That explains why only (server-start) works.

Does that make sense? Can you confirm this?

@DivineDominion
Copy link

DivineDominion commented Aug 17, 2023

@Doc73 emacsclient is the tool to tell the daemon to do stuff, like open a file (using emacs directly would start the program again).

So it's either a misconfiguration of the daemon like @bahmanm said.

If that doesn't work: Maybe JabRef could report or log the emacsclient exit code and similar info? That could help debug the problem.

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 17, 2023 via email

@bahmanm
Copy link

bahmanm commented Aug 17, 2023

To make sure it's not something related to systemd, please run the following:

$ sudo systemctl disable --now emacs
$ systemctl enable --user --now emacs

And then try what you were doing again. HTH

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 17, 2023

Yes, I did also this test.
However, I repeated it (with PC just started) and here is the result:

  1. with (server-start) disabled in init.el, Jabref doesn't send any citations
  2. with (server-start) enabled in init.el, I get this error
⛔ Warning (server): Unable to start the Emacs server.
There is an existing Emacs server, named "server"
To start the server in this Emacs process, stop the existing server or call ‘M-x server-force-delete’ to forcibly disconnect it.

and Jabref doesn't send any citations

  1. Obviously, if I call M-x server-force-delete and than M-x server-start, all is working.

@bahmanm
Copy link

bahmanm commented Aug 17, 2023

Thanks for checking that out. I think, at this stage, we need to figure out what goes wrong when starting the daemon.

Can you please try the following experiments and post back the output here?

Experiment 1

  • Stop all Emacs instances, eg sudo pkill emacs.
  • Run the daemon from the command line emacs --daemon 2>&1 | tee emacs-daemon.log and attach emacs-daemon.log.

Experiment 2

  • Stop all Emacs instances, eg sudo pkill emacs.
  • Check no Emacs services are running systemctl status emacs and systemctl --user status emacs.
  • Run the Emacs service systemctl --user start emacs, fetch the logs journalctl --user -u emacs -S yesterday > emacs-service.log and attach emacs-service.log.

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 18, 2023

Experiment 1

emacs-daemon.log

Experiment 2

emacs-service.log

@bahmanm
Copy link

bahmanm commented Aug 18, 2023

Thanks @Doc73 for the files. That rules out any possible problem w/ the daemon startup ✔️

@Siedlerchr Reading the comments, my understanding is that when you "send to Emacs" you're sending a ELisp expression to Emacs to evaluate. If that's right, is there a way to see the result of the interaction w/ emacsclient and any possible errors/warnings on JabRef side?

@Doc73 Following up on the above, can you start the daemon via systemctl, try to send something to Emacs from JabRef and then check the *Messages* and *Warnings* buffers for relevant info?

There has got to be a trace somewhere!

@Siedlerchr
Copy link
Member

@bahmanm Here is the command and the exeuction we send:

String[] com = new String[addParams.length + 2];
com[0] = commandPath;
System.arraycopy(addParams, 0, com, 1, addParams.length);
String prefix;
String suffix;
prefix = "(with-current-buffer (window-buffer) (insert ";
suffix = "))";
if (OS.WINDOWS) {
// Windows gnuclient/emacsclient escaping:
// java string: "(insert \\\"\\\\cite{Blah2001}\\\")";
// so cmd receives: (insert \"\\cite{Blah2001}\")
// so emacs receives: (insert "\cite{Blah2001}")
com[com.length - 1] = prefix.concat("\\\"\\" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\\\"").concat(suffix);
} else {
// Linux gnuclient/emacslient escaping:
// java string: "(insert \"\\\\cite{Blah2001}\")"
// so sh receives: (insert "\\cite{Blah2001}")
// so emacs receives: (insert "\cite{Blah2001}")
com[com.length - 1] = prefix.concat("\"" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\"").concat(suffix);
}
final Process p = Runtime.getRuntime().exec(com);
JabRefExecutorService.INSTANCE.executeAndWait(() -> {
try (InputStream out = p.getErrorStream()) {
int c;
StringBuilder sb = new StringBuilder();
try {
while ((c = out.read()) != -1) {
sb.append((char) c);
}
} catch (IOException e) {
LOGGER.warn("Could not read from stderr.", e);
}
// Error stream has been closed. See if there were any errors:
if (!sb.toString().trim().isEmpty()) {
LOGGER.warn("Push to Emacs error: " + sb);
couldNotConnect = true;
}
} catch (IOException e) {
LOGGER.warn("File problem.", e);
}
});
} catch (IOException excep) {
couldNotCall = true;
LOGGER.warn("Problem pushing to Emacs.", excep);
}
}

The logs under Help -> View log should contain error/warning in case

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 18, 2023

@bahmanm
I'm sorry, but there are problems....
For JabRef to communicate with Emacs, it is absolutely necessary to start the server via the configuration file (init.el), but, if I try to load the server in this way, I get the error message I mentioned above, that is, that there is already a started server. 😭

BTW, I started Emacs without loading the server via configuration file: JabRef doesn't send anything, but according Help -> View Logs the app sent the citation command. In short, it would have worked, even if nothing happened!

Really, I don't know how to proceed, other than the above ways:

  • M-x server-force-delete and then M-x server-start from within Emacs or
  • sudo pkill emacs and then start Emacs with (server-start) enabled in init.el

@bahmanm
Copy link

bahmanm commented Aug 21, 2023

@Siedlerchr

Here is the command and the exeuction we send:

OK, thanks. Can you also let me know how do you invoke Emacs client? What are the switches/options?
I was able to mimic what JabRef tries to do w/ both Emacs started via systemctl and server-start.

That is, the following command inserted "Hello, world" in *scratch* in both cases.

$ emacsclient -e '(with-current-buffer (window-buffer) (insert "Hello, world"))'

@Doc73

according Help -> View Logs the app sent the citation command.

Can you try running Emacs via systemctl and sending the command from JabRef. Then open a client and check *Messages* and *Warnings* buffers. Is there anything noteworthy there?

@Siedlerchr
Copy link
Member

By default, the additional command line arguments are -n -e (can be configured in the preferences)

Starting itself is done using Java's Process Builder which, under the hood, calls the native OS implementation.
For another application, sublime text in #10104 I had to wrap the command in a shell command "sh", "-c", so that it gets executed from the terminal.

I can also build a new version which contains some more log output of the full command that is sent to Emacs if that helps.

grafik

@bahmanm
Copy link

bahmanm commented Aug 21, 2023

Noted @Siedlerchr. At this stage, I think it's best if I installed JabRef on my machine.

Can you share a sample TeX file w/ bibitems (I've got no idea what is that) so I can try to reproduce @Doc73's problem locally.?

@Siedlerchr
Copy link
Member

Siedlerchr commented Aug 21, 2023

You can download our sample file: https://github.com/JabRef/jabref/blob/main/src/test/resources/testbib/jabref-authors.bib
Just open it with JabRef. In Emacs, it's probably enough to open a plain text document.

You can download JabRef's deb file. https://github.com/JabRef/jabref/releases/tag/v5.9
(JabRef ships with bundled custom jdk, so no need to install java or anything)

(BibTeX and biblatex are text-based format for citations/references in LaTeX and JabRef is a GUI for managing and collecting this)

@bahmanm
Copy link

bahmanm commented Aug 21, 2023

Thanks. This works OOTB w/ Emacs run via systemd 🤔

@Doc73 In addition to checking *Messages* and *Warnings* buffers, can you also try to run Emacs via systemd and execute the following command in a terminal and share back the output here:

$ emacsclient -e '(with-current-buffer (window-buffer) (insert "Hello, world"))'

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 22, 2023

@bahmanm

  1. Boot PC
  2. $ systemctl --user status emacs
● emacs.service - Emacs text editor
     Loaded: loaded (/usr/lib/systemd/user/emacs.service; enabled; preset: enab>
     Active: active (running) since Tue 2023-08-22 10:33:20 CEST; 33s ago
  1. Start JabRef
  2. Start Emacs and open a txt file
  3. Send a citation from JabRef: no error in logs, but nothing happens in Emacs
  4. $ emacsclient -e '(with-current-buffer (window-buffer) (insert "Hello, world"))'
nil
  1. Test option -n -e in Jabref: nothing

In short: emacs daemon is not compatible with server-start, but server-start seems to be needed for Jabref to communicate with Emacs

@bahmanm
Copy link

bahmanm commented Aug 22, 2023

@Doc73 Were you able to see Hello, world in the current buffer (probably *scratch*) after you ran the command?

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 22, 2023

@bahmanm
I opened with Emacs a txt file, but nothing happened

@Siedlerchr
Copy link
Member

Maybe it's a different emacs version?

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 22, 2023

Emacs 29.1

https://packages.debian.org/sid/emacs

Thursday or Friday I'll do some tests with the version of Debian Stable (where I remember there wasn't issues)

@bahmanm
Copy link

bahmanm commented Aug 22, 2023

Same version here @Doc73 🤔

@monnier
Copy link

monnier commented Aug 22, 2023

Just to clarify: the "Emacs daemon" is an Emacs process that starts an "Emacs server". So it's not either/or.
My crystal ball tells me that when you don't run Emacs and JabRef does nothing but claims it successfully sent its request via emacsclient, the problem is that it successfully contacted your Emacs daemon (via its server) but that Emacs simply has no window/frame in which to show you the result so it just ignores the request (or displays it in a completely invisible window).

Maybe part of the problem is in "Start Emacs and open a txt file": you should "start Emacs" with emacsclient (so it contacts the daemon) otherwise that will create a fresh new Emacs session which can't start its own process because it collides with the Emacs daemon's server.

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 22, 2023

@monnier
I've been using jabref and emacs for years with no problems and know how they work.
It's just in this pc that it can't work.

I'll do other tests, now

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 22, 2023

@bahmanm
Copy link

bahmanm commented Aug 23, 2023

@Doc73 Probably I'm missing something but I noticed in both recordings that you run "Emacs (GUI)" which is NOT equal to "Emacs Client". That starts a standalone Emacs w/ no server. Can you try running "Emacs (Client)" and check the results?

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 23, 2023

@bahmanm
Because Emacs (Client) does nothing...
Video del 2023-08-23 08-16-15.webm

Here is an abstract of /usr/share/applications/emacsclient.desktop:

[Desktop Entry]
Name=Emacs (Client)
...
Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec /usr/bin/emacsclient --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec emacsclient --alternate-editor= --create-frame; fi" sh %F
Icon=emacs
...

[Desktop Action new-window]
Name=New Window
Exec=/usr/bin/emacsclient --alternate-editor= --create-frame %F

[Desktop Action new-instance]
Name=New Instance
Exec=emacs %F

The first command returns an error (sh: 1: [: missing ]), the second launches a terminal buffer (where emacsclient -e '(with-current-buffer (window-buffer) (insert "Hello, world"))' works), the third a GUI (where above mentioned command doesn't work).

@bahmanm
Copy link

bahmanm commented Aug 24, 2023

@Doc73 That shouldn't happen 🤔 The application "Emacs (Client)" should open an instance of the client whether you've run the daemon via systemd or (server-start).

Let's try this and see what happens:

$ pkill emacs
$ systemctl --user start emacs
$ emacsclient -c foo.txt

Then try to send something to Emacs.

Screencast.from.2023-08-24.03-20-57.webm

@Doc73
Copy link
Contributor Author

Doc73 commented Aug 25, 2023

@bahmanm
Now I can do some tests also in another machine with Debian Stable.

Here the result of systemctl --user status emacs.service on a freshly booted PC.

On Stable:

○ emacs.service - Emacs text editor
     Loaded: loaded (/usr/lib/systemd/user/emacs.service; disabled; preset: enabled)
     Active: inactive (dead)

On Sid:

● emacs.service - Emacs text editor
     Loaded: loaded (/usr/lib/systemd/user/emacs.service; enabled; preset: enabled)
     Active: active (running) since Fri 2023-08-25 17:06:01 CEST; 2min 5s ago

As a result, everything works fine on Stable: I can send citations from JabRef both to Emacs (Client) and to Emacs (GUI).
Unfortunately, I don't remember if I disabled the service on my Debian 12 Stable.
It goes without saying that if, on my stable, I start Emacs (Client), then I get the same errors on Emacs (GUI).

Remember that Emacs (Client) on Sid does not start anything, at least in my PC!

However the commands you indicated (in Sid)

$ pkill emacs
$ systemctl --user start emacs
$ emacsclient -c foo.txt

start the windows of Emacs which regularly receives the cites from Jabref! In short, in this case everything works perfectly!

@bahmanm
Copy link

bahmanm commented Aug 26, 2023

Oh, great that you did the extra test 👍

@Doc73 @Siedlerchr Uh, do you folks think my work here helping w/ Emacs'y things is done?

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

No branches or pull requests

5 participants