简体   繁体   English

[emacs][gdb 定制] 如何在一个窗口中显示source-buffer?

[英][emacs][gdb customization] How to display source-buffer in one window?

I have customized gdb windows in emacs.我在 emacs 中自定义了 gdb 窗口。 After it during debugging new source code opens in different windows.在调试新的源代码之后,它会在不同的窗口中打开。 I'd like to see source code only in one window.我只想在一个窗口中查看源代码。 My gdb customization is:我的 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)

The main screen is: gdb screen after start主画面为:启动后的gdb画面

But when I started debugging then next source file opens in another window.但是当我开始调试时,下一个源文件在另一个窗口中打开。 See example bellow: New source code in gdb window请参见下面的示例: gdb 窗口中的新源代码

The example of application to reproduce is:应用复制的例子是:

main.cpp主程序

#include "classB.h"

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

classA.h类A.h

#ifndef CLASS_A_H
#define CLASS_A_H

class A
{
public:
  A();
};

#endif

classA.cpp类A.cpp

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

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

classB.h类B.h

#ifndef CLASS_B_H
#define CLASS_B_H

#include "classA.h"

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

#endif

classB.cpp类B.cpp

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

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

Makefile生成文件

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)

Step to reproduce:重现步骤:

  1. Run emacs运行 emacs

  2. Mx gdb Mx 数据库

  3. gdb -i=mi test gdb -i=mi 测试

  4. In gdb command window run: start在 gdb 命令窗口中运行: start

  5. run: next运行:下一个

  6. run: step运行:步骤

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

I tried to use set-window-dedicated-p .我尝试使用set-window-dedicated-p But this is not solution for my problem.但这不是我的问题的解决方案。 I'm new in emacs, help me please, what is wrong in my configuration?我是 emacs 新手,请帮帮我,我的配置有什么问题?

display-buffer-alist lets you control in which windows new buffers are displayed. display-buffer-alist允许您控制在哪些窗口中显示新缓冲区。 You start by registering a function pointer inside it您首先在其中注册一个函数指针

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

then implement the function that selects a window, for example然后实现选择窗口的功能,例如

(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 select source code buffers, for which display-source-code-buffer is called, that returns the window you want. cdb-source-code-buffer-p选择源代码缓冲区,为其调用display-source-code-buffer ,返回您想要的窗口。

Here is a simpler version that worked for me.这是一个对我有用的更简单的版本。 It takes advantage of the fact that by default, the GUD window and IO window are dedicated.它利用了默认情况下 GUD 窗口和 IO 窗口是专用的这一事实。 So it's sufficient to just ask display-buffer to an existing window (since there is only one choice available).因此,仅向现有窗口询问 display-buffer 就足够了(因为只有一种选择可用)。

;; 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)))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM