Updated March 18, 2021


Loading Emacs

Emacs users write custom code for their software. Each 'configuration' can be highly individualized. Because some custom configurations take longer to load than others, Emacs users like to minimize and measure their 'load' time.

The software loads like any other software, loading libraries included in the core, and then additional libraries according to various configuration files. With Emacs, these files are stored in various locations based on the settings specified by the user, and the system Emacs is installed on.

There is an 'XDG_CONFIG_HOME' location, for Linux (and possibly also Mac, though I haven't looked into that), and the traditional locations in what is called the 'home' directory, or the .emacs.d directory.

On Windows, I will usually build a configuration in a directory directly off the c drive, "C:/emacs-27.1", and this will become the 'home' directory. On linux, software installations frequently clutter the system's home directory (with hidden . files), and a lot of user specific configuration files are stored in the '.config/' directory, off of the 'home' directory. This is commonly called the 'dotfiles' directory.

Emacs will look for three files, 'early-init.el' and '.emacs' or 'init.el' in various directories according to this specification:

Emacs can now use the XDG convention for init files. The 'XDG_CONFIG_HOME' environment variable (which defaults to '~/.config') specifies the XDG configuration parent directory. Emacs checks for "init.el" and other configuration files inside the "emacs" subdirectory of 'XDG_CONFIG_HOME', i.e. '$XDG_CONFIG_HOME/emacs/init.el'

However, Emacs will still initially look for init files in their traditional locations if "~/.emacs.d" or "~/.emacs" exist, even if '$XDG_CONFIG_HOME/emacs' also exists. This means that you must delete or rename any existing '~/.emacs.d' and '~/.emacs' to enable use of the XDG directory.

If '~/.emacs.d' does not exist, and Emacs has decided to use it (i.e. '$XDG_CONFIG_HOME/emacs' does not exist), Emacs will create it. Emacs will never create '$XDG_CONFIG_HOME/emacs'.

Whichever directory Emacs decides to use, it will set 'user-emacs-directory' to point to it.

~masteringemacs.org

'.el' files are elisp, emacs programming language files. They are compiled into '.elc' files, which if speficied in the initilization code load first always if present. 'early-init.el' is a file that loads before '.emacs' or 'init.el,' which are two ways of specifying the same initialization file, that is, the main configuration file where users put their specialized code.

I don't bother much with the 'early-init.el,' however, the following code is recommended.


early-init.el


1
2
3
4
5
6
7

;according to package.el, you can only set the variable package-enable-at-startup in early-init.el
; package-enable-at-startup needs package.el to work, so (unless already included check) load that here:
(require 'package)
; you don't want to install all the packages in your archive, as you use use-package to do that
(setq-default package-enable-at-startup nil)


The next few sections are init.el, loaded from the same directory as early-init.el (in my case 'c:\emacs-27.1\.emacs.d\emax')


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

;start init.el


;comment on off to debug init
(setq debug-on-error t)

;if check-wsl it's wsl only
(setq check-wsl (and (string-match-p "microsoft-standard" (shell-command-to-string "uname -a")) (string-match-p "GNU/Linux" (shell-command-to-string "uname -a"))))
;if check-linux it's only linux
(setq check-linux (and (not (string-match-p "microsoft-standard" (shell-command-to-string "uname -a"))) (string-match-p "GNU/Linux" (shell-command-to-string "uname -a"))))

;set windows variables
(if (string-equal system-type "windows-nt")
(progn
(setenv "Home" "c:/emacs-27.1")
(setq package-user-dir "~/elpa/")
(setq user-emacs-directory "~/.emacs.d/")
(setq init-el (concat user-emacs-directory "emax/wemax.el") )
(setq init-org (concat user-emacs-directory "emax/wemax.org") )
(setq dot-files (concat user-emacs-directory "emax"))
;path
(setq emax-root (concat (expand-file-name "~") "/"))
(setq emax-bin (concat emax-root "bin"))
;(setq exec-path (cons emax-bin exec-path))
(setenv  "PATH" (concat
                 ;; "c:/Windows/System32" ";"
                  emax-bin ";"
                 ;; Unix tools
                 "C:\\Program Files\\Git\\usr\\bin" ";"
                 (getenv "PATH")

));end "PATH"
;load-path
(dolist (dir '("~/.config/emacs/" "~/bin/"  "~/share/emacs/27.1/lisp/" "~/elpa/"))
(add-to-list 'load-path dir))
));end if windows

; set wsl variables
(if check-wsl
(progn
(setenv "Home" "/home/poseidon-3")
(setq package-user-dir "~/.emacs.d/elpa/")
(setq user-emacs-directory "c:/emacs-27.1/emacs-27.1/")
(setq init-el (concat user-emacs-directory "wslemax.el"))
(setq init-org (concat user-emacs-directory "wslemax.org") )
(setq dot-files (concat user-emacs-directory "wslemax"))
));end wsl home variables

; set linux variables
(if check-linux
(progn
(setenv "Home" "/home/zuebu")
(setq package-user-dir "~/.emacs.d/elpa/")
(setq user-emacs-directory "~/.config/emacs/")
(setq init-el (concat user-emacs-directory "lemax.el") )
(setq init-org (concat user-emacs-directory "lemax.org") )
(setq dot-files (concat user-emacs-directory "lemax"))
));end linux home variables



An Emacs package called "Org-Mode," provides a lot of functionality. One thing you can do with it is specify sections of an "org" file (file.org), with code delimiters, and later 'tangle' them into other files, with specified file extensions. Incidentally, you can also run the code in those sections and pass the results in a variety of ways.

Org-mode provides a utility called "org-babel" that is commonly used to extend and organize an "init.el" file. In init.el above, for example, I extend the init.el file to files named wemax.el, wslmax.el, or lemax.el, depending on their existence and the system I am using. If they do not exist (or if I specify it), the org files with my customized configuration code, wemax.org, lemax.org, or wslemax.org are 'tangled' into the system appropriate .el files.

I therefore work on my configuration code in an org file, which provides all the advantages of using an org file, and configure that file to 'tangle' into the .el files when I exit emacs. This is a standard feature of 'literate programming', a fancy name I suppose for using the org-babel package to manage your emacs configuration (or other coding tasks.)

The code above sets a package directory, the user-emacs-directory (.emacs.d), variables for the init files, and in the windows case some load-paths (I'm working mostly on my windows system right now, so I've yet to bring my linux and wsl configs up to full speed).


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

; great, adds all package libraries to emacs load path on windows
(let ((default-directory  package-user-dir))
(normal-top-level-add-subdirs-to-load-path))


;Re-define package--save-selected-packages to stop customization sending dependeny info to melpa process.
(defun package--save-selected-packages (&rest opt) nil)

;wemax.el will load before wemax.elc, so ensure directory is compiled on emacs exit
(setq load-prefer-newer t)

;; Set repositories
;changed https to http, until compile emacs with gnutls
(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t))

(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa2" . "http://www.mirrorservice.org/sites/melpa.org/packages/") t))

(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa3" . "http://www.mirrorservice.org/sites/stable.melpa.org/packages/") t))

(unless (assoc-default "orgmode" package-archives)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t))

;(unless (assoc-default "marmalade" package-archives)
;(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/") t))
(unless (assoc-default "gnu" package-archives)
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t))

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


;Loads libraries needed by packages you byte-compile, when you byte-compile them
; for example when you use package.el's list-packages to install, or when you byte-compile your dot-files
(eval-when-compile (package-initialize))


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


;note 'package archives' only exist if you (require 'package) library before this code
;note this does not (require 'package), it only installs it
(defun require-package (package)
  "refresh package archives, check package presence and install if it's not installed"
  (if (null (require package nil t))
      (progn (let* ((ARCHIVES (if (null package-archive-contents)
                                  (progn (package-refresh-contents)
                                         package-archive-contents)
                                package-archive-contents))
                    (AVAIL (assoc package ARCHIVES)))
               (if AVAIL
                   (package-install package)))
             (require package))))

;use above to require use-package
(require-package 'use-package)
(require 'use-package)

;; Use no-littering to automatically set common paths to the new user-emacs-directory
;(use-package no-littering)


(setq-default use-package-verbose t)
; when t use-pacakge-expand-minimally will make the byte-compiled file as minimal as possible.
(setq use-package-expand-minimally nil)


This guy above loads the use-package package when it's not on the system. 'Use-package' provides many utilities for easily loading and configuring various Emacs packages (add-on software).

To use this code intelligently, you will need to research every line. If that doesn't make sense for you - and it shouldn't unless computer science is something you are into or want to get into - find a consultant or friend to explain how it all works, and set you up with a working system. Someone, for example, like me. 😊


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

;add linux path to emacs load-path (linux package, do individually for windows executables )
(if (or check-linux check-wsl)
(use-package exec-path-from-shell
:ensure t
:init
(exec-path-from-shell-initialize)
);end exec-path-from-shell
);end check linux

(use-package auto-compile
:ensure t
:init
;(add-to-list 'load-path (concat package-user-dir "auto-compile"))
:config

(setq auto-compile-display-buffer nil)
(setq auto-compile-mode-line-counter t)

;byte-compiles any lisp file loaded (so byte compile your lisp files when you load them)
;until you can compile directories on emacs exit, leave this on a whenever you add new packages or update packages
;(auto-compile-on-load-mode)

;byte-compiles any lisp file changed and saved
(auto-compile-on-save-mode)
);end auto-compile

;show only abbreviated names on modeline
(use-package diminish)
;:config
;(require 'diminish))

; for use with use package (and outside of it)
(use-package bind-key
;:init
;(add-to-list 'load-path (concat package-user-dir "/bind-key-20210210.1609"))
;:config
;(require 'bind-key)
)



A 'load-path' tells your software where to look for programs and libraries. On Windows, when you add software you can add it to your load-path using environment variables. If you use Chocolatey package manager it is added automatically and your load-path line limit is extended. Now you can access programs from the command line, without changing shell location to the program's root directory. To add this load path to Emacs, you need some specialized code (included on this page).

On Linux to add the load-path to Emacs you can use the package, Exec-path-to-shell, specified above.

Also above are 'diminish,' which compresses package names for your information bar (called the modeline), and 'bind-key,' which provides some improved syntax and functionality for configuring short-cuts, which are a central part of Emacs (the name 'Emacs' is actually short I think for "Elisp Macros", which are essentially short-cuts).

I use the garbage collection hack


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

;garbage collection off during initialization (focus all memory on initialize)
(setq gc-cons-threshold (* 50 1000 1000)
      gc-cons-percentage 0.6)

;reset garbage collection after initialization (return deprecated memory to stack when idle)
(add-hook 'emacs-startup-hook
  (lambda ()
    (setq gc-cons-threshold  (* 2 1000 1000)
          gc-cons-percentage 0.1)))

(use-package gcmh
:init
(gcmh-mode 1)
);


(require 'server)
(setq server-auth-dir (concat user-emacs-directory "server/"))

;didn't bother yet with .emacs.d/server/ permissions
(if (string-equal system-type "windows-nt")
(setq server-auth-dir "c:/emacs-27.1/.config/emacs/server/")
)



The garbage collection hack can speed up your operations. Read up on it. Server auth is redefined later for lemax, and wslmax, still have to reorganize those two files (but not wemax.org, which is right now an awesome file 😏 )


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

;if init-el exists load it, otherwise tangle  init.org (wemax.org, lemax.org, or wslmax.org)

(if (file-exists-p init-el)
(load-file init-el); or if not
;(message "You're testing another file Michael?");sorry: HAL from that old movie, 2001 Space Odyssey was helping check my code

(progn					;
;; Use latest Org
(use-package org :demand t)
(org-babel-load-file init-org)
);end progn
);end if

;;; init.el ends here


Note: that last chunk of code above loads the variable init-el, which is the compiled wemax.el, lemax.el, or wslemax.el, depending on the system, if it exists. If it doesn't exist, it tangles your wemax.org, lemax.org, or wslemax.org

I also want to include in this post the byte-compiling functions, as well as the exit function, which are key for reducing load-time to 3 seconds.

Note: Of course this can be confusing if you don't know what you are looking for. If that is the case, you can ask me for more explanation. Otherwise, make a plan for exactly what you want to get out of Emacs, then, if you want to go big, start with System Crafters on youtube.

Remember, learning and using Emacs, which after all is said and done can improve your technical and knowledge working capacity multiple times over, can be a simple and smooth process, taking only a few easy years, or a stressful and confusing nightmare taking up to a decade. Think about what you want to get out of it, and consult someone who knows what they are doing.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

;(setq byte-compile-warnings -1)

;byte compile
(defun byte-compile-user-init-file ()
(interactive)
(let
((byte-compile-warnings '(unresolved)))
;; in case compilation fails, don't leave the old .elc around:
(when (file-exists-p (concat (expand-file-name init-el) "c"))
(delete-file (concat (expand-file-name init-el) "c")))
(byte-compile-file (expand-file-name init-el))
);end let
);end byte-compile-user-init-file


; fix this to tangle to the file you want tangled for each system, then add to exit functions
(defun tangle-init ()
"If the current buffer is 'init.org' the code-blocks are
tangled, and the tangled file is compiled."
(interactive)
(when (equal buffer-file-name (expand-file-name init-org))
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle)
(byte-compile-user-init-file)))
);end tangle init

;byte recompile package-user-dir (packages)
(defun byte-compile-elpa ()
(byte-recompile-directory package-user-dir 0)
);end byte compile elpa
; rebyte compile dot-files
(defun byte-compile-dot-files ()
(byte-recompile-directory dot-files 0)
);end byte compile dot-files

;btye compiling directories
(defun recompile-a-directory (astring)
"Select directory from clipboard and recompile. If no y or no answer no recompile.
Recompile only byte-compiles .el files newer than or without .elc files of same name"
(interactive "sEnter a Directory: ")
(if (y-or-n-p-with-timeout ( concat "Are you sure you want to byte compile" " " astring "?") 5 nil )
(byte-recompile-directory astring 0)))


Byte compiling code enables your computer to load it much more quickly. Above are some byte compiling functions I use. I usually tangle my entire configuration whenever I change it, and byte-compile the directory it's in occasionally.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

;kill emacs clients and daemon
(defun exit-poseidon ()
(interactive)
(progn
(if (featurep 'command-log-mode)
(progn
;(clm/save-command-log)
(command-log-mode -1)
(global-command-log-mode -1)
));end command-log-mode exit
(if (featurep 'mingus)
(stop-mpd));end if mingus
(tangle-init)
(save-buffers-kill-emacs));end prog
:bind
; the mnemonic is C-x really quit
("C-x r q" . exit-poseidon)
);end exit poseidon-instances

;exit and save command-logs,only works if command-log-mode feature is loaded at the same time global-command-log-mode is started
;kill emacs client or if no client daemon
(defun exit-poseidon-instance ()
(interactive)
(progn
(if (featurep 'command-log-mode)
(progn
;(clm/save-command-log)
(command-log-mode -1)
(global-command-log-mode -1)
));end command-log-mode-exit
(if (featurep 'mingus)
(stop-mpd));end if mingus
(save-buffers-kill-terminal));end progn
);end exit poseidon

;confirm kill emacs
(setq confirm-kill-emacs 'yes-or-no-p)


These functions above are used to exit Emacs. They run some code at exit time. You can ignore the command-log-mode stuff, it's only relevant if you're writing your command log to a file.

Also, the Mingus code is of course only if you have Mingus set up as I do.

In the case where you are using a daemon and a client, you can exit with the instance. Lately I'm loading calendar and news buffers on load, so I'm no longer using the emacs daemon as much.

Below is the original text for this post, which is around a year before this updated text was added. Feel free to browse that also.


Original Post


Below are some notes covering among other things why I got into Emacs, where I got my version, and how my configuration is organized. As mentioned before, other text editors in use today, like Atom, IntelliJ Idea, or Sublime Text are awesome, and offer also great selections of unique packages. Atom, for example, has some super useful snippet packages. You can convert them into Yasnippet format (an Emacs snippet package), but it's a hassle. So there are a lot of reasons not to use Emacs.

Having said that, and despite the fact Emacs is written in the widely used Elisp language, I use it and promote it. Here's why. Emacs has an incredibly clean feel. Properly configured, it's simple, unencumbered text with all the function of an IDE and more. Plus, it's old sKool, with a capital K.

Why

I first got into Emacs in 2013. After five or six years of part-time college in sciences and arts, and many years in industry in a variety of positions, including business owner, I went back to university in 2009 to finish my bachelors degree. Having finished Adam Smith's "The Wealth of Nations," but stumbled on Keynes' "The General Theory of Employment, Interest And Money" I majored in economics. As much as the theory at what is now The Vancouver School of Economics was excellent, on the data and programming side our courses disappointingly veered away from computer science. While at one point we were introduced to the R GUI, in general we were taught Stata, and I did most of my work with Excel, Word, or Open Office.

After graduation, I wound up working with General Equilibrium Modelling Software (GAMS), one of the frameworks used to solve equilibrium models. My supervisor introduced me to Emacs and Emacs Speaks Statistics (ESS), the Emacs alternative to the R GUI or Rstudio, as well as the Emacs GAMS package, now available on Melpa.

A large part of my job was to clean and sort data using Excel and Microsoft Access, but it was easier to find and fix missing observations in R, using ESS. I ended up exploring the Emacs initialization file looking for ways to improve data cleaning efficiency. That's often how the Emacs experience starts - passed on through academic circles.

Quickly I ran into time constraints and came with up Vincent Goulet's pre-configured Emacs installation as a way to save time. It comes at least for now compiled for Windows with a Latex engine and an included R configuration. Still, if you want Image Magick or PDF Tools support, you'll want something else. I'll get to that.

The evolution of every Emacs configuration is too long of a story. It's a trial and error process. Emacs at its best is like an operating system in an operating system. You're building a car (well, a workshop) from second hand parts. You've got to find them, fit them, run them, fix them, and make new ones when you need them. Everything is built in a variation of lisp called elisp, and while lisp is a cool language with a cool history, it's basically useless for anything other than programming theory or specialized bottom-up stuff like Emacs.

You can get from a blank initialization to a fully operational emacs installation without taking a single lisp course, but if I were to start again, I'd take a week or two and do a crash course in lisp. Now I'm not an expert programmer. I've so far covered too many subjects for that. If I were a genius, which I'm not, I'd be a polymath. But, after eight years of programming, I know a good resource when I see it. The late Robert J. Chassel's "An Introduction To Programming In Emacs Lisp" is one such resource. A week in there will get any beginning Emacs enthusiast well ahead of the game.

Another one, for the advanced and ambitious lisp enthusiast, was written by the quite famous programmer, writer, and investor Paul Graham, founder of Ycombinator one the incubators behind such startups as "Dropbox," "Airbnb," "Zapier," "Gitlab," and "Docker." You can buy Paul's book "On Lisp, Advanced Techniques for Common Lisp" from Amazon for $154 USD, or you can download essentially the same thing for free from his website here. Either way, a week in there will get you a great introduction to some foundational programming language theory through lisp.

Emacs configurations get hefty and drag on load time. There are ways around this. You can, for example, run Emacs as a server, in which case the process is always on and doesn't need to load when you start, or you can optimize the load time. Another way around is to use a Linux distro. A lot of Emacs packages are written for Unix and spawn a lot of processes, which slows things down on the Windows NTFS backed file system. If you're just starting out, Linux is anyway a headache well worth your time. But, if you're like me, a long time Windows user, and you want to get the most out of Emacs, you'll need a few resources.

Windows Subsystem Linux, with VirtualBox or X Server is one way to run an Emacs configuration that does more than a Pico or Nano on your windows machine. I use Ubuntu on WSl, but I haven't gotten around to running graphics programs on it. I'm still using Emacs on the Windows system. Other than the start-up time, usually a one-time cost, it's not slow enough for me to notice. Even with a reasonable amount of RAM however any work on data with more than a million records would be more efficiently done on the Linux system.

There are a few other things you'll want to do to speed up Emacs on Windows. One is to defer load times in your initialization with :commands, :defer, :bind, :mode, or :interpreter, from Emacs Use-Package, another does the same with conditional calls to code chunks in your configuration, using something like (eval-after-load 'example-mode '(require 'setup-example-mode)).

Also, if you're using Org-babel in your initialization to separate the code you want to send to the interpreter or compiler from text you want to write or send to the web, you'll want to remember the more separate chunks you tangle the slower the load time. Ideally you would have two versions of your init file, one with lots of organized code chunks for folding and editing easily, and another with one code chunk to optimize load time.

Finally, if you're running Emacs on a windows system, you'll want to run a version that is compiled for windows. This will give you access to useful linux libraries. Today, I'm using a window's compiled version I found on the web last year that supports PDF Tools and Image Magick. Way Cool. The next section is from the notes I took about the Emacs version I found. I don't know the guy who compiled it. I just use his distro.

Windows Emacs Installation

  • a better emacs exe is compiled with imagemagick support, pdftools support, and other libraries sourced from Mingw64. "XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS MODULES THREADS LCMS2"

  • Here are the links to his version and patches:

https://github.com/m-parashar/emax64/releases

https://ntemacs.sourceforge.io/

https://github.com/m-parashar/emax64

https://github.com/m-parashar/emax64/releases

  • I prefer to install to c://, as that is what I'm used to.

Description

  • 64-bit Windows build of Emacs 26.2 final release.

  • Patched with ImageMagick 7 support. Binaries and libs included.

  • PDF-TOOLS (epdfinfo.exe) included. [emax.7z package]

  • Features[1]: "XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS MODULES THREADS LCMS2"

  • Optimized clean build. Options[2]: "--without-compress-install --without-dbus --with-modules 'CFLAGS= -O2 -g3'"

  • Built and tested on a clean Windows 10 system.

  • addpm modified to not create/update any registry HOME entries. It only creates shortcuts as it should.

[1] C-h v system-configuration-features
[2] C-h v system-configuration-options

Installation:

  • Unpack the 7z binary archive, preferably in C:\ root directory.

  • Double-click the addpm.exe file in emax64\bin to create/update shortcuts.

Recommended:

-

installation instructions for msys2, which provides a bash shell and other linux tools for windows, and is a windows programming tool http://www.msys2.org/

-

Install MSYS2 [64-bit: http://repo.msys2.org/distrib/msys2-x86_64-latest.exe]

-

Download and unpack emax.7z into your HOME directory, usually C:\Users\\AppData\Roaming

-

emax.7z is an environment to make your Emacs experience a little more tolerable on Windows.

-

It includes a barebones dotfile along with BusyBox 64-bit, some MinGW packages, SSH, W3M, Aspell, and other GNU tools to help you start right away.

Sources:

  • GNU Emacs sources, patched as described above, are available as a separate src archive.

  • All the other binaries included in the emax64 and emax archives are unmodified and distributed as is.

  • Their sources can be downloaded from MSYS2/MinGW servers: http://repo.msys2.org/mingw/sources/

  • BusyBox (Windows) sources can be obtained from here: https://frippery.org/files/busybox/

What

An Emacs initialization file calls and configures packages (libraries). Like any other program resources need to be loaded into namespaces in order, so they can be found when called on. One of the more popular Emacs packages is called Org-Mode. "Org" is for "organization," but when I hear the name I think of "Origami," because org-mode has cool section folding.

One of the libraries affiliated with Org-mode is called Org-babel. It enables labelled section chunks to be sent to the interpreter or compiler. With Org-babel you can put your entire initialization file into one .org file. You can then fold it to navigate it, interpret it, or compile it for faster loading.

The following elisp sets up my initialization file, which is called on line ~129 with org-babel-load-file. This goes in the .emacs file in your root emacs directory. I'll add to the comments before the code to explain them. I'm a fan of both GPL and BSD, but it's hard to argue with the merits of the free license Manish Parashar has used in his configuration here. Pardon any overkill, I was in a hurry so I just threw Parashar's .emacs together with mine. They were essentially the same, with some minor syntax changes.

.emacs


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

;; This program is free software. You can redistribute it and/or modify it under
;; the terms of the DWTFYWT Public License, version 2 as
;; published by Sam Hocevar.
;; This program is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;; FOR A PARTICULAR PURPOSE.
;; You should have received a copy of the DWTFYWT Public
;; License along with this program. If not, see http://www.wtfpl.net/.

;comment on off to debug init (you'll need this or the restart with debugger to find missing brackets in your init file.)
;(setq debug-on-error t)

;; Set repositories
(require 'package)
(setq-default package-enable-at-startup nil)

(setq load-prefer-newer t)

;; these are the archives emacs will use to find packages. There's overkill here.
(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t))

(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa2" . "http://www.mirrorservice.org/sites/melpa.org/packages/") t))

(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa3" . "http://www.mirrorservice.org/sites/stable.melpa.org/packages/") t))

(unless (assoc-default "orgmode" package-archives)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t))

(unless (assoc-default "marmalade" package-archives)
(add-to-list 'package-archives '("marmalade" . "https://marmalade-repo.org/packages/") t))
(unless (assoc-default "gnu" package-archives)
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/") t))

(unless (assoc-default "melpa-stable" package-archives)
(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/") t))

(setq package-user-dir "~/emax/elpa")

;I don't think you need this. Apparently will not for sure when version 27 is out.
(package-initialize)
; some better initialization code here: https://github.com/jwiegley/use-package/issues/219

;; Install dependencies
(unless (and (package-installed-p 'delight)
               (package-installed-p 'use-package))
(package-refresh-contents)
(package-install 'delight t)
(package-install 'use-package t))
(setq-default
; use-package-always-defer t
 use-package-always-ensure t
 use-package-verbose t)
;(use-package auto-compile)

;; Default value for :pin in each use-package.
;(setq use-package-always-pin "melpa-stable")

(add-to-list 'load-path "c:/emacs/emax/elpa/auto-compile")
(require 'packed)
(require 'auto-compile)
(auto-compile-on-load-mode)
(auto-compile-on-save-mode)

(eval-when-compile
  (setq use-package-expand-minimally byte-compile-current-file))

; to use the package you just ensured was installed, use-package, you require here
(eval-when-compile
(require 'use-package))
;use-package is worth the read, see link in this post.
(use-package diminish
:config
(require 'diminish))

(use-package bind-key
:config
(require 'bind-key))

; you need this to use org-babel
;; Use latest Org
(use-package org
;:pin org
:ensure org-plus-contrib
:demand t)

; defvar, define some path variables so emacs can find libraries when it loads
; I load paths into variables, so I can change them easily in one place if I change computers.
(defvar emax-root (concat (expand-file-name "~") "/emax"))
(defvar emax-bin (concat emax-root "/bin"))
(defvar emax-bin64 (concat emax-root "/bin64"))
(defvar emax-mingw64 (concat emax-root "/mingw64/bin"))
(defvar emax-lisp (concat emax-root "/lisp"))

; add the variables to paths
(setq exec-path (cons emax-bin exec-path))
(setenv "PATH" (concat emax-bin ";" (getenv "PATH")))

(setq exec-path (cons emax-bin64 exec-path))
(setenv "PATH" (concat emax-bin64 ";" (getenv "PATH")))

(setq exec-path (cons emax-mingw64 exec-path))
(setenv "PATH" (concat emax-mingw64 ";" (getenv "PATH")))

(setenv "PATH" (concat "C:\\msys64\\usr\\bin;C:\\msys64\\mingw64\\bin;" (getenv "PATH")))

; except for here, when I do not load paths into variables
(dolist (dir '("~/emax/" "~/emax/bin/" "~/emax/bin64/" "~/emax/mingw64/bin/" "~/emax/lisp/" "~/emax/elpa/"))
(add-to-list 'load-path dir))

(add-to-list 'load-path "c:/emacs/lisp/")
;;the pre-installed packages
(add-to-list 'load-path "c:/emacs/site-lisp/")

(add-to-list 'load-path "c:/emacs/share/26.2/lisp")

; overkill this as much as possible, never works anyway
(set-language-environment 'utf-8)
(setq locale-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

;; Tangle configuration. It's important to use one of these lines. That org file is your inititialization.
;(org-babel-load-file (expand-file-name "~/emax/emax.org"))
(org-babel-load-file "c:/emacs/emax/emax.org")

For you memory guys.
;;(garbage-collect))

;;; init.el ends here

; I don't remember how this got here. I think emacs adds it now. package-selected-packages is a list of installed packages,
; that's either useful or problematic when you call list-packages.
(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.
 '(package-selected-packages
   (quote
   (magit yasnippet-snippets yaml-mode writegood-mode wordnut
which-key-posframe web-mode w3m volatile-highlights
visual-fill-column use-package-hydra tagedit synosaurus
switch-window sublime-themes start-menu spacemacs-theme
solarized-theme snazzy-theme smooth-scrolling smex smartparens
smart-comment slime restart-emacs request rainbow-mode
rainbow-identifiers rainbow-delimiters pretty-hydra powershell
php-extras peep-dired paredit pandoc-mode org-super-agenda
org-ref org-plus-contrib org-pdfview org-bullets
org-beautify-theme olivetti neotree mwim minions mingus
markdown-toc markdown-preview-mode js2-mode jeison intellij-theme
image+ ido-vertical-mode ido-ubiquitous ido-at-point
hungry-delete highlight-parentheses highlight-numbers
highlight-indent-guides helm-projectile helm-mode-manager
helm-ispell helm-helm-commands helm-fuzzier helm-flyspell
helm-emmet helm-css-scss helm-company helm-chrome helm-ag
helm-addressbook frame-cmds flyspell-popup flymd flx-isearch
flx-ido fill-column-indicator engine-mode elnode easy-kill
doom-themes doom-modeline diminish desktop+ delight dashboard
cycle-themes company-web company-try-hard company-tern
company-quickhelp company-php company-fuzzy command-log-mode
color-theme-modern change-inner challenger-deep-theme
browse-kill-ring beacon avy auto-yasnippet anzu
all-the-icons-dired ag academic-phrases ac-php
ac-html-bootstrap))))
(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.
 );



The code above is the opening to the init file. Mine is a big one. The rest of it is stored in my case here: "c:/emacs/emax/emax.org" (whereas the section above is stored here: "C:/emacs/.emacs"). "emax.org" is folded origami style. In later posts, I want to go through quickly each of the sections. So next I'm going to introduce you to the folded headings. When the document is open in Emacs, you hit 'tab' with the cursor ('point') over the section heading and it will toggle the contents to drop down.

MY INITIALIZATION FILE

  • SET UP, DEFAULTS, AND CUSTOMIZATION
  • APPEARANCE
  • Default Operations
  • Selection region and Mark
  • Browsers
  • Finding Files
  • ediff improvements
  • Finding Differences in Files With Diff
  • elnode
  • Editing
  • THE HELM HYDRA
  • Web Developer Hydra
  • Autocomplete
  • Emmet
  • Yasnippet
  • Auto-yasnippet
  • Program Launcher
  • WEB MODE
  • PHP Mode
  • CSS Mode
  • Easy Hugo
  • Configure your code (test)
  • Pretty insane company configuration
  • Javascript Mode
  • Javascript syntax highlighting
  • Json syntax highlighting
  • Hydra for editing javascript
  • Pandoc-Mode
  • Comment/uncomment block
  • Shell
  • Text mode
  • Org
  • Git Magit Hydra
  • Printing
  • Flymake
  • Auctek, Miktex, Latex
  • CSV Mode
  • MYSQL (SQL MODE)
  • ESS Mode
  • Gams
  • HTMLize
  • Markdown
  • Mingus
  • Rectangles
  • Yaml Mode
  • Git

While most of the above is operational, there are a lot of areas I've set up but haven't gotten around to testing. Basically, whenever I do any work I keep notes explaining how I did it. In most cases, I've taken those notes and turned out some Elisp to automate the process, but in quite a few cases I haven't gotten around to it and haven't had to use it again. But, it's 80% done, and when I get the time I'll finish it off, optimized it, and publish it to the net. Below is an image of the same, for good measure.


emacs initialization


That’s all for now…

comments powered by Disqus