Don't let the default bare configuration of Emacs scare you away: It's highly customizable outside (see e.g. better-defaults for what aims to be improvements over default settings), cross-platform, and there are a large number of great packages such as Magit and org-mode. In my opinion, just Magit alone makes your initial investment into learning Emacs worth it. As a plus, when stuck working on a Windows machine, you can still pop open Emacs and make the best of the situation. But Emacs by itself is just a text editor and not a full-blown IDE. But with a little configuration and installing packages, it can be made to act like one.
Initially when I moved the switch to Emacs as my default text
editor back in ~2009, I was almost exclusively working with
C++. I spent consider about of time setting up the "perfect"
configuration for code-completion and jumping to definitions
with cedet
and semantic
combo, which on larger code bases
resulted in a pain-stakingly slow code-completion and error-
prone jump-to-definition with no support for c++11
standards onward.
These days the three class of languages I frequently use are c++, python, js/nodejs, and the the out-of-the-box code completion with emacs for these languages are minimal or non-existent. But with minimal effort and using existing toolset, you can get a uniform-ish and decent IDE-like behavior in Emacs.
C and C++ : RTags
Any decent code completion for Emacs seems to require a daemon running in the background. By far the best solution I have used for C and C++ is RTags. As a plus, with an initial configuration in place, it will "just work" if the project uses cmake as its build tool.
Installation
I use rtags with company
as opposed to auto-complete
as
the text completion framework. This made the initial build,
installation, and setup for getting rtags
working
was a pretty frustrating experience. Specifically, what I
learned was that the code completion for some reason wasn't
working if working under /tmp
. My final setup
documetation was as follows:
- Install prerequisites. For this installation I'm using OpenSUSE
zypper in gcc-c++ clang clang-devel llvm llvm-devel cmake
- Build rtags
> git clone --recursive https://github.com/Andersbakken/rtags.git > cd rtags && mkdir build && cd build > cmake .. > cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 . > make -j 4
- Copy bin files
> cp ./bin/* ~/bin/
- Install emacs prerequisites from melpa:
company, rtags, company-rtags
- Update emacs init scripts
;; use and initalize package if haven't already done so (require 'cl) (require 'rtags) (require 'company) (define-key c-mode-base-map (kbd "M-.") (function rtags-find-symbol-at-point)) (define-key c-mode-base-map (kbd "M-,") (function rtags-find-references-at-point)) (rtags-enable-standard-keybindings) (setq rtags-autostart-diagnostics t) (rtags-diagnostics) (setq rtags-completions-enabled t) (push 'company-rtags company-backends) (global-company-mode) (define-key c-mode-base-map (kbd "<C-tab>") (function company-complete))
- Check if everything's working fine.
If no errors, then pop open a new emacs session, and navigate to> rdm & > cd </path/to/rtags/build/directory> > rc -J ../
/path/to/rtags/src/rdm.cpp
and verify that symbol combinations work.
Troubleshooting
- It took me about 3 hours to finally learn that rtags will
NOT work for code under
/tmp/
. Error code:
.Shouldn't index <FILE_NAME> because of excluded filter
-
There seem to be issues
with
rdm
,rc
, andrp
being symbolic links to executables. The error I was seeing"find process for pid"
. -
Including the
rtags/build/bin
directory to path seems to have issues with code completion. While I know there is amake install
command, I ended up manually copying the bin files to my~/bin/
directory for everything to function. -
Having wrappers
rtags/bin/
aliasgcc/g++
seemed to be causing more issues for code completion. -
Must include
(require 'cl)
in emacs config.
Python
I use jedi and company mode for python. To get started, read the official documentation, or:
- Install prerequisites
su -c "zypper in python3-virtualenv"
- Start a project
> mkdir my-project-name > cd my-project-name > virtualenv-3.7 env # replace with appropriate virtualenv version
- Activate the virtual environment and install
jedi
> . ./env/bin/activate > pip install jedi
-
Move contents to
~/bin/jedi-env
for convenience - Install
elpy
in emacs. I generally install packages from melpa. Pop open emacs and doM-x package-list-packages
and installelpy
- Update
~/.emacs.d/
config files;... (elpy-enable) (add-hook 'python-mode '(lambda() (set (make-local-variable 'company-backends '(elpy-company-backend))) (company-mode))) (defun hf/python-mode-hook () (add-to-list 'company-backends 'company-jedi) (require 'pyvenv) (pyvenv-activate "~/bin/jedi-env/") (setq jedi:setup-keys t) (setq jedi:complete-on-dot t) (setq jedi:use-shortcuts t) (jedi:setup) ) (add-hook 'python-mode-hook 'hf/python-mode-hook) ;...
- If for some reason pyvenv is not enabled, try
explicitely enabling jedi virtual environment
and direct to parent directory containing the virtual environment.M-x pyvenv-activate <enter>
- Everything should work now, e.g.
-
M-.
should jump to definition -
C-M i
should force callelpy-company-backend
and autocomplete at point -
C-c ?
show docstring of object at given point
-
Below shows a demo of how it works. Consider playing the video in fullscreen mode and look at messages in the minibuffer especially when there is a small pause.
Javascript and Node.js
- Install
tern
globallysu -c "npm install -g tern"
- Install
company-tern
in Emacs - Add following to
~/.emacs.d/init.el
(require 'company-tern) (eval-after-load 'company '(add-to-list 'company-backends 'company-tern)) (add-hook 'js2-mode-hook (lambda () (tern-mode t)))
-
Create
.tern-project
in your root project directory with following contents{ "plugins": { "node": { }, "libs": [ ] } }
Demo of how it works: