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.cppand 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, andrpbeing symbolic links to executables. The error I was seeing"find process for pid". -
Including the
rtags/build/bindirectory to path seems to have issues with code completion. While I know there is amake installcommand, 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-envfor convenience - Install
elpyin emacs. I generally install packages from melpa. Pop open emacs and doM-x package-list-packagesand 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 ishould force callelpy-company-backendand 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
terngloballysu -c "npm install -g tern" - Install
company-ternin 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-projectin your root project directory with following contents{ "plugins": { "node": { }, "libs": [ ] } }
Demo of how it works: