Which tutorial/book/course do you recommend if someone is learning Emacs for Elixir development?

I just checked, it took 8-10 seconds. So I miscalculated. 379 packages though.

To me, emacs feels like it does things faster, but its much heavier (by a large factor), vim is way more lightweight feeling and direct, but some actual commands and screen redraws are slower (sucks)

For example, opening project files, making new files or folders, closing buffers,… I don’t want to have to hit 3 keys to do all that in the file or buffer menus. Vim actually may be close to the same number of keys but in my mind it feels way more efficient than always following the SPC b b f e fjeeija ewoifjaw oeifjawo format.

1 Like

My start time for emacs isn’t as heavy as that, still, it’s perhaps the slowest part of it all, which for me doesn’t really bother me since I usually open it on reboot and it’s open until the next reboot in a few days without ever having any problem with that or the dozens (literally dozens and dozens) of opened buffers.

It’s not perfect, but I found it more productive than Atom or textmate for instance (which were the only two other text editors I’ve used). Atom has one thing I absolutely love though, which is the ability to collapse blocks of code, which sometimes helps, but other than that I found emacs to allow very fast and easy jumping around, specifically through the key sequences that you don’t seem to like. If I have 15 buffers opened, between different folders and projects, switching from one to any other is trivial, CTRL+X CTRL+B and I have all opened buffers in front of me, CTRL+S I can type anything to jump to it or just use regular emacs navigation to find what I want - since I always have two buffers split horizontally, I can CTRL+O to open whatever file in the other buffer and then proceed to open another in the current one. If I need a file that’s not in a buffer, if it’s close to the path of the file I’m working on I can just CTRL+X CTRL+F and because of projectile be able to go through the files and directories with simple direction keys, backspace, return, while allowing me to filter files on regex without having to do anything else besides typing (like _web, will get me all files that have _web somewhere in the filename). If it’s not on the same folder but I have an opened buffer in that folder/close to it, I can switch to that buffer and then run projectile’s to navigate from there. You also have a great undo cycle (literally allows you to move through all changes in the buffer), and you can copy/cut multiple things and then paste them and cycle through things you’ve cut (killed…) previously when pasting. Perhaps vim has all of this stuff, I never used it, so not sure it’s better of worse - but I’m very happy with using emacs.

I basically did the tutorial that comes with emacs, then whenever I had a need I googled for it - “emacs repeat search”, “emacs copy paste”, etc etc

This is my init file for it (some things are MacOSX specific, others are for clojure/lisp and not relevant):

;;;;
;; Packages
;;;;

;; Define package repositories
(require 'package)
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/") t)
(add-to-list 'package-archives
             '("tromey" . "http://tromey.com/elpa/") t)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)

;; (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
;;                          ("marmalade" . "http://marmalade-repo.org/packages/")
;;                          ("melpa" . "http://melpa-stable.milkbox.net/packages/")))



;; Load and activate emacs packages. Do this first so that the
;; packages are loaded before you start trying to modify them.
;; This also sets the load path.
(package-initialize)

;; Download the ELPA archive description if needed.
;; This informs Emacs about the latest versions of all packages, and
;; makes them available for download.
(when (not package-archive-contents)
  (package-refresh-contents))

;; Define he following variables to remove the compile-log warnings
;; when defining ido-ubiquitous
(defvar ido-cur-item nil)
(defvar ido-default-item nil)
(defvar ido-cur-list nil)
(defvar predicate nil)
(defvar inherit-input-method nil)

(setq mac-option-key-is-meta t)
(setq mac-right-option-modifier nil)
(when (string= system-type "darwin")       
  (setq dired-use-ls-dired nil))

(global-set-key (kbd "C-.") 'other-window)
(global-set-key (kbd "C-,") 'prev-window)
(global-set-key [3 10] (quote dired-jump))
(global-set-key [24 126] (quote shrink-window))
(desktop-save-mode 1)
(setq-default indent-tabs-mode nil)
(setq tab-stop-list (number-sequence 2 120 2))
(setq tab-width 4)

(defun prev-window ()
  (interactive)
  (other-window -1))


;; The packages you want installed. You can also install these
;; manually with M-x package-install
;; Add in your own as you wish:
(defvar my-packages
  '(;; makes handling lisp expressions much, much easier
    ;; Cheatsheet: http://www.emacswiki.org/emacs/PareditCheatsheet
    paredit

    ;; key bindings and code colorization for Clojure
    ;; https://github.com/clojure-emacs/clojure-mode
    clojure-mode

    ;; extra syntax highlighting for clojure
    clojure-mode-extra-font-locking

    ;; integration with a Clojure REPL
    ;; https://github.com/clojure-emacs/cider
    cider

    ;; allow ido usage in as many contexts as possible. see
    ;; customizations/navigation.el line 23 for a description
    ;; of ido
    ido-ubiquitous

    ;; Enhances M-x to allow easier execution of commands. Provides
    ;; a filterable list of possible commands in the minibuffer
    ;; http://www.emacswiki.org/emacs/Smex
    smex

    ;; project navigation
    projectile

    ;; colorful parenthesis matching
    rainbow-delimiters

    ;; edit html tags like sexps
    tagedit

    ;; git integration
    magit))

;; On OS X, an Emacs instance started from the graphical user
;; interface will have a different environment than a shell in a
;; terminal window, because OS X does not run a shell during the
;; login. Obviously this will lead to unexpected results when
;; calling external utilities like make from Emacs.
;; This library works around this problem by copying important
;; environment variables from the user's shell.
;; https://github.com/purcell/exec-path-from-shell
(if (eq system-type 'darwin)
    (add-to-list 'my-packages 'exec-path-from-shell))

(dolist (p my-packages)
  (when (not (package-installed-p p))
    (package-install p)))


(add-to-list 'load-path "~/.emacs.d/vendor")
;; Place downloaded elisp files in ~/.emacs.d/vendor. You'll then be able
;; to load them.
;;
;; For example, if you download yaml-mode.el to ~/.emacs.d/vendor,
;; then you can add the following code to this file:
;;
(require 'yaml-mode)
 (add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
;; 
;; Adding this code will make Emacs enter yaml mode whenever you open
;; a .yml file

(add-to-list 'auto-mode-alist
 '("\\.\\(?:cap\\|gemspec\\|irbrc\\|gemrc\\|rake\\|rb\\|ru\\|thor\\)\\'" . ruby-mode))
(add-to-list 'auto-mode-alist
             '("\\(?:Brewfile\\|Capfile\\|Gemfile\\(?:\\.[a-zA-Z0-9._-]+\\)?\\|[rR]akefile\\)\\'" . ruby-mode))

(add-to-list 'auto-mode-alist
 '("\\.vue$" . vue-mode))


;;;;
;; Customization
;;;;

;; Add a directory to our load path so that when you `load` things
;; below, Emacs knows where to look for the corresponding file.
(add-to-list 'load-path "~/.emacs.d/customizations")

;; These customizations make it easier for you to navigate files,
;; switch buffers, and choose options from the minibuffer.
(load "navigation.el")

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(ansi-color-faces-vector
   [default default default italic underline success warning error])
 '(ansi-color-names-vector
   ["#242424" "#e5786d" "#95e454" "#cae682" "#8ac6f2" "#333366" "#ccaa8f" "#f6f3e8"])
 '(blink-cursor-blinks 0)
 '(coffee-tab-width 2)
 '(custom-enabled-themes (quote (misterioso)))
 '(global-auto-revert-mode t)
 '(inhibit-startup-buffer-menu t)
 '(initial-buffer-choice "~/code")
 '(package-selected-packages
   (quote
    (haml-mode slim-mode vue-mode ## alchemist tagedit smex rainbow-delimiters projectile paredit magit ido-ubiquitous exec-path-from-shell clojure-mode-extra-font-locking cider))))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(cursor ((t (:background "alternateSelectedControlColor")))))
;; ELPA setup

(require 'package)

(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/"))

(package-initialize)

;; Company setup
;; http://company-mode.github.io/

(require 'company)

(global-company-mode 1)

(setq company-idle-delay 0.1)
(setq company-tooltip-limit 10)
(setq company-minimum-prefix-length 2)
(setq company-tooltip-flip-when-above t)

;; Elixir setup

(require 'elixir-mode)
(require 'alchemist)

(setq alchemist-mix-command "/usr/local/bin/mix")
(setq alchemist-iex-program-name "/usr/local/bin/iex")
(setq alchemist-execute-command "/usr/local/bin/elixir")
(setq alchemist-compile-command "/usr/local/bin/elixirc")

;; Path to the elixir and erlang source directory
;; (setq alchemist-goto-elixir-source-dir "~/Projects/elixir/")
;; (setq alchemist-goto-erlang-source-dir "~/Projects/otp_src_17.4/")

(require 'vue-mode)

(defun get-default-height ()
  (/ (- (display-pixel-height) 120)
    (frame-char-height)))

(add-to-list 'default-frame-alist '(width . 200))
(add-to-list 'default-frame-alist (cons 'height (get-default-height)))

(require 'slim-mode)
(require 'haml-mode)

(add-to-list 'auto-mode-alist '("\\.haml\\'" . haml-mode))

And navigation.el (on ~/.emacs.d/customizations - you can place this anywhere as long as you rename the path on Customization section of the previous file):

;; These customizations make it easier for you to navigate files,
;; switch buffers, and choose options from the minibuffer.


;; "When several buffers visit identically-named files,
;; Emacs must give the buffers distinct names. The usual method
;; for making buffer names unique adds ‘<2>’, ‘<3>’, etc. to the end
;; of the buffer names (all but one of them).
;; The forward naming method includes part of the file's directory
;; name at the beginning of the buffer name
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Uniquify.html
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

;; Turn on recent file mode so that you can more easily switch to
;; recently edited files when you first start emacs
(setq recentf-save-file (concat user-emacs-directory ".recentf"))
(require 'recentf)
(recentf-mode 1)
(setq recentf-max-menu-items 40)


;; ido-mode allows you to more easily navigate choices. For example,
;; when you want to switch buffers, ido presents you with a list
;; of buffers in the the mini-buffer. As you start to type a buffer's
;; name, ido will narrow down the list of buffers to match the text
;; you've typed in
;; http://www.emacswiki.org/emacs/InteractivelyDoThings
(ido-mode t)

;; This allows partial matches, e.g. "tl" will match "Tyrion Lannister"
(setq ido-enable-flex-matching t)

;; Turn this behavior off because it's annoying
(setq ido-use-filename-at-point nil)

;; Don't try to match file across all "work" directories; only match files
;; in the current directory displayed in the minibuffer
(setq ido-auto-merge-work-directories-length -1)

;; Includes buffer names of recently open files, even if they're not
;; open now
(setq ido-use-virtual-buffers t)

;; This enables ido in all contexts where it could be useful, not just
;; for selecting buffer and file names
(ido-ubiquitous-mode 1)

;; Shows a list of buffers
(global-set-key (kbd "C-x C-b") 'ibuffer)


;; Enhances M-x to allow easier execution of commands. Provides
;; a filterable list of possible commands in the minibuffer
;; http://www.emacswiki.org/emacs/Smex
(setq smex-save-file (concat user-emacs-directory ".smex-items"))
(smex-initialize)
(global-set-key (kbd "M-x") 'smex)

;; projectile everywhere!
(projectile-global-mode)
1 Like

I should clarify, I mean I prefer the key combos of Vim more than Emacs. I wasn’t comparing Emacs to no keys at all (like atom or sublime). I think single mode editors are inferior in every single way, except the eye candy aspect (atom has a really nice looking file tree and GUI), but thats 1% of what I care about, so for me I will worship the Vim God until the day I die

PS you can add code folding in vim, im sure you can do that in emacs too.

1 Like

It’s interesting to me to read about VSCode being slow for some and fast for others. I run mine on a i5-6300U CPU / 16 GB ram / older SSD (thinkpad T460) and its very fast. Never noticed any lag with ElixirLS. My other machine is a i7-3770k OC / 32 GB ram / SSD and same result there. Both running LinuxMint.

Would be nice to see profile data from the runs where its slow, to try to improve it.

Then again if it was slow I would go back to neovim.

It looks good too - probably you can’t go wrong with either one of them - I picked emacs and I’m happy with that, stick with your god I’ll stick with mine ok?

You can’t go wrong with either. I don’t care what you use… just pointing out that your code folding feature is definitely not only in Atom

Thanks for re-stating it.

I uninstalled and re-installed VSCode. Now it runs fine. I don’t know what was the problem, but it now works fine with ElixirLS.