2018-07-29 16:38:44 +00:00
|
|
|
|
* Emacs configuration
|
|
|
|
|
|
|
|
|
|
** Configure ~use-package~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(unless (package-installed-p 'use-package)
|
|
|
|
|
(package-refresh-contents)
|
|
|
|
|
(package-install 'use-package))
|
|
|
|
|
|
|
|
|
|
(setq use-package-always-ensure t
|
|
|
|
|
use-package-verbose t)
|
|
|
|
|
|
|
|
|
|
(require 'use-package)
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** Set up my personal keymap
|
|
|
|
|
|
|
|
|
|
I set it up early so I can use it in ~use-package~ calls immediately.
|
|
|
|
|
|
|
|
|
|
#+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)
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** I really don’t want to type more than I really must…
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(defalias 'yes-or-no-p 'y-or-n-p)
|
|
|
|
|
#+END_SRC
|
|
|
|
|
* Set personal information
|
|
|
|
|
|
2018-07-29 18:29:56 +00:00
|
|
|
|
** Who am I?
|
2018-07-29 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(setq user-full-name "Gergely Polonkai"
|
2018-07-29 18:29:56 +00:00
|
|
|
|
user-mail-address "gergely@polonkai.eu")
|
2018-07-29 16:38:44 +00:00
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
* Add ~lisp/~ to ~load-path~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(add-to-list 'load-path (expand-file-name
|
|
|
|
|
(convert-standard-filename "lisp/")
|
|
|
|
|
user-emacs-directory))
|
|
|
|
|
#+END_SRC
|
2018-07-29 16:58:11 +00:00
|
|
|
|
|
2018-07-29 18:35:45 +00:00
|
|
|
|
** Load ~xdg-paths~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(load "xdg-paths")
|
|
|
|
|
#+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-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
|
|
|
|
|
(defun æ-enclose-region (character &optional start end)
|
|
|
|
|
"Enclose region in CHARACTER. If region is empty, simply inserts
|
|
|
|
|
CHARACTER two times and moves point between them.
|
|
|
|
|
|
|
|
|
|
If character is present in `insert-pair-alist', this function
|
|
|
|
|
will enclose region in the corresponding pair. In this case,
|
|
|
|
|
CHARACTER must be the opening member of the pair."
|
|
|
|
|
|
|
|
|
|
(interactive "cWhat character? \nr")
|
|
|
|
|
|
|
|
|
|
(setq open character close character)
|
|
|
|
|
|
|
|
|
|
(let ((pair (assq character insert-pair-alist)))
|
|
|
|
|
(if pair
|
|
|
|
|
(if (nth 2 pair)
|
|
|
|
|
(setq open (nth 1 pair) close (nth 2 pair))
|
|
|
|
|
(setq open (nth 0 pair) close (nth 1 pair)))))
|
|
|
|
|
|
|
|
|
|
(unless (and open close)
|
|
|
|
|
(setq open character)
|
|
|
|
|
(setq close character))
|
|
|
|
|
|
|
|
|
|
(unless (use-region-p)
|
|
|
|
|
(setq start (point) end (point)))
|
|
|
|
|
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char end)
|
|
|
|
|
(insert-char close)
|
|
|
|
|
|
|
|
|
|
(goto-char start)
|
|
|
|
|
(insert-char open))
|
|
|
|
|
|
|
|
|
|
(unless (use-region-p)
|
|
|
|
|
(forward-char)))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
2018-07-29 17:26:22 +00:00
|
|
|
|
*** Convert camelCase to snake_case
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(defun camel-to-snake-case (arg)
|
|
|
|
|
"Convert a camel case (camelCase or CamelCase) word to snake case (snake_case).
|
|
|
|
|
|
|
|
|
|
If the prefix argument ARG is non-nil, convert the text to uppercase."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(progn
|
|
|
|
|
(let ((start (region-beginning))
|
|
|
|
|
(end (region-end))
|
|
|
|
|
(case-fold-search nil)
|
|
|
|
|
(had-initial-underscore nil))
|
|
|
|
|
(goto-char start)
|
|
|
|
|
(when (looking-at "_") (setq had-initial-underscore t))
|
|
|
|
|
(while (re-search-forward "\\([A-Z]\\)" end t)
|
|
|
|
|
(replace-match "_\\1")
|
|
|
|
|
(setq end (1+ end)))
|
|
|
|
|
(if arg
|
|
|
|
|
(upcase-region start end)
|
|
|
|
|
(downcase-region start end))
|
|
|
|
|
(goto-char start)
|
|
|
|
|
(unless had-initial-underscore (delete-char 1)))))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
From http://pages.sachachua.com/.emacs.d/Sacha.html
|
|
|
|
|
|
|
|
|
|
#+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
|
|
|
|
|
|
|
|
|
|
Copied from http://emacs.stackexchange.com/a/27170/507
|
|
|
|
|
|
|
|
|
|
#+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
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
** File manipulation
|
|
|
|
|
|
|
|
|
|
*** Rename the current file
|
|
|
|
|
|
|
|
|
|
Copied from http://whattheemacsd.com/file-defuns.el-01.html
|
|
|
|
|
|
|
|
|
|
#+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
|
|
|
|
|
|
|
|
|
|
Copied from http://whattheemacsd.com/file-defuns.el-02.html
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(defun delete-current-buffer-file ()
|
|
|
|
|
"Remove file connected to current buffer and kill the buffer."
|
|
|
|
|
(interactive)
|
|
|
|
|
|
|
|
|
|
(let ((filename (buffer-file-name))
|
|
|
|
|
(name (buffer-name))
|
|
|
|
|
(buffer (current-buffer)))
|
|
|
|
|
(if (not (and filename (file-exists-p filename)))
|
|
|
|
|
(kill-buffer buffer)
|
|
|
|
|
(when (yes-or-no-p "Are you sure you want to remove this file? ")
|
|
|
|
|
(delete-file filename)
|
|
|
|
|
(kill-buffer buffer)
|
|
|
|
|
(message "File '%s' successfully removed" filename)))))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
*** Allow reopening the previously closed file
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(defvar gpolonkai/last-killed-buffer-file-name
|
|
|
|
|
nil
|
|
|
|
|
"The last killed buffer.
|
|
|
|
|
|
|
|
|
|
Used by `gpolonkai/kill-this-buffer' and `gpolonkai/undo-buffer-kill'.")
|
|
|
|
|
|
|
|
|
|
(defun gpolonkai/kill-this-buffer ()
|
|
|
|
|
"Kill the current buffer, but save the buffer file name so it can be undone."
|
|
|
|
|
(interactive)
|
|
|
|
|
(setq gpolonkai/last-killed-buffer-file-name (buffer-file-name))
|
|
|
|
|
(kill-this-buffer))
|
|
|
|
|
|
|
|
|
|
(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)
|
|
|
|
|
(find-file-other-window user-init-file))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
*** Open my Org-mode index file
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(defun gpolonkai/visit-org-index ()
|
|
|
|
|
"Visit the root of Org-mode notes."
|
|
|
|
|
(interactive)
|
|
|
|
|
(find-file-other-window (concat (file-name-as-directory org-directory)
|
|
|
|
|
"index.org")))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
2018-07-29 17:14:59 +00:00
|
|
|
|
** Frame manipulation
|
|
|
|
|
|
|
|
|
|
*** Hidden modeline mode
|
|
|
|
|
|
|
|
|
|
To temporarily hide the mode line.
|
|
|
|
|
|
|
|
|
|
Copied from http://emacs-doctor.com/emacs-strip-tease.html
|
|
|
|
|
|
|
|
|
|
#+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-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
|
|
|
|
|
|
|
|
|
|
** ~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 "\"\"\"")
|
|
|
|
|
(open-line-below)
|
|
|
|
|
(insert "\"\"\"")
|
|
|
|
|
(open-line-above)))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
2018-07-29 16:58:11 +00:00
|
|
|
|
** EShell related
|
|
|
|
|
|
|
|
|
|
*** Delete a character, or close ~eshell~ if nothing to delet
|
|
|
|
|
|
|
|
|
|
Copied from https://ryuslash.org/posts/C-d-to-close-eshell.html
|
|
|
|
|
|
|
|
|
|
#+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
|
2018-07-29 17:18:20 +00:00
|
|
|
|
|
|
|
|
|
** ~idm~ (ID manager) related functions
|
|
|
|
|
|
|
|
|
|
*** Get specific fields from a record in ~idm~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(defun gpolonkai/idm-record-get-field (record field)
|
|
|
|
|
"Get FIELD of an id-manager RECORD."
|
|
|
|
|
(let ((funcname (intern (concat "idm-record-" (symbol-name field)))))
|
|
|
|
|
(when (fboundp funcname)
|
|
|
|
|
(funcall funcname record))))
|
|
|
|
|
|
|
|
|
|
(defun gpolonkai/idm-get-field-for-account (account field)
|
|
|
|
|
"Get id-manager password for ACCOUNT."
|
|
|
|
|
(let ((db (idm-load-db))
|
|
|
|
|
(lookup-record nil))
|
|
|
|
|
(dolist (record (funcall db 'get-all-records) password)
|
|
|
|
|
(when (string= account (idm-record-name record))
|
|
|
|
|
(setq lookup-record (gpolonkai/idm-record-get-field record field))))
|
|
|
|
|
lookup-record))
|
|
|
|
|
|
|
|
|
|
(defmacro gpolonkai/idm-get-password-for-account (account)
|
|
|
|
|
`(gpolonkai/idm-get-field-for-account ,account 'password))
|
|
|
|
|
|
|
|
|
|
(defmacro gpolonkai/idm-get-id-for-account (account)
|
|
|
|
|
`(gpolonkai/idm-get-field-for-account ,account 'account-id))
|
|
|
|
|
#+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
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(set-face-attribute 'default t :font "Hack-10")
|
|
|
|
|
(set-frame-font "Hack-10" nil t)
|
|
|
|
|
#+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-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
|
|
|
|
|
|
|
|
|
|
** nXML
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package nxml-mode
|
|
|
|
|
:ensure nil
|
|
|
|
|
:config
|
|
|
|
|
(setq nxml-attribute-indent 4
|
|
|
|
|
nxml-child-indent 2
|
|
|
|
|
nxml-outline-child-indent 4))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** ~recentf~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package recentf
|
|
|
|
|
:ensure nil
|
|
|
|
|
:config
|
|
|
|
|
(run-at-time nil (* 5 60) 'recentf-save-list)
|
|
|
|
|
(add-to-list 'recentf-exclude (concat user-emacs-directory "elpa")))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** ~files~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package files
|
|
|
|
|
:ensure nil
|
|
|
|
|
:config
|
|
|
|
|
(setq backup-directory-alist
|
|
|
|
|
`((".*" . ,temporary-file-directory)))
|
|
|
|
|
(setq auto-save-file-name-transforms
|
|
|
|
|
`((".*" ,temporary-file-directory t))))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
2018-07-29 16:38:44 +00:00
|
|
|
|
* ~use-package~ packages
|
|
|
|
|
|
|
|
|
|
** Highlight the current line
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package hl-line
|
|
|
|
|
:config
|
|
|
|
|
(when window-system
|
|
|
|
|
(global-hl-line-mode)))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** Hide certain modes from the mode line
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package diminish
|
|
|
|
|
:defer t)
|
|
|
|
|
#+END_SRC
|
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
|
|
|
|
|
|
|
|
|
|
** 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
|
|
|
|
|
|
|
|
|
|
** Web
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package web-mode
|
|
|
|
|
:mode "\\.html?\\'"
|
|
|
|
|
:config
|
|
|
|
|
(setq web-mode-enable-auto-indentation nil)
|
|
|
|
|
(setq web-mode-enable-engine-detection t))
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** Dockerfile
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package dockerfile-mode)
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** ~.gitconfig~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package gitconfig-mode)
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
|
|
** ~.gitignore~
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
|
(use-package gitignore-mode)
|
|
|
|
|
#+END_SRC
|