Skip to content

M-Taan/emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emacs Configuration

This file contains all of my emacs configuration in a literate style using org-babel.

In addition to this file the configuration are split into 2 more file:

  1. ~/.emacs.d/early-init.el
  2. ~/.emacs.d/custom.el: To avoid polluting my ~/.emacs.d/init.el with autogenerated settings from Custom

Package Setup

Initialize the package archive

(require 'package)

(setq package-archives
'(("melpa" . "https://melpa.org/packages/")
  ("org" . "https://orgmode.org/elpa/")
  ("elpa" . "https://elpa.gnu.org/packages/")))

Base Configuration

Custom

Have a dedicated file for the Custom settings

(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)

Font

(add-to-list 'default-frame-alist
             '(font . "DejaVu Sans Mono-12"))

Miscellaneous Settings

Some random settings that I find helpful

Clutter-less Emacs UI

(fset 'yes-or-no-p 'y-or-n-p)
(setq create-lockfiles nil)
(menu-bar-mode 0)
(tool-bar-mode 0)
(scroll-bar-mode -1)
(blink-cursor-mode 0)
(display-battery-mode 1)
(setq-default cursor-type 'bar)
(setq ring-bell-function 'ignore)

Backups and saving

(setq backup-directory-alist `(("." . ,(concat user-emacs-directory
                                               "backups"))))
(setq auto-save-default nil)

Highlighting and quick editing

(global-hl-line-mode 1)
(subword-mode 1)
(electric-indent-mode +1)
(electric-pair-mode t)
(delete-selection-mode 1)
(global-display-line-numbers-mode 1)
(setq display-line-numbers-type 'relative) 
(setq scroll-margin 10)

Grep

Automatically switch to the grep buffer

(add-hook 'grep-mode-hook
          #'(lambda ()
              (switch-to-buffer-other-window "*grep*")))

Tmux

Opening tmux sessions from emacs at point or at the current directory It mainly utilizes projectile

(defun tmux-session-exists? (session)
  (not (string-empty-p (shell-command-to-string (concat "tmux list-sessions 2>&1 | grep " session)))))

(defun open-tmux-session-current-directory ()
  (interactive)
  (let* ((name (replace-regexp-in-string "\\." "" (projectile-project-name)))
         (attach-session? (tmux-session-exists? name)))
    (if attach-session?
        (start-process-shell-command "tmux" nil (concat "alacritty -e tmux attach -t " name))
      (start-process-shell-command "tmux" nil (concat "alacritty -e tmux new-session -s " name)))))

(defun open-tmux-session-current-project-root ()
  (interactive)
  (let* ((name (replace-regexp-in-string "\\." "" (projectile-project-name)))
         (attach-session? (tmux-session-exists? name)))
    (if attach-session?
        (start-process-shell-command "tmux" nil (concat "alacritty -e tmux attach -t " name))
      (start-process-shell-command "tmux" nil (concat "alacritty -e tmux new-session -s " name " -c " (projectile-project-root))))))

Packages

Evil

(use-package evil
  :ensure t
  :custom
  (evil-undo-system 'undo-redo)
  (evil-want-C-u-scroll t)
  (evil-want-keybinding nil)
  :config
  (evil-mode 1)
  (evil-set-leader nil (kbd "C-SPC"))
  (evil-set-leader 'normal (kbd "SPC")))

(use-package evil-collection
  :ensure t
  :after evil
  :config
  (evil-collection-init))
Keymaps
(evil-define-key 'normal lsp-mode-map (kbd "<leader>l") lsp-command-map)
(evil-define-key nil projectile-mode-map (kbd "<leader>p") projectile-command-map)

(evil-define-key nil  'global
  (kbd "<leader>sb")  'counsel-switch-buffer
  (kbd "<leader>tc")  'open-tmux-session-current-directory
  (kbd "<leader>tr")  'open-tmux-session-current-project-root
  (kbd "<leader>rg")  'counsel-rg
  (kbd "<leader>fzf") 'counsel-fzf
  (kbd "<leader>csb") 'counsel-search
  (kbd "<leader>ff")  'counsel-find-file)

Gptel

(use-package gptel
  :ensure t
  :custom
  (gptel-prompt-prefix-alist
   '((markdown-mode . "# ")
     (org-mode . "")
     (text-mode . "# ")))
  :config
  (setq
   gptel-model "gemma2:2b"
   gptel-backend (gptel-make-ollama "Ollama"
                   :host "localhost:11434"
                   :stream t
                   :models '("gemma2:2b"))
   gptel-default-mode 'org-mode))        

Magit

(use-package magit
  :ensure t)

UI

For themes, doom-themes is the way to go for me accompanied with doom-modeline

(use-package doom-themes
:ensure t
:config
(setq doom-themes-enable-bold t
      doom-themes-enable-italic t)
(load-theme 'doom-tokyo-night t)
(set-face-foreground 'line-number-current-line "#ff9e64"))

(use-package doom-modeline
:ensure t
:init
(doom-modeline-mode 1)
:config
(setq doom-modeline-battery t
      doom-modeline-icon t
      doom-modeline-major-mode-icon t
      doom-modeline-major-mode-color-icon t))

Doom modelines uses nerd-icons so I need that tool

(use-package nerd-icons
  :ensure t)

Sorting and filtering

(use-package prescient
  :ensure t
  :config
  (prescient-persist-mode 1))

Navigation

Ivy and counsel paired with ivy-prescient for good fuzzy finding and sorting

(use-package ivy
  :ensure t
  :init
  (ivy-mode 1)
  (setq projectile-completion-system 'ivy)
  (setq ivy-use-virtual-buffers t))

(use-package counsel
  :ensure t
  :after ivy
  :init (counsel-mode 1))

(use-package ivy-prescient
  :ensure t
  :after (ivy counsel)
  :init (ivy-prescient-mode 1))

Projectile, well it’s projectile

(use-package projectile
  :ensure t
  :init (projectile-mode +1)) 

Treesitter

Behold the beauty of treesitter

(use-package treesit
  :custom
  (treesit-font-lock-level 4)
  (treesit-extra-load-path `(,(concat (getenv "HOME") "/.emacs.d/dist/"))))

Editing

company and company-prescient for code completion

(use-package company
  :ensure t
  :init (global-company-mode))

(use-package company-prescient
  :ensure t
  :after company
  :init (company-prescient-mode 1))

Snippets

(use-package yasnippet
  :ensure t
  :config
  (yas-global-mode 1))

Eldoc

(use-package eldoc
  :ensure t
  :hook
  (emacs-lisp-mode . turn-on-eldoc-mode)
  (lisp-interaction-mode . turn-on-eldoc-mode)
  (ielm-mode . turn-on-eldoc-mode))

Paredit

(use-package paredit
  :ensure t
  :init
  (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)
  :config
  (show-paren-mode t))

Stumpwm

LONG LIVE THE ONE AND TRUE WINDOW MANAGER

(use-package stumpwm-mode
  :ensure t)

Web

Mainly for html files

(use-package tagedit				       
  :ensure t)

(defun web-mode-init-hook ()			       
  "Hook for indentation in Web mode"		       
  (setq web-mode-markup-indent-offset 2)	       
  (setq web-mode-code-indent-offset 2)	       
  (setq web-mode-css-indent-offset 2))

(use-package web-mode			       
  :ensure t					       
  :hook					       
  (web-mode . web-mode-init-hook)		       
  :mode ("\\.html?\\'")			       
  :config					       
  (setq web-mode-enable-current-column-highlight t  
        web-mode-enable-current-element-highlight t 
        web-mode-enable-auto-closing t	       
        web-mode-enable-auto-pairing t))	       

Typescript

Using emacs-29 built-in typescript modes

(use-package add-node-modules-path		       
  :ensure t)					       

(use-package prettier-js			       
  :ensure t)					       

(defun prettier-js-hook ()			       
  (when (s-matches?				       
         (rx (or ".js" ".ts" ".jsx" ".tsx") eos)    
         (buffer-file-name))			       
    (add-node-modules-path)			       
    (prettier-js-mode)))			       

(use-package typescript-ts-mode
  :ensure t
  :hook
  (typescript-ts-mode . prettier-js-hook)
  (tsx-ts-mode . prettier-js-hook)
  :mode (("\\.ts\\'" . typescript-ts-mode))
  :mode (("\\.tsx\\'" . tsx-ts-mode)))

Clojure

THE ONE AND TRUE PROGRAMMING LANGUAGE

clojure-mode paired with cider

(use-package clojure-mode
  :ensure t
  :after paredit
  :mode (("\\.edn$" . clojure-mode)
         ("\\.boot$" . clojure-mode)
         ("\\.cljs.*$" . clojurescript-mode)
         ("\\.cljc.*$" . clojurec-mode)
         ("lein-env" . enh-ruby-mode)
         ("\\.boot\\'" . clojure-mode))
  :hook
  (clojure-mode . enable-paredit-mode)
  :custom
  (cider-repl-display-help-banner nil))

(use-package cider
  :ensure t
  :after (clojure-mode paredit eldoc)
  :hook
  (cider-mode . eldoc-mode)
  (cider-repl-mode . paredit-mode)
  (clojure-mode . cider-mode)
  (cider-repl-mode . paredit-mode)
  :config
  (setq cider-repl-pop-to-buffer-on-connect t
        cider-show-error-buffer t
        cider-auto-select-error-buffer t
        cider-repl-history-file "~/.emacs.d/cider-history"
        cider-repl-wrap-history t))

Zig

zig-mode

(use-package zig-mode
  :ensure t
  :mode ("\\.zig$" . zig-mode))

LSP

(use-package lsp-mode
  :ensure t
  :commands lsp lsp-deferred
  :hook
  (clojure-mode . lsp-deferred)
  (clojurescript-mode . lsp-deferred)
  (clojurec-mode . lsp-deferred)
  (typescript-ts-mode . lsp-deferred)
  (tsx-ts-mode . lsp-deferred)
  (python-mode . lsp-deferred)
  (zig-mode . lsp-deferred)
  :config
  (setq lsp-headerline-breadcrumb-enable nil
        lsp-enable-indentation nil
        lsp-use-plists t
        lsp-modeline-code-actions-enable nil
        lsp-modeline-diagnostics-enable nil
        lsp-modeline-diagnostics-mode nil
        lsp-zig-zls-executable (concat user-emacs-directory "/zig-lsp/zls/zig-out/bin/zls")
        lsp-completion-mode nil))

(use-package lsp-ivy
  :ensure t)

(use-package lsp-ui
  :ensure t
  :hook (lsp-mode . lsp-ui-mode)
  :config
  (set-face-attribute 'lsp-ui-sideline-global nil
                      :background "black")
  (setq lsp-ui-doc-enable nil)
  :custom
  (lsp-ui-sideline-show-diagnostics t)
  (lsp-ui-doc-position 'top))

(use-package flycheck
  :ensure t)

Org

(defun org-mode-init-hook ()
  (org-indent-mode)
  (visual-line-mode 1))

(use-package org
  :ensure t
  :bind
  ("C-c a" . org-agenda)
  :hook
  (org-mode . org-mode-init-hook)
  (org-agenda-mode . org-mode-init-hook)
  :config  
  (setq org-todo-keywords '((type "TODO(t)" "PROJ(p)" "|" "DONE(d)")))
  (setq org-agenda-files '("~/Dropbox/org/work.org"
                           "~/Dropbox/org/personal.org"
                           "~/Dropbox/org/calendar.org"))
  (setq org-agenda-timegrid-use-ampm t)
  (setq org-agenda-start-with-log-mode t)
  (setq org-log-done t)
  (setq org-log-into-drawer t)
  (setq org-ellipsis ""))

org-bullets for nicer bullet points

(use-package org-bullets
  :ensure t
  :after org
  :hook (org-mode . org-bullets-mode)
  :custom
  (org-bullets-bullet-list '("" "" "" "" "" "" "")))

org-gcal to sync the agenda with google calendar

(use-package org-gcal
  :ensure t
  :after org
  :init
  (setq org-gcal-client-id (getenv "EMACS_GOOGLE_CALENDER_CLIENT_ID")
        org-gcal-client-secret (getenv "EMACS_GOOGLE_CALENDER_SECRET_ID")
        org-gcal-fetch-file-alist `((,(getenv "EMACS_GOOGLE_CALENDAR_EMAIL_1") .  "~/Dropbox/org/calendar.org")))
  (setq plstore-cache-passphrase-for-symmetric-encryption t))

Custom org flow

(defconst available-targets '("work" "personal"))

(defun mtaan/current-day-heading ()
  (apply 'format "Date: %s/%s/%s" (calendar-current-date)))

(defun mtaan/get-next-seven-days ()
  (cl-loop for i from 1 to 7
           collect (apply 'format "Date: %s/%s/%s" (calendar-current-date i))))

(defun mtaan/org-add-new-day (target day)
  (when (or (string-empty-p target)
            (not (member target available-targets)))
    (error "Target is not valid"))
  (find-file (concat "~/Dropbox/org/" target ".org"))
  (let* ((heading-exists? (org-find-exact-headline-in-buffer day)))
    (if heading-exists?
        (message "This day is already logged")
      (progn
        (goto-char (point-min))
        (org-insert-heading-respect-content)
        (insert day)))))

(defun mtaan/org-add-new-project-with-day (proj day)
  "By default this will use the work file, maybe later it could be generalized.
   It will also assume that I'm adding a proj under the same day"
  (when (string-empty-p proj)
    (error "Project name shouldn't be empty"))
  (find-file "~/Dropbox/org/work.org")
  (let* ((proj-subheading (concat "PROJ " (capitalize proj)))
         (heading (org-find-exact-headline-in-buffer day nil 't)))
    (unless heading
      (error "This day is not logged"))
    (goto-char heading)
    (end-of-line)
    (org-insert-subheading nil)
    (insert proj-subheading)
    (org-set-property "ID" (concat day " - " proj-subheading))))

(defun mtaan/org-add-new-todo-under-proj-with-day (proj day)
  (when (string-empty-p proj)
    (error "Project name shouldn't be empty"))
  (find-file "~/Dropbox/org/work.org")
  (let* ((proj-subheading (concat "PROJ " (capitalize proj)))
         (heading (org-find-exact-headline-in-buffer day nil 't)))
    (unless heading
      (error "Current day is not logged"))
    (org-id-goto (concat day " - " proj-subheading))
    (end-of-line)
    (org-insert-heading-respect-content)
    (org-demote)
    (insert "TODO ")))

(defun mtaan/org-add-new-day-other-day (target day)
  (interactive (list
                (completing-read "Available targets: " available-targets)
                (completing-read "Available Days: " (mtaan/get-next-seven-days))))
  (mtaan/org-add-new-day target day))

(defun mtaan/org-add-new-project-other-day (proj day)
  (interactive (list
                (read-string "Project Name: ")
                (completing-read "Available days: "
                                 (mtaan/get-next-seven-days))))
  (mtaan/org-add-new-project-with-day proj day))

(defun mtaan/org-add-new-todo-under-proj-other-day (proj day)
  (interactive (list
                (read-string "Project Name: ")
                (completing-read "Available days: "
                                 (mtaan/get-next-seven-days))))
  (mtaan/org-add-new-todo-under-proj-with-day proj day))

(defun mtaan/org-add-current-day (target)
  (interactive (list (completing-read "Available targets: " available-targets)))
  (mtaan/org-add-new-day target (mtaan/current-day-heading)))

(defun mtaan/org-add-new-project-today (proj)
  (interactive "sProject Name: ")
  (mtaan/org-add-new-project-with-day proj (mtaan/current-day-heading)))

(defun mtaan/org-add-new-todo-under-proj-today (proj)
  (interactive "sProject Name: ")
  (mtaan/org-add-new-todo-under-proj-with-day proj (mtaan/current-day-heading)))

About

Personal emacs configurations.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published