emacs/init/multi-emacs-config.el
2020-05-12 15:24:49 +08:00

197 lines
5.8 KiB
EmacsLisp

;;; multi-emacs-config.el --- A tool to use multiple emacs configurations -*- lexical-binding: t; -*-
;;
;; Author: Rongsong Shen<rshen@shenrs.eu>
;;
;;; Commentary:
;;
;; This package will enable us to use multiple EMACS startup
;; configuration(startkit in this package) and switch between
;; these configuration just by change a single environment
;; variable (EMACS_STARTKIT).
;;
;; Currently, we have test it with following:
;; - doom-emacs
;; - spacemacs
;; - frontmacs
;; - ohai-emacs
;; - graphene
;; - prelude
;; - radian emacs
;;
;;; Code:
(require 'cl-lib)
(require 'comint)
(defvar emacs-start-kit
(split-string
(let ((start-kit (getenv "EMACS_STARTKIT")))
(if start-kit
start-kit
"easy-emacs"))
":")
"The name of emacs startkit we will use")
(defvar startkit-name
(car emacs-start-kit)
"The name of Emacs startkit")
(defvar startkit-branch
(let ((branch (cadr emacs-start-kit)))
(if branch
branch
"master"))
"The branch of emacs startkit")
(defvar emacs-config-name
startkit-name
"The directory name of emacs startkit")
(defvar emacs-config-directory
(let ((config-dir (getenv "EMACS_CONFIG_DIR")))
(if config-dir
(format "%s/%s.%s"
config-dir
startkit-name
startkit-branch)
(format "%s/.config/emacs/%s.%s"
(getenv "HOME")
startkit-name
startkit-branch)))
"The based directory of emacs start configuration")
(defvar startkit-info nil
"Information to install emacs startkit")
(defvar emacs-base-directory
(format "%s/Emacs/%s.%s"
(getenv "HOME")
startkit-name
startkit-branch)
"The base directory which Emacs startkit will be put")
(defvar emacs-init-file
(concat emacs-base-directory "/"
"/init.el")
"The full path of emacs start file")
(unless (file-exists-p emacs-config-directory)
(make-directory emacs-config-directory t))
;; setup customization directory for emacs (custom.el)
(unless custom-file
(setq custom-file (expand-file-name "custom.el" emacs-config-directory)))
;; Setup default directory which package will be installed
(setq package-user-dir
(concat emacs-config-directory "/elpa"))
;; setup directory of spacemacs customization
(when (string= startkit-name "spacemacs")
(let ((spacemacs-dir (concat emacs-config-directory "/.local/etc")))
(progn
(setenv "SPACEMACSDIR" spacemacs-dir))))
(defun my-doom-dir (config-dir)
(concat config-dir "/doom"))
(defun my-doom-local-dir (config-dir)
(concat config-dir "/local"))
(defun gen-doom-install-script (branch install-dir config-dir)
(if (string= branch "master")
(list
(format
"git clone https://github.com/hlissner/doom-emacs.git %s"
install-dir)
(format "cd %s" install-dir)
(format "./bin/doom -y --doomdir %s --localdir %s install"
(my-doom-dir config-dir)
(my-doom-local-dir config-dir)))
(list
(format
"git clone -b %s https://github.com/hlissner/doom-emacs.git %s"
branch install-dir)
(format "cd %s" install-dir)
(format "./bin/doom -y --doomdir %s --localdir %s install"
(my-doom-dir config-dir)
(my-doom-local-dir config-dir)))))
(defun doom-load (install-dir config-dir)
(progn
(setenv "DOOMDIR" (my-doom-dir config-dir))
(setenv "DOOMLOCALDIR" (my-doom-local-dir config-dir))
(load-file emacs-init-file)))
(defun gen-easy-install-script (branch install-dir config-dir)
(if (string= branch "master")
(list
(format
"git clone git@shenrs.eu:rshen/easy-emacs.git %s"
install-dir))
(list
(format
"git clone -b %s git@shenrs.eu:rshen/easy-emacs.git %s"
branch install-dir))))
(defun easy-emacs-load (install-dir config-dir)
(progn
(setenv "EASYEMACSDATA" config-dir)
(setenv "EASYEMACSDIR" install-dir)
(load-file emacs-init-file)))
(setq startkit-info
'((doom-emacs . (gen-doom-install-script . doom-load))
(easy-emacs . (gen-easy-install-script . easy-emacs-load))))
(defun get-startkit-installer-gen-fn (name startkit-info)
(car (cdr (assoc name startkit-info))))
(defun get-startkit-loader (name startkit-info)
(cdr (cdr (assoc name startkit-info))))
(defun load-emacs ()
;; use emacs config directory as user-emacs-directory
(setq user-emacs-directory emacs-config-directory)
(funcall (get-startkit-loader (intern startkit-name)
startkit-info)
emacs-base-directory
emacs-config-directory))
(defun on-installer-finished (process event)
"Callback function when uinstaller process has finished.
We use this function to load startkit initialization file"
(cond
((string= event "finished\n") (load-emacs))
(t (message "Event %s has been ignored" event))))
(defun install-emacs-startkit (name branch location config-dir)
"Function to install EMACS startkit. NAME is the name of EMACS startkit.
LOCATION is the target directory which startkit will be installed."
(progn (let* ((shell-buffer (make-comint-in-buffer "installer" nil "/bin/sh"))
(shell-process (get-buffer-process shell-buffer)))
(progn
(set-process-sentinel shell-process 'on-installer-finished)
(display-buffer shell-buffer)
(cl-loop for cmd in
(funcall (get-startkit-installer-gen-fn (intern name)
startkit-info)
branch location config-dir)
do (comint-simple-send shell-process
(concat cmd "\n")))
(comint-simple-send shell-process
"exit\n")))))
(if (not (file-exists-p emacs-init-file))
(progn
(install-emacs-startkit startkit-name
startkit-branch
emacs-base-directory
emacs-config-directory))
(load-emacs))
(provide 'multi-emacs-config)
;;; multi-emacs-config.el ends here