;; -*- lexical-binding: t; -*- (require 'package) (setq package-vc-register-as-project nil) ; Emacs 30 (add-hook 'package-menu-mode-hook #'hl-line-mode) ;; List of packages for auto install scratch (setq package-list '(use-package)) ;; Also read: (setq package-archives '(("gnu-elpa" . "https://elpa.gnu.org/packages/") ("gnu-elpa-devel" . "https://elpa.gnu.org/devel/") ("nongnu" . "https://elpa.nongnu.org/nongnu/") ("melpa" . "https://melpa.org/packages/"))) ;; Highest number gets priority (what is not mentioned has priority 0) (setq package-archive-priorities '(("gnu-elpa" . 3) ("melpa" . 2) ("nongnu" . 1))) ;; NOTE 2023-08-21: I build Emacs from source, so I always get the ;; latest version of built-in packages. However, this is a good ;; solution to set to non-nil if I ever switch to a stable release. (setq package-install-upgrade-built-in nil) ; activate all the packages (in particular autoloads) (package-initialize) ; fetch the list of packages available (unless package-archive-contents (package-refresh-contents)) ;; Whitespace-mode settings. (use-package emacs :init (custom-set-variables '(whitespace-display-mappings '((space-mark 32 [183] [46]) (space-mark 160 [164] [95]) (newline-mark 10 [172 10]) (tab-mark 9 [187 9] [92 9])))) (custom-set-faces '(whitespace-space ((t (:bold t :foreground "#282828")))) '(whitespace-newline ((t (:bold t :foreground "#282828")))) ) (add-hook 'prog-mode-hook (lambda () (setq display-line-numbers 'relative))) (add-hook 'prog-mode-hook 'whitespace-mode) ) ;; Frame settings. (use-package emacs :init (setq default-frame-alist '( (fullscreen . maximized) ;; (font . "JetBrains Mono 22") (font . "Iosevka Fixed 24") (undecorated . t) (vertical-scroll-bars . nil) (inhibit-double-buffering . t) ;; (ns-transparent-titlebar . nil) (background-color . "#181818") ;;"black") )) ) ;; Basic settings. (use-package emacs :init (delete-selection-mode 1) (blink-cursor-mode 0) (save-place-mode t) (savehist-mode t) (setq use-short-answers t ;; set-mark-command-repeat-pop t ring-bell-function 'ignore scroll-conservatively 101 help-window-select t create-lockfiles nil auto-save-default nil make-backup-files nil custom-safe-themes t initial-buffer-choice nil ;; If not nil always show scratch buffer, even open other file. backup-directory-alist '((".*" . "/tmp")) custom-file (make-temp-file "emacs-custom-") whitespace-style (quote (face spaces tabs space-mark tab-mark newline newline-mark)) Man-sed-command "gsed") :config (setq-default truncate-lines nil ;; display-line-numbers 'relative display-line-numbers-width 3 indent-tabs-mode nil tab-width 4 c-basic-offset 4 c-basic-indent 4) (xterm-mouse-mode t) (show-paren-mode t)) ;; Mode line format. ----- (defun my-evil-mode-indicator () (interactive) (cond ((eq evil-state 'visual) "") ((eq evil-state 'insert) "") ((eq evil-state 'normal) "") ((eq evil-state 'emacs) "") (t " * "))) (setq-default mode-line-format '("%e " mode-line-modified " " (:eval (propertize (buffer-name)) 'face 'font-lock-constant-face) "%6l:%c (%o) " (:eval (if (and (mode-line-window-selected-p) (bound-and-true-p evil-mode)) (my-evil-mode-indicator)) " ") (:eval (unless (not vc-mode) (concat " | Git:" (substring-no-properties vc-mode 5)))) mode-line-format-right-align (:eval (concat " " (symbol-name major-mode))) " " mode-line-misc-info)) (use-package emacs :init ;; Add prompt indicator to `completing-read-multiple'. ;; We display [CRM], e.g., [CRM,] if the separator is a comma. (defun crm-indicator (args) (cons (format "[CRM%s] %s" (replace-regexp-in-string "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" crm-separator) (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) ;; Do not allow the cursor in the minibuffer prompt (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) ;; (add hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy) ;; Enable recursive minibuffers (setq enable-recursive-minibuffers t)) (use-package modus-themes :ensure t :defer t :config (custom-set-faces '(dired-header ((t (:foreground "#95a99f"))))) ;; :slant italic))))) (custom-set-faces '(dired-directory ((t (:foreground "#96a6c8"))))) ;; :slant italic))))) (setq modus-themes-italic-constructs nil modus-themes-bold-constructs nil modus-themes-mixed-fonts nil modus-themes-variable-pitch-ui nil modus-themes-custom-auto-reload t modus-themes-disable-other-themes t modus-themes-prompts '(italic bold) modus-themes-completions '((matches . (extrabold)) (selection . (semibold italic text-also))) modus-themes-org-blocks 'tined-background ) (setq modus-vivendi-palette-overrides ;; Setting for theme like gruber-darker `( (fg-main "#e4e4ef") ;; Background (bg-main "#181818") ;; Comment and string (comment "#cc8c3c") ;; yellow-faint) (string "#73c936") ;; Code colors (builtin "#95a99f") (constant "#95a99f") (fnname "#96a6c8") (keyword "#ffdd33") (preprocessor "#95a99f") (type "#95a99f") (cursor "#ffdd33") (variable "#f4f4ff") (bg-region "#484848") (fg-region unspecified) (fg-completion-match-0 "#ffdd33") (fg-prompt "#96a6c8") (bg-mode-line-active "#282828") (fg-mode-line-active "#ffffff") (fg-line-number-active "#ffdd33") (bg-line-number-active "#181818") (bg-line-number-inactive "#181818") ;; SRC-block (bg-prose-block-delimiter bg-inactive) ;; Region bg and fg (bg-region bg-hover) ; try to replace `bg-ochre' with `bg-lavender', `bg-sage' (fg-region unspecified) ))) (load-theme 'modus-vivendi t) ;; Denote package. ---- (use-package denote-org :ensure t) (use-package denote :ensure t :init :custom (denote-directory "~/Nextcloud/DenoteNotes/") :hook (dired-mode . denote-dired-mode) :custom-face (denote-faces-link ((t (:slant italic))))) (global-set-key (kbd "C-c n n") 'denote-open-or-create) (use-package consult-denote :ensure t :config (define-key global-map (kbd "C-c n f") #'consult-denote-find) (define-key global-map (kbd "C-c n g") #'consult-denote-grep)) ;; Org-roam. ------ ;; (use-package org-roam ;; :ensure t ;; :custom ;; (org-roam-directory (file-truename "/Users/norets/Library/Mobile Documents/iCloud~com~logseq~logseq/Documents/Org-roam/pages")) ;; :bind (("C-c n l" . org-roam-buffer-toggle) ;; ("C-c n f" . org-roam-node-find) ;; ("C-c n g" . org-roam-graph) ;; ("C-c n i" . org-roam-node-insert) ;; ("C-c n c" . org-roam-capture) ;; ;; Dailies ;; ("C-c n j" . org-roam-dailies-capture-today)) ;; :config ;; ;; If you're using a vertical completion framework, you might want a more informative completion interface ;; (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) ;; (org-roam-db-autosync-mode) ;; ;; If using org-roam-protocol ;; (require 'org-roam-protocol)) (use-package vertico :ensure t :init (setq vertico-scroll-margin 0) (setq vertico-count 5) (setq vertico-resize nil) (setq vertico-cycle t) (vertico-mode)) (use-package emacs :custom ;; Support opening new minibuffers from inside existing minibuffers. (enable-recursive-minibuffers t) ;; Hide commands in M-x which do not work in the current mode. Vertico ;; commands are hidden in normal buffers. This setting is useful beyond ;; Vertico. (read-extended-command-predicate #'command-completion-default-include-p) ;; Do not allow the cursor in the minibuffer prompt (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))) ;; Dired module. ----- (when (string= system-type "darwin") (setq dired-use-ls-dired nil)) (use-package dired :init (setq delete-by-moving-to-trash t) (setq dired-listing-switches "-lah") (setq dired-dwim-target t) (setq dired-auto-revert-buffer #'dired-directory-changed-p) ) ;; ISearch module. ----- (use-package isearch :ensure nil :demand t :config (setq search-whitespace-regexp ".*?" ; one `setq' here to make it obvious they are a bundle isearch-lax-whitespace t isearch-regexp-lax-whitespace nil)) (use-package isearch :ensure nil :demand t :config (setq search-highlight t) (setq isearch-lazy-highlight t) (setq lazy-highlight-initial-delay 0.5) (setq lazy-highlight-no-delay-length 4)) (use-package isearch :ensure nil :demand t :config (setq isearch-lazy-count t) (setq lazy-count-prefix-format "(%s/%s) ") (setq lazy-count-suffix-format nil)) (use-package isearch :ensure nil :demand t :config (setq isearch-wrap-pause t) ; `no-ding' makes keyboard macros never quit (setq isearch-repeat-on-direction-change t)) (use-package isearch :ensure nil :demand t :config (setq list-matching-lines-jump-to-current-line nil) ; do not jump to current line in `*occur*' buffers ;; (add-hook 'occur-mode-hook #'prot-common-truncate-lines-silently) ; from `prot-common.el' (add-hook 'occur-mode-hook #'hl-line-mode)) (use-package isearch :ensure nil :defer t :config (defun my-occur-from-isearch () (interactive) (let ((query (if isearch-regexp isearch-string (regexp-quote isearch-string)))) (isearch-update-ring isearch-string isearch-regexp) (let (search-nonincremental-instead) (ignore-errors (isearch-done t t))) (occur query))) :bind (:map isearch-mode-map ("C-o" . my-occur-from-isearch))) (use-package isearch :ensure nil :defer t :config (defun my-project-search-from-isearch () (interactive) (let ((query (if isearch-regexp isearch-string (regexp-quote isearch-string)))) (isearch-update-ring isearch-string isearch-regexp) (let (search-nonincremental-instead) (ignore-errors (isearch-done t t))) (project-find-regexp query))) :bind (:map isearch-mode-map ("C-f" . my-project-search-from-isearch))) ;; Selection window (rg, grep, help etc). ----- (defun my-select-window (window &rest _) "Select WINDOW for display-buffer-alist" (select-window window)) (setq display-buffer-alist '(((or . ((derived-mode . occur-mode) (derived-mode . rg-mode) (derived-mode . grep-mode) (derived-mode . Buffer-menu-mode) (derived-mode . log-view-mode) (derived-mode . help-mode) ; See the hooks for `visual-line-mode' (derived-mode . flymake-diagnostics-buffer-mode) "\\*\\(|Buffer List\\|Occur\\|vc-change-log\\|compilation\\|eldoc.*\\).*" )) (display-buffer-reuse-mode-window display-buffer-pop-up-window) (body-function . my-select-window) (dedicated . t) (preserve-size . (t . t))))) ;; Marginalia. ----- (use-package marginalia :ensure t ;; Either bind `marginalia-cycle' globally or only in the minibuffer :bind (("M-A" . marginalia-cycle) :map minibuffer-local-map ("M-A" . marginalia-cycle)) ;; The :init configuration is always executed (Not lazy!) :init ;; Must be in the :init section of use-package such that the mode gets ;; enabled right away. Note that this forces loading the package. (marginalia-mode)) ;; Orderless. ----- (use-package orderless :ensure t :demand t :after minibuffer :config (setq completion-styles '(orderless basic) completion-category-defaults nil ;; orderless-matching-styles '(orderless-prefixes orderless-regexp) completion-category-overrides '((file (styles . (partial-completion)))) )) ;; Corfu (use-package corfu :ensure t :defer 3 :custom (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' (corfu-auto t) ;; Enable auto completion ;; (corfu-separator ?\s) ;; Orderless field separator ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match ;; (corfu-preview-current nil) ;; Disable current candidate preview ;; (corfu-preselect 'prompt) ;; Preselect the prompt ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches ;; (corfu-scroll-margin 5) ;; Use scroll margin (corfu-popupinfo-mode t) :bind (:map corfu-map ("C-y" . corfu-complete) ("C-e" . corfu-reset) ("" . nil) ) :init (global-corfu-mode)) (use-package corfu-terminal :ensure t :defer 3 :init (unless (display-graphic-p) (corfu-terminal-mode +1))) ;; Add extensions (use-package cape :ensure t :defer 3 ;; Bind prefix keymap providing all Cape commands under a mnemonic key. ;; Press C-c p ? to for help. :bind ("C-c p" . cape-prefix-map) ;; Alternative keys: M-p, M-+, ... ;; Alternatively bind Cape commands individually. ;; :bind (("C-c p d" . cape-dabbrev) ;; ("C-c p h" . cape-history) ;; ("C-c p f" . cape-file) ;; ...) :init ;; Add to the global default value of `completion-at-point-functions' which is ;; used by `completion-at-point'. The order of the functions matters, the ;; first function returning a result wins. Note that the list of buffer-local ;; completion functions takes precedence over the global list. (add-hook 'completion-at-point-functions #'cape-dabbrev) (add-hook 'completion-at-point-functions #'cape-file) (add-hook 'completion-at-point-functions #'cape-elisp-block) ;; (add-hook 'completion-at-point-functions #'cape-history) ;; ... ) ;; Org-mode. ------ (use-package org :ensure t :hook (org-mode . visual-line-mode) :custom (org-ellipsis "...") (org-sturtup-indent t) (org-hide-emphasis-markers t)) ;; code blocks. ------ (use-package org :ensure nil :config (require 'org-tempo) (setq org-confirm-babel-evaluate nil) (setq org-src-window-setup 'current-window) (setq org-support-shift-select t) (setq org-edit-src-persistent-message nil) (setq org-src-fontify-natively t) (setq org-src-preserve-indentation t) (setq org-src-tab-acts-natively t) (setq org-hide-emphasis-markers nil) (setq org-edit-src-content-indentation 0)) ;; (use-package mini-modeline ;; ;; :ensure t ;; ;; :quelpa (mini-modeline :repo "kiennq/emacs-mini-modeline" :fetcher github) ;; ;; :after smart-mode-line ;; :config ;; (setq mini-modeline-display-gui-line t) ;; (setq mini-modeline-enhance-visual t) ;; (setq mini-modeline-l-format '("%e " mode-line-modified " " ;; (:eval (propertize (buffer-name)) 'face 'font-lock-constant-face) ;; "%6l:%c (%o) " ;; (:eval (unless (not vc-mode) (concat " | git:" (substring-no-properties vc-mode 5)))))) ;; (setq mini-modeline-r-format '("" ;; (:eval (concat " " (symbol-name major-mode))) ;; " " mode-line-misc-info)) ;; (mini-modeline-mode t)) ;; Avy ----- (use-package avy :ensure t) ;; Move Lines/Text ----- (use-package move-text :ensure t) (defun indent-region-advice (&rest ignored) (let ((deactivate deactivate-mark)) (if (region-active-p) (indent-region (region-beginning) (region-end)) (indent-region (line-beginning-position) (line-end-position))) (setq deactivate-mark deactivate))) (advice-add 'move-text-up :after 'indent-region-advice) (advice-add 'move-text-down :after 'indent-region-advice) ;;; Magit ------ (use-package magit :ensure t :defer 0 :init (setq magit-auto-revert-mode nil)) ;; Multiple-Cursors ------ (use-package multiple-cursors :ensure t :init :bind (("C-S-c C-S-c" . mc/edit-lines) ("C->" . mc/mark-next-like-this) ("C-<" . mc/mark-previous-like-this) ("C-M-j" . mc/mark-all-dwim) ("C-c C-<" . mc/mark-all-like-this) )) ;; TabBarMode ----- (use-package tab-bar :ensure nil :init (setq tab-bar-show 1) ;; hide bar if <= 1 tabs open (setq tab-bar-close-button-show nil) ;; hide tab close / X button (setq tab-bar-new-tab-choice "*scratch*");; buffer to show in new tabs (setq tab-bar-tab-hints t) ;; show tab numbers (setq tab-bar-format '(tab-bar-format-tabs tab-bar-separator)) :config (setq tab-bar-mode nil)) (global-set-key (kbd "s-[") 'tab-bar-switch-to-prev-tab) (global-set-key (kbd "s-]") 'tab-bar-switch-to-next-tab) (global-set-key (kbd "s-t") 'tab-bar-new-tab) (global-set-key (kbd "s-w") 'tab-bar-close-tab) (setq tab-bar-select-tab-modifiers "super") ;; Keybindings ------ (define-key (current-global-map) [remap dired] 'dired-jump) (define-key (current-global-map) [remap list-buffers] 'ibuffer) (define-key (current-global-map) [remap kill-buffer] 'kill-current-buffer) (global-set-key (kbd "M-*") 'pop-tag-mark) ;; Not define by default. (global-set-key (kbd "C-c d d") 'kill-whole-line) (global-set-key (kbd "C-c w s") 'visual-line-mode) (global-set-key (kbd "S-C-") 'shrink-window-horizontally) (global-set-key (kbd "S-C-") 'enlarge-window-horizontally) (global-set-key (kbd "S-C-") 'shrink-window) (global-set-key (kbd "S-C-") 'enlarge-window) (global-set-key (kbd "C-z") 'move-text-down) (global-set-key (kbd "C-q") 'move-text-up) (global-set-key (kbd "C-c t c") 'avy-goto-char) (global-set-key (kbd "C-c t w") 'avy-goto-word-0) ;;; Functions. ----- ;;RecentFiles (defun my/recentf-open-files-compl () (interactive) (recentf-mode 1) (let* ((tocpl (mapcar (lambda (x) (cons (file-name-nondirectory x) x)) recentf-list)) (fname (completing-read "Recent-file name: " tocpl nil nil))) (when fname (find-file (cdr (assoc-string fname tocpl)))))) (global-set-key "\C-x\C-r" 'my/recentf-open-files-compl) ;; Half page up/down (defun my/half-page-up () (interactive) ;; (scroll-down-command ) (move-to-window-line-top-bottom 0) (recenter)) (global-set-key (kbd "M-p") 'my/half-page-up) (defun my/half-page-down () (interactive) (if (eq (line-number-at-pos) (line-number-at-pos (window-start))) ;; If the cursor is at the top of the page, move it to the center (progn (let ((middle-line (1+ (/ (window-height) 2)))) (move-to-window-line middle-line))) ;; (scroll-up scroll-amount) (move-to-window-line -1 ) (recenter))) (global-set-key (kbd "M-n") 'my/half-page-down) ;; Split window and follow cursor. ----- (defun my/split-and-follow-horizontaly () (interactive) (split-window-below) (balance-windows) (other-window 1)) (global-set-key (kbd "C-x 2") 'my/split-and-follow-horizontaly) (defun my/split-and-follow-verticaly () (interactive) (split-window-right) (balance-windows) (other-window 1)) (global-set-key (kbd "C-x 3") 'my/split-and-follow-verticaly) ;; Kill whole word/line (defun my/kill-whole-word () (interactive) (forward-char 1) (backward-word) (kill-word 1)) (global-set-key (kbd "C-c d w") 'my/kill-whole-word) ;; Copy whole word/line (defun my/copy-whole-word () (interactive) (forward-char 1) (backward-word) (mark-word 1) (kill-word 1) (yank)) (global-set-key (kbd "C-c w w") 'my/copy-whole-word) (defun my/copy-whole-line () (interactive) (save-excursion (kill-new (buffer-substring (point-at-bol) (point-at-eol))))) (global-set-key (kbd "C-c w l") 'my/copy-whole-line) ;; Duplicate Line. (defun my/duplicate-line () "Duplicate current line" (interactive) (let ((column (- (point) (point-at-bol))) (line (let ((s (thing-at-point 'line t))) (if s (string-remove-suffix "\n" s) "")))) (move-end-of-line 1) (newline) (insert line) (move-beginning-of-line 1) (forward-char column))) (global-set-key (kbd "C-,") 'my/duplicate-line) ;; Flash mode-line. ------ (defun flash-mode-line () (invert-face 'mode-line) (run-with-timer 0.1 nil #'invert-face 'mode-line)) (setq visible-bell nil ring-bell-function 'flash-mode-line) ;; Starttime ------ (add-to-list 'after-init-hook (lambda () (message (concat "emacs (" (number-to-string (emacs-pid)) ") started in " (emacs-init-time))))) (defun push-mark-no-activate () "Pushes `point' to `mark-ring' and does not activate the region Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled" (interactive) (push-mark (point) t nil) (message "Pushed mark to ring")) (global-set-key (kbd "C-`") 'push-mark-no-activate) (defun jump-to-mark () "Jumps to the local mark, respecting the `mark-ring' order. This is the same as using \\[set-mark-command] with the prefix argument." (interactive) (set-mark-command 1)) (global-set-key (kbd "M-`") 'jump-to-mark) ;; (defun exchange-point-and-mark-no-activate () ;; "Identical to \\[exchange-point-and-mark] but will not activate the region." ;; (interactive) ;; (exchange-point-and-mark) ;; (deactivate-mark nil)) ;; (define-key global-map [remap exchange-point-and-mark] 'exchange-point-and-mark-no-activate)