unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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."



  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).