my-emacs-d/configuration.org

3805 lines
98 KiB
Org Mode
Raw Normal View History

* Add some directories to ~load-path~
** My own (version controlled) ~lisp~ directory
#+BEGIN_SRC emacs-lisp
(add-to-list 'load-path (expand-file-name
(convert-standard-filename "lisp/")
user-emacs-directory))
(add-to-list 'load-path (expand-file-name
(convert-standard-filename "lisp/nyan-prompt")
user-emacs-directory))
#+END_SRC
** The local site-lisp
…if it exists.
#+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 some prerequisites
** Load ~xdg-paths~
#+BEGIN_SRC emacs-lisp
(load "xdg-paths")
#+END_SRC
** Load the tango dark theme
#+BEGIN_SRC emacs-lisp
(load-theme 'tango-dark t)
#+END_SRC
2018-07-29 16:38:44 +00:00
* Emacs configuration
** 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
2018-07-30 17:52:16 +00:00
** Configure ~use-package~ and preload ~bind-key~
2018-07-29 16:38:44 +00:00
#+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
(customize-set-variable 'use-package-always-ensure t)
(customize-set-variable 'use-package-verbose nil)
2018-07-30 17:52:16 +00:00
(use-package bind-key)
2018-07-29 16:38:44 +00:00
#+END_SRC
2020-03-03 05:19:19 +00:00
** Install and configure Quelpa
#+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)))
2020-03-03 05:19:19 +00:00
#+END_SRC
*** And quelpa-use-package, too!
#+BEGIN_SRC emacs-lisp
(quelpa
'(quelpa-use-package
:fetcher git
:url "https://github.com/quelpa/quelpa-use-package.git"))
(require 'quelpa-use-package)
2020-03-03 05:19:19 +00:00
#+END_SRC
** Set up the really basic things
#+BEGIN_SRC emacs-lisp
(use-package emacs
:ensure nil
:custom
(user-full-name "Gergely Polonkai")
2019-11-14 13:56:31 +00:00
(user-mail-address "gergely@polonkai.eu")
(kill-read-only-ok t)
(use-dialog-box nil))
#+END_SRC
2018-07-29 16:38:44 +00:00
** Set up my personal keymap
I set it up early so i can use it in ~use-package~ calls immediately.
2018-07-29 16:38:44 +00:00
#+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)
2018-07-29 16:38:44 +00:00
#+END_SRC
** I really dont want to type more than i really must…
2018-07-29 16:38:44 +00:00
#+BEGIN_SRC emacs-lisp
(defalias 'yes-or-no-p 'y-or-n-p)
#+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
** Set Orgs main directory
2019-10-22 08:33:33 +00:00
Since a lot of packages use it as their base (org-projectile, org-caldav, etc.), i need
2019-10-22 08:33:33 +00:00
it as early as possible.
#+BEGIN_SRC emacs-lisp
(setq org-directory (expand-file-name "NextCloud/orgmode" user-documents-directory))
#+END_SRC
* Custom commands and functions
** Utility functions
*** Check if something is ~nil~ or a list of strings
#+BEGIN_SRC emacs-lisp
(defun nil-or-list-of-strings-p (var)
"Return t if VAR is either nil or a list holding only strings."
(or (null var)
(not (null (delq nil
(mapcar (lambda (x) (and (stringp x) x)) var))))))
#+END_SRC
*** Get the number at point
#+BEGIN_SRC emacs-lisp
(defun get-number-at-point ()
(interactive)
(skip-chars-backward "0123456789.-")
(or (looking-at "[0123456789.-]+")
(error "No number at point"))
(string-to-number (match-string 0)))
#+END_SRC
*** Round number at point to the given decimals
#+BEGIN_SRC emacs-lisp
(defun round-number-at-point-to-decimals (decimal-count)
(interactive "NDecimal count: ")
(let ((mult (expt 10 decimal-count)))
(replace-match (number-to-string
(/
(fround
(*
mult
(get-number-at-point)))
mult)))))
#+END_SRC
*** Make a backup filename under ~user-emacs-cache-directory~
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
*** Run a function on a region
#+BEGIN_SRC emacs-lisp
(defun func-region (start end func)
"Run a function over the region between START and END in current buffer."
(save-excursion
(let ((text (delete-and-extract-region start end)))
(insert (funcall func text)))))
#+END_SRC
*** Copy and show the current location
#+begin_src emacs-lisp
(defun mbork/copy-current-location (arg)
"Show the current location and put it into the kill ring.
Without a prefix, the filename will be relative
to `(vc-root-dir)' if the file is under version control and will
be relative to the files directory otherwise. With a single
prefix, the filename will be used with an absolute path. With at
least two prefixes the filename will be relative to the files
directory."
(interactive "p")
(let ((root (vc-root-dir)))
(if (not buffer-file-name)
(message "Not visiting a file")
(let* ((file-name (cond ((eq arg 1) (file-relative-name buffer-file-name root))
((eq arg 4) buffer-file-name)
(t (file-relative-name buffer-file-name nil))))
(line-number (line-number-at-pos nil t))
(location (format "%s:%s" file-name line-number)))
(kill-new location)
(message location)))))
#+end_src
2018-07-30 17:52:16 +00:00
** Check if we are running under Termux
We need to do things differently, if so.
#+BEGIN_SRC emacs-lisp
(defun termux-p ()
"Check if Emacs is running under Termux."
(string-match-p
(regexp-quote "/com.termux/")
(expand-file-name "~")))
#+END_SRC
** Misc text manipulation functions
*** Delete the current line
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/delete-current-line ()
"Kill the whole line on which point is."
(interactive)
(beginning-of-line)
(kill-line 1))
#+END_SRC
*** Duplicate current line
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/duplicate-line()
"Duplicate line at point."
(interactive)
(save-excursion
(move-beginning-of-line 1)
(kill-line)
(yank)
(open-line 1)
(forward-line 1)
(yank)))
#+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 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
*** Open a new line below
Copied from http://whattheemacsd.com/editing-defuns.el-01.html
#+BEGIN_SRC emacs-lisp
(defun open-line-below ()
"Open a new line below point."
(interactive)
(end-of-line)
(newline)
(indent-for-tab-command))
#+END_SRC
*** Open a new line above
#+BEGIN_SRC emacs-lisp
(defun open-line-above ()
"Open a new line above point."
(interactive)
(beginning-of-line)
(newline)
(forward-line -1)
(indent-for-tab-command))
#+END_SRC
*** TODO Kill or copy the whole line
Got from Xahs site (TODO is for adding a link here.)
#+BEGIN_SRC emacs-lisp
(defun æ-kill-or-copy-whole-line (kill)
"Kill or copy the whole line point is on.
If KILL is non-nil, the line gets killed. Otherwise, it gets just
copied to the kill ring."
(interactive "P")
(if kill
(kill-whole-line)
(let ((beginning (progn (beginning-of-line) (point)))
(end (progn (end-of-line) (point))))
(copy-region-as-kill beginning end))))
#+END_SRC
*** Enclose region in a specific character
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/enclose-region (character &optional start end)
"Enclose region between CHARACTER.
If region is empty and neither START nor END is set, simply inserts CHARACTER
two times and moves point between them.
If character is present in `insert-pair-alist', this function will enclose
region in the corresponding pair. In this case, CHARACTER must be the opening
member of the pair."
(interactive "cWhat character? \nr")
(let ((open character)
(close character)
(pair (assq character insert-pair-alist)))
(if pair
(if (nth 2 pair)
(setq open (nth 1 pair) close (nth 2 pair))
(setq open (nth 0 pair) close (nth 1 pair))))
(unless (and open close)
(setq open character
close character))
(unless (use-region-p)
(setq start (point)
end (point)))
(save-excursion
(goto-char end)
(insert-char close)
(goto-char start)
(insert-char open))
(unless (use-region-p)
(forward-char))))
#+END_SRC
*** Convert ~camelCase~ to ~snake_case~
#+BEGIN_SRC emacs-lisp
(defun camel-to-snake-case (arg)
"Convert a camelCase word to snake_case.
If the prefix argument ARG is non-nil, convert the text to uppercase."
(interactive "p")
(progn
(let ((start (region-beginning))
(end (region-end))
(case-fold-search nil)
(had-initial-underscore nil))
(goto-char start)
(when (looking-at "_") (setq had-initial-underscore t))
(while (re-search-forward "\\([A-Z]\\)" end t)
(replace-match "_\\1")
(setq end (1+ end)))
(if arg
(upcase-region start end)
(downcase-region start end))
(goto-char start)
(unless had-initial-underscore (delete-char 1)))))
#+END_SRC
*** Insert two spaces after specific characters
#+BEGIN_SRC emacs-lisp
(defun org-space-key (&optional arg)
"Insert two spaces after a period.
ARG will be passed down verbatim to `self-insert-command'"
(interactive "p")
(when (looking-back "[.!?…]" nil)
(call-interactively 'self-insert-command arg))
(call-interactively 'self-insert-command arg))
#+END_SRC
*** Fill or unfill a paragraph
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://pages.sachachua.com/.emacs.d/Sacha.html
:END:
#+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
*** Swap occurences of strings
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://emacs.stackexchange.com/a/27170/507
:END:
#+BEGIN_SRC emacs-lisp
(defun so/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))
#+END_SRC
*** Insert the current files name at point
:PROPERTIES:
:SOURCE: http://mbork.pl/2019-02-17_Inserting_the_current_file_name_at_point
:END:
#+BEGIN_SRC emacs-lisp
(defun 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
** Navigation
*** Move to different beginnings 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))))
#+END_SRC
*** Move to the different ends of the current line
#+BEGIN_SRC emacs-lisp
(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 goto-next-char (chr)
(interactive "c")
(let ((substr (char-to-string chr))
(end (save-excursion (end-of-line) (point))))
(when (search-forward substr end t)
(backward-char))))
#+end_src
** File manipulation
*** Rename the current file
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://whattheemacsd.com/file-defuns.el-01.html
:END:
#+BEGIN_SRC emacs-lisp
(defun 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
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://whattheemacsd.com/file-defuns.el-02.html
:END:
#+BEGIN_SRC emacs-lisp
(defun 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
*** Allow reopening the previously closed file
#+BEGIN_SRC emacs-lisp
(defvar gpolonkai/last-killed-buffer-file-name
nil
"The last killed buffer.
Used by `gpolonkai/save-killed-buffer-filename' and `gpolonkai/undo-buffer-kill'.")
(defun gpolonkai/save-killed-buffer-filename ()
"Save the filename of the killed buffer in `gpolonkai/last-killed-buffer-file-name'."
(let ((filename (buffer-file-name)))
(unless filename
(setq gpolonkai/last-killed-buffer-file-name (buffer-file-name)))))
(add-hook 'kill-buffer-hook 'gpolonkai/save-killed-buffer-filename)
(defun gpolonkai/undo-buffer-kill ()
"Undo killing the last buffer.
Esentially it visits the file again."
(interactive)
(if gpolonkai/last-killed-buffer-file-name
(progn
(find-file gpolonkai/last-killed-buffer-file-name)
(setq gpolonkai/last-killed-buffer-file-name nil))
(message "The buffer last killed didnt visit a file.")))
#+END_SRC
*** Open this file as another user
#+BEGIN_SRC emacs-lisp
(defun open-this-file-as-other-user (user)
"Edit current file as USER, using `tramp' and `sudo'.
If the current buffer is not visiting a file, prompt for a file
name."
(interactive "sEdit as user (default: root): ")
(when (string= "" user)
(setq user "root"))
(let* ((filename (or buffer-file-name
(read-file-name (format "Find file (as %s): "
user))))
(tramp-path (concat (format "/sudo:%s@localhost:" user) filename)))
(if buffer-file-name
(find-alternate-file tramp-path)
(find-file tramp-path))))
#+END_SRC
*** Open my own ~init.el~
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/visit-init-file ()
"Open the init file."
(interactive)
(find-file-other-window (expand-file-name "configuration.org" user-emacs-directory)))
#+END_SRC
*** Open my Org-mode index file
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/visit-org-index ()
"Visit the root of Org-mode notes."
(interactive)
(find-file-other-window (expand-file-name "index.org" org-directory)))
#+END_SRC
** Frame manipulation
*** Hidden modeline mode
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://emacs-doctor.com/emacs-strip-tease.html
:END:
To temporarily hide the mode line.
#+BEGIN_SRC emacs-lisp
(defvar hidden-mode-line-mode nil)
(defvar hide-mode-line nil)
(define-minor-mode hidden-mode-line-mode
"Minor mode to hide the mode-line in the current buffer."
:init-value nil
:global nil
:variable hidden-mode-line-mode
:group 'editing-basics
(if hidden-mode-line-mode
(setq hide-mode-line mode-line-format
mode-line-format nil)
(setq mode-line-format hide-mode-line
hide-mode-line nil))
(force-mode-line-update)
(redraw-display)
(when (and (called-interactively-p 'interactive)
hidden-mode-line-mode)
(run-with-idle-timer
0 nil 'message
(concat "Hidden Mode Line Mode enabled. "
"Use M-x hidden-mode-line-mode to make mode-line appear."))))
#+END_SRC
** Window manipulation
*** Transpose windows
#+BEGIN_SRC emacs-lisp
(defun 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 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
*** Scroll up or down in a specific window
#+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
*** Bury a window
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/bury-window (window)
"Quit WINDOW without killing it."
(interactive)
(quit-window nil window))
#+END_SRC
** ~c-mode~ related
*** Copy the prototype of the current 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
** Programming related
*** Check if we are inside a string
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/prog-in-string-p ()
"Return t if point is inside a string."
(nth 3 (syntax-ppss)))
#+END_SRC
*** Check if we are inside a comment
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/prog-in-comment-p ()
"Return t if point is inside a comment."
(nth 4 (syntax-ppss)))
#+END_SRC
2019-12-03 08:25:31 +00:00
*** Add code references to Org documents
:PROPERTIES:
:SOURCE: http://www.howardism.org/Technical/Emacs/capturing-content.html
:END:
#+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
** ~python-mode~ related
*** Add a docstring to the current thing
…be it a function, class, or a module
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/python-add-docstring ()
"Add a Python docstring to the current thing.
If point is inside a function, add docstring to that. If point
is in a class, add docstring to that. If neither, add docstring
to the beginning of the file."
(interactive)
(save-restriction
(widen)
(beginning-of-defun)
(if (not (looking-at-p "\\(def\\|class\\) "))
(progn
(goto-char (point-min))
(back-to-indentation)
(forward-char)
(while (gpolonkai/prog-in-comment-p)
(forward-line)
(back-to-indentation)
(forward-char)))
(search-forward ":")
(while (or (gpolonkai/prog-in-string-p)
(gpolonkai/prog-in-comment-p))
(search-forward ":")))
(if (eq 1 (count-lines 1 (point)))
(open-line-above)
(open-line-below))
(insert "\"\"\"")
(let ((point-pos (point)))
(open-line-below)
(insert "\"\"\"\n")
(goto-char point-pos))))
#+END_SRC
2020-02-13 08:14:33 +00:00
*** Font-lock variables in f-strings
:PROPERTIES:
:SOURCE: https://emacs.stackexchange.com/a/55186/507
:END:
#+BEGIN_SRC emacs-lisp :tangle no
2020-02-13 08:14:33 +00:00
(with-eval-after-load "python"
(setq python-font-lock-keywords
(append python-font-lock-keywords
'(;; this is the full string.
;; group 1 is the quote type and a closing quote is matched
;; group 2 is the string part
("f\\(['\"]\\{1,3\\}\\)\\([^\\1]+?\\)\\1"
;; these are the {keywords}
("{[^}]*?}"
;; Pre-match form
(progn (goto-char (match-beginning 0)) (match-end 0))
;; Post-match form
(goto-char (match-end 0))
;; face for this match
(0 font-lock-variable-name-face t)))))))
#+END_SRC
2020-09-07 09:14:37 +00:00
** Jinja related
*** Mark a string as translatable
#+BEGIN_SRC emacs-lisp
(defun jinja-mark-translatable (begin end)
(interactive (if (use-region-p)
(list (region-beginning) (region-end))
(list (point-min) (point-max))))
(save-excursion
(goto-char end)
(insert "{% endtrans %}")
(goto-char begin)
(insert "{% trans %}")))
#+END_SRC
*** URL-ify and de-URL-ify region
These functions URL-encode/decode a text. Might be helpful when embedding/extracting data to/from
HTML.
#+BEGIN_SRC emacs-lisp
(defun hex-region (start end)
"urlencode the region between START and END in current buffer."
(interactive "r")
(func-region start end #'url-hexify-string))
(defun unhex-region (start end)
"de-urlencode the region between START and END in current buffer."
(interactive "r")
(func-region start end #'url-unhex-string))
#+END_SRC
2018-07-30 17:52:16 +00:00
** Automatically zone out after 60 seconds
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/zone-enable ()
"Enable zoning out."
(interactive)
(zone-when-idle 60)
(message "I will zone out after idling for 60 seconds."))
#+END_SRC
** Utility functions for editing Zim wiki files
#+BEGIN_SRC emacs-lisp
(defun zim-timestamp ()
(with-temp-buffer
(insert (format-time-string "%Y-%m-%dT%H:%M:%S%z"))
(forward-char -2)
(insert ":")
(buffer-string)))
(defun insert-zim-timestamp ()
(interactive)
(insert (zim-timestamp)))
(defun insert-zim-header ()
(interactive)
(save-excursion
(goto-char (point-min))
(insert
(concat "Content-Type: text/x-zim-wiki\n"
"Wiki-Format: zim 0.4\n"
"Creation-Date: " (zim-timestamp) "\n\n"))))
#+END_SRC
2018-07-30 19:14:51 +00:00
** Utility functions for EDiff
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://article.gmane.org/gmane.emacs.orgmode/75222
:END:
2018-07-30 19:14:51 +00:00
2019-02-19 13:34:01 +00:00
EDiff and Org-mode files dont play nice together…
2018-07-30 19:14:51 +00:00
#+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
** Leave ~isearch~ at the other end of the matched string
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://endlessparentheses.com/leave-the-cursor-at-start-of-match-after-isearch.html
:END:
2018-07-30 19:14:51 +00:00
#+BEGIN_SRC emacs-lisp
(defun isearch-exit-other-end ()
"Exit isearch, at the opposite end of the string."
(interactive)
(isearch-exit)
(goto-char isearch-other-end))
#+END_SRC
** Mark the current match after leaving ~isearch~
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://emacs.stackexchange.com/a/31321/507
:END:
2018-07-30 19:14:51 +00:00
#+BEGIN_SRC emacs-lisp
(defun isearch-exit-mark-match ()
"Exit isearch and mark the current match."
(interactive)
(isearch-exit)
(push-mark isearch-other-end)
(activate-mark))
#+END_SRC
** Turn the cursor to purple if Yasnippets TAB function would fire
Taken from [[http://pages.sachachua.com/.emacs.d/Sacha.html][Sacha Chuas config]].
#+BEGIN_SRC emacs-lisp
;; TODO: 'cursor-color is sometimes nil, but why?
(setq default-cursor-color (or (frame-parameter nil 'cursor-color) "#ffd85c"))
(setq yasnippet-can-fire-cursor-color "purple")
;; It will test whether it can expand, if yes, cursor color -> purple.
(defun yasnippet-can-fire-p (&optional field)
"Check if the word before point can be expanded with yasnippet.
TODO: What is FIELD for?"
(interactive)
(setq yas--condition-cache-timestamp (current-time))
(let (templates-and-pos)
(unless (and yas-expand-only-for-last-commands
(not (member last-command yas-expand-only-for-last-commands)))
(setq templates-and-pos (if field
(save-restriction
(narrow-to-region (yas--field-start field)
(yas--field-end field))
(yas--templates-for-key-at-point))
(yas--templates-for-key-at-point))))
(and templates-and-pos (first templates-and-pos))))
(defun sachachua/change-cursor-color-when-can-expand (&optional field)
"Change cursor color if the text before point can be expanded with yasnippet.
TODO: What is FIELD for?"
(interactive)
(when (eq last-command 'self-insert-command)
(set-cursor-color (if (sachachua/can-expand)
yasnippet-can-fire-cursor-color
default-cursor-color))))
(defun sachachua/can-expand ()
"Return t if right after an expandable thing."
(or (abbrev--before-point) (yasnippet-can-fire-p)))
#+END_SRC
** Org mode stuff
*** 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. This is also the reason it has 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
*** 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 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
2018-07-29 16:38:44 +00:00
* UI preferences
** Tweak window chrome
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
** Set the default font and configure font resizing
2018-07-30 17:52:16 +00:00
Before this can be used, make sure the [[https://zhm.github.io/symbola/][Symbola]] font is installed.
2018-07-29 16:38:44 +00:00
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/set-font-size (frame)
(when (display-graphic-p frame)
(set-face-attribute 'default frame :font "Hack-12")
(set-frame-font "Hack-12" t (list frame))))
2018-07-30 17:52:16 +00:00
(defun --set-emoji-font (frame)
"Adjust the font setting of FRAME so Emacs can display Emoji properly."
(when (display-graphic-p frame)
2019-02-04 09:27:01 +00:00
(set-fontset-font t 'symbol
(font-spec :family "Symbola")
2021-10-27 06:06:17 +00:00
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)
2019-02-04 09:27:01 +00:00
(gpolonkai/set-font-size nil)
(--set-emoji-font nil)
2018-07-29 16:38:44 +00:00
#+END_SRC
* Set up global minor modes provided by Emacs
** Pretty lambdas
Because we can.
#+BEGIN_SRC emacs-lisp
(global-prettify-symbols-mode t)
#+END_SRC
2018-07-30 19:14:51 +00:00
And set up all the pretty symbols.
#+BEGIN_SRC emacs-lisp
(setq prettify-symbols-alist
2022-08-18 05:22:06 +00:00
'(("lambda" . ?λ)
("function" . ?ƒ)
("->" . ?→)
("=>" . ?⇒)
("map" . ?↦)
("not" . ?¬)
("and" . ?∧)
("or" . ?)
("<=" . ?≤)
(">=" . ?≥)))
#+END_SRC
…and some pairs to complete
2018-07-30 19:14:51 +00:00
*************** TODO Maybe add-to-list is a better way to do it
*************** END
#+BEGIN_SRC emacs-lisp
(setq insert-pair-alist '(
2018-07-30 19:14:51 +00:00
(40 41) ; ()
(91 93) ; []
(123 125) ; {}
(60 62) ; <>
(34 34) ; ""
(39 39) ; ''
(96 39) ; `'
(8220 8221) ; “”
(8222 8221) ; „”
(8216 8217) ;
(8249 8250) ;
(8250 8249) ;
(171 187) ; «»
(187 171))) ; »«
#+END_SRC
Finally, set the frame title to the current file name
2018-07-30 19:14:51 +00:00
#+BEGIN_SRC emacs-lisp
(setq frame-title-format '((:eval (concat system-name
2018-07-30 19:14:51 +00:00
": "
(if (buffer-file-name)
(abbreviate-file-name (buffer-file-name))
2018-07-30 19:14:51 +00:00
"%b")))))
#+END_SRC
** Treat soft line breaks as hard ones in textual modes
#+BEGIN_SRC emacs-lisp
(add-hook 'text-mode-hook (lambda () (visual-line-mode t)))
#+END_SRC
* Enable disabled commands
Because im a rock star like that.
2018-07-30 19:14:51 +00:00
#+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)
2018-08-09 11:24:38 +00:00
(put 'narrow-to-page 'disabled nil)
2018-07-30 19:14:51 +00:00
(put 'set-goal-column 'disabled nil)
2018-08-09 11:24:38 +00:00
(put 'scroll-left 'disabled nil)
(put 'dired-find-alternate-file 'disabled nil)
2018-08-16 10:05:13 +00:00
(put 'Info-edit 'disabled nil)
(put 'list-timers 'disabled nil)
2018-07-30 19:14:51 +00:00
#+END_SRC
* Packages installed from Quelpa
For some strange reason having this at the end of my configuration can cause unexpected results.
** Matrix client
#+BEGIN_SRC emacs-lisp
(use-package matrix-client
:after quelpa-use-package
:ensure nil
:quelpa (matrix-client :fetcher github :repo "alphapapa/matrix-client.el"
:files (:defaults "logo.png" "matrix-client-standalone.el.sh")))
#+END_SRC
** Ement
#+begin_src emacs-lisp
(use-package plz
:ensure nil
:quelpa (plz :fetcher github :repo "alphapapa/plz.el"))
(use-package ement
:ensure nil
:quelpa (ement :fetcher github :repo "alphapapa/ement.el")
:custom
(ement-save-token t))
#+end_src
* Load some built-in libraries
** ~thingatpt~
#+BEGIN_SRC emacs-lisp
(use-package thingatpt
:ensure nil)
#+END_SRC
** Calendar
#+BEGIN_SRC emacs-lisp
(use-package calendar
:ensure nil
:init
(setq calendar-week-start-day 1
calendar-latitude 47.4
calendar-longitude 19.0
calendar-location-name "Budapest, Hungary"
calendar-time-zone 60
calendar-standard-time-zone-name "CET"
calendar-daylight-time-zone-name "CEST"))
#+END_SRC
2018-07-30 19:14:51 +00:00
*** Add the SysAdmin day to the calendar
Because Im a sysadmin, too.
#+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
** 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
(whitespace-line-column 100)
2018-07-30 17:52:16 +00:00
:bind
(([f10] . whitespace-mode)
([(shift f10)] . global-whitespace-mode)
:map gpolonkai/pers-map
("w" . whitespace-cleanup)))
#+END_SRC
** ~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.
2018-07-30 17:52:16 +00:00
#+BEGIN_SRC emacs-lisp
(use-package eshell
:bind
(:map gpolonkai/pers-map
("e" . eshell))
:hook
(eshell-mode . gpolonkai/eshell-set-c-d-locally))
2018-07-30 17:52:16 +00:00
#+END_SRC
** ~saveplace~
#+BEGIN_SRC emacs-lisp
;; Save place
(use-package saveplace
:config'
(save-place-mode 1)
:custom
(save-place-file (expand-file-name ".places" user-emacs-directory)))
2018-07-30 17:52:16 +00:00
#+END_SRC
** EDiff
#+BEGIN_SRC emacs-lisp
(use-package ediff
:custom
(ediff-merge-split-window-function 'split-window-horizontally)
(ediff-split-window-function 'split-window-vertically)
(ediff-window-setup-function 'ediff-setup-windows-plain))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Automatically revert changed files
…unless they are modified, of course.
#+BEGIN_SRC emacs-lisp
(use-package autorevert
:config
(global-auto-revert-mode 1))
#+END_SRC
** Eww
For in-Emacs browsing needs.
#+BEGIN_SRC emacs-lisp
(use-package eww
:custom
(eww-search-prefix "https://duckduckgo.com/html/?q="))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Electric indent mode
#+BEGIN_SRC emacs-lisp
(use-package electric
:config
;; This seems to be the default, but lets make sure…
(electric-indent-mode 1))
#+END_SRC
** Save history
#+BEGIN_SRC emacs-lisp
(use-package savehist
:config
(savehist-mode 1))
#+END_SRC
** Web jump
#+BEGIN_SRC emacs-lisp
(use-package webjump
:bind
(:map gpolonkai/pers-map
("j" . webjump)))
#+END_SRC
** Which function am i in?
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
2018-07-30 17:52:16 +00:00
#+BEGIN_SRC emacs-lisp
(use-package which-func
:config
(setq which-func-unknown "∅")
:hook
(prog-mode . gpolonkai/activate-which-func-mode))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Fortune cookies
The cookies are from the Hungarian version an ancient MS-DOS based program called ~TAGLINE~.
#+BEGIN_SRC emacs-lisp
(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
** Browse URL functionality in Termux
#+BEGIN_SRC emacs-lisp
(when (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
2018-08-09 11:48:01 +00:00
** Dired customisation
#+BEGIN_SRC emacs-lisp
(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)))
2018-08-09 11:48:01 +00:00
#+END_SRC
** 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
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
** Show line numbers
I dont usually like to see them, but there are occasions when they can be useful.
#+BEGIN_SRC emacs-lisp
(use-package display-line-numbers
:bind
(:map gpolonkai/pers-map
("C-n" . display-line-numbers-mode)))
#+END_SRC
2019-01-30 07:56:54 +00:00
** Check for spelling errors
#+BEGIN_SRC emacs-lisp
(use-package ispell
:custom
(ispell-dictionary "en_GB")
(ispell-program-name "/usr/bin/aspell")
2019-01-30 07:56:54 +00:00
:hook
(mail-send . ispell-message)
(message-send . ispell-message))
#+END_SRC
** Speed bar
#+BEGIN_SRC emacs-lisp
(use-package speedbar)
#+END_SRC
2018-07-29 16:38:44 +00:00
* ~use-package~ packages
** Make sure we have the latest ELPA GPG keys
#+BEGIN_SRC emacs-lisp
(use-package gnu-elpa-keyring-update)
#+END_SRC
2018-07-30 17:52:16 +00:00
** 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)
2018-07-30 17:52:16 +00:00
;; 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))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Nyanyanyanyanya
*** Nyan-cat style position marker
#+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
*** Nyan prompt in EShell
#+BEGIN_SRC emacs-lisp
(use-package nyan-prompt
:disabled
:hook
(eshell-load . nyan-prompt-enable))
#+END_SRC
*** Zone out with Nyancat
Unfortunately, this works only in a graphical mode.
#+BEGIN_SRC emacs-lisp
(use-package zone-nyan
:after
zone
:config
(setq zone-programs (vconcat zone-programs [zone-nyan]))
:custom
(zone-nyan-hide-progress t))
#+END_SRC
2018-08-10 05:14:00 +00:00
** De-light some minor modes
#+BEGIN_SRC emacs-lisp
(use-package delight)
#+END_SRC
2018-07-30 17:52:16 +00:00
** Eye candy
*** Moody mode-line
2018-07-30 17:52:16 +00:00
#+BEGIN_SRC emacs-lisp
(use-package moody
2018-07-30 17:52:16 +00:00
:config
(moody-replace-mode-line-buffer-identification)
(moody-replace-vc-mode)
(set-face-attribute 'mode-line nil :box nil :foreground "#7e7486")
(set-face-attribute 'mode-line-inactive nil :box nil)
:custom
(moody-mode-line-height 18))
2018-07-30 17:52:16 +00:00
#+END_SRC
*** Minions
#+BEGIN_SRC emacs-lisp
(use-package minions
:config
(minions-mode 1))
#+END_SRC
2018-07-30 17:52:16 +00:00
*** Spinner, e.g. to display running background tasks
#+BEGIN_SRC emacs-lisp
(use-package spinner)
#+END_SRC
*** Beacon
Highlight point. Sometimes its not easy to see.
#+BEGIN_SRC emacs-lisp
(use-package beacon
:demand
:config
(beacon-mode 1)
:bind
(:map gpolonkai/pers-map
("b" . beacon-blink)))
#+END_SRC
*** 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))
2018-07-30 17:52:16 +00:00
#+END_SRC
*** Extras for the EShell prompt
#+BEGIN_SRC emacs-lisp
(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))
2018-07-30 17:52:16 +00:00
#+END_SRC
2018-07-30 19:14:51 +00:00
*** Show form feeds as a horizontal line
#+BEGIN_SRC emacs-lisp
(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))
2018-07-30 19:14:51 +00:00
#+END_SRC
2018-07-29 16:38:44 +00:00
** Highlight the current line
#+BEGIN_SRC emacs-lisp
(use-package hl-line
:config
(when window-system
(global-hl-line-mode)))
#+END_SRC
2018-07-29 18:48:11 +00:00
** 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)))
2018-07-29 18:48:11 +00:00
(use-package ggtags
:hook
(c-mode-common . gpolonkai/cond-enable-ggtags-mode))
2018-07-29 18:48:11 +00:00
#+END_SRC
** Multiple cursors
Because one is never enough.
#+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)))
2018-07-29 18:48:11 +00:00
#+END_SRC
2018-07-30 19:14:51 +00:00
*** Incremental search for multiple cursors
#+BEGIN_SRC emacs-lisp
(use-package phi-search)
(use-package phi-search-mc
:config
(phi-search-mc/setup-keys))
#+END_SRC
2018-07-29 18:48:11 +00:00
*** Some extras
#+BEGIN_SRC emacs-lisp
(use-package mc-extras
:demand
:bind
(:map mc/keymap
("C-c m =" . mc/compare-chars)))
#+END_SRC
2018-07-30 17:52:16 +00:00
*** Add extra cursors via ~ace-jump~
#+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)))
2018-07-30 17:52:16 +00:00
#+END_SRC
2018-07-29 18:48:11 +00:00
** Magit
#+BEGIN_SRC emacs-lisp
(use-package magit
:custom
(magit-auto-revert-mode nil)
(magit-last-seen-setup-instructions "1.4.0")
2018-07-29 18:48:11 +00:00
:bind
(:map ctl-x-map
("g" . magit-status))
:hook
(git-commit-mode . turn-on-flyspell))
2018-07-29 18:48:11 +00:00
#+END_SRC
*** Make Magit work with Git forges
#+BEGIN_SRC emacs-lisp
(use-package forge)
#+END_SRC
2018-07-30 17:52:16 +00:00
** Zone
#+BEGIN_SRC emacs-lisp
(use-package zone
:demand
:config
(zone-when-idle 60)
:bind
(:map gpolonkai/pers-map
("zi" . gpolonkai/zone-enable)
("zq" . zone-leave-me-alone)))
#+END_SRC
** Origami
#+BEGIN_SRC emacs-lisp
(use-package origami
:demand
:config
(define-prefix-command 'origami-mode-map)
(define-key ctl-x-map (kbd "z") 'origami-mode-map)
(global-origami-mode)
:bind
(:map origami-mode-map
("o" . origami-open-node)
("O" . origami-open-node-recursively)
("c" . origami-close-node)
("C" . origami-close-node-recursively)
("a" . origami-toggle-node)
("A" . origami-recursively-toggle-node)
("R" . origami-open-all-nodes)
("M" . origami-close-all-nodes)
("v" . origami-show-only-node)
("k" . origami-previous-fold)
("j" . origami-forward-fold)
("x" . origami-reset)))
#+END_SRC
** Smart parens
#+BEGIN_SRC emacs-lisp
(use-package smartparens
:demand
:config
(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)
("C-c s k" . sp-kill-sexp)))
#+END_SRC
** Projectile
#+BEGIN_SRC emacs-lisp
(use-package projectile
2018-08-10 05:14:00 +00:00
:delight '(:eval (concat " [" projectile-project-name "]"))
2018-07-30 17:52:16 +00:00
:pin melpa-stable
:config
2019-01-03 15:24:19 +00:00
(projectile-mode t)
:bind
(:map projectile-mode-map
("C-c p" . projectile-command-map)))
2018-07-30 17:52:16 +00:00
#+END_SRC
*** Repository-based ToDo management with Org mode
#+BEGIN_SRC emacs-lisp
(use-package org-projectile
:after (:all projectile org)
:defer t
: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))
2018-07-30 17:52:16 +00:00
#+END_SRC
2018-11-18 06:03:04 +00:00
** Text object manipulation
2018-07-30 17:52:16 +00:00
2018-11-18 06:03:04 +00:00
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
2018-07-30 17:52:16 +00:00
#+BEGIN_SRC emacs-lisp
2018-11-18 06:03:04 +00:00
(use-package objed
:demand t
2018-11-18 06:03:04 +00:00
:bind
(:map global-map
("M-SPC" . objed-activate)))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Ace window
Besides its standard functionality, I also make add key bindings for burying or scrolling another
window.
#+BEGIN_SRC emacs-lisp
(use-package ace-window
:custom
(aw-background nil)
(aw-dispatch-always t)
2018-07-30 17:52:16 +00:00
: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)))
#+END_SRC
2019-01-23 13:11:13 +00:00
** Golden ratio
#+BEGIN_SRC emacs-lisp
(use-package golden-ratio
:config
(add-to-list 'golden-ratio-extra-commands 'ace-window)
(golden-ratio-mode t))
#+END_SRC
2018-07-30 17:52:16 +00:00
** Avy
#+BEGIN_SRC emacs-lisp
(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
** Focus mode
It is similar to narrow mode, except the narrowing part; it dims everything outside of the current
context.
#+BEGIN_SRC emacs-lisp
(use-package focus
:bind
(([f8] . focus-mode)))
#+END_SRC
** Command logging mode
For occasional screen casting recordings.
#+BEGIN_SRC emacs-lisp
(use-package command-log-mode)
#+END_SRC
** Emamux
For controlling tmux from within Emacs.
#+BEGIN_SRC emacs-lisp
(use-package emamux)
#+END_SRC
** Use StackExchange sites in an Emacs window
#+BEGIN_SRC emacs-lisp
(use-package sx
:demand
:bind
(:map gpolonkai/pers-map
("qi" . sx-inbox)
("qs" . sx-search)))
#+END_SRC
** Goto last change
#+BEGIN_SRC emacs-lisp
(use-package goto-last-change
:bind
(("M-g /" . goto-last-change)))
#+END_SRC
** Rainbow mode
To highlight colours based on their name or hex code.
#+BEGIN_SRC emacs-lisp
(use-package rainbow-mode
:hook
(css-mode . rainbow-mode)
(scss-mode . rainbow-mode)
(sass-mode . rainbow-mode))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Zygospore
Toggle other windows for maximum focus. When focus is no longer needed, they can be toggled back.
~C-x 1~ is conveniently bound to it.
#+BEGIN_SRC emacs-lisp
(use-package zygospore
:bind
(:map ctl-x-map
("1" . zygospore-toggle-delete-other-windows)))
#+END_SRC
** Kanban board
#+BEGIN_SRC emacs-lisp
(use-package kanban)
#+END_SRC
** Highlight dired buffer by file size, modified time, git status
#+BEGIN_SRC emacs-lisp
(use-package dired-k
:bind
(:map dired-mode-map
("K" . dired-k)))
#+END_SRC
** Show number of matches in the mode line while searching
#+BEGIN_SRC emacs-lisp
(use-package anzu
2018-08-10 05:14:00 +00:00
:delight
2018-07-30 17:52:16 +00:00
:config
(global-anzu-mode 1))
#+END_SRC
** Gradually expand region
#+BEGIN_SRC emacs-lisp
(use-package expand-region
:bind
(:map gpolonkai/pers-map
("x" . er/expand-region)))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Read and Edit MediaWiki pages in an Emacs window
#+BEGIN_SRC emacs-lisp
(use-package mediawiki
:after
id-manager
:config
(add-to-list 'mediawiki-site-alist
'("WikEmacs"
"http://wikemacs.org/wiki/"
(password-store-get-field "wikemacs.org" "username")
(password-store-get "wikemacs.org" "password"))))
2018-07-30 17:52:16 +00:00
#+END_SRC
** An Emacs Dashboard
#+BEGIN_SRC emacs-lisp
(use-package dashboard
:after
projectile
:config
(add-to-list 'dashboard-items '(projects . 5) t)
(dashboard-setup-startup-hook))
#+END_SRC
2018-07-30 19:14:51 +00:00
** Hungarian holidays in the Calendar
#+BEGIN_SRC emacs-lisp
(use-package hungarian-holidays
:config
(hungarian-holidays-add))
#+END_SRC
** FlySpell
For all your spell-checking needs.
#+BEGIN_SRC emacs-lisp
(use-package flyspell
:hook
(prog-mode . flyspell-prog-mode)
(text-mode . flyspell-mode))
2018-07-30 19:14:51 +00:00
#+END_SRC
** Delete all the whitespace
#+BEGIN_SRC emacs-lisp
(use-package hungry-delete
:config
(global-hungry-delete-mode))
#+END_SRC
** Send alerts to a notification system
#+BEGIN_SRC emacs-lisp
(use-package alert
:config
(setq alert-default-style
(if (termux-p)
(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
** Replace the GUI popup menu with something more efficient
#+BEGIN_SRC emacs-lisp
(use-package ace-popup-menu
;; Unfortunately, avy-menu (used by this package) is not compatible with minions. I just
;; disable it for now.
2021-03-09 17:00:48 +00:00
:disabled
2018-07-30 19:14:51 +00:00
:config
(ace-popup-menu-mode 1))
#+END_SRC
** Im an achiever!
#+BEGIN_SRC emacs-lisp
(use-package achievements
:demand
2018-07-30 19:14:51 +00:00
:config
(achievements-mode 1)
:bind
(:map gpolonkai/pers-map
("C-a" . achievements-list-achievements)))
2018-07-30 19:14:51 +00:00
#+END_SRC
** Secretaria
Because even secretaries need a secretary today.
#+BEGIN_SRC emacs-lisp
(use-package secretaria
:after
alert
:hook
2018-07-30 19:14:51 +00:00
;; 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))
2018-07-30 19:14:51 +00:00
#+END_SRC
** The Silver Searcher
#+BEGIN_SRC emacs-lisp
(use-package ag
:after projectile
:bind
(:map projectile-mode-map
("C-c p C-a" . ag-project)))
#+END_SRC
** A fancier ~narrow-mode~
#+BEGIN_SRC emacs-lisp
(use-package fancy-narrow
:config
(fancy-narrow-mode))
#+END_SRC
** Undo tree
#+BEGIN_SRC emacs-lisp
(use-package undo-tree)
#+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
** NeoTree, if Dired is not an option
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/neo-set-theme ()
(customize-set-variable 'neo-theme (if (display-graphic-p) 'icons 'arrow)))
2018-07-30 19:14:51 +00:00
(use-package neotree
:after
all-the-icons
:bind
(([f5] . neotree-toggle))
:hook
(neo-enter . gpolonkai/neo-set-theme))
2018-07-30 19:14:51 +00:00
#+END_SRC
** Waka-waka (AKA ActivityWatch)
#+begin_src emacs-lisp
(use-package activity-watch-mode
:config
(global-activity-watch-mode))
#+end_src
** Jump to character, word, line
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:bind
(:map gpolonkai/pers-map
("SPC" . ace-jump-mode)))
#+END_SRC
2018-08-07 12:33:44 +00:00
** Command frequency meter
#+BEGIN_SRC emacs-lisp
(use-package keyfreq
:demand
:custom
(keyfreq-file (expand-file-name "keyfreq" user-emacs-directory))
(keyfreq-file-lock (expand-file-name "keyfreq.lock" user-emacs-directory))
2018-08-07 12:33:44 +00:00
:config
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)
:bind
(:map gpolonkai/pers-map
("C-f" . keyfreq-show)))
2018-08-07 12:33:44 +00:00
#+END_SRC
2018-10-31 15:23:20 +00:00
** EditorConfig
[[http://editorconfig.org/][EditorConfig]] is a nice tool to unify, well, configuration of different editors.
#+BEGIN_SRC emacs-lisp
(use-package editorconfig
:config
(editorconfig-mode t))
#+END_SRC
2018-11-13 13:59:38 +00:00
** occur-like folding in the current buffer
#+BEGIN_SRC emacs-lisp
(defun gpolonkai/toggle-loccur ()
"Toggle `loccur-mode'.
If `loccur-mode' is not active, starts it (which, in turn, will ask for the
pattern to look for). If it is active, it will disable it."
(interactive)
(if loccur-mode
(loccur-mode nil)
(call-interactively 'loccur)))
(use-package loccur
:bind
(:map gpolonkai/pers-map
("C-o" . gpolonkai/toggle-loccur)))
#+END_SRC
** Help merging ~pacsave~ and ~pacnew~ files
#+BEGIN_SRC emacs-lisp
(use-package pacfiles-mode
:commands pacfiles)
#+END_SRC
** Mailing with mu4e
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
#+BEGIN_SRC emacs-lisp
(use-package mu4e
2021-02-18 08:55:30 +00:00
:after ivy
: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")
2020-06-16 04:39:46 +00:00
(mu4e-sent-folder . "/Polonkai/[Gmail].Sendur p&APM-stur")
(mu4e-drafts-folder . "/Polonkai/[Gmail].Dr&APY-g")
(mu4e-trash-folder . "/Polonkai/[Gmail].Rusl")
2021-03-09 16:51:13 +00:00
(mu4e-refile-folder . "/Polonkai/[Gmail].Dr&APY-g")
(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"))))
:vars '((user-mail-address . "gergo@benchmark.games")
(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)
(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")
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
2021-03-09 16:51:13 +00:00
(mu4e-completing-read-function 'ivy-completing-read)
(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
*** Maildir extension so i see a summary of mailboxes
#+BEGIN_SRC emacs-lisp
(use-package mu4e-maildirs-extension
:custom
(mu4e-maildirs-extension-custom-list '("INBOX")))
#+END_SRC
2021-03-09 16:51:13 +00:00
*** Also, some sendmail hacking
#+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
2018-11-20 13:00:41 +00:00
** 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
2018-11-30 08:26:32 +00:00
** Access files in Docker containers using TRAMP
#+BEGIN_SRC emacs-lisp
(use-package docker-tramp)
#+END_SRC
** Transient for creating beautiful command menus
#+BEGIN_SRC emacs-lisp
(use-package transient)
#+END_SRC
** Speed bar in the same frame
#+BEGIN_SRC emacs-lisp
(use-package sr-speedbar
:after speedbar)
#+END_SRC
** Speedbar for projectile
#+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
2020-02-14 18:03:14 +00:00
** Kubernetes dashboard
#+BEGIN_SRC emacs-lisp
(use-package kubernetes
:commands (kubernetes-overview))
#+END_SRC
** A Gopher 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
(use-package elpher)
#+END_SRC
2020-06-16 04:49:10 +00:00
** Tidal, for improvising music
#+BEGIN_SRC emacs-lisp
(use-package tidal)
#+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
2021-10-27 14:27:38 +00:00
** Help editing Ansible files
#+begin_src emacs-lisp
(use-package ansible)
#+end_src
** Edit browser textareas in Emacs
#+begin_src emacs-lisp
(use-package edit-server
:ensure t
:commands edit-server-start
:init (if after-init-time
(edit-server-start)
(add-hook 'after-init-hook
#'(lambda() (edit-server-start))))
:config (setq edit-server-new-frame-alist
'((name . "Edit with Emacs FRAME")
(top . 200)
(left . 200)
(width . 80)
(height . 25)
(minibuffer . t)
(menu-bar-lines . t)
(window-system . x))))
#+end_src
2019-09-09 15:06:54 +00:00
* Dired related packages
** Collapse directories that only contain one file somewhere deep
#+BEGIN_SRC emacs-lisp
(use-package dired-collapse)
#+END_SRC
** Show directory sizes
#+BEGIN_SRC emacs-lisp
2020-12-03 12:00:34 +00:00
(use-package dired-du)
2019-09-09 15:06:54 +00:00
#+END_SRC
** Show Git version information
#+BEGIN_SRC emacs-lisp
(use-package dired-git-info
:bind
(:map dired-mode-map
(")" . dired-git-info-mode)))
#+END_SRC
** Show/hide dot (hidden) files
#+BEGIN_SRC emacs-lisp
(use-package dired-hide-dotfiles
:bind
(:map dired-mode-map
("." . dired-hide-dotfiles-mode)))
#+END_SRC
** Rainbow to the stars…
2019-09-09 15:06:54 +00:00
#+BEGIN_SRC emacs-lisp
(use-package dired-rainbow
:config
2019-09-09 15:06:54 +00:00
(dired-rainbow-define-chmod executable-unix "Green" "-.*x.*"))
#+END_SRC
2018-07-30 17:52:16 +00:00
* Make programming a bit easier
** Electric case
2018-11-21 12:40:58 +00:00
Insert ~snake_case~ and ~camelCase~ without using the Shift key. It is automatically enabled in C
2018-07-30 17:52:16 +00:00
mode.
#+BEGIN_SRC emacs-lisp
(use-package electric-case
:hook
(c-mode . electric-case-c-init))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Electric operator
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))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Yasnippets
#+BEGIN_SRC emacs-lisp
(use-package yasnippet
:demand
:config
(yas-global-mode 1)
:hook
(post-command . sachachua/change-cursor-color-when-can-expand))
2018-07-30 17:52:16 +00:00
#+END_SRC
*** Extra snippets for Vala
#+BEGIN_SRC emacs-lisp
(use-package vala-snippets
:after
yasnippet)
#+END_SRC
*** Miscellanous extra snippets
#+BEGIN_SRC emacs-lisp
(use-package yasnippet-snippets
:after
yasnippet)
2018-07-30 17:52:16 +00:00
#+END_SRC
** Colourful delimiters
#+BEGIN_SRC emacs-lisp
(use-package rainbow-delimiters
:hook
(prog-mode . rainbow-delimiters-mode))
2018-07-30 17:52:16 +00:00
#+END_SRC
2021-03-10 05:23:06 +00:00
** Colourful identifiers
#+begin_src emacs-lisp
(use-package rainbow-identifiers)
#+end_src
2018-07-30 17:52:16 +00:00
** REST Client
#+BEGIN_SRC emacs-lisp
(use-package restclient)
#+END_SRC
2019-10-22 08:34:27 +00:00
** REST Client power for Org-mode!
#+BEGIN_SRC emacs-lisp
(use-package ob-restclient
:after org
:init
(org-babel-do-load-languages 'org-babel-load-languages
'((restclient . t))))
#+END_SRC
2018-07-30 17:52:16 +00:00
** Highlight current symbol
A big help during refactoring.
#+BEGIN_SRC emacs-lisp
(use-package auto-highlight-symbol
:config
(global-auto-highlight-symbol-mode t))
#+END_SRC
** Make ReallyLongCamelCaseWords more readable
#+BEGIN_SRC emacs-lisp
(use-package glasses
2018-08-10 05:14:00 +00:00
:delight " 👓"
:hook
(prog-mode . glasses-mode))
2018-07-30 17:52:16 +00:00
#+END_SRC
2018-07-30 19:14:51 +00:00
** GObject boilerplate generator
#+BEGIN_SRC emacs-lisp
(use-package gobgen)
#+END_SRC
** Highlight TODO, FIXME, and XXX
#+BEGIN_SRC emacs-lisp
(use-package hl-todo)
#+END_SRC
** Bug and patch 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 (in ?! ?#))
(group (+ digit))))
(bug-reference-url-format #'my-gitlab-url)
:hook
(text-mode . bug-reference-mode)
(prog-mode . bug-reference-prog-mode))
#+END_SRC
** Highlight indentation
#+begin_src emacs-lisp
(use-package highlight-indentation
:hook
(python-mode . highlight-indentation-mode))
#+end_src
2018-07-30 19:14:51 +00:00
* Python related setup and ~use-package~ calls
Because, well, thats my job now. Of course it gets a dedicated section.
** Set up pretty symbols for Python
Because they are fancy.
- not: ¬
- in: ∈
- def: ƒ
Maybe add ∉ for ~not in~ later, if possible.
#+BEGIN_SRC emacs-lisp
(add-hook 'python-mode-hook
(lambda ()
(add-to-list 'prettify-symbols-alist
2022-08-18 05:22:06 +00:00
'("not in" . ?∉))
2018-07-30 19:14:51 +00:00
(add-to-list 'prettify-symbols-alist
2022-08-18 05:22:06 +00:00
'("in" . ?∈))
2018-07-30 19:14:51 +00:00
(add-to-list 'prettify-symbols-alist
2022-08-18 05:22:06 +00:00
'("def" . ?ƒ))
(add-to-list 'prettify-symbols-alist
'("is not" . ?≭))
(add-to-list 'prettify-symbols-alist
'("is" . ?≍))
))
2018-07-30 19:14:51 +00:00
#+END_SRC
2021-10-27 14:29:16 +00:00
** Pyre-based LSP
2018-07-30 19:14:51 +00:00
2021-10-27 14:29:16 +00:00
#+begin_src emacs-lisp
(use-package lsp-pyre
:hook
(python-mode . lsp))
#+end_src
2018-07-30 19:14:51 +00:00
2019-12-03 08:25:14 +00:00
** Poetry
Because its also great.
#+BEGIN_SRC emacs-lisp
(use-package poetry
:config
2020-03-03 05:20:34 +00:00
(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))
2019-12-03 08:25:14 +00:00
#+END_SRC
2018-11-19 13:34:35 +00:00
** Automatically insert Sphinx-style docstrings
#+BEGIN_SRC emacs-lisp
(use-package sphinx-doc
:hook
(python-mode . sphinx-doc-mode))
#+END_SRC
2018-07-30 19:14:51 +00:00
* C mode
Because thats still my favourite language.
** Set up my own C 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
** 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")
2020-09-07 09:14:37 +00:00
(customize-set-variable 'c-basic-offset 4)
(customize-set-variable 'tab-width 4)
(customize-set-variable 'indent-tabs-mode nil)
2018-07-30 19:14:51 +00:00
(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
** Set indentation levels to the same as the tab width
2020-09-07 09:14:37 +00:00
#+BEGIN_SRC emacs-lisp :tangle no
2018-07-30 19:14:51 +00:00
(defvaralias 'c-basic-offset 'tab-width)
(defvaralias 'cperl-indent-level 'tab-width)
#+END_SRC
* Web development
** 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))
2018-07-30 19:14:51 +00:00
#+END_SRC
** Emmet mode
#+BEGIN_SRC emacs-lisp
(use-package emmet-mode
:custom
(emmet-self-closing-tag-style "")
:hook
(web-mode . emmet-mode)
(css-mode . emmet-mode))
2018-07-30 19:14:51 +00:00
#+END_SRC
** Query HTML tags by CSS selectors
#+BEGIN_SRC emacs-lisp
(use-package enlive)
#+END_SRC
2018-07-30 17:52:16 +00:00
* FlyCheck
#+BEGIN_SRC emacs-lisp
(use-package flycheck
:config
(global-flycheck-mode)
:custom
(flycheck-python-pylint-executable "python3"))
2018-07-30 17:52:16 +00:00
#+END_SRC
** FlyCheck for pkg-config files
#+BEGIN_SRC emacs-lisp
(use-package flycheck-pkg-config)
#+END_SRC
* Org mode
This is a big one; I use a lot of customisation here.
#+BEGIN_SRC emacs-lisp
(use-package org
:demand
: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>"))))
2018-07-30 17:52:16 +00:00
:config
;; Load the markdown exporter
2018-07-30 17:52:16 +00:00
(require 'ox-md)
2019-02-19 13:06:29 +00:00
;; 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 it possible to use structure templates with < X TAB
(require 'org-tempo)
2019-02-19 13:06:29 +00:00
: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 '((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)
:hook
(ediff-select . f-ediff-org-unfold-tree-element)
(ediff-unselect . f-ediff-org-fold-tree)
2018-07-30 17:52:16 +00:00
:bind
(:map gpolonkai/pers-map
("a" . gpolonkai/org-agenda-list)
("C" . org-capture)
2018-07-30 17:52:16 +00:00
("l" . org-store-link)
:map org-mode-map
("SPC" . 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 ;" . org-toggle-timestamp-type)))
2018-07-30 17:52:16 +00:00
#+END_SRC
** 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"))
2018-07-30 17:52:16 +00:00
:bind
(:map gpolonkai/pers-map
("r" . org-random-todo)))
#+END_SRC
2018-11-20 14:12:51 +00:00
** Load CalDAV entries from NextCloud
#+BEGIN_SRC emacs-lisp
(use-package org-caldav
:after org
:config
(setq
org-caldav-url "https://cloud.polonkai.eu/remote.php/dav/calendars/gergely"
org-caldav-calendar-id "org"
org-caldav-inbox (expand-file-name "cloud-calendar.org" org-directory)
org-caldav-files nil))
#+END_SRC
2018-11-27 05:27:58 +00:00
** Improved list management
#+BEGIN_SRC emacs-lisp
(use-package org-autolist
:hook
(org-mode . org-autolist-mode))
#+END_SRC
2018-12-01 06:29:45 +00:00
** Write messages with Org-mode
#+BEGIN_SRC emacs-lisp
(use-package org-msg
:after mu4e
:defer t
2018-12-01 06:29:45 +00:00
: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"))
2018-12-01 06:29:45 +00:00
#+END_SRC
** Sticky headers 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
2019-10-22 08:34:53 +00:00
** Custom bullets
#+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
2019-10-22 09:08:04 +00:00
** Edit diagrams with mermaid
#+BEGIN_SRC emacs-lisp
(use-package ob-mermaid
:custom
(ob-mermaid-cli-path "/home/polesz/.local/node/bin/mmdc"))
#+END_SRC
2020-03-24 10:30:52 +00:00
** Allow exporting to ReSTructured text
#+BEGIN_SRC emacs-lisp
(use-package ox-rst
:after org)
#+END_SRC
** Export currently clocked in task for Waybar
#+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
2018-07-30 17:52:16 +00:00
* Git & Co.
** Git status on the fringe
In graphical modes we use ~git-gutter-fringe~, and ~git-gutter~ otherwise.
#+BEGIN_SRC emacs-lisp
;; Git gutter
;; If we are in text-only mode, there is no fringe.
(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 blame current line.
#+BEGIN_SRC emacs-lisp
(use-package git-messenger
:bind
(:map gpolonkai/pers-map
("gm" . git-messenger:popup-message)))
#+END_SRC
** Git time machine
See previous versions of the current file.
#+BEGIN_SRC emacs-lisp
(use-package git-timemachine
:bind
(([f6] . git-timemachine-toggle)))
#+END_SRC
* Company & Co.
#+BEGIN_SRC emacs-lisp
(use-package company
2018-08-10 05:14:00 +00:00
:delight " 🏢"
:custom
(company-idle-delay nil)
(company-dabbrev-downcase nil)
2018-07-30 17:52:16 +00:00
:config
(setq company-frontends '(company-pseudo-tooltip-frontend
company-echo-metadata-frontend))
2018-07-30 17:52:16 +00:00
(put 'company-clang-arguments 'safe-local-variable #'nil-or-list-of-strings-p)
(global-company-mode))
#+END_SRC
** Company completion based on local C headers
#+BEGIN_SRC emacs-lisp
(use-package company-c-headers)
#+END_SRC
** Company mode in the shell
#+BEGIN_SRC emacs-lisp
(use-package company-shell)
#+END_SRC
** REST Client completion via Company
#+BEGIN_SRC emacs-lisp
(use-package company-restclient)
#+END_SRC
** Insert Emoji with Company
#+BEGIN_SRC emacs-lisp
(use-package company-emoji
:after
company
:init
(--set-emoji-font nil)
:config
(add-to-list 'company-backends 'company-emoji))
2018-07-30 17:52:16 +00:00
#+END_SRC
** Web mode (~web-mode~ and ~emmet-mode~, too) backend for Company
#+BEGIN_SRC emacs-lisp
(use-package company-web
:config
(require 'company-web-html))
#+END_SRC
2021-02-18 08:55:30 +00:00
* Ivy & Co.
2021-02-18 08:55:30 +00:00
** Ivy & Counsel
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ivy
:config
(ivy-mode 1)
:custom
2021-02-18 08:55:30 +00:00
(ivy-use-virtual-buffers t)
(ivy-count-format "(%d/%d) ")
(ivy-use-selectable-prompt t))
(use-package counsel
:config
2021-02-18 08:55:30 +00:00
(counsel-mode)
:bind
2021-02-18 08:55:30 +00:00
(:map company-mode-map
("C-c j" . counsel-company)
:map company-active-map
("C-c j" . counsel-company)))
#+end_src
2021-02-18 08:55:30 +00:00
** GNU Globals with Counsel
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(defun gpolonkai/enable-counsel-gtags-mode ()
(counsel-gtags-mode t))
2021-02-18 08:55:30 +00:00
(use-package counsel-gtags
:custom
2021-02-18 08:55:30 +00:00
(counsel-gtags-auto-update t)
(counsel-gtags-path-style 'relative)
:hook
2021-02-18 08:55:30 +00:00
(c-mode . gpolonkai/enable-counsel-gtags-mode)
:bind
2021-02-18 08:55:30 +00:00
(:map counsel-gtags-mode-map
("M-t" . counsel-gtags-find-definition)
("M-r" . counsel-gtags-find-reference)
("M-s" . counsel-gtags-find-symbol)
("C-c <" . counsel-gtags-go-backward)
("C-c >" . counsel-gtags-go-forward)))
#+end_src
2021-02-18 08:55:30 +00:00
** Ag with Counsel
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package counsel-ag-popup
:bind
(:map gpolonkai/pers-map
2021-02-18 08:55:30 +00:00
("s" . counsel-ag-popup)))
#+end_src
2021-02-18 08:55:30 +00:00
** Projectile with Counsel
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package counsel-projectile
:custom
2021-02-18 08:55:30 +00:00
(projectile-completion-system 'ivy)
:config
2021-02-18 08:55:30 +00:00
(counsel-projectile-mode))
#+end_src
2021-02-18 08:55:30 +00:00
** FlySpell with Ace
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ace-flyspell
:bind
(:map flyspell-mode-map
2021-02-18 08:55:30 +00:00
("C-M-i" . ace-flyspell-correct-word)))
#+end_src
2021-02-18 08:55:30 +00:00
** C Yasnippets with Ivy
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ivy-yasnippet
:after
yasnippet
:bind
2021-02-18 08:55:30 +00:00
(("C-c y" . ivy-yasnippet)))
#+end_src
2021-02-18 08:55:30 +00:00
** PyDoc with Counsel
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package counsel-pydoc)
#+end_src
2021-02-18 08:55:30 +00:00
** BibTex with Ivy
2021-02-18 08:55:30 +00:00
First, set up ~bibtex-completion~:
#+begin_src emacs-lisp
(use-package bibtex-completion
:after
org
:custom
(bibtex-completion-bibliography (expand-file-name "references.bib" org-directory))
(bibtex-completion-library-path (expand-file-name "bibtex-pdfs" org-directory))
(bibtex-completion-pdf-open-function 'org-open-file)
2021-02-18 08:55:30 +00:00
(bibtex-completion-notes-path (expand-file-name
(convert-standard-filename "bibliography/ivy-bibtex-notes")
org-directory)))
#+end_src
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ivy-bibtex
:after bibtex-completion)
#+end_src
2021-02-18 08:55:30 +00:00
** Access passwords in pass using Ivy
#+begin_src emacs-lisp
(use-package ivy-pass)
#+end_src
* Mode specific ~use-package~ calls
** JavaScript
#+BEGIN_SRC emacs-lisp
(use-package js2-mode
:pin melpa-stable
:mode "\\.js\\'")
#+END_SRC
** Jinja templates
#+begin_src emacs-lisp
(use-package jinja2-mode
:mode "\\.j2\\'")
#+end_src
** TypeScript
#+BEGIN_SRC emacs-lisp
(use-package typescript-mode
:mode "\\.ts\\'")
#+END_SRC
** CoffeeScript
#+BEGIN_SRC emacs-lisp
(use-package coffee-mode
:mode "\\.coffee\\'")
#+END_SRC
** JSON
#+BEGIN_SRC emacs-lisp
(use-package json-mode
:mode "\\.json\\'")
#+END_SRC
** YAML
#+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
** Markdown
#+BEGIN_SRC emacs-lisp
(use-package markdown-mode
:mode (("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode)))
#+END_SRC
** Less
#+BEGIN_SRC emacs-lisp
(use-package less-css-mode
:mode "\\.less\\'")
#+END_SRC
** Sass
#+BEGIN_SRC emacs-lisp
(use-package sass-mode
:mode "\\.sass\\'")
#+END_SRC
** Vala
#+BEGIN_SRC emacs-lisp
(use-package vala-mode
:mode "\\.vala\\'")
#+END_SRC
** Dockerfile
#+BEGIN_SRC emacs-lisp
(use-package dockerfile-mode)
#+END_SRC
2018-07-30 17:52:16 +00:00
** ~po-mode~
#+BEGIN_SRC emacs-lisp
(use-package po-mode
:ensure nil
2018-07-30 17:52:16 +00:00
:mode "\\.po\\'")
#+END_SRC
** C#
#+BEGIN_SRC emacs-lisp
(use-package csharp-mode
:mode "\\.cs\\'")
#+END_SRC
2018-07-30 19:14:51 +00:00
** Gherkin (BDD) feature files
#+BEGIN_SRC emacs-lisp
(use-package feature-mode
:mode "\\.feature\\'")
#+END_SRC
** PlantUML
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")))
2018-07-30 19:14:51 +00:00
(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
2018-08-28 16:05:26 +00:00
** For editing CSV files
#+BEGIN_SRC emacs-lisp
(use-package csv-mode
:mode "\\.csv\\'")
#+END_SRC
2018-08-28 16:06:02 +00:00
** The Go programming language
#+BEGIN_SRC emacs-lisp
(use-package go-mode
:mode "\\.go\\'")
#+END_SRC
2018-08-28 16:06:22 +00:00
** Meson build system
#+BEGIN_SRC emacs-lisp
(use-package meson-mode
:mode "\\.meson\\'")
#+END_SRC
** GraphQL
#+BEGIN_SRC emacs-lisp
(use-package graphql
:mode "\\.graphql\\'")
#+END_SRC
** Gitlab-CI
#+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
** Arduino
#+BEGIN_SRC emacs-lisp
(use-package arduino-mode
:mode "\\.ino\\'")
#+END_SRC
2019-10-22 08:35:42 +00:00
** Vue templates
#+BEGIN_SRC emacs-lisp
(use-package vue-html-mode
:mode "\\.vue\\'")
#+END_SRC
2020-01-06 08:17:16 +00:00
** Pony is awesome!
#+BEGIN_SRC emacs-lisp
(use-package ponylang-mode
:mode "\\.pony\\'")
#+END_SRC
** Rust
#+BEGIN_SRC emacs-lisp
(use-package rust-mode
:mode "\\.rs\\'")
(use-package cargo)
(use-package flycheck-rust)
#+END_SRC
2020-11-05 07:19:34 +00:00
** Fish shell
#+BEGIN_SRC emacs-lisp
(use-package fish-mode
:hook
(fish-mode . (lambda () (add-hook 'before-save-hook 'fish_indent-before-save))))
#+END_SRC
** Clojure
#+begin_src emacs-lisp
(use-package clojure-mode)
#+end_src
2021-02-09 05:20:41 +00:00
** Flutter specific things
#+begin_src emacs-lisp
(use-package lsp-mode)
(use-package lsp-dart
:hook
(dart-mode . lsp))
(use-package lsp-ui)
(use-package hover)
#+end_src
** Bats, for testing shell scripts
#+begin_src emacs-lisp
(use-package bats-mode
:mode "\\.bats\\'")
#+end_src
2021-10-27 14:29:39 +00:00
** Terraform
#+begin_src emacs-lisp
(use-package terraform-mode
:mode "\\.tf\\'")
#+end_src
2018-07-30 19:14:51 +00:00
* Games
** Gnu Go
#+BEGIN_SRC emacs-lisp
(use-package gnugo)
#+END_SRC
* Last, but not least, key bindings!
** TODO My own, personal, Magit-popup! :experimental:
With the new Transient package it will be easier. I just dont know how to use it yet.
#+BEGIN_SRC emacs-lisp
(define-transient-command gpolonkai/clock-menu ()
[("I" "Clock in to last clocked task" org-clock-in-last)
("g" "Go to the currently clocked task" org-clock-goto)
("i" "Clock in here" org-clock-in)
("o" "Clock out" org-clock-out)])
(define-transient-command gpolonkai/special-files-menu ()
[("i" "My Emacs init file" gpolonkai/visit-init-file)
("o" "My main Org file" gpolonkai/visit-org-index)])
(define-transient-command gpolonkai/git-menu ()
[("g" "Update Git gutter everywhere" git-gutter:update-all-windows)
("m" "Show the origin of this line" git-messenger:popup-message)
("n" "Next hunk" git-gutter:next-hunk)
("p" "Previous hunk" git-gutter:previous-hunk)])
(define-transient-command gpolonkai/mail-menu ()
[("c" "Compose mail" mu4e-compose-new)
("i" "Jump to folder" mu4e~headers-jump-to-maildir)
("m" "Mu4e main screen" mu4e)
2020-06-16 04:39:46 +00:00
("s" "Mu4e search" mu4e-headers-search)])
(define-transient-command gpolonkai/sx-menu ()
[("i" "Inbox" sx-inbox)
("s" "Search" sx-search)])
(define-transient-command gpolonkai/zone-menu ()
[("i" "Enable zone on idle" gpolonkai/zone-enable)
("q" "Disable zone on idle" zone-leave-me-alone)])
(define-transient-command gpolonkai/python-menu ()
[("p" "Poetry" poetry)])
(define-transient-command gpolonkai/menu ()
[("a" "My agenda" gpolonkai/org-agenda-list)
("b" "Where has my cursor gone?" beacon-blink)
("C" "Capture" org-capture)
("c" "Clocking…" gpolonkai/clock-menu)
("M-C" "Clean up old buffers" clean-buffer-list)
("e" "EShell" eshell)
("g" "Git…" gpolonkai/git-menu)
("h" "Hide mode-line" hidden-mode-line-mode)
("l" "Store Org link" org-store-link)
("m" "Mail…" gpolonkai/mail-menu)
("o" "Special files…" gpolonkai/special-files-menu)
("p" "Python…" gpolonkai/python-menu)
("q" "Stack Exchange…" gpolonkai/sx-menu)
("r" "Show a random TODO" org-random-todo)
("u" "Open URL" browse-url-at-point)
("w" "Clean up whitespace problems" whitespace-cleanup)
("x" "Expand region" er/expand-region)
("z" "Zone…" gpolonkai/zone-menu)])
#+END_SRC
** The actual key bindings
#+begin_src emacs-lisp
(defun gpolonkai/isearch-regexp (prefix)
"Call `isearch-forward-regex'. If PREFIX is non-nil, call `isearch-backward-regex' instead."
(interactive "P")
(call-interactively
(if prefix
'isearch-backward-regexp
'isearch-forward-regexp)))
#+end_src
2018-07-30 19:14:51 +00:00
#+BEGIN_SRC emacs-lisp
(bind-keys
:map global-map
("M-(" . gpolonkai/enclose-region)
2018-07-30 19:14:51 +00:00
("<C-return>" . open-line-below)
("<C-S-return>" . open-line-above)
("M-t" . nil) ;; Remove the old keybinding
("M-t c" . transpose-chars)
("M-t w" . transpose-words)
("M-t l" . transpose-lines)
("M-t e" . transpose-sexps)
("M-t s" . transpose-sentences)
("M-t p" . transpose-paragraphs)
("M-t W" . transpose-windows)
("C-a" . gpolonkai/move-to-beginning-of-line)
("C-e" . gpolonkai/move-to-end-of-line)
("M-q" . sachachua/fill-or-unfill-paragraph)
("C-c r" . round-number-at-point-to-decimals)
("C-s" . swiper)
("C-r" . gpolonkai/isearch-regexp)
2018-07-30 19:14:51 +00:00
("C-M-s" . isearch-forward)
("C-M-r" . isearch-backward)
("C-~" . toggle-char-case)
("C-z" . nil)
("M-g SPC" . goto-next-char)
2018-07-30 19:14:51 +00:00
:map ctl-x-map
("C-y" . gpolonkai/duplicate-line)
("_" . maximize-window)
("C-r" . rename-current-buffer-file)
("C-d" . delete-current-buffer-file)
("|" . toggle-window-split)
("k" . kill-this-buffer)
2018-07-30 19:14:51 +00:00
("M-k" . gpolonkai/undo-buffer-kill)
("C-b" . bury-buffer)
("/" . repeat)
2021-02-18 08:55:30 +00:00
("C-f" . counsel-find-file)
("b" . counsel-switch-buffer)
2018-07-30 19:14:51 +00:00
:map isearch-mode-map
("<C-return>" . isearch-exit-other-end)
("<S-return>" . isearch-exit-mark-match)
:map gpolonkai/pers-map
("C-t" . gpolonkai/menu)
2018-09-19 12:28:30 +00:00
("h" . hidden-mode-line-mode)
2018-07-30 19:14:51 +00:00
("C-i e" . "gergely@polonkai.eu")
("C-i w" . "http://gergely.polonkai.eu/")
("o i" . gpolonkai/visit-init-file)
("o o" . gpolonkai/visit-org-index)
("u" . browse-url-at-point)
("M-C" . clean-buffer-list)
("C-c" . calc)
("c i" . org-clock-in)
("c I" . org-clock-in-last)
("c o" . org-clock-out)
("c g" . org-clock-goto)
("M-o" . insert-current-file-name-at-point))
2018-07-30 19:14:51 +00:00
#+END_SRC
** TODO These fail to work using ~bind-keys~, but why?
#+BEGIN_SRC emacs-lisp
(define-key 'help-command (kbd "C-l") 'find-library)
(define-key 'help-command (kbd "C-f") 'find-function)
(define-key 'help-command (kbd "C-k") 'find-function-on-key)
(define-key 'help-command (kbd "C-v") 'find-variable)
#+END_SRC
* And finally, server mode
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.
#+BEGIN_SRC emacs-lisp
(require 'server)
(unless (server-running-p)
(server-start))
#+END_SRC