Emacs overhaul, semi-usable config!

This commit is contained in:
2024-08-28 16:22:04 +03:00
parent 0b756f3af0
commit 4fae89d775
2 changed files with 332 additions and 8 deletions
+16 -4
View File
@@ -22,10 +22,20 @@ in
pname = "azos-emacs-base"; pname = "azos-emacs-base";
version = "0.1.6"; version = "0.1.6";
src = ./el/azos-emacs-base.org; src = ./el/azos-emacs-base.org;
packageRequires = [ packageRequires = with emacspkgs; [
emacspkgs.evil evil
emacspkgs.magit evil-collection
emacspkgs.vterm magit
vterm
undo-tree
ivy
ivy-hydra
ivy-avy
counsel
counsel-tramp
counsel-projectile
swiper
projectile
]; ];
}))]; }))];
@@ -33,6 +43,8 @@ in
[((emacsPackagesFor config.azos.emacs.emacspkg).emacsWithPackages ( [((emacsPackagesFor config.azos.emacs.emacspkg).emacsWithPackages (
config.azos.emacs.pkgs config.azos.emacs.pkgs
)) ]; )) ];
home.file."/.emacs.el".text = ''(require 'azos-emacs-base)'';
}; };
imports = [ imports = [
@@ -1,12 +1,324 @@
Hello! #+title: Aner's Emacs Base Configuration
#+property: header-args :results silent
* Bootstrapping
Taken from [[https://stackoverflow.com/questions/151945/how-do-i-control-how-emacs-makes-backup-files][this post on StackOverflow]]
Backups are moved to a =.cache= directory in order to keep them out of local dirs.
Follow symlinks
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setq
vc-follow-symlinks t
backup-directory-alist `(("." . "~/.cache/emacs-backups/"))
auto-save-file-name-transforms '((".*" "~/.cache/emacs-backups/" t))
backup-by-copying t
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t
gc-cons-threshold 100000000 ;Setting garbage collection to 100M.
)
#+end_src
Make sure CL is loaded
CL is a base library that has a bunch of useful stuff, primarily for lists.
We are using the built-in version, no need to pull from anywhere.
This just makes sure the code is loaded early on for later use.
#+begin_src emacs-lisp
(require 'cl-lib)
#+end_src
* Keymap setup
In this section global keybindings are defined using a global minor mode.
First, utility functions that will be bound are defined.
The first, =azos/set-window-width= is a helper function that resizes a window. Used because I wanted a function
that resizes a window to 85 cols easily.
The second, =azos/open-conf-file=, opens the configuration file.
#+begin_src emacs-lisp
(defun azos/set-window-width (n)
(adjust-window-trailing-edge (selected-window) ( - n (window-width)) t))
(defun azos/open-conf-file ()
(interactive)
(find-file (concat user-emacs-directory "config.org")))
#+end_src
Now let's define keybindings. To start, we'd like =M-o= to be available to us, so let's unbind it.
#+begin_src emacs-lisp
;Unbind face menu map
(define-key global-map (kbd "M-o") nil)
#+end_src
This creates an "open keymap", a bunch of keybindings we'll use to open basic applications and files.
This will be mapped to =M-o=, and things will be opened form this sub-menu.
We'll start it with a binding to open the conf file with =M-o o= (MOO!)
Setting of keybindings based on [[https://stackoverflow.com/questions/49853494/the-best-way-to-set-a-key-to-do-nothing][this]]
#+begin_src emacs-lisp
;We'll define a basic keymap and already load window-manip funcs
(defvar azos/global-minor-mode/open-keymap
(let ((map (make-sparse-keymap)))
(define-key map (kbd "o") 'azos/open-conf-file)
map)
"global keymap for opening stuff on azos")
#+end_src
At this stage a minor-mode-map is defined with keybindings, and an accompanying minor-mode is added.
#+begin_src emacs-lisp
(defvar azos/global-minor-mode/keymap
(let ((map (make-sparse-keymap)))
;Window movement and manipulation
(define-key map (kbd "M-h") 'windmove-left)
(define-key map (kbd "M-l") 'windmove-right)
(define-key map (kbd "M-k") 'windmove-up)
(define-key map (kbd "M-j") 'windmove-down)
(define-key map (kbd "M-<left>") 'windmove-left)
(define-key map (kbd "M-<right>") 'windmove-right)
(define-key map (kbd "M-<up>") 'windmove-up)
(define-key map (kbd "M-<down>") 'windmove-down)
(define-key map (kbd "M-d M-d") 'delete-window)
(define-key map (kbd "M-d D") 'kill-buffer-and-window)
(define-key map (kbd "M-\\") 'split-window-horizontally)
(define-key map (kbd "M-\-") 'split-window-vertically)
(define-key map (kbd "M-d R") (lambda () (interactive)
(set-window-width 85)))
(define-key map (kbd "M-o") azos/global-minor-mode/open-keymap)
map)
"azos/global-minor-mode keymap.")
(define-minor-mode azos/global-minor-mode
"A minor mode for azos global keymaps."
:init-value t
:lighter "azos"
:keymap azos/global-minor-mode/keymap)
(azos/global-minor-mode 1)
#+end_src
This keymap will be referenced many times during this document at relevant points.
Keymaps are included with relevant sections.
* EVIL mode
Using evil mode.
This section includes unbinding =C-w= (I honestly forget why).
This section binds keys for changing window size. Done here because can only do after evil loads.
Unbinding C-w taken from https://stackoverflow.com/questions/24988406/unbinding-evils-c-w-mappings
#+begin_src emacs-lisp
(setq evil-want-keybinding nil)
(use-package evil (use-package evil
:init :init
:ensure t
:config
(setq evil-want-C-i-jump nil) (setq evil-want-C-i-jump nil)
(evil-mode 1)) :config
(require 'evil )
(evil-mode 1)
:bind
(:map azos/global-minor-mode/keymap
("M-w h" . evil-window-decreace-width)
("M-w l" . evil-window-increase-width)
("M-w k" . evil-window-decrease-height)
("M-w j" . evil-window-increase-height))
)
#+end_src
Loading evil collection. Functions from this package will be referenced many times later in the configuration.
#+begin_src emacs-lisp
(use-package evil-collection
:config
(setq evil-collection-setup-minibuffer t)
)
#+end_src
Setting theme colors
#+begin_src emacs-lisp
(defvar azos/evil-color-normal "LightGoldenrod1")
(defvar azos/evil-color-emacs "LightBlue1")
(defvar azos/evil-color-insert "PaleGreen1")
(defvar azos/evil-color-replace "LightPink")
(defvar azos/evil-color-motion "LightCyan")
(defvar azos/evil-color-visual "LightGray")
(defvar azos/evil-color-operate "sandy brown")
#+end_src
* Undo tree
Loading =undo-tree= for undo/redo functionality with evil.
Redo taken from https://github.com/syl20bnr/spacemacs/issues/14036
#+begin_src emacs-lisp
(use-package undo-tree
:after evil
:config
(evil-set-undo-system 'undo-tree)
(setq undo-tree-history-directory-alist
(list (cons "." (concat user-emacs-directory "undo-tree"))))
(global-undo-tree-mode 1)
)
#+end_src
* IVY
Enabling IVY. Taken from [[https://github.com/abo-abo/swiper][their website]].
Using ivy, hydra, counsel.
#+begin_src emacs-lisp
(use-package ivy
:custom
(ivy-use-virtual-buffers t)
(enable-recursive-minibuffers t)
(ivy-count-format "(%d/%d) ")
:config
(ivy-mode 1)
)
(use-package ivy-hydra
:after ivy)
(use-package ivy-avy
:after ivy)
(use-package counsel
:after ivy
:bind
(:map azos/global-minor-mode/keymap
("M-i" . counsel-imenu)
("M-b" . counsel-switch-buffer)
("C-x C-f" . counsel-find-file))
(:map azos/global-minor-mode/open-keymap
("l" . counsel-linux-app))
)
#+end_src
Using swiper. Replacing evil search with swiper search.
#+begin_src emacs-lisp
(use-package swiper
:after ivy evil
:config
(setq evil-search-module 'swiper-isearch)
:bind
(:map azos/global-minor-mode/keymap
("C-s" . swiper-isearch))
)
#+end_src
Setting up keymaps
#+begin_src emacs-lisp
(evil-collection-ivy-setup)
#+end_src
* Projectile
Startup up projectile.
A config line here disables modeline display because I don't want my modeline to be cluttered.
Mapping modeline commands to =M-p= prefix. Also adding a shortcut to add project.
#+begin_src emacs-lisp
(use-package projectile
:config
(projectile-mode +1)
(setq projectile-mode-line-function (lambda () ""))
:bind
(:map projectile-command-map
("a" . projectile-add-known-project)
)
(:map azos/global-minor-mode/keymap
("M-p" . projectile-command-map))
)
#+end_src
Ivy for projectile:
Parts taken from [[https://emacs.stackexchange.com/questions/40787/display-corresponding-key-binding-of-command-during-m-x-completion][this post]] and [[https://emacs.stackexchange.com/questions/38841/counsel-m-x-always-shows][this post]] from StackOverflow.
Helps with many functions to use counsel's/ivy's autocomplete with projectile.
#+begin_src emacs-lisp
(use-package counsel-projectile
:after counsel projectile
:config
(counsel-projectile-mode +1)
(setq projectile-completion-system 'ivy)
;Making counsel start with empty regex
(when (commandp 'counsel-M-x)
(global-set-key [remap execute-extended-command] 'counsel-M-x))
(setcdr (assoc 'counsel-M-x ivy-initial-inputs-alist) "")
)
#+end_src
** Tramp
Ensuring tramp is loaded, and loading counsel-tramp for easy tramping.
#+begin_src emacs-lisp
(use-package tramp
:straight (:type built-in))
(use-package counsel-tramp)
#+end_src
* Assorted utility functions
Defining a function to copy filename.
#+begin_src emacs-lisp
(defun azos/copy-file-name () (interactive)
(let ((fpath buffer-file-name))
(if fpath (kill-new fpath) (message "No current file!"))))
#+end_src
Need to define this here so that other parts of code have access to it
#+begin_src emacs-lisp
(defun azos/font-candidate (&rest fonts)
"Return existing font which first match."
(cl-find-if (lambda (f) (find-font (font-spec :name f))) fonts))
#+end_src
#+begin_src emacs-lisp
(defun azos/re-seq (regexp string)
"Get a list of all regexp matches in a string"
(save-match-data
(let ((pos 0)
matches)
(while (string-match regexp string pos)
(push (match-string 0 string) matches)
(setq pos (match-end 0)))
matches)))
#+end_src
* Tie it up
#+begin_src emacs-lisp
(provide 'azos-emacs-base) (provide 'azos-emacs-base)
#+end_src #+end_src