From 95f8dfd48ba8421913ba082537c5ab805ceb5b45 Mon Sep 17 00:00:00 2001 From: Taylor Bockman Date: Thu, 6 Oct 2022 08:44:37 -0700 Subject: [PATCH] init --- .gitignore | 52 +++++++++++++++ README.md | 62 ++++++++++++++++++ elisp/custom.el | 13 ++++ elisp/git.el | 4 ++ elisp/keybinds.el | 11 ++++ elisp/modes/default-modes.el | 37 +++++++++++ elisp/modes/ibuffer-settings.el | 58 ++++++++++++++++ elisp/modes/json-mode-settings.el | 3 + elisp/modes/lisp-mode-settings.el | 53 +++++++++++++++ elisp/modes/markdown-mode-settings.el | 5 ++ elisp/modes/python-mode-settings.el | 66 +++++++++++++++++++ elisp/ui.el | 49 ++++++++++++++ init.el | 120 ++++++++++++++++++++++++++++++++++ 13 files changed, 533 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 elisp/custom.el create mode 100644 elisp/git.el create mode 100644 elisp/keybinds.el create mode 100644 elisp/modes/default-modes.el create mode 100644 elisp/modes/ibuffer-settings.el create mode 100644 elisp/modes/json-mode-settings.el create mode 100644 elisp/modes/lisp-mode-settings.el create mode 100644 elisp/modes/markdown-mode-settings.el create mode 100644 elisp/modes/python-mode-settings.el create mode 100644 elisp/ui.el create mode 100644 init.el diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a7ad8ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,52 @@ +# -*- mode: gitignore; -*- +private.el +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +transient/ +eln-cache diff --git a/README.md b/README.md new file mode 100644 index 0000000..2687f51 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# EMacs Configuration + +Version 2 of my Emacs Configuration updated for Emacs 28.2. Most bindings are kept default. If there are binding changes +they are listed here. + +Clone this repo into your home directory using: + +``` +git clone git@git.xchg.sh:angrygoats/emacs-config.git .emacs.d +``` + +## Server + +By default `init.el` spins up an Emacs server as it's last task. You can set `EDITOR` to `emacsclient` in order to use your existing +Emacs session quickly for tasks like mail (if you use a text-based mail editor). See this [helpful documentation](https://www.nongnu.org/emacsdoc-fr/manuel/emacs-server.html) on using Emacs as a server. + +## Private Configurations + +Sometimes you have certain things that a library might require but you don't want committed to your dotfiles. This git +project will ignore `private.el`. You may put your private information in `~/.emacs.d/elisp/private.el` for it to be loaded. + +## Markdown + +For full use of the markdown mode you will need a markdown preprocessor installed such as pandoc or multimarkdown. +The current configuration is set to use multimarkdown. You may wish to install it using your package manager. + +## Git + +`magit` is installed. [Learn to use it](https://emacsair.me/2017/09/01/magit-walk-through/). + +## Neotree + +A nice tree is provided (with icons) by `Neotree`. You can toggle the tree by using ``C-``` + +## Project Management + +`Projectile` is installed. You may learn more about how to use it [here](https://github.com/bbatsov/projectile). + +## Syntax Checking + +`flycheck` is installed. To list errors found by flycheck you can click the modeline +error indicator or type `C-c ! l` to list them in a new buffer. + +## Switching Between Windows + +To go forward and backward between windows the bindings have been changed to `C-.` and `C-,` respectively. Now, +you can simply hold control and press one more key in order to switch between windows easily. Additionally +you may use `M-` where `` is your left, right, up, or down arrow key in order to move between windows. + +## Languages + +## Lisp + +`SLIME` is installed and automatically configured to `sbcl`. To evalute the current `defun` in `SLIME` press ``. To evalute +the buffer press ``. + +### Notes on SLIME + +When starting you may get an error about an improper number of arguments being passed. Upon tracing the error you will see that +something in `hyperspec.el` is causing an issue. The fix that worked for me is to manually run `SLIME` via `M-x slime`. After that +things will get compiled and `use-package` will then proceed to work as normal. For a first installation even `use-package` may fail. +In this case you will need to do `M-x package-install` and type `slime` to install `SLIME` and then proceed with the fix. diff --git a/elisp/custom.el b/elisp/custom.el new file mode 100644 index 0000000..7580661 --- /dev/null +++ b/elisp/custom.el @@ -0,0 +1,13 @@ +(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 + '(exwm-config all-the-icons-ibuffer slime ivy zerodark-theme zerodark neotree all-the-icons paredit flycheck aggressive-indent aggressive-indent-mode lsp-python-ms py-autopep8 pyenv-mode elpy lsp-ui use-package))) +(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. + ) diff --git a/elisp/git.el b/elisp/git.el new file mode 100644 index 0000000..6a7203b --- /dev/null +++ b/elisp/git.el @@ -0,0 +1,4 @@ +;; Git configurations + +(use-package magit + :ensure t) diff --git a/elisp/keybinds.el b/elisp/keybinds.el new file mode 100644 index 0000000..a3db7b9 --- /dev/null +++ b/elisp/keybinds.el @@ -0,0 +1,11 @@ +;; Keybinds + +(global-set-key (kbd "C-.") #'other-window) +(global-set-key (kbd "C-,") #'prev-window) + +(defun prev-window () + (interactive) + (other-window -1)) + +;; Allow arrow meta-arrow to move between windows. +(windmove-default-keybindings 'meta) diff --git a/elisp/modes/default-modes.el b/elisp/modes/default-modes.el new file mode 100644 index 0000000..831a6f0 --- /dev/null +++ b/elisp/modes/default-modes.el @@ -0,0 +1,37 @@ +;; Default mode definitions. + +;; Force code to always be indented correctly. +(use-package aggressive-indent + :ensure t) + +;; Flycheck is enabled globally. +(use-package flycheck + :ensure t + :hook ((after-init . global-flycheck-mode))) + +;; Company is enabled globally. +(use-package company + :ensure t + :hook ((after-init . global-company-mode))) + +(use-package projectile + :ensure t + :bind-keymap + ("C-c p" . projectile-command-map)) + +(use-package ivy + :ensure t + :config + (ivy-mode 1)) + +(use-package lsp-mode + :ensure t + :hook ((python-mode . lsp-deferred)) + :commands (lsp lsp-deferred)) + +(use-package lsp-ui + :ensure t + :hook (lsp-mode . lsp-ui-mode)) + +(use-package rainbow-delimiters + :ensure t) diff --git a/elisp/modes/ibuffer-settings.el b/elisp/modes/ibuffer-settings.el new file mode 100644 index 0000000..cb26cd4 --- /dev/null +++ b/elisp/modes/ibuffer-settings.el @@ -0,0 +1,58 @@ +;;; ibuffer-settings.el --- Settings for ibuffer. +;;; +;;; Commentary: +;;; +;;; Use C-x C-b to launch ibuffer. +(setq ibuffer-saved-filter-groups + '(("default" + ("Emacs Configuration" (or (filename . ".emacs.d") + (filename . "init.el") + (filename . "package.el") + (filename . "private.el") + (filename . "emacs.d"))) + ("Org" (or (mode . org-mode) + (filename . "OrgMode"))) + ("Magit" (name . "magit")) + ("Help" (or (name . "\*Help\*") + (name . "\*Apropos\*") + (name . "\*info\*"))) + ("Dired" (mode . dired-mode)) + ;; Dev has groups for all languages you program in + ("Dev" (or + (filename . ".c") + (filename . ".cpp") + (filename . ".hpp") + (filename . ".h") + (filename . ".java") + (filename . ".py") + (filename . ".lisp") + (filename . ".properties") + (filename . ".gradle") + (filename . ".am") + (filename . ".json") + (mode . yaml-mode)) + ) + ("Text" (or (filename . ".csv") + (filename . ".tsv") + (filename . ".txt") + (filename . ".log"))) + ("Emacs" (or (name . "^\\*scratch\\*$") + (name . "^\\*Messages\\*$"))) + ("Gnus" (or (mode . message-mode) + (mode . bbdb-mode) + (mode . mail-mode) + (mode . gnus-group-mode) + (mode . gnus-summary-mode) + (mode . gnus-article-mode) + (name . "^\\.bbdb$") + (name . "^\\.newsrc-dribble"))) + ))) +;; Automatically keep buffers up to date and load the filter +(add-hook 'ibuffer-mode-hook + '(lambda () + (ibuffer-auto-mode 1) + (ibuffer-switch-to-saved-filter-groups "default"))) +;; Disable eager line numbering +(add-hook 'ibuffer-mode-hook 'nolinum) +(setq ibuffer-expert t) +(setq ibuffer-show-empty-filter-groups nil) diff --git a/elisp/modes/json-mode-settings.el b/elisp/modes/json-mode-settings.el new file mode 100644 index 0000000..4da31d3 --- /dev/null +++ b/elisp/modes/json-mode-settings.el @@ -0,0 +1,3 @@ +;; JSON mode settings +(use-package json-mode + :ensure t) diff --git a/elisp/modes/lisp-mode-settings.el b/elisp/modes/lisp-mode-settings.el new file mode 100644 index 0000000..813e10b --- /dev/null +++ b/elisp/modes/lisp-mode-settings.el @@ -0,0 +1,53 @@ +;;; lisp-mode-settings.el --- Settings for lisp modes. +;; Slime - requires SBCL to be installed in /usr/local/bin/ (default for the install.sh +;; script) + +(use-package paredit + :ensure t) + +(use-package slime + :ensure t + :config + (global-unset-key (kbd "")) + (global-unset-key (kbd "")) + (define-key lisp-mode-map (kbd "") 'slime-eval-buffer) + (define-key lisp-mode-map (kbd "") 'slime-eval-defun)) + +(setq inferior-lisp-program "sbcl") +(setq slime-contribs '(slime-fancy)) + +;; Enable paredit for lisp +(autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t) +(add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode) +(add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode) +(add-hook 'ielm-mode-hook #'enable-paredit-mode) +(add-hook 'lisp-mode-hook #'enable-paredit-mode) +(add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode) +(add-hook 'scheme-mode-hook #'enable-paredit-mode) + +(add-hook 'clojure-mode-hook 'rainbow-delimiters-mode) +(add-hook 'lisp-mode-hook 'rainbow-delimiters-mode) +(add-hook 'scheme-mode-hook 'rainbow-delimiters-mode) +(add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode) + +;; Only enable aggressive indent on lisp-likes +(add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode) +(add-hook 'lisp-mode-hook #'aggressive-indent-mode) +(add-hook 'scheme-mode-hook #'aggressive-indent-mode) +(add-hook 'clojure-mode-hook #'aggressive-indent-mode) + +;; Autoload the indent function +(autoload 'common-lisp-indent-function "cl-indent" "Common Lisp indent.") + +(defun override-slime-repl-bindings-with-paredit () + (define-key slime-repl-mode-map + (read-kbd-macro paredit-backward-delete-key) nil)) + +(add-hook 'slime-repl-mode-hook 'override-slime-repl-bindings-with-paredit) + +;;--------------------------------------------------------- +;; SLIME Quicklisp Integration. +;;--------------------------------------------------------- +(when (file-exists-p "~/quicklisp/slime-helper.el") + (load (expand-file-name "~/quicklisp/slime-helper.el")) + (setq inferior-lisp-program "sbcl")) diff --git a/elisp/modes/markdown-mode-settings.el b/elisp/modes/markdown-mode-settings.el new file mode 100644 index 0000000..de5cfdf --- /dev/null +++ b/elisp/modes/markdown-mode-settings.el @@ -0,0 +1,5 @@ +;; Markdown mode settings + +(use-package markdown-mode + :ensure t + :init (setq markdown-command "multimarkdown")) diff --git a/elisp/modes/python-mode-settings.el b/elisp/modes/python-mode-settings.el new file mode 100644 index 0000000..b3f859d --- /dev/null +++ b/elisp/modes/python-mode-settings.el @@ -0,0 +1,66 @@ +;;; python-mode-settings.el --- Defines mode settings for python. +;;; +;;; Commentary: +;;; +;;; +;;; - For each project you will need to install flake8/autopep8 into the virtualenv +;;; - For each project you will need to install jedi into the virtualenv +;;; - To set your pyenv use M-x pyenv-mode and select your local virtualenv +;; thx rakan.me +(defun pyenv-activate-current-project () + "Automatically activates pyenv version if .python-version file exists." + (interactive) + (f-traverse-upwards + (lambda (path) + (message path) + (let ((pyenv-version-path (f-expand ".python-version" path))) + (if (f-exists? pyenv-version-path) + (let ((pyenv-current-version (s-trim (f-read-text pyenv-version-path 'utf-8)))) + (pyenv-mode-set pyenv-current-version) + (message (concat "Setting virtualenv to " pyenv-current-version)))))))) + +;; For Python enable Elpy. +(use-package elpy + :ensure t + :init (elpy-enable)) +(setq elpy-rpc-backend "jedi") +(setq jedi:complete-on-dot t) +;; Enable pyenv integration. + +(if (executable-find "pyenv") + (use-package pyenv-mode + :ensure t + :config + (pyenv-mode))) +;; Disable elpy default virtualenv (use the pyenv one) +(setq elpy-rpc-virtualenv-path 'current) + +;; Enable autopep8 +(use-package py-autopep8 + :ensure t) + +(add-hook 'elpy-mode-hook 'py-autopep8-enable-on-save) +;; Enable flake8 - requires flake8 in your path so use pyenv/global pip install +(add-hook 'python-mode-hook '(lambda () + (setq flycheck-python-flake8-executable "flake8") + (flycheck-select-checker 'python-flake8) + (flycheck-mode t))) +;; Activate pyenv automatically if a .python-version is supplied +(if (executable-find "pyenv") + (add-hook 'python-mode-hook 'pyenv-activate-current-project)) + +;; Add company-jedi hook to python mode +(add-hook 'python-mode-hook (lambda () + (add-to-list 'company-backends 'company-jedi))) + +;; Use microsoft's python language server +(add-hook 'python-mode-hook (lambda () (lsp-python-enable))) +(use-package lsp-python-ms + :ensure t + :init (setq lsp-python-ms-auto-install-server t) + :hook (python-mode . (lambda () + (require 'lsp-python-ms) + (lsp)))) ; or lsp-deferred +;; Python testing helpers +(use-package python-pytest + :ensure t) diff --git a/elisp/ui.el b/elisp/ui.el new file mode 100644 index 0000000..ebe7469 --- /dev/null +++ b/elisp/ui.el @@ -0,0 +1,49 @@ +;;; ui.el --- Specific UI definitions. +;; Disable the menubar, scrollbar, and toolbar +(menu-bar-mode -1) +(scroll-bar-mode -1) +(if window-system + (tool-bar-mode -1) + ) + +;; Enable column numbers +(column-number-mode 1) + +;; Enable semantic for language-aware editing commands +(setq semantic-mode 't) + +;; Nice tree +(use-package neotree + :ensure t + :commands neotree-toggle + :init (setq neo-theme (if (display-graphic-p) 'icons 'arrow)) + :bind (("C-`" . neotree-toggle)) + :requires all-the-icons) + +;; Install all-the-icons and it's fonts if they are not already installed. +(use-package all-the-icons + :ensure t + :config (unless (member "all-the-icons" (font-family-list)) + (all-the-icons-install-fonts t))) + +;; Theme +(use-package zerodark-theme + :ensure t + :requires all-the-icons + :config + (load-theme 'zerodark t) + (zerodark-setup-modeline-format)) + +;; Buffer configuration +(use-package all-the-icons-ibuffer + :ensure t + :hook (ibuffer-mode . all-the-icons-ibuffer-mode) + :requires all-the-icons) + +;; Modeline configuration +(display-battery-mode 1) +(display-time-mode 1) +(column-number-mode 1) + +;; Line numbers +(display-line-numbers-mode 1) diff --git a/init.el b/init.el new file mode 100644 index 0000000..980a806 --- /dev/null +++ b/init.el @@ -0,0 +1,120 @@ +(require 'package) +(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) +;; Comment/uncomment this line to enable MELPA Stable if desired. See `package-archive-priorities` +;; and `package-pinned-packages`. Most users will not need or want to do this. +;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t) +(package-initialize) + +;; Disable startup noise +(setq inhibit-startup-message t) + +;; Add custom code to load path. +(add-to-list 'load-path "~/.emacs.d/elisp") +(add-to-list 'load-path "~/.emacs.d/elisp/modes") + +;; Before doing anything else ensure that use-package is installed +;; for later work. +(unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + +(eval-and-compile + (setq use-package-always-ensure t + use-package-expand-minimally t)) + +;;----------------------------------------------------- +;; Set auto-save and backup directory to the temporary +;; file directory in order to keep projects free of +;; annoying backups. +;;----------------------------------------------------- +(setq backup-directory-alist + `((".*" . ,temporary-file-directory))) +(setq auto-save-file-name-transforms + `((".*" , temporary-file-directory t))) + + +;;---------------------------------------------------------- +;; Always follow symbolic links to version controlled files. +;; +;; I prefer this option because I generally only get this +;; message when I edit a dotfile under version control, and +;; repeatedly typing "yes" is annoying. +;;---------------------------------------------------------- +(setq vc-follow-symlinks t) + +;;--------------------------------- +;; Prefer unix style line endings. +;;--------------------------------- +(set-buffer-file-coding-system 'unix) + +;;--------------------------------------------------- +;; Populate emacs path to $PATH when on *nix or OS X. +;;--------------------------------------------------- +(use-package exec-path-from-shell + :ensure t) + +(when (memq window-system '(mac ns x)) + (exec-path-from-shell-initialize)) + +;;------------------------------------ +;; Delete trailing whitespace on save. +;;------------------------------------ +(add-hook 'before-save-hook 'delete-trailing-whitespace) + +;;---------------------------------------------- +;; When a file is updated by an external program +;; (such as git), update the buffer. +;;---------------------------------------------- +(global-auto-revert-mode t) + +;;------------------------------- +;; Stop the annoying features. +;;------------------------------- +(setq visible-bell t) +;; ... and the flashing +(setq ring-bell-function 'ignore) + +;; Bug with Darwin that effects Emacs 28. +;; Causes ld log spam. This can be removed +;; in Emacs 29. +(when (eq system-type 'darwin) + (customize-set-variable 'native-comp-driver-options '("-Wl,-w"))) + +;;-------------------------------------- +;; Enable Org-mode and set agenda files. +;;-------------------------------------- +(require 'org) + +;; Stuff all of the org files you want under +;; ~/org and they will be loaded automatically +;; and have their TODO items accessible by typing +;; C-c a t. +(setq org-agenda-files '("~/org")) +(setq org-log-done t) + +;; Send custom-set-variables type spam to another file. +(when (file-exists-p "~/.emacs.d/elisp/custom.el") + (setq custom-file "~/.emacs.d/elisp/custom.el") + (load custom-file)) + +;;------------------------- +;; Load modes and keybinds. +;;------------------------- + +;; Order is important here - default-modes must be loaded first! +(load-library "default-modes") +(load-library "ui") +(load-library "git") +(load-library "markdown-mode-settings") +(load-library "json-mode-settings") +(load-library "python-mode-settings") +(load-library "lisp-mode-settings") +(load-library "ibuffer-settings") +(load-library "keybinds") + +;; Load anything private +(when (file-exists-p "~/.emacs.d/elisp/private.el") + (load "~/.emacs.d/elisp/private.el")) + +;; Start an emacs server so other things (such as mail clients) can quickly use Emacs. +(server-start)