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

霸气de小男生 提交于 2020-01-17 05:23:04

问题


I have customized gdb windows in emacs. 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:

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

But when I started debugging then next source file opens in another window. See example bellow: New source code in gdb window

The example of application to reproduce is:

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

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

  2. M-x gdb

  3. gdb -i=mi test

  4. In gdb command window run: start

  5. run: next

  6. run: step

My environment is: Ubuntu14.04, gdb - 7.7.1, emacs - 25.1.1.

I tried to use 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?


回答1:


display-buffer-alist lets you control in which windows new buffers are displayed. 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.



来源:https://stackoverflow.com/questions/39762833/emacsgdb-customization-how-to-display-source-buffer-in-one-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!