So you’re coming from VS Code, IntelliJ, Sublime, or another modern IDE. You’re used to things working a certain way. You probably have muscle memory for shortcuts that are now useless. You might even be questioning your life choices right now.
This appendix is your bridge. It’s the Rosetta Stone between the IDE world and the Emacs universe. We’ll translate concepts, map features, and show you how to get your familiar workflows running in Emacs—then show you why the Emacs way might actually be better.
IDE Thinking: “I have an editor with plugins” Emacs Thinking: “I have a Lisp environment that edits text”
This isn’t just semantics. In VS Code, you’re using someone else’s editor with your customizations. In Emacs, you’re building YOUR editor from primitives.
| VS Code | Emacs | Package/Config |
|---|---|---|
Command Palette (Cmd+Shift+P) |
M-x |
Built-in |
| File Explorer | Dired / Treemacs | Built-in / treemacs |
Quick Open (Cmd+P) |
C-x C-f or SPC SPC |
consult/projectile |
Find in Files (Cmd+Shift+F) |
M-x rg or C-c p s r |
ripgrep/projectile |
| Git Integration | Magit | magit |
| Terminal | M-x vterm or M-x eshell |
vterm / eshell |
| Extensions | Packages | MELPA |
| settings.json | init.el | Built-in |
| IntelliSense | LSP-mode + Company | lsp-mode + company |
| Debugger | DAP-mode | dap-mode |
| Markdown Preview | C-c C-c p in markdown-mode |
markdown-mode |
| Zen Mode | writeroom-mode | writeroom-mode |
| Multiple Cursors | multiple-cursors | multiple-cursors |
| Bracket Matching | show-paren-mode | Built-in |
| Minimap | minimap | minimap |
If you can’t live without these:
(cua-mode t)
(setq cua-auto-tabify-rectangles nil)
(setq cua-keep-region-after-copy t)
But try to learn the Emacs way—it’s more powerful.
;; VS Code familiar keybindings
(global-set-key (kbd "C-/") 'comment-line)
(global-set-key (kbd "C-S-k") 'kill-whole-line)
(global-set-key (kbd "C-S-d") 'mc/mark-next-like-this)
(global-set-key (kbd "M-<down>") 'move-line-down)
(global-set-key (kbd "M-<up>") 'move-line-up)
(global-set-key (kbd "C-`") 'vterm)
(defun move-line-up ()
"Move the current line up."
(interactive)
(transpose-lines 1)
(forward-line -2)
(indent-according-to-mode))
(defun move-line-down ()
"Move the current line down."
(interactive)
(forward-line 1)
(transpose-lines 1)
(forward-line -1)
(indent-according-to-mode))
(use-package projectile
:ensure t
:init (projectile-mode +1)
:config
(setq projectile-enable-caching t)
:bind-keymap
("C-c p" . projectile-command-map))
;; Quick file switching
(use-package consult-projectile
:ensure t
:bind ("C-x p f" . consult-projectile-find-file))
(use-package treemacs
:ensure t
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag)))
(use-package treemacs-projectile
:ensure t
:after (treemacs projectile))
(use-package treemacs-magit
:ensure t
:after (treemacs magit))
If you’re coming from Vim (or VS Code with Vim mode):
(use-package evil
:ensure t
:init
(setq evil-want-integration t)
(setq evil-want-keybinding nil)
(setq evil-want-C-u-scroll t)
(setq evil-want-C-i-jump nil)
:config
(evil-mode 1))
(use-package evil-collection
:ensure t
:after evil
:config
(evil-collection-init))
;; Make it even more Vim-like
(use-package evil-commentary
:ensure t
:config (evil-commentary-mode))
(use-package evil-surround
:ensure t
:config (global-evil-surround-mode 1))
M-x is your command palette, but better:
(use-package which-key
:ensure t
:config
(which-key-mode)
(setq which-key-idle-delay 0.3))
(use-package helpful
:ensure t
:bind
([remap describe-function] . helpful-callable)
([remap describe-variable] . helpful-variable)
([remap describe-key] . helpful-key))
;; Better search
(use-package consult
:ensure t
:bind (("C-s" . consult-line) ; Search in buffer
("M-s g" . consult-ripgrep) ; Search in project
("C-x b" . consult-buffer) ; Switch buffer
("M-y" . consult-yank-pop))) ; Clipboard history
(use-package lsp-mode
:ensure t
:commands lsp
:hook ((typescript-mode . lsp)
(js2-mode . lsp)
(python-mode . lsp)
(rust-mode . lsp)
(go-mode . lsp))
:config
(setq lsp-prefer-flymake nil))
(use-package company
:ensure t
:hook (prog-mode . company-mode)
:config
(setq company-idle-delay 0.1
company-minimum-prefix-length 1))
C-x C-c - Quit EmacsC-g - Cancel current commandESC ESC ESC - Get out of anythingmacOS steals many Emacs shortcuts. Fix it:
;; Modern theme
(use-package doom-themes
:ensure t
:config
(load-theme 'doom-one t)
(doom-themes-visual-bell-config)
(doom-themes-org-config))
;; Modern modeline
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1))
;; Icons
(use-package all-the-icons
:ensure t)
;; Run M-x all-the-icons-install-fonts first time
;; Tabs like modern editors
(use-package centaur-tabs
:ensure t
:config
(setq centaur-tabs-style "bar"
centaur-tabs-set-icons t
centaur-tabs-set-modified-marker t)
(centaur-tabs-mode t)
:bind
("C-<prior>" . centaur-tabs-backward)
("C-<next>" . centaur-tabs-forward))
Here’s a config that makes Emacs feel like a modern IDE:
;;; Modern IDE configuration
;; Package management
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(package-initialize)
;; Bootstrap use-package
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
;; Modern completion
(use-package vertico
:ensure t
:init (vertico-mode))
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic)))
(use-package marginalia
:ensure t
:init (marginalia-mode))
(use-package consult
:ensure t
:bind (("C-x b" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("M-g g" . consult-goto-line)
("M-s r" . consult-ripgrep)))
;; IDE features
(use-package lsp-mode
:ensure t
:commands lsp
:hook ((typescript-mode . lsp-deferred)
(js2-mode . lsp-deferred)
(python-mode . lsp-deferred)
(rust-mode . lsp-deferred)
(go-mode . lsp-deferred))
:config
(setq lsp-headerline-breadcrumb-enable t))
(use-package lsp-ui
:ensure t
:commands lsp-ui-mode
:config
(setq lsp-ui-sideline-show-hover t
lsp-ui-doc-position 'at-point))
(use-package company
:ensure t
:hook (after-init . global-company-mode))
(use-package flycheck
:ensure t
:init (global-flycheck-mode))
;; Git
(use-package magit
:ensure t
:bind ("C-x g" . magit-status))
;; Project management
(use-package projectile
:ensure t
:init (projectile-mode +1)
:bind-keymap ("C-c p" . projectile-command-map))
;; File tree
(use-package treemacs
:ensure t
:bind ("M-0" . treemacs-select-window))
;; Better defaults
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
(global-display-line-numbers-mode 1)
(show-paren-mode 1)
(electric-pair-mode 1)
(setq ring-bell-function 'ignore)
;; Theme
(use-package doom-themes
:ensure t
:config (load-theme 'doom-one t))
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1))
VS Code:
Cmd+P → type filenameCmd+S to saveEmacs:
C-x C-f → type filename (with completion)C-x C-s to saveVS Code:
Cmd+Shift+F for find in filesEmacs:
C-c p r (projectile-replace) or M-x rg! to replace all or y/n for eachVS Code:
Emacs with Magit:
C-x g for statuss to stage filesc c to commitC-c C-c to finish;; Faster startup
(setq gc-cons-threshold 100000000)
(setq read-process-output-max (* 1024 1024))
;; Optimize for long lines
(setq-default bidi-display-reordering nil)
;; Native compilation (Emacs 28+)
(setq package-native-compile t)
Things Emacs does that your IDE can’t:
/ssh:server:/path/fileGive Emacs 30 days. Here’s your progression:
Week 1: Basic editing, don’t customize much Week 2: Add packages, configure basics Week 3: Learn Org-mode, try Magit Week 4: Write your first Elisp function
If after 30 days you don’t see the appeal, you can always go back. But fair warning: most people who make it 30 days never leave.
You’re not giving up your IDE. You’re graduating from it. You’re moving from a product to a platform, from customization to programming, from using to creating.
Yes, the learning curve is steep. Yes, you’ll be slower at first. Yes, you’ll miss some features (at first).
But then one day, you’ll write a function that solves a problem unique to your workflow. You’ll record a macro that saves you an hour. You’ll realize your entire digital life is in plain text files you control. You’ll help someone with a problem and realize you can solve it in Emacs without thinking.
And you’ll wonder why anyone uses anything else.
Welcome to Emacs. Welcome home.
“I came from VS Code. I was productive in VS Code. I was happy in VS Code. Then I learned Emacs. Now VS Code feels like typing with mittens on.” —Reformed IDE User, 2024
(message "Welcome to Emacs! Your journey begins...")