diff options
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 293 | ||||
| -rw-r--r-- | lisp/window.el | 18 |
2 files changed, 272 insertions, 39 deletions
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index c2622327967..ea3b1b816a8 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -92,6 +92,8 @@ | |||
| 92 | (require 'json) | 92 | (require 'json) |
| 93 | (require 'bindat) | 93 | (require 'bindat) |
| 94 | (require 'cl-lib) | 94 | (require 'cl-lib) |
| 95 | (require 'cl-seq) | ||
| 96 | (eval-when-compile (require 'pcase)) | ||
| 95 | 97 | ||
| 96 | (declare-function speedbar-change-initial-expansion-list | 98 | (declare-function speedbar-change-initial-expansion-list |
| 97 | "speedbar" (new-default)) | 99 | "speedbar" (new-default)) |
| @@ -253,6 +255,27 @@ Possible values are these symbols: | |||
| 253 | disposition of output generated by commands that | 255 | disposition of output generated by commands that |
| 254 | gdb mode sends to gdb on its own behalf.") | 256 | gdb mode sends to gdb on its own behalf.") |
| 255 | 257 | ||
| 258 | (defvar gdb--window-configuration-before nil | ||
| 259 | "Stores the window configuration before starting GDB.") | ||
| 260 | |||
| 261 | (defcustom gdb-restore-window-configuration-after-quit nil | ||
| 262 | "If non-nil, restore window configuration as of before GDB started. | ||
| 263 | |||
| 264 | Possible values are: | ||
| 265 | t -- Always restore. | ||
| 266 | nil -- Don't restore. | ||
| 267 | `if-gdb-show-main' -- Restore only if variable `gdb-show-main' | ||
| 268 | is non-nil | ||
| 269 | `if-gdb-many-windows' -- Restore only if variable `gdb-many-windows' | ||
| 270 | is non-nil." | ||
| 271 | :type '(choice | ||
| 272 | (const :tag "Always restore" t) | ||
| 273 | (const :tag "Don't restore" nil) | ||
| 274 | (const :tag "Depends on `gdb-show-main'" 'if-gdb-show-main) | ||
| 275 | (const :tag "Depends on `gdb-many-windows'" 'if-gdb-many-windows)) | ||
| 276 | :group 'gdb | ||
| 277 | :version "28.1") | ||
| 278 | |||
| 256 | (defcustom gdb-discard-unordered-replies t | 279 | (defcustom gdb-discard-unordered-replies t |
| 257 | "Non-nil means discard any out-of-order GDB replies. | 280 | "Non-nil means discard any out-of-order GDB replies. |
| 258 | This protects against lost GDB replies, assuming that GDB always | 281 | This protects against lost GDB replies, assuming that GDB always |
| @@ -603,6 +626,25 @@ Also display the main routine in the disassembly buffer if present." | |||
| 603 | :group 'gdb | 626 | :group 'gdb |
| 604 | :version "22.1") | 627 | :version "22.1") |
| 605 | 628 | ||
| 629 | (defcustom gdb-window-configuration-directory user-emacs-directory | ||
| 630 | "Directory where GDB window configuration files are stored. | ||
| 631 | If nil, use `default-directory'." | ||
| 632 | :type 'string | ||
| 633 | :group 'gdb | ||
| 634 | :version "28.1") | ||
| 635 | |||
| 636 | (defcustom gdb-default-window-configuration-file nil | ||
| 637 | "If non-nil, load this window configuration (layout) on startup. | ||
| 638 | This should be the full name of the window configuration file. | ||
| 639 | If this is not an absolute path, GDB treats it as a relative path | ||
| 640 | and looks under `gdb-window-configuration-directory'. | ||
| 641 | |||
| 642 | Note that this variable only takes effect when variable | ||
| 643 | `gdb-many-windows' is t." | ||
| 644 | :type 'string | ||
| 645 | :group 'gdb | ||
| 646 | :version "28.1") | ||
| 647 | |||
| 606 | (defvar gdbmi-debug-mode nil | 648 | (defvar gdbmi-debug-mode nil |
| 607 | "When non-nil, print the messages sent/received from GDB/MI in *Messages*.") | 649 | "When non-nil, print the messages sent/received from GDB/MI in *Messages*.") |
| 608 | 650 | ||
| @@ -761,6 +803,12 @@ detailed description of this mode. | |||
| 761 | (gdb-restore-windows) | 803 | (gdb-restore-windows) |
| 762 | (error | 804 | (error |
| 763 | "Multiple debugging requires restarting in text command mode")) | 805 | "Multiple debugging requires restarting in text command mode")) |
| 806 | |||
| 807 | ;; Save window configuration before starting gdb so we can restore | ||
| 808 | ;; it after gdb quits. Save it regardless of the value of | ||
| 809 | ;; `gdb-restore-window-configuration-after-quit'. | ||
| 810 | (setq gdb--window-configuration-before (window-state-get)) | ||
| 811 | |||
| 764 | ;; | 812 | ;; |
| 765 | (gud-common-init command-line nil 'gud-gdbmi-marker-filter) | 813 | (gud-common-init command-line nil 'gud-gdbmi-marker-filter) |
| 766 | 814 | ||
| @@ -4494,6 +4542,26 @@ SPLIT-HORIZONTAL and show BUF in the new window." | |||
| 4494 | (define-key gud-menu-map [displays] | 4542 | (define-key gud-menu-map [displays] |
| 4495 | `(menu-item "GDB-Windows" ,menu | 4543 | `(menu-item "GDB-Windows" ,menu |
| 4496 | :visible (eq gud-minor-mode 'gdbmi))) | 4544 | :visible (eq gud-minor-mode 'gdbmi))) |
| 4545 | (define-key menu [gdb-restore-windows] | ||
| 4546 | '(menu-item "Restore Initial Layout" gdb-restore-windows | ||
| 4547 | :help "Restore the initial GDB window layout.")) | ||
| 4548 | ;; Window layout vs window configuration: We use "window layout" in | ||
| 4549 | ;; GDB UI. Internally we refer to "window configuration" because | ||
| 4550 | ;; that's the data structure used to store window layouts. Though | ||
| 4551 | ;; bare in mind that there is a small difference between what we | ||
| 4552 | ;; store and what normal window configuration functions | ||
| 4553 | ;; output. Because GDB buffers (source, local, breakpoint, etc) are | ||
| 4554 | ;; different between each debugging sessions, simply save/load | ||
| 4555 | ;; window configurations doesn't | ||
| 4556 | ;; work. `gdb-save-window-configuration' and | ||
| 4557 | ;; `gdb-load-window-configuration' do some tricks to store and | ||
| 4558 | ;; recreate each buffer in the layout. | ||
| 4559 | (define-key menu [load-layout] '("Load Layout" "Load GDB window configuration (layout) from a file" . gdb-load-window-configuration)) | ||
| 4560 | (define-key menu [save-layout] '("Save Layout" "Save current GDB window configuration (layout) to a file" . gdb-save-window-configuration)) | ||
| 4561 | (define-key menu [restore-layout-after-quit] | ||
| 4562 | '(menu-item "Restore Layout After Quit" gdb-toggle-restore-window-configuration | ||
| 4563 | :button (:toggle . gdb-restore-window-configuration-after-quit) | ||
| 4564 | :help "Toggle between always restore the window configuration (layout) after GDB quits and never restore.\n You can also change this setting in Customize to conditionally restore.")) | ||
| 4497 | (define-key menu [gdb] '("Gdb" . gdb-display-gdb-buffer)) | 4565 | (define-key menu [gdb] '("Gdb" . gdb-display-gdb-buffer)) |
| 4498 | (define-key menu [threads] '("Threads" . gdb-display-threads-buffer)) | 4566 | (define-key menu [threads] '("Threads" . gdb-display-threads-buffer)) |
| 4499 | (define-key menu [memory] '("Memory" . gdb-display-memory-buffer)) | 4567 | (define-key menu [memory] '("Memory" . gdb-display-memory-buffer)) |
| @@ -4532,9 +4600,6 @@ SPLIT-HORIZONTAL and show BUF in the new window." | |||
| 4532 | '(menu-item "Display Other Windows" gdb-many-windows | 4600 | '(menu-item "Display Other Windows" gdb-many-windows |
| 4533 | :help "Toggle display of locals, stack and breakpoint information" | 4601 | :help "Toggle display of locals, stack and breakpoint information" |
| 4534 | :button (:toggle . gdb-many-windows))) | 4602 | :button (:toggle . gdb-many-windows))) |
| 4535 | (define-key menu [gdb-restore-windows] | ||
| 4536 | '(menu-item "Restore Window Layout" gdb-restore-windows | ||
| 4537 | :help "Restore standard layout for debug session.")) | ||
| 4538 | (define-key menu [sep1] | 4603 | (define-key menu [sep1] |
| 4539 | '(menu-item "--")) | 4604 | '(menu-item "--")) |
| 4540 | (define-key menu [all-threads] | 4605 | (define-key menu [all-threads] |
| @@ -4609,41 +4674,172 @@ window is dedicated." | |||
| 4609 | (set-window-buffer window (get-buffer name)) | 4674 | (set-window-buffer window (get-buffer name)) |
| 4610 | (set-window-dedicated-p window t)) | 4675 | (set-window-dedicated-p window t)) |
| 4611 | 4676 | ||
| 4677 | (defun gdb-toggle-restore-window-configuration () | ||
| 4678 | "Toggle whether to restore window configuration when GDB quits." | ||
| 4679 | (interactive) | ||
| 4680 | (setq gdb-restore-window-configuration-after-quit | ||
| 4681 | (not gdb-restore-window-configuration-after-quit))) | ||
| 4682 | |||
| 4683 | (defun gdb-get-source-buffer () | ||
| 4684 | "Return a buffer displaying source file or nil if we can't find one. | ||
| 4685 | The source file is the file that contains the source location | ||
| 4686 | where GDB stops. There could be multiple source files during a | ||
| 4687 | debugging session, we get the most recently showed one. If | ||
| 4688 | program hasn't started running yet, the source file is the \"main | ||
| 4689 | file\" where the GDB session starts (see `gdb-main-file')." | ||
| 4690 | (if gud-last-last-frame | ||
| 4691 | (gud-find-file (car gud-last-last-frame)) | ||
| 4692 | (when gdb-main-file | ||
| 4693 | (gud-find-file gdb-main-file)))) | ||
| 4694 | |||
| 4612 | (defun gdb-setup-windows () | 4695 | (defun gdb-setup-windows () |
| 4613 | "Layout the window pattern for option `gdb-many-windows'." | 4696 | "Lay out the window pattern for option `gdb-many-windows'." |
| 4614 | (gdb-get-buffer-create 'gdb-locals-buffer) | 4697 | (if gdb-default-window-configuration-file |
| 4615 | (gdb-get-buffer-create 'gdb-stack-buffer) | 4698 | (gdb-load-window-configuration |
| 4616 | (gdb-get-buffer-create 'gdb-breakpoints-buffer) | 4699 | (if (file-name-absolute-p gdb-default-window-configuration-file) |
| 4617 | (set-window-dedicated-p (selected-window) nil) | 4700 | gdb-default-window-configuration-file |
| 4618 | (switch-to-buffer gud-comint-buffer) | 4701 | (expand-file-name gdb-default-window-configuration-file |
| 4619 | (delete-other-windows) | 4702 | gdb-window-configuration-directory))) |
| 4620 | (let ((win0 (selected-window)) | 4703 | ;; Create default layout as before. |
| 4621 | (win1 (split-window nil ( / ( * (window-height) 3) 4))) | 4704 | (gdb-get-buffer-create 'gdb-locals-buffer) |
| 4622 | (win2 (split-window nil ( / (window-height) 3))) | 4705 | (gdb-get-buffer-create 'gdb-stack-buffer) |
| 4623 | (win3 (split-window-right))) | 4706 | (gdb-get-buffer-create 'gdb-breakpoints-buffer) |
| 4624 | (gdb-set-window-buffer (gdb-locals-buffer-name) nil win3) | 4707 | (set-window-dedicated-p (selected-window) nil) |
| 4625 | (select-window win2) | 4708 | (switch-to-buffer gud-comint-buffer) |
| 4626 | (set-window-buffer | 4709 | (delete-other-windows) |
| 4627 | win2 | 4710 | (let ((win0 (selected-window)) |
| 4628 | (if gud-last-last-frame | 4711 | (win1 (split-window nil ( / ( * (window-height) 3) 4))) |
| 4629 | (gud-find-file (car gud-last-last-frame)) | 4712 | (win2 (split-window nil ( / (window-height) 3))) |
| 4630 | (if gdb-main-file | 4713 | (win3 (split-window-right))) |
| 4631 | (gud-find-file gdb-main-file) | 4714 | (gdb-set-window-buffer (gdb-locals-buffer-name) nil win3) |
| 4632 | ;; Put buffer list in window if we | 4715 | (select-window win2) |
| 4633 | ;; can't find a source file. | 4716 | (set-window-buffer win2 (or (gdb-get-source-buffer) |
| 4634 | (list-buffers-noselect)))) | 4717 | (list-buffers-noselect))) |
| 4635 | (setq gdb-source-window (selected-window)) | 4718 | (setq gdb-source-window (selected-window)) |
| 4636 | (let ((win4 (split-window-right))) | 4719 | (let ((win4 (split-window-right))) |
| 4637 | (gdb-set-window-buffer | 4720 | (gdb-set-window-buffer |
| 4638 | (gdb-get-buffer-create 'gdb-inferior-io) nil win4)) | 4721 | (gdb-get-buffer-create 'gdb-inferior-io) nil win4)) |
| 4639 | (select-window win1) | 4722 | (select-window win1) |
| 4640 | (gdb-set-window-buffer (gdb-stack-buffer-name)) | 4723 | (gdb-set-window-buffer (gdb-stack-buffer-name)) |
| 4641 | (let ((win5 (split-window-right))) | 4724 | (let ((win5 (split-window-right))) |
| 4642 | (gdb-set-window-buffer (if gdb-show-threads-by-default | 4725 | (gdb-set-window-buffer (if gdb-show-threads-by-default |
| 4643 | (gdb-threads-buffer-name) | 4726 | (gdb-threads-buffer-name) |
| 4644 | (gdb-breakpoints-buffer-name)) | 4727 | (gdb-breakpoints-buffer-name)) |
| 4645 | nil win5)) | 4728 | nil win5)) |
| 4646 | (select-window win0))) | 4729 | (select-window win0)))) |
| 4730 | |||
| 4731 | (defun gdb-buffer-p (buffer) | ||
| 4732 | "Return t if BUFFER is GDB-related." | ||
| 4733 | (with-current-buffer buffer | ||
| 4734 | (eq gud-minor-mode 'gdbmi))) | ||
| 4735 | |||
| 4736 | (defun gdb-function-buffer-p (buffer) | ||
| 4737 | "Return t if BUFFER is a GDB function buffer. | ||
| 4738 | |||
| 4739 | Function buffers are locals buffer, registers buffer, etc, but | ||
| 4740 | not including main command buffer (the one where you type GDB | ||
| 4741 | commands) or source buffers (that display program source code)." | ||
| 4742 | (with-current-buffer buffer | ||
| 4743 | (derived-mode-p 'gdb-parent-mode 'gdb-inferior-io-mode))) | ||
| 4744 | |||
| 4745 | (defun gdb--buffer-type (buffer) | ||
| 4746 | "Return the type of BUFFER if it is a function buffer. | ||
| 4747 | Buffer type is like `gdb-registers-type', `gdb-stack-buffer'. | ||
| 4748 | These symbols are used by `gdb-get-buffer-create'. | ||
| 4749 | |||
| 4750 | Return nil if BUFFER is not a GDB function buffer." | ||
| 4751 | (with-current-buffer buffer | ||
| 4752 | (cl-loop for rule in gdb-buffer-rules | ||
| 4753 | for mode-name = (gdb-rules-buffer-mode rule) | ||
| 4754 | for type = (car rule) | ||
| 4755 | if (eq mode-name major-mode) | ||
| 4756 | return type | ||
| 4757 | finally return nil))) | ||
| 4758 | |||
| 4759 | (defun gdb-save-window-configuration (file) | ||
| 4760 | "Save current window configuration (layout) to FILE. | ||
| 4761 | You can later restore this configuration from that file by | ||
| 4762 | `gdb-load-window-configuration'." | ||
| 4763 | (interactive (list (read-file-name | ||
| 4764 | "Save window configuration to file: " | ||
| 4765 | (or gdb-window-configuration-directory | ||
| 4766 | default-directory)))) | ||
| 4767 | ;; We replace the buffer in each window with a placeholder, store | ||
| 4768 | ;; the buffer type (register, breakpoint, etc) in window parameters, | ||
| 4769 | ;; and write the window configuration to the file. | ||
| 4770 | (save-window-excursion | ||
| 4771 | (let ((placeholder (get-buffer-create " *gdb-placeholder*")) | ||
| 4772 | (window-persistent-parameters | ||
| 4773 | (cons '(gdb-buffer-type . writable) window-persistent-parameters))) | ||
| 4774 | (unwind-protect | ||
| 4775 | (dolist (win (window-list nil 'no-minibuffer)) | ||
| 4776 | (select-window win) | ||
| 4777 | (when (gdb-buffer-p (current-buffer)) | ||
| 4778 | (set-window-parameter | ||
| 4779 | nil 'gdb-buffer-type | ||
| 4780 | (cond ((gdb-function-buffer-p (current-buffer)) | ||
| 4781 | ;; 1) If a user arranged the window | ||
| 4782 | ;; configuration herself and saves it, windows | ||
| 4783 | ;; are probably not dedicated. 2) We use the | ||
| 4784 | ;; same dedication flag as in | ||
| 4785 | ;; `gdb-display-buffer'. | ||
| 4786 | (set-window-dedicated-p nil t) | ||
| 4787 | ;; We save this gdb-buffer-type symbol so | ||
| 4788 | ;; we can later pass it to `gdb-get-buffer-create'; | ||
| 4789 | ;; one example: `gdb-registers-buffer'. | ||
| 4790 | (or (gdb--buffer-type (current-buffer)) | ||
| 4791 | (error "Unrecognized gdb buffer mode: %s" major-mode))) | ||
| 4792 | ;; Command buffer. | ||
| 4793 | ((derived-mode-p 'gud-mode) 'command) | ||
| 4794 | ((equal (selected-window) gdb-source-window) 'source))) | ||
| 4795 | (with-window-non-dedicated nil | ||
| 4796 | (set-window-buffer nil placeholder) | ||
| 4797 | (set-window-prev-buffers (selected-window) nil) | ||
| 4798 | (set-window-next-buffers (selected-window) nil)))) | ||
| 4799 | ;; Save the window configuration to FILE. | ||
| 4800 | (let ((window-config (window-state-get nil t))) | ||
| 4801 | (with-temp-buffer | ||
| 4802 | (prin1 window-config (current-buffer)) | ||
| 4803 | (write-file file t))) | ||
| 4804 | (kill-buffer placeholder))))) | ||
| 4805 | |||
| 4806 | (defun gdb-load-window-configuration (file) | ||
| 4807 | "Restore window configuration (layout) from FILE. | ||
| 4808 | FILE should be a window configuration file saved by | ||
| 4809 | `gdb-save-window-configuration'." | ||
| 4810 | (interactive (list (read-file-name | ||
| 4811 | "Restore window configuration from file: " | ||
| 4812 | (or gdb-window-configuration-directory | ||
| 4813 | default-directory)))) | ||
| 4814 | ;; Basically, we restore window configuration and go through each | ||
| 4815 | ;; window and restore the function buffers. | ||
| 4816 | (let* ((placeholder (get-buffer-create " *gdb-placeholder*"))) | ||
| 4817 | (unwind-protect ; Don't leak buffer. | ||
| 4818 | (let ((window-config (with-temp-buffer | ||
| 4819 | (insert-file-contents file) | ||
| 4820 | ;; We need to go to point-min because | ||
| 4821 | ;; `read' reads from point | ||
| 4822 | (goto-char (point-min)) | ||
| 4823 | (read (current-buffer)))) | ||
| 4824 | (source-buffer (or (gdb-get-source-buffer) | ||
| 4825 | ;; Do the same thing as in | ||
| 4826 | ;; `gdb-setup-windows' if no source | ||
| 4827 | ;; buffer is found. | ||
| 4828 | (list-buffers-noselect))) | ||
| 4829 | buffer-type) | ||
| 4830 | (window-state-put window-config (frame-root-window)) | ||
| 4831 | (dolist (window (window-list nil 'no-minibuffer)) | ||
| 4832 | (with-selected-window window | ||
| 4833 | (setq buffer-type (window-parameter nil 'gdb-buffer-type)) | ||
| 4834 | (pcase buffer-type | ||
| 4835 | ('source (when source-buffer | ||
| 4836 | (set-window-buffer nil source-buffer) | ||
| 4837 | (setq gdb-source-window (selected-window)))) | ||
| 4838 | ('command (switch-to-buffer gud-comint-buffer)) | ||
| 4839 | (_ (let ((buffer (gdb-get-buffer-create buffer-type))) | ||
| 4840 | (with-window-non-dedicated nil | ||
| 4841 | (set-window-buffer nil buffer)))))))) | ||
| 4842 | (kill-buffer placeholder)))) | ||
| 4647 | 4843 | ||
| 4648 | (define-minor-mode gdb-many-windows | 4844 | (define-minor-mode gdb-many-windows |
| 4649 | "If nil just pop up the GUD buffer unless `gdb-show-main' is t. | 4845 | "If nil just pop up the GUD buffer unless `gdb-show-main' is t. |
| @@ -4661,7 +4857,12 @@ of the debugged program. Non-nil means display the layout shown for | |||
| 4661 | 4857 | ||
| 4662 | (defun gdb-restore-windows () | 4858 | (defun gdb-restore-windows () |
| 4663 | "Restore the basic arrangement of windows used by gdb. | 4859 | "Restore the basic arrangement of windows used by gdb. |
| 4664 | This arrangement depends on the value of option `gdb-many-windows'." | 4860 | This arrangement depends on the values of variable |
| 4861 | `gdb-many-windows' and `gdb-default-window-configuration-file'." | ||
| 4862 | ;; This function is used when the user messed up window | ||
| 4863 | ;; configuration and wants to "reset to default". The function that | ||
| 4864 | ;; sets up window configuration on start up is | ||
| 4865 | ;; `gdb-get-source-file'. | ||
| 4665 | (interactive) | 4866 | (interactive) |
| 4666 | (switch-to-buffer gud-comint-buffer) ;Select the right window and frame. | 4867 | (switch-to-buffer gud-comint-buffer) ;Select the right window and frame. |
| 4667 | (delete-other-windows) | 4868 | (delete-other-windows) |
| @@ -4708,11 +4909,25 @@ Kills the gdb buffers, and resets variables and the source buffers." | |||
| 4708 | (if (boundp 'speedbar-frame) (speedbar-timer-fn)) | 4909 | (if (boundp 'speedbar-frame) (speedbar-timer-fn)) |
| 4709 | (setq gud-running nil) | 4910 | (setq gud-running nil) |
| 4710 | (setq gdb-active-process nil) | 4911 | (setq gdb-active-process nil) |
| 4711 | (remove-hook 'after-save-hook 'gdb-create-define-alist t)) | 4912 | (remove-hook 'after-save-hook 'gdb-create-define-alist t) |
| 4913 | ;; Recover window configuration. | ||
| 4914 | (when (or (eq gdb-restore-window-configuration-after-quit t) | ||
| 4915 | (and (eq gdb-restore-window-configuration-after-quit | ||
| 4916 | 'if-gdb-show-main) | ||
| 4917 | gdb-show-main) | ||
| 4918 | (and (eq gdb-restore-window-configuration-after-quit | ||
| 4919 | 'if-gdb-many-windows) | ||
| 4920 | gdb-many-windows)) | ||
| 4921 | (when gdb--window-configuration-before | ||
| 4922 | (window-state-put gdb--window-configuration-before) | ||
| 4923 | ;; This way we don't accidentally restore an outdated window | ||
| 4924 | ;; configuration. | ||
| 4925 | (setq gdb--window-configuration-before nil)))) | ||
| 4712 | 4926 | ||
| 4713 | (defun gdb-get-source-file () | 4927 | (defun gdb-get-source-file () |
| 4714 | "Find the source file where the program starts and display it with related | 4928 | "Find the source file where the program starts and display it with related |
| 4715 | buffers, if required." | 4929 | buffers, if required." |
| 4930 | ;; This function is called only once on startup. | ||
| 4716 | (goto-char (point-min)) | 4931 | (goto-char (point-min)) |
| 4717 | (if (re-search-forward gdb-source-file-regexp nil t) | 4932 | (if (re-search-forward gdb-source-file-regexp nil t) |
| 4718 | (setq gdb-main-file (read (match-string 1)))) | 4933 | (setq gdb-main-file (read (match-string 1)))) |
diff --git a/lisp/window.el b/lisp/window.el index fc1e7d4a76c..b54f1633f5e 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -278,6 +278,24 @@ displays the buffer specified by BUFFER-OR-NAME before running BODY." | |||
| 278 | (funcall ,vquit-function ,window ,value) | 278 | (funcall ,vquit-function ,window ,value) |
| 279 | ,value))))) | 279 | ,value))))) |
| 280 | 280 | ||
| 281 | (defmacro with-window-non-dedicated (window &rest body) | ||
| 282 | "Evaluate BODY with WINDOW temporarily made non-dedicated. | ||
| 283 | If WINDOW is nil, use the selected window. Return the value of | ||
| 284 | the last form in BODY." | ||
| 285 | (declare (indent 1) (debug t)) | ||
| 286 | (let ((window-dedicated-sym (gensym)) | ||
| 287 | (window-sym (gensym))) | ||
| 288 | `(let* ((,window-sym (window-normalize-window ,window t)) | ||
| 289 | (,window-dedicated-sym (window-dedicated-p ,window-sym))) | ||
| 290 | (set-window-dedicated-p ,window-sym nil) | ||
| 291 | (unwind-protect | ||
| 292 | (progn ,@body) | ||
| 293 | ;; `window-dedicated-p' returns the value set by | ||
| 294 | ;; `set-window-dedicated-p', which differentiates non-nil and | ||
| 295 | ;; t, so we cannot simply use t here. That's why we use | ||
| 296 | ;; `window-dedicated-sym'. | ||
| 297 | (set-window-dedicated-p ,window-sym ,window-dedicated-sym))))) | ||
| 298 | |||
| 281 | ;; The following two functions are like `window-next-sibling' and | 299 | ;; The following two functions are like `window-next-sibling' and |
| 282 | ;; `window-prev-sibling' but the WINDOW argument is _not_ optional (so | 300 | ;; `window-prev-sibling' but the WINDOW argument is _not_ optional (so |
| 283 | ;; they don't substitute the selected window for nil), and they return | 301 | ;; they don't substitute the selected window for nil), and they return |