dotemacs/init.el

687 lines
19 KiB
EmacsLisp

;; -*- lexical-binding: t; -*-
;; TODO - convert to use-package
;; TODO - drop cp/ prefix, use contrapunctus-, set up nameless package
;; names
;; TODO - create wrapper for
;; xref-find-definitions/xref-find-definitions-other-window
;; TODO - make ag suggest my last isearch term
;; TODO - make a completing prompt for Info manuals instead of the
;; current approach of either opening info and searching for a manual
;; or binding calls to (info "(something)") to keys.
;; TODO - add idle timer for recentf-cleanup
;; TODO - write command to deduce actions for directory based on
;; contents. e.g. if a directory has only/mostly videos, run `vlc
;; --recursive expand <dir>', mostly images - `sxiv -for <dir>', etc.
;; With prefix arg or when confused, ask for command (with
;; completion).
;; TODO - lets write something quicker to find files. Don't ask for
;; directory * - just start in the current working directory. Update
;; results as we type (after a little delay). Don't make user input
;; arguments to find(1) * - by default, search the whole path, put
;; filename matches first, path matches later.
;;
;; * maybe only with prefix arg.
;; TODO - stop desktop-save from saving my buffers - just save history etc (persp-mode?)
;; TODO - make idle timer to find all local git repos with uncommited changes
;; Reorganize into subdirectories?
;; text - org, md, tex
;; prog - lisp, lilypond
;; non-text - doc-view, emms
;; applications - eww, chronometrist, fm, irc
;; input - modal, hindi
;;;; Code:
(org-babel-load-file
(locate-user-emacs-file "init.org"))
(load "cp-ui")
(require 'atomic-chrome)
(atomic-chrome-start-server)
(setq atomic-chrome-url-major-mode-alist
'(("wikisource" . mediawiki-mode)))
(use-package emacs
:config
(setq gc-cons-threshold 100000000
delete-by-moving-to-trash t
trash-directory "~/.trash/"
history-length 1000
use-file-dialog nil))
(use-package doc-view
:config
(setq doc-view-resolution 300))
(use-package gnutls
:config
;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36749
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
(use-package ag
:ensure t
:bind
("<f2> p" . ag)
("<f2> P" . ag-project-regexp)
:config
(setq ag-highlight-search t))
(require 'cp-modal)
(require 'cp-god)
(require 'cp-chronometrist)
(use-package comint
:bind (:map comint-mode-map
("M-p" . #'comint-previous-matching-input-from-input)
("M-n" . #'comint-next-matching-input-from-input)))
(use-package company
:ensure t
:diminish company-mode
:commands global-company-mode
:init (global-company-mode)
:bind ;; ("TAB" . company-indent-or-complete-common)
(:map emacs-lisp-mode-map
("TAB" . company-indent-or-complete-common)
("C-i" . company-indent-or-complete-common)))
(use-package company-emoji
:ensure t
:if (featurep 'company)
:config (add-to-list 'company-backends 'company-emoji))
(use-package counsel
:ensure t
:bind ("M-x" . counsel-M-x)
:config
(setq counsel-find-file-ignore-regexp "\\`\\."))
;; (use-package elsa
;; :commands flycheck-elsa-setup)
(global-set-key (kbd "M-w") 'kill-ring-save)
(define-key emacs-lisp-mode-map (kbd "M-w") nil)
;; M-d is useful in the minibuffer
(define-key emacs-lisp-mode-map (kbd "M-d") nil)
(global-set-key (kbd "M-d") 'easy-kill-delete-region)
(use-package easy-kill
:disabled
:ensure t
:bind (("M-w" . easy-kill)
("M-d" . easy-kill-delete-region)))
(use-package elfeed
:bind (:map elfeed-show-mode-map
("v" . nil))
:config
(add-to-list 'boon-special-mode-list 'elfeed-show-mode)
(add-to-list 'boon-special-mode-list 'elfeed-search-mode))
(use-package hydra
:ensure t
:commands defhydra)
(require 'cp-emms)
(use-package emr
:ensure t
:bind (:map prog-mode-map
("M-S-<return>" . emr-show-refactor-menu)))
(use-package eshell
:ensure t
:config (setq eshell-history-size 999))
(use-package eww
:ensure t
:bind
(:map eww-mode-map
("b" . #'eww-back-url)
("f" . #'eww-forward-url)
("v" . nil)))
(use-package flx-ido
:disabled
:ensure t
:init (flx-ido-mode 1)
(setq ido-enable-flex-matching t
ido-use-faces nil))
(use-package flx-isearch
:disabled
:ensure t
:bind
("C-s" . #'flx-isearch-forward)
("C-r" . #'flx-isearch-backward))
;; (use-package flycheck
;; :ensure t
;; :init (global-flycheck-mode))
;; (use-package flycheck-elsa
;; :hook (emacs-lisp-mode . flycheck-elsa-setup))
(setenv "PATH" (concat "/home/anon/bin:" (getenv "PATH")))
(setenv "EDITOR" "emacsclient")
;; what on earth is this message after every init -
;; ad-handle-definition: `tramp-read-passwd' got redefined
;; ;; (profiler-start 'cpu)
;; (toggle-debug-on-error)
;; ;; (toggle-debug-on-quit)
(require 'dash)
(require 's)
(require 'visual-fill-column)
;; (add-to-list 'load-path "~/.emacs.d/elisp-git/yafolding.el/")
(add-to-list 'load-path "~/.emacs.d/user/")
(add-to-list 'load-path "~/.emacs.d/contrapunctus/")
(add-to-list 'load-path "~/.emacs.d/contrapunctus/fin/")
(add-to-list 'load-path "~/.emacs.d/contrapunctus/ido-mini/")
(load "cp")
;; (if (not (server-running-p)) (server-start))
(server-start)
(use-package general
:commands general-define-key)
;; 2017-06-09T00:24:36+0530
;; my laptop's X, W, and G keys gave up the ghost
;; temporary bindings, till my laptop keyboard is fixed
;; 2020-01-07T12:43:41+0530
;; update to use general, add M-f8 binding
(general-define-key
"<f8>" 'keyboard-quit
"M-<f8>" 'eval-defun
"M-<f9>" 'dired-jump
"<f10>" 'save-buffer
"M-<f10>" 'find-file
"<f11>" 'ido-mini
"M-<f11>" 'ibuffer
"<f12>" 'execute-extended-command
"M-<f12>" 'text-scale-adjust
"C-c C-j" 'join-line
"C-c C-r" (lambda () (interactive) (revert-buffer t t)))
;;;; UTF-8 magic
;; (setq locale-coding-system 'utf-8)
;; (set-terminal-coding-system 'utf-8)
;; (set-keyboard-coding-system 'utf-8)
;; (set-selection-coding-system 'utf-8)
;; (prefer-coding-system 'utf-8)
;;;; Linewrapping
(add-hook 'org-mode-hook 'visual-line-mode)
(add-hook 'erc-mode-hook 'visual-line-mode)
;(global-set-key (kbd "C-x t") 'toggle-truncate-lines)
(add-hook 'markdown-mode-hook 'visual-fill-column-mode)
(add-hook 'text-mode-hook 'visual-line-mode)
(load "cp-md")
(defun cp/turn-on-truncate-lines ()
;; (setq truncate-lines 1)
(toggle-truncate-lines 1))
(defun cp/add-to-hooks (function hooks)
(-map (lambda (hook)
(add-hook hook function))
hooks))
(defun cp/remove-from-hooks (function hooks)
(-map (lambda (hook)
(remove-hook hook function))
hooks))
(cp/add-to-hooks 'cp/turn-on-truncate-lines '(dired-mode-hook
prog-mode-hook
diff-mode-hook
message-mode-hook))
(global-visual-line-mode -1)
(setq truncate-partial-width-windows nil
truncate-lines t)
(add-hook 'erc-mode-hook 'visual-line-mode)
(add-hook 'comint-mode-hook 'visual-line-mode)
;; commented out on 2018-03-19T14:18:34+0530
;; (add-hook 'markdown-mode-hook 'auto-fill-mode)
;; (add-hook 'text-mode-hook 'auto-fill-mode)
;; (add-hook 'paredit-mode-hook 'auto-fill-mode)
;;;; Tab settings
;; (setq default-tab-width 4)
(setq tab-width 4)
;(define-key text-mode-map (kbd "TAB") 'self-insert-command)
(setq-default indent-tabs-mode nil)
;;;; Fix scrolling
(setq scroll-conservatively 10000
scroll-preserve-screen-position t)
(setq auto-window-vscroll nil)
;;; Recenter screen on isearch matches
(add-hook 'isearch-mode-hook 'recenter)
(add-hook 'isearch-update-post-hook 'recenter)
(defadvice isearch-repeat-forward
(after isearch-repeat-forward-recenter activate) (recenter))
(defadvice isearch-repeat-backward
(after isearch-repeat-backward-recenter activate) (recenter))
(ad-activate 'isearch-repeat-forward)
(ad-activate 'isearch-repeat-backward)
(global-set-key (kbd "C-s") 'isearch-forward-regexp)
(global-set-key (kbd "C-r") 'isearch-backward-regexp)
;;;; While we're at it, let's add that to next-error as well
;;;; (this affects jumping to match from M-x grep , too)
(add-hook 'next-error-hook 'recenter)
;;;; ...and to magit-toggle-section
;;; It'd be really cool to (recenter 3) when you /open/ a section,
;;; and (recenter) when you close a section
(defadvice magit-section-toggle
(after magit-section-toggle-recenter activate) (recenter 3))
(ad-activate 'magit-section-toggle)
(defadvice magit-unstage-item
(after magit-unstage-item-move) (next-line))
(ad-activate 'magit-unstage-item)
(defadvice magit-goto-next-section
(after magit-next-section-recenter activate) (recenter 3))
(ad-activate 'magit-goto-next-section)
(defadvice magit-goto-previous-section
(after magit-previous-section-recenter activate) (recenter 3))
(ad-activate 'magit-goto-previous-section)
(defun cp-insert-timestamp ()
(interactive)
(insert (format-time-string "%FT%T%z")))
(require 'fin)
(defun cp/eval-sexp (arg)
"In emacs-lisp-mode, just run eval-defun.
In other modes - jump to first Lisp expression in current line
and eval it."
(interactive "P")
(save-excursion
(cond ((or
(equal major-mode 'emacs-lisp-mode)
(equal major-mode 'lisp-interaction-mode))
(eval-defun arg))
((re-search-line "(")
(progn
(forward-char -1)
(forward-sexp)
(eval-last-sexp arg)))
(t nil))))
(use-package helpful
:ensure t
:bind (("<f1> <f1>" . #'helpful-at-point)
("<f1> f" . #'helpful-callable)
("<f1> c" . #'helpful-command)
("<f1> k" . #'helpful-key)
("<f1> v" . #'helpful-variable)))
(use-package ibuffer
:bind
(:map ibuffer-mode-map
("X" . 'ibuffer-do-kill-on-deletion-marks)))
(use-package info
:ensure t
:config
(info-initialize)
(--map (add-to-list #'Info-directory-list it)
'("~/.emacs.d/info/"
"~/.emacs.d/elisp-git/geiser/doc/"
"~/lilypond/usr/share/info/"))
:bind
(("<f1> i" . nil)
("<f1> i i" . info)
("<f1> i a" . info-apropos)
("<f1> i q" . (lambda () (interactive) (info "(emacs)")))
("<f1> i w" . (lambda () (interactive) (info "(elisp)")))
("<f1> i l" . (lambda () (interactive) (info "(lilypond-notation)")))
("<f1> i r" . (lambda () (interactive) (info "(lilypond-learning)")))
("<f1> i s" . (lambda () (interactive) (info "(stumpwm)")))
("<f1> i o" . (lambda () (interactive) (info "(org)")))
("<f1> i g" . (lambda () (interactive) (info "(guile)"))))
:bind
(:map Info-mode-map
("b" . Info-history-back)
("f" . Info-history-forward)))
(general-define-key
;; "s-k" 'cp-kill-buffer
"s-k" 'bury-buffer
"C-x k" 'cp-kill-buffer
"C-`" 'shell
"M-`" 'eshell
"M-<f2>" 'compile
"M-<f3>" 'run-chicken
"M-<f4>" 'run-lisp
"M-<f5>" 'ielm)
(general-define-key
:prefix "<f1>"
"M" 'describe-mode
"m" 'woman
"l" 'find-library)
(general-define-key
:prefix "<f2>"
;; "<f2>" 'imenu
"<f2>" 'xref-find-definitions
"r" 'xref-find-references
"m" 'imenu
;; "p" 'grep
"p" 'ag-regexp
"o" 'find-grep
"i" 'find-dired
"h" 'proced)
(general-define-key
:prefix "<f5>"
"<f5>" 'eval-buffer
"i" 'cp-open-init
"v" 'visual-line-mode
"f" 'cp-fcf-literally
"f" 'fundamental-mode
"t" 'text-mode
"T" 'cp-insert-timestamp
"c" 'calendar)
(general-define-key
;; [down-mouse-1] 'mouse-set-point
;; [up-mouse-1] 'er/expand-region
[s-mouse-3] 'bury-buffer
[mouse-8] 'delete-window
;; (kbd "<mouse-9>") 'keyboard-quit
;; [mouse-9] 'buffer-menu
[mouse-9] 'ibuffer
[C-mouse-9] 'recentf-open-files
[M-mouse-4] 'next-buffer
[M-mouse-5] 'previous-buffer
[M-mouse-8] 'split-window-right
[M-mouse-9] 'split-window-below
;; quitting from helm-mini - whether with keyboard-quit or
;; keyboard-escape-quit - "banishes" the mouse pointer to the
;; top-right corner!? wtf, helm.
;; (kbd "s-<mouse-9>") 'helm-mini
)
(with-eval-after-load 'help-mode
(cp-set-keys
:keymap help-mode-map
:bindings
`((,(kbd "b") help-go-back)
(,(kbd "f") help-go-forward))))
;; More convenient Unicode keys
(global-unset-key (kbd "M-["))
(cp-set-keys
:bindings
`((,(kbd "C-' r") ,(kbd ""))
(,(kbd "C-' C-r") ,(kbd ""))
(,(kbd "C-' e") ,(kbd ""))
(,(kbd "C-' b") ,(kbd ""))
(,(kbd "C-' f") ,(kbd ""))
(,(kbd "C-' p") ,(kbd ""))
(,(kbd "C-' n") ,(kbd ""))
(,(kbd "C-' l") ,(kbd "λ"))
(,(kbd "C-' F") ,(kbd "ƒ"))))
(setq default-input-method "devanagari-itrans")
(setq backup-by-copying t
backup-directory-alist '(("." . "~/.emacs.d/saves/"))
delete-old-versions t
kept-new-versions 2
kept-old-versions 2
version-control t)
(setq browse-url-browser-function 'browse-url-xdg-open)
(use-package iedit
:ensure t
:bind (("C-;" . #'iedit-mode)
("C-:" . #'iedit-mode-toggle-on-function)))
(use-package ivy
:ensure t
:commands ivy-mode
:init (ivy-mode))
(use-package jabber
:ensure t
:disabled
:commands jabber-connect
:config (global-unset-key (kbd "C-x C-j"))
(global-set-key (kbd "C-x C-j") 'join-line)
(setq jabber-history-enabled t
jabber-history-muc-enabled t
jabber-alert-presence-message-function nil))
(use-package magit
:ensure t
:bind (("<f5> m" . #'magit-status)
:map magit-status-mode-map
;; ([mouse-3] . 'magit-section-toggle)
([down-mouse-3] . 'mouse-set-point)
([up-mouse-3] . 'magit-section-toggle))
:commands magit-status
:hook
(magit-post-stage . (lambda () (recenter))))
(use-package mediawiki
:ensure t
:commands mediawiki-mode)
(use-package midnight
:ensure t
:init
(midnight-mode)
:config
(setq clean-buffer-list-kill-regexps '("")
clean-buffer-list-delay-general 7
clean-buffer-list-delay-special (* 60 60 24 7))
:hook
(midnight . clean-buffer-list))
(use-package nodejs-repl
:ensure t
:config (setq nodejs-repl-command "nodejs"))
(use-package nov
:mode ("\\.epub\\'" . nov-mode))
(use-package package
:config
(when (featurep 'boon)
(general-def package-menu-mode-map
"X" 'package-menu-execute)))
(use-package paradox
:ensure t
:bind
("<f5> p" . #'paradox-list-packages)
:config (setq paradox-execute-asynchronously t)
(when (featurep 'boon)
(general-def paradox-menu-mode-map
"X" 'package-menu-execute)))
(use-package powerline
:ensure t)
(use-package rainbow-delimiters
:ensure t
:hook (prog-mode . rainbow-delimiters-mode))
(use-package swiper
:ensure t
:bind (("C-s" . swiper)
("C-r" . swiper-backward))
:config (add-to-list 'desktop-globals-to-save 'swiper-history))
(use-package sxiv
:config (setq sxiv-exclude-strings '("meh" "\\.NEF$")))
(use-package time
:ensure t
:config
(setq display-time-next-load-average t)
(add-to-list 'zoneinfo-style-world-list '("Europe/Berlin" "Berlin")))
;; (load "cp-adb")
(load "cp-editing")
;; (load "cp-evil")
(load "cp-fm")
(load "cp-lily")
(load "cp-sfz")
(require 'cp-lisp)
(require 'cp-nav)
;; (ispell-change-dictionary "en")
(setq ispell-dictionary "en")
(use-package undo-tree
:commands global-undo-tree-mode
:ensure t
:if (not (featurep 'evil))
:diminish undo-tree-mode
:init (global-undo-tree-mode))
(with-eval-after-load 'text-mode
(define-key text-mode-map (kbd "M-p") 'org-drag-line-backward)
(define-key text-mode-map (kbd "M-n") 'org-drag-line-forward))
(autoload 'byte-recompile-file "bytecomp" "byte-recompile-file" t)
;; (2017-12-29T13:21:57+0530
;; TODO - watch Org and MD files and recompile it if they are newer
;; than their associated HTML files (e.g. I edited the source on a
;; phone and synced it back to the laptop)
;; see (info "(elisp) File Notifications")
;; and (describe-function 'file-newer-than-file-p)
;; )
(defun cp/after-save ()
(let* ((file-path (buffer-file-name))
(file-path-shell (shell-quote-argument file-path)))
(case major-mode
('org-mode (org-html-export-to-html))
('LilyPond-mode (let ((project-dir (locate-dominating-file file-path
"main.ly")))
(when project-dir
(cd project-dir))
(compile (car compile-history))))
('latex-mode (if (file-exists-p "Makefile")
(compile (car compile-history))
(compile (concat "xelatex " file-path-shell))))
;; ('markdown-mode (markdown-export))
('c-mode (compile (concat "gcc -static -o "
(shell-quote-argument
(file-name-base))
" "
file-path-shell))))))
(add-hook 'after-save-hook 'cp/after-save)
;; (load "cp-helm")
(load "cp-hindi")
;; (load "cp-irc")
(load "cp-parens")
(load "cp-playlist")
(require 'keyfreq)
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)
;; ;; disabled on 2017-08-18T19:39:21+0530, no longer interested
;; (open-dribble-file (concat "~/.emacs.d/keylogs/"
;; (format-time-string "%Y%m%d-%H%M%S")
;; ".txt"))
;; 2017-10-14T15:22:56+0530 - I suspect devanagari-itrans tires the
;; left hand faster than the right - let's find out!
(add-hook
'input-method-activate-hook
(lambda ()
(open-dribble-file
(concat
"~/.emacs.d/keylogs/"
(format-time-string "%Y%m%d-%H%M%S")
"-"
current-input-method
".txt"))))
(add-hook
'input-method-deactivate-hook
(lambda () (open-dribble-file nil)))
(use-package recentf
:init (recentf-mode 1)
:bind ("C-x C-r C-o" . recentf-open-files)
:config
(setq recentf-auto-cleanup 'never
recentf-max-menu-items 500
recentf-max-saved-items 1000
recentf-save-file "/home/anon/.emacs.d/recentf"
recentf-exclude '("\\.html\\(\\.orig\\)?$"
"\\.jpe?g$"
"\\.png$"
"\\.mp4$"
"\\.etc"
"\\.umstuff"))
:hook
(kill-emacs . recentf-cleanup))
(require 'cp-ido)
;;;; text size change
;; nicked from wasamasa's init - https://github.com/wasamasa/dotemacs/blob/934d0b37692d62fe9af56b52accac5bcd4445ae3/init.org
(setq default-frame-alist '((font . "DejaVu Sans Mono-10.5")))
(defun my-fix-emojis (&optional frame)
(set-fontset-font "fontset-default" nil "Symbola" frame 'append))
(my-fix-emojis)
(add-hook 'after-make-frame-functions 'my-fix-emojis)
;; (set-face-attribute 'default nil :font "-outline-Bitstream Vera Sans Mono-normal-normal-normal-mono-12-*-*-*-c-*-iso8859-1")
(require 'wgrep)
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)
(mapc (lambda (command)
(put command 'disabled nil))
'(downcase-region
upcase-region
set-goal-column
scroll-left
erc-remove-text-properties-region))
(require 'cp-org)
(require 'cp-desktop)
;; (toggle-debug-on-quit)
;; (profiler-stop)
;; (emacs-init-time)
;; (profiler-report)
;; Local Variables:
;; nameless-current-name: "contrapunctus"
;; End:
(provide 'init)
;;; init.el ends here