GNU bug report logs - #13251
Wishlist: Add ability to set initial buffer for new frames.

Previous Next

Package: emacs;

Reported by: Constantin Kulikov <zxnotdead <at> gmail.com>

Date: Fri, 21 Dec 2012 21:18:02 UTC

Severity: wishlist

Done: martin rudalics <rudalics <at> gmx.at>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 13251 in the body.
You can then email your comments to 13251 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Fri, 21 Dec 2012 21:18:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Constantin Kulikov <zxnotdead <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 21 Dec 2012 21:18:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Constantin Kulikov <zxnotdead <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Wishlist: Add ability to set initial buffer for new frames.
Date: Sat, 22 Dec 2012 00:16:58 +0300
[Message part 1 (text/plain, inline)]
// Discussion in devel.
https://lists.gnu.org/archive/html/emacs-devel/2012-12/msg00521.html
Short:
I want to be able to set buffer that will be displayed in window of newly
created frame.
I need it for my emacs package, that will save and restore some emacs state
including
last window configurations, opened and displayed buffers and such.
I tried this: add hook to `after-make-frame-functions'. Inside this hook I
do
`(switch-to-buffer <some-buffer>)' and frame is switched to that
<some-buffer> at first,
but after a short time it's switched to *scratch*.

The one way I found how to overcome this behaviour is by setting the
`initial-buffer-choice' in the `after-make-frame-functions' hook. One
drawback of this
approach is that it could only be set to name of file, t or nil and so
there is no way to
force switching to buffer without underlying file. This could be fixed int
server.el:1258
replacing

  (unless (or files commands)
        (if (stringp initial-buffer-choice)
        (find-file initial-buffer-choice)
          (switch-to-buffer (get-buffer-create "*scratch*")
                'norecord)))

to
          (unless (or files commands)
            (switch-to-buffer
             (get-buffer-create
              (or (cond
                   ((stringp initial-buffer-choice) (find-file-noselect
initial-buffer-choice))
                   ((functionp initial-buffer-choice) (funcall
initial-buffer-choice)))
                  "*scratch*"))
             'norecord))

and modified defcustom in in startup.el:41 would be:

(defcustom initial-buffer-choice nil
  "Buffer to show after starting Emacs.
If the value is nil and `inhibit-startup-screen' is nil, show the
startup screen.  If the value is a string, visit the specified file
or directory using `find-file'.  If t, open the `*scratch*'
buffer. If function, switch to a buffer returned by this function.

A string value also causes emacsclient to open the specified file
or directory when no target file is specified."
  :type '(choice
      (const     :tag "Startup screen" nil)
      (directory :tag "Directory" :value "~/")
      (file      :tag "File" :value "~/.emacs")
      (function  :tag "Function")
      (const     :tag "Lisp scratch buffer" t))
  :version "23.1"
  :group 'initialization)

This code allows setting `initial-buffer-choice' to a function returning
needed buffer.
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Fri, 21 Dec 2012 21:31:01 GMT) Full text and rfc822 format available.

Message #8 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: Constantin Kulikov <zxnotdead <at> gmail.com>
To: 13251 <at> debbugs.gnu.org
Subject: Re: Wishlist: Add ability to set initial buffer for new frames.
Date: Sat, 22 Dec 2012 00:30:03 +0300
[Message part 1 (text/plain, inline)]
ah sorry, don't need that `or' in server.el:
          (unless (or files commands)
            (switch-to-buffer
             (get-buffer-create
              (cond
               ((stringp initial-buffer-choice) (find-file-noselect
initial-buffer-choice))
               ((functionp initial-buffer-choice) (funcall
initial-buffer-choice))
               (t "*scratch*")))
             'norecord))



2012/12/22 Constantin Kulikov <zxnotdead <at> gmail.com>

> // Discussion in devel.
> https://lists.gnu.org/archive/html/emacs-devel/2012-12/msg00521.html
> Short:
> I want to be able to set buffer that will be displayed in window of newly
> created frame.
> I need it for my emacs package, that will save and restore some emacs
> state including
> last window configurations, opened and displayed buffers and such.
> I tried this: add hook to `after-make-frame-functions'. Inside this hook I
> do
> `(switch-to-buffer <some-buffer>)' and frame is switched to that
> <some-buffer> at first,
> but after a short time it's switched to *scratch*.
>
> The one way I found how to overcome this behaviour is by setting the
> `initial-buffer-choice' in the `after-make-frame-functions' hook. One
> drawback of this
> approach is that it could only be set to name of file, t or nil and so
> there is no way to
> force switching to buffer without underlying file. This could be fixed int
> server.el:1258
> replacing
>
>   (unless (or files commands)
>         (if (stringp initial-buffer-choice)
>         (find-file initial-buffer-choice)
>           (switch-to-buffer (get-buffer-create "*scratch*")
>                 'norecord)))
>
> to
>           (unless (or files commands)
>             (switch-to-buffer
>              (get-buffer-create
>               (or (cond
>                    ((stringp initial-buffer-choice) (find-file-noselect
> initial-buffer-choice))
>                    ((functionp initial-buffer-choice) (funcall
> initial-buffer-choice)))
>                   "*scratch*"))
>              'norecord))
>
> and modified defcustom in in startup.el:41 would be:
>
> (defcustom initial-buffer-choice nil
>   "Buffer to show after starting Emacs.
> If the value is nil and `inhibit-startup-screen' is nil, show the
> startup screen.  If the value is a string, visit the specified file
> or directory using `find-file'.  If t, open the `*scratch*'
> buffer. If function, switch to a buffer returned by this function.
>
> A string value also causes emacsclient to open the specified file
> or directory when no target file is specified."
>   :type '(choice
>       (const     :tag "Startup screen" nil)
>       (directory :tag "Directory" :value "~/")
>       (file      :tag "File" :value "~/.emacs")
>       (function  :tag "Function")
>       (const     :tag "Lisp scratch buffer" t))
>   :version "23.1"
>   :group 'initialization)
>
> This code allows setting `initial-buffer-choice' to a function returning
> needed buffer.
>
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Sat, 22 Dec 2012 15:43:03 GMT) Full text and rfc822 format available.

Message #11 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Constantin Kulikov <zxnotdead <at> gmail.com>
Cc: 13251 <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Sat, 22 Dec 2012 16:42:21 +0100
> (defcustom initial-buffer-choice nil
>   "Buffer to show after starting Emacs.
> If the value is nil and `inhibit-startup-screen' is nil, show the
> startup screen.  If the value is a string, visit the specified file
> or directory using `find-file'.  If t, open the `*scratch*'
> buffer. If function, switch to a buffer returned by this function.

As for the last sentence I'd prefer "If it is a function, switch to the
buffer returned by that function."

> A string value also causes emacsclient to open the specified file
> or directory when no target file is specified."
>   :type '(choice
>       (const     :tag "Startup screen" nil)
>       (directory :tag "Directory" :value "~/")
>       (file      :tag "File" :value "~/.emacs")
>       (function  :tag "Function")
>       (const     :tag "Lisp scratch buffer" t))
>   :version "23.1"

Too late for "23.1" use "24.4" instead.

>   :group 'initialization)
>
> This code allows setting `initial-buffer-choice' to a function returning
> needed buffer.

Could you please send us a patch based on these remarks (including the
change you sketched in your second mail)?

Thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Sat, 22 Dec 2012 19:52:02 GMT) Full text and rfc822 format available.

Message #14 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: Constantin Kulikov <zxnotdead <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 13251 <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Sat, 22 Dec 2012 22:51:25 +0300
[Message part 1 (text/plain, inline)]
Thanks for the tips.



2012/12/22 martin rudalics <rudalics <at> gmx.at>

> > (defcustom initial-buffer-choice nil
> >   "Buffer to show after starting Emacs.
> > If the value is nil and `inhibit-startup-screen' is nil, show the
> > startup screen.  If the value is a string, visit the specified file
> > or directory using `find-file'.  If t, open the `*scratch*'
> > buffer. If function, switch to a buffer returned by this function.
>
> As for the last sentence I'd prefer "If it is a function, switch to the
> buffer returned by that function."
>
> > A string value also causes emacsclient to open the specified file
> > or directory when no target file is specified."
> >   :type '(choice
> >       (const     :tag "Startup screen" nil)
> >       (directory :tag "Directory" :value "~/")
> >       (file      :tag "File" :value "~/.emacs")
> >       (function  :tag "Function")
> >       (const     :tag "Lisp scratch buffer" t))
> >   :version "23.1"
>
> Too late for "23.1" use "24.4" instead.
>
> >   :group 'initialization)
> >
> > This code allows setting `initial-buffer-choice' to a function returning
> > needed buffer.
>
> Could you please send us a patch based on these remarks (including the
> change you sketched in your second mail)?
>
> Thanks, martin
>
[Message part 2 (text/html, inline)]
[initial-buffer-choice-as-function.patch (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Sat, 22 Dec 2012 20:19:02 GMT) Full text and rfc822 format available.

Message #17 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: Constantin Kulikov <zxnotdead <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 13251 <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Sat, 22 Dec 2012 23:18:28 +0300
[Message part 1 (text/plain, inline)]
argh. :( Sorry made a small typo in patch attached in previous message.



2012/12/22 Constantin Kulikov <zxnotdead <at> gmail.com>

> Thanks for the tips.
>
>
>
> 2012/12/22 martin rudalics <rudalics <at> gmx.at>
>
>> > (defcustom initial-buffer-choice nil
>> >   "Buffer to show after starting Emacs.
>> > If the value is nil and `inhibit-startup-screen' is nil, show the
>> > startup screen.  If the value is a string, visit the specified file
>> > or directory using `find-file'.  If t, open the `*scratch*'
>> > buffer. If function, switch to a buffer returned by this function.
>>
>> As for the last sentence I'd prefer "If it is a function, switch to the
>> buffer returned by that function."
>>
>> > A string value also causes emacsclient to open the specified file
>> > or directory when no target file is specified."
>> >   :type '(choice
>> >       (const     :tag "Startup screen" nil)
>> >       (directory :tag "Directory" :value "~/")
>> >       (file      :tag "File" :value "~/.emacs")
>> >       (function  :tag "Function")
>> >       (const     :tag "Lisp scratch buffer" t))
>> >   :version "23.1"
>>
>> Too late for "23.1" use "24.4" instead.
>>
>> >   :group 'initialization)
>> >
>> > This code allows setting `initial-buffer-choice' to a function returning
>> > needed buffer.
>>
>> Could you please send us a patch based on these remarks (including the
>> change you sketched in your second mail)?
>>
>> Thanks, martin
>>
>
>
[Message part 2 (text/html, inline)]
[initial-buffer-choice-as-function.patch (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Sun, 23 Dec 2012 10:15:02 GMT) Full text and rfc822 format available.

Message #20 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Constantin Kulikov <zxnotdead <at> gmail.com>
Cc: 13251 <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Sun, 23 Dec 2012 11:14:10 +0100
> Thanks for the tips.

Thanks for the patch.  Unfortunately, we are not yet done :-(

> === modified file 'lisp/server.el'
> --- lisp/server.el	2012-11-09 06:28:27 +0000
> +++ lisp/server.el	2012-12-22 19:36:57 +0000
> @@ -1256,12 +1256,18 @@
>            (mapc 'funcall (nreverse commands))
>
>  	  ;; If we were told only to open a new client, obey
> -	  ;; `initial-buffer-choice' if it specifies a file.
> -	  (unless (or files commands)
> -	    (if (stringp initial-buffer-choice)
> -		(find-file initial-buffer-choice)
> -	      (switch-to-buffer (get-buffer-create "*scratch*")
> -				'norecord)))
> +	  ;; `initial-buffer-choice' if it specifies a file
> +          ;; or a function
> +          (unless (or files commands)

Here we have to make sure that we do _not_ switch to *scratch* when
`initial-buffer-choice' is nil but show the initial start screen.

> +            (switch-to-buffer
> +             (get-buffer-create
> +              (cond
> +               ((stringp initial-buffer-choice)
> +                (find-file-noselect initial-buffer-choice))
> +               ((functionp initial-buffer-choice)
> +                (funcall initial-buffer-choice))

Let's make sure that both `find-file-noselect' and the function called
via `initial-buffer-choice' really returned a live buffer.  So please
add a call to `buffer-live-p' for these cases.  Which also means that
Stefan's initial proposal for a let-bound `buf' is the better choice ;-)
(he's usually always right in these things).

> +               (t "*scratch*")))
> +             'norecord))
>
>            ;; Delete the client if necessary.
>            (cond
>
> === modified file 'lisp/startup.el'
> --- lisp/startup.el	2012-12-01 02:08:30 +0000
> +++ lisp/startup.el	2012-12-22 20:09:27 +0000
> @@ -43,7 +43,7 @@
>  If the value is nil and `inhibit-startup-screen' is nil, show the
>  startup screen.  If the value is a string, visit the specified file
>  or directory using `find-file'.

I suppose this is no longer true.  Let's say "switch to a buffer
visiting the file or directory specified by the string" instead.

>   If t, open the `*scratch*'
> -buffer.

This should come after the function item.  Note that we are not overly
precise in the doc-string - any non-nil value of `initial-buffer-choice'
will show *scratch*.  But it's better to not tell that in the doc-string
so we have room for future changes - just like the one you proposed.

> +buffer. If function, switch to a buffer returned by this function.

"If the value is a function, switch to the buffer returned by that
function." seems more precise here.

>  A string value also causes emacsclient to open the specified file
>  or directory when no target file is specified."
> @@ -51,8 +51,9 @@
>  	  (const     :tag "Startup screen" nil)
>  	  (directory :tag "Directory" :value "~/")
>  	  (file      :tag "File" :value "~/.emacs")
> +          (function  :tag "Function")
>  	  (const     :tag "Lisp scratch buffer" t))
> -  :version "23.1"
> +  :version "24.4"
>    :group 'initialization)
>
>  (defcustom inhibit-startup-screen nil

And now comes the last problem.  The function `command-line-1' (in
startup.el) contains these lines:

    (when (eq initial-buffer-choice t)
      ;; When initial-buffer-choice equals t make sure that *scratch*
      ;; exists.
      (get-buffer-create "*scratch*"))

I'd remove them because we can handle them here:

    (when initial-buffer-choice
      (cond ((eq initial-buffer-choice t)
	     (switch-to-buffer (get-buffer-create "*scratch*")))
	    ((stringp initial-buffer-choice)
	     (find-file initial-buffer-choice))))

If we allow `initial-buffer-choice' to specify a function, we have to
handle it here in the same way as in server.el.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Sun, 23 Dec 2012 17:05:01 GMT) Full text and rfc822 format available.

Message #23 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: Constantin Kulikov <zxnotdead <at> gmail.com>
To: 13251 <at> debbugs.gnu.org
Subject: Fwd: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Sun, 23 Dec 2012 20:04:24 +0300
[Message part 1 (text/plain, inline)]
---------- Forwarded message ----------
From: Constantin Kulikov <zxnotdead <at> gmail.com>
Date: 2012/12/23
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
frames.
To: martin rudalics <rudalics <at> gmx.at>


another attempt...
[Message part 2 (text/html, inline)]
[initial-buffer-choice-as-function.patch (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Mon, 24 Dec 2012 18:06:02 GMT) Full text and rfc822 format available.

Message #26 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Constantin Kulikov <zxnotdead <at> gmail.com>
Cc: 13251 <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Mon, 24 Dec 2012 19:05:09 +0100
> another attempt...

Committed as a combination of your previous and present patch.  Please
have a look.

Thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13251; Package emacs. (Mon, 24 Dec 2012 19:38:03 GMT) Full text and rfc822 format available.

Message #29 received at 13251 <at> debbugs.gnu.org (full text, mbox):

From: Constantin Kulikov <zxnotdead <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 13251 <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Mon, 24 Dec 2012 22:37:04 +0300
[Message part 1 (text/plain, inline)]
seems it works as I need. Thanks.


2012/12/24 martin rudalics <rudalics <at> gmx.at>

> > another attempt...
>
> Committed as a combination of your previous and present patch.  Please
> have a look.
>
> Thanks, martin
>
[Message part 2 (text/html, inline)]

Reply sent to martin rudalics <rudalics <at> gmx.at>:
You have taken responsibility. (Wed, 02 Jan 2013 08:05:02 GMT) Full text and rfc822 format available.

Notification sent to Constantin Kulikov <zxnotdead <at> gmail.com>:
bug acknowledged by developer. (Wed, 02 Jan 2013 08:05:03 GMT) Full text and rfc822 format available.

Message #34 received at 13251-done <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Constantin Kulikov <zxnotdead <at> gmail.com>
Cc: 13251-done <at> debbugs.gnu.org
Subject: Re: bug#13251: Wishlist: Add ability to set initial buffer for new
	frames.
Date: Wed, 02 Jan 2013 09:03:18 +0100
> seems it works as I need. Thanks.

Bug closed.

Thanks, martin





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 30 Jan 2013 12:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 12 years and 139 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.