diff options
| author | Yuan Fu | 2020-04-06 09:56:15 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2020-04-06 09:56:15 +0200 |
| commit | fd4ee361395060c8afa95393245ac8d51655ae54 (patch) | |
| tree | 7fb6cc73f0792261e9ea4bf16cc2302d9fbbbd44 | |
| parent | 981cea9b624f61de3bc84226d19303ff3f8cbd8b (diff) | |
| download | emacs-fd4ee361395060c8afa95393245ac8d51655ae54.tar.gz emacs-fd4ee361395060c8afa95393245ac8d51655ae54.zip | |
Unify and improve gdb-mi source buffer display logic
Unify the behavior of source buffer display for gdb-mi. Before this
change, stepping and other gdb command handlers use 'gud-display-line',
and 'gdb-goto-breakpoint' uses 'gdb-display-source-buffer'. Now whenever
gdb-mi code tries to open a source buffer, 'gdb-display-source-buffer'
is used. Also, simplify the logic in 'gdb-display-source-buffer' and
add a feature to limit the maximum number of source windows.
* doc/emacs/building.texi (GDB User Interface Layout): Explain source
file display in GDB.
* etc/NEWS (gdb-mi): Add news about source display.
* lisp/progmodes/gdb-mi.el (gdb-source-window): Remove variable,
change to 'gdb-source-window-list'.
(gdb-source-window-list): New variable.
(gdb-display-source-buffer-action,
gdb-max-source-window-count): New options.
(gdb-init-1, gdb-setup-windows, gdb-load-window-configuration,
gdb-restore-windows): Use 'gdb-source-window' rather than
'gdb-source-window-list'.
(gdb-save-window-configuration): Use 'gdb-source-window' rather than
'gdb-source-window-list'. And consider any buffer that is not a
command or function buffer as a source buffer.
(gdb-display-source-buffer): Use new logic.
(gdb-goto-breakpoint): Remove 'display-buffer' call
and don't set 'gdb-source-buffer' anymore.
* lisp/progmodes/gud.el (gud-display-line): If used by gdb-mi, use
'gdb-display-source-buffer' rather than 'display-buffer'. Don't set
'gdb-source-buffer' anymore.
| -rw-r--r-- | doc/emacs/building.texi | 8 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 75 | ||||
| -rw-r--r-- | lisp/progmodes/gud.el | 14 |
4 files changed, 77 insertions, 26 deletions
diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 8a05680c742..77a0e807c2b 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi | |||
| @@ -1022,6 +1022,14 @@ is the relevant buffer type, such as @samp{breakpoints}. You can do | |||
| 1022 | the same with the menu bar, with the @samp{GDB-Windows} and | 1022 | the same with the menu bar, with the @samp{GDB-Windows} and |
| 1023 | @samp{GDB-Frames} sub-menus of the @samp{GUD} menu. | 1023 | @samp{GDB-Frames} sub-menus of the @samp{GUD} menu. |
| 1024 | 1024 | ||
| 1025 | @vindex gdb-max-source-window-count | ||
| 1026 | @vindex gdb-display-source-buffer-action | ||
| 1027 | By default, GDB uses at most one window to display the source file. | ||
| 1028 | You can make it use more windows by customizing | ||
| 1029 | @code{gdb-max-source-window-count}. You can also customize | ||
| 1030 | @code{gdb-display-source-buffer-action} to control how GDB displays | ||
| 1031 | source files. | ||
| 1032 | |||
| 1025 | When you finish debugging, kill the GUD interaction buffer with | 1033 | When you finish debugging, kill the GUD interaction buffer with |
| 1026 | @kbd{C-x k}, which will also kill all the buffers associated with the | 1034 | @kbd{C-x k}, which will also kill all the buffers associated with the |
| 1027 | session. However you need not do this if, after editing and | 1035 | session. However you need not do this if, after editing and |
| @@ -233,6 +233,12 @@ will remember the window configuration before GDB started and restore | |||
| 233 | it after GDB quits. A toggle button is also provided under 'Gud -- | 233 | it after GDB quits. A toggle button is also provided under 'Gud -- |
| 234 | GDB-Windows'. | 234 | GDB-Windows'. |
| 235 | 235 | ||
| 236 | +++ | ||
| 237 | *** gdb-mi now has a better logic for displaying source buffers | ||
| 238 | Now GDB only uses one source window to display source file by default. | ||
| 239 | Customize 'gdb-max-source-window-count' to use more than one window. | ||
| 240 | Control source file display by 'gdb-display-source-buffer-action'. | ||
| 241 | |||
| 236 | ** Gravatar | 242 | ** Gravatar |
| 237 | 243 | ||
| 238 | --- | 244 | --- |
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 07506834f18..ba586981de6 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -224,7 +224,9 @@ Only used for files that Emacs can't find.") | |||
| 224 | (defvar gdb-source-file-list nil | 224 | (defvar gdb-source-file-list nil |
| 225 | "List of source files for the current executable.") | 225 | "List of source files for the current executable.") |
| 226 | (defvar gdb-first-done-or-error t) | 226 | (defvar gdb-first-done-or-error t) |
| 227 | (defvar gdb-source-window nil) | 227 | (defvar gdb-source-window-list nil |
| 228 | "List of windows used for displaying source files. | ||
| 229 | Sorted in most-recently-visited-first order.") | ||
| 228 | (defvar gdb-inferior-status nil) | 230 | (defvar gdb-inferior-status nil) |
| 229 | (defvar gdb-continuation nil) | 231 | (defvar gdb-continuation nil) |
| 230 | (defvar gdb-supports-non-stop nil) | 232 | (defvar gdb-supports-non-stop nil) |
| @@ -645,6 +647,21 @@ Note that this variable only takes effect when variable | |||
| 645 | :group 'gdb | 647 | :group 'gdb |
| 646 | :version "28.1") | 648 | :version "28.1") |
| 647 | 649 | ||
| 650 | (defcustom gdb-display-source-buffer-action '(nil . ((inhibit-same-window . t))) | ||
| 651 | "`display-buffer' action used when GDB displays a source buffer." | ||
| 652 | :type 'list | ||
| 653 | :group 'gdb | ||
| 654 | :version "28.1") | ||
| 655 | |||
| 656 | (defcustom gdb-max-source-window-count 1 | ||
| 657 | "Maximum number of source windows to use. | ||
| 658 | Until there are such number of source windows on screen, GDB | ||
| 659 | tries to open a new window when visiting a new source file; after | ||
| 660 | that GDB starts to reuse existing source windows." | ||
| 661 | :type 'number | ||
| 662 | :group 'gdb | ||
| 663 | :version "28.1") | ||
| 664 | |||
| 648 | (defvar gdbmi-debug-mode nil | 665 | (defvar gdbmi-debug-mode nil |
| 649 | "When non-nil, print the messages sent/received from GDB/MI in *Messages*.") | 666 | "When non-nil, print the messages sent/received from GDB/MI in *Messages*.") |
| 650 | 667 | ||
| @@ -984,7 +1001,7 @@ detailed description of this mode. | |||
| 984 | gdb-first-done-or-error t | 1001 | gdb-first-done-or-error t |
| 985 | gdb-buffer-fringe-width (car (window-fringes)) | 1002 | gdb-buffer-fringe-width (car (window-fringes)) |
| 986 | gdb-debug-log nil | 1003 | gdb-debug-log nil |
| 987 | gdb-source-window nil | 1004 | gdb-source-window-list nil |
| 988 | gdb-inferior-status nil | 1005 | gdb-inferior-status nil |
| 989 | gdb-continuation nil | 1006 | gdb-continuation nil |
| 990 | gdb-buf-publisher '() | 1007 | gdb-buf-publisher '() |
| @@ -2070,17 +2087,36 @@ is running." | |||
| 2070 | ;; GDB frame (after up, down etc). If no GDB frame is visible but the last | 2087 | ;; GDB frame (after up, down etc). If no GDB frame is visible but the last |
| 2071 | ;; visited breakpoint is, use that window. | 2088 | ;; visited breakpoint is, use that window. |
| 2072 | (defun gdb-display-source-buffer (buffer) | 2089 | (defun gdb-display-source-buffer (buffer) |
| 2073 | (let* ((last-window (if gud-last-last-frame | 2090 | "Find a window to display BUFFER. |
| 2074 | (get-buffer-window | 2091 | Always find a window to display buffer, and return it." |
| 2075 | (gud-find-file (car gud-last-last-frame))))) | 2092 | ;; This function doesn't take care of setting up source window(s) at startup, |
| 2076 | (source-window (or last-window | 2093 | ;; that's handled by `gdb-setup-windows' (if `gdb-many-windows' is non-nil). |
| 2077 | (if (and gdb-source-window | 2094 | ;; If `buffer' is already shown in a window, use that window. |
| 2078 | (window-live-p gdb-source-window)) | 2095 | (or (get-buffer-window buffer) |
| 2079 | gdb-source-window)))) | 2096 | (progn |
| 2080 | (when source-window | 2097 | ;; First, update the window list. |
| 2081 | (setq gdb-source-window source-window) | 2098 | (setq gdb-source-window-list |
| 2082 | (set-window-buffer source-window buffer)) | 2099 | (cl-remove-duplicates |
| 2083 | source-window)) | 2100 | (cl-remove-if-not |
| 2101 | (lambda (win) | ||
| 2102 | (and (window-live-p win) | ||
| 2103 | (eq (window-frame win) | ||
| 2104 | (selected-frame)))) | ||
| 2105 | gdb-source-window-list))) | ||
| 2106 | ;; Should we create a new window or reuse one? | ||
| 2107 | (if (> gdb-max-source-window-count | ||
| 2108 | (length gdb-source-window-list)) | ||
| 2109 | ;; Create a new window, push it to window list and return it. | ||
| 2110 | (car (push (display-buffer buffer gdb-display-source-buffer-action) | ||
| 2111 | gdb-source-window-list)) | ||
| 2112 | ;; Reuse a window, we use the oldest window and put that to | ||
| 2113 | ;; the front of the window list. | ||
| 2114 | (let ((last-win (car (last gdb-source-window-list))) | ||
| 2115 | (rest (butlast gdb-source-window-list))) | ||
| 2116 | (set-window-buffer last-win buffer) | ||
| 2117 | (setq gdb-source-window-list | ||
| 2118 | (cons last-win rest)) | ||
| 2119 | last-win))))) | ||
| 2084 | 2120 | ||
| 2085 | 2121 | ||
| 2086 | (defun gdbmi-start-with (str offset match) | 2122 | (defun gdbmi-start-with (str offset match) |
| @@ -4071,9 +4107,7 @@ DOC is an optional documentation string." | |||
| 4071 | (let* ((buffer (find-file-noselect | 4107 | (let* ((buffer (find-file-noselect |
| 4072 | (if (file-exists-p file) file | 4108 | (if (file-exists-p file) file |
| 4073 | (cdr (assoc bptno gdb-location-alist))))) | 4109 | (cdr (assoc bptno gdb-location-alist))))) |
| 4074 | (window (or (gdb-display-source-buffer buffer) | 4110 | (window (gdb-display-source-buffer buffer))) |
| 4075 | (display-buffer buffer)))) | ||
| 4076 | (setq gdb-source-window window) | ||
| 4077 | (with-current-buffer buffer | 4111 | (with-current-buffer buffer |
| 4078 | (goto-char (point-min)) | 4112 | (goto-char (point-min)) |
| 4079 | (forward-line (1- (string-to-number line))) | 4113 | (forward-line (1- (string-to-number line))) |
| @@ -4722,7 +4756,7 @@ file\" where the GDB session starts (see `gdb-main-file')." | |||
| 4722 | (select-window win2) | 4756 | (select-window win2) |
| 4723 | (set-window-buffer win2 (or (gdb-get-source-buffer) | 4757 | (set-window-buffer win2 (or (gdb-get-source-buffer) |
| 4724 | (list-buffers-noselect))) | 4758 | (list-buffers-noselect))) |
| 4725 | (setq gdb-source-window (selected-window)) | 4759 | (setq gdb-source-window-list (list (selected-window))) |
| 4726 | (let ((win4 (split-window-right))) | 4760 | (let ((win4 (split-window-right))) |
| 4727 | (gdb-set-window-buffer | 4761 | (gdb-set-window-buffer |
| 4728 | (gdb-get-buffer-create 'gdb-inferior-io) nil win4)) | 4762 | (gdb-get-buffer-create 'gdb-inferior-io) nil win4)) |
| @@ -4798,7 +4832,8 @@ You can later restore this configuration from that file by | |||
| 4798 | (error "Unrecognized gdb buffer mode: %s" major-mode))) | 4832 | (error "Unrecognized gdb buffer mode: %s" major-mode))) |
| 4799 | ;; Command buffer. | 4833 | ;; Command buffer. |
| 4800 | ((derived-mode-p 'gud-mode) 'command) | 4834 | ((derived-mode-p 'gud-mode) 'command) |
| 4801 | ((equal (selected-window) gdb-source-window) 'source))) | 4835 | ;; Consider everything else as source buffer. |
| 4836 | (t 'source))) | ||
| 4802 | (with-window-non-dedicated nil | 4837 | (with-window-non-dedicated nil |
| 4803 | (set-window-buffer nil placeholder) | 4838 | (set-window-buffer nil placeholder) |
| 4804 | (set-window-prev-buffers (selected-window) nil) | 4839 | (set-window-prev-buffers (selected-window) nil) |
| @@ -4841,7 +4876,7 @@ FILE should be a window configuration file saved by | |||
| 4841 | (pcase buffer-type | 4876 | (pcase buffer-type |
| 4842 | ('source (when source-buffer | 4877 | ('source (when source-buffer |
| 4843 | (set-window-buffer nil source-buffer) | 4878 | (set-window-buffer nil source-buffer) |
| 4844 | (setq gdb-source-window (selected-window)))) | 4879 | (push (selected-window) gdb-source-window-list))) |
| 4845 | ('command (switch-to-buffer gud-comint-buffer)) | 4880 | ('command (switch-to-buffer gud-comint-buffer)) |
| 4846 | (_ (let ((buffer (gdb-get-buffer-create buffer-type))) | 4881 | (_ (let ((buffer (gdb-get-buffer-create buffer-type))) |
| 4847 | (with-window-non-dedicated nil | 4882 | (with-window-non-dedicated nil |
| @@ -4882,7 +4917,7 @@ This arrangement depends on the values of variable | |||
| 4882 | (if gud-last-last-frame | 4917 | (if gud-last-last-frame |
| 4883 | (gud-find-file (car gud-last-last-frame)) | 4918 | (gud-find-file (car gud-last-last-frame)) |
| 4884 | (gud-find-file gdb-main-file))) | 4919 | (gud-find-file gdb-main-file))) |
| 4885 | (setq gdb-source-window win))))) | 4920 | (setq gdb-source-window-list (list win)))))) |
| 4886 | 4921 | ||
| 4887 | ;; Called from `gud-sentinel' in gud.el: | 4922 | ;; Called from `gud-sentinel' in gud.el: |
| 4888 | (defun gdb-reset () | 4923 | (defun gdb-reset () |
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index 567f452b935..eb43e8b7e44 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el | |||
| @@ -2826,9 +2826,13 @@ Obeying it means displaying in another window the specified file and line." | |||
| 2826 | (buffer | 2826 | (buffer |
| 2827 | (with-current-buffer gud-comint-buffer | 2827 | (with-current-buffer gud-comint-buffer |
| 2828 | (gud-find-file true-file))) | 2828 | (gud-find-file true-file))) |
| 2829 | (window (and buffer | 2829 | (window |
| 2830 | (or (get-buffer-window buffer) | 2830 | (when buffer |
| 2831 | (display-buffer buffer '(nil (inhibit-same-window . t)))))) | 2831 | (if (eq gud-minor-mode 'gdbmi) |
| 2832 | (gdb-display-source-buffer buffer) | ||
| 2833 | ;; Gud still has the old behavior. | ||
| 2834 | (or (get-buffer-window buffer) | ||
| 2835 | (display-buffer buffer '(nil (inhibit-same-window . t))))))) | ||
| 2832 | (pos)) | 2836 | (pos)) |
| 2833 | (when buffer | 2837 | (when buffer |
| 2834 | (with-current-buffer buffer | 2838 | (with-current-buffer buffer |
| @@ -2858,9 +2862,7 @@ Obeying it means displaying in another window the specified file and line." | |||
| 2858 | (widen) | 2862 | (widen) |
| 2859 | (goto-char pos)))) | 2863 | (goto-char pos)))) |
| 2860 | (when window | 2864 | (when window |
| 2861 | (set-window-point window gud-overlay-arrow-position) | 2865 | (set-window-point window gud-overlay-arrow-position))))) |
| 2862 | (if (eq gud-minor-mode 'gdbmi) | ||
| 2863 | (setq gdb-source-window window)))))) | ||
| 2864 | 2866 | ||
| 2865 | ;; The gud-call function must do the right thing whether its invoking | 2867 | ;; The gud-call function must do the right thing whether its invoking |
| 2866 | ;; keystroke is from the GUD buffer itself (via major-mode binding) | 2868 | ;; keystroke is from the GUD buffer itself (via major-mode binding) |