unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* get-live-buffer primitive
@ 2012-09-13  7:52 Dmitry Antipov
  2012-09-13 12:44 ` Richard Stallman
  2012-09-13 12:58 ` Stefan Monnier
  0 siblings, 2 replies; 9+ messages in thread
From: Dmitry Antipov @ 2012-09-13  7:52 UTC (permalink / raw)
  To: Emacs development discussions; +Cc: martin rudalics, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 187 bytes --]

What about such a primitive? We already have live_buffer used in markers
code, so we can use this internal thing in Fget_live_buffer and avoid
duplicating some things in elisp...

Dmitry

[-- Attachment #2: get_live_buffer.patch --]
[-- Type: text/plain, Size: 4099 bytes --]

=== modified file 'lisp/window.el'
--- lisp/window.el	2012-09-09 06:43:47 +0000
+++ lisp/window.el	2012-09-13 07:37:03 +0000
@@ -219,16 +219,9 @@
   "Return buffer specified by BUFFER-OR-NAME.
 BUFFER-OR-NAME must be either a buffer or a string naming a live
 buffer and defaults to the current buffer."
-  (cond
-   ((not buffer-or-name)
-    (current-buffer))
-   ((bufferp buffer-or-name)
-    (if (buffer-live-p buffer-or-name)
-	buffer-or-name
-      (error "Buffer %s is not a live buffer" buffer-or-name)))
-   ((get-buffer buffer-or-name))
-   (t
-    (error "No such buffer %s" buffer-or-name))))
+  (let ((buffer (get-live-buffer buffer-or-name)))
+    (or buffer (error "No such live buffer %s" buffer-or-name))
+    buffer))
 
 (defun window-normalize-frame (frame)
   "Return frame specified by FRAME.

=== modified file 'src/buffer.c'
--- src/buffer.c	2012-09-11 04:22:03 +0000
+++ src/buffer.c	2012-09-13 07:47:23 +0000
@@ -469,6 +469,33 @@
   return Fcdr (assoc_ignore_text_properties (buffer_or_name, Vbuffer_alist));
 }
 
+DEFUN ("get-live-buffer", Fget_live_buffer, Sget_live_buffer, 1, 1, 0,
+       doc: /* Return live buffer named BUFFER-OR-NAME.
+If BUFFER-OR-NAME is nil, return current buffer, which is always live.
+If BUFFER-OR-NAME is a string and there is a live buffer with that name,
+return this buffer.  If there is no such buffer or the buffer is killed,
+return nil.  If BUFFER-OR-NAME is a buffer, return it as given if it is
+live, and nil otherwise.  */)
+  (Lisp_Object buffer_or_name)
+{
+  struct buffer *b;
+
+  if (STRINGP (buffer_or_name))
+    {
+      buffer_or_name = Fcdr (assoc_ignore_text_properties
+			     (buffer_or_name, Vbuffer_alist));
+      if (NILP (buffer_or_name))
+	return Qnil;
+    }
+  b = live_buffer (buffer_or_name);
+  if (b)
+    {
+      XSETBUFFER (buffer_or_name, b);
+      return buffer_or_name;
+    }
+  return Qnil;
+}
+
 DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
        doc: /* Return the buffer visiting file FILENAME (a string).
 The buffer's `buffer-file-name' must match exactly the expansion of FILENAME.
@@ -6260,6 +6287,7 @@
   defsubr (&Sbuffer_live_p);
   defsubr (&Sbuffer_list);
   defsubr (&Sget_buffer);
+  defsubr (&Sget_live_buffer);
   defsubr (&Sget_file_buffer);
   defsubr (&Sget_buffer_create);
   defsubr (&Smake_indirect_buffer);

=== modified file 'src/buffer.h'
--- src/buffer.h	2012-09-11 04:22:03 +0000
+++ src/buffer.h	2012-09-13 07:30:23 +0000
@@ -1025,6 +1025,30 @@
 extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
 extern void mmap_set_vars (bool);
 
+/* If BUFFER is nil, return current buffer pointer.  Next, check
+   whether BUFFER is a buffer object and return buffer pointer
+   corresponding to BUFFER if BUFFER is live, or NULL otherwise.  */
+
+BUFFER_INLINE struct buffer *
+live_buffer (Lisp_Object buffer)
+{
+  struct buffer *b;
+
+  if (NILP (buffer))
+    {
+      b = current_buffer;
+      eassert (BUFFER_LIVE_P (b));
+    }
+  else
+    {
+      CHECK_BUFFER (buffer);
+      b = XBUFFER (buffer);
+      if (!BUFFER_LIVE_P (b))
+       b = NULL;
+    }
+  return b;
+}
+
 /* Set the current buffer to B.
 
    We previously set windows_or_buffers_changed here to invalidate

=== modified file 'src/marker.c'
--- src/marker.c	2012-09-11 04:22:03 +0000
+++ src/marker.c	2012-09-13 07:30:02 +0000
@@ -450,30 +450,6 @@
     }
 }
 
-/* If BUFFER is nil, return current buffer pointer.  Next, check
-   whether BUFFER is a buffer object and return buffer pointer
-   corresponding to BUFFER if BUFFER is live, or NULL otherwise.  */
-
-static inline struct buffer *
-live_buffer (Lisp_Object buffer)
-{
-  struct buffer *b;
-
-  if (NILP (buffer))
-    {
-      b = current_buffer;
-      eassert (BUFFER_LIVE_P (b));
-    }
-  else
-    {
-      CHECK_BUFFER (buffer);
-      b = XBUFFER (buffer);
-      if (!BUFFER_LIVE_P (b))
-       b = NULL;
-    }
-  return b;
-}
-
 /* Internal function to set MARKER in BUFFER at POSITION.  Non-zero
    RESTRICTED means limit the POSITION by the visible part of BUFFER.  */
 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13  7:52 get-live-buffer primitive Dmitry Antipov
@ 2012-09-13 12:44 ` Richard Stallman
  2012-09-13 13:42   ` Stefan Monnier
  2012-09-13 12:58 ` Stefan Monnier
  1 sibling, 1 reply; 9+ messages in thread
From: Richard Stallman @ 2012-09-13 12:44 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: rudalics, monnier, emacs-devel

    What about such a primitive? We already have live_buffer used in markers
    code, so we can use this internal thing in Fget_live_buffer and avoid
    duplicating some things in elisp...

`get-buffer' should never return a dead buffer.  (Dead buffers
are removed from Vbuffer_alist.)

If `get-buffer' ever does return a dead buffer, that is a bug,
so we should fix it rather than adding some other primitive.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org  www.gnu.org
Skype: No way! That's nonfree (freedom-denying) software.
  Use Ekiga or an ordinary phone call




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13  7:52 get-live-buffer primitive Dmitry Antipov
  2012-09-13 12:44 ` Richard Stallman
@ 2012-09-13 12:58 ` Stefan Monnier
  1 sibling, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2012-09-13 12:58 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: martin rudalics, Emacs development discussions

> +  (let ((buffer (get-live-buffer buffer-or-name)))
> +    (or buffer (error "No such live buffer %s" buffer-or-name))
> +    buffer))

Why not use `get-buffer' plus a buffer-live-p test on the result?
Or add a `live' optional argument to `get-buffer' to check for liveness.


        Stefan



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13 12:44 ` Richard Stallman
@ 2012-09-13 13:42   ` Stefan Monnier
  2012-09-13 16:50     ` martin rudalics
  2012-09-13 20:45     ` Richard Stallman
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Monnier @ 2012-09-13 13:42 UTC (permalink / raw)
  To: rms; +Cc: rudalics, Dmitry Antipov, emacs-devel

> `get-buffer' should never return a dead buffer.  (Dead buffers
> are removed from Vbuffer_alist.)

It does, if passed a dead buffer.  Maybe we should change that.


        Stefan



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13 13:42   ` Stefan Monnier
@ 2012-09-13 16:50     ` martin rudalics
  2012-09-13 17:00       ` martin rudalics
  2012-09-13 20:45     ` Richard Stallman
  1 sibling, 1 reply; 9+ messages in thread
From: martin rudalics @ 2012-09-13 16:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dmitry Antipov, rms, emacs-devel

 > It does, if passed a dead buffer.

That's too bad.  I never noticed that :-(

 > Maybe we should change that.

Either this or the places where it's used like in Fother_buffer:

       buf = Fget_buffer (build_string ("*scratch*"));
       if (NILP (buf))
	{
	  buf = Fget_buffer_create (build_string ("*scratch*"));
	  Fset_buffer_major_mode (buf);
	}

Probably this is the source of some mysterious crashes with dead
buffers.

martin




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13 16:50     ` martin rudalics
@ 2012-09-13 17:00       ` martin rudalics
  2012-09-13 17:30         ` martin rudalics
  0 siblings, 1 reply; 9+ messages in thread
From: martin rudalics @ 2012-09-13 17:00 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dmitry Antipov, rms, emacs-devel

>       buf = Fget_buffer (build_string ("*scratch*"));
>       if (NILP (buf))
>     {
>       buf = Fget_buffer_create (build_string ("*scratch*"));
>       Fset_buffer_major_mode (buf);
>     }

Sorry.  That was a silly example.

martin




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13 17:00       ` martin rudalics
@ 2012-09-13 17:30         ` martin rudalics
  0 siblings, 0 replies; 9+ messages in thread
From: martin rudalics @ 2012-09-13 17:30 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Dmitry Antipov, rms, emacs-devel

 > Sorry.  That was a silly example.

... but it is silly that `get-buffer-create' can return a killed buffer.

martin




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13 13:42   ` Stefan Monnier
  2012-09-13 16:50     ` martin rudalics
@ 2012-09-13 20:45     ` Richard Stallman
  2012-09-14  9:00       ` martin rudalics
  1 sibling, 1 reply; 9+ messages in thread
From: Richard Stallman @ 2012-09-13 20:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rudalics, dmantipov, emacs-devel

    > `get-buffer' should never return a dead buffer.  (Dead buffers
    > are removed from Vbuffer_alist.)

    It does, if passed a dead buffer.  Maybe we should change that.

That surprised me, but I guess it is true.  Maybe it should not be
changed.

Meanwhile, `get-buffer' will not find a dead buffer by name.
So I don't see a need to create a `get-live-buffer' function.
Unless the purpose were only to get an error if the argument
is a dead buffer.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org  www.gnu.org
Skype: No way! That's nonfree (freedom-denying) software.
  Use Ekiga or an ordinary phone call




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: get-live-buffer primitive
  2012-09-13 20:45     ` Richard Stallman
@ 2012-09-14  9:00       ` martin rudalics
  0 siblings, 0 replies; 9+ messages in thread
From: martin rudalics @ 2012-09-14  9:00 UTC (permalink / raw)
  To: rms; +Cc: dmantipov, Stefan Monnier, emacs-devel

 > Meanwhile, `get-buffer' will not find a dead buffer by name.
 > So I don't see a need to create a `get-live-buffer' function.
 > Unless the purpose were only to get an error if the argument
 > is a dead buffer.

Just a few examples that could benefit from such a function:

Fset_window_buffer has

   buffer = Fget_buffer (buffer_or_name);
   CHECK_BUFFER (buffer);
   if (NILP (BVAR (XBUFFER (buffer), name)))
     error ("Attempt to display deleted buffer");

Finsert_buffer_substring

   buf = Fget_buffer (buffer);
   if (NILP (buf))
     nsberror (buffer);
   bp = XBUFFER (buf);
   if (!BUFFER_LIVE_P (bp))
     error ("Selecting deleted buffer");

Fcompare_buffer_substrings

       buf1 = Fget_buffer (buffer1);
       if (NILP (buf1))
	nsberror (buffer1);
       bp1 = XBUFFER (buf1);
       if (!BUFFER_LIVE_P (bp1))
	error ("Selecting deleted buffer");

       ...

       buf2 = Fget_buffer (buffer2);
       if (NILP (buf2))
	nsberror (buffer2);
       bp2 = XBUFFER (buf2);
       if (!BUFFER_LIVE_P (bp2))
	error ("Selecting deleted buffer");

Fset_buffer

   buffer = Fget_buffer (buffer_or_name);
   if (NILP (buffer))
     nsberror (buffer_or_name);
   if (!BUFFER_LIVE_P (XBUFFER (buffer)))
     error ("Selecting deleted buffer");

martin



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-09-14  9:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-13  7:52 get-live-buffer primitive Dmitry Antipov
2012-09-13 12:44 ` Richard Stallman
2012-09-13 13:42   ` Stefan Monnier
2012-09-13 16:50     ` martin rudalics
2012-09-13 17:00       ` martin rudalics
2012-09-13 17:30         ` martin rudalics
2012-09-13 20:45     ` Richard Stallman
2012-09-14  9:00       ` martin rudalics
2012-09-13 12:58 ` Stefan Monnier

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