From: Samer Masterson <samer@samertm.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-devel@gnu.org
Subject: Re: [PATCH] switch to file buffer from command line args regardless of `initial-buffer-choice'
Date: Fri, 15 May 2015 20:11:03 -0700 [thread overview]
Message-ID: <87oall2p4o.fsf@f-box.i-did-not-set--mail-host-address--so-tickle-me> (raw)
In-Reply-To: <87fv7ge61j.fsf@f-box.i-did-not-set--mail-host-address--so-tickle-me>
Ping. Don't worry if you haven't gotten to this yet.
-s
Samer Masterson <samer@samertm.com> writes:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>> IIUC the problem you're trying to fix is specific to
>> initial-buffer-choice and does not happen to the default *scratch*.
>> Right?
>
> Correct.
>
>>
>>> - (switch-to-buffer
>>> - (if (buffer-live-p buf) buf (get-buffer-create "*scratch*"))
>>> - 'norecord)))
>>> + (unless (> file-count 0)
>>> + (switch-to-buffer
>>> + (if (buffer-live-p buf) buf (get-buffer-create "*scratch*"))
>>> + 'norecord))))
>>
>> So I don't understand why this patch applies to a part of the code that
>> handles initial-buffer-choice and *scratch* in a similar way.
>
> That section of the code is confusing. `initial-buffer-choice' opens
> *scratch* when its value is t, and that's what this line does:
>
> (if (buffer-live-p buf) buf (get-buffer-create "*scratch*"))
>
> It's unrelated to how *scratch* is (usually) the initial buffer when
> `inhibit-startup-screen' is t and `initial-buffer-choice' is nil.
>
> The function `command-line-1' relies on a bunch of implicit state to set
> up Emacs and is kind of hairy, so I refactored it a bit. This is how
> `command-line-1' works without my patch applied:
>
> Before `command-line-1' has been called, *scratch* is already open
> (unless the user put '(kill-buffer "*scratch*")' in their init, then
> *Messages* will be open, and so on).
>
> Then `command-line-1' goes through all the args and opens files as it
> processes them (and whether the file is opened in the current window or
> the other window depends on whether `inhibit-startup-screen' is
> non-nil).
>
> After it's finished processing the command line args, it switches to the
> buffer `initial-buffer-choice'. It does not open the startup screen if
> `initial-buffer-choice' is non-nil, and it does not switch to any files.
> It will open *Buffers List* if three or more files are given to it.
>
> The behavior with my patch: If Emacs is given one file arg, it's opened
> alongside `initial-buffer-choice'. If Emacs is given two or more file
> args, then it will display `initial-buffer-choice' and *Buffer List*,
> which is consistent with the current behavior when
> `initial-buffer-choice' is nil and Emacs is given more files than it can
> display.
>
> I've separated the command line processing logic for files from the
> buffer switching logic. This makes it much more clear what the final
> state of the windows will be. Also, whether the buffer list gets displayed is
> based on how many buffers are shown, not how many file args there are.
>
> Thanks in advance for the review!
>
> Best,
> Samer
>
> Patch below:
>
> From a8e7ec07cffa17719b88bf6022a463b7f812db24 Mon Sep 17 00:00:00 2001
> From: Samer Masterson <samer@samertm.com>
> Date: Fri, 1 May 2015 06:51:14 -0700
> Subject: [PATCH] Show files when `initial-buffer-choice' is non-nil
>
> * startup.el (command-line-1): When Emacs is given a file as an
> argument and `initial-buffer-choice' is non-nil, display both the file
> and `initial-buffer-choice'. For more than one file, show
> `initial-buffer-choice' and *Buffer List*. Refactor display-changing
> commands out of the command line arg parser.
> (initial-buffer-choice): Clarify docstring.
> ---
> etc/NEWS | 7 +
> lisp/startup.el | 581 +++++++++++++++++++++++++++++---------------------------
> 2 files changed, 310 insertions(+), 278 deletions(-)
>
> diff --git a/etc/NEWS b/etc/NEWS
> index e2b6b11..1193055 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -70,6 +70,13 @@ so if you want to use it, you can always take a copy from an older Emacs.
> \f
> * Startup Changes in Emacs 25.1
>
> +** When Emacs is given a file as a command line argument and
> +`initial-buffer-choice' is non-nil, display both the file and
> +`initial-buffer-choice'. When Emacs is given more than one file and
> +`initial-buffer-choice' is non-nil, show `initial-buffer-choice'
> +and *Buffer List*. This makes Emacs convenient to use from the
> +command line when `initial-buffer-choice' is non-nil.
> +
> \f
> * Changes in Emacs 25.1
>
> diff --git a/lisp/startup.el b/lisp/startup.el
> index cb8a6a9..b189f84 100644
> --- a/lisp/startup.el
> +++ b/lisp/startup.el
> @@ -47,6 +47,9 @@ visiting the file or directory that the string specifies. If the
> value is a function, call it with no arguments and switch to the buffer
> that it returns. If t, open the `*scratch*' buffer.
>
> +When `initial-buffer-choice' is non-nil, the startup screen is
> +inhibited.
> +
> If you use `emacsclient' with no target file, then it obeys any
> string or function value that this variable has."
> :type '(choice
> @@ -2145,238 +2148,238 @@ A fancy display is used on graphic displays, normal otherwise."
> (See the node Pure Storage in the Lisp manual for details.)"
> :warning))
>
> - (let ((file-count 0)
> - (command-line-args-left args-left)
> - first-file-buffer)
> - (when command-line-args-left
> - ;; We have command args; process them.
> - (let ((dir command-line-default-directory)
> - tem
> - ;; This approach loses for "-batch -L DIR --eval "(require foo)",
> - ;; if foo is intended to be found in DIR.
> - ;;
> - ;; The directories listed in --directory/-L options will *appear*
> - ;; at the front of `load-path' in the order they appear on the
> - ;; command-line. We cannot do this by *placing* them at the front
> - ;; in the order they appear, so we need this variable to hold them,
> - ;; temporarily.
> - ;;
> - ;; To DTRT we keep track of the splice point and modify `load-path'
> - ;; straight away upon any --directory/-L option.
> - splice
> - just-files ;; t if this follows the magic -- option.
> - ;; This includes our standard options' long versions
> - ;; and long versions of what's on command-switch-alist.
> - (longopts
> - (append '("--funcall" "--load" "--insert" "--kill"
> - "--directory" "--eval" "--execute" "--no-splash"
> - "--find-file" "--visit" "--file" "--no-desktop")
> - (mapcar (lambda (elt) (concat "-" (car elt)))
> - command-switch-alist)))
> - (line 0)
> - (column 0))
> -
> - ;; Add the long X options to longopts.
> - (dolist (tem command-line-x-option-alist)
> - (if (string-match "^--" (car tem))
> - (push (car tem) longopts)))
> -
> - ;; Add the long NS options to longopts.
> - (dolist (tem command-line-ns-option-alist)
> - (if (string-match "^--" (car tem))
> - (push (list (car tem)) longopts)))
> -
> - ;; Loop, processing options.
> - (while command-line-args-left
> - (let* ((argi (car command-line-args-left))
> - (orig-argi argi)
> - argval completion)
> - (setq command-line-args-left (cdr command-line-args-left))
> -
> - ;; Do preliminary decoding of the option.
> - (if just-files
> - ;; After --, don't look for options; treat all args as files.
> - (setq argi "")
> - ;; Convert long options to ordinary options
> - ;; and separate out an attached option argument into argval.
> - (when (string-match "\\`\\(--[^=]*\\)=" argi)
> - (setq argval (substring argi (match-end 0))
> - argi (match-string 1 argi)))
> - (when (string-match "\\`--?[^-]" orig-argi)
> - (setq completion (try-completion argi longopts))
> - (if (eq completion t)
> - (setq argi (substring argi 1))
> - (if (stringp completion)
> - (let ((elt (member completion longopts)))
> - (or elt
> - (error "Option `%s' is ambiguous" argi))
> - (setq argi (substring (car elt) 1)))
> - (setq argval nil
> - argi orig-argi)))))
> -
> - ;; Execute the option.
> - (cond ((setq tem (assoc argi command-switch-alist))
> - (if argval
> - (let ((command-line-args-left
> - (cons argval command-line-args-left)))
> - (funcall (cdr tem) argi))
> - (funcall (cdr tem) argi)))
> -
> - ((equal argi "-no-splash")
> - (setq inhibit-startup-screen t))
> -
> - ((member argi '("-f" ; what the manual claims
> - "-funcall"
> - "-e")) ; what the source used to say
> - (setq inhibit-startup-screen t)
> - (setq tem (intern (or argval (pop command-line-args-left))))
> - (if (commandp tem)
> - (command-execute tem)
> - (funcall tem)))
> -
> - ((member argi '("-eval" "-execute"))
> - (setq inhibit-startup-screen t)
> - (eval (read (or argval (pop command-line-args-left)))))
> -
> - ((member argi '("-L" "-directory"))
> - ;; -L :/foo adds /foo to the _end_ of load-path.
> - (let (append)
> - (if (string-match-p
> - (format "\\`%s" path-separator)
> - (setq tem (or argval (pop command-line-args-left))))
> - (setq tem (substring tem 1)
> - append t))
> - (setq tem (expand-file-name
> - (command-line-normalize-file-name tem)))
> - (cond (append (setq load-path
> - (append load-path (list tem)))
> - (if splice (setq splice load-path)))
> - (splice (setcdr splice (cons tem (cdr splice)))
> - (setq splice (cdr splice)))
> - (t (setq load-path (cons tem load-path)
> - splice load-path)))))
> -
> - ((member argi '("-l" "-load"))
> - (let* ((file (command-line-normalize-file-name
> - (or argval (pop command-line-args-left))))
> - ;; Take file from default dir if it exists there;
> - ;; otherwise let `load' search for it.
> - (file-ex (expand-file-name file)))
> - (when (file-exists-p file-ex)
> - (setq file file-ex))
> - (load file nil t)))
> -
> - ;; This is used to handle -script. It's not clear
> - ;; we need to document it (it is totally internal).
> - ((member argi '("-scriptload"))
> - (let* ((file (command-line-normalize-file-name
> - (or argval (pop command-line-args-left))))
> - ;; Take file from default dir.
> - (file-ex (expand-file-name file)))
> - (load file-ex nil t t)))
> -
> - ((equal argi "-insert")
> - (setq inhibit-startup-screen t)
> - (setq tem (or argval (pop command-line-args-left)))
> - (or (stringp tem)
> - (error "File name omitted from `-insert' option"))
> - (insert-file-contents (command-line-normalize-file-name tem)))
> -
> - ((equal argi "-kill")
> - (kill-emacs t))
> -
> - ;; This is for when they use --no-desktop with -q, or
> - ;; don't load Desktop in their .emacs. If desktop.el
> - ;; _is_ loaded, it will handle this switch, and we
> - ;; won't see it by the time we get here.
> - ((equal argi "-no-desktop")
> - (message "\"--no-desktop\" ignored because the Desktop package is not loaded"))
> -
> - ((string-match "^\\+[0-9]+\\'" argi)
> - (setq line (string-to-number argi)))
> -
> - ((string-match "^\\+\\([0-9]+\\):\\([0-9]+\\)\\'" argi)
> - (setq line (string-to-number (match-string 1 argi))
> - column (string-to-number (match-string 2 argi))))
> -
> - ((setq tem (assoc orig-argi command-line-x-option-alist))
> - ;; Ignore X-windows options and their args if not using X.
> - (setq command-line-args-left
> - (nthcdr (nth 1 tem) command-line-args-left)))
> -
> - ((setq tem (assoc orig-argi command-line-ns-option-alist))
> - ;; Ignore NS-windows options and their args if not using NS.
> - (setq command-line-args-left
> - (nthcdr (nth 1 tem) command-line-args-left)))
> -
> - ((member argi '("-find-file" "-file" "-visit"))
> - (setq inhibit-startup-screen t)
> - ;; An explicit option to specify visiting a file.
> - (setq tem (or argval (pop command-line-args-left)))
> - (unless (stringp tem)
> - (error "File name omitted from `%s' option" argi))
> - (setq file-count (1+ file-count))
> - (let ((file (expand-file-name
> - (command-line-normalize-file-name tem)
> - dir)))
> - (if (= file-count 1)
> - (setq first-file-buffer (find-file file))
> - (find-file-other-window file)))
> - (unless (zerop line)
> - (goto-char (point-min))
> - (forward-line (1- line)))
> - (setq line 0)
> - (unless (< column 1)
> - (move-to-column (1- column)))
> - (setq column 0))
> -
> - ;; These command lines now have no effect.
> - ((string-match "\\`--?\\(no-\\)?\\(uni\\|multi\\)byte$" argi)
> - (display-warning 'initialization
> - (format "Ignoring obsolete arg %s" argi)))
> -
> - ((equal argi "--")
> - (setq just-files t))
> - (t
> - ;; We have almost exhausted our options. See if the
> - ;; user has made any other command-line options available
> - (let ((hooks command-line-functions)
> - (did-hook nil))
> - (while (and hooks
> - (not (setq did-hook (funcall (car hooks)))))
> - (setq hooks (cdr hooks)))
> - (if (not did-hook)
> - ;; Presume that the argument is a file name.
> - (progn
> - (if (string-match "\\`-" argi)
> - (error "Unknown option `%s'" argi))
> - (unless initial-window-system
> - (setq inhibit-startup-screen t))
> - (setq file-count (1+ file-count))
> - (let ((file
> - (expand-file-name
> - (command-line-normalize-file-name orig-argi)
> - dir)))
> - (cond ((= file-count 1)
> - (setq first-file-buffer (find-file file)))
> - (inhibit-startup-screen
> - (find-file-other-window file))
> - (t (find-file file))))
> - (unless (zerop line)
> - (goto-char (point-min))
> - (forward-line (1- line)))
> - (setq line 0)
> - (unless (< column 1)
> - (move-to-column (1- column)))
> - (setq column 0))))))
> - ;; In unusual circumstances, the execution of Lisp code due
> - ;; to command-line options can cause the last visible frame
> - ;; to be deleted. In this case, kill emacs to avoid an
> - ;; abort later.
> - (unless (frame-live-p (selected-frame)) (kill-emacs nil))))))
> + ;; `displayable-buffers' is a list of buffers that may be displayed,
> + ;; which includes files parsed from the command line arguments and
> + ;; `initial-buffer-choice'. All of the display logic happens at the
> + ;; end of this `let'. As files as processed from the command line
> + ;; arguments, their buffers are prepended to `displayable-buffers'
> + ;; but they are not displayed until command line parsing has
> + ;; finished.
> + (let ((displayable-buffers nil))
> + ;; This `let' processes the command line arguments.
> + (let ((command-line-args-left args-left))
> + (when command-line-args-left
> + ;; We have command args; process them.
> + (let* ((dir command-line-default-directory)
> + tem
> + ;; This approach loses for "-batch -L DIR --eval "(require foo)",
> + ;; if foo is intended to be found in DIR.
> + ;;
> + ;; The directories listed in --directory/-L options will *appear*
> + ;; at the front of `load-path' in the order they appear on the
> + ;; command-line. We cannot do this by *placing* them at the front
> + ;; in the order they appear, so we need this variable to hold them,
> + ;; temporarily.
> + ;;
> + ;; To DTRT we keep track of the splice point and modify `load-path'
> + ;; straight away upon any --directory/-L option.
> + splice
> + just-files ;; t if this follows the magic -- option.
> + ;; This includes our standard options' long versions
> + ;; and long versions of what's on command-switch-alist.
> + (longopts
> + (append '("--funcall" "--load" "--insert" "--kill"
> + "--directory" "--eval" "--execute" "--no-splash"
> + "--find-file" "--visit" "--file" "--no-desktop")
> + (mapcar (lambda (elt) (concat "-" (car elt)))
> + command-switch-alist)))
> + (line 0)
> + (column 0)
> + ;; `process-file-arg' opens a file buffer for `name'
> + ;; without switching to the buffer, adds the buffer to
> + ;; `displayable-buffers', and puts the point at
> + ;; `line':`column'. `line' and `column' are both reset
> + ;; to zero when `process-file-arg' returns.
> + (process-file-arg
> + (lambda (name)
> + (let* ((file (expand-file-name
> + (command-line-normalize-file-name name)
> + dir))
> + (buf (find-file-noselect file)))
> + (setq displayable-buffers (cons buf displayable-buffers))
> + (with-current-buffer buf
> + (unless (zerop line)
> + (goto-char (point-min))
> + (forward-line (1- line)))
> + (setq line 0)
> + (unless (< column 1)
> + (move-to-column (1- column)))
> + (setq column 0))))))
> +
> + ;; Add the long X options to longopts.
> + (dolist (tem command-line-x-option-alist)
> + (if (string-match "^--" (car tem))
> + (push (car tem) longopts)))
> +
> + ;; Add the long NS options to longopts.
> + (dolist (tem command-line-ns-option-alist)
> + (if (string-match "^--" (car tem))
> + (push (list (car tem)) longopts)))
> +
> + ;; Loop, processing options.
> + (while command-line-args-left
> + (let* ((argi (car command-line-args-left))
> + (orig-argi argi)
> + argval completion)
> + (setq command-line-args-left (cdr command-line-args-left))
> +
> + ;; Do preliminary decoding of the option.
> + (if just-files
> + ;; After --, don't look for options; treat all args as files.
> + (setq argi "")
> + ;; Convert long options to ordinary options
> + ;; and separate out an attached option argument into argval.
> + (when (string-match "\\`\\(--[^=]*\\)=" argi)
> + (setq argval (substring argi (match-end 0))
> + argi (match-string 1 argi)))
> + (when (string-match "\\`--?[^-]" orig-argi)
> + (setq completion (try-completion argi longopts))
> + (if (eq completion t)
> + (setq argi (substring argi 1))
> + (if (stringp completion)
> + (let ((elt (member completion longopts)))
> + (or elt
> + (error "Option `%s' is ambiguous" argi))
> + (setq argi (substring (car elt) 1)))
> + (setq argval nil
> + argi orig-argi)))))
> +
> + ;; Execute the option.
> + (cond ((setq tem (assoc argi command-switch-alist))
> + (if argval
> + (let ((command-line-args-left
> + (cons argval command-line-args-left)))
> + (funcall (cdr tem) argi))
> + (funcall (cdr tem) argi)))
> +
> + ((equal argi "-no-splash")
> + (setq inhibit-startup-screen t))
> +
> + ((member argi '("-f" ; what the manual claims
> + "-funcall"
> + "-e")) ; what the source used to say
> + (setq inhibit-startup-screen t)
> + (setq tem (intern (or argval (pop command-line-args-left))))
> + (if (commandp tem)
> + (command-execute tem)
> + (funcall tem)))
> +
> + ((member argi '("-eval" "-execute"))
> + (setq inhibit-startup-screen t)
> + (eval (read (or argval (pop command-line-args-left)))))
> +
> + ((member argi '("-L" "-directory"))
> + ;; -L :/foo adds /foo to the _end_ of load-path.
> + (let (append)
> + (if (string-match-p
> + (format "\\`%s" path-separator)
> + (setq tem (or argval (pop command-line-args-left))))
> + (setq tem (substring tem 1)
> + append t))
> + (setq tem (expand-file-name
> + (command-line-normalize-file-name tem)))
> + (cond (append (setq load-path
> + (append load-path (list tem)))
> + (if splice (setq splice load-path)))
> + (splice (setcdr splice (cons tem (cdr splice)))
> + (setq splice (cdr splice)))
> + (t (setq load-path (cons tem load-path)
> + splice load-path)))))
> +
> + ((member argi '("-l" "-load"))
> + (let* ((file (command-line-normalize-file-name
> + (or argval (pop command-line-args-left))))
> + ;; Take file from default dir if it exists there;
> + ;; otherwise let `load' search for it.
> + (file-ex (expand-file-name file)))
> + (when (file-exists-p file-ex)
> + (setq file file-ex))
> + (load file nil t)))
> +
> + ;; This is used to handle -script. It's not clear
> + ;; we need to document it (it is totally internal).
> + ((member argi '("-scriptload"))
> + (let* ((file (command-line-normalize-file-name
> + (or argval (pop command-line-args-left))))
> + ;; Take file from default dir.
> + (file-ex (expand-file-name file)))
> + (load file-ex nil t t)))
> +
> + ((equal argi "-insert")
> + (setq inhibit-startup-screen t)
> + (setq tem (or argval (pop command-line-args-left)))
> + (or (stringp tem)
> + (error "File name omitted from `-insert' option"))
> + (insert-file-contents (command-line-normalize-file-name tem)))
> +
> + ((equal argi "-kill")
> + (kill-emacs t))
> +
> + ;; This is for when they use --no-desktop with -q, or
> + ;; don't load Desktop in their .emacs. If desktop.el
> + ;; _is_ loaded, it will handle this switch, and we
> + ;; won't see it by the time we get here.
> + ((equal argi "-no-desktop")
> + (message "\"--no-desktop\" ignored because the Desktop package is not loaded"))
> +
> + ((string-match "^\\+[0-9]+\\'" argi)
> + (setq line (string-to-number argi)))
> +
> + ((string-match "^\\+\\([0-9]+\\):\\([0-9]+\\)\\'" argi)
> + (setq line (string-to-number (match-string 1 argi))
> + column (string-to-number (match-string 2 argi))))
> +
> + ((setq tem (assoc orig-argi command-line-x-option-alist))
> + ;; Ignore X-windows options and their args if not using X.
> + (setq command-line-args-left
> + (nthcdr (nth 1 tem) command-line-args-left)))
> +
> + ((setq tem (assoc orig-argi command-line-ns-option-alist))
> + ;; Ignore NS-windows options and their args if not using NS.
> + (setq command-line-args-left
> + (nthcdr (nth 1 tem) command-line-args-left)))
> +
> + ((member argi '("-find-file" "-file" "-visit"))
> + (setq inhibit-startup-screen t)
> + ;; An explicit option to specify visiting a file.
> + (setq tem (or argval (pop command-line-args-left)))
> + (unless (stringp tem)
> + (error "File name omitted from `%s' option" argi))
> + (funcall process-file-arg tem))
> +
> + ;; These command lines now have no effect.
> + ((string-match "\\`--?\\(no-\\)?\\(uni\\|multi\\)byte$" argi)
> + (display-warning 'initialization
> + (format "Ignoring obsolete arg %s" argi)))
> +
> + ((equal argi "--")
> + (setq just-files t))
> + (t
> + ;; We have almost exhausted our options. See if the
> + ;; user has made any other command-line options available
> + (let ((hooks command-line-functions)
> + (did-hook nil))
> + (while (and hooks
> + (not (setq did-hook (funcall (car hooks)))))
> + (setq hooks (cdr hooks)))
> + (unless did-hook
> + ;; Presume that the argument is a file name.
> + (if (string-match "\\`-" argi)
> + (error "Unknown option `%s'" argi))
> + ;; FIXME: Why do we only inhibit the startup
> + ;; screen for -nw?
> + (unless initial-window-system
> + (setq inhibit-startup-screen t))
> + (funcall process-file-arg orig-argi)))))
> +
> + ;; In unusual circumstances, the execution of Lisp code due
> + ;; to command-line options can cause the last visible frame
> + ;; to be deleted. In this case, kill emacs to avoid an
> + ;; abort later.
> + (unless (frame-live-p (selected-frame)) (kill-emacs nil)))))))
>
> (when (eq initial-buffer-choice t)
> - ;; When initial-buffer-choice equals t make sure that *scratch*
> + ;; When `initial-buffer-choice' equals t make sure that *scratch*
> ;; exists.
> (get-buffer-create "*scratch*"))
>
> @@ -2389,59 +2392,81 @@ A fancy display is used on graphic displays, normal otherwise."
> (insert initial-scratch-message)
> (set-buffer-modified-p nil))))
>
> + ;; Prepend `initial-buffer-choice' to `displayable-buffers'.
> (when initial-buffer-choice
> (let ((buf
> (cond ((stringp initial-buffer-choice)
> (find-file-noselect initial-buffer-choice))
> ((functionp initial-buffer-choice)
> - (funcall initial-buffer-choice)))))
> - (switch-to-buffer
> - (if (buffer-live-p buf) buf (get-buffer-create "*scratch*"))
> - 'norecord)))
> -
> - (if (or inhibit-startup-screen
> - initial-buffer-choice
> - noninteractive
> - (daemonp)
> - inhibit-x-resources)
> -
> - ;; Not displaying a startup screen. If 3 or more files
> - ;; visited, and not all visible, show user what they all are.
> - (and (> file-count 2)
> - (not noninteractive)
> - (not inhibit-startup-buffer-menu)
> - (or (get-buffer-window first-file-buffer)
> - (list-buffers)))
> -
> - ;; Display a startup screen, after some preparations.
> -
> - ;; If there are no switches to process, we might as well
> - ;; run this hook now, and there may be some need to do it
> - ;; before doing any output.
> - (run-hooks 'emacs-startup-hook 'term-setup-hook)
> -
> - ;; It's important to notice the user settings before we
> - ;; display the startup message; otherwise, the settings
> - ;; won't take effect until the user gives the first
> - ;; keystroke, and that's distracting.
> - (when (fboundp 'frame-notice-user-settings)
> - (frame-notice-user-settings))
> -
> - ;; If there are no switches to process, we might as well
> - ;; run this hook now, and there may be some need to do it
> - ;; before doing any output.
> - (run-hooks 'window-setup-hook)
> -
> - (setq inhibit-startup-hooks t)
> -
> - ;; ;; Do this now to avoid an annoying delay if the user
> - ;; ;; clicks the menu bar during the sit-for.
> - ;; (when (display-popup-menus-p)
> - ;; (precompute-menubar-bindings))
> - ;; (with-no-warnings
> - ;; (setq menubar-bindings-done t))
> -
> - (display-startup-screen (> file-count 0)))))
> + (funcall initial-buffer-choice))
> + ((eq initial-buffer-choice t)
> + (get-buffer-create "*scratch*"))
> + (t
> + (error "initial-buffer-choice must be a string, a function, or t.")))))
> + (unless (buffer-live-p buf)
> + (error "initial-buffer-choice is not a live buffer."))
> + (setq displayable-buffers (cons buf displayable-buffers))))
> +
> + ;; Display the first two buffers in `displayable-buffers'. If
> + ;; `initial-buffer-choice' is non-nil, its buffer will be the
> + ;; first buffer in `displayable-buffers'. The first buffer will
> + ;; be focused.
> + (let ((displayable-buffers-len (length displayable-buffers))
> + ;; `nondisplayed-buffers-p' is true if there exist buffers
> + ;; in `displayable-buffers' that were not displayed to the
> + ;; user.
> + (nondisplayed-buffers-p nil))
> + (when (> displayable-buffers-len 0)
> + (switch-to-buffer (car displayable-buffers)))
> + (when (> displayable-buffers-len 1)
> + (switch-to-buffer-other-window (car (cdr displayable-buffers)))
> + ;; Focus on the first buffer.
> + (other-window -1))
> + (when (> displayable-buffers-len 2)
> + (setq nondisplayed-buffers-p t))
> +
> + (if (or inhibit-startup-screen
> + initial-buffer-choice
> + noninteractive
> + (daemonp)
> + inhibit-x-resources)
> +
> + ;; Not displaying a startup screen. Display *Buffer List* if
> + ;; there exist buffers that were not displayed.
> + (when (and nondisplayed-buffers-p
> + (not noninteractive)
> + (not inhibit-startup-buffer-menu))
> + (list-buffers))
> +
> + ;; Display a startup screen, after some preparations.
> +
> + ;; If there are no switches to process, we might as well
> + ;; run this hook now, and there may be some need to do it
> + ;; before doing any output.
> + (run-hooks 'emacs-startup-hook 'term-setup-hook)
> +
> + ;; It's important to notice the user settings before we
> + ;; display the startup message; otherwise, the settings
> + ;; won't take effect until the user gives the first
> + ;; keystroke, and that's distracting.
> + (when (fboundp 'frame-notice-user-settings)
> + (frame-notice-user-settings))
> +
> + ;; If there are no switches to process, we might as well
> + ;; run this hook now, and there may be some need to do it
> + ;; before doing any output.
> + (run-hooks 'window-setup-hook)
> +
> + (setq inhibit-startup-hooks t)
> +
> + ;; ;; Do this now to avoid an annoying delay if the user
> + ;; ;; clicks the menu bar during the sit-for.
> + ;; (when (display-popup-menus-p)
> + ;; (precompute-menubar-bindings))
> + ;; (with-no-warnings
> + ;; (setq menubar-bindings-done t))
> +
> + (display-startup-screen (> displayable-buffers-len 0))))))
>
> (defun command-line-normalize-file-name (file)
> "Collapse multiple slashes to one, to handle non-Emacs file names."
next prev parent reply other threads:[~2015-05-16 3:11 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-02 8:07 [PATCH] switch to file buffer from command line args regardless of `initial-buffer-choice' Samer Masterson
2015-03-13 22:11 ` Stefan Monnier
2015-05-01 14:17 ` Samer Masterson
2015-05-16 3:11 ` Samer Masterson [this message]
2015-05-20 18:36 ` Stefan Monnier
2015-05-28 21:34 ` Samer Masterson
2015-05-29 5:48 ` Eli Zaretskii
2015-05-29 8:02 ` Samer Masterson
2015-08-03 14:56 ` Rasmus
[not found] ` <CAP6_t8gsmwPj5vkBQ4eegYXYcfmVAtHb+mnrUMYPyZwDXZ8DRw@mail.gmail.com>
[not found] ` <CAP6_t8gDr0y_WvwO43nXOFLU5h4hC-nnpjAmC-wDe7dYcTuwyw@mail.gmail.com>
[not found] ` <874mkdjwt8.fsf@gmx.us>
2015-08-05 20:46 ` Samer Masterson
2015-08-07 15:33 ` Stefan Monnier
2015-08-07 17:42 ` Samer Masterson
2015-08-07 17:42 ` Samer Masterson
2015-08-07 21:22 ` Stefan Monnier
2015-08-10 18:16 ` Samer Masterson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87oall2p4o.fsf@f-box.i-did-not-set--mail-host-address--so-tickle-me \
--to=samer@samertm.com \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).