1923 lines
60 KiB
EmacsLisp
1923 lines
60 KiB
EmacsLisp
;;; init --- Summary
|
||
|
||
;;; Commentary:
|
||
|
||
;;; Code:
|
||
|
||
(setq custom-file (concat user-emacs-directory "customizations.el"))
|
||
(load custom-file)
|
||
|
||
;; Initialize the package system and use-package
|
||
(setq load-prefer-newer t)
|
||
|
||
;; Add my own, version controlled ~lisp~ directory to ~load-path~
|
||
|
||
(add-to-list 'load-path (expand-file-name
|
||
(convert-standard-filename "lisp/")
|
||
user-emacs-directory))
|
||
|
||
;; Do the same with the local ~site-lisp~ if it’s there
|
||
|
||
(let ((site-lisp-dir "/usr/local/share/emacs/site-lisp"))
|
||
(when (file-directory-p site-lisp-dir)
|
||
(dolist (elt (directory-files site-lisp-dir))
|
||
(unless (or (string= elt ".") (string= elt ".."))
|
||
(add-to-list 'load-path (expand-file-name elt site-lisp-dir))))))
|
||
|
||
;; I prefer using freedesktop’s desktop specification everywhere
|
||
(load "xdg-paths")
|
||
|
||
;; Set up the package manager
|
||
|
||
;; Package archives
|
||
|
||
(require 'package)
|
||
|
||
;; GNU ELPA
|
||
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))
|
||
;; MELPA Stable
|
||
(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
|
||
;; MELPA
|
||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
|
||
|
||
;; Finally, initialise the package manager
|
||
(package-initialize)
|
||
|
||
;; use-package is a really convenient way to install packages. It’s installed in 30.1, but let’s stay on the safe side.
|
||
(unless (package-installed-p 'use-package)
|
||
(package-refresh-contents)
|
||
(package-install 'use-package))
|
||
(require 'use-package)
|
||
|
||
(use-package use-package
|
||
:custom
|
||
(use-package-always-ensure t)
|
||
(use-package-verbose nil))
|
||
|
||
(use-package bind-key)
|
||
|
||
;; Custom functions and commands
|
||
(load "gpolonkai/utilities")
|
||
(load "gpolonkai/windows")
|
||
(load "gpolonkai/org-utils")
|
||
(load "gpolonkai/text-utils")
|
||
(load "gpolonkai/nav-utils")
|
||
(load "gpolonkai/file-utils")
|
||
(load "gpolonkai/magit-utils")
|
||
|
||
(defun crm-indicator (args)
|
||
"Generate a prompt for `completing-read-multiple'.
|
||
|
||
ARGS is a cons cell of two strings, which will be used in the prompt in reverse
|
||
order."
|
||
(cons (format "[CRM%s] %s"
|
||
(replace-regexp-in-string
|
||
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'"
|
||
""
|
||
crm-separator)
|
||
(car args))
|
||
(cdr args)))
|
||
|
||
(use-package emacs
|
||
:ensure nil
|
||
:init
|
||
;; Required for Consult/Vertico
|
||
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
|
||
(setq frame-title-format
|
||
'((:eval (concat system-name
|
||
": "
|
||
(if (buffer-file-name)
|
||
(abbreviate-file-name (buffer-file-name))
|
||
"%b")))))
|
||
:custom
|
||
(user-full-name "Gergely Polonkai")
|
||
(user-mail-address "gergely@polonkai.eu")
|
||
(kill-read-only-ok t)
|
||
(use-dialog-box nil)
|
||
(cursor-type 'bar)
|
||
(echo-keystrokes .01)
|
||
(fill-column 120)
|
||
(initial-scratch-message "")
|
||
(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
|
||
(enable-recursive-minibuffers t)
|
||
(completion-cycle-threshold 3)
|
||
(tab-always-indent 'complete)
|
||
:hook
|
||
(minibuffer-setup . cursor-intangible-mode))
|
||
|
||
;; Basic settings
|
||
;;
|
||
;; Now that we have package management configured we can set up defaults more
|
||
;; easily. This includes every builtin packages, font faces, and the like.
|
||
|
||
;; Set Org’s main directory
|
||
;;
|
||
;; Since a lot of packages (org-projectile, org-caldav, etc.) rely on it, it
|
||
;; needs to be set as early as possible.
|
||
|
||
(setq org-directory (expand-file-name "~/Nextcloud/orgmode"))
|
||
|
||
;; Set up my personal keymap
|
||
|
||
(defvar gpolonkai/pers-map (make-sparse-keymap)
|
||
"My own, personal, keymap!")
|
||
(define-prefix-command 'gpolonkai/pers-map)
|
||
(define-key ctl-x-map "t" 'gpolonkai/pers-map)
|
||
(define-key global-map (kbd "C-t") 'gpolonkai/pers-map)
|
||
|
||
;; Set up some faces
|
||
|
||
(use-package faces
|
||
:ensure nil
|
||
:custom-face
|
||
(default ((t (:family "Fira Code Retina" :foundry "simp" :slant normal :weight normal :height 100 :width normal))))
|
||
(trailing-whitespace ((t (:inherit nil :background "red3")))))
|
||
|
||
;; Fira Code comes with nice ligatures, let’s use them!
|
||
|
||
(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 and Fira Code ligatures in programming modes
|
||
(ligature-set-ligatures 'prog-mode
|
||
'(;; == === ==== => =| =>>=>=|=>==>> ==< =/=//=// =~
|
||
;; =:= =!=
|
||
("=" (rx (+ (or ">" "<" "|" "/" "~" ":" "!" "="))))
|
||
;; ;; ;;;
|
||
(";" (rx (+ ";")))
|
||
;; && &&&
|
||
("&" (rx (+ "&")))
|
||
;; !! !!! !. !: !!. != !== !~
|
||
("!" (rx (+ (or "=" "!" "\." ":" "~"))))
|
||
;; ?? ??? ?: ?= ?.
|
||
("?" (rx (or ":" "=" "\." (+ "?"))))
|
||
;; %% %%%
|
||
("%" (rx (+ "%")))
|
||
;; |> ||> |||> ||||> |] |} || ||| |-> ||-||
|
||
;; |->>-||-<<-| |- |== ||=||
|
||
;; |==>>==<<==<=>==//==/=!==:===>
|
||
("|" (rx (+ (or ">" "<" "|" "/" ":" "!" "}" "\]"
|
||
"-" "=" ))))
|
||
;; \\ \\\ \/
|
||
("\\" (rx (or "/" (+ "\\"))))
|
||
;; ++ +++ ++++ +>
|
||
("+" (rx (or ">" (+ "+"))))
|
||
;; :: ::: :::: :> :< := :// ::=
|
||
(":" (rx (or ">" "<" "=" "//" ":=" (+ ":"))))
|
||
;; // /// //// /\ /* /> /===:===!=//===>>==>==/
|
||
("/" (rx (+ (or ">" "<" "|" "/" "\\" "\*" ":" "!"
|
||
"="))))
|
||
;; .. ... .... .= .- .? ..= ..<
|
||
("\." (rx (or "=" "-" "\?" "\.=" "\.<" (+ "\."))))
|
||
;; -- --- ---- -~ -> ->> -| -|->-->>->--<<-|
|
||
("-" (rx (+ (or ">" "<" "|" "~" "-"))))
|
||
;; *> */ *) ** *** ****
|
||
("*" (rx (or ">" "/" ")" (+ "*"))))
|
||
;; www wwww
|
||
("w" (rx (+ "w")))
|
||
;; <> <!-- <|> <: <~ <~> <~~ <+ <* <$ </ <+> <*>
|
||
;; <$> </> <| <|| <||| <|||| <- <-| <-<<-|-> <->>
|
||
;; <<-> <= <=> <<==<<==>=|=>==/==//=!==:=>
|
||
;; << <<< <<<<
|
||
("<" (rx (+ (or "\+" "\*" "\$" "<" ">" ":" "~" "!"
|
||
"-" "/" "|" "="))))
|
||
;; >: >- >>- >--|-> >>-|-> >= >== >>== >=|=:=>>
|
||
;; >> >>> >>>>
|
||
(">" (rx (+ (or ">" "<" "|" "/" ":" "=" "-"))))
|
||
;; #: #= #! #( #? #[ #{ #_ #_( ## ### #####
|
||
("#" (rx (or ":" "=" "!" "(" "\?" "\[" "{" "_(" "_"
|
||
(+ "#"))))
|
||
;; ~~ ~~~ ~= ~- ~@ ~> ~~>
|
||
("~" (rx (or ">" "=" "-" "@" "~>" (+ "~"))))
|
||
;; __ ___ ____ _|_ __|____|_
|
||
("_" (rx (+ (or "_" "|"))))
|
||
;; Fira code: 0xFF 0x12
|
||
("0" (rx (and "x" (+ (in "A-F" "a-f" "0-9")))))
|
||
;; Fira code:
|
||
"Fl" "Tl" "fi" "fj" "fl" "ft"
|
||
;; The few not covered by the regexps.
|
||
"{|" "[|" "]#" "(*" "}#" "$>" "^="))
|
||
;; Enables ligature checks globally in all buffers. You can also do it
|
||
;; per mode with `ligature-mode'.
|
||
(global-ligature-mode t))
|
||
|
||
;; Set the default font and configure font resizing
|
||
|
||
;; Before this can be used, make sure the Symbola font
|
||
;; (https://zhm.github.io/symbola/) font is installed.
|
||
|
||
(defun gpolonkai/set-font-size (frame)
|
||
"Set default fonts and font sizes in FRAME."
|
||
(when (display-graphic-p frame)
|
||
(set-face-attribute 'default frame :font "Fira Code Retina-10")
|
||
(set-frame-font "Fira Code Retina-10" t (list frame))))
|
||
|
||
(defun --set-emoji-font (frame)
|
||
"Adjust the font setting of FRAME so Emacs can display Emoji properly."
|
||
(when (display-graphic-p frame)
|
||
(set-fontset-font t 'symbol
|
||
(font-spec :family "Symbola")
|
||
frame 'prepend)
|
||
(set-fontset-font t 'unicode
|
||
"Noto Emoji"
|
||
nil 'append)))
|
||
|
||
(add-hook 'after-make-frame-functions 'gpolonkai/set-font-size)
|
||
(add-hook 'after-make-frame-functions '--set-emoji-font)
|
||
|
||
(gpolonkai/set-font-size nil)
|
||
(--set-emoji-font nil)
|
||
|
||
;; Set UTF-8 as the default encoding
|
||
(set-language-environment "UTF-8")
|
||
(set-default-coding-systems 'utf-8)
|
||
|
||
(use-package frame
|
||
:ensure nil
|
||
:custom
|
||
(blink-cursor-mode t))
|
||
|
||
;; I really don’t want to type more than i really must…
|
||
|
||
(defalias 'yes-or-no-p 'y-or-n-p)
|
||
|
||
;; Tweak window chrome, AKA let’s set up the UI!
|
||
|
||
;; Turn off the toolbar
|
||
(tool-bar-mode 0)
|
||
;; Turn off the menu bar
|
||
(menu-bar-mode 0)
|
||
|
||
;; If we are running in a graphical environment, turn off the scroll bar
|
||
;;
|
||
;; TODO: This is not done for every new frame!
|
||
(when window-system
|
||
(scroll-bar-mode -1))
|
||
|
||
;; Maximise newly created frames (AKA DE windows)
|
||
(set-frame-parameter nil 'fullscreen 'maximized)
|
||
|
||
;; Enable all the commands! These are disabled for a reason, but i’m a rockstar,
|
||
;; so who cares‽
|
||
;;
|
||
;; TODO: There must be a way to do it programatically
|
||
(put 'downcase-region 'disabled nil)
|
||
(put 'upcase-region 'disabled nil)
|
||
(put 'erase-buffer 'disabled nil)
|
||
(put 'narrow-to-region 'disabled nil)
|
||
(put 'narrow-to-page 'disabled nil)
|
||
(put 'set-goal-column 'disabled nil)
|
||
(put 'scroll-left 'disabled nil)
|
||
(put 'dired-find-alternate-file 'disabled nil)
|
||
(put 'Info-edit 'disabled nil)
|
||
(put 'list-timers 'disabled nil)
|
||
|
||
;; simple to always show the current column, and using visual lines in text
|
||
;; modes
|
||
|
||
(use-package simple
|
||
:ensure nil
|
||
:custom
|
||
(column-number-mode t)
|
||
:hook
|
||
(text-mode . (lambda () (visual-line-mode t))))
|
||
|
||
(use-package prog-mode
|
||
:ensure nil
|
||
:init
|
||
(setq prettify-symbols-alist
|
||
'(("lambda" . ?λ)
|
||
("function" . ?ƒ)
|
||
("map" . ?↦)
|
||
("not" . ?¬)
|
||
("and" . ?∧)
|
||
("or" . ?∨)))
|
||
:config
|
||
(global-prettify-symbols-mode t))
|
||
|
||
(use-package thingatpt
|
||
:ensure nil)
|
||
|
||
(use-package nxml-mode
|
||
:ensure nil
|
||
:custom
|
||
(nxml-attribute-indent 4)
|
||
(nxml-child-indent 4)
|
||
(nxml-outline-child-indent 4))
|
||
|
||
(use-package recentf
|
||
:ensure nil
|
||
:config
|
||
(run-at-time nil (* 5 60) 'recentf-save-list)
|
||
(add-to-list 'recentf-exclude (expand-file-name "elpa" user-emacs-directory)))
|
||
|
||
(use-package files
|
||
:ensure nil
|
||
:custom
|
||
(make-backup-file-name-function 'xah/backup-file-name))
|
||
|
||
(defun prevent-whitespace-mode-for-some ()
|
||
"Prevent `whitespace-mode' from running in some modes."
|
||
(and
|
||
(not (derived-mode-p 'magit-mode))
|
||
(not (derived-mode-p 'org-mode))))
|
||
|
||
(use-package whitespace
|
||
:demand
|
||
:config
|
||
(add-function :before-while whitespace-enable-predicate 'prevent-whitespace-mode-for-some)
|
||
(global-whitespace-mode 1)
|
||
:custom
|
||
(whitespace-line-column 120)
|
||
:bind
|
||
(([f10] . whitespace-mode)
|
||
([(shift f10)] . global-whitespace-mode)
|
||
:map gpolonkai/pers-map
|
||
("w" . whitespace-cleanup))
|
||
:custom-face
|
||
(whitespace-line ((t (:inherit nil :background "orange4")))))
|
||
|
||
;; Taken from https://ryuslash.org/posts/C-d-to-close-eshell.html
|
||
|
||
(defun eshell-C-d ()
|
||
"Either call `delete-char' interactively or quit."
|
||
(interactive)
|
||
|
||
(condition-case err
|
||
(call-interactively #'delete-char)
|
||
(error (if (and (eq (car err) 'end-of-buffer)
|
||
(looking-back eshell-prompt-regexp nil))
|
||
(kill-buffer)
|
||
(signal (car err) (cdr err))))))
|
||
|
||
(defun gpolonkai/eshell-set-c-d-locally ()
|
||
"Bind my `eshell-C-d' function locally."
|
||
(local-set-key (kbd "C-d") #'eshell-C-d))
|
||
|
||
;; Taken from https://blog.hoetzel.info/post/eshell-notifications/
|
||
|
||
(defun eshell-command-alert (process status)
|
||
"Send `alert' with severity based on STATUS when PROCESS finished."
|
||
(let* ((cmd (process-command process))
|
||
(buffer (process-buffer process))
|
||
(msg (format "%s: %s" (mapconcat 'identity cmd " ") status)))
|
||
(if (string-prefix-p "finished" status)
|
||
(alert msg :buffer buffer :severity 'normal)
|
||
(alert msg :buffer buffer :severity 'urgent))))
|
||
|
||
(use-package eshell
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("e" . eshell))
|
||
:hook
|
||
(eshell-mode . gpolonkai/eshell-set-c-d-locally)
|
||
(eshell-kill . eshell-command-alert))
|
||
|
||
(use-package calendar
|
||
:ensure nil
|
||
:custom
|
||
(calendar-week-start-day 1))
|
||
|
||
(use-package cal-dst
|
||
:ensure nil
|
||
:custom
|
||
(calendar-time-zone 60)
|
||
(calendar-standard-time-zone-name "CET")
|
||
(calendar-daylight-time-zone-name "CEST"))
|
||
|
||
(use-package solar
|
||
:ensure nil
|
||
:custom
|
||
(calendar-latitude 47.4)
|
||
(calendar-longitude 19.0)
|
||
(calendar-location-name "Budapest, Hungary"))
|
||
|
||
;; TODO: This :config call can be omitted if i add it to the calendar-load-hook
|
||
(use-package hungarian-holidays
|
||
:config
|
||
(hungarian-holidays-add))
|
||
|
||
(add-to-list 'holiday-other-holidays '(holiday-float 7 5 -1 "SysAdmin Day") t)
|
||
(add-to-list 'holiday-other-holidays '(holiday-fixed 10 21 "Reptile Awareness Day") t)
|
||
|
||
(use-package saveplace
|
||
:ensure nil
|
||
:config
|
||
(save-place-mode 1)
|
||
:custom
|
||
(save-place-file (expand-file-name ".places" user-emacs-directory)))
|
||
|
||
(use-package ediff
|
||
:ensure nil
|
||
:custom
|
||
(ediff-merge-split-window-function 'split-window-horizontally)
|
||
(ediff-split-window-function 'split-window-vertically)
|
||
(ediff-window-setup-function 'ediff-setup-windows-plain))
|
||
|
||
(use-package autorevert
|
||
:ensure nil
|
||
:config
|
||
(global-auto-revert-mode 1))
|
||
|
||
(use-package eww
|
||
:custom
|
||
(eww-search-prefix "https://duckduckgo.com/html/?q="))
|
||
|
||
;; TODO: This :config call can be omitted if i add it to prog-mode-hook
|
||
(use-package electric
|
||
:config
|
||
;; This seems to be the default, but let’s make sure…
|
||
(electric-indent-mode 1))
|
||
|
||
(use-package savehist
|
||
:config
|
||
(savehist-mode 1))
|
||
|
||
(use-package webjump
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("j" . webjump)))
|
||
|
||
(defun gpolonkai/activate-which-func-mode ()
|
||
"Activate `which-func-mode' if it exists."
|
||
(if (fboundp 'which-function-mode)
|
||
(which-function-mode)
|
||
(which-func-mode)))
|
||
|
||
;; This :config call can be omitted if i add it to which-function-mode-hook
|
||
(use-package which-func
|
||
:config
|
||
(setq which-func-unknown "∅")
|
||
:hook
|
||
(prog-mode . gpolonkai/activate-which-func-mode))
|
||
|
||
;; “Fortunes” are from the Hungarian version an ancient MS-DOS based program called TAGLINE
|
||
|
||
(use-package cookie1
|
||
:demand t
|
||
:custom
|
||
(cookie-file (expand-file-name "fortune-cookies.txt" user-emacs-directory))
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("k" . cookie)))
|
||
|
||
(use-package dired
|
||
:ensure nil
|
||
:custom
|
||
(dired-dwim-target t)
|
||
(wdired-create-parent-directories t)
|
||
(wdired-allow-to-change-permissions t)
|
||
:bind
|
||
(:map dired-mode-map
|
||
("RET" . dired-find-alternate-file)
|
||
("^" . (lambda () (interactive) (find-alternate-file "..")))
|
||
("W" . wdired-change-to-wdired-mode)))
|
||
|
||
(use-package goto-addr
|
||
:hook ((compilation-mode . goto-address-mode)
|
||
(prog-mode . goto-address-prog-mode)
|
||
(eshell-mode . goto-address-mode)
|
||
(shell-mode . goto-address-mode))
|
||
:bind
|
||
(:map goto-address-highlight-keymap
|
||
("<RET>" . goto-address-at-point)
|
||
("M-<RET>" . newline))
|
||
:commands (goto-address-prog-mode goto-address-mode))
|
||
|
||
;; Close unused buffers at midnight.
|
||
(use-package midnight
|
||
:ensure nil
|
||
:custom
|
||
(clean-buffer-list-kill-never-buffer-names '("*scratch*"
|
||
"*Messages*"
|
||
"*dashboard*"))
|
||
:config
|
||
(midnight-mode t))
|
||
|
||
(use-package display-line-numbers
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("C-n" . display-line-numbers-mode)))
|
||
|
||
(use-package ispell
|
||
:custom
|
||
(ispell-dictionary "en_GB")
|
||
(ispell-program-name "/usr/bin/hunspell")
|
||
:hook
|
||
(mail-send . ispell-message)
|
||
(message-send . ispell-message))
|
||
|
||
(use-package speedbar)
|
||
|
||
;; A Termux-specific override for `browse-url'
|
||
(when (gpolonkai/termux-p)
|
||
(use-package browse-url
|
||
:ensure nil
|
||
:config
|
||
(advice-add 'browse-url-default-browser :override
|
||
(lambda (url &rest args)
|
||
(start-process-shell-command
|
||
"open-url"
|
||
nil
|
||
(concat "am start -a android.intent.action.VIEW --user 0 -d "
|
||
url))))))
|
||
|
||
(use-package dabbrev
|
||
:bind (("M-/" . dabbrev-completion)
|
||
("C-M-/" . dabbrev-expand)))
|
||
|
||
;; Make sure we always have the latest ELPA GPG keys
|
||
(use-package gnu-elpa-keyring-update)
|
||
|
||
;; Keep packages up to date
|
||
|
||
(use-package auto-package-update
|
||
:custom
|
||
(auto-package-update-interval 7)
|
||
(auto-package-update-delete-old-versions t)
|
||
;; Even though this might require a restart when packages are updated, since
|
||
;; `use-package' invocations update the list of installed packages, we have to
|
||
;; do this in `after-init-hook'.
|
||
:hook
|
||
(after-init . auto-package-update-maybe))
|
||
|
||
;; TODO: This :config call might be omitted if i move it to
|
||
;; ace-window-display-mode-hook
|
||
(use-package ace-window
|
||
:custom
|
||
(aw-background nil)
|
||
(aw-dispatch-always t)
|
||
:config
|
||
(add-to-list 'aw-dispatch-alist
|
||
'(?s gpolonkai/scroll-window-up " Scroll window up")
|
||
t)
|
||
(add-to-list 'aw-dispatch-alist
|
||
'(?S gpolonkai/scroll-window-down " Scroll window down")
|
||
t)
|
||
(add-to-list 'aw-dispatch-alist
|
||
'(?q gpolonkai/bury-window " Bury (quit) window")
|
||
t)
|
||
:bind
|
||
(:map ctl-x-map
|
||
("o" . ace-window))
|
||
:custom-face
|
||
(aw-leading-char-face ((t (:inherit ace-jump-face-foreground :height 2.0)))))
|
||
|
||
(use-package doom-themes
|
||
:custom
|
||
(doom-themes-enable-bold t)
|
||
(doom-themes-enable-italic t)
|
||
:config
|
||
(load-theme 'doom-nord-aurora t)
|
||
(doom-themes-visual-bell-config)
|
||
(doom-themes-org-config))
|
||
|
||
;; The package that converted me to Emacs:
|
||
;; https://gergely.polonkai.eu/blog/2014/9/17/nyanmacs.html
|
||
(use-package nyan-mode
|
||
:config
|
||
(nyan-mode t)
|
||
:custom
|
||
(nyan-bar-length 20)
|
||
(nyan-animate-nyancat t)
|
||
(nyan-wavy-trail t))
|
||
|
||
;; The list of active minor modes can easily fill my whole mode line (twice…).
|
||
;; This is one of the things to protect me from that.
|
||
(use-package delight)
|
||
|
||
(use-package minions
|
||
:config
|
||
(minions-mode 1))
|
||
|
||
(use-package doom-modeline
|
||
:init
|
||
(doom-modeline-mode 1)
|
||
:custom
|
||
(doom-modeline-continuous-word-count-modes '(markdown-mode gfm-mode org-mode rst-mode))
|
||
(doom-modeline-hud t)
|
||
(doom-modeline-minor-modes t))
|
||
|
||
(use-package beacon
|
||
:demand
|
||
:config
|
||
(beacon-mode 1)
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("b" . beacon-blink)))
|
||
|
||
(use-package eshell-fringe-status
|
||
:hook
|
||
(eshell-mode . eshell-fringe-status-mode))
|
||
|
||
(use-package eshell-prompt-extras
|
||
:config
|
||
(with-eval-after-load "esh-opt"
|
||
(autoload 'epe-theme-lambda "eshell-prompt-extras"))
|
||
:custom
|
||
(eshell-highlight-prompt nil)
|
||
(eshell-prompt-function 'epe-theme-lambda))
|
||
|
||
;; Some (many? most?) Emacs packages use this to do some logical separation of
|
||
;; the code. It is also used by some compilers, and Emacs’ help system.
|
||
|
||
(use-package form-feed
|
||
:hook
|
||
(emacs-lisp-mode . form-feed-mode)
|
||
(compilation-mode . form-feed-mode)
|
||
(help-mode . form-feed-mode))
|
||
|
||
(use-package hl-line
|
||
:config
|
||
(when window-system
|
||
(global-hl-line-mode))
|
||
:custom-face
|
||
(hl-line ((t (:inherit nil :background "gray25")))))
|
||
|
||
(use-package ace-jump-mode
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("SPC" . ace-jump-mode)))
|
||
|
||
(defun gpolonkai/no-blink-matching-paren ()
|
||
"Disable blinking matching parens."
|
||
(customize-set-variable 'blink-matching-paren nil))
|
||
|
||
(defun gpolonkai/blink-matching-paren ()
|
||
"Enable blinking matching parens."
|
||
(customize-set-variable 'blink-matching-paren t))
|
||
|
||
(use-package multiple-cursors
|
||
:init
|
||
(defvar gpolonkai/mc-prefix-map (make-sparse-keymap)
|
||
"Prefix keymap for multiple-cursors")
|
||
(define-prefix-command 'gpolonkai/mc-prefix-map)
|
||
(define-key global-map (kbd "C-c m") 'gpolonkai/mc-prefix-map)
|
||
:hook
|
||
(multiple-cursors-mode-enabled . gpolonkai/no-blink-matching-paren)
|
||
(multiple-cursors-mode-disabled . gpolonkai/blink-matching-paren)
|
||
:bind
|
||
(:map gpolonkai/mc-prefix-map
|
||
("t" . mc/mark-all-like-this)
|
||
("m" . mc/mark-all-like-this-dwim)
|
||
("l" . mc/edit-lines)
|
||
("e" . mc/edit-ends-of-lines)
|
||
("a" . mc/edit-beginnings-of-lines)
|
||
("n" . mc/mark-next-like-this)
|
||
("p" . mc/mark-previous-like-this)
|
||
("s" . mc/mark-sgml-tag-pair)
|
||
("d" . mc/mark-all-like-this-in-defun)
|
||
("M-<mouse-1>" . mc/add-cursor-on-click)))
|
||
|
||
;; phi-search is an incremental search compatible with multiple-cursors
|
||
(use-package phi-search)
|
||
(use-package phi-search-mc
|
||
:config
|
||
(phi-search-mc/setup-keys))
|
||
|
||
(use-package mc-extras
|
||
:demand
|
||
:bind
|
||
(:map mc/keymap
|
||
("=" . mc/compare-chars)))
|
||
|
||
(use-package ace-mc
|
||
:bind
|
||
(:map gpolonkai/mc-prefix-map
|
||
("SPC" . ace-mc-add-multiple-cursors)
|
||
("C-SPC" . ace-mc-add-single-cursor)))
|
||
|
||
(use-package smartparens
|
||
:demand
|
||
:config
|
||
(require 'smartparens-config)
|
||
(show-smartparens-global-mode t)
|
||
:hook
|
||
(prog-mode . turn-on-smartparens-strict-mode)
|
||
(markdown-mode . turn-on-smartparens-strict-mode)
|
||
:bind
|
||
(([f9] . smartparens-strict-mode)
|
||
("C-c s u" . sp-unwrap-sexp)
|
||
("C-c s k" . sp-kill-sexp)
|
||
("C-c s r" . sp-rewrap-sexp)))
|
||
|
||
(use-package which-key
|
||
:config
|
||
(which-key-mode)
|
||
(which-key-setup-minibuffer)
|
||
:custom
|
||
(which-key-idle-delay 0.3))
|
||
|
||
(use-package visual-fill-column
|
||
:custom
|
||
(visual-fill-column-center-text t)
|
||
(visual-fill-column-width 120)
|
||
:hook
|
||
(org-mode . visual-fill-column-mode))
|
||
|
||
(use-package spinner)
|
||
|
||
(use-package avy
|
||
:demand
|
||
:config
|
||
(avy-setup-default)
|
||
:bind
|
||
(("M-g c" . avy-goto-char)
|
||
("M-g C" . avy-goto-char-2)
|
||
("M-g f" . avy-goto-line)
|
||
("M-g w" . avy-goto-word-1)
|
||
("M-g e" . avy-goto-word-0)))
|
||
|
||
(use-package goto-last-change
|
||
:bind
|
||
(("M-g /" . goto-last-change)))
|
||
|
||
(use-package rainbow-mode
|
||
:hook
|
||
(css-mode . rainbow-mode)
|
||
(scss-mode . rainbow-mode)
|
||
(sass-mode . rainbow-mode))
|
||
|
||
(use-package zygospore
|
||
:bind
|
||
(:map ctl-x-map
|
||
("1" . zygospore-toggle-delete-other-windows)))
|
||
|
||
(use-package dashboard
|
||
:after
|
||
projectile
|
||
:config
|
||
(add-to-list 'dashboard-items '(projects . 5) t)
|
||
(dashboard-setup-startup-hook)
|
||
:custom
|
||
(dashboard-set-heading-icons t)
|
||
(dashboard-set-file-icons t)
|
||
(dashboard-center-content t)
|
||
(dashboard-set-navigator t)
|
||
(dashboard-items '((agenda . 5)
|
||
(projects . 5)
|
||
(recents . 5)
|
||
(bookmarks . 5))))
|
||
|
||
(use-package sr-speedbar
|
||
:after speedbar)
|
||
|
||
(use-package hungry-delete
|
||
:config
|
||
(global-hungry-delete-mode))
|
||
|
||
(use-package anzu
|
||
:delight
|
||
:config
|
||
(global-anzu-mode 1))
|
||
|
||
;; Should the fonts be missing, run `all-the-icons-install-fonts'. It’s not run
|
||
;; automatically, as it requires connecting to a website and download a pretty
|
||
;; large font file.
|
||
|
||
(use-package all-the-icons)
|
||
|
||
(use-package all-the-icons-dired
|
||
:hook
|
||
(dired-mode . all-the-icons-dired-mode))
|
||
|
||
(use-package flyspell
|
||
:hook
|
||
(prog-mode . flyspell-prog-mode)
|
||
(text-mode . flyspell-mode))
|
||
|
||
(use-package ace-flyspell
|
||
:bind
|
||
(:map flyspell-mode-map
|
||
("C-M-i" . ace-flyspell-correct-word)))
|
||
|
||
;; Text objects are textual patterns like a line, a top level definition, a
|
||
;; word, a sentence or any other unit of text. When objed-mode is enabled,
|
||
;; certain editing commands (configurable) will activate objed and enable its
|
||
;; modal editing features.
|
||
;;
|
||
;; TODO: is :demand really needed here?
|
||
(use-package objed
|
||
:demand t
|
||
:bind
|
||
(:map global-map
|
||
("M-SPC" . objed-activate)))
|
||
|
||
(use-package alert
|
||
:config
|
||
(setq alert-default-style 'libnotify))
|
||
|
||
(alert-add-rule
|
||
:status '(buried)
|
||
:mode 'eshell-mode
|
||
:style 'notifications)
|
||
|
||
(when (gpolonkai/termux-p)
|
||
(use-package alert-termux
|
||
:after alert
|
||
:config
|
||
(setq alert-default-style 'termux)))
|
||
|
||
(use-package undo-tree
|
||
:config
|
||
(global-undo-tree-mode)
|
||
:custom
|
||
(undo-tree-auto-save-history nil))
|
||
|
||
(use-package ciel
|
||
:bind
|
||
(:map global-map
|
||
("C-c i" . ciel-ci)
|
||
("C-c o" . ciel-co)))
|
||
|
||
(use-package hide-mode-line
|
||
:bind (:map gpolonkai/pers-map
|
||
("h" . hide-mode-line-mode)))
|
||
|
||
(use-package string-inflection
|
||
:bind (:map gpolonkai/pers-map
|
||
("i" . string-inflection-all-cycle)))
|
||
|
||
(use-package spdx
|
||
:bind (:map gpolonkai/pers-map
|
||
("L" . spdx-insert-spdx-copyright))
|
||
:custom
|
||
(spdx-copyright-holder 'user)
|
||
(spdx-copyright-sign 'unicode))
|
||
|
||
(use-package ag
|
||
:commands (ag))
|
||
|
||
(use-package rg
|
||
:commands (rg))
|
||
|
||
(use-package outline
|
||
:ensure nil
|
||
:custom-face
|
||
(outline-1 ((t (:inherit font-lock-function-name-face
|
||
:overline t
|
||
:weight bold
|
||
:height 1.2))))
|
||
(outline-2 ((t (:inherit font-lock-variable-name-face
|
||
:overline t
|
||
:weight bold
|
||
:height 1.1))))
|
||
(outline-3 ((t (:inherit font-lock-keyword-face
|
||
:overline t
|
||
:weight bold)))))
|
||
|
||
(defun gpolonkai/setup-org-mode ()
|
||
"Setup Org related variables."
|
||
(org-indent-mode 1)
|
||
(variable-pitch-mode 1)
|
||
(auto-fill-mode 0)
|
||
(visual-line-mode 1))
|
||
|
||
;; From @suckless_shill:matrix.org (viz) in the #org-mode:matrix.org Matrix room
|
||
|
||
(defun vz/org-fontify-horizontal-break ()
|
||
"Display Org’s horizontal break (-----) as a full-width horizontal line."
|
||
(push '("^[[:space:]]*\\(------*\\)\n"
|
||
(0 (progn
|
||
(put-text-property (match-beginning 1) (match-end 1)
|
||
'display (make-string
|
||
(- (match-end 1)
|
||
(match-beginning 1))
|
||
?\s))
|
||
(put-text-property (match-beginning 1) (match-end 0)
|
||
'face '(:strike-through t :extend t)))))
|
||
org-font-lock-extra-keywords)
|
||
(setq-local font-lock-extra-managed-props
|
||
(cons 'display font-lock-extra-managed-props)))
|
||
|
||
(add-hook 'org-font-lock-set-keywords-hook #'vz/org-fontify-horizontal-break)
|
||
|
||
(use-package org
|
||
:demand
|
||
:custom-face
|
||
(org-block ((t (:inherit fixed-pitch))))
|
||
(org-code ((t (:inherit (shadow fixed-pitch)))))
|
||
(org-indent ((t (:inherit (org-hide fixed-pitch)))))
|
||
(org-verbatim ((t (:inherit (shadow fixed-pitch)))))
|
||
(org-special-keyword ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||
(org-meta-line ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||
(org-checkbox ((t (:inherit fixed-pitch))))
|
||
(org-table ((t (:inherit (shadow fixed-pitch)))))
|
||
(org-_drawer ((t (:inherit (shadow fixed-pitch)))))
|
||
:init
|
||
(require 'xdg-paths)
|
||
(defface org-checkbox-todo-text
|
||
'((t (:inherit org-todo)))
|
||
"Face for the text part of an unchecked org-mode checkbox.")
|
||
(defface org-checkbox-done-text
|
||
'((t (:inherit org-done)))
|
||
"Face for the text part of a checked org-mode checkbox.")
|
||
(font-lock-add-keywords
|
||
'org-mode
|
||
`(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?: \\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)" 1 'org-checkbox-todo-text prepend))
|
||
'append)
|
||
(font-lock-add-keywords
|
||
'org-mode
|
||
`(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)" 12 'org-checkbox-done-text prepend))
|
||
'append)
|
||
(setq-default org-default-notes-file (expand-file-name "notes.org" org-directory)
|
||
org-agenda-files `(,org-directory)
|
||
org-time-stamp-formats '("<%Y-%m-%d>" . "<%Y-%m-%d %H:%M>")
|
||
org-todo-keywords '((sequence "TODO(t)"
|
||
"DOING(w@/!)"
|
||
"BLOCKED(b@/!)"
|
||
"SOMEDAY(s!)"
|
||
"|"
|
||
"CANCELED(c@/!)"
|
||
"REVIEW(r@/!)"
|
||
"DONE(d@/!)"))
|
||
org-todo-keyword-faces '(("SOMEDAY" . (:foreground "goldenrod"))
|
||
("CANCELED" . (:foreground "#228b22"
|
||
:strike-through t)))
|
||
org-html-checkbox-types
|
||
'((unicode (on . "<span class=\"task-done\">☑</span>")
|
||
(off . "<span class=\"task-todo\">☐</span>")
|
||
(trans . "<span class=\"task-in-progress\">▣</span>"))))
|
||
:config
|
||
;; Load the markdown exporter
|
||
(require 'ox-md)
|
||
;; Handle org-protocol:// links
|
||
(require 'org-protocol)
|
||
;; Make it possible to encrypt headings
|
||
(require 'org-crypt)
|
||
;; Make it possible to use inline tasks
|
||
(require 'org-inlinetask)
|
||
;; Make sure we load Python babel stuff
|
||
(org-babel-do-load-languages
|
||
'org-babel-load-languages
|
||
'((python . t)))
|
||
;; Track habits
|
||
(require 'org-habit)
|
||
:custom
|
||
(org-log-into-drawer t)
|
||
(org-ellipsis "…#")
|
||
(org-startup-folded 'content)
|
||
(org-log-done 'time)
|
||
(org-src-preserve-indentation t)
|
||
(org-tags-column 0)
|
||
(org-startup-indented t)
|
||
(org-special-ctrl-a/e t)
|
||
(org-return-follows-link t)
|
||
(org-src-fontify-natively t)
|
||
(org-goto-interface 'outline-path-completion)
|
||
(org-goto-max-level 10)
|
||
(org-html-checkbox-type 'unicode)
|
||
(org-src-window-setup 'current-window)
|
||
(org-pretty-entities t)
|
||
(org-pretty-entities-include-sub-superscripts t)
|
||
(org-use-speed-commands t)
|
||
(org-hide-leading-stars t)
|
||
(org-enforce-todo-dependencies t)
|
||
(org-enforce-todo-checkbox-dependencies t)
|
||
(org-catch-invisible-edits 'show)
|
||
(org-log-reschedule 'time)
|
||
(org-log-redeadline 'note)
|
||
(org-refile-use-outline-path 'file)
|
||
(org-outline-path-complete-in-steps nil)
|
||
(org-refile-allow-creating-parent-nodes 'confirm)
|
||
(org-crypt-key "B0740C4C")
|
||
(org-speed-commands-user '(("m" . org-mark-subtree)))
|
||
(org-refile-targets '((nil :maxlevel . 6)
|
||
(org-agenda-files :maxlevel . 3)))
|
||
(org-agenda-custom-commands '(("c" "Simple agenda view"
|
||
((tags "PRIORITY=\"A\""
|
||
((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
|
||
(org-agenda-overriding-header "High priority unfinished tasks")))
|
||
(agenda "")
|
||
(alltodo ""
|
||
((org-agenda-skip-function
|
||
'(or (air-org-skip-subtree-if-habit)
|
||
(air-org-skip-subtree-if-priority ?A)
|
||
(gpolonkai/org-skip-subtree-if-state "SOMEDAY")
|
||
(org-agenda-skip-if nil '(scheduled deadline))))
|
||
(org-agenda-overriding-header "ALL normal priority tasks"))))
|
||
((org-agenda-compact-blocks t)))))
|
||
(org-log-note-clock-out t)
|
||
(org-capture-templates '(("L" "Org-protocol capture" entry
|
||
(file+headline
|
||
(lambda ()
|
||
(expand-file-name "index.org" org-directory))
|
||
"Captures")
|
||
"** %:description\n:PROPERTIES:\n:SOURCE: %:link\n:END:\n\n%:initial"
|
||
:empty-lines 1)
|
||
("R" "Region to Current Clocked Task" plain
|
||
(clock)
|
||
"%i"
|
||
:immediate-finish t
|
||
:empty-lines 1)
|
||
("K" "Kill-ring to Current Clocked Task" plain
|
||
(clock)
|
||
"%c"
|
||
:immediate-finish t
|
||
:empty-lines 1)
|
||
("c" "Item to current Clocked Task" item
|
||
(clock)
|
||
"%i%?"
|
||
:empty-lines 1)
|
||
("g" "GT2 note" entry
|
||
(file+headline
|
||
(lambda ()
|
||
(expand-file-name "gt2-notes.org" org-directory))
|
||
"Captures")
|
||
"** %^{Title}\n:PROPERTIES:\n:CREATED: %T\n:END:\n\n%a\n\n%i%?")
|
||
("p" "Blog post" entry
|
||
(file+olp+datetree
|
||
(lambda ()
|
||
(expand-file-name "blog.org" org-directory)))
|
||
"* %^{Title} :blog:\n:PROPERTIES:\n:CREATED: %T\n:END:\n\n%i%?")))
|
||
(org-read-date-force-compatible-dates nil)
|
||
(org-agenda-prefix-format '((agenda . " %i %-12:c%?-12t% s")
|
||
(todo . " %i %-12:c %(concat \"[ \"(org-format-outline-path (org-get-outline-path)) \" ]\") ")
|
||
(tags . " %i %-12:c %(concat \"[ \"(org-format-outline-path (org-get-outline-path)) \" ]\") ")
|
||
(timeline . " % s")
|
||
(search . " %i %-12:c")))
|
||
(org-agenda-dim-blocked-tasks t)
|
||
(org-link-descriptive t)
|
||
(org-hide-emphasis-markers t)
|
||
(org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled)
|
||
(org-deadline-warning-days 7)
|
||
:hook
|
||
(ediff-select . f-ediff-org-unfold-tree-element)
|
||
(ediff-unselect . f-ediff-org-fold-tree)
|
||
(org-mode . gpolonkai/setup-org-mode)
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("a" . gpolonkai/org-agenda-list)
|
||
("C" . org-capture)
|
||
("l" . org-store-link)
|
||
:map org-mode-map
|
||
("SPC" . gpolonkai/org-space-key)
|
||
("C-c l" . org-toggle-link-display)
|
||
("C-a" . gpolonkai/move-to-beginning-of-line)
|
||
("C-e" . gpolonkai/move-to-end-of-line)
|
||
("C-c h" . outline-previous-heading)
|
||
("C-c ." . gpolonkai/org-insert-current-timestamp)
|
||
("C-c ;" . org-toggle-timestamp-type)))
|
||
|
||
(use-package org-roam
|
||
:after org
|
||
:ensure t
|
||
:config
|
||
(setq org-roam-node-display-template (concat "${title:*} "
|
||
(propertize "${tags:10}" 'face 'org-tag)))
|
||
(org-roam-db-autosync-mode)
|
||
(require 'org-roam-dailies)
|
||
(require 'org-roam-protocol)
|
||
:custom
|
||
(org-roam-directory (file-truename (expand-file-name "roam" org-directory)))
|
||
(org-roam-dailies-directory (file-truename (expand-file-name "roam/journal" org-directory)))
|
||
(org-roam-completion-everywhere t)
|
||
(org-roam-capture-templates '(("d" "default" plain "\n%?"
|
||
:target (file+head
|
||
"${slug}-%<%Y%m%d%H%M%S>.org"
|
||
"#+title: ${title}")
|
||
:unnarrowed t)))
|
||
(org-roam-dailies-capture-templates '(
|
||
("d" "default" entry "* %<%H:%M>: %?"
|
||
:if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))))
|
||
:bind
|
||
(("C-c n c" . org-roam-capture)
|
||
("C-c n g" . org-roam-graph)
|
||
("C-c n i" . org-roam-node-insert)
|
||
("C-c n l" . org-roam-buffer-toggle)
|
||
:map org-mode-map
|
||
("C-M-i" . completion-at-point)
|
||
:map org-roam-dailies-map
|
||
("d" . org-roam-dailies-capture-date)
|
||
("j" . org-roam-dailies-capture-today)
|
||
("Y" . org-roam-dailies-capture-yesterday)
|
||
("T" . org-roam-dailies-capture-tomorrow))
|
||
:bind-keymap
|
||
("C-c n d" . org-roam-dailies-map))
|
||
|
||
(use-package org-roam-timestamps
|
||
:after org-roam
|
||
:config
|
||
(org-roam-timestamps-mode)
|
||
:custom
|
||
(org-roam-timestamps-remember-timestamps t)
|
||
(org-roam-timestamps-timestamp-parent-file t))
|
||
|
||
(use-package org-roam-ui
|
||
:after org-roam
|
||
:custom
|
||
(org-roam-ui-sync-theme t)
|
||
(org-roam-ui-follow t)
|
||
(org-roam-ui-update-on-save t)
|
||
(org-roam-ui-open-on-start nil))
|
||
|
||
(use-package org-bullets
|
||
:custom
|
||
(org-bullets-face-name 'org-bullet-face)
|
||
(org-bullets-bullet-list '("✙" "♱" "♰" "☥" "✞" "✟" "✝" "†" "✠" "✚" "✜" "✛" "✢" "✣" "✤" "✥"))
|
||
:hook
|
||
(org-mode . org-bullets-mode))
|
||
|
||
(use-package org-sticky-header
|
||
:custom
|
||
(org-sticky-header-full-path 'full)
|
||
:hook
|
||
(org-mode . org-sticky-header-mode))
|
||
|
||
(use-package org-random-todo
|
||
:demand
|
||
:config
|
||
;; Don’t bug me too often…
|
||
(setq org-random-todo-how-often 3600)
|
||
:custom
|
||
(org-random-todo-skip-keywords '("SOMEDAY"))
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("r" . org-random-todo)))
|
||
|
||
(use-package org-autolist
|
||
:hook
|
||
(org-mode . org-autolist-mode))
|
||
|
||
(use-package secretaria
|
||
:after
|
||
alert
|
||
:hook
|
||
;; use this for getting a reminder every 30 minutes of those tasks
|
||
;; scheduled for today and which have no time of day defined.
|
||
(after-init . secretaria-unknown-time-always-remind-me))
|
||
|
||
(use-package org-clock-waybar
|
||
:ensure nil
|
||
:vc (:url "https://gitea.polonkai.eu/gergely/org-clock-waybar.git")
|
||
:config
|
||
(org-clock-waybar-setup))
|
||
|
||
(use-package consult-org-roam
|
||
:config
|
||
(consult-org-roam-mode)
|
||
:bind (:map goto-map
|
||
("r" . consult-org-roam-search)
|
||
:map global-map
|
||
("C-c n f" . consult-org-roam-file-find)))
|
||
|
||
(use-package org-appear
|
||
:hook
|
||
(org-mode . org-appear-mode)
|
||
:custom
|
||
(org-appear-autosubmarkers t)
|
||
(org-appear-autolinks t)
|
||
(org-appear-autoemphasis t))
|
||
|
||
(use-package ob-mermaid
|
||
:custom
|
||
(ob-mermaid-cli-path "/home/polesz/.local/node/bin/mmdc"))
|
||
|
||
;; Before using this, make sure the latest PlantUML JAR file is downloaded into
|
||
;; the downloads directory. It is available from here:
|
||
;; http://plantuml.com/download
|
||
|
||
(use-package plantuml-mode
|
||
:init
|
||
(setq plantuml-jar-path
|
||
(expand-file-name
|
||
;; Make sure we have a download location even if XDG is not working
|
||
(cond
|
||
((xdg-user-dir "DOWNLOAD")
|
||
(expand-file-name "plantuml.jar" (xdg-user-dir "DOWNLOAD")))
|
||
(t
|
||
"~/Downloads/plantuml.jar"))))
|
||
(defvaralias 'org-plantuml-jar-path 'plantuml-jar-path)
|
||
:config
|
||
(org-babel-do-load-languages
|
||
'org-babel-load-languages
|
||
'((plantuml . t))))
|
||
|
||
(use-package ox-rst
|
||
:after org)
|
||
|
||
(use-package orgit
|
||
:after magit org)
|
||
|
||
(use-package orgit-forge
|
||
:after magit org orgit)
|
||
|
||
;; Git related things
|
||
|
||
(use-package magit
|
||
:custom
|
||
(magit-auto-revert-mode nil)
|
||
(magit-last-seen-setup-instructions "1.4.0")
|
||
:bind
|
||
(:map ctl-x-map
|
||
("g" . magit-status))
|
||
:hook
|
||
(git-commit-mode . turn-on-flyspell))
|
||
|
||
(use-package forge)
|
||
|
||
;; In graphical mode we use ~git-gutter-finge~, ~git-gutter~ otherwise (as we have no fringe in that case).
|
||
|
||
(let ((gitgutter-package
|
||
(if (display-graphic-p)
|
||
"git-gutter-fringe"
|
||
"git-gutter")))
|
||
(eval `(use-package ,gitgutter-package
|
||
:demand
|
||
:config
|
||
(global-git-gutter-mode t)
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("gg" . git-gutter:update-all-windows)
|
||
("gn" . git-gutter:next-hunk)
|
||
("gp" . git-gutter:previous-hunk)))))
|
||
|
||
(use-package git-messenger
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("gm" . git-messenger:popup-message)))
|
||
|
||
(use-package git-timemachine
|
||
:bind
|
||
(([f6] . git-timemachine-toggle)))
|
||
|
||
;; Completion related external packages
|
||
|
||
(use-package vertico
|
||
:init
|
||
(vertico-mode))
|
||
|
||
(use-package consult
|
||
:bind (:map global-map
|
||
([remap Info-search] . consult-info)
|
||
("M-y" . consult-yank-pop)
|
||
:map ctl-x-map
|
||
("M-:" . consult-complex-command)
|
||
("4 b" . consult-buffer-other-window)
|
||
("5 b" . consult-buffer-other-frame)
|
||
("b" . consult-buffer)
|
||
("r b" . consult-bookmark)
|
||
("x b" . consult-project-buffer)
|
||
:map goto-map
|
||
("e" . consult-compile-error)
|
||
("F" . consult-flymake)
|
||
("g" . consult-goto-line)
|
||
("M-g" . consult-goto-line)
|
||
("i" . consult-imenu)
|
||
("I" . consult-imenu-multi)
|
||
("k" . consult-global-mark)
|
||
("m" . consult-mark)
|
||
("o" . consult-org-heading)
|
||
:map search-map
|
||
("d" . consult-find)
|
||
("D" . consult-locate)
|
||
("e" . consult-isearch-history)
|
||
("k" . consult-keep-lines)
|
||
("l" . consult-line)
|
||
("L" . consult-line-multi)
|
||
:map isearch-mode-map
|
||
("M-e" . consult-isearch-history)
|
||
:map minibuffer-local-map
|
||
("M-s" . consult-history)
|
||
("M-r" . consult-history))
|
||
:hook
|
||
(completion-list-mode . consult-preview-at-point-mode)
|
||
:custom
|
||
(consult-narrow-key "<")
|
||
(consult-project-function (lambda (_) (projectile-project-root)))
|
||
(register-preview-delay 0.5)
|
||
(xref-show-xrefs-function #'consult-xref)
|
||
(xref-show-definitions-function #'consult-xref)
|
||
:init
|
||
(setq register-preview-function #'consult-register-format)
|
||
(advice-add #'register-preview :override #'consult-register-window)
|
||
:config
|
||
(defalias 'consult-line-thing-at-point 'consult-line)
|
||
(consult-customize
|
||
consult-theme :preview-key '(:debounce 0.2 any)
|
||
consult-buffer :preview-key "M-."
|
||
consult-line-thing-at-point :initial (thing-at-point 'symbol)
|
||
consult-ripgrep
|
||
consult-git-grep
|
||
consult-grep
|
||
consult-bookmark
|
||
consult-recent-file
|
||
consult-xref
|
||
consult--source-bookmark
|
||
consult--source-file-register
|
||
consult--source-recent-file
|
||
consult--source-project-recent-file
|
||
:preview-key '(:debounce 0.4 any))
|
||
(autoload 'projectile-project-root "projectile"))
|
||
|
||
(use-package orderless
|
||
:init
|
||
(setq completion-category-defaults nil)
|
||
:custom
|
||
(completion-styles '(orderless basic))
|
||
(completion-category-defaults nil)
|
||
(completion-category-overrides '((file (styles basic partial-completion)))))
|
||
|
||
(use-package marginalia
|
||
:bind (:map minibuffer-local-map
|
||
("M-A" . marginalia-cycle))
|
||
:init
|
||
(marginalia-mode))
|
||
|
||
(use-package embark
|
||
:bind (:map global-map
|
||
("C-." . embark-act))
|
||
:config
|
||
(add-to-list 'display-buffer-alist
|
||
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
|
||
nil
|
||
(window-parameters (mode-line-format . none)))))
|
||
|
||
(use-package embark-consult
|
||
:hook
|
||
(embark-collect-mode . consult-preview-at-point-mode))
|
||
|
||
(use-package consult-projectile
|
||
:demand t
|
||
:after (:all projectile consult embark)
|
||
:config
|
||
(defvar-keymap embark-consult-projectile-project-map
|
||
:doc "Keymap to use for the projectile menu"
|
||
:parent embark-general-map
|
||
"g" #'magit-status)
|
||
(add-to-list 'embark-keymap-alist '(consult-projectile-project embark-consult-projectile-project-map))
|
||
(autoload 'magit-status "magit")
|
||
:bind (:map projectile-command-map
|
||
("p" . consult-projectile-switch-project)))
|
||
|
||
(use-package corfu
|
||
:init
|
||
(global-corfu-mode)
|
||
:custom
|
||
(corfu-cycle t)
|
||
(corfu-separator ?\s))
|
||
|
||
(defvar gpolonkai/completion-at-point-map (make-sparse-keymap)
|
||
"Map for traspose functions.")
|
||
(define-prefix-command 'gpolonkai/completion-at-point-map)
|
||
|
||
(use-package cape
|
||
:bind (:map gpolonkai/completion-at-point-map
|
||
("p" . completion-at-point)
|
||
:map gpolonkai/pers-map
|
||
("p" . gpolonkai/completion-at-point-map))
|
||
:init
|
||
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
|
||
(add-to-list 'completion-at-point-functions #'cape-file)
|
||
(add-to-list 'completion-at-point-functions #'cape-elisp-block)
|
||
(add-to-list 'completion-at-point-functions #'cape-elisp-symbol))
|
||
|
||
;; Project management
|
||
|
||
(use-package projectile
|
||
:demand t
|
||
:delight '(:eval (concat " [" projectile-project-name "]"))
|
||
:config
|
||
(projectile-mode t)
|
||
:bind
|
||
(:map mode-specific-map
|
||
("p" . projectile-command-map)))
|
||
|
||
(use-package projectile-speedbar
|
||
:after (:all projectile sr-speedbar)
|
||
:bind
|
||
(:map projectile-mode-map
|
||
("C-c p B" . projectile-speedbar-toggle)))
|
||
|
||
(use-package org-projectile
|
||
:after (:all projectile org)
|
||
:bind
|
||
(:map projectile-command-map
|
||
("n" . org-projectile-project-todo-completing-read))
|
||
:custom
|
||
(org-projectile-projects-file (expand-file-name "projects.org" org-directory))
|
||
:config
|
||
(push (org-projectile-project-todo-entry) org-capture-templates))
|
||
|
||
;; Dired extras
|
||
|
||
(use-package dired-collapse)
|
||
|
||
(use-package dired-du)
|
||
|
||
(use-package dired-git-info
|
||
:bind
|
||
(:map dired-mode-map
|
||
(")" . dired-git-info-mode)))
|
||
|
||
(use-package dired-hide-dotfiles
|
||
:bind
|
||
(:map dired-mode-map
|
||
("." . dired-hide-dotfiles-mode)))
|
||
|
||
(use-package dired-rainbow
|
||
:config
|
||
(dired-rainbow-define-chmod executable-unix "Green" "-.*x.*"))
|
||
|
||
(use-package dired-k
|
||
:bind
|
||
(:map dired-mode-map
|
||
("K" . dired-k)))
|
||
|
||
;; Mailing
|
||
|
||
;; Due to my programming (and maybe a bit of OCD) needs, i set trailing
|
||
;; whitespace to have a red background so it stands out *a lot*. However, many
|
||
;; emails contain a lot of trailing whitespace which makes them really hard to
|
||
;; read in Emacs.
|
||
;;
|
||
;; The below snippet creates a trailing whitespace face specific to mu4e view
|
||
;; buffers. The accompanying function will be added to ~mu4e-view-mode-hook~.
|
||
|
||
(copy-face 'trailing-whitespace 'trailing-whitespace-mu4e)
|
||
(set-face-attribute 'trailing-whitespace-mu4e nil :background 'unspecified)
|
||
|
||
(defun gpolonkai/mu4e-trailing-whitespace-fix ()
|
||
"Change `trailing-whitespace' face for mu4e buffers."
|
||
(set (make-local-variable 'face-remapping-alist)
|
||
'((trailing-whitespace trailing-whitespace-mu4e))))
|
||
|
||
(use-package mu4e
|
||
:after vertico
|
||
:ensure nil
|
||
:config
|
||
(require 'org-mu4e)
|
||
(setq mu4e-contexts
|
||
`( ,(make-mu4e-context
|
||
:name "polonkai.eu"
|
||
:enter-func (lambda () (mu4e-message "Entering polonkai.eu Context"))
|
||
:leave-func (lambda () (mu4e-message "Leaving polonkai.eu Context"))
|
||
:match-func (lambda (msg)
|
||
(when msg
|
||
(mu4e-message-contact-field-matches
|
||
msg
|
||
:to "gergely@polonkai.eu")))
|
||
:vars '((user-mail-address . "gergely@polonkai.eu")
|
||
(mu4e-sent-folder . "/Polonkai/[Gmail].Sent Mail")
|
||
(mu4e-drafts-folder . "/Polonkai/[Gmail].Drafts")
|
||
(mu4e-trash-folder . "/Polonkai/[Gmail].Bin")
|
||
(mu4e-refile-folder . "/Polonkai/[Gmail].Drafts")
|
||
(message-sendmail-extra-arguments . ("--account=polonkai"))))
|
||
,(make-mu4e-context
|
||
:name "Benchmark.games"
|
||
:enter-func (lambda () (mu4e-message "Entering Benchmark.games Context"))
|
||
:leave-func (lambda () (mu4e-message "Leaving Benchmark.games Context"))
|
||
:match-func (lambda (msg)
|
||
(when msg
|
||
(or
|
||
(mu4e-message-contact-field-matches
|
||
msg
|
||
:to "gergo@gt2.io")
|
||
(mu4e-message-contact-field-matches
|
||
msg
|
||
:to "gergo@benchmarked.games")
|
||
(mu4e-message-contact-field-matches
|
||
msg
|
||
:to "gergo@benchmark.games"))))
|
||
:vars '((user-mail-address . "gergely@benchmark.games")
|
||
(mu4e-sent-folder . "/GT2/[Gmail].Sent Mail")
|
||
(mu4e-drafts-folder . "/GT2/[Gmail].Drafts")
|
||
(mu4e-trash-folder . "/GT2/[Gmail].Trash")
|
||
(mu4e-refile-folder . "/GT2/[Gmail].Drafts")
|
||
(message-sendmail-extra-arguments . ("--account=gt2"))))
|
||
,(make-mu4e-context
|
||
:name "Private"
|
||
:enter-func (lambda () (mu4e-message "Entering Private Context"))
|
||
:leave-func (lambda () (mu4e-message "Leaving Private Context"))
|
||
:match-func (lambda (msg)
|
||
(when msg
|
||
(string-match-p "^/Private" (mu4e-message-field msg :maildir))))
|
||
:vars '((user-mail-address . "me@gergely.polonkai.eu")
|
||
(mu4e-sent-folder . "/Private/Sent")
|
||
(mu4e-drafts-folder . "/Private/Drafts")
|
||
(mu4e-trash-folder . "/Private/Trash")
|
||
(mu4e-refile-folder . "/Private/Drafts")
|
||
(message-sendmail-extra-arguments . ("--account=private" "--read-envelope-from")))))
|
||
org-mu4e-link-query-in-headers-mode nil)
|
||
:custom
|
||
(mu4e-context-policy 'pick-first)
|
||
(mu4e-confirm-quit nil)
|
||
(mail-user-agent 'sendmail-user-agent)
|
||
:hook
|
||
(mu4e-view-mode . gpolonkai/mu4e-trailing-whitespace-fix)
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("m m" . mu4e)
|
||
("m i" . mu4e~headers-jump-to-maildir)
|
||
("m c" . mu4e-compose-new)
|
||
("m s" . mu4e-headers-search)))
|
||
|
||
(use-package sendmail
|
||
:custom
|
||
(sendmail-program "/usr/bin/msmtp")
|
||
(message-sendmail-f-is-evil t)
|
||
(message-sendmail-extra-arguments '("--read-envelope-from"))
|
||
(send-mail-function 'sendmail-send-it)
|
||
(message-send-mail-function 'message-send-mail-with-sendmail))
|
||
|
||
(use-package org-msg
|
||
:after mu4e
|
||
:defer t
|
||
:config
|
||
(org-msg-mode)
|
||
:custom
|
||
(org-msg-supported-mua '((sendmail-user-agent . "mu4e")))
|
||
(org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil")
|
||
(org-msg-startup "hidestars indent inlineimages")
|
||
(org-msg-greeting-fmt "\nHello,\n\n")
|
||
(org-msg-greeting-fmt-mailto nil)
|
||
(org-msg-signature "\n\nBest,\n\n,#+begin_signature\n-- *Gergely Polonkai* \\\\\n,#+end_signature"))
|
||
|
||
;; External packages to boost coding productivity
|
||
|
||
(use-package electric-operator
|
||
:config
|
||
;; Apply electric-operator-mode to vala-mode, too
|
||
(apply #'electric-operator-add-rules-for-mode 'vala-mode
|
||
(electric-operator-get-rules-for-mode 'prog-mode))
|
||
:hook
|
||
(c-mode-common . electric-operator-mode)
|
||
(python-mode . electric-operator-mode))
|
||
|
||
(use-package rainbow-delimiters
|
||
:hook
|
||
(prog-mode . rainbow-delimiters-mode))
|
||
|
||
(use-package rainbow-identifiers)
|
||
|
||
(use-package auto-highlight-symbol
|
||
:config
|
||
(global-auto-highlight-symbol-mode t))
|
||
|
||
(use-package glasses
|
||
:delight " 👓"
|
||
:hook
|
||
(prog-mode . glasses-mode))
|
||
|
||
(use-package hl-todo
|
||
:hook
|
||
(prog-mode . hl-todo-mode))
|
||
|
||
(defvar gpolonkai/bug-reference-url-bug-string "issues"
|
||
"String to insert in a `bug-reference-url-format' for bug references.")
|
||
|
||
(put 'gpolonkai/bug-reference-url-bug-string 'safe-local-variable 'stringp)
|
||
|
||
(defvar gpolonkai/bug-reference-url-patch-string "merge_requests"
|
||
"String to insert in a `bug-reference-url-format' for patch references.")
|
||
|
||
(defvar-local bug-reference-host "gitlab.com"
|
||
"The hostname to use in `bug-reference-url-format'.")
|
||
|
||
(defvar-local bug-reference-group "gamesystems"
|
||
"The group name or username to use in `bug-reference-url-format'.")
|
||
|
||
(defvar-local bug-reference-repository "game-app"
|
||
"The repository name to use in `bug-reference-url-format'.")
|
||
|
||
(put 'gpolonkai/bug-reference-url-patch-string 'safe-local-variable 'stringp)
|
||
|
||
(defun gpolonkai/bug-reference-url ()
|
||
"Return a GitLab issue or Merge Request URL.
|
||
Intended as a value for `bug-referecne-url-format'."
|
||
(format "https://%s/%s/%s/%s/%s"
|
||
bug-reference-host
|
||
bug-reference-group
|
||
bug-reference-repository
|
||
(if (string-suffix-p "!" (match-string-no-properties 1))
|
||
gpolonkai/bug-reference-url-patch-string
|
||
gpolonkai/bug-reference-url-bug-string)
|
||
(match-string-no-properties 2)))
|
||
|
||
(use-package bug-reference
|
||
:custom
|
||
(bug-reference-bug-regexp (rx (group word-boundary
|
||
(: (| (: (in ?B ?b) "ug" (? " ") (? ?#))
|
||
(: (in ?P ?p) "atch" (? " ") ?#)
|
||
(: "RFE" (? " ") ?#)
|
||
(: "PR " (+ (any "a-z+-")) "/")
|
||
(: "MR" (? " ") (? "!"))))
|
||
(group (+ (any "0-9")) (opt (: ?# (+ (any "0-9"))))))))
|
||
(bug-reference-url-format #'my-gitlab-url)
|
||
:hook
|
||
(text-mode . bug-reference-mode)
|
||
(prog-mode . bug-reference-prog-mode))
|
||
|
||
(use-package highlight-indentation
|
||
:hook
|
||
(python-mode . highlight-indentation-mode))
|
||
|
||
(use-package flycheck
|
||
:config
|
||
(global-flycheck-mode)
|
||
:custom
|
||
(flycheck-python-pylint-executable "python3"))
|
||
|
||
(use-package flycheck-pkg-config)
|
||
|
||
;; Utilities
|
||
|
||
(use-package kubernetes
|
||
:commands (kubernetes-overview))
|
||
|
||
;; Gopher is the next generation text protocol. Despite its age (40-ish, as of
|
||
;; writing), it still beats the Web in a lot of aspects.
|
||
|
||
(use-package elpher
|
||
:commands (elpher))
|
||
|
||
(use-package mastodon
|
||
:custom
|
||
(mastodon-instance-url "https://social.polonkai.eu/")
|
||
(mastodon-active-user "gergely"))
|
||
|
||
(use-package twtxt
|
||
:custom
|
||
(twtxt-file (expand-file-name "~/Nextcloud/twtxt.txt"))
|
||
(twtxt-following '(("benaiah" "https://benaiah.me/twtxt.txt")
|
||
("jomo" "https://gist.githubusercontent.com/jomo/64d6bd1b95ec0a24612b/raw/twtxt.txt")
|
||
("quite" "https://lublin.se/twtxt.txt")
|
||
("xena" "https://xena.greedo.xeserv.us/files/xena.txt")
|
||
("hecanjog" "https://hecanjog.com/twtxt.txt"))))
|
||
|
||
(use-package paradox
|
||
:custom
|
||
(paradox-lines-per-entry 2)
|
||
(paradox-automatically-star t)
|
||
(paradox-github-token (nth 1 (auth-source-user-and-password "api.github.com" "gergelypolonkai^paradox")))
|
||
:bind
|
||
(:map gpolonkai/pers-map
|
||
("C-p" . paradox-list-packages)))
|
||
|
||
(use-package tidal
|
||
:mode "\\.tidal\\'")
|
||
|
||
;; Programming-language specific packages
|
||
|
||
;; Python
|
||
|
||
(add-hook 'python-mode-hook
|
||
(lambda ()
|
||
(add-to-list 'prettify-symbols-alist
|
||
'("not in" . ?∉))
|
||
(add-to-list 'prettify-symbols-alist
|
||
'("in" . ?∈))
|
||
(add-to-list 'prettify-symbols-alist
|
||
'("def" . ?ƒ))
|
||
(add-to-list 'prettify-symbols-alist
|
||
'("is not" . ?≭))
|
||
(add-to-list 'prettify-symbols-alist
|
||
'("is" . ?≍))
|
||
))
|
||
|
||
(use-package poetry
|
||
:config
|
||
(poetry-tracking-mode)
|
||
(remove-hook 'post-command-hook 'poetry-track-virtualenv)
|
||
:hook
|
||
(poetry-tracking-mode . (lambda () (remove-hook 'post-command-hook 'poetry-track-virtualenv)))
|
||
(python-mode . poetry-track-virtualenv)
|
||
(projectile-after-switch-project-hook . poetry-track-virtualenv)
|
||
:bind (:map gpolonkai/pers-map
|
||
("pp" . poetry)))
|
||
|
||
(defconst my-c-style
|
||
'((c-tab-always-indent . t)
|
||
(c-comment-only-line-offset . 4)
|
||
(c-hanging-braces-alist . ((substatement-open after)
|
||
(brace-list-open)))
|
||
(c-hanging-colons-alist . ((member-init-intro before)
|
||
(inher-intro)
|
||
(case-label after)
|
||
(label after)
|
||
(access-label after)))
|
||
(c-cleanup-list . (scope-operator
|
||
empty-defun-braces
|
||
defun-close-semi))
|
||
(c-offsets-alist . ((arglist-close . +)
|
||
(arglist-intro . +)
|
||
(substatement-open . 0)
|
||
(case-label . 4)
|
||
(block-open . 0)
|
||
(knr-argdecl-intro . -)
|
||
(comment-intro . 0)
|
||
(member-init-intro . ++)))
|
||
(c-echo-syntactic-information-p . t))
|
||
"My C Programming Style.")
|
||
(c-add-style "PERSONAL" my-c-style)
|
||
|
||
(defvaralias 'c-basic-offset 'tab-width)
|
||
(defvaralias 'cperl-indent-level 'tab-width)
|
||
|
||
(add-hook 'c-mode-common-hook
|
||
(lambda ()
|
||
(local-set-key (kbd "C-c o") 'ff-find-other-file)
|
||
(c-set-style "PERSONAL")
|
||
(customize-set-variable 'c-basic-offset 4)
|
||
(customize-set-variable 'tab-width 4)
|
||
(customize-set-variable 'indent-tabs-mode nil)
|
||
(c-toggle-auto-newline 1)))
|
||
(add-hook 'c-initialization-hook
|
||
(lambda ()
|
||
(define-key c-mode-base-map (kbd "C-m") 'c-context-line-break)))
|
||
|
||
(use-package web-mode
|
||
:mode "\\.html?\\'"
|
||
:custom
|
||
(web-mode-enable-auto-indentation nil)
|
||
(web-mode-enable-engine-detection t))
|
||
|
||
(use-package emmet-mode
|
||
:custom
|
||
(emmet-self-closing-tag-style "")
|
||
:hook
|
||
(web-mode . emmet-mode)
|
||
(css-mode . emmet-mode))
|
||
|
||
(use-package enlive)
|
||
|
||
(use-package json-mode
|
||
:mode "\\.json\\'")
|
||
|
||
(use-package yaml-mode
|
||
:mode (("\\.yml\\'" . yaml-mode)
|
||
("\\.yaml\\'" . yaml-mode))
|
||
:init
|
||
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)))
|
||
|
||
(use-package dockerfile-mode)
|
||
|
||
(use-package systemd
|
||
:mode ("\\.\\(?:automount\\|mount\\|path\\|s\\(?:ervice\\|lice\\|ocket\\)\\|t\\(?:arget\\|imer\\)\\|wants\\)\\'" . systemd-mode))
|
||
|
||
(use-package terraform-mode
|
||
:mode "\\.tf\\'")
|
||
|
||
(use-package bats-mode
|
||
:mode "\\.bats\\'")
|
||
|
||
(use-package fish-mode
|
||
:hook
|
||
(fish-mode . (lambda () (add-hook 'before-save-hook 'fish_indent-before-save)))
|
||
:mode "\\.fish\\'")
|
||
|
||
(use-package gitlab-ci-mode
|
||
:mode "\\.gitlab-ci.yml\\'")
|
||
|
||
(use-package gitlab-ci-mode-flycheck
|
||
:after flycheck gitlab-ci-mode
|
||
:init
|
||
(gitlab-ci-mode-flycheck-enable))
|
||
|
||
(use-package csv-mode
|
||
:mode "\\.csv\\'")
|
||
|
||
(use-package rust-mode
|
||
:mode "\\.rs\\'")
|
||
|
||
(use-package cargo)
|
||
|
||
(use-package cargo-mode
|
||
:mode "Cargo\\.toml\\'")
|
||
|
||
(use-package arduino-mode
|
||
:mode "\\.ino\\'")
|
||
|
||
(use-package nginx-mode)
|
||
|
||
(use-package js2-mode
|
||
:pin melpa-stable
|
||
:mode "\\.js\\'")
|
||
|
||
(use-package typescript-mode
|
||
:mode "\\.ts\\'")
|
||
|
||
(use-package less-css-mode
|
||
:mode "\\.less\\'")
|
||
|
||
(use-package sass-mode
|
||
:mode "\\.sass\\'")
|
||
|
||
(use-package vue-html-mode
|
||
:mode "\\.vue\\'")
|
||
|
||
(use-package jinja2-mode
|
||
:mode "\\.j2\\'")
|
||
|
||
(use-package markdown-mode
|
||
:mode (("\\.md\\'" . markdown-mode)
|
||
("\\.markdown\\'" . markdown-mode)))
|
||
|
||
(use-package vala-mode
|
||
:mode "\\.vala\\'")
|
||
|
||
(use-package po-mode
|
||
:ensure nil
|
||
:mode "\\.po\\'")
|
||
|
||
(use-package meson-mode
|
||
:mode "\\.meson\\'")
|
||
|
||
(defun gpolonkai/cond-enable-ggtags-mode ()
|
||
"Conditionally enable `ggtags-mode'."
|
||
(when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
|
||
(ggtags-mode t)))
|
||
|
||
(use-package ggtags
|
||
:hook
|
||
(c-mode-common . gpolonkai/cond-enable-ggtags-mode))
|
||
|
||
(use-package yuck-mode
|
||
:mode "\\.yuck\\'")
|
||
|
||
(use-package ebnf-mode
|
||
:commands (ebnf-mode))
|
||
|
||
(use-package ansible-vault)
|
||
|
||
;; Key bindings
|
||
|
||
(defvar gpolonkai/transpose-map (make-sparse-keymap)
|
||
"Map for transpose commands.")
|
||
(define-prefix-command 'gpolonkai/transpose-map)
|
||
|
||
(defvar gpolonkai/org-clock-map (make-sparse-keymap)
|
||
"Map for Org clocking commands.")
|
||
(define-prefix-command 'gpolonkai/org-clock-map)
|
||
|
||
(bind-keys
|
||
:map global-map
|
||
("<C-return>" . wted/open-line-below)
|
||
("<C-S-return>" . wted/open-line-above)
|
||
("C-~" . gpolonkai/toggle-char-case)
|
||
("C-a" . gpolonkai/move-to-beginning-of-line)
|
||
("C-e" . gpolonkai/move-to-end-of-line)
|
||
("M-F" . gpolonkai/beginning-of-next-word)
|
||
("C-h C-l" . find-library)
|
||
("C-h C-f" . find-function)
|
||
("C-h C-k" . find-function-on-key)
|
||
("C-h C-v" . find-variable)
|
||
("M-q" . sachachua/fill-or-unfill-paragraph)
|
||
("C-r" . isearch-backward-regexp)
|
||
("C-M-r" . isearch-backward)
|
||
("C-s" . isearch-forward-regexp)
|
||
("C-M-s" . isearch-forward)
|
||
("M-t" . gpolonkai/transpose-map)
|
||
("C-z" . nil)
|
||
:map mode-specific-map
|
||
;; TODO this should be doable from consult-projectile’s config
|
||
("p p" . consult-projectile-switch-project)
|
||
("r" . gpolonkai/round-number-at-point-to-decimals)
|
||
:map gpolonkai/transpose-map
|
||
("c" . transpose-chars)
|
||
("e" . transpose-sexps)
|
||
("l" . transpose-lines)
|
||
("p" . transpose-paragraphs)
|
||
("s" . transpose-sentences)
|
||
("w" . transpose-words)
|
||
("W" . gpolonkai/transpose-windows)
|
||
:map gpolonkai/org-clock-map
|
||
("g" . org-clock-goto)
|
||
("i" . org-clock-in)
|
||
("I" . org-clock-in-last)
|
||
("o" . org-clock-out)
|
||
:map gpolonkai/pers-map
|
||
("c" . gpolonkai/org-clock-map)
|
||
("C-c" . calc)
|
||
("M-C" . clean-buffer-list)
|
||
("M-o" . mbork/insert-current-file-name-at-point)
|
||
("u" . browse-url-at-point)
|
||
:map ctl-x-map
|
||
("|" . gpolonkai/toggle-window-split)
|
||
("C-b" . bury-buffer)
|
||
("C-d" . wted/delete-current-buffer-file)
|
||
("k" . kill-current-buffer)
|
||
("C-r" . wted/rename-current-buffer-file)
|
||
("C-y" . duplicate-line)
|
||
:map isearch-mode-map
|
||
("<C-return>" . ep/isearch-exit-other-end)
|
||
("<S-return>" . e-se/isearch-exit-mark-match)
|
||
:map goto-map
|
||
("SPC" . gpolonkai/goto-next-char))
|
||
|
||
;; And finally, start the Emacs server
|
||
;;
|
||
;; Sometimes i start an ~emacsclient~ process, like for editing a commit message
|
||
;; or something similar. As my startup time is pretty long, waiting for
|
||
;; everything to complete is undesirable.
|
||
|
||
(require 'server)
|
||
(unless (server-running-p)
|
||
(server-start))
|
||
|
||
;;; init.el ends here
|