A Gentle introduction to Cedet

This article doesn't pretend to represent detailed description of customization of Emacsas development environment (this is theme for separate article). I just tried to provide asmall description of "How to customize Cedet to work with C & C++", although most of thisdescription will also applicable for other languages, supported by Cedet.

What is Cedet?
Installation of the Cedet
Customization
Semantic's customization
Customization of Semanticdb
How to customize Semantic to work with C & C++ projects
Preprocessing of source code
Work with Semantic
Names completion
Getting information about tags
Navigation in source code
Search for places where function is called
Source code folding
Other commands implemented by Senator
Work with Srecode
Additional packages
The eassist package

What is Cedet?

The Cedet package is a collection of several libraries, implementing different commands,but used for one task — provide functionality for work with source code written indifferent programming languages:

  • Semantic is base for construction of syntactic analyzers for different programminglanguages. This allows to provide common representation for information extracted fromcode, written in different languages. Using this information, Cedet & other packages(JDEE and ECB), can implement commands, required for modern development environment(something like Eclipse, NetBeans, etc.);
  • SemanticDB is included into Semantic, and implements interfaces to different storagemodules, that keeps information, needed for names completion, source code navigation,and so on. Syntactic information could be saved between Emacs sessions, so it reduceneed for re-parsing of not modified source code.;
  • Senator implements navigation in source code file, using information, extracted bySemantic;
  • Srecode — package for source code generation, using syntactic information, includinginformation, obtained from Semantic;
  • EDE implements set of extensions to work with projects — user can control list ofthe targets to build, perform build of project, etc. Besides this, using notion of theproject, you can have more precise control about Semantic's operations — namecompletions, and so on;
  • Speedbar is used to display information about current buffer using different sources ofinformation — Semantic, some specialized information providers (for texinfo & html,for example), etc.
  • Eieio is a library, implementating CLOS-like (Common Lisp Object System) infrastructurefor Emacs Lisp;
  • Cogre is a library for drawing of UML-like diagrams in Emacs buffer, with basicintegration with Semantic.

Installation of the Cedet

Currently it's better to use development version of the Cedet, that is available fromrepository at Sourceforge.net. After downloading of code, you need to change to cedetdirectory and compile the package with following command:

emacs -Q -l cedet-build.el -f cedet-build

or, to compile in terminal window, and exit after compilation, you can use followingcommand:

emacs -Q -nw -l cedet-build.el -f cedet-build -f save-buffers-kill-terminal

Customization

The loading of package is performed by cedet.el script, so all you need to do — is justadd following line to the your Emacs initialization file2:

(load-file "~/emacs/cedet/common/cedet.el")

If you plan to use projects, then you need to switch on corresponding mode — it'simplemented by EDE package:

(global-ede-mode t)

Semantic's customization

Depending on your requirements, you can use one of the commands, described below, to loadcorresponding set of features (these commands are listed in increasing order, and eachcommand include features of previous commands):

  • semantic-load-enable-minimum-features — enables only minimum of necessary features —keep syntactic information for current buffer up-to date, storing of syntacticinformation for later use (Semanticdb), and loading of corresponding information withSemanticdb and Ebrowse;
  • semantic-load-enable-code-helpers — enables senator-minor-mode for navigation inbuffer, semantic-mru-bookmark-mode for storing positions of visited tags, andsemantic-idle-summary-mode, that shows information about tag under point;
  • semantic-load-enable-gaudy-code-helpers — enables semantic-stickyfunc-name thatdisplays name of current function in topmost line of buffer, semantic-decoration-modeto decorate tags, using different faces, and semantic-idle-completion-mode forautomatic generation of possible names completions, if user stops his work for sometime;
  • semantic-load-enable-excessive-code-helpers — enables which-func-mode, that shows nameof current function in status line;
  • semantic-load-enable-semantic-debugging-helpers — enables several modes, that areuseful when you debugging Semantic — displaying of parsing errors, its state, etc.

So, you need to add call to one of these commands right after command, that performsloading of Cedet. For example:

(semantic-load-enable-excessive-code-helpers)

The rest of this section assumes that the minimal Semantic features have been loaded.

To use additional features for names completion, and displaying of information for tags &classes, you also need to load the semantic-ia package. This could be performed withfollowing command:

(require 'semantic-ia)

After loading of this package, you'll get access to commands, described below.

System header files

To normal work with system-wide libraries, Semantic should has access to system includefiles, that contain information about functions & data types, implemented by theselibraries.

If you use GCC for programming in C & C++, then Semantic can automatically find path,where system include files are located. To do this, you need to load semantic-gcc packagewith following command:

(require 'semantic-gcc)

You can also explicitly specify additional paths for look up of include files (and thesepaths also could vary for specific modes). To add some path to list of system includepaths, you can use the semantic-add-system-include command, that accepts two parameters —string with path to include files, and symbol, representing name of major mode, for whichthis path will used. For example:

(semantic-add-system-include "~/exp/include/boost_1_37" 'c++-mode)

Optimization of Semantic's work

To optimize work with tags, you can use several techniques:

  • limit search by declaring an EDE project, as this described below;
  • explicitly specify a list of root directories for your projects, so Semantic will uselimited number of databases with syntactic information;
  • explicitly generate tags databases for often used directories (/usr/include,/usr/local/include, etc.) with the semanticdb-create-ebrowse-database orsemanticdb-create-cscope-database commands;
  • limit search by customization of the semanticdb-find-default-throttle variable forconcrete modes — for example, don't use information from system include files, byremoving system symbol from list of objects to search for c-mode:
(setq-mode-local c-mode semanticdb-find-default-throttle
                                                                 '(project unloaded system recursive))

Semantic extracts syntactic information when Emacs is idle. You can customize thesemantic-idle-scheduler-idle-time variable to specify idle time (in seconds), if you don'twant to use default value.

Integration with imenu

The Semantic package can be integrated with the imenu package. This enables the displayof a menu with a list of functions, variables, and other tags. To enable this feature youcan either use semantic-load-enable-code-helpers, or, you need to add following code intoyour initialization file:

(defun my-semantic-hook ()
  (imenu-add-to-menubar "TAGS"))
(add-hook 'semantic-init-hooks 'my-semantic-hook)

Customization of Semanticdb

If you use standard procedure for loading of Cedet, then Semanticdb will loadedautomatically. Otherwise, you can load and enable it with following commands:

(require 'semanticdb)
(global-semanticdb-minor-mode 1)

To customize Semanticdb you need to specify some number of variables, that are used tospecify path, where databases will stored, and some other parameters. These variablescould be set via semanticdb customization group.

Besides this, Semanticdb can use databases generated by external utilities — gtags fromGNU Global, ctags, ebrowse & cscope. To activate this you can use following code:

;; if you want to enable support for gnu global
(require 'semanticdb-global)
(semanticdb-enable-gnu-global-databases 'c-mode)
(semanticdb-enable-gnu-global-databases 'c++-mode)

;; enable ctags for some languages:
;;  Unix Shell, Perl, Pascal, Tcl, Fortran, Asm
(semantic-load-enable-primary-exuberent-ctags-support)

How to customize Semantic to work with C & C++ projects

To proper work of Semantic with С & C++ code is recommended to use the EDE package (workwith projects, etc.). For these languages, EDE package defines special project type —ede-cpp-root-project, that provides additional information to Semantic, that will be usedto analyze source code of your project.

To define a project, you need to use following code:

(ede-cpp-root-project "Test"
                :name "Test Project"
                :file "~/work/project/CMakeLists.txt"
                :include-path '("/"
                                "/Common"
                                "/Interfaces"
                                "/Libs"
                               )
                :system-include-path '("~/exp/include")
                :spp-table '(("isUnix" . "")
                             ("BOOST_TEST_DYN_LINK" . "")))

You can use any file at root directory of the project, as a :file parameter. This fileisn't parsed, but it's used only as an anchor to search a files in projects.

To search include files, Semantic uses directories from two lists, that could be specifiedfor project. The :system-include-path parameter is used to specify list of the full pathsthat will searched for "system" include files. Another parameter — :include-pathspecifies the list of directories, relative to the project's root directory, that willsearched for your include files (if names are starting with /, this means, that path isspecified relative to project's root directory). Instead of specifying paths as lists,you can also provide function, that will perform a search for include files in yourproject. You can read about it in the EDE's manual.

Another parameter, that could be specified in project's definition is a list ofdefinitions, that will be used during preprocessing of the code. The :spp-table parameterallows to specify list of pairs, consisting from symbol's name & value, defined for givenname. In our example above, we define two symbols — isUnix and BOOST_TEST_DYN_LINK, thatwill passed to preprocessor, and this allows to perform proper parsing of the code.

User, if this need, can redefine some variables for files inside project. This could bedone by specifying the :local-variables parameter, and passing to it list of pairs symbolname/value, and these values will set for files in project.

Preprocessing of source code

More information about definitions for preprocessor you can find in documentation for thesemantic-lex-c-preprocessor-symbol-map variable. List of preprocessor symbols defined forsome file with source code you can obtain with the semantic-lex-spp-describe command, anduse its result to customize :spp-table parameter or semantic-lex-c-preprocessor-symbol-mapvariable.

Many libraries list all defined macros in one of include files, so you can use thesedefinitions. To do this you need to list these files in thesemantic-lex-c-preprocessor-symbol-file variables, and when Cedet will perform analysis,this values will taken into account. By default, this variable has only one value — filewith definitions for C++ standard library. As example, I want to show Cedet'sconfiguration for work with Qt4:

(setq qt4-base-dir "/usr/include/qt4")
(semantic-add-system-include qt4-base-dir 'c++-mode)
(add-to-list 'auto-mode-alist (cons qt4-base-dir 'c++-mode))
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig.h"))
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig-dist.h"))
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qglobal.h"))

After adding of these lines to your initialization file, you'll be able to use namecompletion for classes, defined in Qt4 library. Example of this you can see on picturebelow.

A Gentle introduction to Cedet_第1张图片

Work with Semantic

From the user's point of view, Semantic implements several major commands — namecompletions, obtaining information about tags (variables, functions, etc.), and navigationin source code. Some of commands are implemented by semantic-ia package, while some otherare implemented in Senator, and rest of them, are implemented by Semantic's kernel.

Some of commands have no standard key bindings, so you it's better to select key bindings,that are comfortable to you, and bind needed commands to them, for example, like this:

(defun my-cedet-hook ()
  (local-set-key [(control return)] 'semantic-ia-complete-symbol)
  (local-set-key "\C-c?" 'semantic-ia-complete-symbol-menu)
  (local-set-key "\C-c>" 'semantic-complete-analyze-inline)
  (local-set-key "\C-cp" 'semantic-analyze-proto-impl-toggle))
(add-hook 'c-mode-common-hook 'my-cedet-hook)

I want to mention, that Semantic's development is pretty active, and if something doesn'twork, or works wrong, then please, send examples of code to the cedet-devel mailing list— the Cedet's author usually answers very quickly.

Names completion

Name completions for names of functions, variables & classes is pretty often used featurewhen you work with source code3. There are two packages inside Semantic that implementthis functionality — semantic-ia and Senator. Commands, implemented by semantic-ia usethe semantic-analyze-possible-completions function to create a list of all possible namescompletion, and this function take into account many parameters, and it could be alsoextended by user to provide more precise list of names. At the same time, commands fromSenator package use more simple methods to create a list of all possibles completions(usually use information about only definitions in current file), and this sometime leadto the wrong completion of names.

If you execute the semantic-ia-complete-symbol command when you typing code, then itsexecution will lead to completion of corresponding name — name of function, variable, orclass member, depending on current context. If there are several variants of name, thenthis name will completed to most common part of it, and if you'll call this command secondtime, then buffer with all possible completions will shown. User can also use thesemantic-ia-complete-symbol-menu command, that also analyze current context, and displayslist of possible completions as a graphical menu, from which the needed name could beselected by user4. Besides this, there is semantic-ia-complete-tip command, thatdisplays list of possible completions as tooltip.

As was mentioned above, the Senator package, also provides commands for names completion,that work fast, but with less precision, as they use few parameters during computation ofnames for completions. The senator-complete-symbol command (C-c , TAB) completes name forcurrent tag, and insert first found completion as result. If it substitute wrong name,then you can insert second name from completion list by repeating this command, and so on.If there are lot of the possible names, or you want to see full list of functions andvariables for some class, then it's better to use the senator-completion-menu-popupcommand (C-c , SPC), that displays list of all possible completions as a graphical menu.

Besides these commands, for some languages user can use special mode —semantic-idle-completions-mode (it loaded when you useemantic-load-enable-gaudy-code-helpers, or you can enable it explicitly) — in this modenames completions are shown automatically if user stops its work for a some time (idletime). By default, only first possible completion is shown, and user can use the TAB keyto navigate through list of possible completions.

For C-like languages, user can use the semantic-complete-self-insert command, bound to the. and/or > keys, as this show below:

(defun my-c-mode-cedet-hook ()
 (local-set-key "." 'semantic-complete-self-insert)
 (local-set-key ">" 'semantic-complete-self-insert))
(add-hook 'c-mode-common-hook 'my-c-mode-cedet-hook)

Use of this setting will lead to execution of semantic-complete-self-insert command whenuser will press . or > after variables, that are class or structure instances, anddisplaying of list of possible completions for given class or structure.

Getting information about tags

The semantic-ia package implements several commands, that allows to get information aboutclasses, functions & variables. As documentation are used comments, extracted from sourcecode, including comments, written for Doxygen. Now following commands are implemented:

semantic-ia-show-doc
shows documentation for function or variable, whose names isunder point. Documentation is shown in separate buffer. For variables this commandshows their declaration, including type of variable, and documentation string, if itavailable. For functions, prototype of the function is shown, including documentationfor arguments and returning value (if comments are available);
semantic-ia-show-summary
shows documentation for name under point, but information isshown in the mini-buffer, so user will see only variable's declaration or function'sprototype;
semantic-ia-describe-class
asks user for a name of the class, and return list offunctions & variables, defined in given class, and all its parent classes.

Navigation in source code

One of the most useful commands for navigation in source code is the semantic-ia-fast-jumpcommand, that allows to jump to declaration of variable or function, whose name is underpoint. You can return back by using the semantic-mrub-switch-tag command (C-x B), that isavailable when you use the semantic-mru-bookmark-mode minor mode.

Semantic also provides two additional commands for jumping to function or variable:defined in current file — semantic-complete-jump-local (C-c , j), or defined in currentproject — semantic-complete-jump (C-c , J). Both commands allow to enter name offunction or variable (including local variables for functions) and jump to givendefinition (you can use name completion when entering the name).

The main difference between semantic-ia-fast-jump & semantic-complete-jump commands isthat the first properly handles complex names, like this::that->foo(), while the second,can find only simple names, like foo.

The semantic-analyze-proto-impl-toggle command allows to switch between function'sdeclaration and its implementation in languages, that allow to have separate declarationand implementation of functions. Another useful command issemantic-decoration-include-visit, that allows to switch to the include file, whose nameis under point.

Senator also implements several commands for navigation in source code. This issenator-next-tag (C-c , n) and senator-previous-tag (C-c , p) commands, that move cursorto next or previous tag, and also the senator-go-to-up-reference command (C-c , u), thatmove cursor to the "parent" tag (for example, for class member function, "parent" tag isclass declaration).

Search for places where function is called

Not so long ago a very useful command was implemented in Semantic — semantic-symref, thatallows to find places, where symbol, whose name is under point, is used in your project.If you want to find usage of symbol with any name, you can use the semantic-symref-symbol,that allows to explicitly specify name of the symbol.

If references to given name weren't found in corresponding database (GNU Global, etc.),then this command tries to find them with the find-grep command. As result of executionof these commands, a new buffer with results will created, and user can use them to jumpto corresponding places:

Source code folding

As Semantic has almost full syntactic information about source code, this allows it toimplement folding functionality, similar to functionality implemented by hideshow package.To enable this feature, you need to do customization of theglobal-semantic-tag-folding-mode variable. When you'll enable it, this will lead todisplaying of small triangles at the fringle field, and you'll able to fold and unfoldpieces of code pressing on them (not only pieces source code, but also comments, and otherobjects).

Senator also has similar functionality, but it usually used for top-level objects —functions, class declarations, etc. You can fold piece of code with the senator-fold-tagcommand (C-c , -), and unfold with senator-unfold-tag (C-c , +).

Other commands implemented by Senator

The Senator package defines number of commands for work with tags, that allow user to cutor copy tag, and insert it in another place, etc. To cut current tag (usually this isdeclaration of some function or its implementation) the senator-kill-tag command (C-c ,C-w) is defined. You can insert tag with standard key binding C-y, while thesenator-yank-tag command (C-c , C-y) inserts only tag declaration, without body. Anotheruseful command is senator-copy-tag (C-c , M-w), that copies current tag — this is veryhandy when you want to insert declaration of function into include file, for example.

Senator allows to change behaviour of standard search commands (re-search-forward,isearch-forward and other), when you work with source code, such way, so they will performsearch only in given tags. To enable this mode you can use thesenator-isearch-toggle-semantic-mode command(C-c , i), and with thesenator-search-set-tag-class-filter command (C-c , f) you can limit search to given tagtypes — function for functions, variable for variables, etc.

You can also perform tags search without enabling this mode — you just need to callcorresponding command: senator-search-forward or senator-search-backward.

Work with Srecode

The Srecode package allows user to define different code templates, but it differs fromother packages, that provide insertion of templates, as far as list of available templatescould vary depending on current context. For example, insertion of get/set functions willhappen only when you inside class declaration. Or, insertion of function declaration,could happen only outside of other function.

The main command, that is used to insert templates, is the srecode-insert, that bound tothe C-c / / keys. This command will ask user for name of template to insert (you canenter it using name completion). List of available templates will vary, depending oncurrent context. If you want to insert the same template once again, then you can use thesrecode-insert-again command (C-c / .).

Templates, defined by user, could also use they own key bindings. They can use lower-casesymbols from range C-c / [a..z], and user can specify template's declaration, which keywill assigned to it. For example, for C++ you can use the C-c / c key binding to insertdeclaration of class.

Key bindings, that use upper-case symbols, are reserved for templates & commands definedin Srecode. For example, C-c / G (srecode-insert-getset) inserts pair of functionsget/set for some class member variable, while C-c / E (srecode-edit) is used to edittemplates. List of this commands vary from time to time, so you need to look intodocumentation to get actual list of commands.

Besides templates, supplied with Cedet, user can define their own templates, and storethem in the ~/.srecode directory, where Cedet finds them automatically. You can readabout templates creation in the Srecode manual, that comes together with otherdocumentation in Cedet distribution.

Additional packages

Together with Cedet the number of additional packages is supplied. Some of them arelocated in the contrib subdirectory, that also will added to package search list, when youload Cedet, so you don't need to do anything special to load them.

The eassist package

The eassist package implements several additional commands, that for their work useinformation obtained from Semantic. By default, these commands have no predefined keybindings, so you need to select them yourself.

The eassist-list-methods command, executed in file with source code, will show you a listof functions, defined in current buffer, and allows you to perform quick jump to selectedfunction.

If you develop code in C and/or C++ languages, then the eassist-switch-h-cpp command,could be very useful to you — it jumps between include file and file, that containsimplementation (if they have same names, but different extensions).

To the main page

1. First line is need only when you build package from CVS

2. You can take my configuration file for Cedet as a base, although it contains lot ofnot needed things

3. There is also semantic-complete-analyze-inline command, that shows list of allpossible completions in separate window, that is often handy than graphical menu

4. If name completion works improperly, then try to analyze why this happens, and sendbug report only after this. Information about debugging you can find in Semantic UserGuide in section Smart Completion Debugging


你可能感兴趣的:(A Gentle introduction to Cedet)