Skip to content

Latest commit

 

History

History
562 lines (451 loc) · 15.9 KB

config.org

File metadata and controls

562 lines (451 loc) · 15.9 KB

My personal Emacs config

This is my configuration for Emacs, both on my Ubuntu PC, Arch-running-ex-chromebook and work Windows laptop. There are some differences between the configs for the different machines, so I have several versions being tangled from this config.

I would say this is fairly close to a vanilla Emacs. Once I get something working fairly well, I’m usually happy with it, and don’t feel the need to tinker anymore. Most of packages I only use with the most basic setup, because that’s fine for me. Some inspiration comes from David Wilson’s wonderful Emacs from scratch https://github.com/daviwil/emacs-from-scratch, developed live on his YouTube.

I decided to make a literate config file mostly because of the different versions I need for my different machines, and this makes it easier to keep track of them.

MELPA and USE-PACKAGE

Melpa and use-package for installing and handling packages

;; Enables basic packaging support
(require 'package)

;; MELPA
;; Adds the Melpa archive to the list of available repositories
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/")
	     '("gnu" . "https://elpa.gnu.org/packages/")
	     )

;; Initializes the package infrastructure
(package-initialize)

;; USE-PACKAGE
;; If we don't have the use-package package, we need to refresh contents and install it. The rest will be installed with it
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

MAGIT

For GIT straight from Emacs, because Magit is the best.

;; MAGIT
(use-package magit
  :ensure t)

ORG-BABEL

Mostly for shell, elisp and python.

;; ORG-BABEL
(org-babel-do-load-languages
 'org-babel-load-languages
 '(
   (python . t)
   (shell . t)
   (emacs-lisp . t)))

;; to syntax highlight code in babel and to remove the "Do you want to execute?" question
(setq org-confirm-babel-evaluate nil
      org-src-fontify-natively t
      org-src-tab-acts-natively t
      org-src-preserve-indentation t
      )
(setq python-indent-guess-indent-offset nil)
(setq python-indent-offset 4)

VERTICO (with ORDERLESS), MARGINALIA and EMBARK

VERTICO

Vertico is a completion framework. And also allows to write space in minibuffer, which doesn’t work in out-of-the-box Emacs.

;; VERTICO
(use-package vertico
  :ensure t
  :init
  (vertico-mode)
  :config
(setq enable-recursive-minibuffers t))

ORDERLESS

Allows for completion in any order.

;; ORDERLESS
(use-package orderless
  :ensure t
  :custom
  (completion-styles '(orderless basic))
  (completion-category-overrides '((file (styles basic partial-completion)))))

MARGINALIA

Adds useful information to the minibuffer for each of the options.

;; MARGINALIA
(use-package marginalia
  :ensure t
  :config
  (marginalia-mode))

EMBARK

Embark allows for a context menu, kind of like a right-click.

;; EMBARK
(use-package embark
  :ensure t
  :bind
  (("C-." . embark-act))         ;; pick some comfortable binding
  )

OX-HUGO

Ox-hugo is an interface with Hugo, a system for making static sites.

;; OX-HUGO
(use-package ox-hugo
  :ensure t
  :pin melpa
  :after ox
  )

LANGUAGETOOL

Interfacing with languagetool for spelling and style check. I only have this one on my home coputer.

(use-package languagetool
  :ensure t
  :defer t
  :commands (languagetool-check
             languagetool-clear-suggestions
             languagetool-correct-at-point
             languagetool-correct-buffer
             languagetool-set-language
             languagetool-server-mode
             languagetool-server-start
             languagetool-server-stop)
  :config
  (setq languagetool-java-arguments '("-Dfile.encoding=UTF-8")
        languagetool-console-command "~/.languagetool/languagetool-commandline.jar"
        languagetool-server-command "~/.languagetool/languagetool-server.jar"))

THEME

Changing to ef-themes from Protesilaos from modus themes.

;; THEME
(require 'ef-themes)

(load-theme 'ef-autumn :no-confirm)

(setq ef-themes-to-toggle '(ef-autumn ef-cyprus))

(define-key global-map (kbd "<f5>") #'ef-themes-toggle)

EXWM

On my chromearch, I only have a very very barebones installation of Arch, because the thing is a brick. So Emacs also doubles as a “desktop”. I obviously use EXWM for that.

I mostly followed the configuration example https://github.com/ch11ng/exwm/wiki/Configuration-Example, with some small changes. Like adding a system tray.

;; EXWM

;; Disable menu-bar, tool-bar and scroll-bar to increase the usable space.
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
;; Also shrink fringes to 1 pixel.
(fringe-mode 1)

;; Turn on `display-time-mode' if you don't use an external bar.
(setq display-time-default-load-average nil)
(display-time-mode t)

;;;; Below are configurations for EXWM.

;; Load EXWM.
(require 'exwm)

;; System tray
(require 'exwm-systemtray)
(exwm-systemtray-enable)
;;(setq exwm-systemtray-height 30)

;; Set the initial number of workspaces (they can also be created later).
(setq exwm-workspace-number 4)

;; All buffers created in EXWM mode are named "*EXWM*". You may want to
;; change it in `exwm-update-class-hook' and `exwm-update-title-hook', which
;; are run when a new X window class name or title is available.  Here's
;; some advice on this topic:
;; + Always use `exwm-workspace-rename-buffer` to avoid naming conflict.
;; + For applications with multiple windows (e.g. GIMP), the class names of
;    all windows are probably the same.  Using window titles for them makes
;;   more sense.
;; In the following example, we use class names for all windows except for
;; Java applications and GIMP.
(add-hook 'exwm-update-class-hook
          (lambda ()
            (unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
                        (string= "gimp" exwm-instance-name))
              (exwm-workspace-rename-buffer exwm-class-name))))
(add-hook 'exwm-update-title-hook
          (lambda ()
            (when (or (not exwm-instance-name)
                      (string-prefix-p "sun-awt-X11-" exwm-instance-name)
                      (string= "gimp" exwm-instance-name))
              (exwm-workspace-rename-buffer exwm-title))))

;; Global keybindings can be defined with `exwm-input-global-keys'.
;; Here are a few examples:
(setq exwm-input-global-keys
      `(
        ;; Bind "s-r" to exit char-mode and fullscreen mode.
        (,(kbd "C-c R") . exwm-reset)
	;; Bind "C-c C-k" to enter char-mode
	(,(kbd "C-c C-k") . exwm-input-release-keyboard)
        ;; Bind "s-&" to launch applications ('M-&' also works if the output
        ;; buffer does not bother you).
        (,(kbd "C-c y") . (lambda (command)
		     (interactive (list (read-shell-command "$ ")))
		     (start-process-shell-command command nil command)))
	))

;; The following example demonstrates how to use simulation keys to mimic
;; the behavior of Emacs.  The value of `exwm-input-simulation-keys` is a
;; list of cons cells (SRC . DEST), where SRC is the key sequence you press
;; and DEST is what EXWM actually sends to application.  Note that both SRC
;; and DEST should be key sequences (vector or string).
(setq exwm-input-simulation-keys
      '(
        ;; movement
        ([?\C-b] . [left])
        ([?\M-b] . [C-left])
        ([?\C-f] . [right])
        ([?\M-f] . [C-right])
        ([?\C-p] . [up])
        ([?\C-n] . [down])
        ([?\C-a] . [home])
        ([?\C-e] . [end])
        ([?\M-v] . [prior])
        ([?\C-v] . [next])
        ([?\C-d] . [delete])
        ([?\C-k] . [S-end delete])
        ;; cut/paste.
        ([?\C-w] . [?\C-x])
        ([?\M-w] . [?\C-c])
        ([?\C-y] . [?\C-v])
        ;; search
        ([?\C-s] . [?\C-f])))

;; Do not forget to enable EXWM. It will start by itself when things are
;; ready.  You can put it _anywhere_ in your configuration.
(exwm-enable)


(start-process-shell-command "cbatticon" nil "cbatticon")

Customizing

A few things I always want

Various settings that I always want. (- Start citar-org-roam.)

;; ===================================
;; Basic Customization
;; ===================================

;; Set org-image width to nil, so it can be set manually
(setq org-image-actual-width nil)

;; Enable word wrap
(add-hook 'text-mode-hook 'turn-on-visual-line-mode)

;; Set visible bell instead of sound
(setq visible-bell 1)

;; Auto save buffer if idled for 2 seconds.
(setq auto-save-timeout 2)
(auto-save-visited-mode +1)

;; Watch and reload the file changed on the disk.
(global-auto-revert-mode +1)
(setq auto-revert-remote-files t)

;; Delete the selected text first before editing.
(delete-selection-mode +1)

;; Disable splash screen
(setq inhibit-startup-message t)

;; Smooth Scrolling
(setq scroll-conservatively 10000
      scroll-step 1)

MIXED-PITCH

Using mixed-pitch mode (from Ricing org-mode), so I can have code and normal text in one file and the text looks nicer. But I am not using my own fonts here, just the modus-themes defaults.

;; MIXED-PITCH
(use-package mixed-pitch
  :ensure t
  :hook
  (text-mode . mixed-pitch-mode)
  ;;:config
  ;;(set-face-attribute 'default nil :font "DejaVu Sans Mono" :height 130)
  ;;(set-face-attribute 'fixed-pitch nil :font "DejaVu Sans Mono")
  ;;(set-face-attribute 'variable-pitch nil :font "DejaVu Sans")
  )

Extra functions

AUTO PUSH and PULL for magit repos

#!/bin/bash

# Function to pull changes for a given repository
function pull_changes {
    local repo_path=$1

    if [[ -z "$repo_path" ]]; then
        echo "Repository path is required."
        return 1
    fi

    if [[ ! -d "$repo_path" ]]; then
        echo "Directory $repo_path does not exist."
        return 1
    fi

    # Navigate to the Git repository
    cd "$repo_path" || return 1

    # Get the current branch
    currentBranch=$(git symbolic-ref --short HEAD)

    if [[ -z "$currentBranch" ]]; then
        echo "Failed to determine the current branch in $repo_path."
        return 1
    fi

    echo "Current branch in $repo_path: $currentBranch"

    # Pull changes from the remote repository
    echo "Pulling changes for branch $currentBranch..."
    git pull origin "$currentBranch"

}

# List of repositories
repos=(
    "/home/nori/Documents/noriparelius"
    "/home/nori/.emacs.d"
)

# Iterate over the list and call the function for each repository
for repo in "${repos[@]}"; do
    pull_changes "$repo"
done
read -p "Press enter to continue"
#!/bin/bash

# Function to commit and push changes for a given repository
function commit_and_push {
    local repo_path=$1

    if [[ -z "$repo_path" ]]; then
        echo "Repository path is required."
        return 1
    fi

    if [[ ! -d "$repo_path" ]]; then
        echo "Directory $repo_path does not exist."
        return 1
    fi

    # Navigate to the Git repository
    cd "$repo_path" || return 1

    # Get the current branch
    currentBranch=$(git symbolic-ref --short HEAD)

    if [[ -z "$currentBranch" ]]; then
        echo "Failed to determine the current branch in $repo_path."
        return 1
    fi
    
    echo "Current branch in $repo_path: $currentBranch"

    # Check for changes
    if [[ -n $(git status --porcelain) ]]; then
        echo "Changes detected in $repo_path, staging changes..."
        git add -A

        # Get current date and time
        currentDate=$(date +'%Y-%m-%d')
        currentTime=$(date +'%H-%M')

        # Commit changes with a message
        echo "Committing changes..."
        git commit -m "Automated commit on $currentDate at $currentTime"

    else
        echo "No changes to commit in $repo_path."
    fi
    # Push changes to the remote repository
    echo "Pushing changes to $currentBranch..."
    git push origin "$currentBranch"

}

# List of repositories
repos=(
    "/home/nori/Documents/noriparelius"

)

# Iterate over the list and call the function for each repository
for repo in "${repos[@]}"; do
    commit_and_push "$repo"
done

read -p "Press enter to continue"
(defun nori-autopull ()
  "Run my git autopull Bash script."
  (interactive)
  (shell-command "bash /home/nori/.emacs.d/autopull.sh"))

(defun nori-autopush ()
  "Run my git autocommitpush Bash script."
  (interactive)
  (shell-command "bash /home/nori/.emacs.d/autocommitpush.sh"))


(add-to-list 'magit-no-confirm 'stage-all-changes) ;; not to be asked to stage all changes, so I can have the next hook

Home config

<<melpa>>
<<magit>>
<<org-babel>>
<<vertico>>
<<orderless>>
<<marginalia>>
<<embark>>
<<ox-hugo>>
<<languagetool>>
<<theme>>

<<custom1>>
<<mixed-pitch>>
<<autopullpush>> 

;; Enable line numbers globally
;;(global-linum-mode t) deprecated since Emacs 29 https://emacs.stackexchange.com/questions/78369/what-to-use-instead-of-linum-mode-in-emacs-29
(global-display-line-numbers-mode t)

(add-hook 'kill-emacs-hook #'nori-autopush) ;; to run it on exit
(nori-autopull)
;; User-Defined init.el ends here

Work config

<<melpa>>
;;<<magit>> works terribly on windows
<<org-babel>>
<<vertico>>
<<orderless>>
<<marginalia>>
<<embark>>
<<ox-hugo>>
<<languagetool>>
<<theme>>

<<custom1>>
<<mixed-pitch>>

(defun nori-autopull-work ()
  "Run my git autopull Batch file."
  (interactive)
  (compile "C:/Users/ELPAR/AppData/Roaming/.emacs.d/autopull-work.bat"))

(defun nori-autopush-work ()
  "Run my git autocommitpush Batch file."
  (interactive)
  (compile "C:/Users/ELPAR/AppData/Roaming/.emacs.d/autopush-work.bat"))

;;(add-hook 'kill-emacs-hook #'nori-autopush-work) ;; doesn't work, it's async
(nori-autopull-work)

;; Enable line numbers globally
;;(global-linum-mode t) deprecated since Emacs 29 https://emacs.stackexchange.com/questions/78369/what-to-use-instead-of-linum-mode-in-emacs-29
(global-display-line-numbers-mode t)

(setq package-install-upgrade-built-in t)

;; User-Defined init.el ends here

Init.el file

The only thing happening here is chosing which config to load, depending on which machine I am on. I figured the easiest was to distinguish them by the name of the computer.

(cond
 ((equal system-name "NoriPCdebian")
  (load "~/.emacs.d/home.el"))
 ((equal system-name "MU386U")
  (load "C:/Users/ELPAR/AppData/Roaming/.emacs.d/work.el")))