my-emacs-d/configuration.org

3272 lines
92 KiB
Org Mode
Raw Permalink Normal View History

* Pre-init
** Add my own, version controlled ~lisp~ directory to ~load-path~
#+begin_src emacs-lisp
(add-to-list 'load-path (expand-file-name
(convert-standard-filename "lisp/")
user-emacs-directory))
#+end_src
** Do the same with the local ~site-lisp~ if its there
#+begin_src emacs-lisp
(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))))))
#+end_src
** Load ~xdg-paths~
I prefer using freedesktops desktop specification everywhere.
#+begin_src emacs-lisp
(load "xdg-paths")
#+end_src
* Set up the package manager
Im a ~package.el~ user. Dont package-shame me!
2018-07-29 16:38:44 +00:00
** Set up the package archives
#+begin_src emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("gnu" . "https://elpa.gnu.org/packages/"))
(add-to-list 'package-archives
'("melpa-stable" . "https://stable.melpa.org/packages/") t)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives
'("org" . "https://orgmode.org/elpa/") t)
(package-initialize)
#+end_src
** Set up ~use-package~
2018-07-29 16:38:44 +00:00
It is built-in since 29.1, and lets hope I never get back using older versions, but lets stay on the safe side for now.
#+begin_src emacs-lisp
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
2018-07-29 16:38:44 +00:00
(require 'use-package)
2018-07-29 16:38:44 +00:00
(use-package use-package
:custom
(use-package-always-ensure t)
(use-package-verbose nil))
2018-07-30 17:52:16 +00:00
(use-package bind-key)
#+end_src
2018-07-29 16:38:44 +00:00
*** Install Quelpa so we can add packages not present in MELPA yet
2020-03-03 05:19:19 +00:00
#+begin_src emacs-lisp
(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)))
#+end_src
2020-03-03 05:19:19 +00:00
*** Finally, combine the powers of use-package and quelpa
2020-03-03 05:19:19 +00:00
#+begin_src emacs-lisp
(quelpa
'(quelpa-use-package
:fetcher git
:url "https://github.com/quelpa/quelpa-use-package.git"))
(require 'quelpa-use-package)
#+end_src
* Custom functions and commands
This is a collection of functions and commands i wrote or stole from all around the internet.
** Utilities
2023-01-31 11:54:41 +00:00
*** Make a backup filename under ~user-emacs-cache-directory~
2023-01-31 11:54:41 +00:00
Taken from [[http://ergoemacs.org/emacs/emacs_set_backup_into_a_directory.html][Xahs site]].
#+begin_src emacs-lisp
(defun xah/backup-file-name (fpath)
"Return a new file path for FPATH under `user-emacs-cache-directory'"
(let* ((backup-root-dir (expand-file-name "backup" user-emacs-cache-directory))
(file-path (replace-regexp-in-string "[A-Za-z]:" "" fpath))
(backup-file-path (replace-regexp-in-string "//" "/" (concat backup-root-dir file-path "~"))))
(make-directory (file-name-directory backup-file-path) (file-name-directory backup-file-path))
backup-file-path))
#+end_src
*** Check if were running under Termux
We need to do things differently, if so.
2019-10-22 08:33:33 +00:00
Theres probably a better way, though, other than checking the path of our home directory.
#+begin_src emacs-lisp
(defun gpolonkai/termux-p ()
"Check if Emacs is running under Termux."
(string-match-p
(regexp-quote "/com.termux/")
(expand-file-name "~")))
#+end_src
*** Find the first number on line
#+begin_src emacs-lisp
(defun gpolonkai/find-number-on-line ()
"Find the first number on the current line."
(save-excursion
(without-restriction
(goto-char (pos-bol))
(when (re-search-forward "[0-9]+" (pos-eol) t)
(number-at-point)))))
#+end_src
*** Round number at point to the given decimals
#+begin_src emacs-lisp
(defun gpolonkai/round-number-at-point-to-decimals (decimal-count)
(interactive "NDecimal count: ")
(let ((mult (expt 10 decimal-count)))
(replace-match (number-to-string
(/
(fround
(*
mult
(number-at-point)))
mult)))))
#+end_src
*** Leave ~isearch~ at the other end of the matched string
From [[http://endlessparentheses.com/leave-the-cursor-at-start-of-match-after-isearch.html][Endless Parentheses]].
2023-10-03 08:29:04 +00:00
#+begin_src emacs-lisp
(defun ep/isearch-exit-other-end ()
"Exit isearch, at the opposite end of the string."
(interactive)
2018-07-30 17:52:16 +00:00
(isearch-exit)
(goto-char isearch-other-end))
#+end_src
2018-07-30 17:52:16 +00:00
*** Mark the current match after leaving ~isearch~
2018-07-30 17:52:16 +00:00
From [[http://emacs.stackexchange.com/a/31321/507][Emacs SE]].
#+begin_src emacs-lisp
(defun e-se/isearch-exit-mark-match ()
"Exit isearch and mark the current match."
(interactive)
(isearch-exit)
(push-mark isearch-other-end)
(activate-mark))
#+end_src
*** Copy the prototype of the current C function
#+begin_src emacs-lisp
(defun gpolonkai/copy-func-prototype ()
"Copy the current function's prototype to the kill ring."
(interactive)
(save-excursion
(beginning-of-defun)
(let ((protocopy-begin (point)))
(forward-list)
(let ((protocopy-end (point)))
(kill-ring-save protocopy-begin protocopy-end)))))
#+end_src
** Window manipulation
*** Bury a window
#+begin_src emacs-lisp
(defun gpolonkai/bury-window (window)
"Quit WINDOW without killing it."
(interactive)
(quit-window nil window))
#+end_src
*** Scroll a specific window up or down
#+begin_src emacs-lisp
(defun gpolonkai/scroll-window-up (window)
"Scroll WINDOW up as `scroll-up-command' would."
(interactive)
(save-selected-window
(select-window window)
(scroll-up)))
(defun gpolonkai/scroll-window-down (window)
"Scroll WINDOW down as `scroll-down-command' would."
(interactive)
(save-selected-window
(select-window window)
(scroll-down)))
#+end_src
*** Transpose windows
#+begin_src emacs-lisp
(defun gpolonkai/transpose-windows (arg)
"Transpose the buffers shown in two windows."
(interactive "p")
(let ((selector (if (>= arg 0) 'next-window 'previous-window)))
(while (/= arg 0)
(let ((this-win (window-buffer))
(next-win (window-buffer (funcall selector))))
(set-window-buffer (selected-window) next-win)
(set-window-buffer (funcall selector) this-win)
(select-window (funcall selector)))
(setq arg (if (plusp arg) (1- arg) (1+ arg))))))
#+end_src
*** Toggle window split between horizontal and vertical
#+begin_src emacs-lisp
(defun gpolonkai/toggle-window-split ()
(interactive)
(if (= (count-windows) 2)
(let* ((this-win-buffer (window-buffer))
(next-win-buffer (window-buffer (next-window)))
(this-win-edges (window-edges (selected-window)))
(next-win-edges (window-edges (next-window)))
(this-win-2nd (not (and (<= (car this-win-edges)
(car next-win-edges))
(<= (cadr this-win-edges)
(cadr next-win-edges)))))
(splitter
(if (= (car this-win-edges)
(car (window-edges (next-window))))
'split-window-horizontally
'split-window-vertically)))
(delete-other-windows)
(let ((first-win (selected-window)))
(funcall splitter)
(if this-win-2nd (other-window 1))
(set-window-buffer (selected-window) this-win-buffer)
(set-window-buffer (next-window) next-win-buffer)
(select-window first-win)
(if this-win-2nd (other-window 1))))
(error "This works only for two windows!")))
#+end_src
** Org-mode related
*** Wrapper around ~org-agenda~ to open my own custom list
#+begin_src emacs-lisp
(defun gpolonkai/org-agenda-list (&optional arg)
(interactive "P")
(org-agenda arg "c"))
#+end_src
*** Insert the current timestamp
#+begin_src emacs-lisp
(defun gpolonkai/org-insert-current-timestamp (&optional arg)
"Insert the current timestamp"
(interactive "P")
(org-time-stamp '(16) arg))
#+end_src
*** Insert two spaces after certain marks
#+begin_src emacs-lisp
(defcustom gpolonkai/org-dbl-space-punct-marks (list ?. ?! ?? ?…)
"Punctuation marks after which the space key should insert two space characters."
:type '(set character))
(defun gpolonkai/org-space-key (&optional arg)
"Insert two spaces after certain markers.
ARG will be passed down verbatim to `self-insert-command'."
(interactive "p")
(when (and
(not (org-in-block-p '("src")))
(looking-back (rx-to-string `(any,@ gpolonkai/org-dbl-space-punct-marks)) nil))
(call-interactively 'self-insert-command arg))
(call-interactively 'self-insert-command arg))
#+end_src
*** Filter out tasks from the Org agenda if they have a specific priority
The whole idea comes from [[https://blog.aaronbieber.com/2016/09/24/an-agenda-for-life-with-org-mode.html][here]] which i use almost verbatim, hence the ~air-~ prefix.
#+begin_src emacs-lisp
(defun air-org-skip-subtree-if-priority (priority)
"Skip an agenda subtree if it has a priority of PRIORITY.
PRIORITY may be one of the characters ?A, ?B, or ?C."
(let ((subtree-end (save-excursion (org-end-of-subtree t)))
(pri-value (* 1000 (- org-lowest-priority priority)))
(pri-current (org-get-priority (thing-at-point 'line t))))
(if (= pri-value pri-current)
subtree-end
nil)))
#+end_src
*** Filter out habits from the Org agenda
#+begin_src emacs-lisp
(defun air-org-skip-subtree-if-habit ()
"Skip an agenda entry if it has a STYLE property equal to \"habit\"."
(let ((subtree-end (save-excursion (org-end-of-subtree t))))
(if (string= (org-entry-get nil "STYLE") "habit")
subtree-end
nil)))
#+end_src
*** Filter out entries from the Org agenda with a specific state
#+begin_src emacs-lisp
(defun gpolonkai/org-skip-subtree-if-state (state)
"Skip an agenda entry if its state is STATE."
(let ((subtree-end (save-excursion (org-end-of-subtree t))))
(if (string= (org-get-todo-state) state)
subtree-end
nil)))
#+end_src
*** Insert a heading with CREATED set to the current time
This emulates how Orgzly work with my current settings.
#+begin_src emacs-lisp
(defun gpolonkai/org-insert-heading-created (&optional arg)
(interactive "p")
(let* ((org-insert-heading-respect-content t)
(format-string (concat "[" (substring (cdr org-time-stamp-formats) 1 -1) "]"))
(timestamp (format-time-string format-string (current-time))))
(if (> arg 1)
(org-insert-subheading '(4))
(org-insert-heading))
(org-set-property "CREATED" timestamp)))
#+end_src
*** Unfold everything during ~ediff~ sessions
EDiff and Org-mode files dont play nice together…
From [[https://list.orgmode.org/loom.20130801T011342-572@post.gmane.org/][the org-mode mailing list]].
#+begin_src emacs-lisp
(defun f-ediff-org-showhide (buf command &rest cmdargs)
"If buffer BUF exists and in `org-mode', execute COMMAND with CMDARGS."
(when buf
(when (eq (buffer-local-value 'major-mode (get-buffer buf)) 'org-mode)
(save-excursion
(set-buffer buf)
(apply command cmdargs)))))
(defun f-ediff-org-unfold-tree-element ()
"Unfold tree at diff location."
(f-ediff-org-showhide ediff-buffer-A 'org-reveal)
(f-ediff-org-showhide ediff-buffer-B 'org-reveal)
(f-ediff-org-showhide ediff-buffer-C 'org-reveal))
(defun f-ediff-org-fold-tree ()
"Fold tree back to top level."
(f-ediff-org-showhide ediff-buffer-A 'hide-sublevels 1)
(f-ediff-org-showhide ediff-buffer-B 'hide-sublevels 1)
(f-ediff-org-showhide ediff-buffer-C 'hide-sublevels 1))
#+end_src
*** Add code references to Org documents
From the [[http://www.howardism.org/Technical/Emacs/capturing-content.html][Howardism blog]].
#+begin_src emacs-lisp
(defun ha/org-capture-fileref-snippet (f type headers func-name)
(let* ((code-snippet
(buffer-substring-no-properties (mark) (- (point) 1)))
(file-name (buffer-file-name))
(file-base (file-name-nondirectory file-name))
(line-number (line-number-at-pos (region-beginning)))
(initial-txt (if (null func-name)
(format "From [[file:%s::%s][%s]]:"
file-name line-number file-base)
(format "From ~%s~ (in [[file:%s::%s][%s]]):"
func-name file-name line-number
file-base))))
(format "
%s
,#+begin_%s %s
%s
,#+end_%s" initial-txt type headers code-snippet type)))
(defun ha/org-capture-clip-snippet (f)
"Given a file, F, this captures the currently selected text
within an Org EXAMPLE block and a backlink to the file."
(with-current-buffer (find-buffer-visiting f)
(ha/org-capture-fileref-snippet f "example" "" nil)))
(defun ha/org-capture-code-snippet (f)
"Given a file, F, this captures the currently selected text
within an Org SRC block with a language based on the current mode
and a backlink to the function and the file."
(with-current-buffer (find-buffer-visiting f)
(let ((org-src-mode (replace-regexp-in-string "-mode" "" (format "%s" major-mode)))
(func-name (which-function)))
(ha/org-capture-fileref-snippet f "src" org-src-mode func-name))))
#+end_src
** Text manipulation
*** Fill or unfill a paragraph
From Sacha Chuas [[http://pages.sachachua.com/.emacs.d/Sacha.html][blog]].
#+begin_src emacs-lisp
(defun sachachua/fill-or-unfill-paragraph (&optional unfill region)
"Fill (or unfill, if UNFILL is non-nil) paragraph (or REGION)."
(interactive (progn
(barf-if-buffer-read-only)
(list (if current-prefix-arg 'unfill) t)))
(let ((fill-column (if unfill (point-max) fill-column)))
(fill-paragraph nil region)))
#+end_src
*** Toggle case of character at point
Based on [[http://ergoemacs.org/emacs/modernization_upcase-word.html][Xahs toggle letter case defun version 2015-12-22]]
#+begin_src emacs-lisp
(defun gpolonkai/toggle-char-case (arg-move-point)
"Toggle the case of the char after point.
If prefix argument ARG-MOVE-POINT is non-nil, move point after the char."
(interactive "P")
(let ((case-fold-search nil))
(cond
((looking-at "[[:lower:]]") (upcase-region (point) (1+ (point))))
((looking-at "[[:upper:]]") (downcase-region (point) (1+ (point)))))
(cond
(arg-move-point (right-char)))))
#+end_src
*** Sort lines by the first number on it
#+begin_src emacs-lisp
(defun gpolonkai/numeric-sort-lines (reverse beg end)
"Sort lines in region by version.
Interactively, REVERSE is the prefix argument, and BEG and END are the region.
Non-nil REVERSE means to sort in reverse order."
(interactive "P\nr")
(save-excursion
(save-restriction
(narrow-to-region beg end)
(goto-char (point-min))
(let ((indibit-field-text-motion t))
(sort-subr reverse 'forward-line 'end-of-line #'gpolonkai/find-number-on-line)))))
#+end_src
*** Open a new line above
#+begin_src emacs-lisp
(defun wted/open-line-above ()
"Open a new line above point."
(interactive)
(beginning-of-line)
(newline)
(forward-line -1)
(let ((tab-always-indent t)
(c-tab-always-indent t))
(indent-for-tab-command)))
#+end_src
*** Open a new line below
Copied from [[http://whattheemacsd.com/editing-defuns.el-01.html][whattheemacsd.com]].
#+begin_src emacs-lisp
(defun wted/open-line-below ()
"Open a new line below point."
(interactive)
(end-of-line)
(newline)
(let ((tab-always-indent t)
(c-tab-always-indent t))
(indent-for-tab-command)))
#+end_src
*** Insert the current files name at point
From [[http://mbork.pl/2019-02-17_Inserting_the_current_file_name_at_point][Marcin Borkowski]].
#+begin_src emacs-lisp
(defun mbork/insert-current-file-name-at-point (&optional full-path)
"Insert the current filename at point.
With prefix argument, use full path."
(interactive "P")
(let* ((buffer
(if (minibufferp)
(window-buffer
(minibuffer-selected-window))
(current-buffer)))
(filename (buffer-file-name buffer)))
(if filename
(insert (if full-path filename (file-name-nondirectory filename)))
(error (format "Buffer %s is not visiting a file" (buffer-name buffer))))))
#+end_src
*** Swap occurences of strings
From [[http://emacs.stackexchange.com/a/27170/507][Emacs SE]].
#+begin_src emacs-lisp
(defun e-se/query-swap-strings (from-string
to-string
&optional delimited start end)
"Swap occurrences of FROM-STRING and TO-STRING.
DELIMITED, START, and END are passed down verbatim to `perform-replace'."
(interactive
(let ((common
(query-replace-read-args
(concat "Query swap"
(if current-prefix-arg
(if (eq current-prefix-arg '-) " backward" " word")
"")
(if (use-region-p) " in region" ""))
nil)))
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (use-region-p) (region-beginning))
(if (use-region-p) (region-end)))))
(perform-replace
(concat "\\(" (regexp-quote from-string) "\\)\\|" (regexp-quote to-string))
`(replace-eval-replacement replace-quote
(if (match-string 1)
,to-string
,from-string))
t t delimited nil nil start end))
2023-10-03 08:29:04 +00:00
#+end_src
** Navigation
*** Move to different beginnings/ends of the current line
Inspired by Bozhidar Batsov's [[http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/][solution]].
#+begin_src emacs-lisp
(defun gpolonkai/move-to-beginning-of-line ()
"Move to different beginnings of the line.
These are, in order:
- beginning of the visual line if `visual-line-mode' is active,
- the first non-whitespace (indentation),
- the actual beginning of the line.
This function will jump between the first character and the
indentation if used multiple times."
(interactive)
(let ((last-pos (point)))
(when visual-line-mode
(beginning-of-visual-line))
(when (= (point) last-pos)
(back-to-indentation))
(when (= (point) last-pos)
(beginning-of-line))
(when (and (eq major-mode 'org-mode)
(= (point) last-pos))
(org-beginning-of-line))
(when (= (point) last-pos)
(back-to-indentation))))
(defun gpolonkai/move-to-end-of-line ()
"Move to the end of the line.
If `visual-line-mode' is active, jump to the end of the visual
line first. Then jump to the actual end of the line."
(interactive)
(let ((last-pos (point)))
(when visual-line-mode
(end-of-visual-line))
(when (= (point) last-pos)
(end-of-line))
(when (and (eq major-mode 'org-mode)
(= (point) last-pos))
(org-end-of-line))))
#+end_src
*** Move to the next occurence of a character within the same line
#+begin_src emacs-lisp
(defun gpolonkai/goto-next-char (chr)
(interactive "c")
(when (search-forward (char-to-string chr) (pos-eol) t)
(backward-char)))
#+end_src
*** Move to the beginning of the next word
#+begin_src emacs-lisp
(defun gpolonkai/beginning-of-next-word ()
(interactive)
(let ((current-point (point)))
(forward-word 1)
(backward-word 1)
(when (<= (point) current-point)
(forward-word 2)
(backward-word 1))))
#+end_src
** File manipulation
*** Rename the current file
From [[http://whattheemacsd.com/file-defuns.el-01.html][whattheemacsd.org]].
#+begin_src emacs-lisp
(defun wted/rename-current-buffer-file ()
"Renames current buffer and file it is visiting."
(interactive)
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file!" name)
(let ((new-name (read-file-name "New name: " filename)))
(if (get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name)
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
; TODO: this is suspicious for me…
(set-buffer-modified-p nil)
(message "File '%s' successfully renamed to '%s'"
name (file-name-nondirectory new-name)))))))
#+end_src
*** Delete the current file
From [[http://whattheemacsd.com/file-defuns.el-02.html][whattheemacsd.org]].
#+begin_src emacs-lisp
(defun wted/delete-current-buffer-file ()
"Remove file connected to current buffer and kill the buffer."
(interactive)
(let ((filename (buffer-file-name))
(name (buffer-name))
(buffer (current-buffer)))
(if (not (and filename (file-exists-p filename)))
(kill-buffer buffer)
(when (yes-or-no-p "Are you sure you want to remove this file? ")
(delete-file filename)
(kill-buffer buffer)
(message "File '%s' successfully removed" filename)))))
#+end_src
* Set up the very basics
Now that we have package management configured we can set up defaults more easily. This includes every builtin packages, font faces, and the like.
#+begin_src emacs-lisp
(use-package emacs
:ensure nil
:init
;; Required for Consult/Vertico
(defun crm-indicator (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
(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)
2023-11-02 16:22:24 +00:00
(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))
#+end_src
** Set Orgs main directory
Since a lot of packages (org-projectile, org-caldav, etc.) rely on it, it needs to be set as early as possible.
#+begin_src emacs-lisp
(setq org-directory (expand-file-name "NextCloud/orgmode" user-documents-directory))
#+end_src
** Set up my personal keymap
I set it up at the beginning so i can use it with ~use-package~ invocations from early on
This might (should?) become a [[*general][general]] map later.
#+begin_src emacs-lisp
(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)
#+end_src
** Set up some faces
#+begin_src emacs-lisp
(use-package faces
:ensure nil
:custom-face
2023-11-02 16:22:55 +00:00
(default ((t (:family "Fira Code Retina" :foundry "simp" :slant normal :weight normal :height 100 :width normal))))
(trailing-whitespace ((t (:inherit nil :background "red3")))))
#+end_src
*** Fira Code comes with nice ligatures, lets use them!
#+begin_src emacs-lisp
(use-package ligature
:config
;; Enable the "www" ligature in every possible major mode
(ligature-set-ligatures 't '("www"))
;; Enable traditional ligature support in eww-mode, if the
;; `variable-pitch' face supports it
(ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
;; Enable all Cascadia 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))
#+end_src
** Set the default font and configure font resizing
Before this can be used, make sure the [[https://zhm.github.io/symbola/][Symbola]] font is installed.
#+begin_src emacs-lisp
(defun gpolonkai/set-font-size (frame)
(when (display-graphic-p frame)
2023-11-02 16:22:55 +00:00
(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)
#+end_src
** Set UTF-8 as the default encoding
Just to make sure, although most Linux DEs do this for me.
#+begin_src emacs-lisp
(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8)
#+end_src
** Default frame settings
#+begin_src emacs-lisp
(use-package frame
:ensure nil
:custom
;; Make that cursor blink!
(blink-cursor-mode t))
#+end_src
** I really dont want to type more than i really must…
#+begin_src emacs-lisp
(defalias 'yes-or-no-p 'y-or-n-p)
#+end_src
** Tweak window chrome, AKA lets set up the UI
Turn off the scroll bar (thats why Nyan-cat is here), the toolbar (I dont really use it), and
the menu bar (I rarely use it, and in those rare occasions I can simply turn it on.)
Also, maximise the frame.
#+begin_src emacs-lisp
(tool-bar-mode 0)
(menu-bar-mode 0)
(when window-system
(scroll-bar-mode -1))
(set-frame-parameter nil 'fullscreen 'maximized)
#+end_src
** Enable all the commands!
These are disabled for a reason, but im a rockstar, so who cares‽
#+begin_src emacs-lisp
(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)
#+end_src
* Global built-in packages
** ~simple~, to always show the current column, and using visual lines in text modes
Column numbers help a lot in debugging, while visual line mode is easier on the eye when writing long text.
#+begin_src emacs-lisp
(use-package simple
:ensure nil
:custom
(column-number-mode t)
:hook
(text-mode . (lambda () (visual-line-mode t))))
#+end_src
** ~prog-mode~
Plus prettify all the symbols!
2023-09-03 19:03:52 +00:00
#+begin_src emacs-lisp
(use-package prog-mode
:ensure nil
:init
(setq prettify-symbols-alist
'(("lambda" . ?λ)
("function" . ?ƒ)
("map" . ?↦)
("not" . ?¬)
("and" . ?∧)
("or" . ?)))
2023-09-03 19:03:52 +00:00
:config
(global-prettify-symbols-mode t))
2023-09-03 19:03:52 +00:00
#+end_src
** ~thingatpt~
#+begin_src emacs-lisp
(use-package thingatpt
:ensure nil)
#+end_src
2018-07-30 19:14:51 +00:00
** ~nxml~
#+begin_src emacs-lisp
(use-package nxml-mode
:ensure nil
:custom
(nxml-attribute-indent 4)
(nxml-child-indent 4)
(nxml-outline-child-indent 4))
#+end_src
** ~recentf~
#+begin_src emacs-lisp
(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)))
#+end_src
** ~files~
#+begin_src emacs-lisp
(use-package files
:ensure nil
:custom
(make-backup-file-name-function 'xah/backup-file-name))
#+end_src
2018-07-30 17:52:16 +00:00
** ~whitespace~
~whitespace-mode~ is turned on by default, and can be toggled with ~F10~.
#+begin_src emacs-lisp
(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))))
2018-07-30 17:52:16 +00:00
(use-package whitespace
:demand
:config
(add-function :before-while whitespace-enable-predicate 'prevent-whitespace-mode-for-some)
2018-07-30 17:52:16 +00:00
(global-whitespace-mode 1)
:custom
2023-11-02 16:22:24 +00:00
(whitespace-line-column 120)
2018-07-30 17:52:16 +00:00
:bind
(([f10] . whitespace-mode)
([(shift f10)] . global-whitespace-mode)
:map gpolonkai/pers-map
2023-01-31 11:54:41 +00:00
("w" . whitespace-cleanup))
:custom-face
(whitespace-line ((t (:inherit nil :background "orange4")))))
#+end_src
2018-07-30 17:52:16 +00:00
** ~eshell~
This is a function to delete a character, or close ~eshell~ if theres nothing to delete. Taken
from [[https://ryuslash.org/posts/C-d-to-close-eshell.html][here]].
#+begin_src emacs-lisp
(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))))))
#+end_src
Function to bind it locally to =C-d=.
#+begin_src emacs-lisp
(defun gpolonkai/eshell-set-c-d-locally ()
(local-set-key (kbd "C-d") #'eshell-C-d))
#+end_src
Now set up eshell.
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package eshell
:bind
(:map gpolonkai/pers-map
("e" . eshell))
:hook
(eshell-mode . gpolonkai/eshell-set-c-d-locally))
#+end_src
** ~calendar~ & Co.
#+begin_src emacs-lisp
(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"))
#+end_src
*** Add Hungarian holidays to the calendar
I know this is the builtin packages section. Sorry for cheating.
#+begin_src emacs-lisp
(use-package hungarian-holidays
:config
(hungarian-holidays-add))
#+end_src
*** Add some other important dates to the calendar
#+begin_src emacs-lisp
(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)
#+end_src
2018-07-30 17:52:16 +00:00
** ~saveplace~
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package saveplace
:ensure nil
2023-10-16 08:04:07 +00:00
:config
(save-place-mode 1)
:custom
(save-place-file (expand-file-name ".places" user-emacs-directory)))
#+end_src
2018-07-30 17:52:16 +00:00
** ~ediff~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(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))
#+end_src
2018-07-30 17:52:16 +00:00
** ~autorevert~
2018-07-30 17:52:16 +00:00
…unless they are modified, of course.
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package autorevert
:ensure nil
2018-07-30 17:52:16 +00:00
:config
(global-auto-revert-mode 1))
#+end_src
2018-07-30 17:52:16 +00:00
** ~eww~
2018-07-30 17:52:16 +00:00
For in-Emacs browsing needs.
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package eww
:custom
(eww-search-prefix "https://duckduckgo.com/html/?q="))
#+end_src
2018-07-30 17:52:16 +00:00
** ~electric~, for automatic indentation
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package electric
:config
;; This seems to be the default, but lets make sure…
(electric-indent-mode 1))
#+end_src
2018-07-30 17:52:16 +00:00
** ~savehist~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package savehist
:config
(savehist-mode 1))
#+end_src
2018-07-30 17:52:16 +00:00
** ~webjump~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package webjump
:bind
(:map gpolonkai/pers-map
("j" . webjump)))
#+end_src
2018-07-30 17:52:16 +00:00
** ~which-func~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
(defun gpolonkai/activate-which-func-mode ()
(if (fboundp 'which-function-mode)
(which-function-mode)
(which-func-mode)))
#+end_src
Enable ~which-func-mode~ in every ~prog-mode~ derived mode.
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package which-func
:config
(setq which-func-unknown "∅")
:hook
(prog-mode . gpolonkai/activate-which-func-mode))
#+end_src
2018-07-30 17:52:16 +00:00
** ~cookie1~, AKA fortune cookies
2018-07-30 17:52:16 +00:00
“Fortunes” are from the Hungarian version an ancient MS-DOS based program called ~TAGLINE~.
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package cookie1
:demand t
:custom
(cookie-file (expand-file-name "fortune-cookies.txt" user-emacs-directory))
2018-07-30 17:52:16 +00:00
:bind
(:map gpolonkai/pers-map
("k" . cookie)))
#+end_src
2018-07-30 19:14:51 +00:00
** ~dired~
2018-08-09 11:48:01 +00:00
#+begin_src emacs-lisp
2018-08-09 11:48:01 +00:00
(use-package dired
:ensure nil
:custom
(dired-dwim-target t)
(wdired-create-parent-directories t)
(wdired-allow-to-change-permissions t)
2018-08-09 11:48:01 +00:00
:bind
(:map dired-mode-map
("RET" . dired-find-alternate-file)
("^" . (lambda () (interactive) (find-alternate-file "..")))
("W" . wdired-change-to-wdired-mode)))
#+end_src
2018-08-09 11:48:01 +00:00
** ~goto-addr~, actionable URLs
#+begin_src emacs-lisp
(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))
#+end_src
** Do things at ~midnight~
Since my machine (and thus, my Emacs) is turned on pretty much 24/7, its a pretty good idea.
By default, it closes a bunch of unused buffers. I might add some more things there later.
#+begin_src emacs-lisp
(use-package midnight
:ensure nil
:config
(setq clean-buffer-list-kill-never-buffer-names '("*scratch*"
"*Messages*"
"*dashboard*"))
(midnight-mode t))
#+end_src
** ~display-line-numbers~
I usually dont want to see them, but there are occasions when theyre useful.
#+begin_src emacs-lisp
(use-package display-line-numbers
:bind
(:map gpolonkai/pers-map
("C-n" . display-line-numbers-mode)))
#+end_src
** ~ispell~
2019-01-30 07:56:54 +00:00
#+begin_src emacs-lisp
2019-01-30 07:56:54 +00:00
(use-package ispell
:custom
(ispell-dictionary "en_GB")
(ispell-program-name "/usr/bin/hunspell")
2019-01-30 07:56:54 +00:00
:hook
(mail-send . ispell-message)
(message-send . ispell-message))
#+end_src
2019-01-30 07:56:54 +00:00
** ~speedbar~
This is basically just a dependency for [[*projectile-speedbar][projectile-speedbar]].
#+begin_src emacs-lisp
(use-package speedbar)
#+end_src
** ~browse-url~
This is a Termux-specific override.
#+begin_src emacs-lisp
(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))))))
#+end_src
** ~dabbrev~
I simply remap ~dabbrev-expand~ to a different key and replace the default binding with ~dabbrev-completion~.
#+begin_src emacs-lisp
(use-package dabbrev
:bind (("M-/" . dabbrev-completion)
("C-M-/" . dabbrev-expand)))
#+end_src
* Project management
** ~projectile~
#+begin_src emacs-lisp
(use-package projectile
:demand t
:delight '(:eval (concat " [" projectile-project-name "]"))
:config
(projectile-mode t)
:bind
(:map mode-specific-map
("p" . projectile-command-map)))
#+end_src
** ~projectile-speedbar~
#+begin_src emacs-lisp
(use-package projectile-speedbar
:after (:all projectile sr-speedbar)
:bind
(:map projectile-mode-map
("C-c p B" . projectile-speedbar-toggle)))
#+end_src
** ~org-projectile~ for per-repository ToDo files using Org
#+begin_src emacs-lisp
(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))
#+end_src
* External packages to boost usability
** ~gnu-elpa-keyring-update~, to make sure we always have the latest ELPA GPG keys
#+begin_src emacs-lisp
(use-package gnu-elpa-keyring-update)
#+end_src
** ~auto-package-update~, to automatically upgrade packages every week
#+begin_src emacs-lisp
(use-package auto-package-update
:custom
(auto-package-update-interval 7)
(auto-package-update-delete-old-versions t)
;; Lets do this in after-init-hook, as use-package invocations may modify
;; the list of installed packages
:hook
(after-init . auto-package-update-maybe))
#+end_src
** ~ace-window~, for better window navigation
Besides its standard functionality i also add key bindings for burying or scrolling other windows.
#+begin_src emacs-lisp
(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)))))
#+end_src
** ~doom-themes~
#+begin_src emacs-lisp
(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))
#+end_src
** Nyanyanyanyanya
*** ~nyan-mode~: Nyan-cat style position marker
The package that [[https://gergely.polonkai.eu/blog/2014/9/17/nyanmacs.html][made me]] switch to Emacs.
#+begin_src emacs-lisp
(use-package nyan-mode
:config
(nyan-mode t)
:custom
(nyan-bar-length 20)
(nyan-animate-nyancat t)
(nyan-wavy-trail t))
#+end_src
** ~delight~ to de-light some minor modes
2018-08-10 05:14:00 +00:00
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.
#+begin_src emacs-lisp
2018-08-10 05:14:00 +00:00
(use-package delight)
#+end_src
** ~minions~, to put all minor modes into a menu
2018-08-10 05:14:00 +00:00
#+begin_src emacs-lisp
(use-package minions
:config
(minions-mode 1))
#+end_src
2018-07-30 17:52:16 +00:00
** ~doom-modeline~, because its much, much more beautiful than the vanilla one
2018-07-30 17:52:16 +00:00
2023-08-30 14:55:20 +00:00
#+begin_src emacs-lisp
(use-package doom-modeline
:init
(doom-modeline-mode 1)
:custom
2023-08-30 14:55:20 +00:00
(doom-modeline-continuous-word-count-modes '(markdown-mode gfm-mode org-mode rst-mode))
(doom-modeline-hud t)
(doom-modeline-minor-modes t))
#+end_src
2018-07-30 17:52:16 +00:00
** ~beacon~ to find the cursor
2018-07-30 17:52:16 +00:00
Sometimes it disappears, or just too hard to see.
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package beacon
:demand
:config
(beacon-mode 1)
:bind
(:map gpolonkai/pers-map
("b" . beacon-blink)))
#+end_src
** ~eshell~ extras
2018-07-30 17:52:16 +00:00
*** Display the status of the last command in the fringe of EShell
#+begin_src emacs-lisp
(use-package eshell-fringe-status
:hook
(eshell-mode . eshell-fringe-status-mode))
#+end_src
2018-07-30 17:52:16 +00:00
*** Extras for the EShell prompt
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(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))
#+end_src
2018-07-30 17:52:16 +00:00
** ~form-feed~, to show form feed characters as a horizontal line
2018-07-30 19:14:51 +00:00
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.
#+begin_src emacs-lisp
2018-07-30 19:14:51 +00:00
(use-package form-feed
:hook
(emacs-lisp-mode . form-feed-mode)
2018-12-22 14:05:40 +00:00
(compilation-mode . form-feed-mode)
(help-mode . form-feed-mode))
#+end_src
2018-07-30 19:14:51 +00:00
** ~hl-line~, to highlight the current line
2018-07-29 16:38:44 +00:00
#+begin_src emacs-lisp
2018-07-29 16:38:44 +00:00
(use-package hl-line
:config
(when window-system
2023-01-31 11:54:41 +00:00
(global-hl-line-mode))
:custom-face
(hl-line ((t (:inherit nil :background "gray25")))))
#+end_src
2018-07-29 16:38:44 +00:00
** ~ace-jump-mode~, to jump to a specific character
2018-07-29 18:48:11 +00:00
#+begin_src emacs-lisp
(use-package ace-jump-mode
:bind
(:map gpolonkai/pers-map
("SPC" . ace-jump-mode)))
#+end_src
2018-07-29 18:48:11 +00:00
** Multiple cursors, because one is often not enough
2018-07-29 18:48:11 +00:00
*** ~multiple-cursors~
2018-07-29 18:48:11 +00:00
#+begin_src emacs-lisp
(defun gpolonkai/no-blink-matching-paren ()
(customize-set-variable 'blink-matching-paren nil))
(defun gpolonkai/blink-matching-paren ()
(customize-set-variable 'blink-matching-paren t))
2018-07-29 18:48:11 +00:00
(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)
2019-02-26 13:23:49 +00:00
: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)))
#+end_src
2018-07-29 18:48:11 +00:00
*** ~phi-search~, incremental search compatible with ~multiple-cursors~
2018-07-30 19:14:51 +00:00
#+begin_src emacs-lisp
2018-07-30 19:14:51 +00:00
(use-package phi-search)
(use-package phi-search-mc
:config
(phi-search-mc/setup-keys))
#+end_src
2018-07-30 19:14:51 +00:00
*** ~mc-extras~
2018-07-29 18:48:11 +00:00
#+begin_src emacs-lisp
2018-07-29 18:48:11 +00:00
(use-package mc-extras
:demand
:bind
(:map mc/keymap
("=" . mc/compare-chars)))
#+end_src
2018-07-29 18:48:11 +00:00
*** Add extra cursors with ~ace-jump~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 20:22:45 +00:00
(use-package ace-mc
:bind
(:map gpolonkai/mc-prefix-map
2019-01-03 15:24:07 +00:00
("SPC" . ace-mc-add-multiple-cursors)
("C-SPC" . ace-mc-add-single-cursor)))
#+end_src
** ~smartparens~ for easier parentheses insertion
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package smartparens
:demand
:config
2023-10-16 12:09:54 +00:00
(require 'smartparens-config)
2018-07-30 17:52:16 +00:00
(show-smartparens-global-mode t)
:hook
(prog-mode . turn-on-smartparens-strict-mode)
(markdown-mode . turn-on-smartparens-strict-mode)
2018-07-30 17:52:16 +00:00
:bind
(([f9] . smartparens-strict-mode)
("C-c s u" . sp-unwrap-sexp)
2023-10-17 12:03:29 +00:00
("C-c s k" . sp-kill-sexp)
("C-c s r" . sp-rewrap-sexp)))
#+end_src
2018-07-30 17:52:16 +00:00
** ~which-key~ to display available key bindings
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
(use-package which-key
:config
(which-key-mode)
(which-key-setup-minibuffer)
:custom
(which-key-idle-delay 0.3))
#+end_src
2018-11-18 06:03:04 +00:00
** ~visual-fill-column~, width limited text view
2018-07-30 17:52:16 +00:00
Its much easier on the eye when writing text, not code.
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
(use-package visual-fill-column
:custom
(visual-fill-column-center-text t)
:hook
(org-mode . visual-fill-column-mode))
#+end_src
2018-07-30 17:52:16 +00:00
** ~spinner~, to display a progress bar for e.g. background tasks
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
(use-package spinner)
#+end_src
2018-07-30 17:52:16 +00:00
** ~avy~ to jump to things
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package avy
:demand
:config
(avy-setup-default)
:bind
(("M-g c" . avy-goto-char)
("M-g C" . avy-goto-char-2)
2018-07-30 17:52:16 +00:00
("M-g f" . avy-goto-line)
("M-g w" . avy-goto-word-1)
("M-g e" . avy-goto-word-0)))
#+end_src
2018-07-30 17:52:16 +00:00
** ~goto-last-change~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package goto-last-change
:bind
(("M-g /" . goto-last-change)))
#+end_src
2018-07-30 17:52:16 +00:00
** ~rainbow-mode~ to highlight colours based on their name/hex code
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package rainbow-mode
:hook
(css-mode . rainbow-mode)
(scss-mode . rainbow-mode)
(sass-mode . rainbow-mode))
#+end_src
2018-07-30 17:52:16 +00:00
** ~zygospore~ to toggle other windows for maximum focus
2018-07-30 17:52:16 +00:00
When focus is no longer needed, they can be toggled back.
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package zygospore
:bind
(:map ctl-x-map
("1" . zygospore-toggle-delete-other-windows)))
#+end_src
2018-07-30 17:52:16 +00:00
** ~dashboard~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
2018-07-30 17:52:16 +00:00
(use-package dashboard
:after
projectile
:config
(add-to-list 'dashboard-items '(projects . 5) t)
2023-01-22 06:49:02 +00:00
(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))))
#+end_src
** ~sr-speedbar~, speed bar in the same frame
#+begin_src emacs-lisp
(use-package sr-speedbar
:after speedbar)
#+end_src
2018-07-30 17:52:16 +00:00
** ~hungry-delete~ to delete all the whitespace
2018-07-30 19:14:51 +00:00
#+begin_src emacs-lisp
(use-package hungry-delete
:config
(global-hungry-delete-mode))
#+end_src
2018-07-30 19:14:51 +00:00
** ~anzu~, to show number of matches while searching
#+begin_src emacs-lisp
(use-package anzu
:delight
:config
(global-anzu-mode 1))
#+end_src
** ~all-the-icons~
Should the fonts be missing, run ~(all-the-icons-install-fonts)~. Its not run
automatically, as it requires connecting to a website and download a pretty
large font file.
#+begin_src emacs-lisp
(use-package all-the-icons)
#+end_src
And apply it to dired, too.
#+begin_src emacs-lisp
(use-package all-the-icons-dired
:hook
(dired-mode . all-the-icons-dired-mode))
#+end_src
** ~flyspell~ for all my spell-checking needs
#+begin_src emacs-lisp
2018-07-30 19:14:51 +00:00
(use-package flyspell
:hook
(prog-mode . flyspell-prog-mode)
(text-mode . flyspell-mode))
#+end_src
2018-07-30 19:14:51 +00:00
** ~ace-flyspell~
#+begin_src emacs-lisp
(use-package ace-flyspell
:bind
(:map flyspell-mode-map
("C-M-i" . ace-flyspell-correct-word)))
#+end_src
** ~objed~, text object manipulation
From the package description:
#+begin_quote
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.
#+end_quote
#+begin_src emacs-lisp
(use-package objed
:demand t
:bind
(:map global-map
("M-SPC" . objed-activate)))
#+end_src
** ~alert~ to send alerts to a notification system
2018-07-30 19:14:51 +00:00
#+begin_src emacs-lisp
2018-07-30 19:14:51 +00:00
(use-package alert
:config
(setq alert-default-style
(if (gpolonkai/termux-p)
2018-07-30 19:14:51 +00:00
(progn
;; TODO Remove this as soon as my PR gets merged
;; https://github.com/jwiegley/alert/pull/41
(unless (fboundp 'alert-termux-notify)
(defcustom alert-termux-command (executable-find "termux-notification")
"Path to the termux-notification command.
This is found in the termux-api package, and it requires the Termux
API addon app to be installed."
:type 'file
:group 'alert)
(defun alert-termux-notify (info)
"Send INFO using termux-notification.
Handles :TITLE and :MESSAGE keywords from the
INFO plist."
(if alert-termux-command
(let ((args (nconc
(when (plist-get info :title)
(list "-t" (alert-encode-string (plist-get info :title))))
(list "-c" (alert-encode-string (plist-get info :message))))))
(apply #'call-process alert-termux-command nil
(list (get-buffer-create " *termux-notification output*") t)
nil args))
(alert-message-notify info)))
(alert-define-style 'termux :title "Notify using termux"
:notifier #'alert-termux-notify))
'termux)
'libnotify)))
#+end_src
** ~undo-tree~
#+begin_src emacs-lisp
2023-10-22 04:56:53 +00:00
(use-package undo-tree
:config
(global-undo-tree-mode)
:custom
(undo-tree-auto-save-history nil))
#+end_src
** ~ciel~ to mimic ViMs ~ci~ functionality
#+begin_src emacs-lisp
(use-package ciel
:bind
(:map global-map
("C-c i" . ciel-ci)
("C-c o" . ciel-co)))
#+end_src
** ~hide-mode-line~ to hide the modeline occasionally
#+begin_src emacs-lisp
(use-package hide-mode-line
:bind (:map gpolonkai/pers-map
("h" . hide-mode-line-mode)))
#+end_src
** ~string-inflection~
#+begin_src emacs-lisp
(use-package string-inflection
:bind (:map gpolonkai/pers-map
("i" . string-inflection-all-cycle)))
#+end_src
2023-10-20 03:10:52 +00:00
** ~spdx~ to insert SPDX compatible license text
#+begin_src emacs-lisp
(use-package spdx
:bind (:map gpolonkai/pers-map
("L" . spdx-insert-spdx-copyright))
:custom
(spdx-copyright-holder 'user)
(spdx-copyright-sign 'unicode))
#+end_src
2023-11-02 16:23:34 +00:00
** ~ag~ to use the silver searcher
#+begin_src emacs-lisp
(use-package ag
:commands (ag))
#+end_src
2023-11-02 16:23:45 +00:00
** ~rg~ to use ripgrep
#+begin_src emacs-lisp
(use-package rg
:commands (rg))
#+end_src
* Dired extras
** ~dired-collapse~, to collapse directories that contain a single file somewhere deep
#+begin_src emacs-lisp
(use-package dired-collapse)
#+end_src
** ~dired-du~ to show directory sizes
#+begin_src emacs-lisp
(use-package dired-du)
#+end_src
** ~dired-git-info~ to show Git version information
#+begin_src emacs-lisp
(use-package dired-git-info
:bind
(:map dired-mode-map
(")" . dired-git-info-mode)))
#+end_src
** ~dired-hide-dotfiles~ to show/hide hidden (dot) files
#+begin_src emacs-lisp
(use-package dired-hide-dotfiles
:bind
(:map dired-mode-map
("." . dired-hide-dotfiles-mode)))
#+end_src
** ~dired-rainbow~ to color code file types
Rainbow to the stars…
#+begin_src emacs-lisp
(use-package dired-rainbow
:config
(dired-rainbow-define-chmod executable-unix "Green" "-.*x.*"))
#+end_src
** ~dired-k~ to highlight dired buffers by file size, mtime, git status, etc.
#+begin_src emacs-lisp
(use-package dired-k
:bind
(:map dired-mode-map
("K" . dired-k)))
#+end_src
* Git related things
** ~magit~
#+begin_src emacs-lisp
(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))
#+end_src
** ~forge~ to make Magit work with Git forges
#+begin_src emacs-lisp
(use-package forge)
#+end_src
** ~git-gutter~ to see changed lines
In graphical mode we use ~git-gutter-finge~, ~git-gutter~ otherwise (as we have no fringe in that case).
It also provides some nice commands to navigate between change sets.
#+begin_src emacs-lisp
(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)))))
#+end_src
** ~git-messenger~, aka annotate current line
#+begin_src emacs-lisp
(use-package git-messenger
:bind
(:map gpolonkai/pers-map
("gm" . git-messenger:popup-message)))
#+end_src
** ~git-timemachine~, to see previous versions of the current file
#+begin_src emacs-lisp
(use-package git-timemachine
:bind
(([f6] . git-timemachine-toggle)))
#+end_src
* Completion related external packages
** ~vertico~
#+begin_src emacs-lisp
(use-package vertico
:init
(vertico-mode))
#+end_src
** ~consult~
#+begin_src emacs-lisp
(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"))
#+end_src
** ~orderless~
#+begin_src emacs-lisp
(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)))))
#+end_src
** ~marginalia~
#+begin_src emacs-lisp
(use-package marginalia
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
:init
(marginalia-mode))
#+end_src
** ~embark~
#+begin_src emacs-lisp
(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))
#+end_src
** ~consult-projectile~
#+begin_src emacs-lisp
(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)))
#+end_src
2023-10-20 09:54:55 +00:00
** ~corfu~
#+begin_src emacs-lisp
(use-package corfu
:init
(global-corfu-mode)
:custom
(corfu-cycle t)
(corfu-separator ?\s))
#+end_src
2023-10-20 09:56:24 +00:00
** ~cape~
#+begin_src emacs-lisp
(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))
#+end_src
* Org mode
** ~outline~
This is the mode Org is based on. Its technically a built-in, but i configure it here so it remains together with other Org setup.
#+begin_src emacs-lisp
(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)))))
#+end_src
** Function to set up Org-mode buffers
2018-07-30 19:14:51 +00:00
#+begin_src emacs-lisp
(defun gpolonkai/setup-org-mode ()
(org-indent-mode 1)
(variable-pitch-mode 1)
(auto-fill-mode 0)
(visual-line-mode 1))
#+end_src
2018-07-30 19:14:51 +00:00
** Display horizontal rulers as a full-width line
From [[https://matrix.to/#/@suckless_shill:matrix.org][viz]] in the [[https://matrix.to/#/#org-mode:matrix.org][org-mode]] Matrix room.
#+begin_src emacs-lisp
(defun vz/org-fontify-horizontal-break ()
"Display Orgs 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)
#+end_src
** Main ~org~ configuration
#+begin_src emacs-lisp
(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)))
#+end_src
** ~org-roam~
Lets see if i can get my brain more organised this way…
#+begin_src emacs-lisp
(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))
#+end_src
** ~org-roam-timestamps~
#+begin_src emacs-lisp
(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))
#+end_src
** ~org-roam-ui~
#+begin_src emacs-lisp
(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))
#+end_src
** ~org-bullets~ for more beautiful bullet points
#+begin_src emacs-lisp
(use-package org-bullets
:custom
(org-bullets-face-name 'org-bullet-face)
(org-bullets-bullet-list '("✙" "♱" "♰" "☥" "✞" "✟" "✝" "†" "✠" "✚" "✜" "✛" "✢" "✣" "✤" "✥"))
:hook
(org-mode . org-bullets-mode))
#+end_src
2018-07-30 19:14:51 +00:00
** ~org-sticky-header~ so i always know where i am
#+begin_src emacs-lisp
(use-package org-sticky-header
:custom
(org-sticky-header-full-path 'full)
:hook
(org-mode . org-sticky-header-mode))
#+end_src
2018-07-30 19:14:51 +00:00
** ~org-random-todo~ to show a random ToDo every hour
#+begin_src emacs-lisp
(use-package org-random-todo
:demand
:config
;; Dont 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)))
#+end_src
** ~org-autolist~ for better list management
#+begin_src emacs-lisp
(use-package org-autolist
:hook
(org-mode . org-autolist-mode))
#+end_src
** ~secretaria~ to remind me of my tasks
And because even secretaries need a secretary today.
#+begin_src emacs-lisp
(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))
#+end_src
** ~org-clock-waybar~ to export currently clocked task for status bar display
#+begin_src emacs-lisp
(use-package org-clock-waybar
:ensure nil
:quelpa (org-clock-waybar
:fetcher git
:url "https://gitea.polonkai.eu/gergely/org-clock-waybar.git")
:config
(org-clock-waybar-setup))
#+end_src
** ~consult-org-roam~
#+begin_src emacs-lisp
(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)))
#+end_src
** ~org-appear~, to display markup only when its actually needed
#+begin_src emacs-lisp
(use-package org-appear
:hook
(org-mode . org-appear-mode)
:custom
(org-appear-autosubmarkers t)
(org-appear-autolinks t)
(org-appear-autoemphasis t))
#+end_src
** ~ob-mermaid~, to generate Mermaid diagrams
#+begin_src emacs-lisp
(use-package ob-mermaid
:custom
(ob-mermaid-cli-path "/home/polesz/.local/node/bin/mmdc"))
#+end_src
** ~plantuml-mode~ to edit PlantUML files in and out of Org documents
Before using this, make sure the latest PlantUML JAR file is downloaded into the downloads
directory. It is available from [[http://plantuml.com/download][here]].
#+begin_src emacs-lisp
(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))))
#+end_src
** ~ox-rst~ to export to ReSTructured text
#+begin_src emacs-lisp
(use-package ox-rst
:after org)
#+end_src
** ~orgit~ and ~orgit-forge~ to store link to Git stuff
#+begin_src emacs-lisp
(use-package orgit
:after magit org)
(use-package orgit-forge
:after magit org orgit)
#+end_src
* Mailing
** Set up whitespace handling in mu4e buffers
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~.
#+begin_src emacs-lisp
(copy-face 'trailing-whitespace 'trailing-whitespace-mu4e)
(set-face-attribute 'trailing-whitespace-mu4e nil :background 'unspecified)
(defun gpolonkai/mu4e-trailing-whitespace-fix ()
(set (make-local-variable 'face-remapping-alist)
'((trailing-whitespace trailing-whitespace-mu4e))))
#+end_src
** ~mu4e~
Now thats out of the way, lets configure mu4e itself.
#+begin_src emacs-lisp
(use-package mu4e
:after vertico
:ensure nil
:config
2019-02-14 07:09:26 +00:00
(require 'org-mu4e)
(setq mu4e-contexts
`( ,(make-mu4e-context
2020-06-16 04:39:46 +00:00
: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
2020-06-16 04:39:46 +00:00
(mu4e-message-contact-field-matches
msg
:to "gergely@polonkai.eu")))
:vars '((user-mail-address . "gergely@polonkai.eu")
2023-09-19 14:59:01 +00:00
(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")
2021-03-09 16:51:13 +00:00
(message-sendmail-extra-arguments . ("--account=polonkai"))))
,(make-mu4e-context
2020-06-16 04:39:46 +00:00
: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
2020-06-16 04:39:46 +00:00
(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"))))
2023-09-19 14:59:01 +00:00
:vars '((user-mail-address . "gergely@benchmark.games")
2020-06-16 04:39:46 +00:00
(mu4e-sent-folder . "/GT2/[Gmail].Sent Mail")
(mu4e-drafts-folder . "/GT2/[Gmail].Drafts")
(mu4e-trash-folder . "/GT2/[Gmail].Trash")
2021-03-09 16:51:13 +00:00
(mu4e-refile-folder . "/GT2/[Gmail].Drafts")
(message-sendmail-extra-arguments . ("--account=gt2"))))
2020-06-16 04:39:46 +00:00
,(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)
2023-10-15 05:00:07 +00:00
(when msg
(string-match-p "^/Private" (mu4e-message-field msg :maildir))))
2020-06-16 04:39:46 +00:00
:vars '((user-mail-address . "me@gergely.polonkai.eu")
(mu4e-sent-folder . "/Private/Sent")
(mu4e-drafts-folder . "/Private/Drafts")
(mu4e-trash-folder . "/Private/Trash")
2021-03-09 16:51:13 +00:00
(mu4e-refile-folder . "/Private/Drafts")
(message-sendmail-extra-arguments . ("--account=private" "--read-envelope-from")))))
2019-02-14 07:09:26 +00:00
org-mu4e-link-query-in-headers-mode nil)
:custom
(mu4e-context-policy 'pick-first)
(mu4e-confirm-quit nil)
2020-01-23 10:02:41 +00:00
(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)))
#+end_src
2018-11-20 13:00:41 +00:00
** ~sendmail~
2021-03-09 16:51:13 +00:00
#+begin_src emacs-lisp
(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))
#+end_src
** ~org-msg~ to write messages using Org-mode
#+begin_src emacs-lisp
(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"))
#+end_src
* External packages to boost coding productivity
** ~electric-operator~ to automatically add spaces around operators
#+begin_src emacs-lisp
(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))
#+end_src
** ~rainbow-delimiters~
#+begin_src emacs-lisp
(use-package rainbow-delimiters
:hook
(prog-mode . rainbow-delimiters-mode))
#+end_src
** ~rainbow-identifiers~
#+begin_src emacs-lisp
(use-package rainbow-identifiers)
#+end_src
** ~auto-highlight-symbol~ to hightlight current symbol
Great help during refactoring.
#+begin_src emacs-lisp
(use-package auto-highlight-symbol
:config
(global-auto-highlight-symbol-mode t))
#+end_src
** ~glasses~, to make ReallyLongCamelCaseWords more readable
#+begin_src emacs-lisp
(use-package glasses
:delight " 👓"
:hook
(prog-mode . glasses-mode))
#+end_src
** ~hl-todo~ to highlight TODO comments
#+begin_src emacs-lisp
(use-package hl-todo
:hook
(prog-mode . hl-todo-mode))
#+end_src
** ~bug-reference~ to turn bug/patch references to links
#+begin_src emacs-lisp
(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))
#+end_src
** ~highlight-indentation~ to highlight indentation levels
#+begin_src emacs-lisp
(use-package highlight-indentation
:hook
(python-mode . highlight-indentation-mode))
#+end_src
** ~flycheck~
#+begin_src emacs-lisp
(use-package flycheck
:config
(global-flycheck-mode)
:custom
(flycheck-python-pylint-executable "python3"))
#+end_src
** ~flycheck-pkg-config~ to aid FlyCheck using ~pkg-config~
#+begin_src emacs-lisp
(use-package flycheck-pkg-config)
#+end_src
* Utilities
** ~kubernetes~, a kubernetes dashboard
#+begin_src emacs-lisp
(use-package kubernetes
:commands (kubernetes-overview))
#+end_src
** ~elpher~, a Gopher/Gemini client
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.
#+begin_src emacs-lisp
2023-10-20 10:09:11 +00:00
(use-package elpher
:commands (elpher))
#+end_src
** ~mastodon~
#+begin_src emacs-lisp
(use-package mastodon
:custom
(mastodon-instance-url "https://social.polonkai.eu/")
(mastodon-active-user "gergely"))
#+end_src
** ~twtxt~
#+begin_src emacs-lisp
(use-package twtxt
:custom
(twtxt-file (expand-file-name "NextCloud/twtxt.txt" user-documents-directory))
(twtxt-following '(("benaiah" "https://benaiah.me/twtxt.txt")
("jomo" "https://gist.githubusercontent.com/jomo/64d6bd1b95ec0a24612b/raw/twtxt.txt")
("quite" "https://lublin.se/twtxt.txt")
2023-10-20 10:09:33 +00:00
("xena" "https://xena.greedo.xeserv.us/files/xena.txt")
("hecanjog" "https://hecanjog.com/twtxt.txt"))))
#+end_src
** ~paradox~ for better package management
I dont always use the package menu, but when i do, i want to do it in style…
#+begin_src emacs-lisp
(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)))
#+end_src
** ~tidal~ for improvising music
#+begin_src emacs-lisp
2023-10-23 06:24:44 +00:00
(use-package tidal
:mode "\\.tidal\\'")
#+end_src
* Programming-language specific packages
** Python
*** Set up pretty symbols
Because they are fancy.
#+begin_src emacs-lisp
(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" . ?≍))
))
#+end_src
*** ~poetry~
2018-12-01 06:29:45 +00:00
#+begin_src emacs-lisp
(use-package poetry
2018-12-01 06:29:45 +00:00
: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)))
#+end_src
2018-12-01 06:29:45 +00:00
** C
Because thats still my favourite language.
*** Set up my indentation style
#+begin_src emacs-lisp
(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)
#+end_src
*** Set indentation levels to the same as the tab width
#+begin_src emacs-lisp :tangle no
(defvaralias 'c-basic-offset 'tab-width)
(defvaralias 'cperl-indent-level 'tab-width)
#+end_src
*** Some common initialisation for C mode
#+begin_src emacs-lisp
(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)))
#+end_src
** Web
*** ~web-mode~
#+begin_src emacs-lisp
(use-package web-mode
:mode "\\.html?\\'"
:custom
(web-mode-enable-auto-indentation nil)
(web-mode-enable-engine-detection t))
#+end_src
*** ~emmet-mode~ for easier HTML/CSS writing
2019-10-22 08:34:53 +00:00
#+begin_src emacs-lisp
(use-package emmet-mode
2019-10-22 08:34:53 +00:00
:custom
(emmet-self-closing-tag-style "")
2019-10-22 08:34:53 +00:00
:hook
(web-mode . emmet-mode)
(css-mode . emmet-mode))
#+end_src
2019-10-22 08:34:53 +00:00
*** ~enlive~, to query HTML tags by CSS selectors
2019-10-22 09:08:04 +00:00
#+begin_src emacs-lisp
(use-package enlive)
#+end_src
** ~json-mode~
2019-10-22 09:08:04 +00:00
#+begin_src emacs-lisp
(use-package json-mode
:mode "\\.json\\'")
#+end_src
2020-03-24 10:30:52 +00:00
** ~yaml-mode~
2020-03-24 10:30:52 +00:00
#+begin_src emacs-lisp
(use-package yaml-mode
:mode (("\\.yml\\'" . yaml-mode)
("\\.yaml\\'" . yaml-mode))
:init
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)))
#+end_src
** ~dockerfile-mode~
#+begin_src emacs-lisp
(use-package dockerfile-mode)
#+end_src
** ~systemd~, for editing systemd unit files
#+begin_src emacs-lisp
(use-package systemd
:mode ("\\.\\(?:automount\\|mount\\|path\\|s\\(?:ervice\\|lice\\|ocket\\)\\|t\\(?:arget\\|imer\\)\\|wants\\)\\'" . systemd-mode))
#+end_src
** ~terraform-mode~
#+begin_src emacs-lisp
(use-package terraform-mode
:mode "\\.tf\\'")
#+end_src
** ~bats-mode~
#+begin_src emacs-lisp
(use-package bats-mode
:mode "\\.bats\\'")
#+end_src
** ~fish-mode~
#+begin_src emacs-lisp
(use-package fish-mode
:hook
2023-10-20 10:12:57 +00:00
(fish-mode . (lambda () (add-hook 'before-save-hook 'fish_indent-before-save)))
:mode "\\.fish\\'")
#+end_src
** ~gitlab-ci-mode~ and ~gitlab-ci-mode-flycheck~
#+begin_src emacs-lisp
(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))
#+end_src
** ~csv-mode~
#+begin_src emacs-lisp
(use-package csv-mode
:mode "\\.csv\\'")
#+end_src
** Rust
*** ~rust-mode~
#+begin_src emacs-lisp
(use-package rust-mode
:mode "\\.rs\\'")
#+end_src
*** ~cargo~ and ~cargo-mode~ for Cargo usage
#+begin_src emacs-lisp
(use-package cargo)
(use-package cargo-mode
:mode "Cargo\\.toml\\'")
#+end_src
** ~arduino-mode~
#+begin_src emacs-lisp
(use-package arduino-mode
:mode "\\.ino\\'")
#+end_src
** ~nginx-mode~
2018-07-30 17:52:16 +00:00
#+begin_src emacs-lisp
(use-package nginx-mode)
#+end_src
2018-07-30 17:52:16 +00:00
** ~js2-mode~
2018-08-28 16:05:26 +00:00
#+begin_src emacs-lisp
(use-package js2-mode
:pin melpa-stable
:mode "\\.js\\'")
#+end_src
2018-08-28 16:05:26 +00:00
** ~typescript-mode~
2018-08-28 16:06:22 +00:00
#+begin_src emacs-lisp
(use-package typescript-mode
:mode "\\.ts\\'")
#+end_src
2018-08-28 16:06:22 +00:00
** ~less-css-mode~
#+begin_src emacs-lisp
(use-package less-css-mode
:mode "\\.less\\'")
#+end_src
** ~sass-mode~
#+begin_src emacs-lisp
(use-package sass-mode
:mode "\\.sass\\'")
#+end_src
** ~vue-html-mode~
2019-10-22 08:35:42 +00:00
#+begin_src emacs-lisp
2019-10-22 08:35:42 +00:00
(use-package vue-html-mode
:mode "\\.vue\\'")
#+end_src
2019-10-22 08:35:42 +00:00
** ~jinja2-mode~
#+begin_src emacs-lisp
(use-package jinja2-mode
:mode "\\.j2\\'")
#+end_src
** ~markdown-mode~
2020-11-05 07:19:34 +00:00
#+begin_src emacs-lisp
(use-package markdown-mode
:mode (("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode)))
#+end_src
2020-11-05 07:19:34 +00:00
** ~vala-mode~
#+begin_src emacs-lisp
(use-package vala-mode
:mode "\\.vala\\'")
#+end_src
** ~po-mode~
2021-10-27 14:29:39 +00:00
#+begin_src emacs-lisp
(use-package po-mode
:ensure nil
:mode "\\.po\\'")
2021-10-27 14:29:39 +00:00
#+end_src
** ~meson-mode~
#+begin_src emacs-lisp
(use-package meson-mode
:mode "\\.meson\\'")
#+end_src
** ~ggtags~, an interfaco for GNU Globals
#+begin_src emacs-lisp
(defun gpolonkai/cond-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))
#+end_src
2023-10-27 04:01:55 +00:00
** ~yuck-mode~
#+begin_src emacs-lisp
(use-package yuck-mode
:mode "\\.yuck\\'")
#+end_src
2023-11-02 16:23:10 +00:00
** ~ebnf-mode~
#+begin_src emacs-lisp
(use-package ebnf-mode
:commands (ebnf-mode))
#+end_src
2023-10-20 08:49:26 +00:00
* Key bindings
#+begin_src emacs-lisp
2023-10-20 10:15:53 +00:00
(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)
2018-07-30 19:14:51 +00:00
(bind-keys
:map global-map
("<C-return>" . wted/open-line-below)
("<C-S-return>" . wted/open-line-above)
2023-10-20 10:15:53 +00:00
("C-~" . gpolonkai/toggle-char-case)
2018-07-30 19:14:51 +00:00
("C-a" . gpolonkai/move-to-beginning-of-line)
("C-e" . gpolonkai/move-to-end-of-line)
("M-F" . gpolonkai/beginning-of-next-word)
2023-10-20 08:49:26 +00:00
("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)
2023-10-20 10:15:53 +00:00
("M-q" . sachachua/fill-or-unfill-paragraph)
("C-r" . isearch-backward-regexp)
2023-10-20 10:15:53 +00:00
("C-M-r" . isearch-backward)
("C-s" . isearch-forward-regexp)
2023-10-20 10:15:53 +00:00
("C-M-s" . isearch-forward)
("M-t" . gpolonkai/transpose-map)
("C-z" . nil)
:map mode-specific-map
;; TODO this should be doable from consult-projectiles config
("p p" . consult-projectile-switch-project)
2023-10-20 10:15:53 +00:00
("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)
2018-07-30 19:14:51 +00:00
:map ctl-x-map
("|" . gpolonkai/toggle-window-split)
2023-10-20 10:15:53 +00:00
("C-b" . bury-buffer)
("C-d" . wted/delete-current-buffer-file)
("k" . kill-this-buffer)
("C-r" . wted/rename-current-buffer-file)
("C-y" . duplicate-line)
2018-07-30 19:14:51 +00:00
:map isearch-mode-map
("<C-return>" . ep/isearch-exit-other-end)
("<S-return>" . e-se/isearch-exit-mark-match)
2023-10-20 10:15:53 +00:00
:map goto-map
("SPC" . gpolonkai/goto-next-char))
2023-10-20 08:49:26 +00:00
#+end_src
2023-10-22 04:57:49 +00:00
* 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.
2023-10-22 04:57:49 +00:00
#+begin_src emacs-lisp
(require 'server)
(unless (server-running-p)
(server-start))
2023-10-22 04:57:49 +00:00
#+end_src