iqbalansari / restart-emacs

A simple emacs package to restart emacs from within emacs
GNU General Public License v3.0
154 stars 14 forks source link

Restart doesn't retain arguments. #11

Open Bost opened 6 years ago

Bost commented 6 years ago

It looks like the emacs process is not restarted the same way as it was started. The path to the binary is different and more importantlly the start parameters are not retained: Before restart:

$ pgrep --list-full emacs
2410 emacs --insecure

After M-x restart-emacs:

$ pgrep --list-full emacs
3573 /usr/local/bin/emacs

I observe this behavior in both versions: melpa 20170609.905 and also melpa-stable 0.1.1 Thx.

iqbalansari commented 6 years ago

Hi @Bost,

Thanks for the bug report and sorry for the delay in reply.

The path to binary is the same that Emacs was started with (see restart-emacs--get-emacs-binary which gets the binary path using invocation-name and invocation-directory). pgrep lists just the command line that process was started with (not the binary that was used)

You are correct about the rest of arguments, I wanted to add this feature, unfortunately there is no cross platform way to access the arguments, on Windows you cannot get the arguments at all, it requires a program which might not always be available. As such I avoided this implementing this. But now that I have request for this I guess I will implement this as a Linux only feature or something.

Thanks

Bost commented 6 years ago

Hi @iqbalansari,

there is no cross platform way to access the arguments, on Windows you cannot get the arguments at all, it requires a program which might not always be available.

For starters, please mention this in the documentation. Then we can ask the emacs developers if this missing program (i.e. functionality) shouldn't be implemented in the core of emacs? Thanks.

iqbalansari commented 6 years ago

Added to the Known Issues section in the README

Georgiy-Tugai commented 5 years ago

What about the command-line-args variable? I'm using Emacs 25.3 on Windows 10 and that variable appears to contain all command line arguments, including the path to the binary.

iqbalansari commented 5 years ago

Hi @Georgiy-Tugai,

If I remember correctly it does not retain all the arguments, only the ones that have not been processed by Emacs. From the documentation of command-line-args

Args passed by shell to Emacs, as a list of strings. Many arguments are deleted from the list as they are processed.


I'm using Emacs 25.3 on Windows 10 and that variable appears to contain all command line arguments

Interesting, are you sure of this? Can you start Emacs from the command with -nw -Q flags and confirm the value of command-line-args

Thanks

seagle0128 commented 5 years ago

I can confirm there is only binary path while I am using emacs 26.1 on Windows 10 with emacs -Q -nw.

command-line-args is a variable defined in ‘C source code’.
Its value is ("C:\\emacs\\bin\\emacs.exe")
Bost commented 1 year ago

Regarding "command line arguments not retained", it looks like this mitigates the problem, even though not completely solves it:

  (defun my=restart-spacemacs-guix--start-gui-using-sh (&optional args)
    "Start GUI version of Emacs using sh.

ARGS is the list arguments with which Emacs should be started"
    (let ((command
;;;; The command arguments returned by `ps' are munched together. Whitespace
;;;; chars are not escaped, that means the emacs invocation arguments can't be
;;;; reliably separated from each other. E.g. when started with:
;;;;     `emacs --eval '(setq my=var #t)'`
;;;; the `ps' returns "emacs --eval (setq my=var #t)", w/o the single quote
;;;; characters.
;;;;
;;;; However a bit of heuristic approach may be applied here. I.e. one may try
;;;; to apply `read-string` or `read-from-string` at anything what comes after
;;;; '--eval', assuming it is a valid sexp,i.e. surrounded by parens or alike.
           ;; (format "%s" (shell-command-to-string
           ;;               (format "ps -ho command -p %s" (emacs-pid))))
           "/path/to/emacs-start-script"  ;; or "/path/to/emacs-start-script & disown"
           ))
      (call-process "sh" nil 0 nil "-c" command)))

  (advice-add #'restart-emacs--start-gui-using-sh
              :override #'my=restart-spacemacs-guix--start-gui-using-sh)

Args passed by shell to Emacs, as a list of strings. Many arguments are deleted from the list as they are processed.

The Command-line argument processing is explained here https://github.com/emacs-mirror/emacs/blob/master/src/emacs.c#L1392

Maybe some sort of

strcpy(command-line-args, command-line-args-original);

could be made before the skip_args gets incremented, and the command-line-args-original can be used to get the args as they came in, when emacs was started.