我在Emacs 24中使用GDB,gdb-many-windows
设置为t
,通常在自己的框架中。我喜欢有一个单独的编辑框架。它看起来像这样(为我粗略的ASCII图表道歉):
+-------------+-------------+
| gdb | locals |
+-------------+-------------+
| source | I/O |
| | |
+-------------+-------------+
| stack | breakpoints |
+-------------+-------------+
除了一个大问题之外,这很有效。每当gdb需要显示不同的源缓冲区时,例如,在上/下/步之后,它并不总是在" source"中显示它。窗口。例如,如果我在不同帧的窗口中打开相同的缓冲区,它将提升该帧,同时将键盘焦点保持在gdb帧中。当帧相互覆盖时,在单显示器设置上非常烦人。
我希望gdb始终使用gdb-many-windows设置中的源窗口来显示源,无论是否在其他地方显示相同的源缓冲区。我怎么能这样做?
编辑:有关重现的更详细说明。我使用Emacs 24.2.1和GDB 7.5-ubuntu。我在Ubuntu 10.04和Linux Mint Nadia with Cinnamon上看到了这个问题。
(setq gdb-many-windows t)
例如:
// foo.c
void bar(int);
void foo(int c) {
if (c > 0)
bar(c - 1);
}
int main(void) {
foo(100);
return 0;
}
// bar.c
void foo(int c);
void bar(int c) {
if (c > 0)
foo(c - 2);
}
// compile with gcc -g -O0 foo.c bar.c -o test
M-x 5 2
打开一个新框架。在该框架中,使用M-x gdb
启动gdb。如上图所示,该帧中应该有六个窗口。将gdb框架放在源框架的顶部。main
中设置断点,然后逐步调用foo
和bar
。调用bar
时,主框架将在gdb框架上凸起,因为bar.c已在那里可见,但键盘焦点将保留在gdb框架中。我认为问题函数是gud.el.gz中的gdb-display-source-buffer
。我打算尝试用defadvice
覆盖这个,但我并不熟悉建议。如果我弄清楚了,我会在这里发布一个答案。
答案 0 :(得分:2)
导致此问题的函数实际上是gud.el.gz中的gud-display-line
。此功能负责将叠加箭头定位在当前行的源窗口中并确保其可见。这是逻辑:
(let* ...
(window (and buffer
(or (get-buffer-window buffer)
(if (eq gud-minor-mode 'gdbmi)
(or (if (get-buffer-window buffer 'visible)
(display-buffer buffer nil 'visible))
(unless (gdb-display-source-buffer buffer)
(gdb-display-buffer buffer nil 'visible))))
(display-buffer buffer))))
我使用defadvice
来覆盖整个函数;基本上,我复制了源代码并更改了窗口选择逻辑。
(defadvice gud-display-line (around do-it-better activate)
(let* ...
(window (and buffer
(or (if (eq gud-minor-mode 'gdbmi)
(unless (gdb-display-source-buffer buffer)
(gdb-display-buffer buffer nil 'visible)))
(get-buffer-window buffer)
(display-buffer buffer))))
...)
显然不是最优雅的解决方案。切换帧时(上/下/帧)也没有用,所以当我想出来的时候我会编辑它。
答案 1 :(得分:1)
我有24.3。我无法重现这个版本的问题。
gud-display-line
如下所示:
(defun gud-display-line (true-file line)
(let* ((last-nonmenu-event t) ; Prevent use of dialog box for questions.
(buffer
(with-current-buffer gud-comint-buffer
(gud-find-file true-file)))
(window (and buffer
(or (get-buffer-window buffer)
(display-buffer buffer))))
(pos))
(when buffer
(with-current-buffer buffer
(unless (or (verify-visited-file-modtime buffer) gud-keep-buffer)
(if (yes-or-no-p
(format "File %s changed on disk. Reread from disk? "
(buffer-name)))
(revert-buffer t t)
(setq gud-keep-buffer t)))
(save-restriction
(widen)
(goto-char (point-min))
(forward-line (1- line))
(setq pos (point))
(or gud-overlay-arrow-position
(setq gud-overlay-arrow-position (make-marker)))
(set-marker gud-overlay-arrow-position (point) (current-buffer))
;; If they turned on hl-line, move the hl-line highlight to
;; the arrow's line.
(when (featurep 'hl-line)
(cond
(global-hl-line-mode
(global-hl-line-highlight))
((and hl-line-mode hl-line-sticky-flag)
(hl-line-highlight)))))
(cond ((or (< pos (point-min)) (> pos (point-max)))
(widen)
(goto-char pos))))
(when window
(set-window-point window gud-overlay-arrow-position)
(if (eq gud-minor-mode 'gdbmi)
(setq gdb-source-window window))))))
window
设置与您的完全不同。也许,上面的代码很有帮助,或者你应该升级到新的gud / gdb东西。
答案 2 :(得分:-1)
我运行Emacs 24.5,对我来说这仍然是一个问题。我现在使用专用窗口手动管理我的窗口,主要使用以下功能:
(defun gdb-restore-windows-gud-io-and-source ()
"Restore GUD buffer, IO buffer and source buffer next to each other."
(interactive)
;; Select dedicated GUD buffer.
(switch-to-buffer gud-comint-buffer)
(delete-other-windows)
(set-window-dedicated-p (get-buffer-window) t)
(when (or gud-last-last-frame gdb-show-main)
(let ((side-win (split-window nil nil t))
(bottom-win (split-window)))
;; Put source to the right.
(set-window-buffer
side-win
(if gud-last-last-frame
(gud-find-file (car gud-last-last-frame))
(gud-find-file gdb-main-file)))
(setq gdb-source-window side-win)
;; Show dedicated IO buffer at the bottom.
(set-window-buffer
bottom-win
(gdb-get-buffer-create 'gdb-inferior-io))
(set-window-dedicated-p bottom-win t))))
这显示左上角的GUD窗口,左下角的IO缓冲区,并将源缓冲区设置为右侧。 GUD和IO缓冲区设置为专用。