diff --git a/airootfs/etc/skel/.config/emacs/init.el b/airootfs/etc/skel/.config/emacs/init.el new file mode 100644 index 000000000..fe1939c44 --- /dev/null +++ b/airootfs/etc/skel/.config/emacs/init.el @@ -0,0 +1 @@ +(org-babel-load-file (expand-file-name "stratmacs.org" user-emacs-directory)) diff --git a/airootfs/etc/skel/.config/emacs/logo.jpeg b/airootfs/etc/skel/.config/emacs/logo.jpeg new file mode 100644 index 000000000..bd47e5c85 Binary files /dev/null and b/airootfs/etc/skel/.config/emacs/logo.jpeg differ diff --git a/airootfs/etc/skel/.config/emacs/logo.png b/airootfs/etc/skel/.config/emacs/logo.png new file mode 100644 index 000000000..bd47e5c85 Binary files /dev/null and b/airootfs/etc/skel/.config/emacs/logo.png differ diff --git a/airootfs/etc/skel/.config/emacs/stratmacs.org b/airootfs/etc/skel/.config/emacs/stratmacs.org new file mode 100644 index 000000000..c0a45c56f --- /dev/null +++ b/airootfs/etc/skel/.config/emacs/stratmacs.org @@ -0,0 +1,951 @@ +#+title: Stratmacs +#+author: ZeStig +#+description: Emacs config for StratOS +# #+STARTUP: showeverything +#+OPTIONS: toc:1 +* Package configuration +This section sets up the package archives and installs the use-package package, which is a declarative package management system for Emacs. +#+begin_src emacs-lisp +(require 'package) +(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) + +(unless (package-installed-p 'use-package) (package-install 'use-package)) ; install use-package with package.el +(require 'use-package-ensure) ; ensure that it installs automatically +(require 'use-package) +(setq package-enable-at-startup nil + use-package-always-ensure t + package--init-file-ensured t) +#+END_SRC + +* Evil mode +For the Vim users out there. +#+begin_src emacs-lisp +(use-package evil + :init ;; tweak evil's configuration before loading it + (setq evil-want-keybinding nil) + (evil-mode 1) + (evil-set-undo-system 'undo-tree) + :config + (evil-define-key 'normal org-mode-map (kbd "") #'org-cycle) + (evil-define-key 'normal org-mode-map (kbd "RET") 'org-enter-maybe-execute-code)) +(use-package evil-collection + :after evil + :ensure t + :config + (evil-collection-init)) +(require 'evil-vars) +(use-package evil-nerd-commenter) +#+end_src + +* Fonts +Font configuration. Install [[https://archlinux.org/packages/extra/any/ttf-jetbrains-mono-nerd/][JetBrains Mono Nerd]] on Arch and [[https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/data/fonts/nerdfonts/default.nix][NerdFonts]] on NixOS. +#+begin_src emacs-lisp +(set-face-attribute 'default nil + :font "JetBrainsMono NF 14" + :weight 'medium) +(set-face-attribute 'variable-pitch nil + :font "JetBrainsMono NF 14" + :weight 'medium) +(set-face-attribute 'fixed-pitch nil + :font "JetBrainsMono NF 14" + :weight 'medium) +(add-to-list 'default-frame-alist '(font . "JetBrainsMono NF 14")) +(set-face-attribute 'font-lock-comment-face nil + :slant 'italic) +(set-face-attribute 'font-lock-keyword-face nil + :slant 'italic) +(set-face-attribute 'font-lock-function-name-face nil + :slant 'italic) +(set-face-attribute 'font-lock-variable-name-face nil + :slant 'italic) +#+end_src + +* Ligatures +This configures ligatures in Emacs. Note that the font configured in this configuration, JetBrainsMono NF, has great support for ligatures. + +#+begin_src emacs-lisp +(use-package ligature + :config + ;; Enable the "www" ligature in every possible major mode + (ligature-set-ligatures 't '("www")) + ;; Enable traditional ligature support in eww-mode, if the + ;; `variable-pitch' face supports it + (ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi")) + ;; Enable all Cascadia Code ligatures in programming modes + (ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "" "---" "-<<" + "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->" + "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "" "###" "#_(" "..<" + "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~=" + "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|" + "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:" + ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:" + "<$" "<=" "<>" "<-" "<<" "<+" "" "++" "?:" + "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)" + "\\\\" "://")) + ;; Enables ligature checks globally in all buffers. You can also do it + ;; per mode with `ligature-mode'. + (global-ligature-mode t)) +#+end_src + +* Icons +~All-the-icons~ is an icon set that can be used with dashboard, dired, ibuffer and other Emacs programs. +#+begin_src emacs-lisp +(use-package all-the-icons + :ensure t + :if (display-graphic-p)) + +(use-package all-the-icons-dired + :hook (dired-mode . (lambda () (all-the-icons-dired-mode t)))) + +(use-package all-the-icons-completion + :after + (marginalia all-the-icons) + :hook + (marginalia-mode . all-the-icons-completion-marginalia-setup) + :init + (all-the-icons-completion-mode)) + +(all-the-icons-completion-mode) +#+end_src + +* Doom settings +Themes and configuration ported from [[https://github.com/doomemacs/doomemacs][Doom Emacs]]. +#+begin_src emacs-lisp +(use-package doom-themes + :ensure t) + +(setq doom-themes-enable-bold t + doom-themes-enable-italic t) +(load-theme 'doom-tokyo-night t) +(setq custom-safe-themes t) +(doom-themes-org-config) + +(use-package doom-modeline + :init + (setq mode-line-format nil) ;; disable non-Doom modeline, the vanilla modeline for ALL buffers + (doom-modeline-mode 1) + :config + (setq doom-modeline-icon t + ;; doom-modeline-minor-modes t ;; display all the minor modes (like vanilla modeline) + doom-modeline-major-mode-icon t + doom-modeline-major-mode-color-icon t + doom-modeline-modal-modern-icon nil ;; remove N,V,I,E from buffer mode icons + doom-modeline-enable-word-count t + doom-modeline-buffer-encoding nil + doom-modeline-persp-icon t + doom-modeline-persp-name t + doom-modeline-height 25)) +#+end_src + +* UI settings +User interface and dashboard settings. Modify these to change the way Stratmacs looks. +#+begin_src emacs-lisp + +(line-number-mode -1) +(tool-bar-mode -1) +(tab-bar-mode -1) +(menu-bar-mode -1) +(scroll-bar-mode -1) ;; PGTK-only +(electric-indent-mode t) +(delete-selection-mode 1) +(buffer-face-mode 1) ; so that different fonts can be used on different buffers if needed +;; (set-frame-parameter (selected-frame) 'alpha '(95 95)) +(setq echo-keystrokes 0.02) +;; (global-visual-line-mode t) ; disable visual line mode +(setq-default truncate-lines t) + +(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-hl-change ((t (:background "#7aa2f7")))) + '(diff-hl-delete ((t (:background "#bb9af7")))) + '(diff-hl-insert ((t (:background "#1a1b26")))) + '(eros-eval-overlay-face ((t (:background "#7aa2f7" :foreground "#1a1b26")))) + '(eros-result-overlay-face ((t (:foreground "#1e1f2f" :background "#7aa2f7")))) + '(org-level-1 ((t (:inherit outline-1 :height 1.4)))) + '(org-level-2 ((t (:inherit outline-2 :height 1.3)))) + '(org-level-3 ((t (:inherit outline-3 :height 1.2)))) + '(org-level-4 ((t (:inherit outline-4 :height 1.1)))) + '(org-level-5 ((t (:inherit outline-5 :height 1.0)))) + '(org-level-6 ((t (:inherit outline-5 :height 1.0)))) + '(org-level-7 ((t (:inherit outline-5 :height 1.0))))) +#+end_src + +* Dashboard +#+begin_src emacs-lisp +(use-package dashboard + :ensure t + :init + (setq initial-buffer-choice 'dashboard-open) + (setq dashboard-set-heading-icons t) + (setq dashboard-icon-type 'all-the-icons) + (setq dashboard-set-file-icons t) + (setq dashboard-banner-logo-title "StratOS' Emacs distribution") + ;; (setq dashboard-banner-logo-title "Find file (SPC .)\nOpen recent files (SPC f r)") + ;;(setq dashboard-startup-banner 'logo) ;; use standard emacs logo as banner + (setq dashboard-startup-banner "~/.config/emacs/logo.png") ;; use custom image as banner + (setq dashboard-center-content t) ;; set to 't' for centered content; nil is the default + (setq dashboard-items '((recents . 5))) + :config + (dashboard-setup-startup-hook) + (general-define-key + :keymaps 'dashboard-mode-map + :states '(normal) + "r" '(dashboard-jump-to-recents :wk "Jump to Recents"))) +#+end_src + +* Smooth scrolling +Smooth scrolling settings - /requires/ Emacs to be built with =PGTK= support. +#+begin_src emacs-lisp +(require 'pixel-scroll) +;; (setq scroll-margin 1 +;; scroll-step 5000 +;; scroll-conservatively 101 +;; redisplay-dont-pause t +;; scroll-preserve-screen-position 1 +;; pixel-scroll-precision-use-momentum 1) +(setq scroll-margin 1 + scroll-step 5000 + scroll-conservatively 100 + scroll-preserve-screen-position 1 + pixel-scroll-precision-use-momentum t) +(pixel-scroll-precision-mode t) +(pixel-scroll-mode t) +#+end_src + +* Company-mode +Complete-anything (aka Company or Company-mode) is a completion mechanism for Emacs. +#+begin_src emacs-lisp +(use-package company + :custom + (setq company-idle-delay 0 + company-minimum-prefix-length 2)) +;; (use-package company-box +;; :after company +;; :hook (company-mode . company-box-mode)) + +(add-hook 'prog-mode-hook 'global-company-mode) +(add-hook 'prog-mode-hook 'company-tng-mode) +(add-hook 'prog-mode-hook 'electric-pair-mode) +;; (add-to-list 'company-backends 'company-capf) +(add-hook 'org-src-mode-hook 'company-mode) +#+end_src + +* Vertico,marginalia etc +*Core* completion/menu engine for Emacs. +#+begin_src emacs-lisp +(use-package vertico +:init +(vertico-mode) +:config +(setq vertico-count 20 + vertico-resize t + vertico-cycle t + completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion)))) +:bind (:map vertico-map + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word)) +;; Tidy shadowed file names +:hook (rfn-eshadow-update-overlay . vertico-directory-tidy)) + +(defvar +vertico-company-completion-styles '(basic partial-completion orderless) + "Completion styles for company to use. + +The completion/vertico module uses the orderless completion style by default, +but this returns too broad a candidate set for company completion. This variable +overrides `completion-styles' during company completion sessions.") +#+end_src + +* Quickrun, marginalia +Completion-related changes go here. +#+begin_src emacs-lisp +(use-package quickrun) +(setq quickrun-focus-p nil) +(add-hook 'quickrun-after-run-hook 'eros-quickrun-show-overlay) +(add-hook 'quickrun-after-run-hook 'clear-eros-overlays) +(add-hook 'quickrun-after-run-hook 'quickrun-hide-window-after-execution) + +(use-package marginalia + :after vertico + :init + (setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) + (marginalia-mode) + (with-eval-after-load 'projectile + (add-to-list 'marginalia-command-categories '(projectile-find-file . file)))) +(use-package eros + :after quickrun) +(require 'quickrun) +(require 'eros) +(eros-mode 1) + +(use-package orderless + :ensure t + :custom + (setq orderless-component-separator 'orderless-escapable-split-on-space) + (completion-styles '(orderless basic substring partial-completion flex)) + (completion-category-overrides '((file (styles basic partial-completion))))) + +#+end_src + +** Functions +#+begin_src emacs-lisp +(defun clear-eros-overlays () + (interactive) + (remove-overlays (point-min) (point-max))) + +(defun quickrun-hide-window-after-execution () + (interactive) + (let ((win (get-buffer-window "*quickrun*"))) + (when win + (delete-window win)))) + +(defun eros-quickrun-show-overlay () + (interactive) + (eros-mode -1) + (eros-mode 1) + (when (and quickrun--timeout-timer + (not (equal quickrun--timeout-timer 'ignore))) + (cancel-timer quickrun--timeout-timer)) + (setq quickrun--timeout-timer + (run-at-time 0.5 nil + (lambda () + (let ((output (with-current-buffer quickrun--buffer-name + (buffer-substring-no-properties (point-min) (point-max))))) + (with-current-buffer (window-buffer (selected-window)) + (condition-case nil + (eros--make-result-overlay output) + (error (message "Error creating Eros overlay"))) + (with-current-buffer quickrun--buffer-name + (let ((inhibit-read-only t)) + (erase-buffer))))))))) +#+end_src + +* Org Mode +Easily one of Emacs' best features, this editor paradigm transforms the editing experience into a divine experience. +#+begin_src emacs-lisp +(setq org-src-preserve-indentation nil + org-src-tab-acts-natively t + org-edit-src-content-indentation 0 + org-confirm-babel-evaluate nil + org-startup-indented t + org-hide-emphasis-markers t) +(setq org-superstar-headline-bullets-list '( "⌬" "⊛" "➤" "▻" "◎" "❂" "⦿" "✦" "❅" "❇" "◈" "▶" "☢" "☯" "☮" "☣") + org-modern-star '("⌬" "⊛" "➤" "▻" "◎" "❂" "⦿" "✦" "❅" "❇" "◈" "▶" "☢" "☯" "☮" "☣")) +(use-package org-modern + :hook (org-mode . org-modern-mode)) +;; :config +;; (add-hook 'org-mode-hook (lambda () (local-set-key (kbd "TAB") 'org-fold-or-unfold-heading))) +;; (setq org-modern-star '("⌬" "⊛" "➤" "▻" "◎" "❂" "⦿" "✦" "❅" "❇" "◈" "▶" "☢" "☯" "☮" "☣")) + +(defadvice org-babel-execute-src-block (around load-language nil activate) + "Load language if needed" + (let ((language (org-element-property :language (org-element-at-point)))) + (unless (cdr (assoc (intern language) org-babel-load-languages)) + (add-to-list 'org-babel-load-languages (cons (intern language) t)) + (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)) + ad-do-it)) + +(setq org-babel-default-header-args + (cons '(:results . "output") + (cons '(:noweb . "yes") + (assq-delete-all :results org-babel-default-header-args)))) +(defun org-enter-maybe-execute () + (interactive) + (if (org-in-src-block-p) + (org-babel-execute-src-block) + (newline))) + +(org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (C . t) + (python . t) + (shell . t))) + +;; Configuring Org exports opening in EWW +(defun org-html-export-to-html-and-open () + "Export the Org file to HTML and open it in EWW." + (interactive) + (let* ((org-file (buffer-file-name)) + (html-file (concat (file-name-sans-extension org-file) ".html")) + (html-file-url html-file)) + (org-export-to-file 'html html-file nil nil nil nil) + (eww-open-file html-file-url))) + +(add-hook 'org-mode-hook + (lambda () + (local-set-key (kbd "C-c C-o") 'org-html-export-to-html-and-open))) +#+end_src + +* Vterm +#+begin_src emacs-lisp +(use-package vterm +:config +(setq shell-file-name "/usr/bin/bash" + vterm-max-scrollback 5000)) +(use-package vterm-toggle + :after vterm + :config + ;; When running programs in Vterm and in 'normal' mode, make sure that ESC + ;; kills the program as it would in most standard terminal programs. + (evil-define-key 'normal vterm-mode-map (kbd "") 'vterm--self-insert) + (evil-define-key 'normal vterm-mode-map (kbd "C-c") 'vterm--self-insert) + (setq vterm-toggle-fullscreen-p nil) + (setq vterm-toggle-scope 'project) + (add-to-list 'display-buffer-alist + '((lambda (buffer-or-name _) + (let ((buffer (get-buffer buffer-or-name))) + (with-current-buffer buffer + (or (equal major-mode 'vterm-mode) + (string-prefix-p vterm-buffer-name (buffer-name buffer)))))) + (display-buffer-reuse-window display-buffer-at-bottom) + ;;(display-buffer-reuse-window display-buffer-in-direction) + ;;display-buffer-in-direction/direction/dedicated is added in emacs27 + ;;(direction . bottom) + ;;(dedicated . t) ;dedicated is supported in emacs27 + (reusable-frames . visible) + (window-height . 0.4)))) +#+end_src + +* Misc +#+begin_src emacs-lisp +(setq use-short-answers t ; y/n instead of yes/no + xterm-mouse-mode t + buffer-face-mode t + delete-selection-mode t + find-file-visit-truename t + browse-url-browser-function 'eww-browse-url + initial-scratch-message 'nil ;; dont display "This buffer is for text that is not saved..." nonsense + undo-tree-auto-save-history nil + backup-directory-alist '((".*" . "~/.local/share/Trash/files")) + auto-save-default nil ; set the default file location of auto-saved files to NIL + inhibit-automatic-native-compliation t + native-comp-enable-subr-trampolines nil + confirm-kill-emacs nil ;;prevent ALL quit prompts + safe-local-variable-values nil + explicit-shell-file-name "/usr/bin/bash" + desktop-save-mode nil + load-prefer-newer 'noninteractive) + +; adding (interactive) to lambdas and functions allows them to be available in the M-x menu +;; dtrt-indent link-hint +;; (add-hook 'prog-mode-hook 'display-line-numbers) +(defmacro k-time (&rest body) +"Measure and return the time it takes evaluating BODY." +`(let ((time (current-time))) + ,@body + (float-time (time-since time)))) +;; Set garbage collection threshold to 1GB. + ;(setq gc-cons-threshold #x40000000) + +;; When idle for 15sec run the GC no matter what. + ;(defvar k-gc-timer + ; (run-with-idle-timer 15 t + ; (lambda () + ; (message "Garbage Collector has run for %.06fsec" + ; (k-time (garbage-collect)))))) +(use-package togetherly) +(use-package htmlize) +(use-package consult) +(use-package projectile) +(use-package rainbow-delimiters) +(use-package helpful) +(use-package undo-tree) + +(use-package flycheck + :ensure t + :defer t + :init (global-flycheck-mode)) + +(use-package which-key +:init +(which-key-mode 1) +:config +(setq which-key-side-window-location 'bottom + which-key-sort-order #'which-key-key-order-alpha + which-key-sort-uppercase-first nil + which-key-add-column-padding 1 + which-key-max-display-columns nil + which-key-min-display-lines 6 + which-key-side-window-slot -10 + which-key-side-window-max-height 0.25 + which-key-idle-delay 0.8 + which-key-max-description-length 25 + which-key-allow-imprecise-window-fit t + which-key-separator " → " )) + +(global-set-key [escape] 'keyboard-escape-quit) +(add-hook 'prog-mode-hook #'rainbow-delimiters-mode) +(add-hook 'evil-local-mode-hook 'turn-on-undo-tree-mode) +;; (add-hook 'man-mode-hook '(lambda () (setq mode-line-format nil ))) +(auto-save-mode nil) ; don't auto save files by default + + + + +(add-to-list 'load-path (expand-file-name "~/.config/emacs/lisp/")) ; load all user-defined Emacs Lisp scripts from this directory +(let ((default-directory "~/.config/emacs/lisp/")) (normal-top-level-add-to-load-path '("*"))) + +(add-hook 'after-save-hook + (lambda () + (when (string= (buffer-file-name) user-init-file) + (load-file user-init-file) + (load-file user-init-file)))) + + + +#+end_src + +** Misc functions +#+begin_src emacs-lisp +(defun eshell-clear-buffer () +"Clear terminal" +(interactive) +(let ((inhibit-read-only t)) +(erase-buffer) +(eshell-send-input))) + +(defun save-file-as (filename) +"Save the current buffer under a different name." +(interactive "FSave file as: ") +(let ((old-filename (buffer-file-name))) +(if old-filename + (write-region (point-min) (point-max) filename) + (progn + (set-visited-file-name filename) + (set-buffer-modified-p t))))) + +(defun find-file-as-root (filename) +"Open file as root." +(interactive "f") +(find-file (concat "/sudo::" filename))) + +(defun evaluate-buffer () +"Evaluate the current buffer." +(interactive) +(if (eq major-mode 'emacs-lisp-mode) + (let ((result (eval-buffer))) + (unless (null result) + (eros--make-result-overlay result))) +(quickrun))) + +(defun evaluate-region () + "Evaluate the selected region." + (interactive) + (if (use-region-p) + (if (eq major-mode 'emacs-lisp-mode) + (let ((result (eros-eval-last-sexp (sexp-at-point)))) + (unless (null result) + (eros--make-result-overlay result))) + (let ((result (quickrun-region (region-beginning) (region-end)))) + (unless (null result) + (eros--make-result-overlay result)))) + (quickrun))) + +(defun scratch () + "Create a new scratch buffer to work in" + (interactive) + (let ((n 0) bufname) + (while (progn + (setq bufname (concat "*scratch" (if (= n 0) "" (int-to-string n)) "*")) + (setq n (1+ n)) + (get-buffer bufname))) + (switch-to-buffer (get-buffer-create bufname)) + (if (= n 1) initial-major-mode))) + +(defun kill-all-buffers-except-dashboard () + "Kill all buffers except the one named 'dashboard'." + (interactive) + (let ((dashboard-buffer-name "*dashboard*") + (buffers-to-keep '("*scratch*"))) ; Add other buffers you want to keep here + (mapc (lambda (buffer) + (unless (or (member (buffer-name buffer) buffers-to-keep) + (equal (buffer-name buffer) dashboard-buffer-name)) + (kill-buffer buffer))) + (buffer-list))) + (dashboard-open) + (message "Killed all buffers except dashboard")) + +(with-current-buffer (get-buffer-create "*dashboard*")(emacs-lock-mode 'kill)) + +(defun kill-other-buffers () + "Keep only the current buffer, scratch, and dashboard buffers, kill all others." + (interactive) + (let ((buffers-to-keep '("*scratch*" "*dashboard*")) + (current-buffer-name (buffer-name))) + (mapc (lambda (buffer) + (unless (or (member (buffer-name buffer) buffers-to-keep) + (equal (buffer-name buffer) current-buffer-name)) + (kill-buffer buffer))) + (buffer-list))) + (message "Kept only current, scratch, and dashboard buffers")) +;;;###autoload +(defun buf-move-up () + "Swap the current buffer and the buffer above the split. +If there is no split, ie now window above the current one, an +error is signaled." + ;; "Switches between the current buffer, and the buffer above the + ;; split, if possible." + (interactive) + (let* ((other-win (windmove-find-other-window 'up)) + (buf-this-buf (window-buffer (selected-window)))) + (if (null other-win) + (error "No window above this one") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +;;;###autoload +(defun buf-move-down () + "Swap the current buffer and the buffer under the split. +If there is no split, ie now window under the current one, an +error is signaled." + (interactive) + (let* ((other-win (windmove-find-other-window 'down)) + (buf-this-buf (window-buffer (selected-window)))) + (if (or (null other-win) + (string-match "^ \\*Minibuf" (buffer-name (window-buffer other-win)))) + (error "No window under this one") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +;;;###autoload +(defun buf-move-left () + "Swap the current buffer and the buffer on the left of the split. +If there is no split, ie now window on the left of the current +one, an error is signaled." + (interactive) + (let* ((other-win (windmove-find-other-window 'left)) + (buf-this-buf (window-buffer (selected-window)))) + (if (null other-win) + (error "No left split") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +;;;###autoload +(defun buf-move-right () + "Swap the current buffer and the buffer on the right of the split. +If there is no split, ie now window on the right of the current +one, an error is signaled." + (interactive) + (let* ((other-win (windmove-find-other-window 'right)) + (buf-this-buf (window-buffer (selected-window)))) + (if (null other-win) + (error "No right split") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +(defun delete-current-buffer-file () + "Delete the current file and buffer, but only if the user confirms." + (interactive) + (when (buffer-file-name) + (when (yes-or-no-p (concat "Are you sure you want to delete " (buffer-file-name) "?")) + (delete-file (buffer-file-name)) + (kill-buffer)))) +#+end_src + +* Diff-HL +This package provides a neat Git diff. +#+begin_src emacs-lisp +(use-package diff-hl) +(add-hook 'prog-mode-hook 'diff-hl-mode) +(setq diff-hl-fringe-face-function 'diff-hl-fringe-face-from-type) +;; (setq diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-type) + +(diff-hl-flydiff-mode) +(global-diff-hl-mode 1) +(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh) +(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh) +#+end_src + +* General - package,keybind settings +All keybind-related config goes here. +#+begin_src emacs-lisp +(use-package general + :config + (general-evil-setup)) + +(general-create-definer stratmacs/leader-keys + :states '(normal insert visual emacs) + :keymaps 'override + :prefix "SPC" ;; set leader + :global-prefix "M-SPC") ;; access leader in insert mode + +(stratmacs/leader-keys + "" '(:ignore t :wk "Leader key") + "SPC" '(eat :wk "Terminal") + "." '(find-file :wk "Find file") + "=" '(perspective-map :wk "Perspective") ;; Lists all the perspective keybindings + "TAB TAB" '(comment-line :wk "Comment lines") + "RET" '(eat :wk "Open terminal") + "/" '(evilnc-comment-or-uncomment-lines :wk "Toggle comment") + "," '(consult-buffer :wk "View buffers") + "u" '(universal-argument :wk "Universal argument") + "x" '(scratch-buffer :wk "Open scratch buffer") + ";" '(is-daemon-running :wk "Is the daemon running?")) + +(stratmacs/leader-keys + "b" '(:ignore t :wk "Bookmarks/Buffers") + "b b" '(switch-to-buffer :wk "Switch to buffer") + "b c" '(clone-indirect-buffer :wk "Create indirect buffer copy in a split") + "b C" '(clone-indirect-buffer-other-window :wk "Clone indirect buffer in new window") + ;; "b d" '(bookmark-delete :wk "Delete bookmark") + "b d" '(kill-all-buffers-except-dashboard :wk "Kill all buffers") + "b i" '(ibuffer :wk "Ibuffer") + "b k" '(kill-current-buffer :wk "Kill current buffer") + "b K" '(kill-some-buffers :wk "Kill multiple buffers") + "b l" '(list-bookmarks :wk "List bookmarks") + "b m" '(bookmark-set :wk "Set bookmark") + "b n" '(next-buffer :wk "Next buffer") + "b o" '(kill-other-buffers :wk "Kill other buffers") + "b p" '(previous-buffer :wk "Previous buffer") + "b r" '(revert-buffer :wk "Reload buffer") + "b R" '(rename-buffer :wk "Rename buffer") + "b s" '(basic-save-buffer :wk "Save buffer") + "b S" '(save-some-buffers :wk "Save multiple buffers") + "b w" '(bookmark-save :wk "Save current bookmarks to bookmark file")) + + +(stratmacs/leader-keys + "c" '(:ignore t :wk "Code") + "c b" '(evaluate-buffer :wk "Eval buffer") + "c e" '(evaluate-region :wk "Eval region") + "c p" '(check-parens :wk "Check parens")) + +(stratmacs/leader-keys + "d" '(:ignore t :wk "Dired") + "d d" '(dired :wk "Open dired") + "d f" '(wdired-finish-edit :wk "Writable dired finish edit") + "d j" '(dired-jump :wk "Dired jump to current") + "d n" '(neotree-dir :wk "Open directory in neotree") + "d p" '(peep-dired :wk "Peep-dired") + "d w" '(wdired-change-to-wdired-mode :wk "Writable dired")) + +(stratmacs/leader-keys + "e" '(:ignore t :wk "Eshell/Eval/EWW") + "e b" '(eval-buffer :wk "Evaluate elisp in buffer") + "e d" '(eval-defun :wk "Evaluate defun containing or after point") + "e e" '(eval-expression :wk "Evaluate and elisp expression") + "e h" '(counsel-esh-history :which-key "Eshell history") + "e l" '(eval-last-sexp :wk "Evaluate elisp expression before point") + "e r" '(eval-region :wk "Evaluate elisp in region") + "e R" '(eww-reload :which-key "Reload current page in EWW") + "e s" '(eshell :which-key "Eshell") + "e w" '(eww :which-key "EWW emacs web wowser")) + +(stratmacs/leader-keys + "f" '(:ignore t :wk "Files") + "f C" '((lambda () (interactive) (find-file "~/.config/emacs/stratmacs.org")) :wk "Open literate config") + "f c" '((lambda () (interactive) (setq recentf-list nil) (dashboard-refresh-buffer)) :wk "Clear recent files") + "f e" '((lambda () (interactive) (dired "~/.config/emacs/")) :wk "Open user-emacs-directory in dired") + ;; "f d" '(find-grep-dired :wk "Search for string in files in DIR") + "f d" '(delete-current-buffer-file :wk "Delete file") + "f g" '(counsel-grep-or-swiper :wk "Search for string current file") + "f i" '((lambda () (interactive) (find-file "~/.config/emacs/init.el")) :wk "Open emacs init.el") + "f j" '(counsel-file-jump :wk "Jump to a file below current directory") + "f l" '(counsel-locate :wk "Locate a file") + "f r" '(recentf-open :wk "Find recent files") + "f R" '(recentf-menu :wk "Edit recent files") + "f s" '(save-buffer :wk "Write file") + "f S" '(write-file :wk "Write file as") + "f u" '(sudo-edit-find-file :wk "Sudo find file") + "f U" '(sudo-edit :wk "Sudo edit file") + "f q" '(save-buffers-kill-terminal :wk "Quit emacs" ) + "q" '(:ignore t :wk "Quit") + "q f" '(save-buffers-kill-terminal :wk "Quit emacs" )) + +(stratmacs/leader-keys + "g" '(:ignore t :wk "Git") + "g /" '(magit-displatch :wk "Magit dispatch") + "g ." '(magit-file-displatch :wk "Magit file dispatch") + "g b" '(magit-branch-checkout :wk "Switch branch") + "g c" '(:ignore t :wk "Create") + "g c b" '(magit-branch-and-checkout :wk "Create branch and checkout") + "g c c" '(magit-commit-create :wk "Create commit") + "g c f" '(magit-commit-fixup :wk "Create fixup commit") + "g C" '(magit-clone :wk "Clone repo") + "g d" '(magit-diff-dwim :wk "Magit diff") + "g f" '(:ignore t :wk "Find") + "g f c" '(magit-show-commit :wk "Show commit") + "g f f" '(magit-find-file :wk "Magit find file") + "g f g" '(magit-find-git-config-file :wk "Find gitconfig file") + "g F" '(magit-fetch :wk "Git fetch") + "g g" '(magit-status :wk "Magit status") + "g i" '(magit-init :wk "Initialize git repo") + "g l" '(magit-log-buffer-file :wk "Magit buffer log") + "g r" '(vc-revert :wk "Git revert file") + "g s" '(magit-stage-file :wk "Git stage file") + "g t" '(git-timemachine :wk "Git time machine") + "g u" '(magit-stage-file :wk "Git unstage file")) + +(stratmacs/leader-keys + "h" '(:ignore t :wk "Help") + "h a" '(counsel-apropos :wk "Apropos") + "h b" '(describe-bindings :wk "Describe bindings") + "h c" '(describe-char :wk "Describe character under cursor") + "h d" '(:ignore t :wk "Emacs documentation") + "h d a" '(about-emacs :wk "About Emacs") + "h d d" '(view-emacs-debugging :wk "View Emacs debugging") + "h d f" '(view-emacs-FAQ :wk "View Emacs FAQ") + "h d m" '(info-emacs-manual :wk "The Emacs manual") + "h d n" '(view-emacs-news :wk "View Emacs news") + "h d o" '(describe-distribution :wk "How to obtain Emacs") + "h d p" '(view-emacs-problems :wk "View Emacs problems") + "h d t" '(view-emacs-todo :wk "View Emacs todo") + "h d w" '(describe-no-warranty :wk "Describe no warranty") + "h e" '(view-echo-area-messages :wk "View echo area messages") + "h f" '(describe-function :wk "Describe function") + "h F" '(describe-face :wk "Describe face") + "h g" '(describe-gnu-project :wk "Describe GNU Project") + "h i" '(info :wk "Info") + "h I" '(describe-input-method :wk "Describe input method") + "h k" '(describe-key :wk "Describe key") + "h l" '(view-lossage :wk "Display recent keystrokes and the commands run") + "h L" '(describe-language-environment :wk "Describe language environment") + "h m" '(describe-mode :wk "Describe mode") + "h r" '(:ignore t :wk "Reload") + "h r r" '((lambda () (interactive) (load-file "~/.config/emacs/stratmacs.el")) :wk "Reload emacs config") + "h t" '(load-theme :wk "Load theme") + "h v" '(describe-variable :wk "Describe variable") + "h w" '(where-is :wk "Prints keybinding for command if set") + "h x" '(describe-command :wk "Display full documentation for command")) + +(stratmacs/leader-keys + "o" '(:ignore t :wk "Org") + "o a" '(org-agenda :wk "Org agenda") + "o e" '(org-export-dispatch :wk "Org export dispatch") + "o i" '(org-toggle-item :wk "Org toggle item") + "o t" '(org-todo :wk "Org todo") + "o B" '(org-babel-tangle :wk "Org babel tangle") + "o T" '(org-todo-list :wk "Org todo list")) + +(stratmacs/leader-keys + "o b" '(:ignore t :wk "Tables") + "o b -" '(org-table-insert-hline :wk "Insert hline in table")) + +(stratmacs/leader-keys + "o d" '(:ignore t :wk "Date/deadline") + "o d t" '(org-time-stamp :wk "Org time stamp")) + +(stratmacs/leader-keys + "p" '(projectile-command-map :wk "Projectile")) + +(stratmacs/leader-keys + "s" '(:ignore t :wk "Search") + "s d" '(dictionary-search :wk "Search dictionary") + "s m" '(man :wk "Man pages") + "s t" '(tldr :wk "Lookup TLDR docs for a command") + "s w" '(woman :wk "Similar to man but doesn't require man")) + +(stratmacs/leader-keys + "t" '(:ignore t :wk "Toggle") + "t e" '(eshell-toggle :wk "Toggle eshell") + "t f" '(toggle-frame-fullscreen :wk "Toggle fullscreen") + "t F" '(flycheck-mode :wk "Toggle flycheck") + "t l" '(display-line-numbers-mode :wk "Toggle line numbers") + "t n" '(neotree-toggle :wk "Toggle neotree file viewer") + "t o" '(org-mode :wk "Toggle org mode") + "t r" '(rainbow-mode :wk "Toggle rainbow mode") + "t t" '(visual-line-mode :wk "Toggle truncated lines") + "t v" '(vterm-toggle :wk "Toggle vterm")) + +(stratmacs/leader-keys + "w" '(:ignore t :wk "Words & Windows") + ;; Window splits + "w c" '(evil-window-delete :wk "Close window") + "w n" '(evil-window-new :wk "New window") + "w s" '(evil-window-split :wk "Horizontal split window") + "w v" '(evil-window-vsplit :wk "Vertical split window") + ;; Window motions + "w m m" '(lambda ()(interactive)(maximize-window)) + + "w h" '(evil-window-left :wk "Window left") + "w j" '(evil-window-down :wk "Window down") + "w k" '(evil-window-up :wk "Window up") + "w l" '(evil-window-right :wk "Window right") + "w w" '(evil-window-next :wk "Goto next window") + ;; Move Windows + "w H" '(buf-move-left :wk "Buffer move left") + "w J" '(buf-move-down :wk "Buffer move down") + "w K" '(buf-move-up :wk "Buffer move up") + "w L" '(buf-move-right :wk "Buffer move right") + ;; Words + "w d" '(downcase-word :wk "Downcase word") + "w u" '(upcase-word :wk "Upcase word") + "w =" '(count-words :wk "Count words/lines for buffer") + "w L" '(buf-move-right :wk "Buffer move right")) +#+end_src + +** Keybind-related extra configuration +#+begin_src emacs-lisp +(use-package evil-easymotion) +(general-define-key + :states '(normal) + :keymaps 'override-global-map + "/" '(consult-line :wk "Search in buffer") + "s" '(evil-avy-goto-char-timer :wk "Hop to")) + +(general-define-key + :states '(normal visual insert emacs) + "C-e" 'evil-end-of-line-or-visual-line) +#+end_src + +* Magit +The very best Git client, period. +#+begin_src emacs-lisp +(use-package magit) +(magit-auto-revert-mode -1) +#+end_src + +* Tree-sitter +#+begin_src emacs-lisp +; (use-package tree-sitter) +; (use-package tree-sitter-langs) +; (add-hook 'tree-sitter-mode-hook 'tree-sitter-hl-mode) +; (add-hook 'python-mode-hook #'tree-sitter-mode) +; (add-hook 'sh-mode-hook #'tree-sitter-mode) +#+end_src + +* Eglot +A post-modern LSP client built into Emacs. +#+begin_src emacs-lisp +(use-package eglot + :defer t + :hook (python-mode . eglot-ensure) + :hook (c-mode . eglot-ensure) + :hook (c++-mode . eglot-ensure) + :hook (go-mode . eglot-ensure)) +#+end_src + +* Rust support +Add Rust support in Emacs. +#+begin_src emacs-lisp +(use-package rust-mode +:init + (add-hook 'rust-mode-hook (lambda() (setq indent-tabs-mode nil))) + (add-hook 'rust-mode-hook (setq rust-format-on-save t))) +#+end_src + +* Rainbow mode +Rainbow mode is used to colourize colour names in buffers. +#+begin_src emacs-lisp +(use-package rainbow-mode) +(add-hook 'prog-mode-hook 'rainbow-mode) +#+end_src diff --git a/airootfs/etc/skel/.local/share/fonts/GrapeNuts-Regular.ttf b/airootfs/etc/skel/.local/share/fonts/GrapeNuts-Regular.ttf new file mode 100644 index 000000000..d2db83499 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/GrapeNuts-Regular.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/Icomoon-Feather.ttf b/airootfs/etc/skel/.local/share/fonts/Icomoon-Feather.ttf new file mode 100644 index 000000000..88bdfd0b0 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/Icomoon-Feather.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/Iosevka-Nerd-Font-Complete.ttf b/airootfs/etc/skel/.local/share/fonts/Iosevka-Nerd-Font-Complete.ttf new file mode 100644 index 000000000..bbb351c75 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/Iosevka-Nerd-Font-Complete.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/JetBrains-Mono-Nerd-Font-Complete.ttf b/airootfs/etc/skel/.local/share/fonts/JetBrains-Mono-Nerd-Font-Complete.ttf new file mode 100644 index 000000000..f9f01859c Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/JetBrains-Mono-Nerd-Font-Complete.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/NFM.ttf b/airootfs/etc/skel/.local/share/fonts/NFM.ttf new file mode 100644 index 000000000..bc1f88e3d Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/NFM.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/all-the-icons.ttf b/airootfs/etc/skel/.local/share/fonts/all-the-icons.ttf new file mode 100644 index 000000000..634d48e99 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/all-the-icons.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/file-icons.ttf b/airootfs/etc/skel/.local/share/fonts/file-icons.ttf new file mode 100644 index 000000000..dd42225c8 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/file-icons.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/fontawesome.ttf b/airootfs/etc/skel/.local/share/fonts/fontawesome.ttf new file mode 100644 index 000000000..f221e50a2 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/fontawesome.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/material-design-icons.ttf b/airootfs/etc/skel/.local/share/fonts/material-design-icons.ttf new file mode 100644 index 000000000..7015564ad Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/material-design-icons.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/octicons.ttf b/airootfs/etc/skel/.local/share/fonts/octicons.ttf new file mode 100644 index 000000000..6f3edd667 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/octicons.ttf differ diff --git a/airootfs/etc/skel/.local/share/fonts/weathericons.ttf b/airootfs/etc/skel/.local/share/fonts/weathericons.ttf new file mode 100644 index 000000000..948f0a5d2 Binary files /dev/null and b/airootfs/etc/skel/.local/share/fonts/weathericons.ttf differ diff --git a/airootfs/usr/local/bin/StratOS-configure-gnome b/airootfs/usr/local/bin/StratOS-configure-gnome index a5d5ff891..626ccc11b 100755 --- a/airootfs/usr/local/bin/StratOS-configure-gnome +++ b/airootfs/usr/local/bin/StratOS-configure-gnome @@ -24,5 +24,5 @@ gsettings set org.gnome.desktop.interface monospace-font-name 'JetBrainsMonoNF 1 gsettings set org.gnome.desktop.interface color-scheme prefer-dark # System dark theme gsettings set org.gnome.desktop.interface clock-show-weekday true gsettings set org.gnome.desktop.interface clock-show-seconds true -gsettings set org.gnome.shell favorite-apps "['org.gnome.Terminal.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Settings.desktop', 'chromium.desktop']" +gsettings set org.gnome.shell favorite-apps "['org.gnome.Terminal.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Settings.desktop', 'emacs.desktop', 'chromium.desktop']" gsettings set org.gnome.desktop.wm.preferences button-layout "close,minimize,maximize:" diff --git a/packages.x86_64 b/packages.x86_64 index b169c24d1..b2b90c0ec 100644 --- a/packages.x86_64 +++ b/packages.x86_64 @@ -12,6 +12,7 @@ broadcom-wl # btrfs-progs calamares ckbcomp +cmake # for Emacs chromium # clonezilla # cryptsetup @@ -29,6 +30,7 @@ dosfstools e2fsprogs edk2-shell efibootmgr +emacs # OG ethtool exfatprogs f2fs-tools