6

I am a long term eclipse CDT user migrating to emacs (ver. 23.3.1), because I have to work on a large C codebase accessible only through a telnet/ssh shell. After going through several online guides, I have managed to get emacs work with cscope on the code. I have some minor issues with it (see below), I am asking it as a single question as I think they are very basic questions which any expert might know. If you feel they need to be split into multiple questions, please let me know

  1. For navigating the cscope buffer, there are commands available to jump to next and previous symbol (C-c s n, C-c s p). I am not able to find a command to open the file where the cursor is currently set. What I do currently is move the cursor to the previous symbol and do a C-c s n to open the file. This feels very unnatural, there should be a command to jump to current symbol
  2. Similar to cscope-find-global-definition, is there any command to jump to local definition. Sometimes while reading huge functions, it is helpful to quickly jump back to the definition of the variable. I understand this can be achieved by backward I-search, but it would be helpful to have a quick way to jump to definition.
  3. I created a cscope database using the command cscope -b -R -q, but emacs was returning 0 results for every lookup. Then I added (setq cscope-do-not-update-database t) to my .emacs and it started working. I looked into the description of the variable and it says that if the variable is non-nil it will never check/update the cscope database. How did setting it to True made my cscope to work. From the description I would have expected the opposite. What is that variable doing?
3

You can check my C/C++ guide for all the needs above:

  1. You can use GNU Global with ggtags or helm-gtags, which can be installed through MELPA. GNU Global can use cscope backend, but you should use its native backend for generating tag datdabase for C/C++ code. You can jump to definitions or references instantly, even for project as large as Linux kernel. Here is a demo of how you can select all available tags in your project:

helm-gtags-select

Following my ggtags or helm-gtags in my guide, you can jump to any definition with ggtags-find-tag-dwim or helm-gtags-dwim which is bound to M-. and jump back where you were with M-,.

  1. You don't need to jump back to local definition to see the details. Simply using semantic-idle-summary-mode, it will show definition of any variable/function/class/struct at point like this, automatically:

Demo 1:

semantic-idle-summary-mode1

Demo 2:

semantic-idle-summary-mode2

Demo 3:

semantic-idle-summary-mode3

As you can see in the screenshot, the function signature of find_if is shown in the minibuffer.

You can also keep the definition of current function always visible at the top like this:

semantic-sticky-func-mode

To enable those features, add this configuration to your init file (either ~/.emacs or ~/.emacs.d/init.el:

(semantic-mode 1)
(add-to-list 'semantic-default-submodes 'global-semantic-stickyfunc-mode)
(add-to-list 'semantic-default-submodes 'global-semantic-idle-summary-mode)

You can use highlight-symbol (you can install from MELPA to highlight and jump back and forth occurrences of the same symbol in buffer with the following configuration:

(require 'highlight-symbol)

(highlight-symbol-nav-mode)

(add-hook 'prog-mode-hook (lambda () (highlight-symbol-mode)))
(add-hook 'org-mode-hook (lambda () (highlight-symbol-mode)))

(setq highlight-symbol-idle-delay 0.2
      highlight-symbol-on-navigation-p t)

(global-set-key (kbd "M-n") 'highlight-symbol-next)
(global-set-key (kbd "M-p") 'highlight-symbol-prev)

After that, you can jump back and forth with M-p and M-n

  1. Use GNU Global to look thins up. It just works.

You may want to check Semantic Refactor, a package for common refactoring tasks (i.e. rename local variables easy and precisely, extract a piece of code into a separate function...). Here are the demos

If you just want to try before going through all installation and configuration, use my demo Emacs kit made for the guide:

git clone https://github.com/tuhdo/emacs-c-ide-demo.git ~/.emacs.d

EDIT: Semantic Refactor requires at least Emacs 24.4 or latest CEDET to work properly.

  • 1
    Thanks for the tutorial, it is really something valuable. – avp Sep 22 '15 at 8:01
0

@Tu Do's answer is impressive. I use this ido hack to quickly jump to function definitions, it does its best to pars most common languages :

(defun ido-goto-symbol (&optional symbol-list)
  "Refresh imenu and jump to a place in the buffer using Ido. Bound to M-i.
Try it on your dad's stereo."
  (interactive)
  (unless (featurep 'imenu)
    (require 'imenu nil t))
  (cond
   ((not symbol-list)
    (let ((ido-mode ido-mode)
          (ido-enable-flex-matching
           (if (boundp 'ido-enable-flex-matching)
               ido-enable-flex-matching t))
          name-and-pos symbol-names position)
      (unless ido-mode
        (ido-mode 1)
        (setq ido-enable-flex-matching t))
      (while (progn
               (imenu--cleanup)
               (setq imenu--index-alist nil)
               (ido-goto-symbol (imenu--make-index-alist))
               (setq selected-symbol
                     (ido-completing-read "Symbol? " symbol-names))
               (string= (car imenu--rescan-item) selected-symbol)))
      (unless (and (boundp 'mark-active) mark-active)
        (push-mark nil t nil))
      (setq position (cdr (assoc selected-symbol name-and-pos)))
      (cond
       ((overlayp position)
        (goto-char (overlay-start position)))
       (t
        (goto-char position)))))
   ((listp symbol-list)
    (dolist (symbol symbol-list)
      (let (name position)
        (cond
         ((and (listp symbol) (imenu--subalist-p symbol))
          (ido-goto-symbol symbol))
         ((listp symbol)
          (setq name (car symbol))
          (setq position (cdr symbol)))
         ((stringp symbol)
          (setq name symbol)
          (setq position
                (get-text-property 1 'org-imenu-marker symbol))))
        (unless (or (null position) (null name)
                    (string= (car imenu--rescan-item) name))
          (add-to-list 'symbol-names name)
          (add-to-list 'name-and-pos (cons name position))))))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.