CEDET & Emacs
17 May 2019Back in 2014 as part of my switch from XEmacs to Emacs I came across CEDET (Collection of Emacs Development Environment Tools) and although I recall using it for a personal project or two around the time, I otherwise never seriously used it. However I recently had reason to re-evaluate it, and as well as details of my updated configuration there is technical commentary resultant of this investigation alongside an overview of my modern requirements. Some of this was originally slated for a more general write-up on system setup, but I felt there was enough to say for it to be spun out into its own article.
Background
I have historically used XEmacs but due to circumstances at the time I made a switch to Vim in late-2013 — in short XEmacs was broken, I was unimpressed with Emacs, and Vim was in favour amoung colleagues. My feeling about Vim when I started using it was that it is geared for editing files rather than writing them anew, considering the ease at which things like re-indentation and search/replace can be done, and I felt that the former emphasis was useful given that most of the time I was making changes to existing program code rather than writing large blocks of new business logic. Later on I finally wrote off XEmacs as dead and had a proper investigation into using Emacs, and concluded that using it with CEDET and Tab-bar was a good combination for writing C code.When in 2015 I returned to writing C code professionally I found that Emacs with CEDET exhibited strange effects such as that shown below as well as general clunkiness on the under-powered setup I ended up using: Fedora 20 or 21 running in a VM using one of the two cores on a Windows8 laptop — I adopted this setup because I found the latency of a remote desktop onto the dedicated development servers to be a bit too high for my liking. To make matters worse using Emacs in an xterm ended up being a complete non-starter due to there being issues I was simply not interested in investigating and I certainly was not interested in maintaining a seperare configuration — in constrast Vim (runs in console) and GVim (runs in own window) are virtually identical in operation. Since I had already looked into Vim for C programming my preference for Vim was finally cemented, so when I got an upgraded work computer around two years later I did not even think of reconsidering my editor of choice.
I recently moved to a new company, where things are rather different to my previous two companies — all development occurs on desktop workstations rather than servers or VMs that are accessed via shell logins, and I had a virtual blank sheet in terms of what software was used for the workstation build. Deciding on development environment does not happen very often, and following chance remarks from a colleague about Emacs put the idea that I ought to at least check it out.
Personal requirements
Choosing an editor for developing program code is a huge investment — I have used (G)Vim for five years and before that used XEmacs for twelve — so before I even consider a change I have to be convinced trading in existing familiarity is likely to be worthwhile. For convenience and sanity I use the same setup for both personal and professional projects, so any viable candidate has to satisfy requirements for both, and in rough order of importance there are four things I look for — indentation support, auto-completion, tabbed viewing, and code folding.Customisable automatic indentation Manually doing code indentation is a right pain and automating it has the added benefit of highlighting subtle errors in program flow caused by incorrect bracing. However almost all the source code editors I have seen assume either a fixed bracing style, typically one I consider to be awful such as GNU style, or are very limited in what variations they allow. My preferred style is a slight variant of Whitesmiths — I don't indent the top-level function braces, and in the past I used an unusual 3-space tab — of which a sample is shown below:
int heaviside(int idxParam) { if( idxParam < 0 ) { return 0; } else { return 1; } }
Code auto-completion
Particularly when coding guidelines push developers towards using relatively long identifiers for functions and variables, typing them all out is both tedious and error-prone, so it is useful to be able to type a short prefix and then select one from a list of matching identifiers. While context-sensitive completion best personified by Visual Studio's Intellisense are nice, I find that simple and light-weight word-based autocompletion suits me fine in practice, and has the added advantage of not being tied to any specific language.
Tabbed editing
I like using tabbed programs because it keeps down the number of open windows on my desktops, and it is in line with my preference that operating systems should just handle switching between program instances and not concern themselves with individual documents. I never liked taskbar button combining when I first saw it in WindowsXP, as I preferred my tabs being chronological, and some of the other workstation environments I have used in the past such as CDE and TWM didn't even have taskbars. https://lists.gnu.org/archive/html/emacs-devel/2010-04/msg00013.html
Code folding
The basic idea behind code folding is hiding detail that is not of interest, which is useful when using small displays that cannot easily accommodate multiple side-by-side views of the same source file, or in order to see the overall structure of a program. In the past when I used token-based folding and hence had complete control over fold locations I often used it as a substitute to putting a piece of code into its own function, but these days fold tokens are a no-no in the code-bases I work with professionally so I now instead use syntax folding and set things up to only fold entire functions.
XEmacs alive, barely
I am not sure if XEmacs is back from the dead or simply more visible in its development, but either way it is in a lot better state than what I saw last time I checked it five years ago. Problem is that XEmacs is incompatible with Emacs's lisp packages and its own package eco-system is extinct, whereas in the interim my requirements for a programming editor have moved on. If I was to seriously consider re-adopting XEmacs I would at the very least expect something like AutoComplete, but short of major effort on my part nothing like that is on the horizon — incidentally AutoComplete is no longer maintained, which makes me wonder if Emacs's package eco-system also has issues.CEDET developments
In the process of cleaning up my Emacs configuration, which included updating the version of CEDET I had, I found out that the development of CEDET is a complete mess. CEDET had de-facto two forks, a stand-alone version and a version bundled with Emacs itself, although from around 2014 it appears they began to diverge and this was probably driven by changes to Emacs itself. Most of the documentation out there is written assuming use of the stand-alone version, but it looks like development of the latter version ceased in late-2017 — there seems to have been an effort that year to pull changes from the stand-alone version into the bundled version, but it is pretty clear that some features were dropped and a few other bits changed in the process. The latter is why a lot of the documentation out there is basically useless. The most annoying thing is the absence ofglobal-cedet-m3-minor-mode
, which is a context-sensitive right-click pop-up menu CEDET, although the two key-combinations below achieve the most important things the pop-up contained:
M-x ---j
- Esc-X then three minuses then j — jump to function definition
C-c ,g
- Ctrl-C then comma then g — search for instances of tag (i.e. keyword)
Emacs Configuration
In this section I will briefly cover all the sections from my Emacs configuration files — most don't need much explanation and some might not even be of interest, but for completeness I include them all. Firstly, set the mouse wheel scroll delta to three lines, and no acceleration so this speed is constant:(setq mouse-wheel-scroll-amount '(3 ((shift) . 3))) (setq mouse-wheel-progressive-speed nil)
Default width of 84 chars, which allows for 80 columns of code plus an allowance for line numbers on the left-hand side. I am not sure what units the height is, as it approximates lines but is shorter than expected.
(add-to-list 'default-frame-alist '(height . 54)) (add-to-list 'default-frame-alist '(width . 84))
Move scrollbar to righthand-side:
(set-scroll-bar-mode 'right)
Line & column numbers in footer:
(global-linum-mode 1)
Windows-style (Ctrl-X/Ctrl-V/Ctrl-V) cut-and-paste:
(cua-mode 1)
Load Tab-bar — I have no idea where this version came from:
(add-to-list 'load-path "~/.emacs.d/lib") (load-file "~/.emacs.d/lib/tabbar-ruler.el")
Some customised searching buttons, some of which are obviously close-copies of search keys from Vim:
(require 'highlight-symbol) (global-set-key [f3] 'highlight-symbol) (global-set-key (kbd "C-~") 'highlight-symbol-next) (global-set-key (kbd "C-#") 'highlight-symbol-prev) (global-set-key [(shift f3)] 'highlight-symbol-query-replace)
These respectively load my preferred C indentation style and the CEDET configuration, both of which are presented later.
(load-file "~/.emacs.d/remy-c-style.el") (load-file "~/.emacs.d/cedit.el")
The custom-file
is the one that Save Options under the Options menu writes to. I have included the current contents of mine.
(setq custom-file "~/.emacs.d/custom.el") (load custom-file)
CEDET Configuration
This is my CEDET setup, most of which is setting up custom hot-keys such as Ctrl-n to bring up the code auto-completion popup window. Thesemantic-tag-folding.el
is something I pulled over from the stand-alone CEDET and it implements code -folding toggles on the left-hand side.
(semantic-mode 1) (load-file "~/.emacs.d/lib/semantic-tag-folding.el") (defun my-semantic-hook () (global-semantic-tag-folding-mode 1) (local-set-key (kbd "C-c <left>") 'semantic-tag-folding-fold-block) (local-set-key (kbd "C-c <right>") 'semantic-tag-folding-show-block) (local-set-key (kbd "C-N") 'semantic-ia-complete-symbol-menu) (local-set-key (kbd "C-S-N") 'senator-force-refresh) (local-set-key (kbd "C-S-N") 'senator-completion-menu-popup) ) (add-hook 'semantic-init-hooks 'my-semantic-hook)
remy-c-style.el file
A Whitesmiths-esque indentation style. I most likley wrote this snippet back in 2000 so have long forgotten how to work out what parts of C code correspond to each tag.(setq remy-c-style '((c-offsets-alist . ((defun-block-intro . 0) (statement-block-intro . 0) (substatement-open . +) (inclass . 0))))) (add-hook 'c-mode-common-hook (function (lambda () (c-add-style "remy-c-style" remy-c-style t))))
custom.el file
For reference mycustom.el
looks like the following, albiet with comments stripped out.
(custom-set-variables '(backward-delete-function (quote backward-delete-char-untabify)) '(blink-cursor-mode nil) '(c-label-minimum-indentation 0) '(column-number-mode t) '(cua-mode t nil (cua-base)) '(default-gutter-position (quote top)) '(delete-key-deletes-forward t) '(font-lock-mode t t (font-lock)) '(gutter-buffers-tab-visible-p t) '(inhibit-startup-screen t) '(mouse-wheel-progressive-speed nil) '(package-selected-packages (quote (auto-complete-c-headers))) '(safe-local-variable-values (quote ((c-indent-level . 8)))) '(show-paren-mode t) '(xterm-mouse-mode t)) (custom-set-faces '(default ((t (:inherit nil :stipple nil :background "white" :foreground "black" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 98 :width normal :foundry "unknown" :family "DejaVu Sans Mono")))))
Watch out for the final long line — I'm not sure if Emacs allows it to be split.