From 48a85d7becc204490cdb1738314097b2d5a041e1 Mon Sep 17 00:00:00 2001 From: Marcel Fries Date: Thu, 4 Jul 2024 07:41:47 +0200 Subject: [PATCH] Move config from README to init.el --- README.org | 581 ----------------------------------------------------- init.el | 400 +++++++++++++++++++++++++++++++++++- 2 files changed, 393 insertions(+), 588 deletions(-) delete mode 100644 README.org diff --git a/README.org b/README.org deleted file mode 100644 index ea96f53..0000000 --- a/README.org +++ /dev/null @@ -1,581 +0,0 @@ -#+TITLE: luxicks Emacs Configuration -#+PROPERTY: header-args :results silent -This is my configuration for the emacs editor. - -- Personal information (name, email) are stored in a separate ~personal.el~ file. -- Machine specific settings are stored in a separate ~custom.el~ file. -- Both files are loaded automatically. - -* Set Up use-package -Packages provided by =straight.el= https://github.com/radian-software/straight.el -#+BEGIN_SRC emacs-lisp - (defvar bootstrap-version) - (let ((bootstrap-file - (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) - (bootstrap-version 6)) - (unless (file-exists-p bootstrap-file) - (with-current-buffer - (url-retrieve-synchronously - "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" - 'silent 'inhibit-cookies) - (goto-char (point-max)) - (eval-print-last-sexp))) - (load bootstrap-file nil 'nomessage)) - - (straight-use-package 'use-package) - (setq straight-use-package-by-default t) - - (package-initialize) - - (straight-use-package 'bind-key) -#+end_src - -* Theming -#+begin_src emacs-lisp - (use-package modus-themes - :straight t - :config - ;; Add all your customizations prior to loading the themes - (setq modus-themes-italic-constructs t - modus-themes-bold-constructs nil) - - ;; Maybe define some palette overrides, such as by using our presets - (setq modus-themes-common-palette-overrides - modus-themes-preset-overrides-intense) - - ;; Load the theme of your choice. - (load-theme 'modus-operandi t) - - (define-key global-map (kbd "") #'modus-themes-toggle)) -#+end_src - -*Set up the default frame look* -#+begin_src emacs-lisp - (setq default-frame-alist - (append (list '(width . 90) '(height . 50) - '(vertical-scroll-bars . nil) - '(internal-border-width . 5)))) -#+end_src - -* Fix Defaults -** Hide UI elements -Remove all those UI elements. They do not look good and waste space. -#+BEGIN_SRC emacs-lisp - (tool-bar-mode -1) - (menu-bar-mode -1) - (scroll-bar-mode -1) - (tooltip-mode -1) - (fringe-mode -1) -#+END_SRC - -** Disable file backups -Emacs sure loves to clutter directories with backup files. -#+BEGIN_SRC emacs-lisp - (setq make-backup-files nil) - (setq auto-save-default nil) - (setq create-lockfiles nil) -#+END_SRC - -** File management -Configure dired to only use one buffer. -#+BEGIN_SRC emacs-lisp - (setf dired-kill-when-opening-new-dired-buffer t) - (setq dired-listing-switches "-laGh1v --group-directories-first") - - (setq dired-omit-files - (rx (or (seq bol (? ".") "#") ;; emacs autosave files - (seq bol "." (not (any "."))) ;; dot-files - (seq "~" eol) ;; backup-files - (seq bol "CVS" eol) ;; CVS dirs - ))) - - (defun my-dired-init () - "to be run as hook for `dired-mode'." - (interactive) - (dired-hide-details-mode 1) - (dired-omit-mode 1)) - - (add-hook 'dired-mode-hook 'my-dired-init) -#+END_SRC - -Use ranger inside of emacs -#+BEGIN_SRC emacs-lisp - (use-package ranger :straight t) - (ranger-override-dired-mode t) -#+END_SRC - -** Other Settings -#+begin_src emacs-lisp - ;; The default encoding should be utf-8 everywhere - (prefer-coding-system 'utf-8) - - ;; All "Yes or No" questions can be shortend to "y or n". - (defalias 'yes-or-no-p 'y-or-n-p) - - ;; No more startup messages and screens - (setq inhibit-startup-screen t) - (setq initial-buffer-choice nil) - (defun display-startup-echo-area-message () - (message "Welcome Back!")) - - ;; Highlight matching braces - (show-paren-mode t) - - ;; cua-mode. Like any other editor - (cua-mode t) - - ;; Configure the cursor - (setq-default - cursor-type 'bar - indent-tabs-mode nil - cursor-in-non-selected-windows nil) - (blink-cursor-mode 0) - - ;; Default column with - (set-fill-column 95) - - ;; Start up in the home directory - (setq default-directory "~/") - - ;; Make C-k always kill the whole line - (setq kill-whole-line t) - - ;; Do not ding. Ever. - (setq ring-bell-function 'ignore) - - ;; Dialogues always go in the modeline. - (setq use-dialog-box nil) - - ;; Show tooltips on hover and not in the echo area. - ;; Those are often cut of. - (tooltip-mode) - - ;; Better line wraping - (global-visual-line-mode 1) -#+end_src - -** Keybindings -#+BEGIN_SRC emacs-lisp - (bind-key "C-x k" 'kill-buffer-with-prejudice) - (bind-key "C-x C-k" 'kill-buffer-and-window) - (bind-key "M-p" 'switch-to-previous-buffer) - (bind-key "M-i" 'delete-indentation) - (bind-key "C-+" 'text-scale-increase) - (bind-key "C--" 'text-scale-decrease) - ;; buffer-list is not a good default - (bind-key "C-x C-b" 'ibuffer) - (bind-key "C-c n" 'display-line-numbers-mode) - (global-set-key (kbd "") 'menu-bar-mode) -#+END_SRC - -Unbind useless keys. -#+BEGIN_SRC emacs-lisp - (unbind-key "C-") ;; prevent switching to tab mode randomly - (unbind-key "C-h n") ;; I have never wanted to see emacs news ever - (unbind-key "C-h C-n") ;; why on earth is it bound to two keybindings?? - (unbind-key "C-x C-d") ;; list-directory is utterly useless given the existence of dired - (unbind-key "C-x C-r") ;; as is find-file-read-only -#+END_SRC - -* Useful Functions -** Edit This File -A simple funtion to open this file for quick editing. -#+BEGIN_SRC emacs-lisp - (defun edit-config () - (interactive) - (find-file "~/.emacs.d/README.org")) -#+END_SRC - -** Reformating -Reindet the whole buffer with ~F1~ -#+BEGIN_SRC emacs-lisp - (defun lux/indent-buffer () - "Reindents the whole buffer" - (interactive) - (save-excursion - (indent-region (point-min) (point-max) nil))) - (global-set-key [f1] 'lux/indent-buffer) -#+END_SRC - -** Window Splitting -These are functions for splitting windows and move the cursor over immediately. -#+BEGIN_SRC emacs-lisp - (defun lux/split-right-and-enter () - "Split the window to the right and enter it." - (interactive) - (split-window-right) - (other-window 1)) - (bind-key "M-3" 'lux/split-right-and-enter) - - (defun lux/split-below-and-enter () - "Split the window down and enter it." - (interactive) - (split-window-below) - (other-window 1)) - (bind-key "M-2" 'lux/split-below-and-enter) -#+END_SRC - -Rebind the default window controls to use "M-*" keys for ease-of-use -#+begin_src emacs-lisp - (bind-key "M-1" 'delete-other-windows) - (bind-key "C-M-1" 'delete-other-windows) - (bind-key "M-0" 'delete-window) -#+end_src - -** Quick buffer switching -#+BEGIN_SRC emacs-lisp - (defun switch-to-previous-buffer () - "Switch to previously open buffer.Repeated invocations toggle between the two most recently open buffers." - (interactive) - (switch-to-buffer (other-buffer (current-buffer) 1))) -#+END_SRC - -* Fonts -Set up the fonts to use. -#+begin_src emacs-lisp - (set-face-attribute 'default nil :font "Iosevka Term-12") - (set-face-attribute 'fixed-pitch nil :font "Iosevka Term-12") - (set-face-attribute 'variable-pitch nil :font "Iosevka Aile") - - (let* ((variable-tuple - (cond ((x-list-fonts "Iosevka Aile") '(:font "Iosevka Aile")) - ((x-family-fonts "Sans Serif") '(:family "Sans Serif")) - (nil (warn "Cannot find a Sans Serif Font. Install Iosevka Aile.")))) - (headline `(:inherit default :weight bold))) - - (custom-theme-set-faces - 'user - `(org-level-8 ((t (,@headline ,@variable-tuple)))) - `(org-level-7 ((t (,@headline ,@variable-tuple)))) - `(org-level-6 ((t (,@headline ,@variable-tuple)))) - `(org-level-5 ((t (,@headline ,@variable-tuple)))) - `(org-level-4 ((t (,@headline ,@variable-tuple)))) - `(org-level-3 ((t (,@headline ,@variable-tuple)))) - `(org-level-2 ((t (,@headline ,@variable-tuple)))) - `(org-level-1 ((t (,@headline ,@variable-tuple)))) - `(org-document-title ((t (,@headline ,@variable-tuple :underline nil)))))) - - (custom-theme-set-faces - 'user - '(variable-pitch ((t (:family "Iosevka Aile" :height 120 :weight thin)))) - '(fixed-pitch ((t ( :family "Iosevka Term" :height 120))))) -#+end_src - -* Completion -** Ivy -Use Ivy to make minibuf promts better. Adds the ability to sort and filter. -#+BEGIN_SRC emacs-lisp - (use-package ivy - :straight t - :diminish - :init - (ivy-mode 1) - (unbind-key "S-SPC" ivy-minibuffer-map) - (setq ivy-height 30 - ivy-use-virtual-buffers t - ivy-use-selectable-prompt t) - :bind (("C-x b" . ivy-switch-buffer) - ("C-c C-r" . ivy-resume) - ("C-s" . swiper))) - - ;; ivy-rich makes Ivy look a little bit more like Helm. - (use-package ivy-rich - :straight t - :after counsel - :custom - (ivy-virtual-abbreviate 'full - ivy-rich-switch-buffer-align-virtual-buffer t - ivy-rich-path-style 'abbrev) - :init - (ivy-rich-mode)) - - (use-package ivy-hydra - :straight t) -#+END_SRC - -** Smex -Sort commands by recency in ivy windows -#+BEGIN_SRC emacs-lisp - (use-package smex - :straight t) -#+END_SRC - -** Counsel -#+BEGIN_SRC emacs-lisp - (use-package counsel - :straight t - :after ivy - :init (counsel-mode 1) - :bind (("C-c ;" . counsel-M-x) - ("C-c U" . counsel-unicode-char) - ("C-c i" . counsel-imenu) - ("C-c y" . counsel-yank-pop) - ("C-c r" . counsel-recentf) - :map ivy-minibuffer-map - ("C-r" . counsel-minibuffer-history)) - :diminish) -#+END_SRC - -** Ido -#+begin_src emacs-lisp - (use-package ido - :straight t - :config (ido-mode 1) - :bind (("C-x f" . ido-find-file))) -#+end_src - -** Autocompletion -#+BEGIN_SRC emacs-lisp - (use-package auto-complete - :straight t - :config - (ac-config-default)) -#+END_SRC - -* Magit -Magit is THE go to package for using git in emacs. -#+BEGIN_SRC emacs-lisp - (use-package magit - :straight t - :bind (("C-c g" . magit-status)) - :diminish magit-auto-revert-mode - :diminish auto-revert-mode - :custom - (magit-remote-set-if-missing t) - (magit-diff-refine-hunk t) - :config - (magit-auto-revert-mode t) - (advice-add 'magit-refresh :before #'maybe-unset-buffer-modified) - (advice-add 'magit-commit :before #'maybe-unset-buffer-modified) - (setq magit-completing-read-function 'ivy-completing-read) - (add-to-list 'magit-no-confirm 'stage-all-changes)) - - (use-package libgit - :straight t - :disabled - :after magit) -#+END_SRC -The ~advice-add~ entries are thereto stop magit from bugging us to save buffers when commiting and refreshing. - -** Helper Functions -#+BEGIN_SRC emacs-lisp - (autoload 'diff-no-select "diff") - (defun current-buffer-matches-file-p () - "Return t if the current buffer is identical to its associated file." - (when (and buffer-file-name (buffer-modified-p)) - (diff-no-select buffer-file-name (current-buffer) nil 'noasync) - (with-current-buffer "*Diff*" - (and (search-forward-regexp "^Diff finished \(no differences\)\." (point-max) 'noerror) t)))) -#+END_SRC - -Clear modified bit on all unmodified buffers -#+BEGIN_SRC emacs-lisp - (defun maybe-unset-buffer-modified (&optional _) - (interactive) - (dolist (buf (buffer-list)) - (with-current-buffer buf - (when (and buffer-file-name (buffer-modified-p) (current-buffer-matches-file-p)) - (set-buffer-modified-p nil))))) - -#+END_SRC - -Don't prompt to save unmodified buffers on exit. -#+BEGIN_SRC emacs-lisp - (advice-add 'save-buffers-kill-emacs :before #'maybe-unset-buffer-modified) -#+END_SRC - -#+BEGIN_SRC emacs-lisp - (defun kill-buffer-with-prejudice (&optional _) - "Kill a buffer, eliding the save dialogue if there are no diffs." - (interactive) - (when (current-buffer-matches-file-p) (set-buffer-modified-p nil)) - (kill-buffer)) -#+END_SRC - -* Org Mode -Configuration to make org-mode better as a word processor -#+BEGIN_SRC emacs-lisp - (use-package org-modern - :straight t - :hook (org-mode . org-modern-mode)) - - (setq - ;; Edit settings - org-auto-align-tags nil - org-tags-column 0 - org-catch-invisible-edits 'show-and-error - org-special-ctrl-a/e t - org-insert-heading-respect-content t - - ;; Org styling, hide markup etc. - org-hide-emphasis-markers t - org-pretty-entities t - ) - - ;; Ellipsis styling - (setq org-ellipsis "…") - (set-face-attribute 'org-ellipsis nil :inherit 'default :box nil) - - ;; Always collapse org files - (setq org-startup-folded t) -#+END_SRC - -** Archive Location -When archiving items in org files, the default ist to crate a separate file named ~.org_archive~. -This clutters up my notes folder quite a bit, as I use a lot of separate files with thier respective archives. -All archives should be stored in a single ~.archive~ file per directory. -#+BEGIN_SRC emacs-lisp - (setq org-archive-location "./.archive::* From %s") -#+END_SRC -** Templates -*** Babel -Here we set custom templates to be used for structure expansion. -These are used when we type "<" folowed by the shortcut for a template and hit "TAB". -e.g. "") 'copilot-accept-completion) - (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion) - (define-key copilot-completion-map (kbd "M--") 'copilot-complete) -#+end_src - -** Elisp -Some customization for writing elisp -#+BEGIN_SRC emacs-lisp - (defun my-elisp-mode-hook () - "My elisp customizations." - (electric-pair-local-mode 1) - (add-hook 'before-save-hook 'check-parens nil t) - (auto-composition-mode nil)) - - (add-hook 'emacs-lisp-mode-hook 'my-elisp-mode-hook) -#+END_SRC - -** Common Lisp -#+BEGIN_SRC emacs-lisp - (setq inferior-lisp-program "sbcl") - (use-package slime - :straight t) - (slime-setup '(slime-fancy slime-quicklisp slime-asdf)) - (add-hook 'slime-repl-mode-hook (lambda () (paredit-mode +1))) -#+END_SRC - -* Load additional files -All information about the current user should reside in the ~personal.el~ file. -This file contains personal information like name, email or other identifying information. -This file should contain definitions, that are the same on every device, but sould not be commited to a repository. -#+BEGIN_SRC emacs-lisp - (setq personal-file "~/.emacs.d/personal.el") - (load personal-file 'noerror) -#+END_SRC - -Load a custom file from the emacs home dir. -This file is specific to the machine emacs runs on. -It conatins customizations and file locations that are machine dependend. -#+BEGIN_SRC emacs-lisp - (setq custom-file "~/.emacs.d/custom.el") - (load custom-file 'noerror) -#+END_SRC - - diff --git a/init.el b/init.el index 7bcd13e..4c4e9d7 100644 --- a/init.el +++ b/init.el @@ -1,11 +1,397 @@ -;; init.el -- Marcel Fries +;; The default encoding should be utf-8 everywhere +(prefer-coding-system 'utf-8) +(set-default-coding-systems 'utf-8) +(set-language-environment 'utf-8) +(set-selection-coding-system 'utf-8) -;; Configure emacs in a literate style from an org file. -;; The file sould be named "README.org". It should be located in your ".emacs.d" directory. -;; Source at https://git.sr.ht/~luxick/emacs-config +;; custom.el - device specific settings +(setq custom-file "~/.emacs.d/custom.el") +(load custom-file 'noerror) -(require 'org) -(org-babel-load-file - (expand-file-name (concat user-emacs-directory "README.org"))) +;; personal.el - personal settings +(setq personal-file "~/.emacs.d/personal.el") +(load personal-file 'noerror) + +;; Setup straight.el +;; https://github.com/radian-software/straight.el +(defvar bootstrap-version) +(let ((bootstrap-file + (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) + (bootstrap-version 6)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + +(straight-use-package 'use-package) +(setq straight-use-package-by-default t) +(package-initialize) +(straight-use-package 'bind-key) + +;; Themeing + +;; use modus themes +(use-package modus-themes + :straight t + :config + ;; Add all your customizations prior to loading the themes + (setq modus-themes-italic-constructs t + modus-themes-bold-constructs nil) + + ;; Maybe define some palette overrides, such as by using our presets + (setq modus-themes-common-palette-overrides + modus-themes-preset-overrides-intense) + + ;; Load the theme of your choice. + (load-theme 'modus-operandi t) + + (define-key global-map (kbd "") #'modus-themes-toggle)) + +;; Default frame size +(setq default-frame-alist + (append (list '(width . 90) '(height . 50) + '(vertical-scroll-bars . nil) + '(internal-border-width . 5)))) + +;; Disable some UI elements +(tool-bar-mode -1) +(menu-bar-mode -1) +(scroll-bar-mode -1) +(tooltip-mode -1) +(fringe-mode -1) + +;; Font settings +(set-face-attribute 'default nil :font "Iosevka Term-12") +(set-face-attribute 'fixed-pitch nil :font "Iosevka Term-12") +(set-face-attribute 'variable-pitch nil :font "Iosevka Aile") + +(let* ((variable-tuple + (cond ((x-list-fonts "Iosevka Aile") '(:font "Iosevka Aile")) + ((x-family-fonts "Sans Serif") '(:family "Sans Serif")) + (nil (warn "Cannot find a Sans Serif Font. Install Iosevka Aile.")))) + (headline `(:inherit default :weight bold))) + + (custom-theme-set-faces + 'user + `(org-level-8 ((t (,@headline ,@variable-tuple)))) + `(org-level-7 ((t (,@headline ,@variable-tuple)))) + `(org-level-6 ((t (,@headline ,@variable-tuple)))) + `(org-level-5 ((t (,@headline ,@variable-tuple)))) + `(org-level-4 ((t (,@headline ,@variable-tuple)))) + `(org-level-3 ((t (,@headline ,@variable-tuple)))) + `(org-level-2 ((t (,@headline ,@variable-tuple)))) + `(org-level-1 ((t (,@headline ,@variable-tuple)))) + `(org-document-title ((t (,@headline ,@variable-tuple :underline nil)))))) + +(custom-theme-set-faces + 'user + '(variable-pitch ((t (:family "Iosevka Aile" :height 120 :weight thin)))) + '(fixed-pitch ((t ( :family "Iosevka Term" :height 120))))) + +;; Icons +(use-package all-the-icons + :straight t) + +;; Rainbow delimiters +(use-package rainbow-delimiters + :straight t + :hook (prog-mode . rainbow-delimiters-mode)) + +;; Disable backup files +(setq make-backup-files nil) +(setq auto-save-default nil) +(setq create-lockfiles nil) + +;; Dired settings +(setf dired-kill-when-opening-new-dired-buffer t) +(setq dired-listing-switches "-laGh1v --group-directories-first") +(setq dired-omit-files + (rx (or (seq bol (? ".") "#") ;; emacs autosave files + (seq bol "." (not (any "."))) ;; dot-files + (seq "~" eol) ;; backup-files + (seq bol "CVS" eol) ;; CVS dirs + ))) +(defun my-dired-init () + "to be run as hook for `dired-mode'." + (interactive) + (dired-hide-details-mode 1) + (dired-omit-mode 1)) +(add-hook 'dired-mode-hook 'my-dired-init) + +;; Ranger +(use-package ranger :straight t) +(ranger-override-dired-mode t) + +;; All "Yes or No" questions can be shortend to "y or n". +(defalias 'yes-or-no-p 'y-or-n-p) + +;; No more startup messages and screens +(setq inhibit-startup-screen t) +(setq initial-buffer-choice nil) +(defun display-startup-echo-area-message () + (message "Welcome Back!")) + +;; Highlight matching braces +(show-paren-mode t) + +;; cua-mode. Like any other editor +(cua-mode t) + +;; Configure the cursor +(setq-default + cursor-type 'bar + indent-tabs-mode nil + cursor-in-non-selected-windows nil) +(blink-cursor-mode 0) + +;; Default column with +(set-fill-column 95) + +;; Start up in the home directory +(setq default-directory "~/") + +;; Make C-k always kill the whole line +(setq kill-whole-line t) + +;; Do not ding. Ever. +(setq ring-bell-function 'ignore) + +;; Dialogues always go in the modeline. +(setq use-dialog-box nil) + +;; Show tooltips on hover and not in the echo area. +;; Those are often cut of. +(tooltip-mode) + +;; Better line wraping +(global-visual-line-mode 1) + +;; Keybindings +(bind-key "C-x k" 'kill-buffer-with-prejudice) +(bind-key "C-x C-k" 'kill-buffer-and-window) +(bind-key "M-i" 'delete-indentation) +(bind-key "C-+" 'text-scale-increase) +(bind-key "C--" 'text-scale-decrease) +(bind-key "C-x C-b" 'ibuffer) +(bind-key "C-c n" 'display-line-numbers-mode) +(bind-key "M-1" 'delete-other-windows) +(bind-key "C-M-1" 'delete-other-windows) +(bind-key "M-0" 'delete-window) +(global-set-key (kbd "") 'menu-bar-mode) + + +;; Edit this file +(defun edit-config () + (interactive) + (find-file "~/.emacs.d/init.el")) + +;; Custom functions +(defun lux/indent-buffer () + "Reindents the whole buffer" + (interactive) + (save-excursion + (indent-region (point-min) (point-max) nil))) +(global-set-key [f1] 'lux/indent-buffer) + +(defun lux/split-right-and-enter () + "Split the window to the right and enter it." + (interactive) + (split-window-right) + (other-window 1)) +(bind-key "M-3" 'lux/split-right-and-enter) + +(defun lux/split-below-and-enter () + "Split the window down and enter it." + (interactive) + (split-window-below) + (other-window 1)) +(bind-key "M-2" 'lux/split-below-and-enter) + +(defun switch-to-previous-buffer () + "Switch to previously open buffer.Repeated invocations toggle between the two most recently open buffers." + (interactive) + (switch-to-buffer (other-buffer (current-buffer) 1))) +(bind-key "M-p" 'switch-to-previous-buffer) + +;; Ace for qucik window switching +(use-package ace-window + :straight t + :bind (("M-o" . 'ace-window)) + :config + (custom-set-faces + '(aw-leading-char-face + ((t (:inherit ace-jump-face-foreground :height 3.0)))) + )) + +;; Ivy completion +(use-package ivy + :straight t + :diminish + :init + (ivy-mode 1) + (unbind-key "S-SPC" ivy-minibuffer-map) + (setq ivy-height 30 + ivy-use-virtual-buffers t + ivy-use-selectable-prompt t) + :bind (("C-x b" . ivy-switch-buffer) + ("C-c C-r" . ivy-resume) + ("C-s" . swiper))) + +;; ivy-rich makes Ivy look a little bit more like Helm. +(use-package ivy-rich + :straight t + :after counsel + :custom + (ivy-virtual-abbreviate 'full + ivy-rich-switch-buffer-align-virtual-buffer t + ivy-rich-path-style 'abbrev) + :init + (ivy-rich-mode)) + +(use-package ivy-hydra :straight t) + +;; smex for better M-x +(use-package smex :straight t) + +(use-package counsel + :straight t + :after ivy + :init (counsel-mode 1) + :bind (("C-c ;" . counsel-M-x) + ("C-c U" . counsel-unicode-char) + ("C-c i" . counsel-imenu) + ("C-c y" . counsel-yank-pop) + ("C-c r" . counsel-recentf) + :map ivy-minibuffer-map + ("C-r" . counsel-minibuffer-history)) + :diminish) + +(use-package ido + :straight t + :config (ido-mode 1) + :bind (("C-x f" . ido-find-file))) + +(use-package auto-complete + :straight t + :config + (ac-config-default)) + +;; Magit - git client +(use-package magit + :straight t + :bind (("C-c g" . magit-status)) + :diminish magit-auto-revert-mode + :diminish auto-revert-mode + :custom + (magit-remote-set-if-missing t) + (magit-diff-refine-hunk t) + :config + (magit-auto-revert-mode t) + (advice-add 'magit-refresh :before #'maybe-unset-buffer-modified) + (advice-add 'magit-commit :before #'maybe-unset-buffer-modified) + (setq magit-completing-read-function 'ivy-completing-read) + (add-to-list 'magit-no-confirm 'stage-all-changes)) + +(use-package libgit + :straight t + :disabled + :after magit) + +;; Duplicate +(use-package duplicate-thing + :straight t + :bind (("C-c u" . duplicate-thing))) + +;; Markdown +(use-package markdown-mode + :straight t + :mode ("\\.md$" . gfm-mode) + :config + (when (executable-find "pandoc") + (setq markdown-command "pandoc -f markdown -t html"))) + +;; Org mode +(use-package org-modern + :straight t + :hook (org-mode . org-modern-mode)) + +(setq + ;; Edit settings + org-auto-align-tags nil + org-tags-column 0 + org-catch-invisible-edits 'show-and-error + org-special-ctrl-a/e t + org-insert-heading-respect-content t + + ;; Org styling, hide markup etc. + org-hide-emphasis-markers t + org-pretty-entities t + ) + +;; Always collapse org files +(setq org-startup-folded t) + +;; Programming configuration +(use-package paredit + :straight t) +(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 'prog-mode-hook 'display-line-numbers-mode) + +;; Copilot +(use-package copilot + :straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el")) + :ensure t) +(add-hook 'prog-mode-hook 'copilot-mode) +(define-key copilot-completion-map (kbd "") 'copilot-accept-completion) +(define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion) +(define-key copilot-completion-map (kbd "M--") 'copilot-complete) + +;; Elisp +(defun my-elisp-mode-hook () + "My elisp customizations." + (electric-pair-local-mode 1) + (add-hook 'before-save-hook 'check-parens nil t) + (auto-composition-mode nil)) +(add-hook 'emacs-lisp-mode-hook 'my-elisp-mode-hook) + +;; Common Lisp +(setq inferior-lisp-program "sbcl") +(use-package slime + :straight t) +(slime-setup '(slime-fancy slime-quicklisp slime-asdf)) +(add-hook 'slime-repl-mode-hook (lambda () (paredit-mode +1))) + +;; Misc functions + +(autoload 'diff-no-select "diff") +(defun current-buffer-matches-file-p () + "Return t if the current buffer is identical to its associated file." + (when (and buffer-file-name (buffer-modified-p)) + (diff-no-select buffer-file-name (current-buffer) nil 'noasync) + (with-current-buffer "*Diff*" + (and (search-forward-regexp "^Diff finished \(no differences\)\." (point-max) 'noerror) t)))) + +(defun maybe-unset-buffer-modified (&optional _) + (interactive) + (dolist (buf (buffer-list)) + (with-current-buffer buf + (when (and buffer-file-name (buffer-modified-p) (current-buffer-matches-file-p)) + (set-buffer-modified-p nil))))) + +(defun kill-buffer-with-prejudice (&optional _) + "Kill a buffer, eliding the save dialogue if there are no diffs." + (interactive) + (when (current-buffer-matches-file-p) (set-buffer-modified-p nil)) + (kill-buffer)) (provide 'init)