2019-10-22 08:27:25 +00:00
* 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
2019-10-22 08:33:00 +00:00
* 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
2018-12-10 07:25:05 +00:00
** Set up the package archives
#+BEGIN_SRC emacs-lisp
(require 'package)
(add-to-list 'package-archives
2021-11-23 08:48:11 +00:00
'("gnu" . "https://elpa.gnu.org/packages/ "))
2018-12-10 07:25:05 +00:00
(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
2021-11-23 08:48:11 +00:00
'("org" . "https://orgmode.org/elpa/ ") t)
2018-12-10 07:25:05 +00:00
(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
2019-02-19 09:43:16 +00:00
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
2018-07-29 16:38:44 +00:00
2019-02-19 09:43:16 +00:00
(require 'use-package)
2018-07-29 16:38:44 +00:00
2019-02-19 09:43:16 +00:00
(customize-set-variable 'use-package-always-ensure t)
2019-02-22 06:09:07 +00:00
(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
2020-11-01 05:07:11 +00:00
(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
2020-11-01 05:07:11 +00:00
(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
2018-11-21 12:59:29 +00:00
** 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")
2021-02-09 05:19:51 +00:00
(kill-read-only-ok t)
(use-dialog-box nil))
2018-11-21 12:59:29 +00:00
#+END_SRC
2018-07-29 16:38:44 +00:00
** Set up my personal keymap
2020-11-05 07:24:53 +00:00
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)
2018-08-07 12:32:25 +00:00
(define-key global-map (kbd "C-t") 'gpolonkai/pers-map)
2018-07-29 16:38:44 +00:00
#+END_SRC
2020-11-05 07:24:53 +00:00
** I really don’ t 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
2018-08-09 11:24:25 +00:00
** Set UTF-8 as the default encoding
2020-11-05 07:24:53 +00:00
Just to make sure, although most Linux DEs do this for me.
2018-08-09 11:24:25 +00:00
#+BEGIN_SRC emacs-lisp
(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8)
#+END_SRC
2020-11-05 07:24:53 +00:00
** Set Org’ s main directory
2019-10-22 08:33:33 +00:00
2021-03-09 16:41:40 +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
2018-07-29 16:58:11 +00:00
* Custom commands and functions
2018-07-29 17:37:35 +00:00
** 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
2018-07-30 18:02:49 +00:00
*** 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
2018-08-06 06:25:56 +00:00
*** Make a backup filename under ~user-emacs-cache-directory~
Taken from [[http://ergoemacs.org/emacs/emacs_set_backup_into_a_directory.html ][Xah’ s site ]].
#+BEGIN_SRC emacs-lisp
(defun xah/backup-file-name (fpath)
"Return a new file path for FPATH under `user-emacs-cache-directory'"
2018-08-07 12:33:32 +00:00
(let* ((backup-root-dir (expand-file-name "backup" user-emacs-cache-directory))
(file-path (replace-regexp-in-string "[A-Za-z]:" "" fpath))
2018-08-06 06:25:56 +00:00
(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
2018-09-06 12:04:55 +00:00
*** 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
2022-08-18 05:21:31 +00:00
*** 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 file’ s 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 file’ s
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
2018-07-29 16:58:11 +00:00
** 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 ][Xah’ s 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 Xah’ s 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
2018-07-29 17:00:38 +00:00
*** Enclose region in a specific character
#+BEGIN_SRC emacs-lisp
2019-02-19 09:44:31 +00:00
(defun gpolonkai/enclose-region (character &optional start end)
"Enclose region between CHARACTER.
2018-07-29 17:00:38 +00:00
2019-02-19 09:44:31 +00:00
If region is empty and neither START nor END is set, simply inserts CHARACTER
two times and moves point between them.
2018-07-29 17:00:38 +00:00
2019-02-19 09:44:31 +00:00
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."
2018-07-29 17:00:38 +00:00
2019-02-19 09:44:31 +00:00
(interactive "cWhat character? \nr")
2018-07-29 17:00:38 +00:00
2019-02-19 09:44:31 +00:00
(let ((open character)
(close character)
(pair (assq character insert-pair-alist)))
2018-07-29 17:00:38 +00:00
(if pair
(if (nth 2 pair)
(setq open (nth 1 pair) close (nth 2 pair))
2019-02-19 09:44:31 +00:00
(setq open (nth 0 pair) close (nth 1 pair))))
(unless (and open close)
(setq open character
close character))
(unless (use-region-p)
2019-02-22 06:09:34 +00:00
(setq start (point)
end (point)))
2019-02-19 09:44:31 +00:00
(save-excursion
(goto-char end)
(insert-char close)
2018-07-29 17:00:38 +00:00
2019-02-19 09:44:31 +00:00
(goto-char start)
(insert-char open))
(unless (use-region-p)
(forward-char))))
2018-07-29 17:00:38 +00:00
#+END_SRC
2019-02-19 09:50:20 +00:00
*** Convert ~camelCase~ to ~snake_case~
2018-07-29 17:26:22 +00:00
#+BEGIN_SRC emacs-lisp
(defun camel-to-snake-case (arg)
2019-02-19 09:50:20 +00:00
"Convert a camelCase word to snake_case.
2018-07-29 17:26:22 +00:00
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
2018-07-29 17:35:59 +00:00
*** 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:
2018-07-29 17:35:59 +00:00
#+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:
2018-07-29 17:35:59 +00:00
#+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
2019-02-19 13:32:47 +00:00
*** Insert the current file’ s 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
2018-07-29 16:58:11 +00:00
** 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
2021-11-23 08:52:10 +00:00
*** 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
2018-07-29 16:58:11 +00:00
** 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:
2018-07-29 16:58:11 +00:00
#+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:
2018-07-29 16:58:11 +00:00
#+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.
2018-09-19 07:42:24 +00:00
Used by `gpolonkai/save-killed-buffer-filename' and `gpolonkai/undo-buffer-kill'.")
2018-07-29 16:58:11 +00:00
2018-09-19 07:42:24 +00:00
(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
2018-11-30 09:42:12 +00:00
(setq gpolonkai/last-killed-buffer-file-name (buffer-file-name)))))
2018-09-19 07:42:24 +00:00
(add-hook 'kill-buffer-hook 'gpolonkai/save-killed-buffer-filename)
2018-07-29 16:58:11 +00:00
(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 didn’ t visit a file.")))
#+END_SRC
2018-07-29 17:05:26 +00:00
*** 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)
2018-07-30 20:24:40 +00:00
(find-file-other-window (expand-file-name "configuration.org" user-emacs-directory)))
2018-07-29 17:05:26 +00:00
#+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)
2019-02-19 10:03:18 +00:00
(find-file-other-window (expand-file-name "index.org" org-directory)))
2018-07-29 17:05:26 +00:00
#+END_SRC
2018-07-29 17:14:59 +00:00
** Frame manipulation
*** Hidden modeline mode
2019-02-19 09:51:33 +00:00
:PROPERTIES:
:SOURCE: http://emacs-doctor.com/emacs-strip-tease.html
:END:
2018-07-29 17:14:59 +00:00
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
2018-07-30 17:58:19 +00:00
** 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
2018-07-29 16:58:11 +00:00
** ~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
2018-07-29 17:26:22 +00:00
** 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
2018-07-29 17:26:22 +00:00
** ~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 "\"\"\"")
2019-12-09 05:13:35 +00:00
(let ((point-pos (point)))
(open-line-below)
(insert "\"\"\"\n")
(goto-char point-pos))))
2018-07-29 17:26:22 +00:00
#+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:
2020-09-07 09:18:56 +00:00
#+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
2018-09-06 12:04:55 +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
2018-07-30 17:53:54 +00:00
** 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 don’ t 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 Yasnippet’ s TAB function would fire
Taken from [[http://pages.sachachua.com/.emacs.d/Sacha.html ][Sacha Chua’ s 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
2021-03-18 05:09:06 +00:00
** Org mode stuff
*** Filter out tasks from the Org agenda if they have a specific priority
2018-11-18 06:10:04 +00:00
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.
2021-03-18 05:09:06 +00:00
#+begin_src emacs-lisp
2018-11-18 06:10:04 +00:00
(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)))
2021-03-18 05:09:06 +00:00
#+end_src
2018-11-18 06:10:04 +00:00
2021-03-18 05:09:06 +00:00
*** Filter out habits from the Org agenda
2018-11-18 06:10:04 +00:00
2021-03-18 05:09:06 +00:00
#+begin_src emacs-lisp
2018-11-18 06:10:04 +00:00
(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)))
2021-03-18 05:09:06 +00:00
#+end_src
2018-11-18 06:10:04 +00:00
2021-03-18 05:09:06 +00:00
*** Filter out entries from the Org agenda with a specific state
2018-11-19 13:33:24 +00:00
2021-03-18 05:09:06 +00:00
#+begin_src emacs-lisp
2018-11-19 13:33:24 +00:00
(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)))
2021-03-18 05:09:06 +00:00
#+end_src
2018-11-19 13:33:24 +00:00
2021-03-18 05:09:06 +00:00
*** Wrapper around ~org-agenda~ to open my own custom list
2018-11-18 06:10:04 +00:00
2021-03-18 05:09:06 +00:00
#+begin_src emacs-lisp
2018-11-18 06:10:04 +00:00
(defun gpolonkai/org-agenda-list (&optional arg)
(interactive "P")
(org-agenda arg "c"))
2021-03-18 05:09:06 +00:00
#+end_src
2018-11-18 06:10:04 +00:00
2021-03-18 05:25:18 +00:00
*** 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 (that’ s why Nyan-cat is here), the toolbar (I don’ t 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
2018-11-30 09:09:45 +00:00
(defun gpolonkai/set-font-size (frame)
2019-03-29 06:50:02 +00:00
(when (display-graphic-p frame)
(set-face-attribute 'default frame :font "Hack-12")
2019-11-20 07:32:31 +00:00
(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."
2019-03-29 06:50:02 +00:00
(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)))
2018-11-30 09:09:45 +00:00
(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" . ?∨ )
("<=" . ?≤)
(">=" . ?≥)))
2020-11-05 07:23:46 +00:00
#+END_SRC
…and some pairs to complete
2018-07-30 19:14:51 +00:00
2020-11-05 07:23:46 +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) ; «»
2020-11-05 07:23:46 +00:00
(187 171))) ; »«
#+END_SRC
Finally, set the frame title to the current file name
2018-07-30 19:14:51 +00:00
2020-11-05 07:23:46 +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)
2020-11-05 07:23:46 +00:00
(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
2020-11-05 07:24:53 +00:00
Because i’ m 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
2021-02-09 05:19:06 +00:00
* 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
2021-03-18 05:23:17 +00:00
** 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
2018-07-29 18:29:56 +00:00
* 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 I’ m 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
2018-07-29 18:29:56 +00:00
** nXML
#+BEGIN_SRC emacs-lisp
(use-package nxml-mode
:ensure nil
2018-11-21 12:59:29 +00:00
:custom
(nxml-attribute-indent 4)
(nxml-child-indent 4)
(nxml-outline-child-indent 4))
2018-07-29 18:29:56 +00:00
#+END_SRC
** ~recentf~
#+BEGIN_SRC emacs-lisp
(use-package recentf
:ensure nil
:config
(run-at-time nil (* 5 60) 'recentf-save-list)
2019-02-19 10:03:18 +00:00
(add-to-list 'recentf-exclude (expand-file-name "elpa" user-emacs-directory)))
2018-07-29 18:29:56 +00:00
#+END_SRC
** ~files~
#+BEGIN_SRC emacs-lisp
(use-package files
:ensure nil
2018-11-21 12:59:29 +00:00
:custom
(make-backup-file-name-function 'xah/backup-file-name))
2018-07-29 18:29:56 +00:00
#+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
2019-02-03 07:24:47 +00:00
(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
2019-02-03 07:24:47 +00:00
(add-function :before-while whitespace-enable-predicate 'prevent-whitespace-mode-for-some)
2018-07-30 17:52:16 +00:00
(global-whitespace-mode 1)
2018-11-21 12:59:29 +00:00
: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~
2018-11-21 12:12:45 +00:00
This is a function to delete a character, or close ~eshell~ if there’ s 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
2018-11-21 12:12:45 +00:00
("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
2018-08-06 06:26:37 +00:00
:config'
2018-11-21 12:59:29 +00:00
(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
2018-11-21 12:59:29 +00:00
: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
2018-11-21 12:59:29 +00:00
: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 let’ s 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
2020-11-05 07:24:53 +00:00
** Which function am i in?
2018-07-30 17:52:16 +00:00
2018-11-21 12:39:14 +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
2018-11-21 12:39:14 +00:00
(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
2018-11-21 12:59:29 +00:00
: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
2018-11-21 12:59:29 +00:00
: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)
2018-08-13 05:33:58 +00:00
("^" . (lambda () (interactive) (find-alternate-file "..")))
("W" . wdired-change-to-wdired-mode)))
2018-08-09 11:48:01 +00:00
#+END_SRC
2018-09-24 07:36:24 +00:00
** 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
2018-10-26 16:24:49 +00:00
** 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
2018-11-19 12:03:14 +00:00
** Show line numbers
I don’ t 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
2018-11-21 12:59:29 +00:00
: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
2019-12-09 05:11:18 +00:00
** Speed bar
#+BEGIN_SRC emacs-lisp
(use-package speedbar)
#+END_SRC
2018-07-29 16:38:44 +00:00
* ~use-package~ packages
2019-11-14 13:46:57 +00:00
** 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
2018-11-21 12:59:29 +00:00
:custom
(auto-package-update-interval 7)
(auto-package-update-delete-old-versions t)
2018-07-30 17:52:16 +00:00
;; Let’ s do this in after-init-hook, as use-package invocations may modify
;; the list of installed packages
2018-11-21 12:39:14 +00:00
:hook
(after-init . auto-package-update-maybe))
2018-07-30 17:52:16 +00:00
#+END_SRC
2018-07-29 18:46:29 +00:00
** Nyanyanyanyanya
*** Nyan-cat style position marker
#+BEGIN_SRC emacs-lisp
(use-package nyan-mode
:config
2018-11-21 12:59:29 +00:00
(nyan-mode t)
:custom
(nyan-bar-length 20)
(nyan-animate-nyancat t)
(nyan-wavy-trail t))
2018-07-29 18:46:29 +00:00
#+END_SRC
*** Nyan prompt in EShell
#+BEGIN_SRC emacs-lisp
2018-11-30 09:09:45 +00:00
(use-package nyan-prompt
2021-03-09 16:58:14 +00:00
:disabled
:hook
(eshell-load . nyan-prompt-enable))
2018-07-29 18:46:29 +00:00
#+END_SRC
*** Zone out with Nyancat
Unfortunately, this works only in a graphical mode.
#+BEGIN_SRC emacs-lisp
2018-11-30 09:09:45 +00:00
(use-package zone-nyan
:after
zone
:config
2018-11-21 12:59:29 +00:00
(setq zone-programs (vconcat zone-programs [zone-nyan]))
:custom
(zone-nyan-hide-progress t))
2018-07-29 18:46:29 +00:00
#+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
2018-11-30 08:24:21 +00:00
*** Moody mode-line
2018-07-30 17:52:16 +00:00
#+BEGIN_SRC emacs-lisp
2018-11-30 08:24:21 +00:00
(use-package moody
2018-07-30 17:52:16 +00:00
:config
2018-11-30 08:24:21 +00:00
(moody-replace-mode-line-buffer-identification)
(moody-replace-vc-mode)
(set-face-attribute 'mode-line nil :box nil :foreground "#7e7486")
2018-11-21 12:59:29 +00:00
(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
2018-09-28 09:02:28 +00:00
*** 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 it’ s 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
2018-11-30 09:09:45 +00:00
(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"
2021-03-09 16:58:14 +00:00
(autoload 'epe-theme-lambda "eshell-prompt-extras"))
2018-11-21 12:59:29 +00:00
: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
2018-11-21 12:39:14 +00:00
:hook
2018-11-21 13:14:04 +00:00
(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
2018-11-21 12:39:14 +00:00
(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
2018-11-21 12:39:14 +00:00
: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
2018-11-21 12:39:14 +00:00
(defun gpolonkai/no-blink-matching-paren ()
2018-11-21 12:59:29 +00:00
(customize-set-variable 'blink-matching-paren nil))
2018-11-21 12:39:14 +00:00
(defun gpolonkai/blink-matching-paren ()
2018-11-21 12:59:29 +00:00
(customize-set-variable 'blink-matching-paren t))
2018-11-21 12:39:14 +00:00
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)
2018-11-21 12:39:14 +00:00
: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
2018-11-21 12:59:29 +00:00
: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
2018-11-21 12:39:14 +00:00
("g" . magit-status))
:hook
(git-commit-mode . turn-on-flyspell))
2018-07-29 18:48:11 +00:00
#+END_SRC
2020-11-05 07:24:53 +00:00
*** Make Magit work with Git forges
2018-12-22 14:06:37 +00:00
#+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)
2018-11-21 12:39:14 +00:00
: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
2019-10-22 08:33:53 +00:00
(use-package org-projectile
2019-11-14 13:31:41 +00:00
:after (:all projectile org)
2019-10-22 08:33:53 +00:00
: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
2018-11-19 14:22:29 +00:00
: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
2018-11-21 12:59:29 +00:00
: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)
2018-11-25 10:34:40 +00:00
("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
2018-11-21 12:39:14 +00:00
: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
2018-08-06 06:27:14 +00:00
(: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/ "
2021-03-18 05:06:12 +00:00
(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
2018-11-21 12:39:14 +00:00
: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
2018-09-28 09:02:28 +00:00
;; 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
** I’ m an achiever!
#+BEGIN_SRC emacs-lisp
(use-package achievements
2018-08-16 10:04:44 +00:00
:demand
2018-07-30 19:14:51 +00:00
:config
2018-08-16 10:04:44 +00:00
(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
2018-11-21 12:39:14 +00:00
: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.
2018-11-21 12:39:14 +00:00
(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)~ . It’ s 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
2018-11-30 09:09:45 +00:00
(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
2018-11-30 09:09:45 +00:00
(([f5] . neotree-toggle))
:hook
(neo-enter . gpolonkai/neo-set-theme))
2018-07-30 19:14:51 +00:00
#+END_SRC
2021-03-09 16:42:55 +00:00
** Waka-waka (AKA ActivityWatch)
#+begin_src emacs-lisp
(use-package activity-watch-mode
:config
(global-activity-watch-mode))
#+end_src
2018-07-30 20:18:03 +00:00
** 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
2018-08-16 10:04:44 +00:00
:demand
2018-11-21 12:59:29 +00:00
: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)
2018-08-16 10:04:44 +00:00
(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
2018-11-19 08:47:43 +00:00
** Help merging ~pacsave~ and ~pacnew~ files
#+BEGIN_SRC emacs-lisp
(use-package pacfiles-mode
:commands pacfiles)
#+END_SRC
2018-11-19 13:40:55 +00:00
** Mailing with mu4e
2019-02-22 06:08:38 +00:00
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
2018-11-19 13:40:55 +00:00
#+BEGIN_SRC emacs-lisp
(use-package mu4e
2021-02-18 08:55:30 +00:00
:after ivy
2018-11-19 13:40:55 +00:00
:ensure nil
:config
2019-02-14 07:09:26 +00:00
(require 'org-mu4e)
2018-11-19 13:40:55 +00:00
(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"))
2018-11-19 13:40:55 +00:00
:match-func (lambda (msg)
(when msg
2020-06-16 04:39:46 +00:00
(mu4e-message-contact-field-matches
msg
:to "gergely@polonkai.eu")))
2018-11-19 13:40:55 +00:00
: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"))))
2018-11-19 13:40:55 +00:00
,(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"))
2018-11-19 13:40:55 +00:00
: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)
2019-02-19 09:46:26 +00:00
:custom
2021-03-09 16:51:13 +00:00
(mu4e-completing-read-function 'ivy-completing-read)
2019-02-19 09:46:26 +00:00
(mu4e-context-policy 'pick-first)
2019-02-21 16:07:05 +00:00
(mu4e-confirm-quit nil)
2020-01-23 10:02:41 +00:00
(mail-user-agent 'sendmail-user-agent)
2019-02-22 06:08:38 +00:00
:hook
(mu4e-view-mode . gpolonkai/mu4e-trailing-whitespace-fix)
2018-11-19 13:40:55 +00:00
:bind
(:map gpolonkai/pers-map
2018-11-25 05:51:30 +00:00
("m m" . mu4e)
("m i" . mu4e~headers-jump-to-maildir)
("m c" . mu4e-compose-new)
("m s" . mu4e-headers-search)))
2018-11-20 12:59:50 +00:00
#+END_SRC
2018-11-20 13:00:41 +00:00
2019-12-12 15:00:30 +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
** ViM’ s ~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-19 13:40:55 +00:00
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
2019-02-19 14:22:17 +00:00
** Transient for creating beautiful command menus
#+BEGIN_SRC emacs-lisp
(use-package transient)
#+END_SRC
2019-12-09 05:11:18 +00:00
** 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
2020-06-16 04:47:57 +00:00
** 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
2021-03-09 16:47:46 +00:00
** Paradox, for better package management
I don’ t 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)
2021-11-23 11:27:38 +00:00
(paradox-github-token (nth 1 (auth-source-user-and-password "api.github.com" "gergelypolonkai^paradox")))
2021-03-09 16:47:46 +00:00
: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
2021-10-27 14:28:11 +00:00
** 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
2021-02-09 07:05:13 +00:00
: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
2018-11-21 12:39:14 +00:00
: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
2018-11-21 12:39:14 +00:00
(electric-operator-get-rules-for-mode 'prog-mode))
:hook
2019-02-07 08:02:42 +00:00
(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)
2018-11-21 12:39:14 +00:00
: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
2019-11-14 13:32:03 +00:00
(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
2018-11-21 12:39:14 +00:00
: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 " 👓"
2018-11-21 12:39:14 +00:00
: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
2019-09-09 15:46:43 +00:00
** 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
2021-10-27 14:28:50 +00:00
** 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, that’ s 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 it’ s 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 that’ s 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)
2018-11-21 12:59:29 +00:00
(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?\\'"
2018-11-21 12:59:29 +00:00
: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
2018-11-21 12:59:29 +00:00
:custom
(emmet-self-closing-tag-style "")
2018-11-21 12:39:14 +00:00
: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
2019-11-14 13:57:35 +00:00
(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)
2018-10-19 07:25:16 +00:00
(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)
2019-02-26 13:23:16 +00:00
(setq-default org-default-notes-file (expand-file-name "notes.org" org-directory)
2018-11-18 06:04:43 +00:00
org-agenda-files `(,org-directory)
2018-08-09 11:48:27 +00:00
org-time-stamp-formats '("<%Y-%m-%d >" . "<%Y-%m-%d %H:%M >")
org-todo-keywords '((sequence "TODO(t)"
"DOING(w@/!)"
"BLOCKED(b@/!)"
2018-11-19 13:34:01 +00:00
"SOMEDAY(s!)"
2018-08-09 11:48:27 +00:00
"|"
"CANCELED(c@/!)"
"REVIEW(r@/!)"
"DONE(d@/!)"))
2019-02-26 13:23:16 +00:00
org-todo-keyword-faces '(("SOMEDAY" . (:foreground "goldenrod"))
2018-10-26 16:27:49 +00:00
("CANCELED" . (:foreground "#228b22" :strike-through t)))
2018-08-09 11:48:27 +00:00
org-html-checkbox-types
'((unicode (on . "<span class=\"task-done\" >☑</span >")
(off . "<span class=\"task-todo\" >☐</span >")
2019-09-23 11:53:40 +00:00
(trans . "<span class=\"task-in-progress\" >▣</span >"))))
2018-07-30 17:52:16 +00:00
:config
2018-09-19 08:47:26 +00:00
;; 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)
2019-02-26 13:23:16 +00:00
;; Make it possible to encrypt headings
(require 'org-crypt)
2020-11-05 07:23:46 +00:00
;; Make it possible to use inline tasks
(require 'org-inlinetask)
2020-11-05 08:24:12 +00:00
;; Make it possible to use structure templates with < X TAB
(require 'org-tempo)
2019-02-19 13:06:29 +00:00
2019-02-26 13:23:16 +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)
2020-11-05 08:24:12 +00:00
(org-enforce-todo-checkbox-dependencies t)
2019-02-26 13:23:16 +00:00
(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")
2019-09-23 11:53:40 +00:00
(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)
2019-11-14 13:32:44 +00:00
(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%?")))
2019-12-09 05:12:05 +00:00
(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")))
2020-11-05 08:24:12 +00:00
(org-agenda-dim-blocked-tasks t)
2018-11-21 12:39:14 +00:00
: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
2018-11-18 06:10:04 +00:00
("a" . gpolonkai/org-agenda-list)
2018-11-23 14:40:36 +00:00
("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)
2018-10-26 16:35:18 +00:00
("C-e" . gpolonkai/move-to-end-of-line)
2018-11-25 10:34:40 +00:00
("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
;; Don’ t bug me too often…
(setq org-random-todo-how-often 3600)
2019-09-09 15:07:12 +00:00
: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
2021-11-23 08:54:34 +00:00
:after mu4e
:defer t
2018-12-01 06:29:45 +00:00
:config
2018-11-21 12:59:29 +00:00
(org-msg-mode)
:custom
2021-11-23 08:54:34 +00:00
(org-msg-supported-mua '((sendmail-user-agent . "mu4e")))
2018-11-21 12:59:29 +00:00
(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
2019-02-03 07:25:42 +00:00
** Sticky headers so i always know where i am
#+BEGIN_SRC emacs-lisp
(use-package org-sticky-header
2018-11-21 12:59:29 +00:00
:custom
(org-sticky-header-full-path 'full)
2019-02-03 07:25:42 +00:00
: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
2021-03-18 05:24:40 +00:00
** 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 " 🏢"
2018-11-21 12:59:29 +00:00
:custom
(company-idle-delay nil)
(company-dabbrev-downcase nil)
2018-07-30 17:52:16 +00:00
:config
2018-11-21 12:59:29 +00:00
(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
2018-11-30 09:09:45 +00:00
(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.
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** Ivy & Counsel
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ivy
:config
(ivy-mode 1)
2018-11-21 12:59:29 +00:00
: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
2018-07-29 18:33:15 +00:00
:config
2021-02-18 08:55:30 +00:00
(counsel-mode)
2018-07-29 18:33:15 +00:00
: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
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** GNU Globals with Counsel
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(defun gpolonkai/enable-counsel-gtags-mode ()
(counsel-gtags-mode t))
2018-11-21 12:39:14 +00:00
2021-02-18 08:55:30 +00:00
(use-package counsel-gtags
2018-11-21 12:59:29 +00:00
:custom
2021-02-18 08:55:30 +00:00
(counsel-gtags-auto-update t)
(counsel-gtags-path-style 'relative)
2018-11-21 12:39:14 +00:00
:hook
2021-02-18 08:55:30 +00:00
(c-mode . gpolonkai/enable-counsel-gtags-mode)
2018-07-29 18:33:15 +00:00
: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
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** Ag with Counsel
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package counsel-ag-popup
2018-07-29 18:33:15 +00:00
:bind
(:map gpolonkai/pers-map
2021-02-18 08:55:30 +00:00
("s" . counsel-ag-popup)))
#+end_src
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** Projectile with Counsel
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package counsel-projectile
2018-11-21 12:59:29 +00:00
:custom
2021-02-18 08:55:30 +00:00
(projectile-completion-system 'ivy)
2018-07-29 18:33:15 +00:00
:config
2021-02-18 08:55:30 +00:00
(counsel-projectile-mode))
#+end_src
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** FlySpell with Ace
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ace-flyspell
2018-07-29 18:33:15 +00:00
:bind
(:map flyspell-mode-map
2021-02-18 08:55:30 +00:00
("C-M-i" . ace-flyspell-correct-word)))
#+end_src
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** C Yasnippets with Ivy
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ivy-yasnippet
2019-11-14 13:33:04 +00:00
:after
yasnippet
2018-07-29 18:33:15 +00:00
:bind
2021-02-18 08:55:30 +00:00
(("C-c y" . ivy-yasnippet)))
#+end_src
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** PyDoc with Counsel
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package counsel-pydoc)
#+end_src
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
** BibTex with Ivy
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
First, set up ~bibtex-completion~ :
#+begin_src emacs-lisp
(use-package bibtex-completion
2018-07-29 18:33:15 +00:00
:after
org
2018-11-21 12:59:29 +00:00
: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
2018-07-29 18:33:15 +00:00
2021-02-18 08:55:30 +00:00
#+begin_src emacs-lisp
(use-package ivy-bibtex
:after bibtex-completion)
#+end_src
2019-09-09 15:10:41 +00:00
2021-02-18 08:55:30 +00:00
** Access passwords in pass using Ivy
#+begin_src emacs-lisp
(use-package ivy-pass)
#+end_src
2019-09-09 15:10:41 +00:00
2018-07-29 18:15:59 +00:00
* Mode specific ~use-package~ calls
** JavaScript
#+BEGIN_SRC emacs-lisp
(use-package js2-mode
:pin melpa-stable
:mode "\\.js\\'")
#+END_SRC
2021-03-10 05:22:33 +00:00
** Jinja templates
#+begin_src emacs-lisp
(use-package jinja2-mode
:mode "\\.j2\\'")
#+end_src
2018-07-29 18:15:59 +00:00
** 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
2019-02-14 18:34:07 +00:00
: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")
2019-02-19 10:03:18 +00:00
(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
2019-09-09 15:26:48 +00:00
** GraphQL
#+BEGIN_SRC emacs-lisp
(use-package graphql
:mode "\\.graphql\\'")
#+END_SRC
2019-09-09 15:27:10 +00:00
** 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
2019-09-09 15:48:23 +00:00
** 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
2020-07-20 04:40:05 +00:00
** Rust
#+BEGIN_SRC emacs-lisp
(use-package rust-mode
:mode "\\.rs\\'")
2022-04-07 14:39:02 +00:00
(use-package cargo)
2020-07-20 04:40:05 +00:00
(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
2020-12-10 04:12:35 +00:00
** 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
2021-03-09 16:49:33 +00:00
** 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!
2019-02-19 14:22:17 +00:00
** TODO My own, personal, Magit-popup! :experimental:
With the new Transient package it will be easier. I just don’ t 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)])
2019-02-19 14:22:17 +00:00
(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)])
2019-12-12 15:01:02 +00:00
(define-transient-command gpolonkai/python-menu ()
[("p" "Poetry" poetry)])
2019-02-19 14:22:17 +00:00
(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)
2019-12-12 15:01:02 +00:00
("p" "Python…" gpolonkai/python-menu)
2019-02-19 14:22:17 +00:00
("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
2021-03-09 16:54:32 +00:00
#+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
2019-02-19 09:44:31 +00:00
("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)
2021-03-09 16:54:32 +00:00
("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)
2020-03-03 05:19:40 +00:00
("C-z" . nil)
2021-11-23 08:52:10 +00:00
("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)
2018-09-19 07:42:24 +00:00
("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
2019-02-19 14:22:17 +00:00
("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)
2018-11-23 14:40:36 +00:00
("M-C" . clean-buffer-list)
("C-c" . calc)
("c i" . org-clock-in)
("c I" . org-clock-in-last)
2018-11-25 10:34:40 +00:00
("c o" . org-clock-out)
2019-02-19 13:32:47 +00:00
("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
2018-10-26 16:24:49 +00:00
2018-10-19 07:26:04 +00:00
* 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