From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Yuan Fu Newsgroups: gmane.emacs.bugs Subject: bug#39181: 27.0.50; [PATCH] Allow users to store & restore gdb-mi layout Date: Sat, 7 Mar 2020 14:17:14 -0500 Message-ID: <7DBBA6F5-4F53-48DC-A895-A0B06FF2A333@gmail.com> References: <75FC69BA-CCD4-46D0-B9F5-109200C796F3@gmail.com> <55235252-FD03-4801-804A-864EFC1DCA0A@gmail.com> <90254CFF-2FFD-4D54-8467-717FF10166A2@gmail.com> <5c8d9f6a-0bc5-b2ff-1513-4b8631fee1a3@gmx.at> <2A945E3B-5506-4077-9C2E-AD049BCEFA23@gmail.com> <87zhcsyoee.fsf@gmail.com> Mime-Version: 1.0 (Mac OS X Mail 13.0 \(3608.60.0.2.5\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_26A6C6FE-A765-440C-8ADE-B1F50EEC2D51" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="70820"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 39181@debbugs.gnu.org To: =?UTF-8?Q?=C5=A0t=C4=9Bp=C3=A1n_?= =?UTF-8?Q?N=C4=9Bmec?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Mar 07 20:18:16 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jAexj-000IKw-TN for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 07 Mar 2020 20:18:16 +0100 Original-Received: from localhost ([::1]:52058 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jAexi-000644-RM for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 07 Mar 2020 14:18:14 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39033) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jAexX-00063x-F1 for bug-gnu-emacs@gnu.org; Sat, 07 Mar 2020 14:18:04 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jAexW-0001BV-F7 for bug-gnu-emacs@gnu.org; Sat, 07 Mar 2020 14:18:03 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:41598) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jAexW-0001Al-8L for bug-gnu-emacs@gnu.org; Sat, 07 Mar 2020 14:18:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jAexW-0006n0-4c for bug-gnu-emacs@gnu.org; Sat, 07 Mar 2020 14:18:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Yuan Fu Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 07 Mar 2020 19:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 39181 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 39181-submit@debbugs.gnu.org id=B39181.158360864526055 (code B ref 39181); Sat, 07 Mar 2020 19:18:02 +0000 Original-Received: (at 39181) by debbugs.gnu.org; 7 Mar 2020 19:17:25 +0000 Original-Received: from localhost ([127.0.0.1]:47571 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jAewv-0006mA-G3 for submit@debbugs.gnu.org; Sat, 07 Mar 2020 14:17:25 -0500 Original-Received: from mail-qt1-f194.google.com ([209.85.160.194]:38873) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jAewt-0006lx-Qo for 39181@debbugs.gnu.org; Sat, 07 Mar 2020 14:17:24 -0500 Original-Received: by mail-qt1-f194.google.com with SMTP id e20so4271520qto.5 for <39181@debbugs.gnu.org>; Sat, 07 Mar 2020 11:17:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=JR/9E0hhabcer+SiV0dMT1+0Kai7mZqNkIsABzK8i0Q=; b=m61cZyBp5LO96t9zfskSzXWgAMSSSdLmlEkuUApK35ahuWd86YBxtNLZZVvt8ULExk dddlGM6K7tP8IFqJez1Z7rCmX4Q07jDSr1M5Aus5CnUGUVHU0yeLPRXgC6nLNnNmZcVe YPuTRfyiO/lpq2PtC0qoiMe+NBpQROYpS0+QG5iPPoTDizXaVzOj9l1deKSlAYPCt/fI MqOtWaME67y7K9HMCfrzdLtHmLoZT9jS9BU6WF2a1048G3YMwruoWO/0p6p1aLc4LvHy bYKloRYFg0e5bZ5ZGkbIDQbFSHpuCaSGM8DXEkx+/JG5nIA4fybVIkz6dOtHIG6plKEK UY1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=JR/9E0hhabcer+SiV0dMT1+0Kai7mZqNkIsABzK8i0Q=; b=rFoDT7ZK1YitpElXMT1KcU6Xj+wkolbf4pFfR5eW3MG2FmF5hEJytMspFvetb9nb62 BlGJkR8q+Uz4hSoHWz76YqKEZY8LX2nlMhd21wfp0xSb6KeSlzqn6kaux8d+EuitBVnX k4DciT5JviLKwbeS5DECh8c+dD4DRULnIBcL58XTmLP8GnL4Hg/DfWcZzEweCJcHoxvW wWR7ncG/TxVfvibZR/twpaccgaru6XrrPGy3hxTW5I7raZFMtlq7xRRVeI9Q95fbwp5E 27kxW2cxemlJH71Nw/hnknVlFwntnbfSnqngJKVnTaKL4WxfbxRQzug6pXB0ll7laYht S2OQ== X-Gm-Message-State: ANhLgQ1PpjmN1E59WRqqL7hHe73AHe84wR0VkaRZ9nHOmDPK2pW1sNP+ 5TpFrP/7LTvCGKGMGCJNqgU= X-Google-Smtp-Source: ADFU+vt/Cz9ei5O/LYEWd5tEFTyYJDGQ3b/3FBDD20TKkCPCFDfIbU5qyRkXb3WdAOWlIpvDrzzS+w== X-Received: by 2002:ac8:44c1:: with SMTP id b1mr7702640qto.331.1583608638216; Sat, 07 Mar 2020 11:17:18 -0800 (PST) Original-Received: from [192.168.1.5] (c-174-60-229-153.hsd1.pa.comcast.net. [174.60.229.153]) by smtp.gmail.com with ESMTPSA id 184sm2767610qkh.63.2020.03.07.11.17.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Mar 2020 11:17:17 -0800 (PST) In-Reply-To: <87zhcsyoee.fsf@gmail.com> X-Mailer: Apple Mail (2.3608.60.0.2.5) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:177029 Archived-At: --Apple-Mail=_26A6C6FE-A765-440C-8ADE-B1F50EEC2D51 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Mar 7, 2020, at 2:07 PM, =C5=A0t=C4=9Bp=C3=A1n N=C4=9Bmec = wrote: >=20 > On Sat, 7 Mar 2020 13:09:53 -0500 > Yuan Fu wrote: >=20 > [...] >=20 >> diff --git a/lisp/window.el b/lisp/window.el >> index bd825c09e1..229400966a 100644 >> --- a/lisp/window.el >> +++ b/lisp/window.el >> @@ -278,6 +278,19 @@ with-displayed-buffer-window >> (funcall ,vquit-function ,window ,value) >> ,value))))) >>=20 >> +(defmacro with-selected-window-undedicated (&rest body) >> + "Run BODY in the selected window temporarily undedicated." >> + (let ((window-dedicated-sym (gensym))) >> + `(let ((,window-dedicated-sym (window-dedicated-p))) >> + (when ,window-dedicated-sym >> + (set-window-dedicated-p nil nil)) >> + ,@body >> + (when ,window-dedicated-sym >> + ;; `window-dedicated-p' returns the value set by >> + ;; `set-window-dedicated-p', which differentiates >> + ;; non-nil and t, so we cannot simply set to t. >> + (set-window-dedicated-p nil ,window-dedicated-sym))))) >> + >> ;; The following two functions are like `window-next-sibling' and >> ;; `window-prev-sibling' but the WINDOW argument is _not_ optional = (so >> ;; they don't substitute the selected window for nil), and they = return >=20 > I'm sorry, I only skimmed through your patch, but shouldn't this use > 'unwind-protect'? Otherwise the "temporarily" won't hold in case of > abnormal exit from BODY, unless I'm missing something. >=20 > =E2=80=94=20 > =C5=A0t=C4=9Bp=C3=A1n Thanks for spotting that. I added the unwind-protext form. Yuan --Apple-Mail=_26A6C6FE-A765-440C-8ADE-B1F50EEC2D51 Content-Disposition: attachment; filename=new-window.patch Content-Type: application/octet-stream; x-unix-mode=0700; name="new-window.patch" Content-Transfer-Encoding: quoted-printable =46rom=201c628f05b11de93102fc7972f6c5ecd396e6cebf=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Yuan=20Fu=20=0ADate:=20Tue,=20= 3=20Mar=202020=2018:30:03=20-0500=0ASubject:=20[PATCH]=20Add=20window=20= streo/restore=20feature=20for=20gdb-mi=0AMIME-Version:=201.0=0A= Content-Type:=20text/plain;=20charset=3DUTF-8=0A= Content-Transfer-Encoding:=208bit=0A=0AAdd=20a=20feature=20that=20allows=20= a=20user=20to=20save=20a=20gdb=20window=20layout=20to=20a=20file=0Awith=20= 'gdb-save-window-layout'=20and=20load=20it=20back=20it=20with=0A= 'gdb-load-window-layout'.=20=20Set=20a=20default=20window=20= configuration=20by=0Asetting=20'gdb-default-window-layout-file'.=20=20= Note=20that=20for=20the=20default=0Awindow=20configuration=20to=20take=20= effect,=20'gdb-many-windows'=20needs=20to=20be=20t.=0AMake=20gdb=20= preserve=20the=20window=20configuration=20that=20the=20user=20had=20= before=0Astarting=20gdb.=20=20In=20window.el,=20add=20= 'with-selected-window-undedicated'.=0A*=20lisp/progmodes/gdb-mi.el=20= (require):=20add=20'pcase',=20wrap=20'pcase'=20and=20'cl-lib'=0Ainside=20= =E2=80=98eval-when-compile=E2=80=99.=0A= (gdb--window-configuration-before):=20New=20variable.=0A= (gdb-restore-window-layout-after-quit):=20New=20custom=20variable.=0A= (gdb):=20Save=20configuration=20on=20startup.=0A(gdb-reset):=20Restore=20= window=20configuration=20after=20quit.=0A(gdb-window-layout-directory,=20= gdb-default-window-layout-file):=20New=0Avariables.=0A(gud-menu-map):=20= Add=20"Load=20window=20layout"=20and=20"Save=20window=20layout"=20to=0A= menu.=20Add=20"Restore=20window=20layout"=20button=20to=20menu.=0A= (gdb-toggle-restore-window-layout):=20New=20function.=0A= (gdb-get-source-buffer):=20New=20function,=20extracted=20out=20of=0A= 'gdb-restore-window'.=0A(gdb-setup-windows):=20Add=20a=20condition=20= branch=20that=20loads=20default=20window=0Alayout=20when=20available.=0A= (gdb-buffer-p,=20gdb-function-buffer-p,=20gdb--buffer-type,=0A= gdb-save-window-layout,=20gdb-load-window-layout):=20New=20functions.=0A= (gdb-many-windows,=20gdb-get-source-file):=20Add=20comments.=0A*=20= lisp/window.el=20(with-selected-window-undedicated):=20New=20function.=0A= ---=0A=20lisp/progmodes/gdb-mi.el=20|=20272=20= ++++++++++++++++++++++++++++++++++-----=0A=20lisp/window.el=20=20=20=20=20= =20=20=20=20=20=20|=20=2014=20++=0A=202=20files=20changed,=20252=20= insertions(+),=2034=20deletions(-)=0A=0Adiff=20--git=20= a/lisp/progmodes/gdb-mi.el=20b/lisp/progmodes/gdb-mi.el=0Aindex=20= da5a2a503a..206d81ec6a=20100644=0A---=20a/lisp/progmodes/gdb-mi.el=0A+++=20= b/lisp/progmodes/gdb-mi.el=0A@@=20-92,6=20+92,8=20@@=0A=20(require=20= 'json)=0A=20(require=20'bindat)=0A=20(require=20'cl-lib)=0A+(require=20= 'cl-seq)=0A+(eval-when-compile=20(require=20'pcase))=0A=20=0A=20= (declare-function=20speedbar-change-initial-expansion-list=0A=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"speedbar"=20(new-default))=0A= @@=20-253,6=20+255,25=20@@=20gdb-output-sink=0A=20=09=20=20=20=20=20=20=20= disposition=20of=20output=20generated=20by=20commands=20that=0A=20=09=20=20= =20=20=20=20=20gdb=20mode=20sends=20to=20gdb=20on=20its=20own=20= behalf.")=0A=20=0A+(defvar=20gdb--window-configuration-before=20nil=0A+=20= =20"Stores=20the=20window=20configuration=20before=20starting=20gdb.")=0A= +=0A+(defcustom=20gdb-restore-window-layout-after-quit=20nil=0A+=20=20= "Specify=20whether=20to=20restore=20the=20window=20layout=20the=20user=20= had=20before=20gdb=20starts.=0A+=0A+Possible=20values=20are:=0A+=20=20=20= =20t=20--=20Always=20restore.=0A+=20=20=20=20nil=20--=20Don't=20restore.=0A= +=20=20=20=20'if-show-main=20--=20Restore=20only=20if=20`gdb-show-main'=20= is=20non-nil=0A+=20=20=20=20'if-many-windows=20--=20Restore=20only=20if=20= variable=20`gdb-many-windows'=20is=20non-nil."=0A+=20=20:type=20'(choice=0A= +=20=20=20=20=20=20=20=20=20=20(const=20:tag=20"Always=20restore"=20t)=0A= +=20=20=20=20=20=20=20=20=20=20(const=20:tag=20"Don't=20restore"=20nil)=0A= +=20=20=20=20=20=20=20=20=20=20(const=20:tag=20"Depends=20on=20= `gdb-show-main'"=20'if-gdb-show-main)=0A+=20=20=20=20=20=20=20=20=20=20= (const=20:tag=20"Depends=20on=20`gdb-many-windows'"=20= 'if-gdb-many-windows))=0A+=20=20:group=20'gdb=0A+=20=20:version=20= "28.1")=0A+=0A=20(defcustom=20gdb-discard-unordered-replies=20t=0A=20=20=20= "Non-nil=20means=20discard=20any=20out-of-order=20GDB=20replies.=0A=20= This=20protects=20against=20lost=20GDB=20replies,=20assuming=20that=20= GDB=20always=0A@@=20-603,6=20+624,22=20@@=20gdb-show-main=0A=20=20=20= :group=20'gdb=0A=20=20=20:version=20"22.1")=0A=20=0A+(defcustom=20= gdb-window-layout-directory=20user-emacs-directory=0A+=20=20"The=20= default=20directory=20where=20window=20configuration=20files=20are=20= stored.=0A+If=20nil,=20use=20`default-directory'."=0A+=20=20:type=20= 'string=0A+=20=20:group=20'gdb=0A+=20=20:version=20"28.1")=0A+=0A= +(defcustom=20gdb-default-window-layout-file=20nil=0A+=20=20"If=20= non-nil,=20GDB=20loads=20this=20window=20layout=20file=20on=20startup.=0A= +This=20should=20be=20the=20path=20to=20the=20window=20layout=20file.=20=20= If=20the=20path=0A+is=20not=20an=20absolute=20path,=20GDB=20treats=20it=20= as=20a=20relative=20path=20and=0A+looks=20under=20= `gdb-window-layout-directory'."=0A+=20=20:type=20'string=0A+=20=20:group=20= 'gdb=0A+=20=20:version=20"28.1")=0A+=0A=20(defvar=20gdbmi-debug-mode=20= nil=0A=20=20=20"When=20non-nil,=20print=20the=20messages=20sent/received=20= from=20GDB/MI=20in=20*Messages*.")=0A=20=0A@@=20-761,6=20+798,12=20@@=20= gdb=0A=20=20=20=20=20(gdb-restore-windows)=0A=20=20=20=20=20(error=0A=20=20= =20=20=20=20"Multiple=20debugging=20requires=20restarting=20in=20text=20= command=20mode"))=0A+=0A+=20=20;;=20Save=20window=20configuration=20= before=20starting=20gdb=20so=20we=20can=20restore=0A+=20=20;;=20it=20= after=20gdb=20quits.=20Save=20it=20regardless=20of=20the=20value=20of=0A= +=20=20;;=20`gdb-restore-window-layout-after-quit'.=0A+=20=20(setq=20= gdb--window-configuration-before=20(window-state-get))=0A+=0A=20=20=20;;=0A= =20=20=20(gud-common-init=20command-line=20nil=20= 'gud-gdbmi-marker-filter)=0A=20=0A@@=20-4491,6=20+4534,14=20@@=20= gdb-preempt-existing-or-display-buffer=0A=20=20=20(define-key=20= gud-menu-map=20[displays]=0A=20=20=20=20=20`(menu-item=20"GDB-Windows"=20= ,menu=0A=20=09=09:visible=20(eq=20gud-minor-mode=20'gdbmi)))=0A+=20=20= (define-key=20menu=20[load-layout]=20'("Load=20layout"=20"Load=20GDB=20= window=20layout=20from=20a=20file"=20.=20gdb-load-window-layout))=0A+=20=20= (define-key=20menu=20[save-layout]=20'("Save=20layout"=20"Save=20current=20= GDB=20window=20layout=20to=20a=20file"=20.=20gdb-save-window-layout))=0A= +=20=20(define-key=20menu=20[restore-layout-when-finish]=0A+=20=20=20=20= '(menu-item=20"Restore=20layout=20after=20quit"=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20gdb-toggle-restore-window-layout=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20.=20(:button=20(:toggle=20.=20= gdb-restore-window-layout-after-quit)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:help=20"Toggle=20= between=20always=20restore=20the=20window=20layout=20after=20GDB=20quits=20= and=20never=20restore.=0A+You=20can=20also=20change=20this=20setting=20= in=20Customize=20to=20conditionally=20restore.")))=0A=20=20=20= (define-key=20menu=20[gdb]=20'("Gdb"=20.=20gdb-display-gdb-buffer))=0A=20= =20=20(define-key=20menu=20[threads]=20'("Threads"=20.=20= gdb-display-threads-buffer))=0A=20=20=20(define-key=20menu=20[memory]=20= '("Memory"=20.=20gdb-display-memory-buffer))=0A@@=20-4606,41=20+4657,178=20= @@=20gdb-set-window-buffer=0A=20=20=20(set-window-buffer=20window=20= (get-buffer=20name))=0A=20=20=20(set-window-dedicated-p=20window=20t))=0A= =20=0A+(defun=20gdb-toggle-restore-window-layout=20()=0A+=20=20"Toggle=20= whether=20to=20restore=20window=20layout=20when=20GDB=20quit."=0A+=20=20= (interactive)=0A+=20=20(setq=20gdb-restore-window-layout-after-quit=0A+=20= =20=20=20=20=20=20=20(not=20gdb-restore-window-layout-after-quit)))=0A+=0A= +(defun=20gdb-get-source-buffer=20()=0A+=20=20"Return=20a=20buffer=20= displaying=20source=20file=20or=20nil=20if=20we=20can't=20find=20one.=0A= +=0A+The=20source=20file=20is=20the=20file=20that=20contains=20the=20= code=20at=20where=20GDB=0A+stops.=20=20There=20could=20be=20multiple=20= source=20files=20during=20a=20debugging=0A+session,=20we=20get=20the=20= most=20recently=20showed=20one.=20=20If=20program=20hasn't=0A+start=20= running=20yet,=20the=20source=20file=20is=20the=20\"main=20file\"=20at=20= where=0A+the=20GDB=20session=20starts=20(see=20`gdb-main-file')."=0A+=20=20= (if=20gud-last-last-frame=0A+=20=20=20=20=20=20(gud-find-file=20(car=20= gud-last-last-frame))=0A+=20=20=20=20(when=20gdb-main-file=0A+=20=20=20=20= =20=20(gud-find-file=20gdb-main-file))))=0A+=0A=20(defun=20= gdb-setup-windows=20()=0A=20=20=20"Layout=20the=20window=20pattern=20for=20= option=20`gdb-many-windows'."=0A-=20=20(gdb-get-buffer-create=20= 'gdb-locals-buffer)=0A-=20=20(gdb-get-buffer-create=20'gdb-stack-buffer)=0A= -=20=20(gdb-get-buffer-create=20'gdb-breakpoints-buffer)=0A-=20=20= (set-window-dedicated-p=20(selected-window)=20nil)=0A-=20=20= (switch-to-buffer=20gud-comint-buffer)=0A-=20=20(delete-other-windows)=0A= -=20=20(let=20((win0=20(selected-window))=0A-=20=20=20=20=20=20=20=20= (win1=20(split-window=20nil=20(=20/=20(=20*=20(window-height)=203)=20= 4)))=0A-=20=20=20=20=20=20=20=20(win2=20(split-window=20nil=20(=20/=20= (window-height)=203)))=0A-=20=20=20=20=20=20=20=20(win3=20= (split-window-right)))=0A-=20=20=20=20(gdb-set-window-buffer=20= (gdb-locals-buffer-name)=20nil=20win3)=0A-=20=20=20=20(select-window=20= win2)=0A-=20=20=20=20(set-window-buffer=0A-=20=20=20=20=20win2=0A-=20=20=20= =20=20(if=20gud-last-last-frame=0A-=20=20=20=20=20=20=20=20=20= (gud-find-file=20(car=20gud-last-last-frame))=0A-=20=20=20=20=20=20=20= (if=20gdb-main-file=0A-=20=20=20=20=20=20=20=20=20=20=20(gud-find-file=20= gdb-main-file)=0A-=20=20=20=20=20=20=20=20=20;;=20Put=20buffer=20list=20= in=20window=20if=20we=0A-=20=20=20=20=20=20=20=20=20;;=20can't=20find=20= a=20source=20file.=0A-=20=20=20=20=20=20=20=20=20= (list-buffers-noselect))))=0A-=20=20=20=20(setq=20gdb-source-window=20= (selected-window))=0A-=20=20=20=20(let=20((win4=20(split-window-right)))=0A= -=20=20=20=20=20=20(gdb-set-window-buffer=0A-=20=20=20=20=20=20=20= (gdb-get-buffer-create=20'gdb-inferior-io)=20nil=20win4))=0A-=20=20=20=20= (select-window=20win1)=0A-=20=20=20=20(gdb-set-window-buffer=20= (gdb-stack-buffer-name))=0A-=20=20=20=20(let=20((win5=20= (split-window-right)))=0A-=20=20=20=20=20=20(gdb-set-window-buffer=20(if=20= gdb-show-threads-by-default=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (gdb-threads-buffer-name)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (gdb-breakpoints-buffer-name))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20nil=20win5))=0A-=20=20=20= =20(select-window=20win0)))=0A+=20=20(if=20= gdb-default-window-layout-file=0A+=20=20=20=20=20=20= (gdb-load-window-layout=0A+=20=20=20=20=20=20=20(if=20= (file-name-absolute-p=20gdb-default-window-layout-file)=0A+=20=20=20=20=20= =20=20=20=20=20=20gdb-default-window-layout-file=0A+=20=20=20=20=20=20=20= =20=20(expand-file-name=20gdb-default-window-layout-file=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= gdb-window-layout-directory)))=0A+=20=20=20=20;;=20Create=20default=20= layout=20as=20before.=0A+=20=20=20=20(gdb-get-buffer-create=20= 'gdb-locals-buffer)=0A+=20=20=20=20(gdb-get-buffer-create=20= 'gdb-stack-buffer)=0A+=20=20=20=20(gdb-get-buffer-create=20= 'gdb-breakpoints-buffer)=0A+=20=20=20=20(set-window-dedicated-p=20= (selected-window)=20nil)=0A+=20=20=20=20(switch-to-buffer=20= gud-comint-buffer)=0A+=20=20=20=20(delete-other-windows)=0A+=20=20=20=20= (let=20((win0=20(selected-window))=0A+=20=20=20=20=20=20=20=20=20=20= (win1=20(split-window=20nil=20(=20/=20(=20*=20(window-height)=203)=20= 4)))=0A+=20=20=20=20=20=20=20=20=20=20(win2=20(split-window=20nil=20(=20= /=20(window-height)=203)))=0A+=20=20=20=20=20=20=20=20=20=20(win3=20= (split-window-right)))=0A+=20=20=20=20=20=20(gdb-set-window-buffer=20= (gdb-locals-buffer-name)=20nil=20win3)=0A+=20=20=20=20=20=20= (select-window=20win2)=0A+=20=20=20=20=20=20(set-window-buffer=0A+=20=20=20= =20=20=20=20win2=0A+=20=20=20=20=20=20=20(or=20(gdb-get-source-buffer)=0A= +=20=20=20=20=20=20=20=20=20=20=20(list-buffers-noselect)))=0A+=20=20=20=20= =20=20(setq=20gdb-source-window=20(selected-window))=0A+=20=20=20=20=20=20= (let=20((win4=20(split-window-right)))=0A+=20=20=20=20=20=20=20=20= (gdb-set-window-buffer=0A+=20=20=20=20=20=20=20=20=20= (gdb-get-buffer-create=20'gdb-inferior-io)=20nil=20win4))=0A+=20=20=20=20= =20=20(select-window=20win1)=0A+=20=20=20=20=20=20(gdb-set-window-buffer=20= (gdb-stack-buffer-name))=0A+=20=20=20=20=20=20(let=20((win5=20= (split-window-right)))=0A+=20=20=20=20=20=20=20=20(gdb-set-window-buffer=20= (if=20gdb-show-threads-by-default=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (gdb-threads-buffer-name)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (gdb-breakpoints-buffer-name))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20nil=20win5))=0A+=20= =20=20=20=20=20(select-window=20win0))))=0A+=0A+(defun=20gdb-buffer-p=20= (buffer)=0A+=20=20"Return=20t=20if=20BUFFER=20is=20GDB-related."=0A+=20=20= (with-current-buffer=20buffer=0A+=20=20=20=20(eq=20gud-minor-mode=20= 'gdbmi)))=0A+=0A+(defun=20gdb-function-buffer-p=20(buffer)=0A+=20=20= "Return=20t=20if=20BUFFER=20is=20a=20GDB=20function=20buffer.=0A+=0A= +Function=20buffers=20are=20locals=20buffer,=20registers=20buffer,=20= etc,=20but=0A+not=20including=20main=20command=20buffer=20(the=20one=20= in=20where=20you=20type=20GDB=0A+commands)=20or=20source=20buffers=20= (that=20displays=20program=20source=20code)."=0A+=20=20= (with-current-buffer=20buffer=0A+=20=20=20=20(derived-mode-p=20= 'gdb-parent-mode=20'gdb-inferior-io-mode)))=0A+=0A+(defun=20= gdb--buffer-type=20(buffer)=0A+=20=20"Return=20the=20type=20of=20BUFFER=20= if=20it=20is=20a=20function=20buffer.=0A+=0A+Buffer=20type=20is=20like=20= `gdb-registers-type',=20`gdb-stack-buffer'.=0A+These=20symbols=20are=20= used=20by=20`gdb-get-buffer-create'.=0A+=0A+Return=20nil=20if=20BUFFER=20= isn't=20a=20GDB=20function=20buffer."=0A+=20=20(with-current-buffer=20= buffer=0A+=20=20=20=20(cl-loop=20for=20rule=20in=20gdb-buffer-rules=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20for=20mode-name=20=3D=20= (gdb-rules-buffer-mode=20rule)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= for=20type=20=3D=20(car=20rule)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= if=20(eq=20mode-name=20major-mode)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20return=20type=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20finally=20= return=20nil)))=0A+=0A+(defun=20gdb-save-window-layout=20(file)=0A+=20=20= "Save=20current=20window=20layout=20(window=20configuration)=20to=20= FILE.=0A+=0A+You=20can=20later=20restore=20this=20layout=20from=20that=20= file=20by=0A+`gdb-load-window-layout'."=0A+=20=20(interactive=20(list=20= (read-file-name=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"Save=20window=20configuration=20to=20file:=20"=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(or=20= gdb-window-layout-directory=20default-directory))))=0A+=20=20;;=20We=20= replace=20the=20buffer=20in=20each=20window=20with=20a=20placeholder,=20= store=0A+=20=20;;=20the=20buffer=20type=20(register,=20breakpoint,=20= etc)=20in=20window=20parameters,=0A+=20=20;;=20and=20write=20the=20= window=20configuration=20to=20the=20file.=0A+=20=20= (save-window-excursion=0A+=20=20=20=20(let=20((placeholder=20= (get-buffer-create=20"=20*gdb-placeholder*"))=0A+=20=20=20=20=20=20=20=20= =20=20(window-persistent-parameters=0A+=20=20=20=20=20=20=20=20=20=20=20= (cons=20'(gdb-buffer-type=20.=20writable)=20= window-persistent-parameters)))=0A+=20=20=20=20=20=20(unwind-protect=0A+=20= =20=20=20=20=20=20=20=20=20(dolist=20(win=20(window-list=20nil=20= 'no-minibuffer))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(select-window=20= win)=0A+=20=20=20=20=20=20=20=20=20=20=20=20(when=20(gdb-buffer-p=20= (current-buffer))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (set-window-parameter=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= nil=20'gdb-buffer-type=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (cond=20((gdb-function-buffer-p=20(current-buffer))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=201)=20If=20a=20user=20= arranged=20the=20window=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20;;=20configuration=20herself=20and=20saves=20it,=20= windows=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20;;=20are=20probably=20not=20dedicated.=20=202)=20We=20use=20the=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20same=20= dedication=20flag=20as=20in=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20;;=20`gdb-display-buffer'.=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(set-window-dedicated-p=20= nil=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20;;=20We=20save=20this=20gdb-buffer-type=20symbol=20so=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20we=20can=20later=20= pass=20it=20to=20`gdb-get-buffer-create';=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20;;=20one=20example:=20= `gdb-registers-buffer'.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(or=20(gdb--buffer-type=20(current-buffer))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (error=20"Unrecognized=20gdb=20buffer=20mode:=20%s"=20major-mode)))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Command=20= buffer.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ((derived-mode-p=20'gud-mode)=20'command)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20((equal=20(selected-window)=20= gdb-source-window)=20'source)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(with-selected-window-undedicated=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(set-window-buffer=20nil=20placeholder)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(set-window-prev-buffers=20(selected-window)=20= nil)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (set-window-next-buffers=20(selected-window)=20nil))))=0A+=20=20=20=20=20= =20=20=20;;=20Save=20the=20window=20configuration=20to=20FILE.=0A+=20=20=20= =20=20=20=20=20(let=20((window-config=20(window-state-get=20nil=20t)))=0A= +=20=20=20=20=20=20=20=20=20=20(with-temp-buffer=0A+=20=20=20=20=20=20=20= =20=20=20=20=20(prin1=20window-config=20(current-buffer))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20(write-file=20file=20t)))=0A+=20=20=20=20=20=20=20= =20(kill-buffer=20placeholder)))))=0A+=0A+(defun=20= gdb-load-window-layout=20(file)=0A+=20=20"Restore=20window=20layout=20= (window=20configuration)=20from=20FILE.=0A+=0A+FILE=20should=20be=20a=20= window=20layout=20file=20saved=20by=0A+`gdb-save-window-layout'."=0A+=20=20= (interactive=20(list=20(read-file-name=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20"Restore=20window=20configuration=20= from=20file:=20"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(or=20gdb-window-layout-directory=20default-directory))))=0A= +=20=20;;=20Basically,=20we=20restore=20window=20configuration=20and=20= go=20through=20each=0A+=20=20;;=20window=20and=20restore=20the=20= function=20buffers.=0A+=20=20(let*=20((placeholder=20(get-buffer-create=20= "=20*gdb-placeholder*")))=0A+=20=20=20=20(unwind-protect=20;=20Don't=20= leak=20buffer.=0A+=20=20=20=20=20=20=20=20(let=20((window-config=20= (with-temp-buffer=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(insert-file-contents=20file)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;;=20We=20need=20to=20go=20to=20point-min=20even=20we=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;;=20are=20reading=20the=20whole=20buffer.=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(goto-char=20(point-min))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(read=20= (current-buffer))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (source-buffer=20(if=20gdb-source-window=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (window-buffer=20gdb-source-window)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(or=20= (gdb-get-source-buffer)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Do=20the=20= same=20thing=20as=20in=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20= `gdb-setup-windows'=20if=20no=20source=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ;;=20buffer=20is=20found.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (list-buffers-noselect))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= buffer-type)=0A+=20=20=20=20=20=20=20=20=20=20(window-state-put=20= window-config=20(frame-root-window))=0A+=20=20=20=20=20=20=20=20=20=20= (dolist=20(window=20(window-list=20nil=20'no-minibuffer))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20(with-selected-window=20window=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(setq=20buffer-type=20(window-parameter=20nil=20= 'gdb-buffer-type))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20(pcase=20= buffer-type=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20('source=20= (when=20source-buffer=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(set-window-buffer=20nil=20= source-buffer)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(setq=20gdb-source-window=20(selected-window))))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20('command=20= (switch-to-buffer=20gud-comint-buffer))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(_=20(let=20((buffer=20(gdb-get-buffer-create=20= buffer-type)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(with-selected-window-undedicated=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(set-window-buffer=20nil=20= buffer))))))))=0A+=20=20=20=20=20=20(kill-buffer=20placeholder))))=0A=20=0A= =20(define-minor-mode=20gdb-many-windows=0A=20=20=20"If=20nil=20just=20= pop=20up=20the=20GUD=20buffer=20unless=20`gdb-show-main'=20is=20t.=0A@@=20= -4659,6=20+4847,9=20@@=20gdb-many-windows=0A=20(defun=20= gdb-restore-windows=20()=0A=20=20=20"Restore=20the=20basic=20arrangement=20= of=20windows=20used=20by=20gdb.=0A=20This=20arrangement=20depends=20on=20= the=20value=20of=20option=20`gdb-many-windows'."=0A+=20=20;;=20This=20= function=20is=20used=20when=20the=20user=20messed=20up=20window=0A+=20=20= ;;=20configuration=20and=20want=20to=20"reset=20to=20default".=20=20The=20= function=20that=0A+=20=20;;=20sets=20up=20window=20configuration=20on=20= start=20up=20is=20`gdb-get-source-file'.=0A=20=20=20(interactive)=0A=20=20= =20(switch-to-buffer=20gud-comint-buffer)=20;Select=20the=20right=20= window=20and=20frame.=0A=20=20=20(delete-other-windows)=0A@@=20-4705,11=20= +4896,24=20@@=20gdb-reset=0A=20=20=20(if=20(boundp=20'speedbar-frame)=20= (speedbar-timer-fn))=0A=20=20=20(setq=20gud-running=20nil)=0A=20=20=20= (setq=20gdb-active-process=20nil)=0A-=20=20(remove-hook=20= 'after-save-hook=20'gdb-create-define-alist=20t))=0A+=20=20(remove-hook=20= 'after-save-hook=20'gdb-create-define-alist=20t)=0A+=20=20;;=20Recover=20= window=20configuration.=0A+=20=20(when=20(or=20(eq=20= gdb-restore-window-layout-after-quit=20t)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20(and=20(eq=20gdb-restore-window-layout-after-quit=20'if-show-main)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20gdb-show-main)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20(and=20(eq=20= gdb-restore-window-layout-after-quit=20'if-many-windows)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20gdb-many-windows))=0A+=20=20=20=20= (when=20gdb--window-configuration-before=0A+=20=20=20=20=20=20= (window-state-put=20gdb--window-configuration-before)=0A+=20=20=20=20=20=20= ;;=20This=20way=20we=20don't=20accidentally=20restore=20an=20outdated=20= window=0A+=20=20=20=20=20=20;;=20configuration.=20=20Maybe=20the=20user=20= changed=20the=20configuration=0A+=20=20=20=20=20=20;;=20after=20starting=20= GDB,=20who=20knows.=0A+=20=20=20=20=20=20(setq=20= gdb--window-configuration-before=20nil))))=0A=20=0A=20(defun=20= gdb-get-source-file=20()=0A=20=20=20"Find=20the=20source=20file=20where=20= the=20program=20starts=20and=20display=20it=20with=20related=0A=20= buffers,=20if=20required."=0A+=20=20;;=20This=20function=20is=20called=20= only=20once=20on=20startup.=0A=20=20=20(goto-char=20(point-min))=0A=20=20= =20(if=20(re-search-forward=20gdb-source-file-regexp=20nil=20t)=0A=20=20=20= =20=20=20=20(setq=20gdb-main-file=20(read=20(match-string=201))))=0Adiff=20= --git=20a/lisp/window.el=20b/lisp/window.el=0Aindex=20= bd825c09e1..9ddde7d1c1=20100644=0A---=20a/lisp/window.el=0A+++=20= b/lisp/window.el=0A@@=20-278,6=20+278,20=20@@=20= with-displayed-buffer-window=0A=20=09=20=20=20=20=20(funcall=20= ,vquit-function=20,window=20,value)=0A=20=09=20=20=20,value)))))=0A=20=0A= +(defmacro=20with-selected-window-undedicated=20(&rest=20body)=0A+=20=20= "Run=20BODY=20in=20the=20selected=20window=20temporarily=20undedicated."=0A= +=20=20(let=20((window-dedicated-sym=20(gensym)))=0A+=20=20=20=20`(let=20= ((,window-dedicated-sym=20(window-dedicated-p)))=0A+=20=20=20=20=20=20=20= (when=20,window-dedicated-sym=0A+=20=20=20=20=20=20=20=20=20= (set-window-dedicated-p=20nil=20nil))=0A+=20=20=20=20=20=20=20= (unwind-protect=0A+=20=20=20=20=20=20=20=20=20=20=20(progn=20,@body)=0A+=20= =20=20=20=20=20=20=20=20(when=20,window-dedicated-sym=0A+=20=20=20=20=20=20= =20=20=20=20=20;;=20`window-dedicated-p'=20returns=20the=20value=20set=20= by=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20`set-window-dedicated-p',=20= which=20differentiates=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20non-nil=20= and=20t,=20so=20we=20cannot=20simply=20set=20to=20t.=0A+=20=20=20=20=20=20= =20=20=20=20=20(set-window-dedicated-p=20nil=20= ,window-dedicated-sym))))))=0A+=0A=20;;=20The=20following=20two=20= functions=20are=20like=20`window-next-sibling'=20and=0A=20;;=20= `window-prev-sibling'=20but=20the=20WINDOW=20argument=20is=20_not_=20= optional=20(so=0A=20;;=20they=20don't=20substitute=20the=20selected=20= window=20for=20nil),=20and=20they=20return=0A--=20=0A2.25.1=0A=0A= --Apple-Mail=_26A6C6FE-A765-440C-8ADE-B1F50EEC2D51 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii --Apple-Mail=_26A6C6FE-A765-440C-8ADE-B1F50EEC2D51--