1

What variable can Emacs Lisp access, to know the filenames specified on the command line that was used to invoke this Emacs session?

The general command-line-args contains the remaining command-line arguments; but the filenames specified to Emacs are not necessarily equal to that list.

For example, a filename can be specified as a simple positional argument; or can be specified as an argument to the --file or --find-file options, etc.; in principle, the difference between emacs and emacsclient command-line syntax might make a difference; etc.

Rather than making assumptions about how the command-line arguments relate to the filenames specified, I want to make use of the fact Emacs has already done this at start-up time, and should already know what filenames were specified.

Does Emacs keep the list of filenames, specified on the command line, for opening in this Emacs session? In which variable?

2 Answers 2

1

If you look in startup.el you will find the function command-line-1. It is long but quite easy to follow. You will notice that it defines a helper function called process-file-arg, then calls it whenever it sees arguments like --find-file, --file, --visit, etc. All it does is open the file in a buffer, add the file name to the history of opened files, and then move point to a specific line and character if requested.

Therefore, you can either consult file-name-history, or use buffer-list to examine the list of open buffers. Of course, both of those are modified further as the user uses Emacs. Perhaps if you describe what you are ultimately trying to do, there will be a better answer.

3
  • So the OP could save file-name-history into their own variable at the beginning of the init file and have it available for the rest of the session. Probably not quite enough in all circumstances, but close enough.
    – NickD
    Dec 20, 2022 at 15:24
  • 2
    This will not work if the init file sets file-name-history to some state saved in an earlier session. Loading the init file is step 14 in the startup while opening the files from the command line is step 25. Maybe, (cl-letf (((symbol-function 'file-history--add) (lambda ...)))) in an advice of command-line-1 would work.
    – Tobias
    Dec 20, 2022 at 18:04
  • Maybe the thing to do then is to remember command-line-args-left in a user's own variable at the end of the init file? Assuming that the init file does not touch command-line-args-left...
    – NickD
    Dec 21, 2022 at 21:58
1

It may be that the init file opens buffers and sets file-name-history to some state saved in an earlier session.

Loading the init file is step 14 in the startup while opening the files from the command line is step 25.

Therefore, just exploring the list of open buffers or looking at file-name-history after starting Emacs does not work in general.

The following code snippet which you can paste into your init file, advices file-name-history--add locally in command-line-1 such that it collects the file names determined in command-line-1 in the new variable command-line-files.

(require 'cl-lib)

(defvar command-line-files nil
  "List of file names discovered through `command-line-1'.")

(defun command-line-1-get-files (fun &rest args)
  "Populate `command-line-files' in `command-line-1'."
  (cl-letf* ((old-file-history--add (symbol-function 'file-name-history--add))
         ((symbol-function 'file-name-history--add)
          (lambda (file)
        (push (abbreviate-file-name file) command-line-files)
        (funcall old-file-history--add file))))
    (apply fun args)))


(advice-add 'command-line-1 :around #'command-line-1-get-files)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.