资源说明:emacs dotfiles and plugins
#+TITLE: ~.emacs.d~ * Synopsis Emacs configuration files written with the help of [[https://orgmode.org/][org-mode]] and [[https://orgmode.org/worg/org-contrib/babel/][org-babel]] * Install Emacs with ~homebrew~ #+BEGIN_SRC shell brew install emacs-plus@28 --with-mailutils --with-no-frame-refocus --with-xwidgets --with-native-comp #+END_SRC To start a bg service, run: #+BEGIN_SRC xml brew services start d12frosted/emacs-plus/emacs-plus@28 #+END_SRC * Tidy up .emacs.d mess #+begin_src emacs-lisp (use-package no-littering) #+end_src * Better package management ** Better list-package mode #+BEGIN_SRC emacs-lisp (use-package paradox :custom (paradox-github-token t) :config (paradox-enable)) #+END_SRC ** Quelpa & use-packlage #+begin_src emacs-lisp (use-package quelpa-use-package :ensure nil :config (unless (package-installed-p 'quelpa) (with-temp-buffer (url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el") (eval-buffer) (quelpa-self-upgrade) (quelpa '(quelpa-use-package :fetcher git :url "https://github.com/quelpa/quelpa-use-package.git")) (require 'quelpa-use-package)))) #+end_src ** Auto minor-mode for use-package #+BEGIN_SRC emacs-lisp (use-package auto-minor-mode) #+END_SRC ** Ensure system-package #+BEGIN_SRC emacs-lisp (use-package system-packages :custom (system-packages-package-manager 'brew)) (use-package use-package-ensure-system-package :after system-packages) #+END_SRC * Initialiation defaults ** Async #+begin_src emacs-lisp (use-package async) #+end_src ** Measure startup time #+BEGIN_SRC emacs-lisp (add-hook 'emacs-startup-hook (lambda () (message "*** Emacs loaded in %s with %d garbage collections." (format "%.2f seconds" (float-time (time-subtract after-init-time before-init-time))) gcs-done))) #+END_SRC ** Starting the server if not already started #+begin_src emacs-lisp (if (and (fboundp 'server-running-p) (not (server-running-p))) (server-start)) #+end_src ** Electric pairs only for prog-mode #+begin_src emacs-lisp (add-hook 'prog-mode-hook (lambda () (electric-pair-mode 1))) #+end_src ** Focus new frame #+begin_src emacs-lisp (when (featurep 'ns) (defun ns-raise-emacs () "Raise Emacs." (ns-do-applescript "tell application \"Emacs\" to activate")) (defun ns-raise-emacs-with-frame (frame) "Raise Emacs and select the provided frame." (with-selected-frame frame (when (display-graphic-p) (ns-raise-emacs)))) (add-hook 'after-make-frame-functions 'ns-raise-emacs-with-frame) (when (display-graphic-p) (ns-raise-emacs))) #+end_src ** Errors handling and ignore server errors When running as a deamon emacs checks if custom.el is in safe place. Here were setting custom.el in ~/tmp~ dir and it will sometimes throw an errors. Here is a dirty hack. #+BEGIN_SRC emacs-lisp (defadvice server-ensure-safe-dir (around my-around-server-ensure-safe-dir activate) "Ignores any errors raised from server-ensure-safe-dir" (ignore-errors ad-do-it)) #+end_src Disable native-compile warnings when starting emacs. Warnings should not break the init of Emacs. #+begin_src emacs-lisp (setq warning-minimum-level :error) #+end_src ** Setting default coding system #+BEGIN_SRC emacs-lisp (set-language-environment 'utf-8) (set-keyboard-coding-system 'utf-8-mac) ; For old Carbon emacs on OS X only (setq locale-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (set-terminal-coding-system 'utf-8) (set-selection-coding-system 'utf-8) (prefer-coding-system 'utf-8) #+END_SRC ** Setting default display and editing options #+BEGIN_SRC emacs-lisp (set-default 'truncate-lines t) (global-hl-line-mode 0) (set-window-margins nil 0 0) (electric-pair-mode 0) (line-number-mode 1) (column-number-mode 1) (global-linum-mode 0) (delete-selection-mode 1) (global-auto-revert-mode 1) (menu-bar-mode -1) (use-package desktop :ensure nil :custom (desktop-save 'ask-if-new) (desktop-restore-eager 5) (desktop-load-locked-desktop t) (desktop-auto-save-timeout 30) (desktop-base-lock-name "lock") (desktop-files-not-to-save "^$") :config (desktop-save-mode +1)) (setq left-fringe-width 16 right-fringe-width 16 auto-save-default nil frame-resize-pixelwise t frame-title-format nil inhibit-startup-screen t make-backup-files nil ns-use-proxy-icon nil pop-up-frames nil ring-bell-function 'ignore show-paren-mode 1 show-trailing-whitespace nil transient-mark-mode t vc-handled-backends nil ns-right-alternate-modifier nil create-lockfiles nil visible-bell t split-height-threshold 80 split-width-threshold 160 compilation-scroll-output t) (fset 'yes-or-no-p 'y-or-n-p) ;;http://mbork.pl/2021-11-13_y-or-n-p_but_with_RET_meaning_yes (defconst y-or-n-p-ret-yes-map (let ((map (make-sparse-keymap))) (set-keymap-parent map y-or-n-p-map) (define-key map [return] 'act) map) "A keymap for y-or-n-p with RET meaning \"yes\".") (setq y-or-n-p-map y-or-n-p-ret-yes-map) (global-unset-key (kbd "C-x C-c")) (global-unset-key (kbd "S-w")) (global-unset-key (kbd "C-x C-z")) (windmove-default-keybindings 'super) (winner-mode 1) ;; font sizes (global-set-key (kbd "s-=") (lambda () (interactive) (let ((old-face-attribute (face-attribute 'default :height))) (message (format "Changed font size to %d" (+ old-face-attribute 10))) (set-face-attribute 'default nil :height (+ old-face-attribute 10))))) (global-set-key (kbd "s--") (lambda () (interactive) (let ((old-face-attribute (face-attribute 'default :height))) (message (format "Changed font size to %d" (- old-face-attribute 10))) (set-face-attribute 'default nil :height (- old-face-attribute 10))))) (global-set-key "\C-l" 'goto-line) (global-set-key (kbd "") 'keyboard-escape-quit) (global-set-key (kbd "M-s- ") 'tab-next) (global-set-key (kbd "M-s- ") 'tab-previous) (tab-bar-mode 1) #+END_SRC ** Alerter - notifications for macos #+begin_src emacs-lisp (defun alerter--symbol-value (symbol) "Stripts keyword symbol name from a colon" (replace-regexp-in-string "^:" "" (symbol-name symbol))) (defun alerter--option (args) "Returns a function that will generate single argument for alerter using ARGS as a string" (lambda (key) (concat "-" (alerter--symbol-value key) " " (plist-get args key)))) (setq alerter-default-args '(:title "Emacs" :sender "org.gnu.Emacs" :timeout "5")) (defun alerter (message &rest args) "Notify user using native macOS notifications. MESSAGE will be displayed using alerter package, with additional ARGS" (if (executable-find "alerter") (let* ((args (append alerter-default-args args)) (options (seq-filter (lambda (element) (keywordp element)) args)) (config (mapconcat (alerter--option args) options " ")) (cmd (concat "alerter " config " -message \"" (replace-regexp-in-string "\"" "\\\"" message t t) "\" &"))) (message cmd) (call-process-shell-command cmd)) (error "Can't find alerter executable"))) #+end_src ** Check on save if config is valid #+begin_src emacs-lisp (setq check-if-config-valid-files '("init.el" "early-init.el" "README.org")) (defun check-if-config-valid () (alerter "Checking config..." :group "check-config" ) (async-start (lambda () (call-process-shell-command "./scripts/validate")) (lambda (results) (if (< 0 results ) (alerter "Problem with emacs config!" :group "check-config" :sound "funky" ) (alerter "Config valid!" :group "check-config" ))))) (defun current-file-is-config () (member t (mapcar (lambda (file) (message (expand-file-name file user-emacs-directory)) (message (buffer-file-name)) (equal (expand-file-name file user-emacs-directory) (buffer-file-name))) check-if-config-valid-files))) (add-hook 'after-save-hook (lambda () (if (current-file-is-config) (check-if-config-valid)))) #+end_src ** xwidget-webkit problem with emacsclient We need to redefine ~xwidget-webkit-enable-plugins~ variable for webkit to work properly #+begin_src emacs-lisp (if (boundp 'xwidget-webkit-enable-plugins) (setq xwidget-webkit-enable-plugins t) (defvar xwidget-webkit-enable-plugins t)) #+end_src ** Default trash behavior #+BEGIN_SRC emacs-lisp (use-package osx-trash :if (eq system-type 'darwin) :ensure-system-package trash :init (osx-trash-setup) :custom (delete-by-moving-to-trash t)) #+END_SRC ** System specific defaults #+BEGIN_SRC emacs-lisp (when (eq system-type 'darwin) (defvar ls-lisp-use-insert-directory-program) (defvar powerline-image-apple-rgb) (setq ns-use-srgb-colorspace t) (setq powerline-image-apple-rgb t) (require 'ls-lisp) (setq ls-lisp-use-insert-directory-program nil)) #+END_SRC ** Disabling suspend-frame binding Very annoying binding, lets get rid of it. #+BEGIN_SRC emacs-lisp (global-unset-key (kbd "C-z")) #+END_SRC ** Browser Url Set build-in module defaults to handle chrome as a default browser #+BEGIN_SRC emacs-lisp (use-package browse-url :custom (browse-url-browser-function 'browse-url-default-browser)) (use-package browse-url-dwim :config (browse-url-dwim-mode 1)) #+END_SRC ** Mac Only - initialize emacs with proper PATH Move your env variables to ~.zshenv~ befre setting this up #+BEGIN_SRC emacs-lisp (use-package exec-path-from-shell :custom (exec-path-from-shell-arguments nil) :config (when (or (memq window-system '(ns x)) (daemonp)) (exec-path-from-shell-initialize) (exec-path-from-shell-copy-env "GOPATH") (when (eq (length (getenv "NODE_PATH")) 0) (setenv "NODE_PATH" "/usr/local/lib/node_modules")))) #+END_SRC ** EasyGP Assistant #+begin_src emacs-lisp (use-package epa :if (eq system-type 'darwin) :ensure-system-package (gpg pinentry-mac)) (use-package epa :if (eq system-type 'gnu/linux)) #+end_src when staring, we should prepare our [[https://cerb.ai/guides/mail/gpg-setup-on-mac/][gpg config]] #+begin_src sh gpg --list-keys echo "pinentry-program /usr/local/bin/pinentry-mac" >> $HOME/.gnupg/gpg-agent.conf gpg --expert --full-generate-key #+end_src * Window management and frame management ** Pooper (link) #+begin_src emacs-lisp (use-package popper :ensure t ; or :straight t :bind (("s-§" . popper-toggle-latest) ("M-§" . popper-cycle) ("s-M-§" . popper-toggle-type) ("s- " . popper-toggle-latest) ("M- " . popper-cycle) ("s-M- " . popper-toggle-type)) :custom (popper-reference-buffers '("\\*Messages\\*" "Output\\*$" "\\*Async Shell Command\\*" compilation-mode vterm-mode)) (popper-mode-line '(:eval (propertize " POP " 'face 'mode-line-emphasis))) :config (popper-mode +1) (popper-echo-mode +1)) #+end_src ** Shackle ([[https://github.com/wasamasa/shackle][link]]) *Shackle* gives you the means to put an end to popped up buffers not behaving they way you'd like them to. By setting up simple rules you can for instance make Emacs always select help buffers for you or make everything reuse your currently selected window. #+BEGIN_SRC emacs-lisp (use-package shackle :custom (shackle-rules '(("*eshell*" :select t :other t) (flycheck-error-list-mode :select t :align below :size 0.25) (compilation-mode :select nil :align below :size 0.25) (messages-buffer-mode :select t :align below :size 0.25) (inferior-emacs-lisp-mode :select t :align below :size 0.25) (help-mode :select t :align right :size 0.5) (helpful-mode :select t :align right :size 0.5) ("*rg*" :select t :other t) (" *Deletions*" :select t :align below :size 0.25) (" *Marked Files*" :select t :align below :size 0.25) ("*Org Select*" :same t) ("*Org Note*" :select t :align below :size 0.33) ("*Org Links*" :select t :align below :size 0.2) (" *Org todo*" :select t :align below :size 0.2) ("*Man.*" :select t :align below :size 0.5 :regexp t) ("*Org Src.*" :select t :align right :size 0.5 :regexp t))) :config (shackle-mode t)) #+END_SRC * Packages ** Bufler #+begin_src emacs-lisp (use-package bufler :quelpa (bufler :fetcher github :repo "alphapapa/bufler.el" :files (:defaults (:exclude "helm-bufler.el")))) #+end_src ** Eshell ([[https://masteringemacs.org/article/complete-guide-mastering-eshell][link]]) *Eshell* is a shell written entirely in Emacs-Lisp, and it replicates most of the features and commands from GNU CoreUtils and the Bourne-like shells. So by re-writing common commands like ls and cp in Emacs-Lisp, Eshell will function identically on any environment Emacs itself runs on. #+BEGIN_SRC emacs-lisp (use-package eshell :custom (eshell-banner-message "") (eshell-scroll-to-bottom-on-input t) (eshell-error-if-no-glob t) (eshell-hist-ignoredups t) (eshell-save-history-on-exit t) (eshell-prefer-lisp-functions nil) (eshell-destroy-buffer-when-process-dies t) (eshell-highlight-prompt nil) :config (setenv "PAGER" "cat") (setenv "PATH" (concat "/usr/local/bin:/usr/local/sbin:" (getenv "PATH"))) (defun eshell/gst (&rest args) (magit-status (pop args) nil) (eshell/echo))) (use-package xterm-color :after (eshell eshell-toggle) :hook (eshell-before-prompt . (lambda () (setq xterm-color-preserve-properties t))) (eshell-preoutput-filter-functions . xterm-co§§§§§§§§§§§§lor-filter) (shell-mode . (lambda () ;; Disable font-locking in this buffer to improve performance (font-lock-mode -1) ;; Prevent font-locking from being re-enabled in this buffer (make-local-variable 'font-lock-function) (setq font-lock-function (lambda (_) nil)) (add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t))) :custom (comint-output-filter-functions (remove 'ansi-color-process-output comint-output-filter-functions)) (eshell-output-filter-functions (remove 'eshell-handle-ansi-color eshell-output-filter-functions)) :config) (use-package eshell-up :after eshell) (use-package shrink-path :after eshell :custom ((eshell-prompt-regexp "^.*❯ ") (eshell-prompt-function (lambda nil (let ((base/dir (shrink-path-prompt default-directory))) (concat (propertize (car base/dir) 'face 'font-lock-comment-face) (propertize (cdr base/dir) 'face 'font-lock-constant-face) (propertize " ❯" 'face 'eshell-prompt-face) ;; needed for the input text to not have prompt face (propertize " " 'face 'default))))))) #+END_SRC ** Toogle undecorated frame #+BEGIN_SRC emacs-lisp (defun toggle-frame-maximized-undecorated () (interactive) (let* ((frame (selected-frame)) (on? (and (frame-parameter frame 'undecorated) (eq (frame-parameter frame 'fullscreen) 'maximized))) (geom (frame-monitor-attribute 'geometry)) (initial-x (first geom)) (display-height (first (last geom)))) (if on? (progn (set-frame-parameter frame 'undecorated nil) (toggle-frame-maximized)) (progn (set-frame-position frame initial-x 0) (set-frame-parameter frame 'fullscreen 'maximized) (set-frame-parameter frame 'undecorated t) (set-frame-height frame (- display-height 26) nil t) (set-frame-position frame initial-x 0))))) #+END_SRC ** Scratch ([[https://github.com/ieure/scratch-el][link]]) Scratch is an extension to Emacs that enables one to create scratch buffers that are in the same mode as the current buffer. This is notably useful when working on code in some language; you may grab code into a scratch buffer, and, by virtue of this extension, do so using the Emacs formatting rules for that language. #+BEGIN_SRC emacs-lisp (use-package scratch) #+END_SRC ** Eshell Toggle ([[https://github.com/4DA/eshell-toggle][link]]) Simple functionality to show/hide eshell/ansi-term (or almost any other buffer, see eshell-toggle-init-function description below) at the bottom of active window with directory of its buffer. #+BEGIN_SRC emacs-lisp (use-package eshell-toggle :after eshell :bind ("s-`" . eshell-toggle) :custom (eshell-toggle-name-separator " ❯ ") (eshell-toggle-size-fraction 3) (eshell-toggle-use-projectile-root t)) #+END_SRC ** ESUP #+begin_src emacs-lisp (use-package esup) #+end_src ** vterm #+BEGIN_SRC emacs-lisp (use-package vterm :after consult :custom (vterm-always-compile-module t)) (use-package multi-vterm :after vterm) #+END_SRC ** Marginalia #+begin_src emacs-lisp ;; Enable richer annotations using the Marginalia package (use-package marginalia ;; Either bind `marginalia-cycle` globally or only in the minibuffer :bind (: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)) #+end_src ** Editor Config ([[https://github.com/editorconfig/editorconfig-emacs][link]]) *EditorConfig* helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems. #+BEGIN_SRC emacs-lisp (use-package editorconfig :init (editorconfig-mode 1)) #+END_SRC ** Posframe #+BEGIN_SRC emacs-lisp (use-package posframe :ensure t) #+END_SRC ** Expand region #+BEGIN_SRC emacs-lisp (use-package expand-region :bind ("C-=" . er/expand-region)) #+END_SRC ** Restart Emacs #+BEGIN_SRC emacs-lisp (use-package restart-emacs) #+END_SRC ** All the icons ([[https://github.com/domtronn/all-the-icons.el][link]]) A utility package to collect various Icon Fonts and propertize them within Emacs. #+BEGIN_SRC emacs-lisp (use-package all-the-icons :custom (inhibit-compacting-font-caches t)) #+END_SRC ** Projectile ([[https://github.com/bbatsov/projectile][link]]) Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies (when feasible) #+BEGIN_SRC emacs-lisp (use-package projectile :demand t :bind-keymap ("C-c p" . projectile-command-map) :custom (projectile-enable-caching t) (projectile-sort-order 'recently-active) :config (projectile-mode) ;; Projectile is testing in the reverse order so more specific must me at the end (projectile-register-project-type 'npm '("package.json") :compile "npm i" :test "npm test" :run "npm start" :test-suffix ".spec.js") (projectile-register-project-type 'opera '("desktop/BUILD.gn" "desktop/gn_opera.py") :project-file "desktop/BUILD.gn" :configure "desktop/gn_opera.py --release --force product=\\\"gx\\\" use_jumbo_build=false rich_hints_test_build=true use_goma=true goma_dir=\"\\\"/Users/opera_user/goma\\\"\"" :compile "ninja -j 150 -C chromium/src/out/Release opera")) #+END_SRC ** ibuffer-projectile ([[https://github.com/purcell/ibuffer-projectile][link]]) #+begin_src emacs-lisp (use-package ibuffer-projectile :hook (ibuffer . (lambda () (ibuffer-projectile-set-filter-groups) (unless (eq ibuffer-sorting-mode 'alphabetic) (ibuffer-do-sort-by-alphabetic))))) #+end_src ** Vertico ([[https://github.com/minad/vertico][link]]) #+begin_src emacs-lisp (use-package vertico :init :custom (vertico-resize nil) (vertico-cycle t) :config (vertico-mode 1)) #+end_src also helpful emacs config just for vertico #+begin_src emacs-lisp (use-package emacs :ensure nil :init ;; Add prompt indicator to `completing-read-multiple'. ;; Alternatively try `consult-completing-read-multiple'. (defun crm-indicator (args) (cons (concat "[CRM] " (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) :hook (minibuffer-setup . cursor-intangible-mode) :custom ;; Do not allow the cursor in the minibuffer prompt (minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) ;; Emacs 28: Hide commands in M-x which do not work in the current mode. ;; Vertico commands are hidden in normal buffers. (read-extended-command-predicate #'command-completion-default-include-p) ;; Enable recursive minibuffers (enable-recursive-minibuffers t)) #+end_src ** Orderless ([[https://github.com/oantolin/orderless][link]]) #+begin_src emacs-lisp (use-package orderless :custom (completion-styles '(orderless)) (completion-category-defaults nil) (completion-category-overrides '((file (styles partial-completion))) (orderless-component-separator #'orderless-escapable-split-on-space))) #+end_src ** Savehist #+begin_src emacs-lisp (use-package savehist :after no-littering :init (savehist-mode)) #+end_src ** Consult ([[https://github.com/minad/consult][link]]) #+begin_src emacs-lisp ;; Example configuration for Consult (use-package consult :after projectile :demand t ;; Replace bindings. Lazily loaded due by `use-package'. :bind (;; C-c bindings (mode-specific-map) ("C-c h" . consult-history) ("C-c m" . consult-mode-command) ("C-c b" . consult-bookmark) ("C-c k" . consult-kmacro) ;; C-x bindings (ctl-x-map) ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command ("C-x b" . consult-buffer) ;; orig. switch-to-buffer ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame ;; Custom M-# bindings for fast register access ("M-#" . consult-register-load) ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) ("C-M-#" . consult-register) ;; Other custom bindings ("M-y" . consult-yank-pop) ;; orig. yank-pop (" a" . consult-apropos) ;; orig. apropos-command ;; M-g bindings (goto-map) ("M-g e" . consult-compile-error) ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck ("M-g g" . consult-goto-line) ;; orig. goto-line ("M-g M-g" . consult-goto-line) ;; orig. goto-line ("M-g o" . consult-outline) ;; Alternative: consult-org-heading ("M-g m" . consult-mark) ("M-g k" . consult-global-mark) ("M-g i" . consult-imenu) ("M-g I" . consult-imenu-multi) ;; M-s bindings (search-map) ("M-s f" . consult-find) ("M-s F" . consult-locate) ("M-s g" . consult-grep) ("M-s G" . consult-git-grep) ("M-s r" . consult-ripgrep) ("M-s l" . consult-line) ("M-s L" . consult-line-multi) ("M-s m" . consult-multi-occur) ("M-s k" . consult-keep-lines) ("M-s u" . consult-focus-lines) ;; Isearch integration ("M-s e" . consult-isearch-history) :map isearch-mode-map ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string ("M-s l" . consult-line) ;; needed by consult-line to detect isearch ("M-s L" . consult-line-multi)) ;; needed by consult-line to detect isearch ;; Enable automatic preview at point in the *Completions* buffer. ;; This is relevant when you use the default completion UI, ;; and not necessary for Vertico, Selectrum, etc. ;; The :init configuration is always executed (Not lazy) :init ;; Optionally configure the register formatting. This improves the register ;; preview for `consult-register', `consult-register-load', ;; `consult-register-store' and the Emacs built-ins. (setq register-preview-delay 0 register-preview-function #'consult-register-format) ;; Optionally tweak the register preview window. ;; This adds thin lines, sorting and hides the mode line of the window. (advice-add #'register-preview :override #'consult-register-window) ;; Optionally replace `completing-read-multiple' with an enhanced version. (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple) ;; Use Consult to select xref locations with preview (setq xref-show-xrefs-function #'consult-xref xref-show-definitions-function #'consult-xref) ;; Configure other variables and modes in the :config section, ;; after lazily loading the package. :config ;; Optionally configure preview. The default value ;; is 'any, such that any key triggers the preview. ;; (setq consult-preview-key 'any) ;; (setq consult-preview-key (kbd "M-.")) ;; (setq consult-preview-key (list (kbd " ") (kbd " "))) ;; For some commands and buffer sources it is useful to configure the ;; :preview-key on a per-command basis using the `consult-customize' macro. (consult-customize consult-theme :preview-key '(:debounce 0.2 any) consult-ripgrep consult-git-grep consult-grep consult-bookmark consult-recent-file consult-xref consult--source-buffer consult--source-project-buffer consult--source-bookmark :preview-key (kbd "M-.")) ;; Optionally configure the narrowing key. ;; Both < and C-+ work reasonably well. (setq consult-narrow-key "<") ;; (kbd "C-+") (autoload 'projectile-project-root "projectile") (setq consult-project-root-function #'projectile-project-root)) #+end_src ** Consult Projectile ([[https://github.com/emacsmirror/consult-projectile][link]]) #+begin_src emacs-lisp (use-package consult-projectile :demand t :after (consult projectile) :bind-keymap ("C-c p" . projectile-command-map) :bind (:map projectile-command-map ("p" . consult-projectile)) :custom (projectile-switch-project-action 'consult-projectile)) #+end_src ** Embark ([[https://github.com/oantolin/embark/][link]]) #+begin_src emacs-lisp (defun embark-which-key-indicator () "An embark indicator that displays keymaps using which-key. The which-key help message will show the type and value of the current target followed by an ellipsis if there are further targets." (lambda (&optional keymap targets prefix) (if (null keymap) (which-key--hide-popup-ignore-command) (which-key--show-keymap (if (eq (plist-get (car targets) :type) 'embark-become) "Become" (format "Act on %s '%s'%s" (plist-get (car targets) :type) (embark--truncate-target (plist-get (car targets) :target)) (if (cdr targets) "…" ""))) (if prefix (pcase (lookup-key keymap prefix 'accept-default) ((and (pred keymapp) km) km) (_ (key-binding prefix 'accept-default))) keymap) nil nil t (lambda (binding) (not (string-suffix-p "-argument" (cdr binding)))))))) (use-package embark :after which-key :demand t :bind (("s-." . embark-act) ;; pick some comfortable binding ("C-;" . embark-dwim) ;; good alternative: M-. ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' :custom (embark-indicators '(embark-which-key-indicator embark-highlight-indicator embark-isearch-highlight-indicator)) (prefix-help-command #'embark-prefix-help-command) :config ;; Unbind help-command so completing-read interface can do it's job (unbind-key "C-h " global-map) (unbind-key "C-h" help-map) ;;(unbind-key "C-h" ehelp-map) ;; Hide the mode line of the Embark live/completions buffers (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil (window-parameters (mode-line-format . none))))) (defun embark-hide-which-key-indicator (fn &rest args) "Hide the which-key indicator immediately when using the completing-read prompter." (which-key--hide-popup-ignore-command) (let ((embark-indicators (remq #'embark-which-key-indicator embark-indicators))) (apply fn args))) (advice-add #'embark-completing-read-prompter :around #'embark-hide-which-key-indicator) #+end_src ** Embark Consult ([[https://github.com/oantolin/embark/blob/master/embark-consult.el][link]]) Consult users will also want the embark-consult package. #+begin_src emacs-lisp (use-package embark-consult :after (embark consult) :demand t :hook (embark-collect-mode . consult-preview-at-point-mode)) #+end_src ** Confu #+begin_src emacs-lisp (use-package corfu ;; Optional customizations :custom (completion-cycle-threshold 3) (tab-always-indent 'complete) (tab-first-completion 'word-or-paren-or-punct) (corfu-cycle t) (corfu-auto t) (corfu-commit-predicate nil) (corfu-quit-at-boundary t) (corfu-quit-no-match t) ;; Automatically quit if there is no match (corfu-echo-documentation 0.5) ;; Disable documentation in the echo area :init (corfu-global-mode)) ;; Use dabbrev with Corfu! (use-package dabbrev ;; Swap M-/ and C-M-/ :bind (("M-/" . dabbrev-completion) ("C-M-/" . dabbrev-expand))) ;; Enable Corfu completion UI ;; See the Corfu REA DME for more configuration tips. (use-package corfu :init (corfu-global-mode)) ;; Add extensions (use-package cape ;; Bind dedicated completion commands :bind (("C-." . completion-at-point) ("C-c /" . completion-fil)) :init (add-to-list 'completion-at-point-functions #'cape-file) (add-to-list 'completion-at-point-functions #'cape-tex) (add-to-list 'completion-at-point-functions #'cape-dabbrev) (add-to-list 'completion-at-point-functions #'cape-keyword)) #+end_src ** kind-icon () #+begin_src emacs-lisp (use-package kind-icon :ensure t :after corf :custom (kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) #+end_src ** K8s #+BEGIN_SRC emacs-lisp (use-package kubernetes :commands (kubernetes-overview) :custom ((kubernetes-commands-display-buffer-function 'display-buffer) (Kubernetes-Commands-display-buffer-select nil))) #+END_SRC ** Multiple Cursors ([[https://github.com/magnars/multiple-cursors.el][link]]) Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, there are kinks. Don't be afraid tho, I've been using it since 2011 with great success and much merriment. #+BEGIN_SRC emacs-lisp (use-package multiple-cursors :bind ("C->" . mc/mark-next-like-this) ("C-<" . mc/mark-previous-like-this)) #+END_SRC ** Org ([[https://orgmode.org/][link]]) Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text syste. #+BEGIN_SRC emacs-lisp (defmacro org-babel-add-langs (langs) `(org-babel-do-load-languages 'org-babel-load-languages (append org-babel-load-languages ',langs))) (defun alist-unique (alist) (reduce (lambda (output value) (let* ((key (car value)) (existing-value (alist-get key output))) (cond ((not output) (list value)) ((not existing-value) (append output (list value))) (t output)))) alist :initial-value nil)) (defun append-alist-unique (values alist) "Add unique VALUE to ALIST when car of VALUE is unique, returns ALIST otherwise" (alist-unique (append alist values))) (use-package org :hook (org-mode . turn-on-auto-fill) (org-src-mode . (lambda () (setq-local flycheck-disabled-checkers '(emacs-lisp-checkdoc)))) :bind ("C-c l" . org-store-link) ("C-c a" . org-agenda) ("C-c c" . org-capture) :config (org-babel-add-langs ((emacs-lisp . t))) (org-indent-mode t) (custom-set-faces '(org-ellipsis ((t (:foreground "gray40" :underline nil))))) (org-babel-add-langs ((ditaa . t))) :custom (org-modules '(org-protocol org-habit org-mouse org-tempo org-notify org-mac-link org-mac-iCal org-panel)) (org-blank-before-new-entry '((heading . t) (plain-list-item . t))) (org-hide-leading-stars t) (org-src-tab-acts-natively t) (org-startup-indented t) (org-babel-min-lines-for-block-output 1) (org-speed-command-help t) (org-startup-folded "showeverything") (org-startup-with-inline-images t) (org-src-preserve-indentation t) (org-ellipsis " … " ) (org-pretty-entities t) (org-hide-emphasis-markers t) (org-agenda-block-separator "") (org-fontify-whole-heading-line t) (org-fontify-done-headline t) (org-fontify-quote-and-verse-blocks t) (org-tags-column 0) (org-indent-indentation-per-level 1) (org-directory "~/Dropbox/org") (org-default-notes-file "notes.org") (org-agenda-files (list "inbox.org" "links.org" "todo.org" "done.org" "journal.org")) (org-refile-targets '((org-agenda-files :maxlevel . 1))) (org-refile-allow-creating-parent-nodes 'confirm) (org-capture-templates '(("a" "Appointment" entry (file "gcal.org" ) "* %?\n\n%^T\n\n:PROPERTIES:\n\n:END:\n\n") ("l" "Link" entry (file+headline "links.org" "Links") "* %? %^L %^g \n%T" :prepend t) ("b" "Blog idea" entry (file+headline "todo.org" "Blog Topics:") "* %?\n%T" :prepend t) ("t" "Todo Item" entry (file+headline "todo.org" "Todo") "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:" :prepend t :empty-lines 1) ("n" "Note" entry (file+headline "todo.org" "Note space") "* %?\n%u" :prepend t) ("j" "Journal" entry (file+olp+datetree "journal.org") "* %?\nEntered on %U\n %i\n %a") ))) #+END_SRC #+BEGIN_SRC emacs-lisp (use-package org-habit :ensure nil) (use-package org-contacts :ensure nil) (use-package org-tree-slide :custom (org-tree-slide-skip-outline-level 4) (org-tree-slide-skip-done nil) :config (global-set-key (kbd " ") 'org-tree-slide-mode) (global-set-key (kbd "S- ") 'org-tree-slide-skip-done-toggle) (define-key org-tree-slide-mode-map (kbd " ") 'org-tree-slide-move-previous-tree) (define-key org-tree-slide-mode-map (kbd " ") 'org-tree-slide-move-next-tree) (define-key org-tree-slide-mode-map (kbd " ") 'org-tree-slide-content) (org-tree-slide-narrowing-control-profile)) (use-package org-bullets :hook (org-mode . org-bullets-mode)) ;; org-babel (org-babel-add-langs ((emacs-lisp . t) (shell . t))) (use-package ob-restclient :config (org-babel-add-langs ((restclient . t)))) (use-package ob-js :ensure nil :config (org-babel-add-langs ((js . t))) (add-to-list 'org-babel-tangle-lang-exts '("js" . "js"))) (use-package ob-deno :config (org-babel-add-langs ((deno . t)))) (use-package org-super-agenda :init :custom (org-super-agenda-groups ;; Each group has an implicit boolean OR operator between its selectors. '((:name "Today" ; Optionally specify section name :time-grid t ; Items that appear on the time grid :todo "TODAY") ; Items that have this TODO keyword (:name "Important" ;; Single arguments given alone :tag "bills" :priority "A") ;; Set order of multiple groups at once (:order-multi (2 (:name "Shopping in town" ;; Boolean AND group matches items that match all subgroups :and (:tag "shopping" :tag "@town")) (:name "Food-related" ;; Multiple args given in list with implicit OR :tag ("food" "dinner")) (:name "Personal" :habit t :tag "personal") (:name "Space-related (non-moon-or-planet-related)" ;; Regexps match case-insensitively on the entire entry :and (:regexp ("space" "NASA") ;; Boolean NOT also has implicit OR between selectors :not (:regexp "moon" :tag "planet"))))) ;; Groups supply their own section names when none are given (:todo "WAITING" :order 8) ; Set order of this section (:todo ("SOMEDAY" "TO-READ" "CHECK" "TO-WATCH" "WATCHING") ;; Show this group at the end of the agenda (since it has the ;; highest number). If you specified this group last, items ;; with these todo keywords that e.g. have priority A would be ;; displayed in that group instead, because items are grouped ;; out in the order the groups are listed. :order 9) (:priority<= "B" ;; Show this section after "Today" and "Important", because ;; their order is unspecified, defaulting to 0. Sections ;; are displayed lowest-number-first. :order 1) ;; After the last group, the agenda will display items that didn't ;; match any of these groups, with the default order position of 99 )) (org-super-agenda-mode)) (defun make-orgcapture-frame () "Create a new frame and run org-capture." (interactive) (make-frame '((name . "remember") (width . 80) (height . 16) (top . 400) (left . 300) (font . "-apple-Monaco-medium-normal-normal-*-13-*-*-*-m-0-iso10646-1") )) (select-frame-by-name "remember") (org-capture) (delete-other-windows)) (use-package yequake :custom (yequake-frames '(("org-capture" (buffer-fns . (yequake-org-capture)) (width . 0.75) (height . 0.5) (alpha . 0.95) (frame-parameters . ((undecorated . t) (skip-taskbar . t) (sticky . t))))))) #+END_SRC ** Org Roam #+begin_src emacs-lisp (defun org-roam-node-insert-immediate (arg &rest args) "This will allow you to quickly create new notes for topics you're mentioning while writing so that you can go back later and fill those notes in with more details!" (interactive "P") (let ((args (cons arg args)) (org-roam-capture-templates (list (append (car org-roam-capture-templates) '(:immediate-finish t))))) (apply #'org-roam-node-insert args))) (defun my/org-roam-filter-by-tag (tag-name) "returns a filter function for " (lambda (node) (member tag-name (org-roam-node-tags node)))) (defun my/org-roam-list-notes-by-tag (tag-name) "Returns list of noted with given filetag" (mapcar #'org-roam-node-file (seq-filter (my/org-roam-filter-by-tag tag-name) (org-roam-node-list)))) (defun my/org-roam-refresh-agenda-list () "Refreshes the agenda list adding Project notes to the list" (interactive) (setq org-agenda-files (my/org-roam-list-notes-by-tag "Project"))) (use-package org-roam :custom (org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) (org-roam-directory "~/Dropbox/OrgRoam") (org-roam-completion-everywhere t) (org-roam-capture-templates '(("d" "default" plain "%?" :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n") :unnarrowed t) ("p" "project" plain (file "~/Dropbox/OrgRoam/Templates/Project.org") :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+category: ${title}\n#+filetags: Project") :unnarrowed t))) :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) ("C-c n I" . org-roam-node-insert-immediate) ;; Dailies ("C-c n j" . org-roam-dailies-capture-today) :map org-mode-map ("C-M-i" . completion-at-point) :map org-roam-dailies-map ("Y" . org-roam-dailies-capture-yesterday) ("T" . org-roam-dailies-capture-tomorrow)) :bind-keymap ("C-c n d" . org-roam-dailies-map) :custom-face (org-roam-link ((t (:foreground "#e24888" :underline t)))) (org-roam-link-current ((t (:foreground "#e24888" :underline t)))) :config (org-roam-setup) (require 'org-roam-dailies) (org-roam-db-autosync-mode) (my/org-roam-refresh-agenda-list)) #+end_src ** Htmlize for org-mode #+BEGIN_SRC emacs-lisp (use-package htmlize) #+END_SRC ** Load theme #+BEGIN_SRC emacs-lisp (use-package doom-themes :config (load-theme 'doom-molokai t) (doom-themes-org-config) (doom-themes-visual-bell-config) (doom-themes-neotree-config)) #+END_SRC ** Better defaults #+BEGIN_SRC emacs-lisp (use-package better-defaults) #+END_SRC ** Key suffixes popup #+BEGIN_SRC emacs-lisp (use-package which-key :init (which-key-mode) :custom ((which-key-popup-type 'side-window) (which-key-side-window-location 'bottom) (which-key-side-window-max-width 0.33) (which-key-side-window-max-height 0.25))) #+END_SRC ** Editing forms in chrome #+BEGIN_SRC emacs-lisp (use-package atomic-chrome :config (atomic-chrome-start-server)) #+END_SRC ** Better help dialogs #+BEGIN_SRC emacs-lisp (use-package helpful :bind (("C-h f" . helpful-callable) ("C-h v" . helpful-variable) ("C-h k" . helpful-key))) #+END_SRC ** Better list-package mode #+BEGIN_SRC emacs-lisp (use-package paradox :custom (paradox-github-token t) :config (paradox-enable)) #+END_SRC ** Cycling between different var notations #+BEGIN_SRC emacs-lisp (use-package string-inflection :bind ("C-c C-u" . string-inflection-all-cycle)) #+END_SRC ** Open dash at point #+BEGIN_SRC emacs-lisp (use-package dash-at-point :bind ("C-c d" . dash-at-point) ("C-c e" . dash-at-point-with-docset)) #+END_SRC ** Move lines using alt + arrows #+BEGIN_SRC emacs-lisp (use-package move-text :config (move-text-default-bindings)) #+END_SRC ** Anzu - current match / all matches in modeline #+BEGIN_SRC emacs-lisp (use-package anzu :init (global-anzu-mode +1) :bind ("M-%" . anzu-query-replace) ("C-M-%" . anzu-query-replace-regexp)) #+END_SRC ** Modeline #+BEGIN_SRC emacs-lisp (use-package doom-modeline :after all-the-icons :custom ((doom-modeline-icon t) (doom-modeline-major-mode-icon t) (doom-modeline-major-mode-color-icon t) (doom-modeline-buffer-state-icon t) (doom-modeline-buffer-modification-icon t) (doom-modeline-minor-modes nil) (doom-modeline-checker-simple-format t)) :hook (after-init . doom-modeline-mode)) #+END_SRC ** Magit - best git client ever #+BEGIN_SRC emacs-lisp (use-package magit :init :bind ("C-x g" . magit-status) :hook (global-git-commit-mode . flyspell-mode) :custom (vc-handled-backends nil) (magit-process-finish-apply-ansi-colors t) (magit-refresh-status-buffer t) (magit-blame-goto-chunk-hook '(magit-blame-maybe-show-message)) :config (remove-hook 'magit-refs-sections-hook 'magit-insert-tags) (add-hook 'magit-process-find-password-functions 'magit-process-password-auth-source) (transient-define-suffix magit-submodule-update-all () "Update all submodules" :description "Update All (git submodule update --init --recursive)" (interactive) (magit-with-toplevel (magit-run-git-async "submodule" "update" "--init" "--recursive")))) #+END_SRC #+BEGIN_SRC emacs-lisp (use-package forge :after magit :config (add-to-list 'forge-alist '("gitlab.services.ams.osa" "gitlab.services.ams.osa/api/v4" "gitlab.services.ams.osa" forge-gitlab-repository))) #+END_SRC ** magit-todos ([[https://github.com/alphapapa/magit-todos][link]]) #+begin_src emacs-lisp (use-package magit-todos :after (magit) :config (magit-todos-mode 1)) #+end_src ** Magit Delta #+begin_src emacs-lisp (use-package magit-delta :ensure-system-package git-delta :hook (magit-mode . magit-delta-mode)) #+end_src ** git-gutter #+begin_src emacs-lisp (use-package git-gutter :hook (text-mode . git-gutter-mode) :config (setq git-gutter:update-interval 1)) (use-package git-gutter-fringe :config (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated)) (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated)) (define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240] nil nil 'bottom)) #+end_src ** hl-todo-mode ([[https://github.com/tarsius/hl-todo][link]]) #+begin_src emacs-lisp (use-package hl-todo :config :hook (prog-mode . hl-todo-mode)) #+end_src ** goto-line-preview #+BEGIN_SRC emacs-lisp (use-package goto-line-preview :bind ([remap goto-line] . goto-line-preview) :config) #+END_SRC ** unfill #+BEGIN_SRC emacs-lisp (use-package unfill :bind ([remap fill-paragraph] . unfill-toggle)) #+END_SRC ** Snippets #+BEGIN_SRC emacs-lisp (use-package yasnippet :hook (prog-mode . yas-minor-mode)) (use-package yasnippet-snippets :after yasnippet :config (yas-reload-all)) #+END_SRC ** Prescient #+begin_src emacs-lisp (use-package prescient :config (prescient-persist-mode)) #+end_src ** command-log #+BEGIN_SRC emacs-lisp (use-package command-log-mode) #+END_SRC ** Key statistics #+BEGIN_SRC emacs-lisp (use-package keyfreq :config (setq keyfreq-excluded-commands '( mwheel-scroll self-insert-command forward-char left-char right-char backward-char previous-line next-line)) (keyfreq-mode 1) (keyfreq-autosave-mode 1)) #+END_SRC ** rg - ripgrep frontend #+BEGIN_SRC emacs-lisp (use-package rg :ensure-system-package rg :custom (rg-custom-type-aliases '(("svelte" . "*.svelte"))) :config (rg-enable-menu)) #+END_SRC ** Dired I've tried ~[[https://github.com/ralesi/ranger.el][ranger-mode~]] with it's simplier ~[[https://github.com/ralesi/ranger.el#minimal-ranger-mode-deer][deer-mode~]] and I must say, nothing beets good old [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Dired.html][Dired]]. With some additions of course, like [[https://github.com/purcell/diredfl][~diredfl~]] for colors and [[https://gitlab.com/xuhdev/dired-quick-sort][~dired-quick-sort~]] for better sorting with native ~gnu ls~ #+BEGIN_SRC emacs-lisp (use-package dired :ensure nil :custom (dired-dwim-target t) :config (cond ((string-equal system-type "darwin") (setq insert-directory-program "gls" dired-use-ls-dired t) (setq dired-listing-switches "-alXv --group-directories-first")))) (use-package diredfl :after dired :init (diredfl-global-mode 1)) (use-package dired-quick-sort :after dired :custom (ls-lisp-use-insert-directory-program t) :config (dired-quick-sort-setup)) (use-package dired-subtree :after dired :bind (:map dired-mode-map ("TAB" . dired-subtree-toggle))) #+END_SRC ** Flycheck #+BEGIN_SRC emacs-lisp (use-package flycheck :custom (flycheck-idle-change-delay 1) :custom-face (flycheck-error ((t (:underline (:color "#e74c3c" :style wave))))) (flycheck-info ((t (:underline (:color "#b6e63e" :style wave))))) :config (global-flycheck-mode 1)) #+END_SRC ** restclient #+BEGIN_SRC emacs-lisp (use-package restclient :defer t :mode (("\\.http\\'" . restclient-mode)) :bind (:map restclient-mode-map ("C-c C-f" . json-mode-beautify))) #+END_SRC ** jq #+BEGIN_SRC emacs-lisp (use-package jq-mode :after (org-mode json-mode) :commands (jq-mode jq-interactively) :mode ("\\.jq$" . js-mode) :bind (:map json-mode-map ("C-c C-j" . jq-interactively)) :config (org-babel-add-langs ((jq . t)))) #+END_SRC ** LSP Mode #+BEGIN_SRC emacs-lisp (use-package lsp-mode :commands (lsp lsp-deferred) :custom (lsp-auto-guess-root t) (lsp-keymap-prefix "C-c l") (lsp-enable-indentation nil) (lsp-enable-on-type-formatting nil) (lsp-clients-typescript-init-opts '(:includeCompletionsForModuleExports nil :generateReturnInDocTemplate t)) (lsp-yaml-schema-store-local-db (no-littering-expand-var-file-name "./lsp/lsp-yaml-schemas.json")) :hook (lsp-mode . lsp-enable-which-key-integration) :custom-face '((lsp-lsp-flycheck-info-unnecessary-face ((t (:underline (:color "#b6e63e" :style wave)))) t))) (use-package lsp-ui :after lsp-mode :hook (lsp-mode . lsp-ui-mode) :custom (lsp-ui-sideline-enable nil) (lsp-ui-sideline-show-hover nil) (lsp-ui-doc-position 'at-point)) (use-package lsp-tailwindcss :custom (lsp-tailwindcss-add-on-mode t)) #+END_SRC ** DAP Mode Run ~dap-chrome-setup~ after requiring ~dab-chrome~ #+begin_src emacs-lisp (use-package dap-mode :config (require 'dap-chrome) (dap-ui-mode 1) (dap-tooltip-mode 1) (dap-ui-controls-mode 1) (dap-register-debug-template "Opera GX Corner [laungh]" (list :type "chrome" :name "Opera GX Corner [laungh]" :request "laungh" :url "https://local.op-test.net/" :runtimeExecutable "/Applications/Opera GX.app/Contents/MacOS/Opera" :webRoot "${workspaceFolder}/dist/" :userDataDir t :sourceMaps t )) (dap-register-debug-template "Opera GX Corner [attach]" (list :type "chrome" :name "Opera GX Corner [attach]" :request "attach" :port 9222 :url "https://local.op-test.net/" :webRoot "${workspaceFolder}/dist/" :userDataDir t :sourceMaps t ))) #+end_src ** File types *** .env #+begin_src emacs-lisp (use-package dotenv-mode :mode ("\\.env\\..*\\'" . dotenv-mode)) #+end_src *** Elisp #+begin_src emacs-lisp (use-package elisp :ensure nil :mode ("\\.el\\'" . emacs-lisp-mode)) #+end_src *** Markdown #+BEGIN_SRC emacs-lisp (use-package markdown-mode :mode (("README\\.md\\'" . gfm-mode) ("\\.md\\'" . markdown-mode) ("\\.markdown\\'" . markdown-mode))) (use-package grip-mode :bind (:map markdown-mode-command-map ("g" . grip-mode)) :config (let ((credential (auth-source-user-and-password "github.com"))) (setq grip-github-user (car credential) grip-github-password (cadr credential)))) (use-package edit-indirect :after markdown-mode) #+END_SRC *** Htmlize for org-mode #+BEGIN_SRC emacs-lisp (use-package htmlize) #+END_SRC *** YAML #+BEGIN_SRC emacs-lisp (use-package yaml-mode :mode "\\.yaml") #+END_SRC *** GO #+BEGIN_SRC emacs-lisp (use-package go-mode :mode "\\.go" :config (add-hook 'go-mode-hook (lambda () (add-hook 'before-save-hook 'gofmt-before-save) (local-set-key (kbd "M-.") 'godef-jump)))) #+END_SRC *** JSON #+BEGIN_SRC emacs-lisp (use-package json-mode :mode "\\.json$" :interpreter "json" :config (setq js-indent-level 2)) #+END_SRC *** CSS #+BEGIN_SRC emacs-lisp (use-package css-mode :mode "\\.css") #+END_SRC *** SCSS #+BEGIN_SRC emacs-lisp (use-package scss-mode :mode "\\.scss" :hook (scss-mode . lsp-deferred)) #+END_SRC *** LUA #+BEGIN_SRC emacs-lisp (use-package lua-mode :mode ("\\.lua")) #+END_SRC *** JS #+BEGIN_SRC emacs-lisp (use-package typescript-mode :after lsp-mode :mode ("\\.ts$") :custom (typescript-indent-level 2) :hook (typescript-mode . lsp-deferred)) (use-package js2-mode :mode ("\\.[cm]*js$") :hook (js2-mode . lsp-deferred)) (use-package eslintd-fix :hook (js2-mode . eslintd-fix-mode)) (use-package apheleia :config (apheleia-global-mode +1)) (use-package web-mode :after lsp-mode :mode ("\\.html\\'" "\\.tsx\\'" "\\.svelte\\'") :hook (web-mode . lsp-deferred) :custom (web-mode-content-types-alist '(("jsx" . "\\.tsx\\'") ("jsx" . "\\.jsx\\'") ("svelte" . "\\.svelte\\'") ("html" . "\\.html\\'"))) (web-mode-enable-auto-indentation nil) (web-mode-indentation-params '(("lineup-args" . t) ("lineup-calls" . t) ("lineup-concats" . t) ("lineup-quotes" . t) ("lineup-ternary" . nil) ("case-extra-offset" . t)))) #+END_SRC *** Py #+BEGIN_SRC emacs-lisp (use-package python-mode :mode "\\.py" :interpreter "py" :config (setq python-shell-interpreter "ipython" python-shell-interpreter-args "-i --simple-prompt")) #+END_SRC *** Dockerfile and docker-compose.yml #+begin_src emacs-lisp (use-package dockerfile-mode :mode "Dockerfile$") (use-package docker-compose-mode :mode "docker-compose.yml.py$") #+end_src * Other #+BEGIN_SRC emacs-lisp ;; TODO: Use general for keybindings (defun my-delete-trailing-whitespace () "Deleting trailing whitespaces." (when (derived-mode-p 'prog-mode) (delete-trailing-whitespace))) (message ".emacs loaded successfully.") (put 'downcase-region 'disabled nil) (put 'upcase-region 'disabled nil) #+END_SRC
本源码包内暂不包含可直接显示的源代码文件,请下载源码包。