【问题标题】:[emacs][gdb customization] How to display source-buffer in one window?[emacs][gdb 自定义] 如何在一个窗口中显示源缓冲区?
【发布时间】:2016-09-29 06:23:16
【问题描述】:

我在 emacs 中自定义了 gdb 窗口。在调试过程中,新的源代码会在不同的窗口中打开。我只想在一个窗口中查看源代码。我的 gdb 自定义是:

;     _____________________________________________________________________________________
;    |                                          |                                          |
;    |              BREAKPOINTS                 |                                          |
;    |__________________________________________|                                          |
;    |                                          |                                          |
;    |                 STACK                    |                                          |
;    |__________________________________________|                                          |
;    |                                          |                                          |
;    |                                          |                                          |
;    |                 LOCALS                   |                                          |
;    |                                          |                SOURCE CODE               |
;    |__________________________________________|                                          |
;    |                                          |                                          |
;    |                                          |                                          |
;    |                                          |                                          |
;    |                                          |                                          |
;    |                                          |                                          |
;    |                                          |                                          |
;    |                  GDB                     |                                          |
;    |                                          |__________________________________________|
;    |                                          |                                          |
;    |                                          |                                          |
;    |                                          |                    I/O                   |
;    |                                          |                                          |
;    |__________________________________________|__________________________________________|

(require 'gud)

; invoke
(global-set-key [f8] 'gdb)

; GDB layout
(defadvice gdb-setup-windows (after activate)
  (gdb-setup-my-windows)
)

(defun gdb-setup-my-windows ()
  (set-window-dedicated-p (selected-window) nil)
  (switch-to-buffer gud-comint-buffer)
  (delete-other-windows)
  (let
    ((win0 (selected-window))             ; breakpoints
     (win1 (split-window-horizontally
         (floor (* 0.5 (window-width)))))   ; source + i/o
     (win2 (split-window-vertically
         (floor (* 0.5 (window-body-height))))) ; gdb
     (win3 (split-window-vertically
        (floor (* 0.5 (window-body-height))))) ; locals
     (win4 (split-window-vertically
         (floor (* 0.6 (window-body-height))))) ; stack
    )
    (select-window win1)
    ; configurating right window
    (let
    ((winSrc (selected-window)) ; source
     (winIO (split-window-vertically (floor (* 0.9 (window-body-height))))) ; I/O
     )
      (set-window-buffer winIO (gdb-get-buffer-create 'gdb-inferior-io))
      (set-window-buffer
    winSrc
    (if gud-last-last-frame
     (gud-find-file (car gud-last-last-frame))
      (if gdb-main-file
       (gud-find-file gdb-main-file)
     (list-buffers-noselect))))
      (setq gdb-source-window winSrc)
      (set-window-dedicated-p winIO t)
   )

    (set-window-buffer win0 (gdb-get-buffer-create 'gdb-breakpoints-buffer))
    (set-window-buffer win3 (gdb-get-buffer-create 'gdb-locals-buffer))
    (set-window-buffer win4 (gdb-get-buffer-create 'gdb-stack-buffer))
    (select-window win2)
  )
)

; GDB variables
(setq gdb-many-windows t)
(setq gdb-show-main t)
(setq gdb-show-changed-values t)
(setq gdb-use-colon-colon-notation t)
(setq gdb-use-separate-io-buffer nil)
(setq gdb-delete-out-of-scope t)
(setq gdb-speedbar-auto-raise t)

主屏幕是: gdb screen after start

但是当我开始调试时,下一个源文件会在另一个窗口中打开。请参见下面的示例: New source code in gdb window

应用复现的例子是:

main.cpp

#include "classB.h"

int main()
{
  B *b = 0;
  b = new B();
  return 0;
}

classA.h

#ifndef CLASS_A_H
#define CLASS_A_H

class A
{
public:
  A();
};

#endif

classA.cpp

#include "classA.h"
#include <iostream>

A::A()
{
  std::cout << "Constructor A" << std::endl;
}

classB.h

#ifndef CLASS_B_H
#define CLASS_B_H

#include "classA.h"

class B : public A
{
public:
  B();
};

#endif

classB.cpp

#include "classB.h"
#include <iostream>

B::B() : A()
{
  std::cout << "Constructor B" << std::endl;
}

生成文件

SOURCES=main.cpp classA.cpp classB.cpp
TARGET=test
CXX_FLAGS=-g

.PHONY: all

all: $(TARGET)

$(TARGET): $(SOURCES)
    $(CXX) $(CXX_FLAGS) $^ -o $@

.PHONY: clean

clean:
    rm -vf $(TARGET)

重现步骤:

  1. 运行 emacs

  2. M-x gdb

  3. gdb -i=mi 测试

  4. 在 gdb 命令窗口中运行:开始

  5. 运行:下一个

  6. 运行:步骤

我的环境是:Ubuntu14.04,gdb - 7.7.1,emacs - 25.1.1。

我尝试使用 set-window-dedicated-p。但这不是我的问题的解决方案。 我是emacs新手,请帮帮我,我的配置有什么问题?

【问题讨论】:

  • 抱歉跑题了,你用什么主题来处理linum 和缓冲区分隔符?
  • 我建议从您的标题中删除 [tags],因为 SO 已经将标签作为问题的一部分。
  • @ChakravarthyRaghunandan,我正在使用idea-darkula-theme。

标签: debugging emacs gdb customization


【解决方案1】:

display-buffer-alist 允许您控制在哪些窗口中显示新缓冲区。首先在其中注册一个函数指针

(add-to-list 'display-buffer-alist
         (cons 'cdb-source-code-buffer-p
           (cons 'display-source-code-buffer nil)))

然后实现选择窗口的函数,例如

(defun cdb-source-code-buffer-p (bufName action)
  "Return whether BUFNAME is a source code buffer."
  (let ((buf (get-buffer bufName)))
    (and buf
     (with-current-buffer buf
       (derived-mode-p buf 'c++-mode 'c-mode 'csharp-mode 'nxml-mode)))))

(defun display-source-code-buffer (sourceBuf alist)
  "Find a window with source code and set sourceBuf inside it."
  (let* ((curbuf (current-buffer))
     (wincurbuf (get-buffer-window curbuf))
     (win (if (and wincurbuf
               (derived-mode-p sourceBuf 'c++-mode 'c-mode 'nxml-mode)
               (derived-mode-p (current-buffer) 'c++-mode 'c-mode 'nxml-mode))
          wincurbuf
        (get-window-with-predicate
         (lambda (window)
           (let ((bufName (buffer-name (window-buffer window))))
             (or (cdb-source-code-buffer-p bufName nil)
             (assoc bufName display-buffer-alist)
             ))))))) ;; derived-mode-p doesn't work inside this, don't know why...
    (set-window-buffer win sourceBuf)
    win))

cdb-source-code-buffer-p 选择源代码缓冲区,为此调用display-source-code-buffer,返回所需的窗口。

【讨论】:

  • 对不起,我是 Emacs 的新手,我不明白如何在我的文件中使用它和 gdb 配置。你能解释一下吗?我将这些函数添加到我的配置文件中并尝试调用 display-source-code-buffer 函数,但它不起作用。
  • @EgorCh。请阅读display-buffer-alist 的文档,输入M-x describe-variable 然后输入display-buffer-alist。在那里您将了解到您自己不会调用display-source-code-buffer,Emacs 在需要显示源代码缓冲区时会为您调用它。有关 Emacs lisp 的一般介绍,请阅读 this
  • 是否有可能只在 emacs 中 gdb 模式处于活动状态时将其添加到 display-buffer-alist 回调中,不知何故?这解决了问题,但会影响任何代码,例如 find-file-other-window
  • @sonictk in cdb-source-code-buffer-p 你可以测试gdb是否处于活动状态
【解决方案2】:

这是一个对我有用的更简单的版本。它利用了默认情况下 GUD 窗口和 IO 窗口是专用的这一事实。因此,只需向现有窗口询问显示缓冲区就足够了(因为只有一个选项可用)。

;; Ensure that all source files are opened in the same window when gdb                                                                                                  
;; is running.                                                                                                                                                          
(add-to-list 'display-buffer-alist
         (cons 'gdb-source-code-buffer-p
           (cons 'display-buffer-use-some-window nil)))

(defun gdb-source-code-buffer-p (bufName action)
  "Return whether BUFNAME is a source code buffer and gdb is running."
  (let ((buf (get-buffer bufName)))
    (and buf
         (eq gud-minor-mode 'gdbmi)
         (with-current-buffer buf
           (derived-mode-p buf 'c++-mode 'c-mode)))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多