├── .gitignore ├── .gitmodules ├── README ├── config.org ├── init.el └── resources ├── auto-insert ├── 01:.*.el ├── 02:.*.erl ├── 03:.*.org ├── 04:.*.py └── 05:.*.sh ├── ditaa0_9.jar └── yasnippet-private ├── .keep └── jabber-chat-mode ├── misreading └── replace regexp /.gitignore: -------------------------------------------------------------------------------- 1 | */#*# 2 | *~ 3 | .python-environments 4 | config.el 5 | credentials.el.gpg 6 | customizations.el 7 | data 8 | dired-history 9 | elpa 10 | quelpa 11 | todo.org 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "resources/yasnippet"] 2 | path = resources/yasnippet 3 | url = https://github.com/wiedzmin/yasnippet-snippets 4 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;; GNU Emacs configuration 3 | ;; (c) Alexander Ermolov 2009-2019 4 | ;; aaermolov AT gmail.com 5 | ;; 6 | ;; Thanks to all, who has helped me in creation, especially to: 7 | ;; Alex Ott 8 | ;; Alexander Solovyov 9 | ;; Alexey Lebedev aka binarin 10 | ;; Emacswiki.org 11 | ;; Ivan Shvedunov aka ivan4th 12 | ;; Sacha Chua 13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 14 | -------------------------------------------------------------------------------- /config.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Wiedzmin's literate Emacs configuration 2 | #+OPTIONS: toc:4 h:4 3 | #+PROPERTY: header-args:conf :comments link :tangle-mode (identity #o444) 4 | 5 | * bootstrapping 6 | ** basic utils 7 | :PROPERTIES: 8 | :ID: 6384b6fd-8dd7-4e9d-a4a2-eec18757ab1e 9 | :END: 10 | It's good to have centralized working datasets storage, 11 | to prevent pollution of Emacs config directory. 12 | #+BEGIN_SRC emacs-lisp :tangle yes 13 | (use-package no-littering 14 | :ensure t 15 | :custom 16 | (no-littering-var-directory (expand-file-name "data/" user-emacs-directory))) 17 | #+END_SRC 18 | #+BEGIN_SRC emacs-lisp :tangle yes 19 | (use-package subr-x) 20 | 21 | (setq home-directory (getenv "HOME")) 22 | (setq config-basedir 23 | (file-name-directory 24 | (or (buffer-file-name) load-file-name))) 25 | 26 | (defun concat-normalize-slashes (prefix suffix) 27 | (concat "/" 28 | (string-join 29 | (split-string 30 | (string-join (list prefix suffix) "/") "/" t) "/"))) 31 | 32 | (defun at-homedir (&optional suffix) 33 | (concat-normalize-slashes home-directory suffix)) 34 | 35 | (defun at-org-dir (&optional suffix) 36 | (concat-normalize-slashes (at-homedir "/docs/org") 37 | suffix)) 38 | 39 | (defun at-org-kb-dir (&optional suffix) 40 | (concat-normalize-slashes (at-homedir "/docs/org-kb") 41 | suffix)) 42 | 43 | (defun at-config-basedir (&optional suffix) 44 | (concat-normalize-slashes config-basedir suffix)) 45 | 46 | (defun at-user-data-dir (&optional suffix) 47 | (concat-normalize-slashes no-littering-var-directory suffix)) 48 | 49 | (defun at-workspace-dir (&optional suffix) 50 | (concat-normalize-slashes (at-homedir "/workspace") suffix)) 51 | 52 | (defvar enable-experimental-packages nil) 53 | #+END_SRC 54 | ** essential packages and tweaks 55 | :PROPERTIES: 56 | :ID: f2a7ba0e-9ec0-4f97-9b28-adc923f60859 57 | :END: 58 | #+BEGIN_SRC emacs-lisp :tangle yes 59 | (load (at-config-basedir "credentials.el.gpg")) 60 | 61 | (use-package auto-compile 62 | :ensure t 63 | :config 64 | (auto-compile-on-load-mode 1) 65 | (auto-compile-on-save-mode 1) 66 | :custom 67 | (auto-compile-display-buffer nil) 68 | (auto-compile-mode-line-counter t)) 69 | 70 | (use-package f 71 | :ensure t 72 | :after (s dash)) 73 | 74 | (use-package names :ensure t) 75 | (use-package anaphora :ensure t) 76 | 77 | (use-package delight :ensure t) 78 | 79 | (use-package notifications) 80 | 81 | (use-package cus-edit 82 | :hook (kill-emacs-hook . (lambda () (delete-file custom-file))) 83 | :custom 84 | (custom-file (at-config-basedir "customizations.el"))) 85 | 86 | (use-package emacs 87 | :general 88 | ("M-\"" 'eval-region) 89 | ([remap kill-buffer] 'kill-this-buffer) 90 | :config 91 | (fset 'yes-or-no-p 'y-or-n-p) 92 | (setq scalable-fonts-allowed t) 93 | (setq use-dialog-box nil) 94 | (setq enable-recursive-minibuffers t) 95 | ;; don't let the cursor go into minibuffer prompt 96 | (setq minibuffer-prompt-properties 97 | '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)) 98 | (when (eq system-type 'gnu-linux) 99 | (setq x-alt-keysym 'meta)) 100 | (put 'downcase-region 'disabled nil) 101 | (put 'erase-buffer 'disabled nil) 102 | (put 'narrow-to-region 'disabled nil) 103 | (put 'scroll-left 'disabled nil) 104 | (put 'scroll-right 'disabled nil) 105 | (put 'upcase-region 'disabled nil) 106 | (setq scroll-preserve-screen-position 'always) 107 | ;; reduce point movement lag, see https://emacs.stackexchange.com/questions/28736/emacs-pointcursor-movement-lag/28746 108 | (setq auto-window-vscroll nil) 109 | (setq undo-limit 1000000) 110 | (advice-add 'undo-auto--last-boundary-amalgamating-number :override #'ignore) ;; https://stackoverflow.com/a/41560712/2112489 111 | (setq indent-tabs-mode nil) 112 | (set-default 'indent-tabs-mode nil);; Never insert tabs, !!!DO NOT REMOVE!!! 113 | (setq-default tab-width 4) 114 | (setq mark-even-if-inactive nil) 115 | (setq-default fill-column 200) 116 | (setq-default indicate-empty-lines t) 117 | (setq-default truncate-lines t) 118 | (setq x-stretch-cursor t) 119 | (setq user-full-name (capitalize private/real-name)) 120 | ;; print symbols 121 | (setq print-circle t) 122 | (setq print-gensym t) 123 | ;; encodings 124 | (setq locale-coding-system 'utf-8) 125 | (define-coding-system-alias 'UTF-8 'utf-8) 126 | (define-coding-system-alias 'utf-8-emacs 'utf-8) ; needed by bbdb... 127 | (define-coding-system-alias 'utf_8 'utf-8) 128 | (set-default buffer-file-coding-system 'utf-8-unix) 129 | (setq sentence-end-double-space nil) 130 | (setq tab-always-indent t) 131 | (setq frame-inhibit-implied-resize nil) 132 | (setq split-width-threshold nil) 133 | (setq split-height-threshold nil) 134 | (setq same-window-buffer-names 135 | '("*Help*"))) 136 | #+END_SRC 137 | ** input methods 138 | :PROPERTIES: 139 | :ID: 19ad65dc-243b-4d83-b4ed-c0161f35e3ae 140 | :END: 141 | Set default input method 142 | #+BEGIN_SRC emacs-lisp :tangle yes 143 | (setq default-input-method 'russian-computer) 144 | #+END_SRC 145 | Reverse input method makes Emacs with non-English system keyboard layout 146 | to behave correctly with keybindings. It definitely makes sense while 147 | using Emacs in such X WMs when there is no chance to hook into keyboard 148 | layouts switching (those are probably all, except StumpWM/XMonad, AFAIK) 149 | #+BEGIN_SRC emacs-lisp :tangle yes 150 | (use-package reverse-im 151 | :ensure t 152 | :if (not (member (getenv "CURRENT_WM") '("stumpwm" "xmonad"))) 153 | :config 154 | (reverse-im-activate "russian-computer")) 155 | #+END_SRC 156 | ** encryption and security 157 | :PROPERTIES: 158 | :ID: f23f36ac-a857-455c-9186-129925c5d5c4 159 | :END: 160 | #+BEGIN_SRC emacs-lisp :tangle yes 161 | (use-package auth-source 162 | :custom 163 | ;;TODO: investigate and setup ghub according to https://github.com/magit/ghub/blob/master/ghub.org#user-content-manually-creating-and-storing-a-token 164 | ;;TODO: check if it needed and resurrect .authinfo.gpg 165 | (auth-sources '("~/.authinfo.gpg"))) 166 | 167 | (use-package epa 168 | :after (epg) 169 | :config 170 | (epa-file-enable) 171 | :custom 172 | (epa-pinentry-mode 'loopback)) 173 | 174 | (use-package epg-config 175 | :after (epg) 176 | :custom 177 | (epg-gpg-program "gpg2") 178 | (epg-gpg-home-directory "~/.gnupg")) 179 | 180 | (use-package password-cache 181 | :custom 182 | (password-cache-expiry nil) 183 | (password-cache t)) 184 | 185 | (use-package keychain-environment 186 | :ensure t 187 | :config 188 | (keychain-refresh-environment)) 189 | #+END_SRC 190 | ** GC tweaks 191 | :PROPERTIES: 192 | :ID: f696a57b-17a7-485b-8642-c6d1431ba612 193 | :END: 194 | #+BEGIN_SRC emacs-lisp :tangle yes 195 | (setq gc-cons-percentage 0.3) 196 | 197 | (setq gc-cons-threshold most-positive-fixnum) 198 | (add-hook 'after-init-hook #'(lambda () 199 | (setq gc-cons-threshold 800000))) 200 | 201 | (add-hook 'minibuffer-setup-hook (lambda () (setq gc-cons-threshold most-positive-fixnum))) 202 | (add-hook 'minibuffer-exit-hook (lambda () (setq gc-cons-threshold 800000))) 203 | 204 | (add-hook 'focus-out-hook #'garbage-collect) 205 | #+END_SRC 206 | ** encodings 207 | :PROPERTIES: 208 | :ID: 3819b6d8-73a0-4fba-bf37-ab10e3c9f45a 209 | :END: 210 | #+BEGIN_SRC emacs-lisp :tangle yes 211 | (use-package mule 212 | :config 213 | (prefer-coding-system 'utf-8) 214 | (set-default-coding-systems 'utf-8) 215 | (set-buffer-file-coding-system 'utf-8 'utf-8-unix) 216 | (set-selection-coding-system 'utf-8) 217 | (set-terminal-coding-system 'utf-8) 218 | (set-clipboard-coding-system 'utf-8) 219 | (set-keyboard-coding-system 'utf-8)) 220 | #+END_SRC 221 | * appearance 222 | ** fonts 223 | :PROPERTIES: 224 | :ID: bd3e3e74-904d-40f2-b8e7-ed96b0d366ad 225 | :END: 226 | #+BEGIN_SRC emacs-lisp :tangle yes 227 | (use-package font-core 228 | :config 229 | (global-font-lock-mode 1)) 230 | 231 | (use-package font-lock 232 | :preface 233 | (defun custom/highlight-keywords () 234 | ;; highlight additional keywords 235 | (font-lock-add-keywords nil '(("\\<\\(FIXME\\|FIX_ME\\|FIX ME\\):" 1 font-lock-warning-face t))) 236 | (font-lock-add-keywords nil '(("\\<\\(BUG\\|BUGS\\):" 1 font-lock-warning-face t))) 237 | (font-lock-add-keywords nil '(("\\<\\(TODO\\|TO DO\\NOTE\\|TBD\\):" 1 font-lock-warning-face t))) 238 | (font-lock-add-keywords nil '(("\\<\\(DONE\\|HACK\\):" 1 font-lock-doc-face t))) 239 | ;; highlight too long lines 240 | (font-lock-add-keywords nil '(("^[^\n]\\{120\\}\\(.*\\)$" 1 font-lock-warning-face t)))) 241 | :hook ((emacs-lisp-mode-hook lisp-mode-hook python-mode-hook) . custom/highlight-keywords) 242 | :config 243 | (setq font-lock-maximum-decoration t)) 244 | 245 | (use-package face-remap 246 | :general 247 | ("C-=" 'text-scale-increase) 248 | ("C--" 'text-scale-decrease)) 249 | 250 | (use-package unicode-fonts 251 | :ensure t 252 | :after (persistent-soft) 253 | :config 254 | (unicode-fonts-setup)) 255 | #+END_SRC 256 | ** setup smart modeline 257 | :PROPERTIES: 258 | :ID: 487f7c0d-ba0c-4598-a6fa-d817a8b30ba4 259 | :END: 260 | #+BEGIN_SRC emacs-lisp :tangle yes 261 | (use-package doom-modeline 262 | :ensure t 263 | :custom 264 | (doom-modeline-height 25) 265 | (doom-modeline-icon t) 266 | (doom-modeline-major-mode-icon nil) 267 | (doom-modeline-minor-modes nil) 268 | :config 269 | (doom-modeline 1)) 270 | #+END_SRC 271 | ** load themes and choose one 272 | :PROPERTIES: 273 | :ID: 561c87c4-8d29-4a80-ac66-2dc3251cf5ca 274 | :END: 275 | Also some other good-looking theme is "material-theme" 276 | #+BEGIN_SRC emacs-lisp :tangle yes 277 | (use-package nord-theme :ensure t :config (load-theme 'nord t) :disabled) 278 | (use-package kaolin-themes :ensure t :config (load-theme 'kaolin-dark t) :disabled) 279 | (use-package hc-zenburn-theme :ensure t :config (load-theme 'hc-zenburn t)) 280 | (use-package darkburn-theme :ensure t :config (load-theme 'darkburn t) :disabled) 281 | (use-package solarized-theme :ensure t :config (load-theme 'solarized-dark t) :disabled) 282 | 283 | ;; Providing dark enough colors, unless we are using an appropriate theme, Darkburn, for example 284 | (when (boundp 'zenburn-colors-alist) 285 | (set-face-attribute 'default nil :background "#1A1A1A") 286 | (set-face-attribute 'region nil :background (cdr (assoc "zenburn-bg-2" zenburn-colors-alist)))) 287 | #+END_SRC 288 | ** frames 289 | :PROPERTIES: 290 | :ID: 8f6440cb-848f-4f09-a13a-a39cb3e18531 291 | :END: 292 | #+BEGIN_SRC emacs-lisp :tangle yes 293 | (use-package tooltip 294 | :config 295 | (tooltip-mode 0)) 296 | 297 | (use-package avoid 298 | :config 299 | (mouse-avoidance-mode 'jump)) 300 | 301 | (use-package frame 302 | :preface 303 | (defvar opacity-percent 75 "Opacity percent") 304 | (defun custom/toggle-transparency () 305 | (interactive) 306 | (let ((alpha (frame-parameter nil 'alpha))) 307 | (set-frame-parameter 308 | nil 'alpha 309 | (if (eql (cond ((numberp alpha) alpha) 310 | ((numberp (cdr alpha)) 311 | (cdr alpha)) 312 | ;; Also handle undocumented ( ) form. 313 | ((numberp (cadr alpha)) (cadr alpha))) 314 | 100) 315 | `(,opacity-percent . 50) '(100 . 100))))) 316 | :general 317 | ("M-o" 'ace-window) 318 | (:prefix "" 319 | "n" 'make-frame-command 320 | "k" 'delete-frame 321 | "s" 'delete-other-frames 322 | "v" 'custom/toggle-transparency) 323 | :config 324 | (general-unbind 'global "M-o") 325 | (add-to-list 'default-frame-alist `(alpha . (100 . 100))) 326 | (blink-cursor-mode 0) 327 | (set-frame-parameter (selected-frame) 'alpha '(100 . 100)) 328 | (setq frame-title-format "emacs - %b %f") ;; for various external tools 329 | (setq opacity-percent 75) 330 | (setq truncate-partial-width-windows nil)) 331 | 332 | (use-package tool-bar 333 | :config 334 | (tool-bar-mode -1)) 335 | 336 | (use-package scroll-bar 337 | :config 338 | (scroll-bar-mode -1) 339 | (when (>= emacs-major-version 25) 340 | (horizontal-scroll-bar-mode -1))) 341 | 342 | (use-package menu-bar 343 | :general 344 | (:keymaps 'mode-specific-map 345 | "b" 'toggle-debug-on-error 346 | "q" 'toggle-debug-on-quit) 347 | :config 348 | (menu-bar-mode -1)) 349 | 350 | (use-package popwin :ensure t) 351 | 352 | (use-package hl-line 353 | :config 354 | (global-hl-line-mode 1)) 355 | 356 | (use-package time 357 | :config 358 | (display-time) 359 | :custom 360 | (display-time-day-and-date t) 361 | ;; (display-time-form-list (list 'time 'load)) 362 | (display-time-world-list 363 | '(("Europe/Moscow" "Moscow"))) 364 | (display-time-mail-file t) 365 | (display-time-default-load-average nil) 366 | (display-time-24hr-format t) 367 | (display-time-string-forms '( day " " monthname " (" dayname ") " 24-hours ":" minutes))) 368 | #+END_SRC 369 | ** uniquify buffer names 370 | :PROPERTIES: 371 | :ID: 636ed879-e1ab-4a6a-b88e-160833520849 372 | :END: 373 | #+BEGIN_SRC emacs-lisp :tangle yes 374 | (use-package uniquify 375 | :custom 376 | (uniquify-buffer-name-style 'post-forward) 377 | (uniquify-separator ":") 378 | (uniquify-ignore-buffers-re "^\\*") 379 | (uniquify-strip-common-suffix nil)) 380 | #+END_SRC 381 | * persistence 382 | :PROPERTIES: 383 | :ID: 315c2a85-73ef-49a1-afbd-a94df7b4c16a 384 | :END: 385 | backups, history and timely saving 386 | #+BEGIN_SRC emacs-lisp :tangle yes 387 | (use-package savehist 388 | :config 389 | (savehist-mode t) 390 | :custom 391 | (savehist-save-minibuffer-history t) 392 | (savehist-autosave-interval 60) 393 | (history-length 10000) 394 | (history-delete-duplicates t) 395 | (savehist-additional-variables 396 | '(kill-ring 397 | search-ring 398 | regexp-search-ring))) 399 | 400 | (use-package backup-each-save 401 | :ensure t 402 | :hook (after-save-hook . backup-each-save)) 403 | 404 | (use-package super-save 405 | :ensure t 406 | :delight super-save-mode 407 | :custom 408 | (super-save-remote-files nil) 409 | :config 410 | (super-save-mode 1)) 411 | #+END_SRC 412 | maintain recent files 413 | #+BEGIN_SRC emacs-lisp :tangle yes 414 | (use-package recentf 415 | :no-require t 416 | :defer 1 417 | :config 418 | (use-package recentf-ext :ensure t) 419 | (add-to-list 'recentf-exclude no-littering-var-directory) 420 | (add-to-list 'recentf-exclude no-littering-etc-directory) 421 | (recentf-mode t) 422 | :custom 423 | (recentf-max-saved-items 250) 424 | (recentf-max-menu-items 15)) 425 | #+END_SRC 426 | Simultaneous edits still will be detected when saving is made. But disabling lock files prevents our working 427 | dirs from being clobbered with. 428 | #+BEGIN_SRC emacs-lisp :tangle yes 429 | (setf create-lockfiles nil) 430 | #+END_SRC 431 | * common 432 | ** emacs server 433 | :PROPERTIES: 434 | :ID: d12f1321-1005-42b2-8d96-0e55ebb5cee9 435 | :END: 436 | #+BEGIN_SRC emacs-lisp :tangle yes 437 | (use-package server 438 | :defer 2 439 | :preface 440 | (defun custom/server-save-edit () 441 | (interactive) 442 | (save-buffer) 443 | (server-edit)) 444 | (defun custom/save-buffer-clients-on-exit () 445 | (interactive) 446 | (if (and (boundp 'server-buffer-clients) server-buffer-clients) 447 | (server-save-edit) 448 | (save-buffers-kill-emacs t))) 449 | :hook (server-visit-hook . (lambda () (local-set-key (kbd "C-c C-c") 'custom/server-save-edit))) 450 | :config 451 | (unless (and (string-equal "root" (getenv "USER")) 452 | (server-running-p)) 453 | (require 'server) 454 | (server-start)) 455 | (advice-add 'save-buffers-kill-terminal :before 'custom/save-buffer-clients-on-exit)) 456 | #+END_SRC 457 | ** misc 458 | :PROPERTIES: 459 | :ID: 3b824d3a-e56f-4be5-b663-f92c7dcc81ad 460 | :END: 461 | #+BEGIN_SRC emacs-lisp :tangle yes 462 | (use-package amx 463 | :ensure t 464 | :general ("M-x" 'amx) 465 | :custom 466 | (amx-backend 'ivy) 467 | (amx-save-file (at-user-data-dir "amx-items"))) 468 | 469 | (use-package tramp 470 | :config 471 | (setq tramp-default-method "ssh") 472 | (setq tramp-ssh-controlmaster-options "") 473 | (setq tramp-default-proxies-alist nil)) 474 | 475 | (use-package paradox 476 | :ensure t 477 | :after (seq let-alist spinner) 478 | :commands paradox-list-packages 479 | :custom 480 | (paradox-execute-asynchronously t) 481 | (paradox-column-width-package 27) 482 | (paradox-column-width-version 13) 483 | (paradox-github-token private/paradox-github-token) 484 | :config 485 | (remove-hook 'paradox-after-execute-functions #'paradox--report-buffer-print)) 486 | 487 | ;; for some reason feature 'files' provided with use-package 488 | ;; brings more headache than it deserves, so a little bit of 489 | ;; dirty imperative style below (still hope on fixing it later) 490 | (defun custom/untabify-buffer () 491 | (when (member major-mode '(haskell-mode 492 | emacs-lisp-mode 493 | lisp-mode 494 | python-mode)) 495 | (untabify (point-min) (point-max)))) 496 | (add-hook 'before-save-hook #'delete-trailing-whitespace) 497 | (add-hook 'before-save-hook #'custom/untabify-buffer) 498 | (when (> emacs-major-version 25) (auto-save-visited-mode 1)) 499 | (setq require-final-newline t) 500 | (setq enable-local-variables nil) 501 | ;; backup settings 502 | (setq auto-save-default nil) 503 | (setq backup-by-copying t) 504 | (setq backup-by-copying-when-linked t) 505 | (setq backup-directory-alist '(("." . "~/.cache/emacs/backups"))) 506 | (setq delete-old-versions -1) 507 | (setq kept-new-versions 6) 508 | (setq kept-old-versions 2) 509 | (setq version-control t) 510 | (setq save-abbrevs 'silently) 511 | (global-set-key (kbd "C-x f") 'find-file) ; I never use set-fill-column and I hate hitting it by accident. 512 | 513 | (use-package novice 514 | :config 515 | (setq disabled-command-function nil)) 516 | 517 | (use-package which-key 518 | :ensure t 519 | :config 520 | (which-key-setup-side-window-right) 521 | (which-key-mode)) 522 | 523 | (use-package ibuffer 524 | :commands ibuffer 525 | :general 526 | ([remap list-buffers] 'ibuffer) 527 | (:keymaps 'ibuffer-mode-map 528 | "/ ." '(lambda (qualifier) 529 | (interactive "sFilter by extname: ") 530 | (ibuffer-filter-by-filename (concat "\\." qualifier "$"))) 531 | "M-o" 'other-window) ; was ibuffer-visit-buffer-1-window 532 | :hook (ibuffer-mode-hook . (lambda () 533 | ;; Make sure we're always using our buffer groups 534 | (ibuffer-switch-to-saved-filter-groups "default"))) 535 | :custom 536 | (ibuffer-default-sorting-mode 'major-mode) ;recency 537 | (ibuffer-always-show-last-buffer :nomini) 538 | (ibuffer-default-shrink-to-minimum-size t) 539 | (ibuffer-jump-offer-only-visible-buffers t) 540 | (ibuffer-saved-filters 541 | '(("dired" ((mode . dired-mode))) 542 | ("foss" ((filename . "foss"))) 543 | ("pets" ((filename . "pets"))) 544 | ("jabberchat" ((mode . jabber-chat-mode))) 545 | ("orgmode" ((mode . org-mode))) 546 | ("elisp" ((mode . emacs-lisp-mode))) 547 | ("fundamental" ((mode . fundamental-mode))) 548 | ("haskell" ((mode . haskell-mode))))) 549 | (ibuffer-saved-filter-groups custom/ibuffer-saved-filter-groups)) 550 | 551 | (use-package ibuffer-vc 552 | :ensure t 553 | :disabled 554 | :hook (ibuffer-hook . (lambda () 555 | (ibuffer-vc-set-filter-groups-by-vc-root) 556 | (unless (eq ibuffer-sorting-mode 'alphabetic) 557 | (ibuffer-do-sort-by-alphabetic)))) 558 | :custom 559 | (ibuffer-formats 560 | '((mark modified read-only vc-status-mini " " 561 | (name 18 18 :left :elide) 562 | " " 563 | (size 9 -1 :right) 564 | " " 565 | (mode 16 16 :left :elide) 566 | " " 567 | filename-and-process)) "include vc status info")) 568 | 569 | (use-package ibuffer-project 570 | :ensure t 571 | :hook ((ibuffer-hook . (lambda () (setq ibuffer-filter-groups (ibuffer-project-generate-filter-groups)))) 572 | (ibuffer-hook . (lambda () 573 | (setq ibuffer-filter-groups (ibuffer-project-generate-filter-groups)) 574 | (unless (eq ibuffer-sorting-mode 'project-file-relative) 575 | (ibuffer-do-sort-by-project-file-relative))))) 576 | :custom 577 | (ibuffer-formats 578 | '((mark modified read-only locked " " 579 | (name 18 18 :left :elide) 580 | " " 581 | (size 9 -1 :right) 582 | " " 583 | (mode 16 16 :left :elide) 584 | " " project-file-relative)))) 585 | #+END_SRC 586 | * navigate 587 | ** Ivy 588 | :PROPERTIES: 589 | :ID: 977de8de-42e2-478a-ad6b-6c2d87b6e47a 590 | :END: 591 | #+BEGIN_SRC emacs-lisp :tangle yes 592 | (use-package ivy 593 | :ensure t 594 | :delight ivy-mode 595 | :general 596 | ("M-" 'ivy-switch-buffer) 597 | ("" 'ivy-resume) 598 | (:keymaps 'ctl-x-map 599 | "b" 'ivy-switch-buffer) 600 | (:keymaps 'mode-specific-map 601 | "v" 'ivy-push-view 602 | "V" 'ivy-pop-view) 603 | (:keymaps 'ivy-minibuffer-map 604 | "C-j" 'ivy-immediate-done) 605 | :config 606 | (general-unbind 'global "C-x C-b") 607 | (ivy-mode 1) 608 | :custom-face 609 | (ivy-current-match ((t (:background "gray1")))) 610 | :custom 611 | (ivy-display-style 'fancy) 612 | (ivy-use-selectable-prompt t "Make the prompt line selectable") 613 | (ivy-use-virtual-buffers t) ;; add 'recentf-mode’and bookmarks to 'ivy-switch-buffer'. 614 | (ivy-height 20) ;; number of result lines to display 615 | (ivy-count-format "%d/%d ") 616 | (ivy-initial-inputs-alist nil) ;; no regexp by default 617 | (ivy-re-builders-alist 618 | ;; allow input not in order 619 | '((read-file-name-internal . ivy--regex-fuzzy) 620 | (t . ivy--regex-ignore-order)))) 621 | 622 | (use-package counsel 623 | :ensure t 624 | :defer 2 625 | :after (swiper) 626 | :delight counsel-mode 627 | :preface 628 | (defun custom/open-org-file () 629 | (interactive) 630 | (ivy-read "Org files: " 631 | (funcall #'(lambda () (f-files (at-org-dir) nil t))) 632 | :action #'(lambda (candidate) 633 | (find-file candidate)) 634 | :require-match t 635 | :caller 'custom/open-org-file)) 636 | (defun custom/open-org-kb-file () 637 | (interactive) 638 | (ivy-read "Org files: " 639 | (funcall #'(lambda () (f-files (at-org-kb-dir) nil t))) 640 | :action #'(lambda (candidate) 641 | (find-file candidate)) 642 | :require-match t 643 | :caller 'custom/open-org-kb-file)) 644 | :init 645 | (require 'iso-transl) 646 | :general 647 | ([remap menu-bar-open] 'counsel-tmm) 648 | ([remap insert-char] 'counsel-unicode-char) 649 | ([remap isearch-forward] 'counsel-grep-or-swiper) 650 | (:keymaps 'mode-specific-map 651 | "C-SPC" 'counsel-mark-ring 652 | "C-." 'counsel-fzf 653 | "w" 'counsel-wmctrl 654 | "O" 'custom/open-org-file 655 | "K" 'custom/open-org-kb-file) 656 | (:keymaps 'ctl-x-map 657 | "C-r" 'counsel-recentf) 658 | ("C-h L" 'counsel-locate) 659 | (:prefix "" 660 | "y" 'counsel-yank-pop 661 | "m" 'counsel-mark-ring 662 | "c" 'counsel-command-history 663 | "e" 'counsel-expression-history 664 | "p" 'counsel-package 665 | "l" 'counsel-git-log 666 | "g" 'counsel-rg 667 | "G" '(lambda () (interactive) (counsel-rg (thing-at-point 'symbol))) 668 | "m" 'swiper-multi 669 | "I" 'ivy-imenu-anywhere) 670 | (:keymaps 'help-map 671 | "l" 'counsel-find-library) 672 | (:prefix "" 673 | "l" 'counsel-find-library 674 | "b" 'counsel-descbinds 675 | "i" 'counsel-info-lookup-symbol) 676 | (:keymaps 'iso-transl-ctl-x-8-map 677 | "RET" 'counsel-unicode-char) 678 | (:keymaps 'ivy-minibuffer-map 679 | "M-y" 'ivy-next-line) 680 | :custom 681 | (counsel-git-cmd "rg --files") 682 | (counsel-grep-base-command "rg -i -M 120 --no-heading --line-number --color never '%s' %s") 683 | (counsel-rg-base-command "rg -i -M 120 --no-heading --line-number --color never %s .") 684 | :config 685 | (counsel-mode 1)) 686 | 687 | (use-package ivy-rich 688 | :ensure t 689 | :after (ivy) 690 | :defines ivy-rich-abbreviate-paths ivy-rich-switch-buffer-name-max-length 691 | :custom 692 | (ivy-rich-switch-buffer-name-max-length 60 "Increase max length of buffer name.") 693 | :config 694 | (ivy-rich-mode 1)) 695 | 696 | (use-package ivy-xref 697 | :ensure t 698 | :custom 699 | (xref-show-xrefs-function #'ivy-xref-show-xrefs "Use Ivy to show xrefs")) 700 | 701 | (use-package ivy-dired-history 702 | :ensure t 703 | :after (dired savehist) 704 | :config 705 | (add-to-list 'savehist-additional-variables 'ivy-dired-history-variable)) 706 | 707 | (use-package ivy-historian 708 | :ensure t 709 | :config 710 | (ivy-historian-mode)) 711 | #+END_SRC 712 | ** URLs, links and TAPs 713 | :PROPERTIES: 714 | :ID: 26a89d53-8c77-48d7-82b4-09a6acef1e6f 715 | :END: 716 | #+BEGIN_SRC emacs-lisp :tangle yes 717 | (use-package link-hint 718 | :ensure t 719 | :general 720 | (:keymaps 'mode-specific-map 721 | "o s" 'custom/open-url-current-buffer 722 | "o f" 'link-hint-open-link 723 | "o y" 'link-hint-copy-link 724 | "o F" 'link-hint-open-multiple-links 725 | "o Y" 'link-hint-copy-multiple-links) 726 | :custom 727 | (link-hint-avy-style 'de-bruijn)) 728 | 729 | (use-package browse-url 730 | :if (and (eq system-type 'gnu/linux) 731 | (eq window-system 'x)) 732 | :preface 733 | (defun custom/buffer-urls--candidates () 734 | (save-excursion 735 | (save-restriction 736 | (let ((urls)) 737 | (goto-char (point-min)) 738 | (while (re-search-forward org-plain-link-re nil t) 739 | (push (thing-at-point 'url) urls)) 740 | (remove nil urls))))) 741 | (defun custom/open-url-current-buffer () 742 | (interactive) 743 | (ivy-read "URLs: " 744 | (funcall #'custom/buffer-urls--candidates) 745 | :action #'(lambda (candidate) 746 | (browse-url candidate)) 747 | :require-match t 748 | :caller 'custom/open-url-current-buffer)) 749 | (defun feh-browse (url &rest ignore) 750 | "Browse image using feh." 751 | (interactive (browse-url-interactive-arg "URL: ")) 752 | (start-process (concat "feh " url) nil "feh" url)) 753 | (defun mpv-browse (url &rest ignore) 754 | "Browse video using mpv." 755 | (interactive (browse-url-interactive-arg "URL: ")) 756 | (start-process (concat "mpv --loop-file=inf" url) nil "mpv" "--loop-file=inf" url)) 757 | :custom 758 | (browse-url-browser-function 'browse-url-generic) 759 | (browse-url-generic-program "xdg-open") 760 | :config 761 | (setq browse-url-browser-function 762 | (append 763 | (mapcar (lambda (re) 764 | (cons re #'eww-browse-url)) 765 | private/browse-url-images-re) 766 | (mapcar (lambda (re) 767 | (cons re #'mpv-browse)) 768 | private/browse-url-videos-re) 769 | '(("." . browse-url-xdg-open))))) 770 | #+END_SRC 771 | ** cursor positioning 772 | :PROPERTIES: 773 | :ID: da45d0ec-d722-4d55-9841-912ccf83aadf 774 | :END: 775 | #+BEGIN_SRC emacs-lisp :tangle yes 776 | ;;Make cursor stay in the same column when scrolling using pgup/dn. 777 | ;;Previously pgup/dn clobbers column position, moving it to the 778 | ;;beginning of the line. 779 | ;; 780 | (defadvice custom/scroll-up (around ewd-scroll-up first act) 781 | "Keep cursor in the same column." 782 | (let ((col (current-column))) 783 | ad-do-it 784 | (move-to-column col))) 785 | (defadvice custom/scroll-down (around ewd-scroll-down first act) 786 | "Keep cursor in the same column." 787 | (let ((col (current-column))) 788 | ad-do-it 789 | (move-to-column col))) 790 | 791 | (use-package saveplace 792 | :defer 1 793 | :config 794 | (save-place-mode 1)) 795 | 796 | (use-package on-screen :ensure t) 797 | #+END_SRC 798 | ** special navigation 799 | :PROPERTIES: 800 | :ID: 96abc097-e32b-4e28-b1ab-85691f83ea61 801 | :END: 802 | #+BEGIN_SRC emacs-lisp :tangle yes 803 | (use-package beginend 804 | :ensure t 805 | :delight beginend-global-mode beginend-prog-mode beginend-magit-status-mode 806 | :config 807 | (beginend-global-mode)) 808 | 809 | (use-package mwim 810 | :ensure t 811 | :general 812 | ([remap move-beginning-of-line] 'mwim-beginning-of-code-or-line) 813 | ([remap move-end-of-line] 'mwim-end-of-code-or-line)) 814 | 815 | (use-package smooth-scrolling :ensure t) 816 | 817 | (use-package bln-mode 818 | :ensure t 819 | :general 820 | (:keymaps 'mode-specific-map 821 | "h" 'bln-backward-half 822 | "j" 'bln-forward-half-v 823 | "k" 'bln-backward-half-v 824 | "l" 'bln-forward-half)) 825 | #+END_SRC 826 | ** projects 827 | :PROPERTIES: 828 | :ID: b530ebb1-9107-4c98-a03b-c139588735f9 829 | :END: 830 | #+BEGIN_SRC emacs-lisp :tangle yes 831 | (use-package projectile 832 | :ensure t 833 | :delight (projectile-mode " prj") 834 | :custom 835 | (projectile-enable-caching t) 836 | (projectile-require-project-root nil) 837 | (projectile-completion-system 'ivy) 838 | (projectile-track-known-projects-automatically t) 839 | :config 840 | (setq projectile-switch-project-action 'projectile-commander) 841 | (projectile-mode 1)) 842 | 843 | (use-package counsel-projectile 844 | :ensure t 845 | :after (counsel projectile) 846 | :preface 847 | (defun custom/open-project-todos () 848 | (interactive) 849 | (let ((todos-file (expand-file-name "todo.org" (projectile-project-root)))) 850 | (condition-case nil 851 | (when (file-exists-p todos-file) 852 | (find-file todos-file)) 853 | (error (message "Cannot find project todos"))))) 854 | (defun custom/ensure-project-switch-buffer (arg) 855 | "Custom switch to buffer. 856 | With universal argument ARG or when not in project, rely on 857 | `ivy-switch-buffer'. 858 | Otherwise, use `counsel-projectile-switch-to-buffer'." 859 | (interactive "P") 860 | (if (or arg 861 | (not (projectile-project-p))) 862 | (ivy-switch-buffer) 863 | (counsel-projectile-switch-to-buffer))) 864 | (defun custom/search-deadgrep () 865 | (interactive) 866 | (let ((term (read-from-minibuffer "Search term: "))) 867 | (deadgrep term))) 868 | (defun counsel-projectile-switch-project-action-open-todos (project) 869 | "Open project's TODOs." 870 | (let ((projectile-switch-project-action #'custom/open-project-todos)) 871 | (counsel-projectile-switch-project-by-name project))) 872 | (defun counsel-projectile-switch-project-action-deadgrep (project) 873 | "Search in project with deadgrep." 874 | (let ((projectile-switch-project-action #'custom/search-deadgrep)) 875 | (counsel-projectile-switch-project-by-name project))) 876 | :general 877 | (:keymaps 'ctl-x-map 878 | "j j" 'counsel-projectile-switch-project 879 | "b" 'custom/ensure-project-switch-buffer) 880 | (:prefix "" 881 | "i" 'projectile-invalidate-cache 882 | "k" 'projectile-kill-buffers 883 | "c" 'projectile-commander 884 | "d" 'projectile-dired 885 | "f" 'projectile-recentf 886 | "t" 'custom/open-project-todos 887 | "T" 'doom/ivy-tasks 888 | "h" 'projectile-find-file) 889 | :config 890 | (counsel-projectile-mode 1) 891 | (add-to-list 'counsel-projectile-switch-project-action 892 | '("t" counsel-projectile-switch-project-action-open-todos "open project's todos") t) 893 | (add-to-list 'counsel-projectile-switch-project-action 894 | '("d" counsel-projectile-switch-project-action-deadgrep "search project with deadgrep") t) 895 | (setq projectile-switch-project-action 'counsel-projectile-switch-project)) 896 | #+END_SRC 897 | ** dired 898 | :PROPERTIES: 899 | :ID: c33b40eb-4d4b-44ba-9b00-5725a2af0ada 900 | :END: 901 | #+BEGIN_SRC emacs-lisp :tangle yes 902 | (use-package dired 903 | :commands dired 904 | :hook (dired-mode-hook . auto-revert-mode) 905 | :general 906 | ([remap list-directory] 'dired) 907 | (:keymaps 'dired-mode-map 908 | "e" '(lambda () 909 | (interactive) 910 | (when (derived-mode-p 'dired-mode) 911 | (if (file-directory-p (dired-get-filename)) 912 | (message "Directories cannot be opened in EWW") 913 | (eww-open-file (dired-get-file-for-visit))))) 914 | "C-x C-k" 'dired-do-delete) 915 | :preface 916 | (defvar custom/large-file-ok-types 917 | (rx "." (or "mp4" "mkv" "pdf") string-end) 918 | "Regexp matching filenames which are definitely ok to visit, 919 | even when the file is larger than `large-file-warning-threshold'.") 920 | (defadvice abort-if-file-too-large (around custom/check-large-file-ok-types) 921 | "If FILENAME matches `custom/large-file-ok-types', do not abort." 922 | (unless (string-match-p custom/large-file-ok-types (ad-get-arg 2)) 923 | ad-do-it)) 924 | :custom 925 | (dired-recursive-deletes 'top) ;; Allows recursive deletes 926 | (dired-dwim-target t) 927 | (dired-listing-switches "-lah1v --group-directories-first") ;;TODO: think of using TIME_STYLE env var 928 | :config 929 | (put 'dired-find-alternate-file 'disabled nil) 930 | (ad-activate 'abort-if-file-too-large) 931 | (use-package dired-filetype-face :ensure t) 932 | (use-package wdired 933 | :general 934 | (:keymaps 'dired-mode-map 935 | "r" 'wdired-change-to-wdired-mode) 936 | :custom 937 | (wdired-allow-to-change-permissions 'advanced)) 938 | (use-package dired-narrow 939 | :ensure t 940 | :general 941 | (:keymaps 'dired-mode-map 942 | "/" 'dired-narrow)) 943 | (use-package dired-quick-sort 944 | :ensure t 945 | :config 946 | (dired-quick-sort-setup)) 947 | (use-package diredfl 948 | :ensure t 949 | :config 950 | (diredfl-global-mode)) 951 | (use-package dired-x 952 | :config 953 | ;; do not bind C-x C-j, it may be binded later 954 | (setq dired-bind-jump nil)) 955 | (use-package dired-hide-dotfiles 956 | :ensure t 957 | :after (dired) 958 | :general 959 | (:keymaps 'dired-mode-map 960 | "." 'dired-hide-dotfiles-mode) 961 | :hook 962 | (dired-mode . dired-hide-dotfiles-mode))) 963 | 964 | ;; Reload dired after making changes 965 | (--each '(dired-do-rename 966 | dired-create-directory 967 | wdired-abort-changes) 968 | (eval `(defadvice ,it (after revert-buffer activate) 969 | (revert-buffer)))) 970 | #+END_SRC 971 | ** search 972 | :PROPERTIES: 973 | :ID: 2623e68d-5af5-4868-81d9-aab1e516026b 974 | :END: 975 | #+BEGIN_SRC emacs-lisp :tangle yes 976 | (use-package deadgrep 977 | :ensure t 978 | :commands deadgrep 979 | :general 980 | (:keymaps 'mode-specific-map 981 | "d" 'deadgrep)) 982 | 983 | (use-package socyl 984 | :ensure t 985 | :general 986 | (:keymaps 'mode-specific-map 987 | "r" 'socyl-search-regexp) 988 | :custom 989 | (socyl-backend 'ripgrep)) 990 | 991 | (use-package phi-search 992 | :ensure t 993 | :commands phi-search phi-search-backward 994 | :hook (isearch-mode-hook . phi-search-from-isearch-mc/setup-keys) 995 | :config 996 | (use-package phi-search-mc 997 | :ensure t 998 | :config 999 | (phi-search-mc/setup-keys))) 1000 | 1001 | (use-package wgrep 1002 | :ensure t 1003 | :general 1004 | (:keymaps 'grep-mode-map 1005 | "C-x C-q" 'wgrep-change-to-wgrep-mode 1006 | "C-c C-c" 'wgrep-finish-edit)) 1007 | 1008 | (defadvice occur-mode-goto-occurrence (after close-occur activate) 1009 | (delete-other-windows)) 1010 | 1011 | (use-package imenu-anywhere 1012 | :ensure t 1013 | :commands ivy-imenu-anywhere) 1014 | 1015 | ;; inline tasks navigation 1016 | (use-package doom-todo-ivy 1017 | :quelpa 1018 | (doom-todo-ivy :repo "jsmestad/doom-todo-ivy" :fetcher github) 1019 | :hook (after-init . doom-todo-ivy)) 1020 | #+END_SRC 1021 | ** operations with windows/frames 1022 | :PROPERTIES: 1023 | :ID: 3f1d854c-5c75-4a89-b266-79cc876f8b5f 1024 | :END: 1025 | #+BEGIN_SRC emacs-lisp :tangle yes 1026 | (use-package winner 1027 | :config 1028 | (winner-mode 1)) 1029 | 1030 | (use-package windsize 1031 | :ensure t 1032 | :disabled ;;TODO: remap keys and reenable 1033 | :general 1034 | ("C-s-k" 'windsize-up) 1035 | ("C-s-j" 'windsize-down) 1036 | ("C-s-h" 'windsize-left) 1037 | ("C-s-l" 'windsize-right)) 1038 | 1039 | (use-package ace-window 1040 | :ensure t 1041 | :after (avy) 1042 | :commands ace-window 1043 | :custom 1044 | (aw-background nil) 1045 | (aw-leading-char-style 'char) 1046 | (aw-scope 'visible) 1047 | :config 1048 | (ace-window-display-mode 1) 1049 | :custom-face (aw-leading-char-face 1050 | ((t (:inherit ace-jump-face-foreground 1051 | :foreground "green" 1052 | :height 0.1))))) 1053 | #+END_SRC 1054 | ** warping 1055 | :PROPERTIES: 1056 | :ID: e366a2e8-2acd-4623-b584-2f64f06d7fa4 1057 | :END: 1058 | #+BEGIN_SRC emacs-lisp :tangle yes 1059 | (use-package swiper 1060 | :ensure t 1061 | :commands swiper swiper-multi swiper-occur 1062 | :preface 1063 | (defun custom/swiper (&optional tap) 1064 | (interactive "P") 1065 | (if tap 1066 | (swiper (thing-at-point 'symbol)) 1067 | (swiper))) 1068 | :general 1069 | ("C-s" 'custom/swiper) 1070 | :config 1071 | (general-unbind 'global "C-s") 1072 | :custom 1073 | (swiper-include-line-number-in-search t) 1074 | :custom-face (swiper-match-face-1 ((t (:background "#dddddd")))) 1075 | :custom-face (swiper-match-face-2 ((t (:background "#bbbbbb" :weight bold)))) 1076 | :custom-face (swiper-match-face-3 ((t (:background "#bbbbff" :weight bold)))) 1077 | :custom-face (swiper-match-face-4 ((t (:background "#ffbbff" :weight bold))))) 1078 | 1079 | (use-package avy 1080 | :ensure t 1081 | :general 1082 | ("C-:" 'avy-goto-char) 1083 | ("M-s M-s" 'avy-goto-word-0) 1084 | :custom 1085 | (avy-timeout-seconds 0.5) 1086 | (avy-keys '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) 1087 | :custom-face (avy-goto-char-timer-face ((nil (:foreground "green" :weight bold)))) 1088 | :config 1089 | (avy-setup-default)) 1090 | 1091 | (use-package filecache) 1092 | #+END_SRC 1093 | * editing 1094 | ** move and bend text around 1095 | :PROPERTIES: 1096 | :ID: b3febdce-3124-4695-b010-9822943b04c7 1097 | :END: 1098 | #+BEGIN_SRC emacs-lisp :tangle yes 1099 | (use-package ialign 1100 | :ensure t 1101 | :general 1102 | (:keymaps 'ctl-x-map 1103 | "l" 'ialign)) 1104 | 1105 | (use-package multiple-cursors 1106 | :ensure t 1107 | :general 1108 | (:keymaps 'region-bindings-mode-map 1109 | "C-*" 'mc/mark-all-like-this 1110 | "C-S-" 'mc/mark-previous-like-this 1111 | "C-S-" 'mc/mark-next-like-this 1112 | "C-%" 'mc/mark-more-like-this-extended)) 1113 | 1114 | (use-package delsel 1115 | :general 1116 | (:keymaps 'mode-specific-map 1117 | "C-g" 'minibuffer-keyboard-quit) 1118 | :config 1119 | (delete-selection-mode 1)) 1120 | 1121 | ;;TODO: bind to keys more extensively 1122 | ;;TODO: consolidate (un)filling functionality 1123 | (use-package unfill 1124 | :ensure t 1125 | :general 1126 | ([remap fill-paragraph] 'unfill-toggle)) 1127 | 1128 | (use-package simple 1129 | :hook 1130 | (((prog-mode-hook text-mode-hook) . turn-on-auto-fill)) 1131 | :delight 1132 | ((visual-line-mode . " ↩") 1133 | (auto-fill-function . " ↵")) 1134 | :preface 1135 | (defun custom/newline-hook () 1136 | (local-set-key (kbd "C-m") 'newline-and-indent) 1137 | (local-set-key (kbd "") 'newline-and-indent)) 1138 | (defun custom/gnocchi-case (s) 1139 | "Convert S to 'gnocchi case'." 1140 | (declare (side-effect-free t)) 1141 | (s-join " " (mapcar 'downcase (s-split-words s)))) 1142 | (defun custom/switch-case (&optional style) 1143 | (interactive) 1144 | (let* ((bounds (bounds-of-thing-at-point 'symbol)) 1145 | (from (if (use-region-p) (region-beginning) (car bounds))) 1146 | (to (if (use-region-p) (region-end) (cdr bounds))) 1147 | (data (buffer-substring-no-properties from to)) 1148 | (result (funcall (cond ((eq style 'camel) 's-lower-camel-case) 1149 | ((eq style 'camel-up) 's-upper-camel-case) 1150 | ((eq style 'snake) 's-snake-case) 1151 | ((eq style 'gnocchi) 'custom/gnocchi-case) 1152 | ((eq style 'kebab) 's-dashed-words) 1153 | (t 's-lower-camel-case)) 1154 | data))) 1155 | (save-excursion 1156 | (delete-region from to) 1157 | (goto-char from) 1158 | (insert result)))) 1159 | :hook (((yaml-mode-hook emacs-lisp-mode-hook lisp-mode-hook python-mode-hook) . custom/newline-hook)) 1160 | :general 1161 | ("M-g" 'goto-line) 1162 | ("M-SPC" 'cycle-spacing) 1163 | (:prefix "" 1164 | "b" 'subword-mode 1165 | "v" 'view-mode) 1166 | (:prefix "C-z" 1167 | "o" 'just-one-space 1168 | "w" 'delete-trailing-whitespace 1169 | "s" 'transpose-sexps 1170 | "6" '(lambda () (interactive) (custom/switch-case 'camel)) 1171 | "^" '(lambda () (interactive) (custom/switch-case 'camel-up)) 1172 | "_" '(lambda () (interactive) (custom/switch-case 'snake)) 1173 | "SPC" '(lambda () (interactive) (custom/switch-case 'gnocchi)) 1174 | "-" '(lambda () (interactive) (custom/switch-case 'kebab))) 1175 | :custom 1176 | (bidi-display-reordering nil) 1177 | (kill-whole-line t) 1178 | (next-line-add-newlines nil) 1179 | (blink-matching-paren nil) 1180 | (set-mark-command-repeat-pop nil) 1181 | (save-interprogram-paste-before-kill t) 1182 | (x-gtk-use-system-tooltips nil) 1183 | (eval-expression-print-length nil) 1184 | (eval-expression-print-level nil) 1185 | (kill-ring-max 1024) 1186 | :config 1187 | (general-unbind 'global "" "C-z") 1188 | (column-number-mode 1) 1189 | (line-number-mode 1) 1190 | (size-indication-mode 1) 1191 | (toggle-truncate-lines 1) 1192 | (transient-mark-mode 1) 1193 | (put 'transient-mark-mode 'permanent-local t) 1194 | (put 'set-goal-column 'disabled nil)) 1195 | 1196 | (use-package tabify 1197 | :general 1198 | (:keymaps 'mode-specific-map 1199 | "t SPC" 'untabify 1200 | "t TAB" 'tabify)) 1201 | 1202 | (use-package sort 1203 | :general 1204 | (:keymaps 'mode-specific-map 1205 | "s s" 'sort-lines 1206 | "s u" 'delete-duplicate-lines)) 1207 | #+END_SRC 1208 | ** scope 1209 | :PROPERTIES: 1210 | :ID: 95be5ba3-1e7f-4d62-94ad-d734f064add4 1211 | :END: 1212 | #+BEGIN_SRC emacs-lisp :tangle yes 1213 | (use-package easy-kill 1214 | :ensure t 1215 | :general 1216 | ([remap kill-ring-save] 'easy-kill) 1217 | ([remap mark-sexp] 'easy-mark)) 1218 | 1219 | (use-package region-bindings-mode 1220 | :ensure t 1221 | :custom 1222 | (region-bindings-mode-disable-predicates '((lambda () buffer-read-only))) 1223 | :config 1224 | (region-bindings-mode-enable)) 1225 | 1226 | (use-package recursive-narrow 1227 | :ensure t 1228 | :general 1229 | (:keymaps 'mode-specific-map 1230 | "n r" 'narrow-to-region 1231 | "n d" 'narrow-to-defun 1232 | "n w" 'widen 1233 | "n N" 'recursive-narrow-or-widen-dwim 1234 | "n D" 'recursive-widen-dwim)) 1235 | 1236 | (use-package highlight-indent-guides 1237 | :ensure t 1238 | :general 1239 | (:keymaps 'mode-specific-map 1240 | "g h" 'highlight-indent-guides-mode) 1241 | :custom 1242 | (highlight-indent-guides-method 'fill) 1243 | (highlight-indent-guides-responsive 'stack)) 1244 | #+END_SRC 1245 | ** commenting 1246 | :PROPERTIES: 1247 | :ID: b5079d1e-1e13-4acd-92d5-25cc660dad24 1248 | :END: 1249 | #+BEGIN_SRC emacs-lisp :tangle yes 1250 | (use-package comment-dwim-2 1251 | :ensure t 1252 | :general 1253 | (:keymaps 'mode-specific-map 1254 | "]" 'comment-dwim-2)) 1255 | 1256 | (use-package newcomment 1257 | :general 1258 | (:keymaps 'mode-specific-map 1259 | "/" 'comment-box)) 1260 | #+END_SRC 1261 | ** clipboard and killring 1262 | :PROPERTIES: 1263 | :ID: 1486e40e-8c27-4ed9-8bce-83464ad35e19 1264 | :END: 1265 | #+BEGIN_SRC emacs-lisp :tangle yes 1266 | (use-package savekill :ensure t) 1267 | 1268 | (use-package copy-as-format 1269 | :ensure t 1270 | :general 1271 | (:keymaps 'mode-specific-map 1272 | "f s" 'copy-as-format-slack 1273 | "f g" 'copy-as-format-github 1274 | "f o" 'copy-as-format-org-mode 1275 | "f m" 'copy-as-format-markdown 1276 | "f a" 'copy-as-format-asciidoc 1277 | "f b" 'copy-as-format-bitbucket 1278 | "f d" 'copy-as-format-disqus 1279 | "f l" 'copy-as-format-gitlab 1280 | "f c" 'copy-as-format-hipchat 1281 | "f h" 'copy-as-format-html 1282 | "f j" 'copy-as-format-jira 1283 | "f w" 'copy-as-format-mediawiki 1284 | "f p" 'copy-as-format-pod 1285 | "f r" 'copy-as-format-rst 1286 | "f f" 'copy-as-format)) 1287 | 1288 | (use-package select 1289 | :custom 1290 | (select-enable-clipboard t) 1291 | (x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))) 1292 | #+END_SRC 1293 | ** undo/redo 1294 | :PROPERTIES: 1295 | :ID: 106282c8-1906-4508-a07e-62a831b60458 1296 | :END: 1297 | #+BEGIN_SRC emacs-lisp :tangle yes 1298 | (use-package undo-propose 1299 | :ensure t 1300 | :general 1301 | (:keymaps 'ctl-x-map 1302 | "u" 'undo-propose)) 1303 | #+END_SRC 1304 | ** spellchecking 1305 | *** flycheck 1306 | :PROPERTIES: 1307 | :ID: 4c008f67-6b4f-4e10-afb1-b36e165a7a12 1308 | :END: 1309 | #+BEGIN_SRC emacs-lisp :tangle yes 1310 | (use-package flycheck 1311 | :ensure t 1312 | :preface 1313 | ;; CREDITS: https://github.com/nathankot/dotemacs 1314 | (defvar counsel-flycheck-history nil 1315 | "History for `counsel-flycheck'") 1316 | (defun counsel-flycheck () 1317 | (interactive) 1318 | (if (not (bound-and-true-p flycheck-mode)) 1319 | (message "Flycheck mode is not available or enabled") 1320 | (ivy-read "Error: " 1321 | (let ((source-buffer (current-buffer))) 1322 | (with-current-buffer (or (get-buffer flycheck-error-list-buffer) 1323 | (progn 1324 | (with-current-buffer 1325 | (get-buffer-create flycheck-error-list-buffer) 1326 | (flycheck-error-list-mode) 1327 | (current-buffer)))) 1328 | (flycheck-error-list-set-source source-buffer) 1329 | (flycheck-error-list-reset-filter) 1330 | (revert-buffer t t t) 1331 | (split-string (buffer-string) "\n" t " *"))) 1332 | :action (lambda (s &rest _) 1333 | (-when-let* ( (error (get-text-property 0 'tabulated-list-id s)) 1334 | (pos (flycheck-error-pos error)) ) 1335 | (goto-char (flycheck-error-pos error)))) 1336 | :history 'counsel-flycheck-history))) 1337 | :general 1338 | (:keymaps 'mode-specific-map 1339 | "y" 'counsel-flycheck) 1340 | :custom-face (flycheck-warning ((t (:foreground "yellow" :background "red")))) 1341 | :custom 1342 | (flycheck-check-syntax-automatically '(mode-enabled save idle-change)) 1343 | (flycheck-display-errors-delay 0.4) 1344 | (flycheck-display-errors-function #'flycheck-display-error-messages-unless-error-list) 1345 | (flycheck-global-modes '(not emacs-lisp-mode)) 1346 | :config 1347 | (global-flycheck-mode 1)) 1348 | 1349 | (use-package flycheck-pos-tip 1350 | :ensure t 1351 | :after (flycheck) 1352 | :config 1353 | (flycheck-pos-tip-mode 1)) 1354 | #+END_SRC 1355 | **** BACKLOG review concrete checkers functionality and usage 1356 | ** utils 1357 | :PROPERTIES: 1358 | :ID: 793cf236-4c97-4a11-911a-9a64b9f89efd 1359 | :END: 1360 | #+BEGIN_SRC emacs-lisp :tangle yes 1361 | (use-package executable 1362 | :hook (after-save-hook . executable-make-buffer-file-executable-if-script-p)) 1363 | 1364 | (use-package text-mode 1365 | :hook (text-mode-hook . text-mode-hook-identify)) 1366 | 1367 | (use-package jka-cmpr-hook 1368 | :config 1369 | (auto-compression-mode 1)) 1370 | 1371 | (use-package electric 1372 | :config 1373 | (electric-indent-mode -1)) 1374 | 1375 | (use-package persistent-scratch 1376 | :ensure t 1377 | :mode ("^*scratch*$" . lisp-interaction-mode) 1378 | :hook ((after-init-hook . persistent-scratch-restore) 1379 | (kill-emacs-hook . persistent-scratch-save))) 1380 | 1381 | (use-package yatemplate 1382 | :ensure t 1383 | :after (yasnippet) 1384 | :init 1385 | (auto-insert-mode) 1386 | :custom 1387 | (yatemplate-dir (at-config-basedir "resources/auto-insert")) 1388 | :config 1389 | (yatemplate-fill-alist)) 1390 | 1391 | (use-package editorconfig 1392 | :ensure t 1393 | :delight (editorconfig-mode " EC") 1394 | :hook ((prog-mode-hook text-mode-hook) . editorconfig-mode)) 1395 | 1396 | (use-package autorevert 1397 | :defer 2 1398 | :custom 1399 | (auto-revert-verbose nil) 1400 | (global-auto-revert-non-file-buffers t) 1401 | (auto-revert-check-vc-info t) 1402 | ;; (vc-handled-backends (delq 'Git vc-handled-backends)) 1403 | ;; (vc-handled-backends nil) 1404 | :config 1405 | (global-auto-revert-mode 1)) 1406 | 1407 | (use-package kmacro 1408 | :custom 1409 | (setq kmacro-ring-max 16)) 1410 | 1411 | (use-package mwheel 1412 | :custom 1413 | (mouse-wheel-scroll-amount '(1 ((shift) . 1))) 1414 | (mouse-wheel-progressive-speed nil)) 1415 | #+END_SRC 1416 | *** whitespaces 1417 | :PROPERTIES: 1418 | :ID: 3efe6111-4b9c-42a9-9a03-0d26ec8fed58 1419 | :END: 1420 | #+BEGIN_SRC emacs-lisp :tangle yes 1421 | (use-package whitespace 1422 | :ensure t 1423 | :defer 2 1424 | :hook 1425 | ((prog-mode-hook text-mode-hook) . whitespace-turn-on) 1426 | :general 1427 | (:keymaps 'mode-specific-map 1428 | "x w" 'whitespace-mode 1429 | "x W" 'global-whitespace-mode) 1430 | :custom 1431 | (whitespace-line-column 121) 1432 | (whitespace-style '(indentation::space 1433 | space-after-tab 1434 | space-before-tab 1435 | trailing 1436 | lines-tail 1437 | tab-mark 1438 | face 1439 | tabs))) 1440 | 1441 | ;;TODO: consolidate all whitespaces utils 1442 | ;;TODO: think of activating ws-butler in some modes, just for hands-on testing 1443 | (use-package ws-butler 1444 | :ensure t 1445 | :commands ws-butler-mode) 1446 | #+END_SRC 1447 | ** major (and helper) modes 1448 | :PROPERTIES: 1449 | :ID: a525152e-b1d7-4a69-a12a-7246e1679498 1450 | :END: 1451 | #+BEGIN_SRC emacs-lisp :tangle yes 1452 | (use-package rst 1453 | :mode ("\\.rst$" . rst-mode)) 1454 | 1455 | (use-package vimrc-mode 1456 | :ensure t 1457 | :mode ((".vim\\(rc\\)?$" . vimrc-mode) 1458 | ("*pentadactyl*" . vimrc-mode))) 1459 | 1460 | (use-package sh-script 1461 | :mode (("bashrc$" . shell-script-mode) 1462 | ("bash_profile$" . shell-script-mode) 1463 | ("bash_aliases$" . shell-script-mode) 1464 | ("bash_local$" . shell-script-mode) 1465 | ("bash_completion$" . shell-script-mode) 1466 | (".powenv$" . shell-script-mode) 1467 | ("\\zsh\\'" . shell-script-mode)) 1468 | :config 1469 | ;; zsh 1470 | (setq system-uses-terminfo nil)) 1471 | 1472 | (use-package nginx-mode 1473 | :ensure t 1474 | :mode ("nginx" . nginx-mode)) 1475 | 1476 | (use-package fic-mode :ensure t) 1477 | 1478 | (use-package csv-mode 1479 | :ensure t 1480 | :mode ("\\.csv" . csv-mode) 1481 | :config 1482 | (setq-default csv-align-padding 2)) 1483 | 1484 | (use-package jinja2-mode 1485 | :ensure t 1486 | :mode ("\\.j2$" . jinja2-mode)) 1487 | 1488 | (use-package yaml-mode 1489 | :ensure t 1490 | :mode (("\\.yml\\'" . yaml-mode) 1491 | ("\\.yaml\\'" . yaml-mode))) 1492 | #+END_SRC 1493 | *** docker 1494 | :PROPERTIES: 1495 | :ID: 84391052-7b6b-4c35-b3bb-687ea1613a9b 1496 | :END: 1497 | #+BEGIN_SRC emacs-lisp :tangle yes 1498 | (use-package dockerfile-mode 1499 | :ensure t 1500 | :mode ("\\Dockerfile" . dockerfile-mode)) 1501 | 1502 | (use-package docker-compose-mode 1503 | :ensure t 1504 | :mode ("docker-compose" . docker-compose-mode)) 1505 | #+END_SRC 1506 | ** sexps 1507 | :PROPERTIES: 1508 | :ID: d4065366-b58b-4cac-a41c-432fc6e3d1ba 1509 | :END: 1510 | #+BEGIN_SRC emacs-lisp :tangle yes 1511 | (use-package smartparens 1512 | :ensure t 1513 | :after (dash) 1514 | :demand t 1515 | :hook (((prog-mode-hook yaml-mode-hook) . smartparens-mode) 1516 | ((lisp-mode-hook emacs-lisp-mode-hook markdown-mode-hook) . smartparens-strict-mode)) 1517 | :general 1518 | (:keymaps 'smartparens-mode-map 1519 | ;;TODO: try to make more brief keybindings 1520 | "C-M-t" 'sp-transpose-sexp 1521 | "M-F" nil 1522 | "M-B" nil 1523 | "M-" nil 1524 | "C-S-a" 'sp-beginning-of-sexp 1525 | "C-S-d" 'sp-end-of-sexp 1526 | ")" 'sp-up-sex 1527 | "C-" 'sp-select-previous-thing) 1528 | :config 1529 | (use-package smartparens-config) 1530 | (show-smartparens-global-mode t) 1531 | (sp-use-smartparens-bindings)) 1532 | 1533 | (use-package paren 1534 | :defer 2 1535 | :custom 1536 | (show-paren-delay 0) 1537 | :config 1538 | (show-paren-mode t)) 1539 | #+END_SRC 1540 | ** indentation 1541 | :PROPERTIES: 1542 | :ID: 26fdd8dd-8d85-4aed-9b34-99b9869ee54c 1543 | :END: 1544 | #+BEGIN_SRC emacs-lisp :tangle yes 1545 | (use-package dtrt-indent 1546 | :ensure t 1547 | :config 1548 | (dtrt-indent-mode)) 1549 | 1550 | (use-package aggressive-indent 1551 | :ensure t 1552 | :if enable-experimental-packages 1553 | :config 1554 | (global-aggressive-indent-mode 1) 1555 | (add-to-list 'aggressive-indent-excluded-modes 'html-mode) 1556 | (add-to-list 'aggressive-indent-excluded-modes 'slime-repl-mode) 1557 | (add-to-list 'aggressive-indent-excluded-modes 'haskell-mode) 1558 | (add-to-list 'aggressive-indent-excluded-modes 'lisp-mode) 1559 | (add-to-list 'aggressive-indent-excluded-modes 'emacs-lisp-mode) 1560 | (delete 'lisp-mode aggressive-indent-modes-to-prefer-defun) 1561 | (delete 'emacs-lisp-mode aggressive-indent-modes-to-prefer-defun) 1562 | (add-to-list 'aggressive-indent-dont-indent-if 1563 | '(not (null (string-match (rx (zero-or-more space) (syntax comment-start) (zero-or-more anything)) (thing-at-point 'line)))))) 1564 | 1565 | (use-package dynamic-ruler 1566 | :ensure t 1567 | :general 1568 | ("C->" 'dynamic-ruler) 1569 | ("C-^" 'dynamic-ruler-vertical)) 1570 | #+END_SRC 1571 | * completion 1572 | ** snippets 1573 | :PROPERTIES: 1574 | :ID: 82415c3d-9621-4a30-876b-f528246d9e6c 1575 | :END: 1576 | #+BEGIN_SRC emacs-lisp :tangle yes 1577 | (use-package yasnippet ;;TODO: make more declarative 1578 | :ensure t 1579 | :demand t 1580 | :delight yas-minor-mode 1581 | :mode (("yasnippet/snippets" . snippet-mode) 1582 | ("\\.yasnippet$" . snippet-mode)) 1583 | :preface 1584 | ;; hook for automatic reloading of changed snippets 1585 | (defun custom/update-yasnippets-on-save () 1586 | (when (string-match "/resources/yasnippet" buffer-file-name) 1587 | (yas-load-directory (at-config-basedir "resources/")))) 1588 | ;; Inter-field navigation 1589 | (defun custom/yas-goto-end-of-active-field () 1590 | (interactive) 1591 | (let* ((snippet (car (yas--snippets-at-point))) 1592 | (position (yas--field-end (yas--snippet-active-field snippet)))) 1593 | (if (= (point) position) 1594 | (move-end-of-line) 1595 | (goto-char position)))) 1596 | (defun custom/yas-goto-start-of-active-field () 1597 | (interactive) 1598 | (let* ((snippet (car (yas--snippets-at-point))) 1599 | (position (yas--field-start (yas--snippet-active-field snippet)))) 1600 | (if (= (point) position) 1601 | (move-beginning-of-line) 1602 | (goto-char position)))) 1603 | (defun custom/do-yas-expand () 1604 | (let ((yas/fallback-behavior 'return-nil)) 1605 | (yas/expand))) 1606 | (defun custom/tab-indent-or-complete () 1607 | (interactive) 1608 | (if (minibufferp) 1609 | (minibuffer-complete) 1610 | (if (or (not yas/minor-mode) 1611 | (null (custom/do-yas-expand))) 1612 | (if (check-expansion) 1613 | (company-complete-common) 1614 | (indent-for-tab-command))))) 1615 | :general 1616 | (:prefix "" 1617 | "v" 'yas-visit-snippet-file 1618 | "i" 'ivy-yasnippet) 1619 | (:keymaps 'yas-keymap 1620 | [(tab)] nil 1621 | [(shift tab)] nil 1622 | [backtab] nil 1623 | "TAB" nil 1624 | "" 'yas-exit-all-snippets 1625 | "C-e" 'custom/yas-goto-end-of-active-field 1626 | "C-a" 'custom/yas-goto-start-of-active-field 1627 | "C-n" 'yas-next-field-or-maybe-expand 1628 | "C-p" 'yas-prev-field) 1629 | (:keymaps 'yas-minor-mode-map 1630 | [(tab)] nil 1631 | "" nil 1632 | "TAB" nil) 1633 | :hook 1634 | (hippie-expand-try-functions-list . yas-hippie-try-expand) 1635 | (after-save-hook . custom/update-yasnippets-on-save) 1636 | :config 1637 | ;; snippets editing mode 1638 | (use-package ivy-yasnippet 1639 | :after (dash ivy yasnippet) 1640 | :ensure t) 1641 | (setq yas-snippet-dirs nil) 1642 | (push yas-installed-snippets-dir yas-snippet-dirs) 1643 | (push (at-config-basedir "resources/yasnippet/") yas-snippet-dirs) 1644 | (push (at-config-basedir "resources/yasnippet-private/") yas-snippet-dirs) 1645 | (setq yas-key-syntaxes '("w" "w_" "w_." "^ " "w_.()" yas-try-key-from-whitespace)) 1646 | (setq yas-expand-only-for-last-commands '(self-insert-command)) 1647 | (setq yas-prompt-functions 1648 | '(yas-completing-prompt 1649 | yas-x-prompt 1650 | yas-no-prompt)) 1651 | ;; Wrap around region 1652 | (setq yas-wrap-around-region t) 1653 | (yas-global-mode 1)) 1654 | #+END_SRC 1655 | **** BACKLOG try https://github.com/abrochard/org-sync-snippets 1656 | ** company 1657 | :PROPERTIES: 1658 | :ID: f265a0cd-6f51-4150-a9c5-1ee0a79bc95b 1659 | :END: 1660 | #+BEGIN_SRC emacs-lisp :tangle yes 1661 | (use-package company 1662 | :ensure t 1663 | :demand t 1664 | :delight (company-mode " γ") 1665 | :general 1666 | (:keymaps 'company-active-map 1667 | "C-n" 'company-select-next 1668 | "C-p" 'company-select-previous 1669 | "C-d" 'company-show-doc-buffer 1670 | "M-." 'company-show-location) 1671 | :custom 1672 | (company-idle-delay 0) 1673 | (company-minimum-prefix-length 2) 1674 | (company-tooltip-align-annotations t) 1675 | (company-show-numbers t) 1676 | :config 1677 | (use-package company-flx 1678 | :ensure t 1679 | :no-require t 1680 | :after (company) 1681 | :config 1682 | (company-flx-mode +1)) 1683 | (use-package company-quickhelp 1684 | :ensure t 1685 | :no-require t 1686 | :after (company) 1687 | :general 1688 | (:keymaps 'company-active-map 1689 | "C-c h" 'company-quickhelp-manual-begin) 1690 | :config 1691 | (company-quickhelp-mode 1)) 1692 | (use-package company-statistics 1693 | :ensure t 1694 | :after (company) 1695 | :config 1696 | (company-statistics-mode)) 1697 | (global-company-mode)) 1698 | #+END_SRC 1699 | *** specialized uses 1700 | **** ansible 1701 | :PROPERTIES: 1702 | :ID: 66b51149-ccb4-4e7e-8781-f099c321b6d1 1703 | :END: 1704 | #+BEGIN_SRC emacs-lisp :tangle yes 1705 | (use-package company-ansible 1706 | :ensure t 1707 | :after (company) 1708 | :config 1709 | (add-to-list 'company-backends 'company-ansible)) 1710 | 1711 | (use-package poly-ansible 1712 | :ensure t) 1713 | #+END_SRC 1714 | *** try 3rdparty packages 1715 | **** https://github.com/nsf/gocode 1716 | **** https://github.com/sebastiw/distel-completion 1717 | **** https://github.com/iquiw/company-ghc 1718 | **** https://github.com/iquiw/company-cabal 1719 | **** https://github.com/iquiw/company-restclient 1720 | **** https://github.com/Valloric/ycmd + https://github.com/abingham/emacs-ycmd 1721 | ** abbrevs 1722 | :PROPERTIES: 1723 | :ID: 47d2e50a-055b-4dc5-ab50-5a8028c34f3e 1724 | :END: 1725 | #+BEGIN_SRC emacs-lisp :tangle yes 1726 | (use-package hippie-exp 1727 | :general 1728 | ("C-S-" 'hippie-expand) 1729 | :custom 1730 | (setq hippie-expand-try-functions-list 1731 | '(yas-hippie-try-expand 1732 | try-expand-all-abbrevs 1733 | try-complete-file-name-partially 1734 | try-complete-file-name 1735 | try-expand-dabbrev 1736 | try-expand-dabbrev-from-kill 1737 | try-expand-dabbrev-all-buffers 1738 | try-expand-list 1739 | try-expand-line 1740 | try-complete-lisp-symbol-partially 1741 | try-complete-lisp-symbol))) 1742 | 1743 | (use-package abbrev 1744 | :delight (abbrev-mode " Abv") 1745 | :config 1746 | (setq-default abbrev-mode t)) 1747 | #+END_SRC 1748 | * programming 1749 | ** common 1750 | *** virtualization 1751 | :PROPERTIES: 1752 | :ID: 318076ea-2093-4a67-9879-c476ca30f85c 1753 | :END: 1754 | #+BEGIN_SRC emacs-lisp :tangle yes 1755 | (use-package docker 1756 | :ensure t 1757 | :after (dash docker-tramp s tablist json-mode) 1758 | :delight docker-mode 1759 | :custom 1760 | (docker-containers-show-all t) 1761 | :config 1762 | ;;TODO: bind keys 1763 | ;;FIXME: epkgs.docker is something another then the original - investigate this 1764 | (docker-global-mode 1)) 1765 | 1766 | (use-package docker-tramp :ensure t) 1767 | 1768 | (use-package vagrant-tramp :ensure t) 1769 | 1770 | ;;TODO: rebind to something 1771 | (use-package counsel-tramp 1772 | :ensure t 1773 | :after (docker-tramp vagrant-tramp)) 1774 | #+END_SRC 1775 | *** eldoc 1776 | :PROPERTIES: 1777 | :ID: 4c7f893f-75f5-447e-9404-4ee913bb7b29 1778 | :END: 1779 | #+BEGIN_SRC emacs-lisp :tangle yes 1780 | (use-package eldoc 1781 | :delight eldoc-mode 1782 | :hook ((emacs-lisp-mode-hook lisp-interaction-mode-hook ielm-mode-hook) . turn-on-eldoc-mode) 1783 | :custom 1784 | (eldoc-idle-delay 0)) 1785 | 1786 | (use-package c-eldoc 1787 | :ensure t 1788 | :after (eldoc) 1789 | :hook ((c-mode-hook c++-mode-hook) . c-turn-on-eldoc-mode)) 1790 | 1791 | (use-package eldoc-eval 1792 | :ensure t 1793 | :after (eldoc)) 1794 | #+END_SRC 1795 | *** packages/modes 1796 | :PROPERTIES: 1797 | :ID: eaf84ab6-e3df-4c7c-89cd-65515830664f 1798 | :END: 1799 | #+BEGIN_SRC emacs-lisp :tangle yes 1800 | ;;TODO: extend setup 1801 | (use-package compile) 1802 | (use-package multi-compile :ensure t) 1803 | 1804 | (use-package regex-tool 1805 | :ensure t 1806 | :commands regex-tool 1807 | :custom 1808 | (regex-tool-backend 'perl)) 1809 | 1810 | (use-package xr 1811 | :ensure t) 1812 | 1813 | (use-package prog-fill 1814 | :ensure t 1815 | :general 1816 | (:keymaps 'prog-mode-map 1817 | "M-q" 'prog-fill)) 1818 | 1819 | (use-package ini-mode 1820 | :ensure t 1821 | :mode ("\\.ini\\'" . ini-mode)) 1822 | 1823 | (use-package po-mode 1824 | :ensure t 1825 | :mode ("\\.po$\\|\\.po\\." . po-mode)) 1826 | 1827 | (use-package diff-mode 1828 | :mode ("diff" . diff-mode)) 1829 | 1830 | (use-package make-mode 1831 | :mode ("[Mm]akefile" . makefile-mode)) 1832 | 1833 | ;; TODO: (alex3rd) extend setup 1834 | (use-package format-all :ensure t) 1835 | 1836 | (use-package skeletor 1837 | :ensure t 1838 | :custom 1839 | (skeletor-project-directory (at-workspace-dir "pets"))) 1840 | 1841 | (use-package lsp-mode 1842 | :ensure t 1843 | :hook (lsp-after-open-hook . lsp-enable-imenu) 1844 | :custom 1845 | (lsp-message-project-root-warning t) 1846 | (lsp-inhibit-message t) 1847 | (lsp-prefer-flymake nil) 1848 | :config 1849 | (use-package lsp-clients)) 1850 | 1851 | (use-package lsp-ui 1852 | :ensure t 1853 | :after (lsp-mode) 1854 | :hook (lsp-mode-hook . lsp-ui-mode) 1855 | :general 1856 | (:keymaps 'lsp-ui-mode-map 1857 | [remap xref-find-definitions] 'lsp-ui-peek-find-definitions 1858 | [remap xref-find-references] 'lsp-ui-peek-find-references) 1859 | (:keymaps 'mode-specific-map 1860 | "R" 'lsp-restart-workspace)) 1861 | 1862 | (use-package company-lsp 1863 | :ensure t 1864 | :custom 1865 | (company-lsp-cache-candidates 'auto) 1866 | (company-lsp-async t) 1867 | (company-lsp-enable-recompletion t) 1868 | :config 1869 | (push 'company-lsp company-backends)) 1870 | #+END_SRC 1871 | ** vcs 1872 | *** git 1873 | :PROPERTIES: 1874 | :ID: 55dea188-0ba1-40da-b7b0-819246bc9500 1875 | :END: 1876 | #+BEGIN_SRC emacs-lisp :tangle yes 1877 | (use-package magit 1878 | :ensure t 1879 | :after (async dash with-editor git-commit magit-popup) 1880 | :commands magit-status magit-blame 1881 | :mode (("COMMIT_EDITMSG" . conf-javaprop-mode) 1882 | ("COMMIT" . git-commit-mode)) 1883 | :general 1884 | (:prefix "C-'" 1885 | "s" 'magit-status 1886 | "f" 'magit-log-buffer-file 1887 | "c" 'magit-checkout 1888 | "w" 'magit-diff-working-tree 1889 | "r" 'magit-reflog 1890 | "b" 'magit-blame-addition 1891 | "B" 'magit-branch-manager 1892 | "l" 'magit-log 1893 | "l" 'open-global-repos-list) 1894 | (:keymaps 'magit-status-mode-map 1895 | "E" 'magit-rebase-interactive 1896 | "q" 'custom/magit-kill-buffers) 1897 | :preface 1898 | (defun open-global-repos-list () 1899 | (interactive) 1900 | (let ((repos-buffer (get-buffer "*Magit Repositories*"))) 1901 | (if repos-buffer 1902 | (switch-to-buffer repos-buffer) 1903 | (magit-list-repositories)))) 1904 | (defun custom/magit-restore-window-configuration (&optional kill-buffer) 1905 | "Bury or kill the current buffer and restore previous window configuration." 1906 | (let ((winconf magit-previous-window-configuration) 1907 | (buffer (current-buffer)) 1908 | (frame (selected-frame))) 1909 | (quit-window kill-buffer (selected-window)) 1910 | (when (and winconf (equal frame (window-configuration-frame winconf))) 1911 | (set-window-configuration winconf) 1912 | (when (buffer-live-p buffer) 1913 | (with-current-buffer buffer 1914 | (setq magit-previous-window-configuration nil)))))) 1915 | (defun custom/magit-kill-buffers () 1916 | "Restore window configuration and kill all Magit buffers." 1917 | (interactive) 1918 | (let ((buffers (magit-mode-get-buffers))) 1919 | (magit-restore-window-configuration) 1920 | (mapc #'kill-buffer buffers))) 1921 | :custom 1922 | (magit-completing-read-function 'ivy-completing-read) 1923 | (magit-blame-heading-format "%H %-20a %C %s") 1924 | (magit-diff-refine-hunk t) 1925 | (magit-display-buffer-function 'magit-display-buffer-fullframe-status-topleft-v1) 1926 | (magit-repository-directories private/magit-repositories) 1927 | :config 1928 | (use-package magit-filenotify 1929 | :ensure t 1930 | :delight (magit-filenotify-mode " FN") 1931 | :after magit 1932 | :hook (magit-status-mode-hook . (lambda () 1933 | (condition-case nil 1934 | (magit-filenotify-mode) 1935 | (error (magit-filenotify-mode -1)))))) 1936 | (use-package vdiff-magit 1937 | :ensure t 1938 | :general 1939 | (:keymaps 'magit-mode-map 1940 | "d" 'vdiff-magit-dwim 1941 | "p" 'vdiff-magit-popup) 1942 | :config 1943 | (setcdr (assoc ?e (plist-get magit-dispatch-popup :actions)) 1944 | '("vdiff dwim" 'vdiff-magit-dwim)) 1945 | (setcdr (assoc ?E (plist-get magit-dispatch-popup :actions)) 1946 | '("vdiff popup" 'vdiff-magit-popup)))) 1947 | 1948 | (use-package magithub 1949 | :disabled 1950 | :ensure t 1951 | :after (magit) 1952 | :custom 1953 | (magithub-clone-default-directory (at-workspace-dir "foss")) 1954 | :config 1955 | (magithub-feature-autoinject t)) 1956 | 1957 | (use-package git-timemachine 1958 | :ensure t 1959 | :after (ivy) 1960 | :demand t 1961 | :preface 1962 | ;; credits to @binchen 1963 | (defun custom/git-timemachine-show-selected-revision () 1964 | "Show last (current) revision of file." 1965 | (interactive) 1966 | (let* ((collection (mapcar (lambda (rev) 1967 | ;; re-shape list for the ivy-read 1968 | (cons (concat (substring-no-properties (nth 0 rev) 0 7) "|" (nth 5 rev) "|" (nth 6 rev)) rev)) 1969 | (git-timemachine--revisions)))) 1970 | (ivy-read "commits:" 1971 | collection 1972 | :action (lambda (rev) 1973 | ;; compatible with ivy 9+ and ivy 8 1974 | (unless (string-match-p "^[a-z0-9]*$" (car rev)) 1975 | (setq rev (cdr rev))) 1976 | (git-timemachine-show-revision rev)) 1977 | :unwind (lambda () (if (not (eq last-command-event 13)) 1978 | (git-timemachine-quit)))))) 1979 | (defun custom/git-timemachine () 1980 | "Open git snapshot with the selected version. Based on ivy-mode." 1981 | (interactive) 1982 | (git-timemachine--start #'custom/git-timemachine-show-selected-revision)) 1983 | :general 1984 | (:keymaps 'mode-specific-map 1985 | ";" 'custom/git-timemachine)) 1986 | 1987 | (use-package gitignore-mode 1988 | :ensure t 1989 | :mode ("^.gitignore$" . gitignore-mode)) 1990 | 1991 | ;; think of relocating, cause it supports not only Git 1992 | (use-package diff-hl 1993 | :ensure t 1994 | :hook (magit-post-refresh-hook . diff-hl-magit-post-refresh) 1995 | :config 1996 | (global-diff-hl-mode 1)) 1997 | 1998 | (use-package git-msg-prefix 1999 | :ensure t 2000 | :general 2001 | (:keymaps 'git-commit-mode-map 2002 | "C-c i" 'commit-msg-prefix) 2003 | :custom 2004 | (git-msg-prefix-log-flags " --since='1 week ago' ") 2005 | (commit-msg-prefix-input-method 'ivy-read)) 2006 | 2007 | (use-package browse-at-remote 2008 | :ensure t 2009 | :general 2010 | (:keymaps 'mode-specific-map 2011 | "g g" 'browse-at-remote) 2012 | (:keymaps 'magit-status-mode-map 2013 | "o" 'browse-at-remote) 2014 | :custom 2015 | (browse-at-remote-prefer-symbolic nil)) 2016 | #+END_SRC 2017 | **** BACKLOG [#A] find some way (maybe smth like spacemacs dashboard) to represent the states of repos from some list (either hardcoded or created dynamically), with unstaged/unpushed/whatever_useful info displayed 2018 | *** tools 2019 | :PROPERTIES: 2020 | :ID: 32595eee-b431-4a3b-aa90-4bf77268a449 2021 | :END: 2022 | #+BEGIN_SRC emacs-lisp :tangle yes 2023 | (use-package smerge-mode 2024 | :delight (smerge-mode "∓") 2025 | :general 2026 | (:keymaps 'mode-specific-map 2027 | "g k" 'smerge-prev 2028 | "g j" 'smerge-next) 2029 | (:keymaps 'local 2030 | :predicate '(bound-and-true-p smerge-mode) 2031 | "n" 'smerge-next 2032 | "p" 'smerge-prev 2033 | "b" 'smerge-keep-base 2034 | "u" 'smerge-keep-upper 2035 | "l" 'smerge-keep-lower 2036 | "a" 'smerge-keep-all 2037 | "RET" 'smerge-keep-current 2038 | "C-m" 'smerge-keep-current 2039 | "<" 'smerge-diff-base-upper 2040 | "=" 'smerge-diff-upper-lower 2041 | ">" 'smerge-diff-base-lower 2042 | "R" 'smerge-refine 2043 | "E" 'smerge-ediff 2044 | "C" 'smerge-combine-with-next 2045 | "r" 'smerge-resolve 2046 | "k" 'smerge-kill-current 2047 | "ZZ" '(lambda () 2048 | (interactive) 2049 | (save-buffer) 2050 | (bury-buffer))) 2051 | :hook (find-file-hooks . (lambda () 2052 | (save-excursion 2053 | (goto-char (point-min)) 2054 | (when (re-search-forward "^<<<<<<< " nil t) 2055 | (smerge-mode 1)))))) 2056 | #+END_SRC 2057 | ** languages 2058 | *** common 2059 | :PROPERTIES: 2060 | :ID: d641747c-bda2-4c36-ac7f-9fbaee986ee0 2061 | :END: 2062 | #+BEGIN_SRC emacs-lisp :tangle yes 2063 | (use-package info-look) 2064 | #+END_SRC 2065 | *** elisp 2066 | :PROPERTIES: 2067 | :ID: 133554f2-800c-481d-8bcf-252753c28efd 2068 | :END: 2069 | #+BEGIN_SRC emacs-lisp :tangle yes 2070 | (use-package edebug-x :ensure t) 2071 | 2072 | (use-package elisp-slime-nav 2073 | :delight elisp-slime-nav-mode 2074 | :ensure t 2075 | :hook ((emacs-lisp-mode-hook ielm-mode-hook) . elisp-slime-nav-mode)) 2076 | 2077 | (use-package elisp-mode 2078 | :hook ((emacs-lisp-mode-hook . (lambda () 2079 | (auto-fill-mode 1) 2080 | (setq indent-tabs-mode nil) 2081 | (setq comment-start ";;") 2082 | (turn-on-eldoc-mode))))) 2083 | 2084 | (use-package company-elisp 2085 | :after (elisp-mode company) 2086 | :config 2087 | (add-to-list 'company-backends 'company-elisp)) 2088 | 2089 | (add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode) 2090 | (add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode) 2091 | 2092 | (dolist (mode '(paredit-mode smartparens-mode)) 2093 | (when (fboundp mode) 2094 | (add-hook 'eval-expression-minibuffer-setup-hook mode))) 2095 | #+END_SRC 2096 | *** lisp 2097 | :PROPERTIES: 2098 | :ID: 4aca675a-9557-41a4-8fe2-121fab08fdfd 2099 | :END: 2100 | #+BEGIN_SRC emacs-lisp :tangle yes 2101 | (use-package slime 2102 | :ensure t 2103 | :pin melpa-stable ;; corresponds to quicklisp version 2104 | :hook ((lisp-mode-hook . (lambda () 2105 | (slime-mode t) 2106 | (set (make-local-variable 'slime-lisp-implementations) 2107 | (list (assoc 'sbcl slime-lisp-implementations))))) 2108 | (inferior-lisp-mode-hook . inferior-slime-mode) 2109 | (slime-mode-hook . (lambda () (when (> emacs-major-version 25) 2110 | (slime-autodoc-mode -1)))) ;; some signature down the call stack is broken in 2.20 2111 | (lisp-mode-hook . (lambda () 2112 | (auto-fill-mode 1) 2113 | (setq indent-tabs-mode nil)))) 2114 | :init 2115 | (use-package slime-autoloads) 2116 | :custom 2117 | (slime-complete-symbol*-fancy t) 2118 | (slime-complete-symbol-function 'slime-fuzzy-complete-symbol) 2119 | (slime-net-coding-system 'utf-8-unix) 2120 | :config 2121 | (defadvice slime-documentation-lookup 2122 | (around change-browse-url-browser-function activate) 2123 | "Use w3m for slime documentation lookup." 2124 | (let ((browse-url-browser-function 'w3m-browse-url)) 2125 | ad-do-it)) 2126 | (slime-setup 2127 | '(slime-fancy-inspector slime-fancy-trace slime-fontifying-fu 2128 | slime-hyperdoc slime-package-fu slime-references slime-trace-dialog 2129 | slime-xref-browser slime-asdf slime-autodoc slime-banner slime-fancy 2130 | slime-fuzzy slime-repl slime-sbcl-exts)) 2131 | (add-to-list 'slime-lisp-implementations '(sbcl ("sbcl") :coding-system utf-8-unix))) 2132 | 2133 | ;;TODO: check if there is any conflict inconsistency between slime-builtin/company completion 2134 | (use-package slime-company 2135 | :ensure t 2136 | :after (slime company)) 2137 | 2138 | (setq custom/hyperspec-root "~/help/HyperSpec/") 2139 | 2140 | (use-package inf-lisp 2141 | :config 2142 | (setq inferior-lisp-program "sbcl")) 2143 | 2144 | (use-package common-lisp-snippets 2145 | :ensure t 2146 | :after (yasnippet)) 2147 | 2148 | ;; lookup information in hyperspec 2149 | (info-lookup-add-help 2150 | :mode 'lisp-mode 2151 | :regexp "[^][()'\" \t\n]+" 2152 | :ignore-case t 2153 | :doc-spec '(("(ansicl)Symbol Index" nil nil nil))) 2154 | #+END_SRC 2155 | *** python :review: 2156 | :PROPERTIES: 2157 | :ID: ebee8721-2700-4182-850c-cfb29daadfb8 2158 | :END: 2159 | #+BEGIN_SRC emacs-lisp :tangle yes 2160 | (use-package python 2161 | :mode ("\\.py$" . python-mode) 2162 | :hook 2163 | (python-mode-hook . (lambda () 2164 | (setq indent-tabs-mode nil) 2165 | (setq tab-width 4) 2166 | (setq imenu-create-index-function 'imenu-default-create-index-function) 2167 | (auto-fill-mode 1))) 2168 | ;; Highlight the call to ipdb, src http://pedrokroger.com/2010/07/configuring-emacs-as-a-python-ide-2/ 2169 | (python-mode-hook . (lambda () 2170 | (highlight-lines-matching-regexp "import ipdb") 2171 | (highlight-lines-matching-regexp "ipdb.set_trace()") 2172 | (highlight-lines-matching-regexp "import wdb") 2173 | (highlight-lines-matching-regexp "wdb.set_trace()"))) 2174 | (python-mode-hook . lsp) 2175 | (python-mode-hook . flycheck-mode) 2176 | :general 2177 | (:keymaps 'python-mode-map 2178 | "M-_" 'python-indent-shift-left 2179 | "M-+" 'python-indent-shift-right) 2180 | :config 2181 | (add-function :before-until (local 'eldoc-documentation-function) 2182 | #'(lambda () ""))) 2183 | 2184 | (use-package py-yapf :ensure t) 2185 | 2186 | (use-package pyvenv 2187 | :ensure t 2188 | :after (projectile dash) 2189 | :init 2190 | (defun custom/switch-python-project-context () 2191 | (let ((project-root (projectile-project-root))) 2192 | (when (-non-nil (mapcar (lambda (variant) (file-exists-p (concat project-root variant))) 2193 | '("requirements.pip" "requirements.txt"))) 2194 | (pyvenv-deactivate) 2195 | (pyvenv-activate (format "%s/%s" 2196 | (pyvenv-workon-home) 2197 | (file-name-base 2198 | (directory-file-name 2199 | project-root))))))) 2200 | :config 2201 | (pyvenv-mode 1) 2202 | :hook ((projectile-after-switch-project-hook . custom/switch-python-project-context) 2203 | (python-mode . custom/switch-python-project-context))) 2204 | 2205 | (use-package pip-requirements 2206 | :ensure t 2207 | :delight (pip-requirements-mode "PyPA Requirements") 2208 | :preface 2209 | (defun custom/pip-requirements-ignore-case () 2210 | (setq-local completion-ignore-case t)) 2211 | :mode ("requirements\\." . pip-requirements-mode) 2212 | :hook (pip-requirements-mode . custom/pip-requirements-ignore-case)) 2213 | #+END_SRC 2214 | ***** BACKLOG imports/formatting automation (search elpy/standalone extensions) 2215 | ****** isort 2216 | ***** BACKLOG fix new setup 2217 | ****** incorrect flake8 config (excludes) 2218 | ****** check/add W0512 2219 | ****** check epc/importmagic work 2220 | ****** actualize py-isort setup 2221 | ****** review pylint setup 2222 | *** golang 2223 | :PROPERTIES: 2224 | :ID: a11c0b98-c406-4f14-99c3-8ef24f4624c9 2225 | :END: 2226 | #+BEGIN_SRC emacs-lisp :tangle yes 2227 | ;;TODO: some harness either here or withoin shell to automate the burden of setting up new golang project's boilerplate 2228 | 2229 | (use-package go-mode 2230 | :ensure t 2231 | :no-require t 2232 | :after (multi-compile) 2233 | :mode ("\\.go$" . go-mode) 2234 | :hook (before-save-hook . gofmt-before-save) 2235 | :general 2236 | (:keymaps 'go-mode-map 2237 | "C-c C-c" 'multi-compile-run 2238 | "M-." 'godef-jump 2239 | "M-," 'pop-tag-mark) 2240 | :config 2241 | (use-package godoctor :ensure t) 2242 | (setq gofmt-command "goimports") 2243 | (add-to-list 'multi-compile-alist 2244 | '(go-mode . (("go-build/git" "go build -v" 2245 | (locate-dominating-file buffer-file-name ".git")) ;;TODO: try to guess binary name from project name (investigate how this refers to libraries builds, etc.) 2246 | ("go-build/main" "go build -v" 2247 | (locate-dominating-file buffer-file-name "main.go")) 2248 | ("go-build-and-run/git" "go build -v && echo '########## build finished ##########' && eval ./${PWD##*/}" 2249 | (multi-compile-locate-file-dir ".git")) 2250 | ("go-build-and-run/main" "go build -v && echo '########## build finished ##########' && eval ./${PWD##*/}" 2251 | (multi-compile-locate-file-dir "main.go")))))) 2252 | 2253 | (use-package company-go 2254 | :ensure t 2255 | :after (go-mode company) 2256 | :config 2257 | (add-to-list 'company-backends 'company-go)) 2258 | 2259 | (use-package go-guru 2260 | :ensure t 2261 | :hook (go-mode-hook . go-guru-hl-identifier-mode)) 2262 | 2263 | (use-package flycheck-gometalinter 2264 | :ensure t 2265 | :custom 2266 | ;; only run fast linters 2267 | (flycheck-gometalinter-fast t) 2268 | ;; use in tests files 2269 | (flycheck-gometalinter-test t) 2270 | (flycheck-gometalinter-deadline "10s") 2271 | ;; gometalinter: skips 'vendor' directories and sets GO15VENDOREXPERIMENT=1 2272 | (flycheck-gometalinter-vendor t) 2273 | ;; gometalinter: only enable selected linters 2274 | (flycheck-gometalinter-disable-all t) 2275 | (flycheck-gometalinter-enable-linters 2276 | '("golint" "vet" "vetshadow" "golint" "ineffassign" "goconst" "errcheck" "deadcode")) 2277 | :config 2278 | (flycheck-gometalinter-setup)) 2279 | 2280 | (use-package go-eldoc 2281 | :ensure t 2282 | :hook (go-mode-hook . go-eldoc-setup)) 2283 | 2284 | (use-package gotest 2285 | :ensure t 2286 | :after (go-mode) 2287 | :general 2288 | (:keymaps 'go-mode-map 2289 | "C-c C-x f" 'go-test-current-file 2290 | "C-c C-x t" 'go-test-current-test 2291 | "C-c C-x p" 'go-test-current-project 2292 | "C-c C-x T" 'go-test-current-benchmark 2293 | "C-c C-x F" 'go-test-current-file-benchmarks 2294 | "C-c C-x P" 'go-test-current-project-benchmarks 2295 | "C-c C-x x" 'go-run)) 2296 | 2297 | (use-package go-tag 2298 | :ensure t 2299 | :no-require t 2300 | :after (go-mode) 2301 | :general 2302 | (:keymaps 'go-mode-map 2303 | "C-c t" 'go-tag-add 2304 | "C-c T" 'go-tag-remove) 2305 | :custom 2306 | (go-tag-args '("-transform" "camelcase"))) 2307 | 2308 | (use-package go-playground 2309 | :ensure t 2310 | :after (go-mode)) 2311 | 2312 | (use-package gorepl-mode 2313 | :ensure t 2314 | :hook (go-mode-hook . gorepl-mode)) 2315 | #+END_SRC 2316 | **** BACKLOG try to integrate https://getgb.io/ 2317 | *** lua 2318 | :PROPERTIES: 2319 | :ID: 6f132b0e-a71f-467c-9dd5-5dad03db781b 2320 | :END: 2321 | #+BEGIN_SRC emacs-lisp :tangle yes 2322 | (use-package lua-mode 2323 | :ensure t 2324 | :preface 2325 | (defun lua-broken-indentation-fix () 2326 | (save-excursion 2327 | (lua-forward-line-skip-blanks 'back) 2328 | (let* ((current-indentation (current-indentation)) 2329 | (line (thing-at-point 'line t)) 2330 | (busted-p (s-matches? 2331 | (rx (+ bol (* space) 2332 | (or "context" "describe" "it" "setup" "teardown") 2333 | "(")) 2334 | line))) 2335 | (when busted-p 2336 | (+ current-indentation lua-indent-level))))) 2337 | (defun rgc-lua-calculate-indentation-override (old-function &rest arguments) 2338 | (or (lua-broken-indentation-fix) 2339 | (apply old-function arguments))) 2340 | :mode ("\\.lua$" . lua-mode) 2341 | :hook (lua-mode-hook . (lambda () 2342 | (setq flycheck-checker 'lua-luacheck))) 2343 | :config 2344 | (advice-add #'lua-calculate-indentation-override 2345 | :around #'rgc-lua-calculate-indentation-override)) 2346 | 2347 | (use-package company-lua 2348 | :ensure t 2349 | :after (lua-mode company)) 2350 | #+END_SRC 2351 | *** NixOS 2352 | :PROPERTIES: 2353 | :ID: 29ef8b65-a278-4dc7-9c8f-86c1c72ce85a 2354 | :END: 2355 | #+BEGIN_SRC emacs-lisp :tangle yes 2356 | (use-package nix-mode 2357 | :ensure t 2358 | :mode (("\\.nix$" . nix-mode) 2359 | ((rx (eval "configuration.nix") (zero-or-more anything) eol) . nix-mode))) 2360 | 2361 | (use-package company-nixos-options 2362 | :ensure t 2363 | :disabled 2364 | :config 2365 | (add-to-list 'company-backends 'company-nixos-options)) 2366 | #+END_SRC 2367 | *** Rust 2368 | :PROPERTIES: 2369 | :ID: 14b5a898-7acf-4f43-8d3c-3c86926e5bba 2370 | :END: 2371 | #+BEGIN_SRC emacs-lisp :tangle yes 2372 | (use-package rustic 2373 | :ensure t 2374 | :hook (rust-mode-hook . lsp) 2375 | :custom (rustic-rls-pkg 'lsp-mode) 2376 | :mode ("\\.rs" . rustic-mode)) 2377 | #+END_SRC 2378 | *** Clojure 2379 | :PROPERTIES: 2380 | :ID: 14b5a898-7acf-4f43-8d3c-3c86926e5bba 2381 | :END: 2382 | #+BEGIN_SRC emacs-lisp :tangle no 2383 | (use-package clojure-mode 2384 | :defer t 2385 | :config 2386 | (define-clojure-indent 2387 | (alet 'defun) 2388 | (mlet 'defun))) 2389 | 2390 | (use-package clojure-snippets 2391 | :defer t) 2392 | 2393 | (use-package cider 2394 | :defer t 2395 | ;; :custom 2396 | ;; (cider-repl-display-help-banner nil) 2397 | :config 2398 | ;; sadly, we can't use :diminish keyword here, yet 2399 | (diminish 'cider-mode 2400 | '(:eval (format " 🍏%s" (cider--modeline-info))))) 2401 | 2402 | (use-package kibit-helper 2403 | :disabled ;;TODO: setup kibit first 2404 | :defer t) 2405 | #+END_SRC 2406 | *** other 2407 | :PROPERTIES: 2408 | :ID: 14b5a898-7acf-4f43-8d3c-3c86926e5bba 2409 | :END: 2410 | Languages without much extra customization are going precisely here 2411 | #+BEGIN_SRC emacs-lisp :tangle yes 2412 | (use-package actionscript-mode 2413 | :ensure t 2414 | :mode ("\\.actionscript" . actionscript-mode)) 2415 | 2416 | (use-package json-mode 2417 | :after (json-reformat json-snatcher) 2418 | :mode ("\\.json$" . json-mode)) 2419 | 2420 | (use-package opascal 2421 | :quelpa 2422 | (opascal :repo "ki11men0w/emacs-delphi-mode" :fetcher github) 2423 | :mode ("\\.\\(pas\\|dpr\\|dpk\\)\\'" . opascal-mode) 2424 | :preface 2425 | (defun custom/enclose-by-spaces (left right) 2426 | "Insert symbols LEFT and RIGHT around a region or point." 2427 | (interactive "r") 2428 | (if (use-region-p) ; act on region 2429 | (let ((start (region-beginning)) 2430 | (end (region-end))) 2431 | (save-excursion 2432 | (goto-char end) 2433 | (insert " ") 2434 | (goto-char start) 2435 | (insert " "))) 2436 | (progn ; act around point 2437 | (insert " " " ") 2438 | (backward-char 1)))) 2439 | :general 2440 | (:keymaps 'mode-specific-map 2441 | "a" 'custom/enclose-by-spaces) 2442 | :custom 2443 | (opascal-indent-level 2) 2444 | :config 2445 | (smartparens-mode -1)) 2446 | 2447 | (use-package ccls 2448 | :ensure t 2449 | :after (lsp-mode) 2450 | :hook ((c-mode-hook c++-mode-hook objc-mode-hook) . (lambda () (require 'ccls) (lsp))) 2451 | :custom 2452 | (ccls-executable "/run/current-system/sw/bin/ccls") 2453 | :config 2454 | (setq-default flycheck-disabled-checkers '(c/c++-clang c/c++-cppcheck c/c++-gcc))) 2455 | #+END_SRC 2456 | ** webdev 2457 | *** setup 2458 | :PROPERTIES: 2459 | :ID: 73d9af60-e617-48c7-b5b2-26830d73f6b0 2460 | :END: 2461 | #+BEGIN_SRC emacs-lisp :tangle yes 2462 | (use-package sgml-mode 2463 | :general 2464 | (:keymaps 'html-mode-map 2465 | "C-c C-w" 'html-wrap-in-tag)) 2466 | 2467 | (use-package markdown-mode 2468 | :ensure t 2469 | :mode (("\\.markdown$" . markdown-mode) 2470 | ("\\.md$" . markdown-mode) 2471 | ("\\.mkd$" . markdown-mode) 2472 | ("\\.pdc$" . markdown-mode) 2473 | ("\\.README$" . markdown-mode)) 2474 | :general 2475 | (:keymaps 'markdown-mode-map 2476 | "C-c C-v" 'markdown-preview 2477 | "C-" 'yas/expand)) 2478 | 2479 | (use-package graphql-mode 2480 | :ensure t 2481 | :mode ("\\.graphql$" . graphql-mode)) 2482 | 2483 | (use-package web-mode 2484 | :ensure t 2485 | :mode (("\\.phtml\\'" . web-mode) 2486 | ("\\.tpl\\.php\\'" . web-mode) 2487 | ("\\.[agj]sp\\'" . web-mode) 2488 | ("\\.as[cp]x\\'" . web-mode) 2489 | ("\\.erb\\'" . web-mode) 2490 | ("\\.mustache\\'" . web-mode) 2491 | ("\\.djhtml\\'" . web-mode) 2492 | ("\\.html?\\'" . web-mode)) 2493 | :general 2494 | (:keymaps 'web-mode-map 2495 | "M-SPC" 'company-complete) ;; manual autocomplete 2496 | :hook (web-mode-hook . (lambda () 2497 | (set (make-local-variable 'company-backends) 2498 | '(company-tern company-web-html company-yasnippet company-files)) 2499 | (company-mode t))) 2500 | :custom 2501 | (web-mode-enable-current-element-highlight t) 2502 | (web-mode-enable-auto-closing t) 2503 | (web-mode-enable-auto-expanding t) 2504 | (web-mode-enable-auto-pairing t) 2505 | (web-mode-enable-auto-quoting t) 2506 | (web-mode-enable-css-colorization t) 2507 | (web-mode-markup-indent-offset 2) 2508 | (web-mode-code-indent-offset 2) 2509 | (web-mode-css-indent-offset 2) 2510 | :config 2511 | (use-package company-web 2512 | :ensure t 2513 | :after (company dash web-completion-data)) 2514 | (use-package web-mode-edit-element 2515 | :ensure t 2516 | :hook (web-mode-hook . web-mode-edit-element-minor-mode)) 2517 | (use-package web-narrow-mode 2518 | :ensure t 2519 | :hook (web-mode-hook . web-narrow-mode)) 2520 | (add-to-list 'web-mode-engines-alist '("django" . "\\.html\\'")) 2521 | ;; Enable JavaScript completion between etc. 2522 | ;; TODO: check why company and AC are mentioned together (see below) 2523 | (defadvice company-tern (before web-mode-set-up-ac-sources activate) 2524 | "Set `tern-mode' based on current language before running company-tern." 2525 | (message "advice") 2526 | (if (equal major-mode 'web-mode) 2527 | (let ((web-mode-cur-language 2528 | (web-mode-language-at-pos))) 2529 | (if (or (string= web-mode-cur-language "javascript") 2530 | (string= web-mode-cur-language "jsx") 2531 | ) 2532 | (unless tern-mode (tern-mode)) 2533 | (if tern-mode (tern-mode -1))))))) 2534 | 2535 | (use-package css-mode 2536 | :mode ("\\.scss$" . css-mode)) 2537 | 2538 | (use-package css-eldoc 2539 | :ensure t 2540 | :after (eldoc) 2541 | :hook (css-mode-hook . turn-on-css-eldoc)) 2542 | #+END_SRC 2543 | *** color helper 2544 | :PROPERTIES: 2545 | :ID: 0d387fc8-4354-42cc-911b-c316221a228e 2546 | :END: 2547 | #+BEGIN_SRC emacs-lisp :tangle yes 2548 | (use-package rainbow-mode 2549 | :ensure t 2550 | :hook (css-mode-hook . rainbow-mode)) 2551 | #+END_SRC 2552 | *** emmet mode setup 2553 | :PROPERTIES: 2554 | :ID: dca077a3-6d96-4286-be6b-49edfec189ca 2555 | :END: 2556 | #+BEGIN_SRC emacs-lisp :tangle yes 2557 | (use-package emmet-mode 2558 | :ensure t 2559 | :delight emmet-mode 2560 | :commands emmet-mode 2561 | :general 2562 | (:keymaps 'emmet-mode-keymap 2563 | "C-j" nil 2564 | "" nil 2565 | "C-c C-j" 'emmet-expand-line) 2566 | :hook ((sgml-mode-hook nxml-mode-hook django-mode sgml-mode-hook css-mode-hook) . emmet-mode) 2567 | :custom 2568 | (emmet-move-cursor-between-quotes t) 2569 | (emmet-indentation 2)) 2570 | #+END_SRC 2571 | * clients 2572 | ** restclient 2573 | :PROPERTIES: 2574 | :ID: 628303d1-2a9b-48e9-b2f9-9797d652e2d8 2575 | :END: 2576 | #+BEGIN_SRC emacs-lisp :tangle yes 2577 | (use-package company-restclient 2578 | :ensure t 2579 | :after (restclient company)) 2580 | 2581 | (use-package ob-restclient 2582 | :ensure t 2583 | :after (ob restclient) 2584 | :commands (org-babel-execute:restclient)) 2585 | 2586 | (use-package httprepl :ensure t) 2587 | #+END_SRC 2588 | ** tmux 2589 | :PROPERTIES: 2590 | :ID: dbced8f9-5c3e-4408-854f-99aa26bf3d52 2591 | :END: 2592 | #+BEGIN_SRC emacs-lisp :tangle yes 2593 | (use-package emamux 2594 | :ensure t 2595 | :general 2596 | (:prefix "" 2597 | "n" 'emamux:new-window 2598 | "s" 'emamux:send-region 2599 | "r" 'emamux:run-command)) 2600 | #+END_SRC 2601 | ** internal browser (w3m/eww) 2602 | :PROPERTIES: 2603 | :ID: 5b5a4f9f-0802-4b4a-b6c3-55562ac635cf 2604 | :END: 2605 | #+BEGIN_SRC emacs-lisp :tangle yes 2606 | (use-package w3m 2607 | :ensure t 2608 | :commands w3m 2609 | :hook (w3m-display-hook . (lambda (url) 2610 | (rename-buffer 2611 | (format "*w3m: %s*" (or w3m-current-title 2612 | w3m-current-url)) t))) 2613 | :custom 2614 | (w3m-coding-system 'utf-8) 2615 | (w3m-file-coding-system 'utf-8) 2616 | (w3m-file-name-coding-system 'utf-8) 2617 | (w3m-input-coding-system 'utf-8) 2618 | (w3m-output-coding-system 'utf-8) 2619 | (w3m-terminal-coding-system 'utf-8) 2620 | (w3m-use-cookies t) 2621 | :config 2622 | ;; special chars 2623 | (standard-display-ascii ?\200 [15]) 2624 | (standard-display-ascii ?\201 [21]) 2625 | (standard-display-ascii ?\202 [24]) 2626 | (standard-display-ascii ?\203 [13]) 2627 | (standard-display-ascii ?\204 [22]) 2628 | (standard-display-ascii ?\205 [25]) 2629 | (standard-display-ascii ?\206 [12]) 2630 | (standard-display-ascii ?\210 [23]) 2631 | (standard-display-ascii ?\211 [14]) 2632 | (standard-display-ascii ?\212 [18]) 2633 | (standard-display-ascii ?\214 [11]) 2634 | (standard-display-ascii ?\222 [?\']) 2635 | (standard-display-ascii ?\223 [?\"]) 2636 | (standard-display-ascii ?\224 [?\"]) 2637 | (standard-display-ascii ?\227 " -- ")) 2638 | 2639 | (use-package w3m-search 2640 | :after (w3m) 2641 | :config 2642 | (add-to-list 'w3m-search-engine-alist 2643 | '("emacs-wiki" "http://www.emacswiki.org/cgi-bin/wiki.pl?search=%s"))) 2644 | 2645 | (use-package eww 2646 | :preface 2647 | (defun eww-more-readable () ;;TODO: add to appropriate hook 2648 | "Makes eww more pleasant to use. Run it after eww buffer is loaded." 2649 | (interactive) 2650 | (setq eww-header-line-format nil) ;; removes page title 2651 | (setq mode-line-format nil) ;; removes mode-line 2652 | (set-window-margins (get-buffer-window) 20 20) ;; increases size of margins 2653 | (redraw-display) ;; apply mode-line changes 2654 | (eww-reload 'local))) ;; apply eww-header changes 2655 | #+END_SRC 2656 | ** open ebooks internally 2657 | :PROPERTIES: 2658 | :ID: 27a0775b-b056-4eb1-80e2-086bc44cb8b8 2659 | :END: 2660 | #+BEGIN_SRC emacs-lisp :tangle yes 2661 | (use-package pdf-tools 2662 | :ensure t 2663 | :hook ((pdf-view-mode-hook . (pdf-links-minor-mode 2664 | pdf-outline-minor-mode)) 2665 | (after-init-hook . pdf-tools-install)) 2666 | :config 2667 | (use-package pdf-view 2668 | :ensure nil 2669 | :mode ("\\.pdf$" . pdf-view-mode) 2670 | ;; :magic ("%PDF" . pdf-view-mode) 2671 | :preface 2672 | (defun custom/scroll-other-window (&optional arg) 2673 | (interactive "P") 2674 | (awhen (ignore-errors (other-window-for-scrolling)) 2675 | (let* ((buffer (window-buffer it)) 2676 | (mode (with-current-buffer buffer major-mode))) 2677 | (cond 2678 | ((eq mode 'pdf-view-mode) 2679 | (save-selected-window 2680 | (select-window it) 2681 | (with-current-buffer buffer 2682 | (pdf-view-next-page (cond ((eq arg '-) -1) 2683 | ((numberp arg) arg) 2684 | (t 1)))))) 2685 | (t (scroll-other-window arg)))))) 2686 | :general 2687 | ("C-M-v" 'custom/scroll-other-window) 2688 | (:keymaps 'pdf-view-mode-map 2689 | "C-s" 'isearch-forward 2690 | "h" 'pdf-annot-add-highlight-markup-annotation 2691 | "t" 'pdf-annot-add-text-annotation 2692 | "y" 'pdf-view-kill-ring-save 2693 | "D" 'pdf-annot-delete) 2694 | :hook ((after-init-hook . pdf-tools-install) 2695 | (pdf-view-mode-hook . pdf-isearch-minor-mode) 2696 | ;; (pdf-tools-enabled-hook . pdf-view-midnight-minor-mode) 2697 | (pdf-view-mode-hook . (lambda () (cua-mode -1)))) ;; turn off cua so copy works 2698 | :custom 2699 | (pdf-view-midnight-colors (quote ("white smoke" . "#002b36"))) ;; more brightness in midnight mode 2700 | (pdf-view-resize-factor 1.1) ;; more fine-grained zooming 2701 | (pdf-view-display-size 'fit-page)) 2702 | (use-package pdf-annot 2703 | :ensure nil 2704 | :general 2705 | (:keymaps 'pdf-annot-edit-contents-minor-mode-map 2706 | "" 'pdf-annot-edit-contents-commit 2707 | "" 'newline) 2708 | :custom 2709 | (pdf-annot-activate-created-annotations t) 2710 | :config 2711 | (advice-add 'pdf-annot-edit-contents-commit :after 'save-buffer))) 2712 | #+END_SRC 2713 | ** email 2714 | *** common 2715 | :PROPERTIES: 2716 | :ID: 5b4ffaf1-14e1-4ecb-b08f-9bbf3be90413 2717 | :END: 2718 | #+BEGIN_SRC emacs-lisp :tangle yes 2719 | (use-package footnote) 2720 | 2721 | (use-package sendmail 2722 | :custom 2723 | (mail-specify-envelope-from t) 2724 | (mail-envelope-from 'header) 2725 | (send-mail-function 'sendmail-send-it)) 2726 | 2727 | (use-package message 2728 | :hook (message-mode-hook . turn-on-orgtbl) 2729 | :custom 2730 | (message-sendmail-envelope-from 'header) 2731 | (message-kill-buffer-on-exit t)) 2732 | #+END_SRC 2733 | *** notmuch 2734 | :PROPERTIES: 2735 | :ID: 18ebc99a-8bc4-4f0b-9e11-9b388c9170d6 2736 | :END: 2737 | #+BEGIN_SRC emacs-lisp :tangle yes 2738 | (use-package notmuch 2739 | :ensure t 2740 | :no-require t 2741 | :commands notmuch 2742 | :general 2743 | (:keymaps 'notmuch-search-mode-map 2744 | "!" '(lambda () 2745 | "toggle unread tag for thread" 2746 | (interactive) 2747 | (if (member "unread" (notmuch-search-get-tags)) 2748 | (notmuch-search-tag '("-unread" "-spam")) 2749 | (notmuch-search-tag '("+unread")))) 2750 | "g" 'notmuch-refresh-this-buffer) 2751 | (:keymaps 'notmuch-message-mode-map 2752 | "#" 'mml-attach-file) 2753 | (:keymaps 'mode-specific-map 2754 | "4 n" 'notmuch 2755 | "4 N" 'counsel-notmuch) 2756 | :hook ((notmuch-hello-refresh-hook . (lambda () 2757 | (if (and (eq (point) (point-min)) 2758 | (search-forward "Saved searches:" nil t)) 2759 | (progn 2760 | (forward-line) 2761 | (widget-forward 1)) 2762 | (if (eq (widget-type (widget-at)) 'editable-field) 2763 | (beginning-of-line))))) 2764 | (message-setup-hook . mml-secure-message-sign-pgpmime)) ;; Crypto Settings 2765 | :custom 2766 | (mm-text-html-renderer 'w3m) 2767 | (notmuch-mua-compose-in 'current-window) 2768 | (notmuch-identities private/gmail-accounts) 2769 | (notmuch-fcc-dirs private/notmuch-fcc-dirs) 2770 | (notmuch-search-line-faces '(("unread" . (:foreground "white")) 2771 | ("deleted" . (:foreground "red" :background "blue")))) 2772 | (notmuch-saved-searches private/notmuch-saved-searches) 2773 | (notmuch-crypto-process-mime t) ; Automatically check signatures 2774 | (notmuch-hello-hide-tags (quote ("killed"))) 2775 | (notmuch-address-command "notmuch-addrlookup") 2776 | :config 2777 | (use-package org-notmuch 2778 | :after (org notmuch)) 2779 | (use-package counsel-notmuch 2780 | :ensure t 2781 | :after (counsel notmuch) 2782 | :commands counsel-notmuch)) 2783 | #+END_SRC 2784 | **** BACKLOG try tagging from https://asynchronous.in/2017/04/21/Email-with-notmuch-and-astroid/ 2785 | ** security 2786 | :PROPERTIES: 2787 | :ID: cec54d13-16be-4e61-850f-37f7ba2aeb0e 2788 | :END: 2789 | #+BEGIN_SRC emacs-lisp :tangle yes 2790 | (use-package pass 2791 | :ensure t 2792 | :general 2793 | (:prefix "" 2794 | "p" 'pass 2795 | "!" 'ivy-pass) 2796 | :config 2797 | (use-package ivy-pass :ensure t)) 2798 | #+END_SRC 2799 | ** various useful packages 2800 | :PROPERTIES: 2801 | :ID: 52e2700e-1695-4382-b0ef-992b1f575976 2802 | :END: 2803 | #+BEGIN_SRC emacs-lisp :tangle yes 2804 | (imagemagick-register-types) 2805 | 2806 | (use-package wttrin 2807 | :ensure t 2808 | :after (xterm-color) 2809 | :custom 2810 | (wttrin-default-cities '("Moscow"))) 2811 | 2812 | (use-package webpaste 2813 | :ensure t 2814 | :general 2815 | (:prefix "M-p" 2816 | "b" 'webpaste-paste-buffer 2817 | "r" 'webpaste-paste-region) 2818 | :custom 2819 | (webpaste-provider-priority '("ix.io" "gist.github.com"))) 2820 | 2821 | (use-package atomic-chrome 2822 | :ensure t 2823 | :custom 2824 | (atomic-chrome-buffer-open-style 'frame) 2825 | (atomic-chrome-server-ghost-text-port 4001) 2826 | :config 2827 | ;; TODO: (alex3rd) make use of atomic-chrome-url-major-mode-alist 2828 | (atomic-chrome-start-server)) 2829 | 2830 | (use-package carbon-now-sh 2831 | :quelpa 2832 | (carbon-now-sh :repo "wiedzmin/carbon-now-sh.el" :fetcher github)) 2833 | #+END_SRC 2834 | ** Twitter 2835 | :PROPERTIES: 2836 | :ID: 124e9f69-847c-4682-989c-98e42f9a81b5 2837 | :END: 2838 | #+BEGIN_SRC emacs-lisp :tangle yes 2839 | (use-package twittering-mode 2840 | :ensure t 2841 | :general 2842 | (:keymaps 'mode-specific-map 2843 | "5 t" 'twit) 2844 | :init 2845 | (setq twittering-use-master-password t) 2846 | (setq twittering-private-info-file (expand-file-name "~/docs/enc/cred/.twittering-mode.gpg"))) 2847 | #+END_SRC 2848 | ** Telegram 2849 | :PROPERTIES: 2850 | :ID: cae5fbbf-3814-451b-8b20-491425fa09a3 2851 | :END: 2852 | #+BEGIN_SRC emacs-lisp :tangle yes 2853 | (use-package telega 2854 | :disabled 2855 | :quelpa 2856 | (telega :repo "zevlg/telega.el" :fetcher github :version original) 2857 | :custom 2858 | (telega-completing-read-function #'ivy-completing-read) 2859 | :hook (telega-root-mode . telega-notifications-mode) 2860 | :config 2861 | (use-package telega-notifications)) 2862 | #+END_SRC 2863 | ** browser editing connectivity 2864 | :PROPERTIES: 2865 | :ID: e3a36f53-7898-472c-a446-8f6e8496c3df 2866 | :END: 2867 | #+BEGIN_SRC emacs-lisp :tangle yes 2868 | (use-package edit-server 2869 | :ensure t 2870 | :config 2871 | (edit-server-start)) 2872 | #+END_SRC 2873 | * orgmode 2874 | ** preface 2875 | *** Notes about setting up org-capture 2876 | update-desktop-database 2877 | 2878 | URL: 2879 | javascript:location.href='org-protocol://capture://l/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection()) 2880 | 2881 | ~/.local/share/applications/mimeapps.list 2882 | [Default Applications] 2883 | x-scheme-handler/org-protocol=org-protocol.desktop 2884 | 2885 | ~/.local/share/applications/org-protocol.desktop 2886 | [Desktop Entry] 2887 | Name=org-protocol 2888 | Exec=emacsclient %u 2889 | Type=Application 2890 | Terminal=false 2891 | Categories=System; 2892 | MimeType=x-scheme-handler/org-protocol; 2893 | *** org-id usage 2894 | org-id usage example for the future: 2895 | "* TODO___ %a\n :PROPERTIES:\n :ID: %(org-id-new)\n :END:\n %U\n\n %i" 2896 | ** setup 2897 | :PROPERTIES: 2898 | :ID: 1b1592b1-0ffd-46c4-bea7-4b2faba6ea27 2899 | :END: 2900 | #+BEGIN_SRC emacs-lisp :tangle yes 2901 | (use-package org 2902 | :ensure org-plus-contrib 2903 | :after (f) 2904 | :mode (("\\.org$" . org-mode) 2905 | ("\\.org_archive$" . org-mode)) 2906 | :preface 2907 | (defun custom/finally-tangle-literate-config () 2908 | (shell-command (format "ntangle %s" (concat user-emacs-directory literate-config-filename)))) 2909 | ;; remove read-only props from yanked text (e.g. from jabber.el chat buffer) 2910 | (defadvice org-yank (after make-yank-writeable disable) 2911 | (let ((inhibit-read-only t)) 2912 | (remove-text-properties (region-beginning) (region-end) 2913 | '(read-only t)))) 2914 | (defvar custom/org-journal-file (at-org-dir "/journal.org")) 2915 | (defvar custom/org-browser-tabs (at-org-dir "/browser-tabs.org")) 2916 | (defun custom/verify-refile-target () ;; Exclude DONE state tasks from refile targets 2917 | "Exclude todo keywords with a done state from refile targets" 2918 | (not (member (nth 2 (org-heading-components)) org-done-keywords))) 2919 | ;;TODO: customize "todo-only" parameter for "org-tags-view" 2920 | (defun custom/follow-tag-link (tag) 2921 | "Display a list of TODO headlines with tag TAG. 2922 | With prefix argument, also display headlines without a TODO keyword." 2923 | (org-tags-view nil tag)) ;nil was (null current-prefix-arg) originally 2924 | ;; http://irreal.org/blog/?p=6166 2925 | (defun custom/org-tags-all () 2926 | ;;TODO: bind some key to close buffer 2927 | (interactive) 2928 | (with-current-buffer (get-buffer-create "*org-tags*") 2929 | (delete-region (point-min) (point-max)) 2930 | (org-mode) 2931 | ;;TODO: review tag collection methods and find some truth 2932 | ;; (sort (delete-dups (apply 'append (delete-dups (org-map-entries (lambda () org-scanner-tags) t 'agenda)))) 'string<) 2933 | (let ((tags (sort (delete-dups 2934 | (cl-loop for buffer in (org-buffer-list 'agenda t) 2935 | append (with-current-buffer buffer 2936 | (org-with-wide-buffer 2937 | (goto-char (point-min)) 2938 | (cl-loop while (re-search-forward org-complex-heading-regexp nil t) 2939 | when (match-string 5) 2940 | append (split-string (substring-no-properties (match-string 5)) 2941 | ":" t "[[:space:]]+")))))) 2942 | 'string<))) 2943 | (dolist (tag tags) 2944 | (insert (concat "[[elisp:(org-tags-view nil \"" tag "\")][" tag "]]\n")))) 2945 | (beginning-of-buffer) 2946 | (switch-to-buffer (current-buffer)) 2947 | (read-only-mode))) 2948 | ;; Remove empty CLOCK drawers on clock out 2949 | (defun custom/remove-empty-drawer-on-clock-out () 2950 | (interactive) 2951 | (save-excursion 2952 | (beginning-of-line 0) 2953 | (org-remove-empty-drawer-at "CLOCK" (point)))) 2954 | (defun custom/org-use-speed-commands-for-headings-and-lists () 2955 | "Activate speed commands on list items too." 2956 | (or (and (looking-at org-outline-regexp) (looking-back "^\**")) 2957 | (save-excursion (and (looking-at (org-item-re)) (looking-back "^[ \t]*"))))) 2958 | ;; TODO: bind somewhere 2959 | (defun custom/org-capture-refile-and-jump () 2960 | (interactive) 2961 | (org-capture-refile) 2962 | (org-refile-goto-last-stored)) 2963 | ;;TODO: investigate usage, seems useful 2964 | (defun custom/org-link-describe (link desc) 2965 | (cond ((string-match "file:" link) 2966 | (replace-regexp-in-string "^file:" "File link -> " (org-link-unescape link))) 2967 | (t (or desc link)))) 2968 | ;; (SEC-HIGH SEC-LOW MICROSEC PICOSEC) current-idle-time 2969 | (defvar custom/idle-clockout-timeout 1800 2970 | "Perform first attempt to clock-out after this period of emacs 2971 | inactivity. It can decide to postpone the clocking-out if it's 2972 | only emacs that is idle, but not the computer itself.") 2973 | (defvar custom/idle-clockout-recheck-interval 300 2974 | "After a sufficient idle time was achieved by emacs, we'll 2975 | periodically check current idle time of the whole OS to decide 2976 | whether we need to clock out") 2977 | (defvar custom/idle-clockout-repeat-timer nil 2978 | "Timer for repeatedly (during a single idle interval) checking 2979 | whether we need to clock-out") 2980 | (defun custom/clockout-when-idle () 2981 | (awhen custom/idle-clockout-repeat-timer 2982 | (cancel-timer it)) 2983 | (when (org-clocking-p) 2984 | (if (> (org-user-idle-seconds) 2985 | custom/idle-clockout-timeout) 2986 | (let ((org-clock-out-switch-to-state "WAITING")) ;TODO: introduce variable 2987 | (org-clock-out nil t)) 2988 | (setf custom/idle-clockout-repeat-timer 2989 | (run-with-idle-timer 2990 | (time-add (current-idle-time) custom/idle-clockout-recheck-interval) 2991 | nil 2992 | 'custom/clockout-when-idle))))) 2993 | :general 2994 | (:prefix "" 2995 | "g" 'org-clock-goto 2996 | "." 'org-clock-in 2997 | "," 'org-clock-out 2998 | "^" 'org-mru-clock-select-recent-task 2999 | "c" 'org-clock-cancel 3000 | "x" 'counsel-org-clock-context 3001 | "h" 'counsel-org-clock-history 3002 | "d" 'org-clock-display 3003 | "R" 'org-clock-report 3004 | "p" 'org-pomodoro 3005 | "s" 'org-schedule 3006 | "|" 'org-deadline 3007 | "t" 'org-toggle-timestamp-type 3008 | "e" 'org-capture 3009 | "w" 'org-store-link 3010 | "y" 'org-insert-link-global 3011 | "S" 'org-set-property 3012 | "D" 'org-delete-property 3013 | "A" 'org-footnote-action 3014 | "r" 'org-refile 3015 | "T" 'org-table-create 3016 | "a" 'org-agenda 3017 | "b" 'org-dashboard-display 3018 | "v" 'org-reveal 3019 | "f" 'ace-link-org 3020 | "n" 'org-narrow-to-subtree 3021 | "-" 'org-sparse-tree 3022 | "l" 'counsel-org-agenda-headlines 3023 | "H" 'org-recent-headings-ivy 3024 | "=" 'org-show-todo-tree 3025 | "\\" 'counsel-org-tag 3026 | "" 'outline-next-visible-heading 3027 | "" 'outline-previous-visible-heading 3028 | "" 'org-forward-heading-same-level 3029 | "" 'org-backward-heading-same-level 3030 | "u" 'outline-up-heading 3031 | "G" 'org-goto 3032 | ";" 'custom/org-tags-all) 3033 | ;; (:keymaps 'org-agenda-mode-map 3034 | ;; " ." 'org-agenda-clock-in org-agenda-mode-map 3035 | ;; " ," 'org-agenda-clock-out org-agenda-mode-map 3036 | ;; " o" 'ace-link-org org-agenda-mode-map) 3037 | (:keymaps 'org-mode-map 3038 | "C-'" nil 3039 | "C-c [" nil 3040 | "C-c ]" nil 3041 | "C-c C-o" nil 3042 | "s-j" 'org-babel-next-src-block 3043 | "s-k" 'org-babel-previous-src-block 3044 | "s-l" 'org-edit-src-code 3045 | "C-c C-'" 'org-edit-src-code) 3046 | (:keymaps 'org-src-mode-map 3047 | "s-l" 'org-edit-src-exit 3048 | "C-c C-'" 'org-edit-src-exit) 3049 | 3050 | :config 3051 | (use-package org-capture-pop-frame :ensure t) 3052 | (add-hook 'kill-emacs-hook #'custom/finally-tangle-literate-config) 3053 | (setq org-archive-location (concat custom/org-journal-file "::datetree/")) 3054 | (setq org-contrib-base '(org-agenda org-archive org-attach org-bbdb 3055 | org-bibtex org-clock org-docview org-habit 3056 | org-id org-info org-inlinetask org-irc 3057 | org-mouse org-protocol org-timer org-w3m)) 3058 | (setq org-contrib-extra '(org-bookmark org-checklist org-collector 3059 | org-drill org-expiry org-index org-interactive-query 3060 | org-man org-velocity)) 3061 | (setq org-modules `(,@org-contrib-base ,@org-contrib-extra)) 3062 | (add-to-list 'file-coding-system-alist (cons "\\.\\(org\\|org_archive\\|/TODO\\)$" 'utf-8)) 3063 | (setq org-lowest-priority 70) ;; extend priorities set (given ascii code) 3064 | (setq org-use-speed-commands 'custom/org-use-speed-commands-for-headings-and-lists) 3065 | (setq org-use-speed-commands t) 3066 | (add-to-list 'org-speed-commands-user '("x" org-todo "DONE")) 3067 | (add-to-list 'org-speed-commands-user '("y" org-todo-yesterday "DONE")) 3068 | (add-to-list 'org-speed-commands-user '("s" call-interactively 'org-schedule)) 3069 | (add-to-list 'org-speed-commands-user '("i" call-interactively 'org-clock-in)) 3070 | (add-to-list 'org-speed-commands-user '("o" call-interactively 'org-clock-out)) 3071 | (add-to-list 'org-speed-commands-user '("$" call-interactively 'org-archive-subtree)) 3072 | (f-entries (at-org-dir) 3073 | (lambda (entry) (when (and (f-file? entry) 3074 | (s-suffix? "org" entry) 3075 | (file-exists-p entry)) 3076 | (push entry org-agenda-files))) 3077 | t) 3078 | (dolist (orgfile (directory-files (at-org-dir "/journals") t "journal") ) 3079 | (setq org-agenda-files 3080 | (delete orgfile org-agenda-files))) 3081 | (add-to-list 'org-agenda-files (at-config-basedir "config.org")) 3082 | ;; agenda customizations 3083 | (setq org-confirm-elisp-link-not-regexp "org-tags-view") 3084 | (setf org-agenda-clockreport-parameter-plist '(:link t :maxlevel 2 :narrow 60)) 3085 | (setq org-agenda-dim-blocked-tasks 'invisible) 3086 | (setq org-agenda-include-all-todo t) 3087 | (setq org-agenda-include-diary t) 3088 | (setq org-agenda-inhibit-startup t) 3089 | (setq org-agenda-persistent-filter t) 3090 | (setq org-agenda-repeating-timestamp-show-all nil) 3091 | (setq org-agenda-restore-windows-after-quit t) 3092 | (setq org-agenda-show-all-dates t) 3093 | (setq org-agenda-show-inherited-tags nil) 3094 | (setq org-agenda-show-log t) 3095 | (setq org-agenda-skip-additional-timestamps-same-entry t) 3096 | (setq org-agenda-skip-deadline-if-done t) 3097 | (setq org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled) 3098 | (setq org-agenda-skip-scheduled-if-done t) 3099 | (setq org-agenda-skip-timestamp-if-done t) 3100 | (setq org-agenda-span 'month) 3101 | (setq org-agenda-start-on-weekday 1) 3102 | (setq org-agenda-sticky nil) ;otherwise agenda behaves strangely on non-stuck projects 3103 | (setq org-agenda-tags-todo-honor-ignore-options t) 3104 | (setq org-agenda-todo-ignore-deadlines 'all) 3105 | (setq org-agenda-todo-ignore-scheduled 'all) 3106 | (setq org-agenda-todo-ignore-timestamp 'past) 3107 | (setq org-agenda-todo-ignore-with-date t) 3108 | (setq org-agenda-todo-list-sublevels nil) 3109 | (setq org-agenda-use-tag-inheritance t) 3110 | (setq org-agenda-window-setup 'current-window) 3111 | (setf agenda-opts-all-with-time 3112 | '((org-agenda-todo-ignore-scheduled nil) 3113 | (org-agenda-todo-ignore-deadlines nil) 3114 | (org-agenda-todo-ignore-with-date nil))) 3115 | (setq org-agenda-time-grid 3116 | '((daily today require-timed remove-match) 3117 | "----------------" 3118 | (930 1000 1200 1400 1600 1800 2000 2200 2400 2500))) 3119 | (setq org-agenda-custom-commands 3120 | `(("d" . "some non-straightforward TODO statuses") 3121 | ("db" todo "BACKLOG" nil) 3122 | ("ds" todo "SOON" nil) 3123 | ("dc" todo "CANCELLED" nil) 3124 | ("dw" todo "WAITING|FEEDBACK" nil) 3125 | ("dg" todo "GOING" ,agenda-opts-all-with-time) 3126 | ("da" tags "+actual_p") 3127 | ("c" . "by context") 3128 | ("cp" tags "+@personal/GOING|WAITING|BACKLOG|SOON") 3129 | ("cr" tags "+@project/GOING|WAITING|BACKLOG|SOON") 3130 | ("cj" tags "+@job/GOING|WAITING|FEEDBACK|BACKLOG|SOON") 3131 | ("cw" tags "+@workplace/GOING|WAITING|BACKLOG|SOON") 3132 | ("ct" tags "+@phonecall/WAITING|BACKLOG|SOON") 3133 | ("cs" tags "+@someday") 3134 | ("cq" tags "+@quicknote") 3135 | ("e" . "by essence") 3136 | ;;TODO: find more handy shortcuts 3137 | ("ec" tags "+current") 3138 | ("ef" tags "+reference") 3139 | ("em" tags "+master") 3140 | ("eo" tags "+ordering") 3141 | ("er" tags "+repair") 3142 | ("ed" tags "+develop") 3143 | ("ei" tags "+investigate") 3144 | ("ee" tags "+entertainment") 3145 | ("ey" tags "+family") 3146 | ("eH" tags-todo "+housekeeping") 3147 | ("eC" tags-todo "+current") 3148 | ("eF" tags-todo "+reference") 3149 | ("eM" tags-todo "+master") 3150 | ("eO" tags-todo "+ordering") 3151 | ("eR" tags-todo "+repair") 3152 | ("eD" tags-todo "+develop") 3153 | ("eI" tags-todo "+investigate") 3154 | ("eE" tags-todo "+entertainment") 3155 | ("u" . "unassigned") 3156 | ("up" alltodo "Unprioritized TODO entries" 3157 | ((org-agenda-skip-function 3158 | (lambda nil 3159 | (org-agenda-skip-entry-if 'regexp "\\[#[ABC]]"))) 3160 | (org-tags-match-list-sublevels 'indented) 3161 | (org-agenda-sorting-strategy 3162 | '((agenda time-up tag-up) )) 3163 | ;; '(org-agenda-sorting-strategy '((agenda time-up priority-down tag-up) (todo tag-up))) 3164 | (org-agenda-overriding-header "Unprioritized TODO entries: "))) 3165 | ("P" . "Prioritized tasks") 3166 | ("Pa" "Prioritized tasks A" 3167 | ((tags-todo "+PRIORITY=\"A\"") )) 3168 | ("Pb" "Prioritized tasks B" 3169 | ((tags-todo "+PRIORITY=\"B\""))) 3170 | ("Pc" "Prioritized tasks C" 3171 | ((tags-todo "+PRIORITY=\"C\""))) 3172 | ("S" "Scheduled tasks" agenda "" 3173 | ((org-agenda-time-grid nil) 3174 | (org-deadline-warning-days 32) 3175 | (org-agenda-entry-types '(:scheduled)) 3176 | )) 3177 | ("p" tags "+purchase") 3178 | ("b" . "tickets") 3179 | ("be" tags "+ticket+emacs") 3180 | ("bs" tags "+ticket+stumpwm") 3181 | ("jc" tags "+@job+current/GOING|FEEDBACK") 3182 | )) 3183 | (setq org-agenda-prefix-format '((agenda . " %i %-12:c%?-12t% s %b") 3184 | (timeline . " % s") 3185 | (todo . " %i %-12:c") 3186 | (tags . " %i %-12:c") 3187 | (search . " %i %-12:c"))) 3188 | ;; clocking customizations 3189 | (setq org-clock-history-length 35) 3190 | (setq org-clock-idle-time 3) 3191 | (setq org-clock-in-resume t) 3192 | (setq org-clock-in-switch-to-state "GOING") 3193 | (setq org-clock-out-switch-to-state "HOLD") 3194 | (setq org-clock-into-drawer "CLOCK") 3195 | (setq org-clock-out-remove-zero-time-clocks t) 3196 | (setq org-clock-persist t) 3197 | ;; just clock-out unconditionally - it seems easier to maintain (credits to @binarin) 3198 | (setf org-clock-x11idle-program-name "xprintidle") 3199 | (setf org-x11idle-exists-p t) 3200 | ;; refiling customizations 3201 | (setq org-outline-path-complete-in-steps nil) 3202 | (setq org-refile-allow-creating-parent-nodes 'confirm) 3203 | (setq org-refile-target-verify-function 'custom/verify-refile-target) 3204 | (setq org-refile-targets '((org-agenda-files :maxlevel . 5) (nil :maxlevel . 5))) 3205 | (setq org-refile-use-outline-path 'file) 3206 | ;; various customizations 3207 | (setf org-catch-invisible-edits nil) 3208 | (setf org-fast-tag-selection-include-todo nil) 3209 | (setf org-id-link-to-org-use-id t) 3210 | (setq appt-display-interval 5) 3211 | (setq appt-message-warning-time 10) 3212 | (setq calendar-date-style 'european) 3213 | (setq org-M-RET-may-split-line '((default . nil))) 3214 | (setq org-align-all-tags t) 3215 | (setq org-attach-directory (at-org-dir "/org-attach-data")) 3216 | (setq org-blank-before-new-entry '((heading) (plain-list-item . auto))) 3217 | (setq org-columns-default-format "%42ITEM %TODO %3Effort(E){:} %3CLOCKSUM_T(R) %SCHEDULED") 3218 | (setq org-confirm-elisp-link-function 'y-or-n-p) 3219 | (setq org-ctrl-k-protect-subtree t) 3220 | (setq org-cycle-include-plain-lists 'integrate) 3221 | (setq org-cycle-separator-lines 0) 3222 | (setq org-deadline-warning-days 30) 3223 | (setq org-default-notes-file (at-org-dir "/refile.org")) 3224 | (setq org-ditaa-jar-path (at-config-basedir "resources/ditaa0_9.jar")) 3225 | (setq org-element-use-cache nil) 3226 | (setq org-enforce-todo-checkbox-dependencies t) 3227 | (setq org-enforce-todo-dependencies t) ;;TODO: try ORDERED/NOBLOCKING props : org-toggle-ordered-property 3228 | (setq org-export-coding-system 'utf-8) 3229 | (setq org-export-with-drawers t) 3230 | (setq org-extend-today-until 2) 3231 | (setq org-fast-tag-selection-single-key 'expert) 3232 | (setq org-fontify-done-headline t) 3233 | (setq org-global-properties '(("STYLE_ALL" . "habit"))) 3234 | (setq org-goto-max-level 10) 3235 | (setq org-hide-leading-stars t) 3236 | (setq org-indirect-buffer-display 'current-window) 3237 | (setq org-insert-mode-line-in-empty-file t) 3238 | (setq org-log-done t) 3239 | (setq org-log-into-drawer t) 3240 | (setq org-log-repeat 'time) 3241 | (setq org-loop-over-headlines-in-active-region t) 3242 | (setq org-read-date-prefer-future 'time) 3243 | (setq org-return-follows-link t) 3244 | (setq org-special-ctrl-a/e t) 3245 | (setq org-special-ctrl-k t) 3246 | (setq org-src-fontify-natively t) 3247 | (setq org-src-tab-acts-natively t) 3248 | (setq org-startup-folded nil) 3249 | (setq org-stuck-projects '("+LEVEL=1/-DONE" ("TODO" "GOING" "NEXT" "WAITING" "HOLD" "CANCELLED") nil "")) 3250 | (setq org-tags-column -80) 3251 | (setq org-track-ordered-property-with-tag t) 3252 | (setq org-use-effective-time t) 3253 | (setq org-use-property-inheritance t) 3254 | (setq org-use-sub-superscripts nil) 3255 | (setq org-yank-adjusted-subtrees t) 3256 | (setq org-agenda-show-future-repeats 'next) 3257 | (setq org-highlight-latex-and-related '(latex)) 3258 | (setq org-confirm-shell-link-function 'y-or-n-p) 3259 | (setq org-confirm-elisp-link-function 'y-or-n-p) 3260 | (setq org-src-window-setup 'current-window) 3261 | (setq org-confirm-babel-evaluate nil) 3262 | (setf org-make-link-description-function #'custom/org-link-describe) 3263 | (when (featurep 'unicode-fonts) 3264 | (setq org-ellipsis "⤵")) 3265 | ;; keywords setup 3266 | (setq kw-seq-common '(sequence "BACKLOG(b)" "SOON(s)" "REPEAT(r)" "GOING(g!)" "NEXT(x)" "WAITING(w@/!)" "FEEDBACK" 3267 | "|" "DONE(d!/@)" "CANCELLED(c@/!)" "OUTDATED(o)")) 3268 | (setq org-todo-keywords 3269 | `(,kw-seq-common)) 3270 | (setq org-todo-keywords-for-agenda '("BACKLOG(b)" "SOON(s)" "REPEAT(r)" "GOING(g!)" "NEXT(x)" "WAITING(w@/!)" "FEEDBACK")) 3271 | (setq org-done-keywords-for-agenda '("DONE(d)" "CANCELLED(c)" "OUTDATED(o)")) 3272 | ;; faces 3273 | (setq org-todo-keyword-faces 3274 | '(("BACKLOG" . (:foreground "gray" :weight bold)) 3275 | ("SOON" . (:foreground "magenta" :weight bold)) 3276 | ("REPEAT" . (:foreground "blue" :weight bold)) 3277 | ("NEXT" . (:foreground "red" :weight bold)) 3278 | ("WAITING" . (:foreground "orange" :weight bold)) 3279 | ("FEEDBACK" . (:foreground "yellow" :weight bold)) 3280 | ("CANCELLED" . (:foreground "cyan" :weight bold)) 3281 | ("DONE" . (:foreground "green" :weight bold)))) 3282 | (setq org-priority-faces 3283 | '((?A :foreground "red" :weight bold) 3284 | (?B :foreground "#94bff3" :weight bold) 3285 | (?C :foreground "#6f6f6f") 3286 | (?D :foreground "#c390d4") 3287 | (?E :foreground "#90c3d4") 3288 | (?F :foreground "#a1d490"))) 3289 | (set-face-attribute 'org-done nil :foreground "PaleGreen" :weight 'normal :strike-through t) 3290 | (set-face-attribute 'org-headline-done nil :foreground "LightSalmon" :weight 'normal :strike-through t) 3291 | ;; tags 3292 | (setq org-tag-alist '(("current" . ?c) 3293 | ("reference" . ?f) 3294 | ("orgmode" . ?g) 3295 | ("purchase" . ?p) 3296 | ("master" . ?m) 3297 | ("ordering" . ?o) 3298 | ("housekeeping" . ?h) 3299 | ("entertainment" . ?e) 3300 | ("interesting" . ?i) 3301 | ("repair" . ?r) 3302 | )) 3303 | (setq org-tags-exclude-from-inheritance '("project")) 3304 | (setq org-todo-state-tags-triggers 3305 | '(("GOING" ("current" . t)) 3306 | ("DONE" ("current")))) 3307 | ;; org-habit 3308 | (setq org-habit-graph-column 50) 3309 | (setq org-habit-preceding-days 10) 3310 | (setq org-habit-following-days 4) 3311 | (setq org-habit-show-habits-only-for-today nil) 3312 | ;; org-capture 3313 | (setq org-capture-templates 3314 | `(("n" "NixOS") 3315 | ("nt" "NixOS" entry (file "/etc/nixos/todo.org") "* BACKLOG %?[[%:link][%:description]] %U\n %:initial") 3316 | ("nc" "NixOS code snippet" entry (file "/etc/nixos/todo.org") 3317 | "* %^{title} :nix:code_snippet:\n :PROPERTIES:\n :CREATED: %U\n :END:\n\n#+BEGIN_SRC nix\n %i%?\n#+END_SRC\n") 3318 | ("ns" "NixOS shell excerpt" entry (file "/etc/nixos/todo.org") "* %? %U :%:description:\n %:initial") 3319 | ("e" "Emacs") 3320 | ("et" "Emacs" entry (file ,(at-config-basedir "/todo.org")) "* BACKLOG %?[[%:link][%:description]] %U\n %:initial") 3321 | ("ec" "Emacs code snippet" entry (file ,(at-config-basedir "/todo.org")) 3322 | "* %^{title} :emacs:code_snippet:\n :PROPERTIES:\n :CREATED: %U\n :END:\n\n#+BEGIN_SRC emacs-lisp\n %i%?\n#+END_SRC\n") 3323 | ("es" "NixOS shell excerpt" entry (file ,(at-config-basedir "/todo.org")) "* %? %U :%:description:\n %:initial") 3324 | ("x" "XMonad") 3325 | ("xt" "XMonad" entry (file ,(at-homedir "/.xmonad/todo.org")) "* BACKLOG %?[[%:link][%:description]] %U\n %:initial") 3326 | ("xc" "XMonad code snippet" entry (file ,(at-homedir "/.xmonad/todo.org")) 3327 | "* %^{title} :xmonad:code_snippet:\n :PROPERTIES:\n :CREATED: %U\n :END:\n\n#+BEGIN_SRC haskell\n %i%?\n#+END_SRC\n") 3328 | ("xs" "XMonad shell excerpt" entry (file ,(at-homedir "/.xmonad/todo.org")) "* %? %U :%:description:\n %:initial") 3329 | ("d" "deferred tabs" entry (file+olp custom/org-browser-tabs "groups" "deferred tabs") "* %?%:link %U :deferred:") 3330 | ("p" "projects") 3331 | ("pi" "project ideas" entry (file ,(at-org-dir "/projects.org")) "* %? %U :@project:idea:") 3332 | ("pn" "new project" entry (file ,(at-org-dir "/projects.org")) "* %? %U :@project:") 3333 | ("m" "mastering" entry (file+headline ,(at-org-dir "/mastering.org") "inbox") "* %? %U") 3334 | )) 3335 | ;; holidays 3336 | (setq holiday-orthodox-holidays nil) ; Orthodox holidays to some extent 3337 | (setq holiday-personal-holidays nil) ; personal anniversaries, etc. 3338 | (setq holiday-other-holidays 3339 | (append holiday-orthodox-holidays holiday-personal-holidays)) 3340 | (setq calendar-holidays 3341 | (append holiday-other-holidays 3342 | holiday-solar-holidays)) 3343 | (add-hook 'org-mode-hook 'turn-on-font-lock) 3344 | (add-hook 'org-clock-out-hook 'custom/remove-empty-drawer-on-clock-out 'append) 3345 | (add-hook 'org-after-refile-insert-hook 'save-buffer) 3346 | (add-hook 'org-capture-mode-hook 3347 | (lambda () (setq-local org-complete-tags-always-offer-all-agenda-tags t))) 3348 | ;; run some commands 3349 | (org-add-link-type "tag" 'custom/follow-tag-link) 3350 | (org-clock-persistence-insinuate) ;; Resume clocking tasks when emacs is restarted 3351 | (run-at-time "06:00" 86400 '(lambda () (setq org-habit-show-habits t))) 3352 | (set-charset-priority 'unicode) 3353 | (turn-on-orgtbl) 3354 | (run-with-idle-timer custom/idle-clockout-timeout t 'custom/clockout-when-idle) 3355 | (font-lock-add-keywords 3356 | 'org-mode 3357 | `(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)" 1 'org-headline-done prepend)) 3358 | 'append)) 3359 | 3360 | (use-package org-protocol 3361 | :after (org server)) 3362 | 3363 | (use-package ob-css 3364 | :ensure org-plus-contrib 3365 | :commands (org-babel-execute:css 3366 | org-babel-prep-session:css)) 3367 | 3368 | (use-package ob-dot 3369 | :ensure org-plus-contrib 3370 | :commands (org-babel-execute:dot 3371 | org-babel-expand-body:dot)) 3372 | 3373 | (use-package ob-ditaa 3374 | :ensure org-plus-contrib 3375 | :commands (org-babel-execute:ditaa 3376 | org-babel-prep-session:ditaa)) 3377 | 3378 | (use-package ob-emacs-lisp 3379 | :ensure org-plus-contrib 3380 | :commands (org-babel-execute:emacs-lisp 3381 | org-babel-expand-body:emacs-lisp)) 3382 | 3383 | (use-package ob-lisp 3384 | :ensure org-plus-contrib 3385 | :commands (org-babel-execute:lisp 3386 | org-babel-expand-body:lisp)) 3387 | 3388 | (use-package ob-js 3389 | :ensure org-plus-contrib 3390 | :commands (org-babel-execute:js 3391 | org-babel-prep-session:js 3392 | org-babel-variable-assignments:js)) 3393 | 3394 | (use-package ob-latex 3395 | :ensure org-plus-contrib 3396 | :commands (org-babel-execute:latex 3397 | org-babel-expand-body:latex 3398 | org-babel-prep-session:latex)) 3399 | 3400 | (use-package ob-org 3401 | :ensure org-plus-contrib 3402 | :commands (org-babel-execute:org 3403 | org-babel-expand-body:org 3404 | org-babel-prep-session:org)) 3405 | 3406 | (use-package ob-plantuml 3407 | :ensure org-plus-contrib 3408 | :commands (org-babel-execute:plantuml 3409 | org-babel-prep-session:plantuml 3410 | org-babel-variable-assignments:plantuml)) 3411 | 3412 | (use-package ob-scheme 3413 | :ensure org-plus-contrib 3414 | :commands (org-babel-execute:scheme 3415 | org-babel-expand-body:scheme)) 3416 | 3417 | (use-package ob-python 3418 | :ensure org-plus-contrib 3419 | :commands (org-babel-execute:python)) 3420 | 3421 | (use-package ob-shell 3422 | :ensure org-plus-contrib 3423 | :commands (org-babel-execute:sh 3424 | org-babel-expand-body:sh 3425 | org-babel-execute:bash 3426 | org-babel-expand-body:bash)) 3427 | 3428 | (use-package ox-html 3429 | :ensure org-plus-contrib 3430 | :commands (org-html-convert-region-to-html 3431 | org-html-export-as-html 3432 | org-html-export-to-html)) 3433 | #+END_SRC 3434 | ** additional packages / extensions 3435 | :PROPERTIES: 3436 | :ID: 73af33db-8f7b-4a96-a108-b541def2aae4 3437 | :END: 3438 | #+BEGIN_SRC emacs-lisp :tangle yes 3439 | (use-package ob-async 3440 | :ensure t 3441 | :after (org ob)) 3442 | 3443 | (use-package org-pomodoro 3444 | :ensure t 3445 | :after (alert)) 3446 | 3447 | (use-package orgit 3448 | ;;TODO: automate insertion of links below (yasnippet/whatever) 3449 | ;; orgit:/path/to/repo/ links to a `magit-status' buffer 3450 | ;; orgit-rev:/path/to/repo/::REV links to a `magit-revision' buffer 3451 | ;; orgit-log:/path/to/repo/::ARGS links to a `magit-log' buffer 3452 | :ensure t) 3453 | 3454 | (use-package orglink 3455 | :ensure t 3456 | :delight (orglink-mode " OL") 3457 | :config 3458 | ;; TODO: customize orglink-activate-in-modes 3459 | ;; TODO: automate insertion of link types below 3460 | ;; [[Code]] 3461 | ;; [[Code][start of code]] 3462 | ;; [[define-derived-mode orglink-mode][orglink-mode]] 3463 | ;; 3464 | ;; man:info 3465 | ;; 3466 | ;; https://github.com/tarsius/orglink 3467 | (global-orglink-mode)) 3468 | 3469 | (use-package org-clock-today 3470 | :ensure t 3471 | :config 3472 | (org-clock-today-mode 1)) 3473 | 3474 | (use-package org-recent-headings 3475 | :ensure t 3476 | :disabled 3477 | :custom 3478 | (org-recent-headings-save-file (at-user-data-dir "org-recent-headings")) 3479 | :config 3480 | (org-recent-headings-mode 1)) 3481 | 3482 | (use-package org-link-minor-mode 3483 | :ensure t 3484 | :config 3485 | (org-link-minor-mode t)) 3486 | 3487 | (use-package org-randomnote 3488 | :ensure t 3489 | :general 3490 | (:keymaps 'mode-specific-map 3491 | "o r" 'org-randomnote) 3492 | :custom 3493 | (org-randomnote-candidates org-agenda-files) 3494 | (org-randomnote-open-behavior 'indirect-buffer)) 3495 | 3496 | (use-package russian-holidays 3497 | :ensure t 3498 | :after (org) 3499 | :config 3500 | (setq calendar-holidays 3501 | (push russian-holidays calendar-holidays))) 3502 | 3503 | (use-package org-rich-yank 3504 | :ensure t 3505 | :after (org) 3506 | :general 3507 | (:keymaps 'org-mode-map 3508 | "C-M-y" 'org-rich-yank)) 3509 | 3510 | (use-package counsel-org-clock 3511 | :ensure t 3512 | :after (org counsel) 3513 | :custom 3514 | (counsel-org-clock-default-action 'counsel-org-clock-clock-dwim-action)) 3515 | 3516 | (use-package org-download 3517 | :ensure t 3518 | ;;TODO: bind keys ASAP 3519 | ;;TODO: use in automation 3520 | :hook (dired-mode-hook . org-download-enable) 3521 | :custom 3522 | (org-download-method 'attach)) 3523 | #+END_SRC 3524 | * publishing 3525 | :PROPERTIES: 3526 | :ID: 27edca98-b474-41dd-8a12-79b20eb52ede 3527 | :END: 3528 | #+BEGIN_SRC emacs-lisp :tangle yes 3529 | (use-package blockdiag-mode :ensure t) 3530 | 3531 | (use-package ob-blockdiag 3532 | :ensure t 3533 | :config 3534 | (org-babel-do-load-languages 'org-babel-load-languages 3535 | '((blockdiag . t)))) 3536 | 3537 | (use-package plantuml-mode 3538 | :ensure t 3539 | :mode ("\\.plantuml\\'" . plantuml-mode) 3540 | :custom 3541 | (plantuml-jar-path "/usr/share/plantuml/lib/plantuml.jar") 3542 | (org-plantuml-jar-path plantuml-jar-path) 3543 | :config 3544 | (add-to-list 'org-src-lang-modes '("plantuml" . plantuml)) 3545 | (org-babel-do-load-languages 'org-babel-load-languages 3546 | '((plantuml . t)))) 3547 | #+END_SRC 3548 | * help 3549 | :PROPERTIES: 3550 | :ID: c49ac158-ba13-49ea-88cc-a85abf12b9e3 3551 | :END: 3552 | #+BEGIN_SRC emacs-lisp :tangle yes 3553 | (use-package info 3554 | :preface 3555 | (defun custom/open-info (topic bname) 3556 | "Open info on TOPIC in BNAME." 3557 | (if (get-buffer bname) 3558 | (progn 3559 | (switch-to-buffer bname) 3560 | (unless (string-match topic Info-current-file) 3561 | (Info-goto-node (format "(%s)" topic)))) 3562 | (info topic bname))) 3563 | (defun custom/info-org () (custom/open-info "org" "*org info*")) 3564 | (defun custom/info-org-clocking () (org-info "Clocking commands")) 3565 | (defun custom/info-elisp () (custom/open-info "elisp" "*elisp info*")) 3566 | (defun custom/info-emacs () (custom/open-info "emacs" "*emacs info*")) 3567 | (defun custom/info-gcl () (custom/open-info "gcl" "*hyperspec*")) 3568 | :general 3569 | (:keymaps 'mode-specific-map 3570 | "C-h o" 'custom/open-org 3571 | "C-h ?" 'custom/info-org-clocking 3572 | "C-h e" 'custom/open-elisp 3573 | "C-h m" 'custom/open-emacs 3574 | "C-h h" 'custom/open-gcl) 3575 | :config 3576 | (info-initialize) 3577 | (setq Info-additional-directory-list 3578 | (list (concat home-directory "/help/info"))) 3579 | (add-to-list 'Info-directory-list "/usr/share/info") 3580 | (add-to-list 'Info-directory-list 3581 | (format "%selpa/%s" 3582 | user-emacs-directory 3583 | (car (directory-files (at-config-basedir "elpa") nil "^use-package-"))))) 3584 | 3585 | (use-package helpful 3586 | :ensure t 3587 | :general 3588 | ;;TODO: investigate more concise way 3589 | ;;TODO: use C-u version (catch up TAPs) 3590 | (:prefix "" 3591 | "f" 'helpful-function 3592 | "v" 'helpful-variable 3593 | "C" 'helpful-callable 3594 | "m" 'helpful-macro 3595 | "c" 'helpful-command 3596 | "k" 'helpful-key 3597 | "RET" 'helpful-at-point) 3598 | (:prefix "C-h" 3599 | "f" 'helpful-function 3600 | "v" 'helpful-variable 3601 | "C" 'helpful-callable 3602 | "m" 'helpful-macro 3603 | "c" 'helpful-command 3604 | "k" 'helpful-key 3605 | "RET" 'helpful-at-point)) 3606 | 3607 | (use-package help-find-org-mode 3608 | :ensure t 3609 | :pin melpa-stable 3610 | :config (help-find-org-mode t)) 3611 | 3612 | (use-package info-buffer 3613 | :ensure t 3614 | :general 3615 | ("C-h i" 'info-buffer)) 3616 | 3617 | (use-package info-colors 3618 | :ensure t 3619 | :hook (Info-selection-hook . info-colors-fontify-node)) 3620 | 3621 | (use-package woman 3622 | :config 3623 | (defalias 'man 'woman) ;'Woman' offers completion better than 'man'. 3624 | (setenv "MANPATH" "/usr/share/man:/usr/local/man")) 3625 | 3626 | (use-package apropos 3627 | :general 3628 | (:keymaps 'mode-specific-map 3629 | "H a" 'apropos 3630 | "H d" 'apropos-documentation 3631 | "H v" 'apropos-variable 3632 | "H c" 'apropos-command 3633 | "H l" 'apropos-library 3634 | "H u" 'apropos-user-option 3635 | "H i" 'info-apropos 3636 | "H t" 'tags-apropos 3637 | "H e" 'apropos-value)) 3638 | #+END_SRC 3639 | -------------------------------------------------------------------------------- /init.el: -------------------------------------------------------------------------------- 1 | (setq debug-on-error t) 2 | (setq debug-on-quit t) 3 | 4 | (setq load-prefer-newer t) 5 | (setq message-log-max t) ;; we don't want to lose any startup log info 6 | (setq shell-file-name "/bin/bash") 7 | 8 | (defvar literate-config-filename "config.org") 9 | (defvar tangled-config-filename (concat (file-name-sans-extension literate-config-filename) ".el")) 10 | 11 | ;; ================= Emergency keybindings ================= 12 | (global-set-key (kbd "C-x C-.") ;; Run use-package linter 13 | (lambda () 14 | (interactive) 15 | (let ((tangled-config-file (concat user-emacs-directory "config.el"))) 16 | (when (file-exists-p tangled-config-file) ;; because tangled file may be removed for some reason 17 | (find-file tangled-config-file) 18 | (use-package-lint))))) 19 | (global-set-key (kbd "C-x C-,") #'goto-char) 20 | ;; ========================================================= 21 | 22 | (require 'cl) 23 | 24 | ;; =================== Package management =================== 25 | (require 'package) 26 | (unless package--initialized 27 | (package-initialize)) 28 | (setq package-enable-at-startup nil) 29 | 30 | (add-to-list 'package-archives 31 | '("melpa-stable" . "https://stable.melpa.org/packages/")) 32 | (add-to-list 'package-archives 33 | '("melpa" . "https://melpa.org/packages/")) 34 | (add-to-list 'package-archives 35 | '("org" . "https://orgmode.org/elpa/")) 36 | (setf (cdr (assoc "gnu" package-archives)) 37 | "https://elpa.gnu.org/packages/") 38 | (setq package-archive-priorities 39 | '(("melpa-stable" . 5) 40 | ("gnu" . 5) 41 | ("melpa" . 10))) 42 | 43 | (mapcar 44 | (lambda (package) 45 | (unless (package-installed-p package) 46 | (unless package-archive-contents 47 | (package-refresh-contents)) 48 | (package-install package))) 49 | ;;base system packages for bootstrapping 50 | '(use-package el-get)) 51 | 52 | (setq use-package-compute-statistics t) 53 | (setq use-package-verbose t) 54 | (setq use-package-hook-name-suffix "") 55 | (put 'use-package 'lisp-indent-function 1) 56 | 57 | (unless (require 'quelpa nil t) ;;TODO: consider trying self-upgrades 58 | (with-temp-buffer 59 | (url-insert-file-contents "https://raw.github.com/quelpa/quelpa/master/bootstrap.el") 60 | (eval-buffer))) 61 | 62 | (use-package quelpa :ensure t) 63 | (use-package quelpa-use-package 64 | :ensure t 65 | :custom 66 | (quelpa-use-package-inhibit-loading-quelpa 67 | t "Improve startup performance")) 68 | 69 | (use-package general :ensure t) 70 | 71 | (add-hook 'emacs-startup-hook 72 | (lambda () 73 | (message "Emacs ready in %s with %d garbage collections." 74 | (format "%.2f seconds" 75 | (float-time 76 | (time-subtract after-init-time before-init-time))) 77 | gcs-done))) 78 | 79 | (use-package use-package-el-get 80 | :ensure t 81 | :config 82 | (use-package-el-get-setup)) 83 | ;; ========================================================= 84 | 85 | ;; ============= A bunch of essential packages ============= 86 | 87 | (use-package exec-path-from-shell 88 | :ensure t 89 | :if (memq window-system '(mac ns)) 90 | :custom 91 | (exec-path-from-shell-check-startup-files 92 | nil "Used WM(s) do not check non-interactive startup files anyway") 93 | :config 94 | (exec-path-from-shell-initialize)) 95 | 96 | (use-package bug-hunter :disabled) 97 | ;; ========================================================= 98 | 99 | (org-babel-load-file (concat (file-name-directory load-file-name) literate-config-filename)) 100 | 101 | ;; ======= A bunch of essential packages (continued) ======= 102 | (use-package iqa ;; open literate config fast in case of emergency (and not only) 103 | :ensure t 104 | :init 105 | (setq iqa-user-init-file (concat user-emacs-directory literate-config-filename)) 106 | :config 107 | (iqa-setup-default)) 108 | 109 | (use-package restart-emacs 110 | :ensure t 111 | :config 112 | (global-set-key (kbd "C-x C-c") 'restart-emacs)) 113 | ;; ========================================================= 114 | 115 | (setq debug-on-error nil) 116 | (setq debug-on-quit nil) 117 | -------------------------------------------------------------------------------- /resources/auto-insert/01:.*.el: -------------------------------------------------------------------------------- 1 | ;;; %b --- 2 | 3 | ;; Copyright (C) 2015 Alex Ermolov 4 | ;; 5 | ;; Author: aaermolov@gmail.com 6 | ;; Keywords: 7 | ;; Requirements: 8 | 9 | 10 | (provide '%F) 11 | 12 | ;;; %b ends here 13 | -------------------------------------------------------------------------------- /resources/auto-insert/02:.*.erl: -------------------------------------------------------------------------------- 1 | %%% File : %b 2 | %%% Created : %D 3 | %%% Description : 4 | %%% 5 | 6 | -module(%F). 7 | %% -export([]). 8 | %% -import(,[]) 9 | %% -compile(export_all). 10 | -------------------------------------------------------------------------------- /resources/auto-insert/03:.*.org: -------------------------------------------------------------------------------- 1 | #+AUTHOR: Alex Ermolov 2 | #+EMAIL: aaermolov@gmail.com 3 | -------------------------------------------------------------------------------- /resources/auto-insert/04:.*.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /resources/auto-insert/05:.*.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | -------------------------------------------------------------------------------- /resources/ditaa0_9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmacsRuPub/emacs-config/8b9306c7d6e6797a834bb57eb5178c348bb73274/resources/ditaa0_9.jar -------------------------------------------------------------------------------- /resources/yasnippet-private/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmacsRuPub/emacs-config/8b9306c7d6e6797a834bb57eb5178c348bb73274/resources/yasnippet-private/.keep -------------------------------------------------------------------------------- /resources/yasnippet-private/jabber-chat-mode/misreading: -------------------------------------------------------------------------------- 1 | # -*- mode: snippet -*- 2 | # name: misreading 3 | # key: misread 4 | # insert a "misreading" harness for some fancy misreading 5 | # -- 6 | + прочтение: "$1" --> "$2" 7 | -------------------------------------------------------------------------------- /resources/yasnippet-private/jabber-chat-mode/replace regexp: -------------------------------------------------------------------------------- 1 | # -*- mode: snippet -*- 2 | # name: replace regexp 3 | # key: rr 4 | # insert a regexp replacing harness to denote some back-in-time text replacing 5 | # -- 6 | s/$1/$2 7 | --------------------------------------------------------------------------------