From db1f5392bca1d72a0e9f64248105e3ea0740594a Mon Sep 17 00:00:00 2001 From: Sebastian Miele Date: Tue, 20 Oct 2020 21:11:32 +0200 Subject: [PATCH] Restructure and fix some bugs Restructure so that many things that previously got done at least twice, now get done only once. Fix #6, #7, #8, #10, #11. --- chemacs.el | 169 +++++++++++++++++++++++--------------------------- early-init.el | 13 ++-- init.el | 14 +++-- 3 files changed, 91 insertions(+), 105 deletions(-) diff --git a/chemacs.el b/chemacs.el index 312b689..d381613 100644 --- a/chemacs.el +++ b/chemacs.el @@ -20,32 +20,19 @@ ;; ;; See README.md for instructions. -;; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -;; this must be here to keep the package system happy, normally you do -;; `package-initialize' for real in your own init.el -;; (package-initialize) - ;;; Code: (defvar chemacs-version "2.0") (defvar config-home (or (getenv "XDG_CONFIG_HOME") "~/.config")) (defvar chemacs-profiles-paths (list "~/.emacs-profiles.el" (format "%s/%s" config-home "chemacs/profiles.el" ))) -(defvar chemacs-default-profile-paths (list "~/.emacs-profile" (format "%s/%s" config-home "profile"))) +(defvar chemacs-default-profile-paths (list "~/.emacs-profile" (format "%s/%s" config-home "chemacs/profile"))) (defvar chemacs-profiles-path (or (car (seq-filter 'file-exists-p chemacs-profiles-paths)) (car chemacs-profiles-paths))) -(defvar chemacs-default-profile-path (or (car (seq-filter 'file-exists-p chemacs-profiles-paths)) (car chemacs-profiles-paths))) +(defvar chemacs-default-profile-path (or (car (seq-filter 'file-exists-p chemacs-default-profile-paths)) (car chemacs-default-profile-paths))) (when (not (file-exists-p chemacs-profiles-path)) (error "[chemacs] %s does not exist." chemacs-profiles-path)) -(defvar chemacs-emacs-profiles - (with-temp-buffer - (insert-file-contents chemacs-profiles-path) - (goto-char (point-min)) - (read (current-buffer)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun chemacs-detect-default-profile () +(defvar chemacs-default-profile-name (if (file-exists-p chemacs-default-profile-path) (with-temp-buffer (insert-file-contents chemacs-default-profile-path) @@ -54,6 +41,80 @@ (symbol-name (read (current-buffer)) )) "default")) +(defun chemacs-handle-command-line (args) + (when args + ;; Handle either --with-profile profilename or + ;; --with-profile=profilename + (let ((s (split-string (car args) "="))) + (cond ((equal (car args) "--with-profile") + ;; This is just a no-op so Emacs knows --with-profile + ;; is a valid option. If we wait for + ;; command-switch-alist to be processed then + ;; after-init-hook has already run. + (add-to-list 'command-switch-alist + '("--with-profile" . + (lambda (_) (pop command-line-args-left)))) + (cadr args)) + + ;; Similar handling for `--with-profile=profilename' + ((equal (car s) "--with-profile") + (add-to-list 'command-switch-alist `(,(car args) . (lambda (_)))) + (mapconcat 'identity (cdr s) "=")) + + (t (chemacs-handle-command-line (cdr args))))))) + +(defvar chemacs-profile-name + (let ((name (chemacs-handle-command-line command-line-args))) + (if name name chemacs-default-profile-name))) + +(defvar chemacs-profile + (let ((profiles + (with-temp-buffer + (insert-file-contents chemacs-profiles-path) + (goto-char (point-min)) + (read (current-buffer))))) + (cdr (assoc chemacs-profile-name profiles)))) + +(unless chemacs-profile + (error "No profile `%s' in %s" profile chemacs-profiles-path)) + +(defun chemacs-profile-get (key &optional default) + (alist-get key chemacs-profile default)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(setq user-emacs-directory (file-name-as-directory + (chemacs-profile-get 'user-emacs-directory))) + +;; Allow multiple profiles to each run their server +;; use `emacsclient -s profile_name' to connect +(let ((name (chemacs-profile-get 'server-name))) + (when name (setq server-name name))) + +;; Set environment variables, these are visible to init-file with +;; getenv +(mapcar (lambda (env) + (setenv (car env) (cdr env))) + (chemacs-profile-get 'env)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun chemacs-load-user-early-init () + (let ((early-init-file (expand-file-name "early-init.el" user-emacs-directory))) + (load early-init-file t t))) + +(defun chemacs-load-user-init () + (when (chemacs-profile-get 'straight-p) (chemacs-load-straight)) + (let ((init-file (expand-file-name "init.el" user-emacs-directory))) + (load init-file t t) + ;; Prevent customize from changing ~/.emacs (this file), but if + ;; init.el has set a value for custom-file then don't touch it. + (let ((custom-file- (chemacs-profile-get 'custom-file init-file))) + (when (not custom-file) + (setq custom-file custom-file-) + (unless (equal custom-file init-file) + (load custom-file)))))) + (defun chemacs-load-straight () (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) @@ -67,78 +128,4 @@ (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun chemacs-get-emacs-profile (profile) - (cdr (assoc profile chemacs-emacs-profiles))) - -(defun chemacs-emacs-profile-key (key &optional default) - (alist-get key (chemacs-get-emacs-profile chemacs-current-emacs-profile) - default)) - -(defun chemacs-load-profile (profile) - (when (not (chemacs-get-emacs-profile profile)) - (error "No profile `%s' in %s" profile chemacs-profiles-path)) - (setq chemacs-current-emacs-profile profile) - (let* ((emacs-directory (file-name-as-directory - (chemacs-emacs-profile-key 'user-emacs-directory))) - (init-file (expand-file-name "init.el" emacs-directory)) - (custom-file- (chemacs-emacs-profile-key 'custom-file init-file)) - (server-name- (chemacs-emacs-profile-key 'server-name)) - (early-init-file (expand-file-name "early-init.el" emacs-directory))) - (setq user-emacs-directory emacs-directory) - - ;; Allow multiple profiles to each run their server - ;; use `emacsclient -s profile_name' to connect - (when server-name- - (setq server-name server-name-)) - - ;; Set environment variables, these are visible to init-file with getenv - (mapcar (lambda (env) - (setenv (car env) (cdr env))) - (chemacs-emacs-profile-key 'env)) - - (if (and (boundp 'chemacs-early-init) chemacs-early-init) - (when (file-exists-p early-init-file) - (load early-init-file) - (setq chemacs-early-init nil)) - (when (chemacs-emacs-profile-key 'straight-p) - (chemacs-load-straight)) - - ;; Start the actual initialization - (load init-file) - - ;; Prevent customize from changing ~/.emacs (this file), but if init.el has - ;; set a value for custom-file then don't touch it. - (when (not custom-file) - (setq custom-file custom-file-) - (unless (equal custom-file init-file) - (load custom-file)))))) - -(defun chemacs-check-command-line-args (args) - (if args - ;; Handle either `--with-profile profilename' or - ;; `--with-profile=profilename' - (let ((s (split-string (car args) "="))) - (cond ((equal (car args) "--with-profile") - ;; This is just a no-op so Emacs knows --with-profile - ;; is a valid option. If we wait for - ;; command-switch-alist to be processed then - ;; after-init-hook has already run. - (add-to-list 'command-switch-alist - '("--with-profile" . - (lambda (_) (pop command-line-args-left)))) - ;; Load the profile - (chemacs-load-profile (cadr args))) - - ;; Similar handling for `--with-profile=profilename' - ((equal (car s) "--with-profile") - (add-to-list 'command-switch-alist `(,(car args) . (lambda (_)))) - (chemacs-load-profile (mapconcat 'identity (cdr s) "="))) - - (t (chemacs-check-command-line-args (cdr args))))) - - ;; If no profile given, load the "default" profile - (chemacs-load-profile (chemacs-detect-default-profile)))) - -(chemacs-check-command-line-args command-line-args) +(provide 'chemacs) diff --git a/early-init.el b/early-init.el index 78b0396..c4ae04b 100644 --- a/early-init.el +++ b/early-init.el @@ -1,10 +1,7 @@ ;;; early-init.el --- -*- lexical-binding: t; -*- -(let ((chemacs-directory - (file-name-directory (file-truename load-file-name)))) - (load (expand-file-name "chemacs.el" chemacs-directory))) - -;; Check for a --with-profile flag and honor it; otherwise load the -;; default profile. -(defvar chemacs-early-init t) -(chemacs-check-command-line-args command-line-args) +(require 'chemacs + (expand-file-name "chemacs.el" + (file-name-directory + (file-truename load-file-name)))) +(chemacs-load-user-early-init) diff --git a/init.el b/init.el index 55a678e..44948e1 100644 --- a/init.el +++ b/init.el @@ -1,9 +1,11 @@ ;;; init.el --- -*- lexical-binding: t; -*- -(let ((chemacs-directory - (file-name-directory (file-truename load-file-name)))) - (load (expand-file-name "chemacs.el" chemacs-directory))) +(require 'chemacs + (expand-file-name "chemacs.el" + (file-name-directory + (file-truename load-file-name)))) +(chemacs-load-user-init) -;; Check for a --with-profile flag and honor it; otherwise load the -;; default profile. -(chemacs-check-command-line-args command-line-args) +;; this must be here to keep the package system happy, normally you do +;; `package-initialize' for real in your own init.el +;; (package-initialize)