Rewrite core libraries (WIP)
This commit is contained in:
parent
83c852e11f
commit
50ea98319f
68 changed files with 1892 additions and 5345 deletions
|
@ -1,87 +0,0 @@
|
||||||
;;; core-autoinsert.el
|
|
||||||
|
|
||||||
(use-package autoinsert
|
|
||||||
:after yasnippet
|
|
||||||
:config
|
|
||||||
(setq auto-insert-query nil ; Don't prompt before insertion
|
|
||||||
auto-insert-alist '()) ; Tabula rasa
|
|
||||||
(auto-insert-mode 1)
|
|
||||||
|
|
||||||
(mapc (lambda (rule)
|
|
||||||
(define-auto-insert
|
|
||||||
(nth 0 rule)
|
|
||||||
(vector `(lambda () (doom/auto-insert-snippet ,(nth 1 rule) ',(nth 2 rule) ,(nth 3 rule))))))
|
|
||||||
`(;; General
|
|
||||||
("/\\.gitignore$" "__" gitignore-mode)
|
|
||||||
("/Dockerfile$" "__" dockerfile-mode)
|
|
||||||
("/docker-compose.yml$" "__" yaml-mode)
|
|
||||||
;; Org-mode
|
|
||||||
("\\.org$" "__" org-mode)
|
|
||||||
("/Work/.+\\.org$" "__project.org" org-mode)
|
|
||||||
("/Invoices/.+\\.org$" "__invoice.org" org-mode)
|
|
||||||
("/Contacts/.+\\.org$" "__contact.org" org-mode)
|
|
||||||
;; C/C++
|
|
||||||
("/Makefile$" "__" makefile-gmake-mode)
|
|
||||||
("/main\\.\\(cc\\|cpp\\)$" "__main.cpp" c++-mode)
|
|
||||||
("/win32_\\.\\(cc\\|cpp\\)$" "__winmain.cpp" c++-mode)
|
|
||||||
("\\.h\\(h\\|pp|xx\\)$" "__hpp" c++-mode)
|
|
||||||
("\\.\\(cc\\|cpp\\)$" "__cpp" c++-mode)
|
|
||||||
("\\.h$" "__h" c-mode)
|
|
||||||
("\\.c$" "__c" c-mode)
|
|
||||||
;; Elisp
|
|
||||||
("-test\\.el$" "__" emacs-ert-mode)
|
|
||||||
("/.+\\.el$" "__initfile" emacs-lisp-mode)
|
|
||||||
("\\(\\.emacs\\.d\\|doom-emacs\\)/private/\\(snippets\\|templates\\)/.+$"
|
|
||||||
"__" snippet-mode)
|
|
||||||
;; Go
|
|
||||||
("/main\\.go$" "__main.go" go-mode t)
|
|
||||||
("\\.go$" "__.go" go-mode)
|
|
||||||
;; HTML
|
|
||||||
("\\.html$" "__.html" web-mode)
|
|
||||||
;; java
|
|
||||||
("/src/.+/.+\\.java$" "__" java-mode)
|
|
||||||
("/main\\.java$" "__main" java-mode)
|
|
||||||
("/build\\.gradle$" "__build.gradle" android-mode)
|
|
||||||
;; Javascript
|
|
||||||
("\\.lbaction/.+/Info.plist$" "__Info.plst" lb6-mode)
|
|
||||||
("\\.lbaction/.+/\\(default\\|suggestions\\)\\.js$" "__default.js" lb6-mode)
|
|
||||||
("/package\\.json$" "__package.json" json-mode)
|
|
||||||
("/bower\\.json$" "__bower.json" json-mode)
|
|
||||||
("\\.\\(json\\|jshintrc\\)$" "__" json-mode)
|
|
||||||
("/gulpfile\\.js$" "__gulpfile.js" js-mode)
|
|
||||||
;; Lua
|
|
||||||
("/main\\.lua$" "__main.lua" love-mode)
|
|
||||||
("/conf\\.lua$" "__conf.lua" love-mode)
|
|
||||||
;; Markdown
|
|
||||||
("\\.md$" "__" markdown-mode)
|
|
||||||
;; PHP
|
|
||||||
("\\.class\\.php$" "__.class.php" php-mode)
|
|
||||||
("\\.php$" "__" php-mode)
|
|
||||||
;; Python
|
|
||||||
;;("tests?/test_.+\\.py$" "__" nose-mode)
|
|
||||||
;;("/setup\\.py$" "__setup.py" python-mode)
|
|
||||||
("\\.py$" "__" python-mode)
|
|
||||||
;; Ruby
|
|
||||||
("/\\.rspec$" "__.rspec" rspec-mode)
|
|
||||||
("/spec_helper\\.rb$" "__helper" rspec-mode t)
|
|
||||||
("_spec\\.rb$" "__" rspec-mode t)
|
|
||||||
("/Rakefile$" "__Rakefile" ruby-mode t)
|
|
||||||
("/Gemfile$" "__Gemfile" ruby-mode t)
|
|
||||||
("\\.gemspec$" "__.gemspec" ruby-mode t)
|
|
||||||
("/lib/.+\\.rb$" "__module" ruby-mode t)
|
|
||||||
("\\.rb$" "__" ruby-mode)
|
|
||||||
;; Rust
|
|
||||||
("/Cargo.toml$" "__Cargo.toml" rust-mode)
|
|
||||||
("/main\\.rs$" "__main.rs" rust-mode)
|
|
||||||
;; SCSS
|
|
||||||
("/master\\.scss$" "__master.scss" scss-mode)
|
|
||||||
("/normalize\\.scss$" "__normalize.scss" scss-mode)
|
|
||||||
("\\.scss$" "__" scss-mode)
|
|
||||||
;; Slim
|
|
||||||
("/\\(index\\|main\\)\\.slim$" "__" slim-mode)
|
|
||||||
;; Shell scripts
|
|
||||||
("\\.z?sh$" "__" sh-mode)
|
|
||||||
)))
|
|
||||||
|
|
||||||
(provide 'core-autoinsert)
|
|
||||||
;;; core-autoinsert.el ends here
|
|
6
core/core-autoload.el
Normal file
6
core/core-autoload.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;;; core-autoload.el
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'core-autoload)
|
||||||
|
;;; core-autoload.el ends here
|
|
@ -1,55 +0,0 @@
|
||||||
;;; core-company.el
|
|
||||||
|
|
||||||
(use-package company
|
|
||||||
:commands (company-mode global-company-mode company-complete
|
|
||||||
company-complete-common company-manual-begin company-grab-line)
|
|
||||||
:init
|
|
||||||
(setq company-idle-delay nil
|
|
||||||
company-minimum-prefix-length 2
|
|
||||||
company-tooltip-limit 10
|
|
||||||
company-dabbrev-downcase nil
|
|
||||||
company-dabbrev-ignore-case nil
|
|
||||||
company-dabbrev-code-other-buffers t
|
|
||||||
company-tooltip-align-annotations t
|
|
||||||
company-require-match 'never
|
|
||||||
company-global-modes '(not eshell-mode comint-mode erc-mode message-mode help-mode)
|
|
||||||
company-frontends '(company-pseudo-tooltip-frontend company-echo-metadata-frontend)
|
|
||||||
company-backends '(company-capf company-yasnippet)
|
|
||||||
company-quickhelp-delay nil
|
|
||||||
company-statistics-file (concat doom-temp-dir "/company-stats-cache.el"))
|
|
||||||
|
|
||||||
:config
|
|
||||||
(require 'company-capf)
|
|
||||||
(require 'company-yasnippet)
|
|
||||||
|
|
||||||
;; Rewrites evil-complete to use company-dabbrev
|
|
||||||
(setq evil-complete-next-func 'doom/company-evil-complete-next
|
|
||||||
evil-complete-previous-func 'doom/company-evil-complete-previous)
|
|
||||||
|
|
||||||
(push 'company-sort-by-occurrence company-transformers)
|
|
||||||
|
|
||||||
(define-key company-active-map "\C-w" nil)
|
|
||||||
|
|
||||||
(global-company-mode +1)
|
|
||||||
|
|
||||||
;; NOTE: Doesn't look pretty outside of emacs-mac
|
|
||||||
(require 'company-quickhelp)
|
|
||||||
(company-quickhelp-mode +1)
|
|
||||||
|
|
||||||
(require 'company-statistics)
|
|
||||||
(company-statistics-mode +1))
|
|
||||||
|
|
||||||
(use-package company-dabbrev :commands company-dabbrev)
|
|
||||||
(use-package company-dabbrev-code :commands company-dabbrev-code)
|
|
||||||
(use-package company-etags :commands company-etags)
|
|
||||||
(use-package company-elisp :commands company-elisp)
|
|
||||||
(use-package company-files :commands company-files)
|
|
||||||
(use-package company-gtags :commands company-gtags)
|
|
||||||
(use-package company-ispell :commands company-ispell)
|
|
||||||
|
|
||||||
(use-package company-dict
|
|
||||||
:commands company-dict
|
|
||||||
:config (setq company-dict-dir (concat doom-private-dir "/dict")))
|
|
||||||
|
|
||||||
(provide 'core-company)
|
|
||||||
;;; core-company.el ends here
|
|
124
core/core-completion.el
Normal file
124
core/core-completion.el
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
;;; core-completion.el --- auto-completion, for the lazy typist
|
||||||
|
|
||||||
|
(package! company
|
||||||
|
:commands (company-mode company-complete company-complete-common company-manual-begin)
|
||||||
|
:init
|
||||||
|
(setq company-idle-delay nil
|
||||||
|
company-minimum-prefix-length 2
|
||||||
|
company-tooltip-limit 10
|
||||||
|
company-dabbrev-downcase nil
|
||||||
|
company-dabbrev-ignore-case nil
|
||||||
|
company-dabbrev-code-other-buffers t
|
||||||
|
company-tooltip-align-annotations t
|
||||||
|
company-require-match 'never
|
||||||
|
company-global-modes '(not eshell-mode comint-mode erc-mode message-mode help-mode)
|
||||||
|
company-frontends '(company-pseudo-tooltip-frontend company-echo-metadata-frontend)
|
||||||
|
company-backends '(company-capf company-yasnippet)
|
||||||
|
company-quickhelp-delay nil
|
||||||
|
company-statistics-file (concat doom-temp-dir "company-stats-cache.el"))
|
||||||
|
|
||||||
|
;; vim-like omni-complete
|
||||||
|
(map! :i "C-SPC" 'doom/company-complete
|
||||||
|
(:prefix "C-x"
|
||||||
|
:i "C-l" 'doom/company-whole-lines
|
||||||
|
:i "C-k" 'doom/company-dict-or-keywords
|
||||||
|
:i "C-f" 'company-files
|
||||||
|
:i "C-]" 'company-tags
|
||||||
|
:i "s" 'company-ispell
|
||||||
|
:i "C-s" 'company-yasnippet
|
||||||
|
:i "C-o" 'company-capf
|
||||||
|
:i "C-n" 'company-dabbrev-code
|
||||||
|
:i "C-p" (λ! (let ((company-selection-wrap-around t))
|
||||||
|
(call-interactively 'company-dabbrev-code)
|
||||||
|
(company-select-previous-or-abort)))))
|
||||||
|
|
||||||
|
:config
|
||||||
|
(require 'company-capf)
|
||||||
|
(require 'company-yasnippet)
|
||||||
|
(push 'company-sort-by-occurrence company-transformers)
|
||||||
|
;; Don't interfere with insert mode binding for `evil-delete-backward-word'
|
||||||
|
(define-key company-active-map "\C-w" nil)
|
||||||
|
|
||||||
|
(map! (:map company-active-map
|
||||||
|
"C-o" 'company-search-kill-others
|
||||||
|
"C-n" 'company-select-next
|
||||||
|
"C-p" 'company-select-previous
|
||||||
|
"C-h" 'company-quickhelp-manual-begin
|
||||||
|
"C-S-h" 'company-show-doc-buffer
|
||||||
|
"C-S-s" 'company-search-candidates
|
||||||
|
"C-s" 'company-filter-candidates
|
||||||
|
"C-SPC" 'company-complete-common
|
||||||
|
[tab] 'company-complete-common-or-cycle
|
||||||
|
[backtab] 'company-select-previous
|
||||||
|
[escape] (λ! (company-abort) (evil-normal-state 1))
|
||||||
|
[C-return] 'counsel-company)
|
||||||
|
|
||||||
|
(:map company-search-map
|
||||||
|
"C-n" 'company-search-repeat-forward
|
||||||
|
"C-p" 'company-search-repeat-backward
|
||||||
|
[escape] 'company-search-abort))
|
||||||
|
|
||||||
|
(global-company-mode +1))
|
||||||
|
|
||||||
|
(package! company-dict
|
||||||
|
:commands company-dict
|
||||||
|
:config (setq company-dict-dir (concat doom-private-dir "dict")))
|
||||||
|
|
||||||
|
;; NOTE: Doesn't look pretty on OSX without emacs-mac
|
||||||
|
(package! company-quickhelp
|
||||||
|
:after company
|
||||||
|
:config (company-quickhelp-mode +1))
|
||||||
|
|
||||||
|
(package! company-statistics
|
||||||
|
:after company
|
||||||
|
:config (company-statistics-mode +1))
|
||||||
|
|
||||||
|
;;
|
||||||
|
(autoload 'company-dabbrev "company-dabbrev" nil t)
|
||||||
|
(autoload 'company-dabbrev-code "company-dabbrev-code" nil t)
|
||||||
|
(autoload 'company-etags "company-etags" nil t)
|
||||||
|
(autoload 'company-elisp "company-elisp" nil t)
|
||||||
|
(autoload 'company-files "company-files" nil t)
|
||||||
|
(autoload 'company-gtags "company-gtags" nil t)
|
||||||
|
(autoload 'company-ispell "company-ispell" nil t)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Defuns
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defun doom/company-complete ()
|
||||||
|
"Bring up the completion popup. If only one result, complete it."
|
||||||
|
(interactive)
|
||||||
|
(require 'company)
|
||||||
|
(when (and (company-manual-begin)
|
||||||
|
(= company-candidates-length 1))
|
||||||
|
(company-complete-common)))
|
||||||
|
|
||||||
|
(defun doom/company-whole-lines (command &optional arg &rest ignored)
|
||||||
|
"`company-mode' completion backend that completes whole-lines, akin to vim's
|
||||||
|
C-x C-l."
|
||||||
|
(interactive (list 'interactive))
|
||||||
|
(require 'company)
|
||||||
|
(unless (bound-and-true-p company-mode) (company-mode))
|
||||||
|
(let ((lines (split-string
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"^[\t\s]+" ""
|
||||||
|
(concat (buffer-substring-no-properties (point-min) (line-beginning-position))
|
||||||
|
(buffer-substring-no-properties (line-end-position) (point-max))))
|
||||||
|
"\\(\r\n\\|[\n\r]\\)" t)))
|
||||||
|
(cl-case command
|
||||||
|
(interactive (company-begin-backend 'doom/company-whole-lines))
|
||||||
|
(prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
|
||||||
|
(candidates (all-completions arg lines)))))
|
||||||
|
|
||||||
|
(defun doom/company-dict-or-keywords ()
|
||||||
|
"`company-mode' completion combining `company-dict' and `company-keywords'."
|
||||||
|
(interactive)
|
||||||
|
(require 'company-dict)
|
||||||
|
(require 'company-keywords)
|
||||||
|
(let ((company-backends '((company-keywords company-dict))))
|
||||||
|
(call-interactively 'company-complete)))
|
||||||
|
|
||||||
|
(provide 'core-completion)
|
||||||
|
;;; core-completion.el ends here
|
33
core/core-dashboard.el
Normal file
33
core/core-dashboard.el
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
;;; core-dashboard.el
|
||||||
|
|
||||||
|
(setq initial-major-mode 'doom-mode
|
||||||
|
initial-scratch-message "\n Loading..."
|
||||||
|
inhibit-startup-screen t
|
||||||
|
;; shuts up emacs at startup
|
||||||
|
inhibit-startup-echo-area-message user-login-name)
|
||||||
|
|
||||||
|
(define-derived-mode doom-mode special-mode
|
||||||
|
(concat "v" doom-version)
|
||||||
|
"Major mode for DOOM buffers.")
|
||||||
|
|
||||||
|
(define-derived-mode doom-dashboard-mode doom-mode
|
||||||
|
(concat "v" doom-version)
|
||||||
|
"Major mode for DOOM buffers.")
|
||||||
|
|
||||||
|
(defvar doom-dashboard-buffer value
|
||||||
|
"")
|
||||||
|
|
||||||
|
(defvar doom-dashboard-buffer-name " *doom*"
|
||||||
|
"")
|
||||||
|
|
||||||
|
(defvar doom-dashboard--edited nil
|
||||||
|
"")
|
||||||
|
|
||||||
|
(defvar doom-dashboard-inhibit-reload nil
|
||||||
|
"")
|
||||||
|
|
||||||
|
(defvar doom-dashboard-mode-line-format (assq 'minimal doom-modeline-formats)
|
||||||
|
"")
|
||||||
|
|
||||||
|
(provide 'core-dashboard)
|
||||||
|
;;; core-dashboard.el ends here
|
|
@ -1,429 +0,0 @@
|
||||||
;;; core-defuns.el
|
|
||||||
|
|
||||||
;; Bootstrap macro
|
|
||||||
(defmacro doom (&rest packages)
|
|
||||||
"Bootstrap DOOM emacs and initialize PACKAGES"
|
|
||||||
`(let (file-name-handler-alist)
|
|
||||||
;; Local settings
|
|
||||||
(load "~/.emacs.local.el" t t)
|
|
||||||
;; Bootstrap
|
|
||||||
(unless noninteractive
|
|
||||||
,@(mapcar (lambda (pkg)
|
|
||||||
(let ((lib-path (locate-library (symbol-name pkg))))
|
|
||||||
(unless lib-path
|
|
||||||
(error "Initfile not found: %s" pkg))
|
|
||||||
`(require ',pkg ,(file-name-sans-extension lib-path))))
|
|
||||||
packages)
|
|
||||||
(when window-system
|
|
||||||
(require 'server)
|
|
||||||
(unless (server-running-p)
|
|
||||||
(server-start)))
|
|
||||||
;; Prevent any auto-displayed text + benchmarking
|
|
||||||
(advice-add 'display-startup-echo-area-message :override 'ignore)
|
|
||||||
(message ""))
|
|
||||||
(setq-default gc-cons-threshold 4388608
|
|
||||||
gc-cons-percentage 0.4)))
|
|
||||||
|
|
||||||
;; Backwards compatible `with-eval-after-load'
|
|
||||||
(unless (fboundp 'with-eval-after-load)
|
|
||||||
(defmacro with-eval-after-load (file &rest body)
|
|
||||||
`(eval-after-load ,file (lambda () ,@body))))
|
|
||||||
|
|
||||||
(defmacro λ! (&rest body)
|
|
||||||
"A shortcut for inline keybind lambdas."
|
|
||||||
`(lambda () (interactive) ,@body))
|
|
||||||
|
|
||||||
(defmacro shut-up! (&rest body)
|
|
||||||
"Silence message output from code."
|
|
||||||
(declare (indent defun))
|
|
||||||
`(let (message-log-max) ,@body (message "")))
|
|
||||||
|
|
||||||
(defmacro after! (feature &rest forms)
|
|
||||||
"A smart wrapper around `with-eval-after-load', that supresses warnings
|
|
||||||
during compilation."
|
|
||||||
(declare (indent defun) (debug t))
|
|
||||||
`(,(if (or (not (boundp 'byte-compile-current-file))
|
|
||||||
(not byte-compile-current-file)
|
|
||||||
(if (symbolp feature)
|
|
||||||
(require feature nil :no-error)
|
|
||||||
(load feature :no-message :no-error)))
|
|
||||||
'progn
|
|
||||||
(message "after: cannot find %s" feature)
|
|
||||||
'with-no-warnings)
|
|
||||||
(with-eval-after-load ',feature ,@forms)))
|
|
||||||
|
|
||||||
(defmacro noop! (name &optional args)
|
|
||||||
`(defun ,name ,args (interactive) (error "%s not implemented!" name)))
|
|
||||||
|
|
||||||
(defmacro add-hook! (hook &rest func-or-forms)
|
|
||||||
"A convenience macro for `add-hook'.
|
|
||||||
|
|
||||||
HOOK can be one hook or a list of hooks. If the hook(s) are not quoted, -hook is
|
|
||||||
appended to them automatically. If they are quoted, they are used verbatim.
|
|
||||||
|
|
||||||
FUNC-OR-FORMS can be a quoted symbol, a list of quoted symbols, or forms. Forms will be
|
|
||||||
wrapped in a lambda. A list of symbols will expand into a series of add-hook calls.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
(add-hook! 'some-mode-hook 'enable-something)
|
|
||||||
(add-hook! some-mode '(enable-something and-another))
|
|
||||||
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
|
|
||||||
(add-hook! (one-mode second-mode) 'enable-something)
|
|
||||||
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))"
|
|
||||||
(declare (indent defun) (debug t))
|
|
||||||
(unless func-or-forms
|
|
||||||
(error "add-hook!: FUNC-OR-FORMS is empty"))
|
|
||||||
(let* ((val (car func-or-forms))
|
|
||||||
(quoted (eq (car-safe hook) 'quote))
|
|
||||||
(hook (if quoted (cadr hook) hook))
|
|
||||||
(funcs (if (eq (car-safe val) 'quote)
|
|
||||||
(if (cdr-safe (cadr val))
|
|
||||||
(cadr val)
|
|
||||||
(list (cadr val)))
|
|
||||||
(list func-or-forms)))
|
|
||||||
(forms '()))
|
|
||||||
(mapc
|
|
||||||
(lambda (f)
|
|
||||||
(let ((func (cond ((symbolp f) `(quote ,f))
|
|
||||||
(t `(lambda (&rest _) ,@func-or-forms)))))
|
|
||||||
(mapc
|
|
||||||
(lambda (h)
|
|
||||||
(push `(add-hook ',(if quoted h (intern (format "%s-hook" h))) ,func) forms))
|
|
||||||
(-list hook)))) funcs)
|
|
||||||
`(progn ,@forms)))
|
|
||||||
|
|
||||||
(defmacro associate! (mode &rest rest)
|
|
||||||
"Associate a major or minor mode to certain patterns and project files."
|
|
||||||
(declare (indent 1))
|
|
||||||
(let ((minor (plist-get rest :minor))
|
|
||||||
(in (plist-get rest :in))
|
|
||||||
(match (plist-get rest :match))
|
|
||||||
(files (plist-get rest :files))
|
|
||||||
(pred (plist-get rest :when)))
|
|
||||||
`(progn
|
|
||||||
(,@(cond ((or files in pred)
|
|
||||||
(when (and files (not (or (listp files) (stringp files))))
|
|
||||||
(user-error "associate! :files expects a string or list of strings"))
|
|
||||||
(let ((hook-name (intern (format "doom--init-mode-%s" mode))))
|
|
||||||
`(progn
|
|
||||||
(defun ,hook-name ()
|
|
||||||
(when (and ,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t)
|
|
||||||
(or ,(not files)
|
|
||||||
(and (boundp ',mode)
|
|
||||||
(not ,mode)
|
|
||||||
(doom/project-has-files ,@(-list files))))
|
|
||||||
(or (not ,pred)
|
|
||||||
(funcall ,pred buffer-file-name)))
|
|
||||||
(,mode 1)))
|
|
||||||
,@(if (and in (listp in))
|
|
||||||
(mapcar (lambda (h) `(add-hook ',h ',hook-name))
|
|
||||||
(mapcar (lambda (m) (intern (format "%s-hook" m))) in))
|
|
||||||
`((add-hook 'find-file-hook ',hook-name))))))
|
|
||||||
(match
|
|
||||||
`(add-to-list ',(if minor 'doom-auto-minor-mode-alist 'auto-mode-alist)
|
|
||||||
(cons ,match ',mode)))
|
|
||||||
(t (user-error "associate! invalid rules for mode [%s] (in %s) (match %s) (files %s)"
|
|
||||||
mode in match files)))))))
|
|
||||||
|
|
||||||
(defmacro def-project-type! (name lighter &rest body)
|
|
||||||
"Define a minor mode for a specific framework, library or project type."
|
|
||||||
(declare (indent 2))
|
|
||||||
(let* ((mode-name (format "%s-project-mode" name))
|
|
||||||
(mode (intern mode-name))
|
|
||||||
(mode-map (intern (format "%s-map" mode-name)))
|
|
||||||
(mode-hook-sym (intern (format "%s-hook" mode-name)))
|
|
||||||
(mode-init-sym (intern (format "doom--init-project-%s" mode-name))))
|
|
||||||
(let ((modes (plist-get body :modes))
|
|
||||||
(pred (plist-get body :when))
|
|
||||||
(match (plist-get body :match))
|
|
||||||
(files (plist-get body :files))
|
|
||||||
(build (plist-get body :build))
|
|
||||||
(bind (plist-get body :bind))
|
|
||||||
elem)
|
|
||||||
(while (keywordp (car body))
|
|
||||||
(pop body)
|
|
||||||
(pop body))
|
|
||||||
`(progn
|
|
||||||
(define-minor-mode ,mode
|
|
||||||
"Auto-generated by `def-project-type!'"
|
|
||||||
:init-value nil
|
|
||||||
:lighter ,(concat " " lighter)
|
|
||||||
:keymap (make-sparse-keymap))
|
|
||||||
|
|
||||||
(after! yasnippet
|
|
||||||
(add-hook ',mode-hook-sym
|
|
||||||
(lambda ()
|
|
||||||
(if ,mode
|
|
||||||
(yas-activate-extra-mode ',mode)
|
|
||||||
(yas-deactivate-extra-mode ',mode)))))
|
|
||||||
|
|
||||||
,(when bind `(map! :map ,mode-map ,bind))
|
|
||||||
|
|
||||||
(associate! ,mode
|
|
||||||
:minor t
|
|
||||||
:in ,modes
|
|
||||||
:match ,match
|
|
||||||
:files ,files
|
|
||||||
:when ,pred)
|
|
||||||
|
|
||||||
(defun ,mode-init-sym ()
|
|
||||||
(after! company-dict
|
|
||||||
(push ',mode company-dict-minor-mode-list))
|
|
||||||
,(when build
|
|
||||||
(let ((cmd build) file)
|
|
||||||
(when (and (not (functionp build)) (listp build))
|
|
||||||
(setq cmd (car-safe (cdr-safe build))
|
|
||||||
file (cdr-safe (cdr-safe build))))
|
|
||||||
`(def-builder! ,mode ,cmd ,file)))
|
|
||||||
,@body
|
|
||||||
(remove-hook ',mode-hook-sym ',mode-init-sym))
|
|
||||||
(add-hook ',mode-hook-sym ',mode-init-sym)
|
|
||||||
',mode))))
|
|
||||||
|
|
||||||
|
|
||||||
(after! evil
|
|
||||||
(defalias 'ex! 'evil-ex-define-cmd)
|
|
||||||
|
|
||||||
;; NOTE evil-mode doesn't read local `evil-ex-commands', and will not
|
|
||||||
;; autocomplete local commands.
|
|
||||||
(defun ex-local! (cmd fn)
|
|
||||||
"Define a buffer-local ex command."
|
|
||||||
(unless (local-variable-p 'evil-ex-commands)
|
|
||||||
(setq-local evil-ex-commands (copy-alist evil-ex-commands)))
|
|
||||||
(evil-ex-define-cmd cmd fn))
|
|
||||||
|
|
||||||
;; Register keywords for proper indentation (see `map!')
|
|
||||||
(put ':prefix 'lisp-indent-function 'defun)
|
|
||||||
(put ':map 'lisp-indent-function 'defun)
|
|
||||||
(put ':map* 'lisp-indent-function 'defun)
|
|
||||||
(put ':after 'lisp-indent-function 'defun)
|
|
||||||
(put ':when 'lisp-indent-function 'defun)
|
|
||||||
(put ':unless 'lisp-indent-function 'defun)
|
|
||||||
(put ':leader 'lisp-indent-function 'defun)
|
|
||||||
(put ':localleader 'lisp-indent-function 'defun)
|
|
||||||
|
|
||||||
(defmacro map! (&rest rest)
|
|
||||||
"A nightmare of a key-binding macro that will use `evil-define-key',
|
|
||||||
`evil-define-key*', `define-key' and `global-set-key' depending on context and
|
|
||||||
plist key flags. It was designed to make binding multiple keys more concise,
|
|
||||||
like in vim.
|
|
||||||
|
|
||||||
Yes, it tries to do too much. Yes, I only did it to make the \"frontend\" config
|
|
||||||
that little bit more concise. Yes, I could simply have used the above functions.
|
|
||||||
But it takes a little insanity to custom write your own emacs.d, so what else
|
|
||||||
were you expecting?
|
|
||||||
|
|
||||||
States
|
|
||||||
:n normal
|
|
||||||
:v visual
|
|
||||||
:i insert
|
|
||||||
:e emacs
|
|
||||||
:o operator
|
|
||||||
:m motion
|
|
||||||
:r replace
|
|
||||||
:L local
|
|
||||||
|
|
||||||
These can be combined (order doesn't matter), e.g. :nvi will apply to
|
|
||||||
normal, visual and insert mode. The state resets after the following
|
|
||||||
key=>def pair.
|
|
||||||
|
|
||||||
Capitalize the state flag to make it a local binding.
|
|
||||||
|
|
||||||
If omitted, the keybind will be defined globally.
|
|
||||||
|
|
||||||
Flags
|
|
||||||
:unset [KEY] ; unset key
|
|
||||||
(:map [KEYMAP] [...]) ; apply inner keybinds to KEYMAP
|
|
||||||
(:map* [KEYMAP] [...]) ; apply inner keybinds to KEYMAP (deferred)
|
|
||||||
(:prefix [PREFIX] [...]) ; assign prefix to all inner keybindings
|
|
||||||
(:after [FEATURE] [...]) ; apply keybinds when [FEATURE] loads
|
|
||||||
|
|
||||||
Conditional keybinds
|
|
||||||
(:when [CONDITION] [...])
|
|
||||||
(:unless [CONDITION] [...])
|
|
||||||
|
|
||||||
Example
|
|
||||||
(map! :map magit-mode-map
|
|
||||||
:m \"C-r\" 'do-something ; assign C-r in motion state
|
|
||||||
:nv \"q\" 'magit-mode-quit-window ; assign to 'q' in normal and visual states
|
|
||||||
\"C-x C-r\" 'a-global-keybind
|
|
||||||
|
|
||||||
(:when IS-MAC
|
|
||||||
:n \"M-s\" 'some-fn
|
|
||||||
:i \"M-o\" (lambda (interactive) (message \"Hi\"))))"
|
|
||||||
(let ((keymaps (if (boundp 'keymaps) keymaps))
|
|
||||||
(state-map '(("n" . normal)
|
|
||||||
("v" . visual)
|
|
||||||
("i" . insert)
|
|
||||||
("e" . emacs)
|
|
||||||
("o" . operator)
|
|
||||||
("m" . motion)
|
|
||||||
("r" . replace)))
|
|
||||||
(prefix (if (boundp 'prefix) prefix))
|
|
||||||
(defer (if (boundp 'defer) defer))
|
|
||||||
local key def states forms)
|
|
||||||
(while rest
|
|
||||||
(setq key (pop rest))
|
|
||||||
(push
|
|
||||||
(reverse
|
|
||||||
(cond
|
|
||||||
;; it's a sub expr
|
|
||||||
((listp key)
|
|
||||||
`(,(macroexpand `(map! ,@key))))
|
|
||||||
|
|
||||||
;; it's a flag
|
|
||||||
((keywordp key)
|
|
||||||
(when (memq key '(:leader :localleader))
|
|
||||||
(push (cond ((eq key :leader)
|
|
||||||
doom-leader)
|
|
||||||
((eq key :localleader)
|
|
||||||
doom-localleader))
|
|
||||||
rest)
|
|
||||||
(setq key :prefix))
|
|
||||||
(pcase key
|
|
||||||
(:prefix (setq prefix (concat prefix (kbd (pop rest)))) nil)
|
|
||||||
(:map (setq keymaps (-list (pop rest))) nil)
|
|
||||||
(:map* (setq defer t keymaps (-list (pop rest))) nil)
|
|
||||||
(:unset `(,(macroexpand `(map! ,(kbd (pop rest)) nil))))
|
|
||||||
(:after (prog1 `((after! ,(pop rest) ,(macroexpand `(map! ,@rest)))) (setq rest '())))
|
|
||||||
(:when (prog1 `((if ,(pop rest) ,(macroexpand `(map! ,@rest)))) (setq rest '())))
|
|
||||||
(:unless (prog1 `((if (not ,(pop rest)) ,(macroexpand `(map! ,@rest)))) (setq rest '())))
|
|
||||||
(otherwise ; might be a state prefix
|
|
||||||
(mapc (lambda (letter)
|
|
||||||
(cond ((assoc letter state-map)
|
|
||||||
(push (cdr (assoc letter state-map)) states))
|
|
||||||
((string= letter "L")
|
|
||||||
(setq local t))
|
|
||||||
(t (user-error "Invalid mode prefix %s in key %s" letter key))))
|
|
||||||
(split-string (substring (symbol-name key) 1) "" t))
|
|
||||||
(unless states
|
|
||||||
(user-error "Unrecognized keyword %s" key))
|
|
||||||
(when (assoc "L" states)
|
|
||||||
(cond ((= (length states) 1)
|
|
||||||
(user-error "local keybinding for %s must accompany another state" key))
|
|
||||||
((> (length keymaps) 0)
|
|
||||||
(user-error "local keybinding for %s cannot accompany a keymap" key))))
|
|
||||||
nil)))
|
|
||||||
|
|
||||||
;; It's a key-def pair
|
|
||||||
((or (stringp key)
|
|
||||||
(characterp key)
|
|
||||||
(vectorp key))
|
|
||||||
(when (stringp key)
|
|
||||||
(setq key (kbd key)))
|
|
||||||
(when prefix
|
|
||||||
(setq key (cond ((vectorp key) (vconcat prefix key))
|
|
||||||
(t (concat prefix key)))))
|
|
||||||
(unless (> (length rest) 0)
|
|
||||||
(user-error "Map has no definition for %s" key))
|
|
||||||
(setq def (pop rest))
|
|
||||||
(let (out-forms)
|
|
||||||
(cond ((and keymaps states)
|
|
||||||
(mapc (lambda (keymap)
|
|
||||||
(push `(,(if defer 'evil-define-key 'evil-define-key*)
|
|
||||||
',states ,keymap ,key ,def)
|
|
||||||
out-forms))
|
|
||||||
keymaps))
|
|
||||||
(keymaps
|
|
||||||
(mapc (lambda (keymap) (push `(define-key ,keymap ,key ,def) out-forms))
|
|
||||||
keymaps))
|
|
||||||
(states
|
|
||||||
(mapc (lambda (state)
|
|
||||||
(push `(define-key
|
|
||||||
(evil-state-property ',state ,(if local :local-keymap :keymap) t)
|
|
||||||
,key ,def)
|
|
||||||
out-forms))
|
|
||||||
states))
|
|
||||||
(t (push `(,(if local 'local-set-key 'global-set-key)
|
|
||||||
,key ,def)
|
|
||||||
out-forms)))
|
|
||||||
(setq states '()
|
|
||||||
local nil)
|
|
||||||
out-forms))
|
|
||||||
|
|
||||||
(t (user-error "Invalid key %s" key))))
|
|
||||||
forms))
|
|
||||||
`(progn ,@(apply #'nconc (delete nil (delete (list nil) (reverse forms))))))))
|
|
||||||
|
|
||||||
(defmacro def-repeat! (command next-func prev-func)
|
|
||||||
"Repeat motions with SPC/S-SPC"
|
|
||||||
`(defadvice ,command
|
|
||||||
(before ,(intern (format "doom-space--%s" (symbol-name command))) activate)
|
|
||||||
(define-key evil-motion-state-map (kbd "SPC") ',next-func)
|
|
||||||
(define-key evil-motion-state-map (kbd "S-SPC") ',prev-func)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Global Defuns
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defsubst --subdirs (path &optional include-self)
|
|
||||||
"Get list of subdirectories in PATH, including PATH is INCLUDE-SELF is
|
|
||||||
non-nil."
|
|
||||||
(let ((result (if include-self (list path) (list))))
|
|
||||||
(mapc (lambda (file)
|
|
||||||
(when (file-directory-p file)
|
|
||||||
(push file result)))
|
|
||||||
(ignore-errors (directory-files path t "^[^.]" t)))
|
|
||||||
result))
|
|
||||||
|
|
||||||
(defun doom-reload ()
|
|
||||||
"Reload `load-path' and `custom-theme-load-path', in case you updated cask
|
|
||||||
while emacs was open!"
|
|
||||||
(interactive)
|
|
||||||
(let* ((-packages-path (--subdirs doom-packages-dir))
|
|
||||||
(-load-path
|
|
||||||
(append (list doom-private-dir doom-core-dir doom-modules-dir doom-packages-dir)
|
|
||||||
(--subdirs doom-core-dir t)
|
|
||||||
(--subdirs doom-modules-dir t)
|
|
||||||
-packages-path
|
|
||||||
(--subdirs (expand-file-name (format "../../%s/bootstrap" emacs-version)
|
|
||||||
doom-packages-dir))
|
|
||||||
doom--load-path))
|
|
||||||
(-custom-theme-load-path
|
|
||||||
(append (--subdirs doom-themes-dir t)
|
|
||||||
custom-theme-load-path)))
|
|
||||||
(setq load-path -load-path
|
|
||||||
custom-theme-load-path -custom-theme-load-path)
|
|
||||||
(if (called-interactively-p 'interactive)
|
|
||||||
(message "Reloaded!")
|
|
||||||
(list -load-path
|
|
||||||
-custom-theme-load-path
|
|
||||||
(mapcar '--subdirs -packages-path)))))
|
|
||||||
|
|
||||||
(defun doom-reload-autoloads ()
|
|
||||||
"Regenerate and reload autoloads.el."
|
|
||||||
(interactive)
|
|
||||||
(let ((generated-autoload-file (concat doom-core-dir "/autoloads.el")))
|
|
||||||
(when (file-exists-p generated-autoload-file)
|
|
||||||
(delete-file generated-autoload-file)
|
|
||||||
(message "Deleted old autoloads.el"))
|
|
||||||
(mapc (lambda (dir)
|
|
||||||
(update-directory-autoloads (concat dir "/defuns"))
|
|
||||||
(message "Scanned: %s" dir))
|
|
||||||
(list doom-core-dir doom-modules-dir))
|
|
||||||
(when (called-interactively-p 'interactive)
|
|
||||||
(load "autoloads"))
|
|
||||||
(message "Done!")))
|
|
||||||
|
|
||||||
(defun doom-byte-compile (&optional minimal)
|
|
||||||
"Byte compile the core and library .el files in ~/.emacs.d. If MINIMAL is nil,
|
|
||||||
only byte compile a few important files. If t, compile all files too. If 'basic,
|
|
||||||
only compile defun libraries."
|
|
||||||
(interactive)
|
|
||||||
(mapc (lambda (f) (byte-compile-file (concat doom-emacs-dir "/" f) t))
|
|
||||||
'("init.el" "core/core.el" "core/core-defuns.el" "core/core-ui.el"
|
|
||||||
"core/core-modeline.el" "core/core-os.el" "core/core-os-osx.el"
|
|
||||||
"core/core-os-win32.el" "core/core-os-linux.el"
|
|
||||||
"private/my-commands.el" "private/my-bindings.el"))
|
|
||||||
(unless (eq minimal 'basic)
|
|
||||||
(unless minimal
|
|
||||||
(byte-recompile-directory doom-core-dir 0 t)
|
|
||||||
(byte-recompile-directory doom-modules-dir 0 t))
|
|
||||||
(when minimal
|
|
||||||
(byte-recompile-directory (concat doom-core-dir "/defuns") 0 t)
|
|
||||||
(byte-recompile-directory (concat doom-modules-dir "/defuns") 0 t)))
|
|
||||||
(message "Compiled!"))
|
|
||||||
|
|
||||||
(provide 'core-defuns)
|
|
||||||
;;; core-defuns.el ends here
|
|
|
@ -1,42 +0,0 @@
|
||||||
;;; core-docs.el
|
|
||||||
|
|
||||||
(use-package dash-at-point
|
|
||||||
:when IS-MAC
|
|
||||||
:commands (dash-at-point dash-at-point-with-docset dash-at-point-run-search
|
|
||||||
dash-at-point-guess-docset)
|
|
||||||
:init
|
|
||||||
(defun doom-docs-lookup (&optional search all)
|
|
||||||
(let ((docset (unless all (dash-at-point-guess-docset))))
|
|
||||||
(dash-at-point-run-search search docset))))
|
|
||||||
|
|
||||||
(use-package zeal-at-point
|
|
||||||
:when (not IS-MAC)
|
|
||||||
:commands (zeal-at-point zeal-at-point-set-docset)
|
|
||||||
:init
|
|
||||||
(defun doom-docs-lookup (&optional search all)
|
|
||||||
(let ((zeal-at-point-docset (if all "" zeal-at-point-docset)))
|
|
||||||
(zeal-at-point search))))
|
|
||||||
|
|
||||||
(defmacro def-docset! (mode docset)
|
|
||||||
`(add-hook! ,mode
|
|
||||||
(setq-local ,(if IS-MAC 'dash-at-point-docset 'zeal-at-point-docset)
|
|
||||||
,docset)))
|
|
||||||
|
|
||||||
(use-package google-this
|
|
||||||
:commands (google-this-search
|
|
||||||
google-this-lucky-and-insert-url
|
|
||||||
google-this-lucky-search
|
|
||||||
google-this-string
|
|
||||||
google-this-line
|
|
||||||
google-this-ray
|
|
||||||
google-this-word
|
|
||||||
google-this-symbol
|
|
||||||
google-this-region
|
|
||||||
google-this
|
|
||||||
google-this-noconfirm
|
|
||||||
google-this-error
|
|
||||||
google-this-cpp-reference
|
|
||||||
google-this-forecast))
|
|
||||||
|
|
||||||
(provide 'core-docs)
|
|
||||||
;;; core-docs.el ends here
|
|
|
@ -1,58 +1,58 @@
|
||||||
;;; core-editor.el
|
;;; core-editor.el --- filling the editor shaped hole in the Emacs OS
|
||||||
|
|
||||||
(global-auto-revert-mode 1) ; revert buffers for changed files
|
;; Bookmarks
|
||||||
;; Enable syntax highlighting for older emacs
|
(setq bookmark-default-file (concat doom-temp-dir "/bookmarks")
|
||||||
(unless (bound-and-true-p global-font-lock-mode)
|
bookmark-save-flag t)
|
||||||
(global-font-lock-mode t))
|
|
||||||
|
|
||||||
(setq-default
|
;; Formatting
|
||||||
;; Formatting
|
(setq delete-trailing-lines nil
|
||||||
delete-trailing-lines nil
|
fill-column 80
|
||||||
fill-column 80
|
sentence-end-double-space nil)
|
||||||
;; Spaces, not tabs
|
|
||||||
indent-tabs-mode nil
|
;; Scrolling
|
||||||
require-final-newline t
|
(setq hscroll-margin 1
|
||||||
tab-always-indent t
|
hscroll-step 1
|
||||||
tab-width 4
|
scroll-conservatively 1001
|
||||||
;; Wrapping
|
scroll-margin 0
|
||||||
truncate-lines t
|
scroll-preserve-screen-position t)
|
||||||
truncate-partial-width-windows 50
|
|
||||||
visual-fill-column-center-text nil
|
;; Whitespace (see `editorconfig')
|
||||||
word-wrap t
|
(setq indent-tabs-mode nil
|
||||||
;; Scrolling
|
require-final-newline t
|
||||||
hscroll-margin 1
|
tab-always-indent t
|
||||||
hscroll-step 1
|
tab-width 4
|
||||||
scroll-conservatively 1001
|
tabify-regexp "^\t* [ \t]+" ; for :retab
|
||||||
scroll-margin 0
|
whitespace-line-column fill-column
|
||||||
scroll-preserve-screen-position t
|
whitespace-style
|
||||||
;; Regions
|
'(face tabs tab-mark trailing indentation lines-tail)
|
||||||
shift-select-mode t
|
whitespace-display-mappings
|
||||||
;; Whitespace
|
'((tab-mark ?\t [?› ?\t]) (newline-mark 10 [36 10])))
|
||||||
tabify-regexp "^\t* [ \t]+"
|
|
||||||
whitespace-line-column fill-column
|
;; Wrapping
|
||||||
whitespace-style '(face tabs tab-mark
|
(setq truncate-lines t
|
||||||
trailing indentation lines-tail)
|
truncate-partial-width-windows 50
|
||||||
whitespace-display-mappings
|
visual-fill-column-center-text nil
|
||||||
'((tab-mark ?\t [?› ?\t])
|
word-wrap t)
|
||||||
(newline-mark 10 [36 10])))
|
|
||||||
|
;; Regions
|
||||||
|
(setq shift-select-mode t)
|
||||||
|
|
||||||
;; Save point across sessions
|
;; Save point across sessions
|
||||||
(require 'saveplace)
|
(require 'saveplace)
|
||||||
(setq-default
|
(setq save-place-file (concat doom-temp-dir "saveplace")
|
||||||
save-place-file (concat doom-temp-dir "/saveplace")
|
save-place t)
|
||||||
save-place t)
|
|
||||||
(when (>= emacs-major-version 25)
|
(when (>= emacs-major-version 25)
|
||||||
(save-place-mode +1))
|
(save-place-mode +1))
|
||||||
|
|
||||||
;; Save history across sessions
|
;; Save history across sessions
|
||||||
(require 'savehist)
|
(require 'savehist)
|
||||||
(setq savehist-file (concat doom-temp-dir "/savehist")
|
(setq savehist-file (concat doom-temp-dir "savehist")
|
||||||
savehist-save-minibuffer-history t
|
savehist-save-minibuffer-history t
|
||||||
savehist-additional-variables
|
savehist-additional-variables
|
||||||
'(kill-ring search-ring regexp-search-ring))
|
'(kill-ring search-ring regexp-search-ring))
|
||||||
(savehist-mode 1)
|
(savehist-mode 1)
|
||||||
|
|
||||||
;; Remove text property cruft from history
|
;; Remove text-property cruft from history
|
||||||
(defun unpropertize-savehist ()
|
(defun unpropertize-savehist ()
|
||||||
(mapc (lambda (list)
|
(mapc (lambda (list)
|
||||||
(when (boundp list)
|
(when (boundp list)
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
;; Keep track of recently opened files
|
;; Keep track of recently opened files
|
||||||
(require 'recentf)
|
(require 'recentf)
|
||||||
(setq recentf-save-file (concat doom-temp-dir "/recentf")
|
(setq recentf-save-file (concat doom-temp-dir "recentf")
|
||||||
recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
||||||
"emacs\\.d/private/cache/.+" "emacs\\.d/workgroups/.+$"
|
"emacs\\.d/private/cache/.+" "emacs\\.d/workgroups/.+$"
|
||||||
"wg-default" "/company-statistics-cache.el$"
|
"wg-default" "/company-statistics-cache.el$"
|
||||||
|
@ -76,18 +76,21 @@
|
||||||
recentf-filename-handlers '(abbreviate-file-name))
|
recentf-filename-handlers '(abbreviate-file-name))
|
||||||
(recentf-mode 1)
|
(recentf-mode 1)
|
||||||
|
|
||||||
;; window config undo/redo
|
;; Ediff
|
||||||
(setq winner-dont-bind-my-keys t)
|
(add-hook! ediff-load
|
||||||
(require 'winner)
|
(setq ediff-diff-options "-w"
|
||||||
;; Ignore all special buffers
|
ediff-split-window-function 'split-window-horizontally
|
||||||
(advice-add 'winner-window-list :filter-return 'doom*winner-window-list)
|
ediff-window-setup-function 'ediff-setup-windows-plain)) ; no extra frames
|
||||||
(defun doom*winner-window-list (windows)
|
|
||||||
(-remove (lambda (win) (string-match-p "^\\s-*\\*" (buffer-name (window-buffer win))))
|
|
||||||
windows))
|
|
||||||
(winner-mode 1)
|
|
||||||
|
|
||||||
;; Let editorconfig handle global whitespace settings
|
;; revert buffers for changed files
|
||||||
(use-package editorconfig :demand t
|
(global-auto-revert-mode +1)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Plugins
|
||||||
|
;;
|
||||||
|
|
||||||
|
(package! editorconfig :demand t
|
||||||
:mode ("\\.?editorconfig$" . editorconfig-conf-mode)
|
:mode ("\\.?editorconfig$" . editorconfig-conf-mode)
|
||||||
:config (editorconfig-mode +1)
|
:config (editorconfig-mode +1)
|
||||||
(push 'doom-mode editorconfig-exclude-modes)
|
(push 'doom-mode editorconfig-exclude-modes)
|
||||||
|
@ -95,164 +98,15 @@
|
||||||
(add-hook! 'editorconfig-custom-hooks
|
(add-hook! 'editorconfig-custom-hooks
|
||||||
(if indent-tabs-mode (whitespace-mode +1))))
|
(if indent-tabs-mode (whitespace-mode +1))))
|
||||||
|
|
||||||
|
(package! smartparens :demand t
|
||||||
;;
|
|
||||||
;; Hooks 'n hacks
|
|
||||||
;;
|
|
||||||
|
|
||||||
(associate! makefile-gmake-mode :match "/Makefile$")
|
|
||||||
(add-hook! special-mode (setq truncate-lines nil))
|
|
||||||
;; If file is oversized...
|
|
||||||
(add-hook! find-file
|
|
||||||
(when (> (buffer-size) 1048576)
|
|
||||||
(setq buffer-read-only t)
|
|
||||||
(buffer-disable-undo)
|
|
||||||
(fundamental-mode)
|
|
||||||
(visual-line-mode)))
|
|
||||||
|
|
||||||
(defadvice delete-trailing-whitespace
|
|
||||||
(around delete-trailing-whitespace-ignore-line activate)
|
|
||||||
"Don't delete trailing whitespace on current line, if in insert mode."
|
|
||||||
(let ((spaces (1- (current-column)))
|
|
||||||
(linestr (buffer-substring-no-properties
|
|
||||||
(line-beginning-position)
|
|
||||||
(line-end-position))))
|
|
||||||
ad-do-it
|
|
||||||
(when (and (evil-insert-state-p)
|
|
||||||
(string-match-p "^[\s\t]*$" linestr))
|
|
||||||
(insert linestr))))
|
|
||||||
|
|
||||||
;; Disable by default, please
|
|
||||||
(electric-indent-mode -1)
|
|
||||||
;; Smarter, keyword-based electric-indent (see `def-electric!')
|
|
||||||
(defvar doom-electric-indent-p nil)
|
|
||||||
(defvar-local doom-electric-indent-words '())
|
|
||||||
(setq electric-indent-chars '(?\n ?\^?))
|
|
||||||
(push (lambda (c)
|
|
||||||
(when (and (eolp) doom-electric-indent-words)
|
|
||||||
(save-excursion
|
|
||||||
(backward-word)
|
|
||||||
(looking-at-p
|
|
||||||
(concat "\\<" (regexp-opt doom-electric-indent-words))))))
|
|
||||||
electric-indent-functions)
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Plugins
|
|
||||||
;;
|
|
||||||
|
|
||||||
(use-package ace-window
|
|
||||||
:commands ace-window
|
|
||||||
:config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
|
|
||||||
aw-scope 'frame
|
|
||||||
aw-background t))
|
|
||||||
|
|
||||||
(use-package ace-link :commands (ace-link-help ace-link-org))
|
|
||||||
|
|
||||||
(use-package avy
|
|
||||||
:commands (avy-goto-char-2 avy-goto-line)
|
|
||||||
:config (setq avy-all-windows nil
|
|
||||||
avy-background t))
|
|
||||||
|
|
||||||
(use-package command-log-mode
|
|
||||||
:commands (clm/command-log-buffer command-log-mode global-command-log-mode)
|
|
||||||
:config (setq command-log-mode-is-global t))
|
|
||||||
|
|
||||||
(use-package dumb-jump
|
|
||||||
:commands (dumb-jump-go dumb-jump-quick-look dumb-jump-back)
|
|
||||||
:config
|
|
||||||
(setq dumb-jump-default-project doom-emacs-dir)
|
|
||||||
(dumb-jump-mode +1))
|
|
||||||
|
|
||||||
(use-package emr
|
|
||||||
:commands (emr-show-refactor-menu emr-declare-command)
|
|
||||||
:config
|
|
||||||
(emr-initialize)
|
|
||||||
(define-key popup-menu-keymap [escape] 'keyboard-quit))
|
|
||||||
|
|
||||||
(use-package expand-region
|
|
||||||
:commands (er/expand-region er/contract-region er/mark-symbol er/mark-word))
|
|
||||||
|
|
||||||
(use-package goto-last-change :commands goto-last-change)
|
|
||||||
|
|
||||||
(use-package hideshow
|
|
||||||
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
|
|
||||||
:config (setq hs-isearch-open t)
|
|
||||||
:init
|
:init
|
||||||
(defun doom*load-hs-minor-mode ()
|
|
||||||
(hs-minor-mode 1)
|
|
||||||
(advice-remove 'evil-toggle-fold 'doom-load-hs-minor-mode))
|
|
||||||
(advice-add 'evil-toggle-fold :before 'doom*load-hs-minor-mode)
|
|
||||||
;; Prettify code folding in emacs
|
|
||||||
(define-fringe-bitmap 'hs-marker [16 48 112 240 112 48 16] nil nil 'center)
|
|
||||||
(defface hs-face '((t (:background "#ff8")))
|
|
||||||
"Face to hightlight the ... area of hidden regions"
|
|
||||||
:group 'hideshow)
|
|
||||||
(defface hs-fringe-face '((t (:foreground "#888")))
|
|
||||||
"Face used to highlight the fringe on folded regions"
|
|
||||||
:group 'hideshow)
|
|
||||||
(setq hs-set-up-overlay
|
|
||||||
(lambda (ov)
|
|
||||||
(when (eq 'code (overlay-get ov 'hs))
|
|
||||||
(let* ((marker-string "*")
|
|
||||||
(display-string (concat " " (all-the-icons-octicon "ellipsis" :v-adjust 0) " "))
|
|
||||||
(len (length display-string)))
|
|
||||||
(put-text-property 0 1 'display
|
|
||||||
(list 'right-fringe 'hs-marker 'hs-fringe-face)
|
|
||||||
marker-string)
|
|
||||||
(put-text-property 0 1 'face 'hs-face display-string)
|
|
||||||
(put-text-property (1- len) len 'face 'hs-face display-string)
|
|
||||||
(put-text-property 1 (1- len)
|
|
||||||
'face `(:inherit hs-face :family ,(all-the-icons-octicon-family) :height 1.1)
|
|
||||||
display-string)
|
|
||||||
(overlay-put ov 'before-string marker-string)
|
|
||||||
(overlay-put ov 'display display-string))))))
|
|
||||||
|
|
||||||
(use-package help-fns+ ; Improved help commands
|
|
||||||
:commands (describe-buffer describe-command describe-file
|
|
||||||
describe-keymap describe-option describe-option-of-type))
|
|
||||||
|
|
||||||
(use-package imenu-list
|
|
||||||
:commands imenu-list-minor-mode
|
|
||||||
:config
|
|
||||||
(setq imenu-list-mode-line-format nil
|
|
||||||
imenu-list-position 'right
|
|
||||||
imenu-list-size 32)
|
|
||||||
(map! :map imenu-list-major-mode-map
|
|
||||||
:n [escape] 'doom/imenu-list-quit
|
|
||||||
:n "RET" 'imenu-list-goto-entry
|
|
||||||
:n "SPC" 'imenu-list-display-entry
|
|
||||||
:n [tab] 'hs-toggle-hiding))
|
|
||||||
|
|
||||||
(use-package re-builder
|
|
||||||
:commands (re-builder reb-mode-buffer-p)
|
|
||||||
:init (add-hook 'reb-mode-hook 'doom|reb-cleanup)
|
|
||||||
:config
|
|
||||||
(evil-set-initial-state 'reb-mode 'insert)
|
|
||||||
(setq reb-re-syntax 'string)
|
|
||||||
(map! (:map* rxt-help-mode-map
|
|
||||||
:n [escape] 'kill-buffer-and-window)
|
|
||||||
(:map* reb-mode-map
|
|
||||||
:n "C-g" 'reb-quit
|
|
||||||
:n [escape] 'reb-quit
|
|
||||||
:n [backtab] 'reb-change-syntax)))
|
|
||||||
|
|
||||||
(use-package pcre2el :commands (rxt-quote-pcre))
|
|
||||||
|
|
||||||
(use-package rotate-text
|
|
||||||
:commands (rotate-text rotate-text-backward)
|
|
||||||
:config (push '("true" "false") rotate-text-words))
|
|
||||||
|
|
||||||
(use-package smart-forward
|
|
||||||
:commands (smart-up smart-down smart-backward smart-forward))
|
|
||||||
|
|
||||||
(use-package smartparens
|
|
||||||
:config
|
|
||||||
(setq sp-autowrap-region nil ; let evil-surround handle this
|
(setq sp-autowrap-region nil ; let evil-surround handle this
|
||||||
sp-highlight-pair-overlay nil
|
sp-highlight-pair-overlay nil
|
||||||
sp-cancel-autoskip-on-backward-movement nil
|
sp-cancel-autoskip-on-backward-movement nil
|
||||||
sp-show-pair-delay 0
|
sp-show-pair-delay 0
|
||||||
sp-max-pair-length 3)
|
sp-max-pair-length 3)
|
||||||
|
|
||||||
|
:config
|
||||||
(smartparens-global-mode 1)
|
(smartparens-global-mode 1)
|
||||||
(require 'smartparens-config)
|
(require 'smartparens-config)
|
||||||
;; Smartparens interferes with Replace mode
|
;; Smartparens interferes with Replace mode
|
||||||
|
@ -271,19 +125,78 @@
|
||||||
(sp-local-pair
|
(sp-local-pair
|
||||||
'css-mode "/*" "*/" :post-handlers '(("[d-3]||\n[i]" "RET") ("| " "SPC")))
|
'css-mode "/*" "*/" :post-handlers '(("[d-3]||\n[i]" "RET") ("| " "SPC")))
|
||||||
(sp-local-pair '(sh-mode markdown-mode) "`" nil
|
(sp-local-pair '(sh-mode markdown-mode) "`" nil
|
||||||
:unless '(sp-point-before-word-p sp-point-before-same-p))
|
:unless '(sp-point-before-word-p sp-point-before-same-p))
|
||||||
(sp-with-modes '(xml-mode nxml-mode php-mode)
|
(sp-with-modes '(xml-mode nxml-mode php-mode)
|
||||||
(sp-local-pair "<!--" "-->" :post-handlers '(("| " "SPC")))))
|
(sp-local-pair "<!--" "-->" :post-handlers '(("| " "SPC")))))
|
||||||
|
|
||||||
(use-package smex
|
|
||||||
:commands (smex smex-major-mode-commands)
|
;;
|
||||||
|
;; Autoloaded Plugins
|
||||||
|
;;
|
||||||
|
|
||||||
|
(package! ace-link :commands (ace-link-help ace-link-org))
|
||||||
|
|
||||||
|
(package! ace-window
|
||||||
|
:commands ace-window
|
||||||
|
:config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
|
||||||
|
aw-scope 'frame
|
||||||
|
aw-background t))
|
||||||
|
|
||||||
|
(package! avy
|
||||||
|
:commands (avy-goto-char-2 avy-goto-line)
|
||||||
|
:config (setq avy-all-windows nil
|
||||||
|
avy-background t))
|
||||||
|
|
||||||
|
(package! command-log-mode
|
||||||
|
:commands (clm/command-log-buffer command-log-mode global-command-log-mode)
|
||||||
|
:config (setq command-log-mode-is-global t))
|
||||||
|
|
||||||
|
(package! emr
|
||||||
|
:commands (emr-show-refactor-menu emr-declare-command)
|
||||||
:config
|
:config
|
||||||
(setq smex-save-file (concat doom-temp-dir "/smex-items"))
|
(emr-initialize)
|
||||||
(smex-initialize))
|
(define-key popup-menu-keymap [escape] 'keyboard-quit))
|
||||||
|
|
||||||
(use-package swiper :commands (swiper swiper-all))
|
(package! expand-region :commands (er/expand-region er/contract-region er/mark-symbol er/mark-word))
|
||||||
|
|
||||||
(use-package wgrep
|
(package! goto-last-change :commands goto-last-change)
|
||||||
|
|
||||||
|
(package! help-fns+ ; Improved help commands
|
||||||
|
:commands (describe-buffer describe-command describe-file
|
||||||
|
describe-keymap describe-option describe-option-of-type))
|
||||||
|
|
||||||
|
(package! imenu-anywhere
|
||||||
|
:commands (ido-imenu-anywhere ivy-imenu-anywhere helm-imenu-anywhere))
|
||||||
|
|
||||||
|
(package! imenu-list :commands imenu-list-minor-mode)
|
||||||
|
|
||||||
|
(package! pcre2el :commands rxt-quote-pcre)
|
||||||
|
|
||||||
|
(package! re-builder
|
||||||
|
:commands (re-builder reb-mode-buffer-p)
|
||||||
|
:init (add-hook 'reb-mode-hook 'doom|reb-cleanup)
|
||||||
|
:config
|
||||||
|
(evil-set-initial-state 'reb-mode 'insert)
|
||||||
|
(setq reb-re-syntax 'string)
|
||||||
|
;; (map! (:map* rxt-help-mode-map
|
||||||
|
;; :n [escape] 'kill-buffer-and-window)
|
||||||
|
;; (:map* reb-mode-map
|
||||||
|
;; :n "C-g" 'reb-quit
|
||||||
|
;; :n [escape] 'reb-quit
|
||||||
|
;; :n [backtab] 'reb-change-syntax))
|
||||||
|
)
|
||||||
|
|
||||||
|
(package! rotate-text
|
||||||
|
:quelpa (rotate-text :fetcher github :repo "debug-ito/rotate-text.el")
|
||||||
|
:commands (rotate-text rotate-text-backward)
|
||||||
|
:config (push '("true" "false") rotate-text-words))
|
||||||
|
|
||||||
|
(package! smart-forward
|
||||||
|
:commands (smart-up smart-down smart-backward smart-forward))
|
||||||
|
|
||||||
|
(package! swiper :commands (swiper swiper-all))
|
||||||
|
|
||||||
|
(package! wgrep
|
||||||
:commands (wgrep-setup wgrep-change-to-wgrep-mode)
|
:commands (wgrep-setup wgrep-change-to-wgrep-mode)
|
||||||
:config
|
:config
|
||||||
(def-popup! "^\\*ivy-occur counsel-ag" :align below :size 25 :select t :regexp t)
|
(def-popup! "^\\*ivy-occur counsel-ag" :align below :size 25 :select t :regexp t)
|
||||||
|
@ -291,97 +204,5 @@
|
||||||
(advice-add 'wgrep-abort-changes :after 'doom/popup-close)
|
(advice-add 'wgrep-abort-changes :after 'doom/popup-close)
|
||||||
(advice-add 'wgrep-finish-edit :after 'doom/popup-close))
|
(advice-add 'wgrep-finish-edit :after 'doom/popup-close))
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Keybinding fixes
|
|
||||||
;;
|
|
||||||
|
|
||||||
;; This section is dedicated to bindings that "fix" certain keys so that they
|
|
||||||
;; behave more like vim (or how I like it).
|
|
||||||
|
|
||||||
;; Line-wise mouse selection on margin
|
|
||||||
(map! "<left-margin> <down-mouse-1>" 'doom/mouse-drag-line
|
|
||||||
"<left-margin> <mouse-1>" 'doom/mouse-select-line
|
|
||||||
"<left-margin> <drag-mouse-1>" 'doom/mouse-select-line)
|
|
||||||
|
|
||||||
;; Restores "dumb" indentation to the tab key. This rustles a lot of peoples'
|
|
||||||
;; jimmies, apparently, but it's how I like it.
|
|
||||||
(map! :i "<tab>" 'doom/dumb-indent
|
|
||||||
:i "<backtab>" 'doom/dumb-dedent
|
|
||||||
:i "<C-tab>" 'indent-for-tab-command
|
|
||||||
:i "<A-tab>" (λ! (insert "\t"))
|
|
||||||
;; No dumb-tab for lisp
|
|
||||||
(:map* lisp-mode-map :i [remap doom/dumb-indent] 'indent-for-tab-command)
|
|
||||||
(:map* emacs-lisp-mode-map :i [remap doom/dumb-indent] 'indent-for-tab-command)
|
|
||||||
;; Highjacks space/backspace to:
|
|
||||||
;; a) eat spaces on either side of the cursor, if present ( | ) -> (|)
|
|
||||||
;; b) allow backspace to delete space-indented blocks intelligently
|
|
||||||
;; c) but do none of this when inside a string
|
|
||||||
:i "SPC" 'doom/inflate-space-maybe
|
|
||||||
:i [remap delete-backward-char] 'doom/deflate-space-maybe
|
|
||||||
:i [remap newline] 'doom/newline-and-indent
|
|
||||||
;; Smarter move-to-beginning-of-line
|
|
||||||
:i [remap move-beginning-of-line] 'doom/move-to-bol
|
|
||||||
;; Restore bash-esque keymaps in insert mode; C-w and C-a already exist
|
|
||||||
:i "C-e" 'doom/move-to-eol
|
|
||||||
:i "C-u" 'doom/backward-kill-to-bol-and-indent
|
|
||||||
;; Fixes delete
|
|
||||||
:i "<kp-delete>" 'delete-char
|
|
||||||
;; Fix osx keymappings and then some
|
|
||||||
:i "<M-left>" 'doom/move-to-bol
|
|
||||||
:i "<M-right>" 'doom/move-to-eol
|
|
||||||
:i "<M-up>" 'beginning-of-buffer
|
|
||||||
:i "<M-down>" 'end-of-buffer
|
|
||||||
:i "<C-up>" 'smart-up
|
|
||||||
:i "<C-down>" 'smart-down
|
|
||||||
;; Fix emacs motion keys
|
|
||||||
:i "A-b" 'evil-backward-word-begin
|
|
||||||
:i "A-w" 'evil-forward-word-begin
|
|
||||||
:i "A-e" 'evil-forward-word-end
|
|
||||||
;; Textmate-esque insert-line before/after
|
|
||||||
:i [M-return] 'evil-open-below
|
|
||||||
:i [S-M-return] 'evil-open-above
|
|
||||||
;; insert lines in-place)
|
|
||||||
:n [M-return] (λ! (save-excursion (evil-insert-newline-below)))
|
|
||||||
:n [S-M-return] (λ! (save-excursion (evil-insert-newline-above)))
|
|
||||||
;; Make ESC quit all the things
|
|
||||||
(:map (minibuffer-local-map
|
|
||||||
minibuffer-local-ns-map
|
|
||||||
minibuffer-local-completion-map
|
|
||||||
minibuffer-local-must-match-map
|
|
||||||
minibuffer-local-isearch-map)
|
|
||||||
[escape] 'abort-recursive-edit
|
|
||||||
"C-r" 'evil-paste-from-register)
|
|
||||||
|
|
||||||
(:map (evil-ex-search-keymap read-expression-map)
|
|
||||||
"C-w" 'backward-kill-word
|
|
||||||
"C-u" 'backward-kill-sentence
|
|
||||||
"C-b" 'backward-word)
|
|
||||||
|
|
||||||
(:map evil-ex-completion-map "C-a" 'move-beginning-of-line)
|
|
||||||
|
|
||||||
(:after view
|
|
||||||
(:map view-mode-map "<escape>" 'View-quit-all))
|
|
||||||
|
|
||||||
(:after help-mode
|
|
||||||
(:map help-map
|
|
||||||
;; Remove slow/annoying help subsections
|
|
||||||
"h" nil
|
|
||||||
"g" nil)))
|
|
||||||
|
|
||||||
(map! :map key-translation-map
|
|
||||||
|
|
||||||
;; Fix certain keys in the terminal
|
|
||||||
(:unless window-system "TAB" [tab])
|
|
||||||
|
|
||||||
;; Common unicode characters
|
|
||||||
:i "A-o" (kbd "ø")
|
|
||||||
:i "A-O" (kbd "Ø")
|
|
||||||
:i "A--" (kbd "–")
|
|
||||||
:i "A-_" (kbd "—")
|
|
||||||
:i "A-8" (kbd "•")
|
|
||||||
:i "A-*" (kbd "°")
|
|
||||||
:i "A-p" (kbd "π"))
|
|
||||||
|
|
||||||
(provide 'core-editor)
|
(provide 'core-editor)
|
||||||
;;; core-editor.el ends here
|
;;; core-editor.el ends here
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
;;; core-eval.el
|
|
||||||
|
|
||||||
;; + Running inline code + REPLs (using `quickrun' + `repl-toggle')
|
|
||||||
;; + Simple code navigation (using `dump-jump' and `imenu-list')
|
|
||||||
|
|
||||||
;; remove ellipsis when printing sexp in message buffer
|
|
||||||
(setq eval-expression-print-length nil
|
|
||||||
eval-expression-print-level nil)
|
|
||||||
|
|
||||||
(use-package quickrun
|
|
||||||
:commands (quickrun
|
|
||||||
quickrun-region
|
|
||||||
quickrun-with-arg
|
|
||||||
quickrun-shell
|
|
||||||
quickrun-compile-only
|
|
||||||
quickrun-replace-region)
|
|
||||||
:init (add-hook 'quickrun/mode-hook 'linum-mode)
|
|
||||||
:config
|
|
||||||
(setq quickrun-focus-p nil)
|
|
||||||
(def-popup! "*quickrun*" :align below :size 10)
|
|
||||||
|
|
||||||
;;; Popup hacks
|
|
||||||
(advice-add 'quickrun :before 'doom*quickrun-close-popup)
|
|
||||||
(advice-add 'quickrun-region :before 'doom*quickrun-close-popup)
|
|
||||||
;; Ensures window is scrolled to BOF
|
|
||||||
(add-hook 'quickrun-after-run-hook 'doom|quickrun-after-run))
|
|
||||||
|
|
||||||
(use-package repl-toggle
|
|
||||||
:commands (rtog/toggle-repl rtog/add-repl)
|
|
||||||
:preface (defvar rtog/mode-repl-alist nil)
|
|
||||||
:init
|
|
||||||
(defvar doom-repl-buffer nil "The current REPL buffer.")
|
|
||||||
(add-hook! repl-toggle-mode (evil-initialize-state 'emacs))
|
|
||||||
:config
|
|
||||||
(def-popup!
|
|
||||||
(:custom (lambda (b &rest _)
|
|
||||||
(when (and (featurep 'repl-toggle)
|
|
||||||
(string-prefix-p "*" (buffer-name (get-buffer b))))
|
|
||||||
(buffer-local-value 'repl-toggle-mode b))))
|
|
||||||
:popup t :align below :size 16 :select t)
|
|
||||||
|
|
||||||
(map! :map repl-toggle-mode-map
|
|
||||||
:ei "C-n" 'comint-next-input
|
|
||||||
:ei "C-p" 'comint-previous-input
|
|
||||||
:ei "<down>" 'comint-next-input
|
|
||||||
:ei "<up>" 'comint-previous-input))
|
|
||||||
|
|
||||||
(provide 'core-eval)
|
|
||||||
;;; core-eval.el ends here
|
|
|
@ -1,6 +1,19 @@
|
||||||
;;; core-evil.el --- the root of all evil
|
;;; core-evil.el --- Come to the dark side, we have cookies
|
||||||
|
|
||||||
(use-package evil
|
;; TODO Document
|
||||||
|
|
||||||
|
(defvar doom-evil-leader ","
|
||||||
|
"docstring")
|
||||||
|
|
||||||
|
(defvar doom-evil-localleader "\\"
|
||||||
|
"docstring")
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Packages
|
||||||
|
;;
|
||||||
|
|
||||||
|
(package! evil :demand t
|
||||||
:init
|
:init
|
||||||
(setq evil-magic t
|
(setq evil-magic t
|
||||||
evil-want-C-u-scroll t
|
evil-want-C-u-scroll t
|
||||||
|
@ -19,288 +32,16 @@
|
||||||
evil-emacs-state-tag "E"
|
evil-emacs-state-tag "E"
|
||||||
evil-operator-state-tag "O"
|
evil-operator-state-tag "O"
|
||||||
evil-motion-state-tag "M"
|
evil-motion-state-tag "M"
|
||||||
evil-replace-state-tag "R"
|
evil-replace-state-tag "R")
|
||||||
|
|
||||||
;; Set cursor colors
|
|
||||||
evil-default-cursor (face-attribute 'cursor :background nil t)
|
|
||||||
evil-normal-state-cursor 'box
|
|
||||||
evil-emacs-state-cursor `(,(face-attribute 'warning :foreground nil nil) box)
|
|
||||||
evil-insert-state-cursor 'bar
|
|
||||||
evil-visual-state-cursor 'hollow)
|
|
||||||
|
|
||||||
;; highlight matching delimiters where it's important
|
|
||||||
(defun show-paren-mode-off () (show-paren-mode -1))
|
|
||||||
(add-hook 'evil-insert-state-entry-hook 'show-paren-mode)
|
|
||||||
(add-hook 'evil-insert-state-exit-hook 'show-paren-mode-off)
|
|
||||||
(add-hook 'evil-visual-state-entry-hook 'show-paren-mode)
|
|
||||||
(add-hook 'evil-visual-state-exit-hook 'show-paren-mode-off)
|
|
||||||
(add-hook 'evil-operator-state-entry-hook 'show-paren-mode)
|
|
||||||
(add-hook 'evil-operator-state-exit-hook 'show-paren-mode-off)
|
|
||||||
(add-hook 'evil-normal-state-entry-hook 'show-paren-mode-off)
|
|
||||||
;; Disable highlights on insert-mode
|
|
||||||
(add-hook 'evil-insert-state-entry-hook 'evil-ex-nohighlight)
|
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(evil-mode 1)
|
(evil-mode +1)
|
||||||
(evil-select-search-module 'evil-search-module 'evil-search)
|
(evil-select-search-module 'evil-search-module 'evil-search))
|
||||||
|
|
||||||
(mapc (lambda (r) (evil-set-initial-state (car r) (cdr r)))
|
|
||||||
'((compilation-mode . normal)
|
|
||||||
(help-mode . normal)
|
|
||||||
(message-mode . normal)
|
|
||||||
(debugger-mode . normal)
|
|
||||||
(image-mode . normal)
|
|
||||||
(doc-view-mode . normal)
|
|
||||||
(eww-mode . normal)
|
|
||||||
(tabulated-list-mode . emacs)
|
|
||||||
(profile-report-mode . emacs)
|
|
||||||
(Info-mode . emacs)
|
|
||||||
(view-mode . emacs)
|
|
||||||
(comint-mode . emacs)
|
|
||||||
(cider-repl-mode . emacs)
|
|
||||||
(term-mode . emacs)
|
|
||||||
(calendar-mode . emacs)
|
|
||||||
(Man-mode . emacs)
|
|
||||||
(grep-mode . emacs)))
|
|
||||||
|
|
||||||
;; Popups
|
;;
|
||||||
(def-popup! "*evil-registers*" :align below :size 0.3)
|
;; Autoloaded Packages
|
||||||
(def-popup! "*Command Line*" :align below :size 8 :select t)
|
;;
|
||||||
|
|
||||||
;;; Evil hacks
|
|
||||||
;; Don't interfere with neotree + auto move to new split
|
|
||||||
(advice-add 'evil-window-split :around 'doom*evil-window-split)
|
|
||||||
(advice-add 'evil-window-vsplit :around 'doom*evil-window-vsplit)
|
|
||||||
;; Integrate evil's command window into shackle
|
|
||||||
(advice-add 'evil-command-window :override 'doom*evil-command-window)
|
|
||||||
(add-hook 'evil-command-window-mode-hook 'doom-hide-mode-line-mode)
|
|
||||||
;; Close popups, disable search highlights and quit the minibuffer if open
|
|
||||||
(advice-add 'evil-force-normal-state :after 'doom*evil-esc-quit)
|
|
||||||
|
|
||||||
;; Fix harmless (yet disruptive) error reporting w/ hidden buffers caused by
|
|
||||||
;; workgroups killing windows
|
|
||||||
;; TODO Delete timer on dead windows?
|
|
||||||
(defadvice evil-ex-hl-do-update-highlight
|
|
||||||
(around evil-ex-hidden-buffer-ignore-errors activate)
|
|
||||||
(ignore-errors ad-do-it))
|
|
||||||
|
|
||||||
;; Hide keystroke display while isearch is active
|
|
||||||
(add-hook! isearch-mode (setq echo-keystrokes 0))
|
|
||||||
(add-hook! isearch-mode-end (setq echo-keystrokes 0.02))
|
|
||||||
|
|
||||||
(def-repeat! evil-ex-search-next evil-ex-search-next evil-ex-search-previous)
|
|
||||||
(def-repeat! evil-ex-search-previous evil-ex-search-next evil-ex-search-previous)
|
|
||||||
(def-repeat! evil-ex-search-forward evil-ex-search-next evil-ex-search-previous)
|
|
||||||
(def-repeat! evil-ex-search-backward evil-ex-search-next evil-ex-search-previous)
|
|
||||||
|
|
||||||
;; monkey patch `evil-ex-replace-special-filenames' to add most of vim's file
|
|
||||||
;; ex substitution flags to evil-mode
|
|
||||||
(advice-add 'evil-ex-replace-special-filenames
|
|
||||||
:override 'doom*evil-ex-replace-special-filenames)
|
|
||||||
|
|
||||||
;; Extra argument types for highlight buffer (or global) regexp matches
|
|
||||||
(evil-ex-define-argument-type buffer-match :runner doom/evil-ex-buffer-match)
|
|
||||||
(evil-ex-define-argument-type global-match :runner doom/evil-ex-global-match)
|
|
||||||
|
|
||||||
(evil-define-interactive-code "<//>"
|
|
||||||
:ex-arg buffer-match
|
|
||||||
(list (when (evil-ex-p) evil-ex-argument)))
|
|
||||||
(evil-define-interactive-code "<g//>"
|
|
||||||
:ex-arg global-match
|
|
||||||
(when (evil-ex-p) (evil-ex-parse-global evil-ex-argument)))
|
|
||||||
|
|
||||||
(evil-define-operator doom:evil-ex-global (beg end pattern command &optional invert)
|
|
||||||
"Rewritten :g[lobal] that will highlight buffer matches. Takes the same arguments."
|
|
||||||
:motion mark-whole-buffer :move-point nil
|
|
||||||
(interactive "<r><g//><!>")
|
|
||||||
(evil-ex-global beg end pattern command invert))
|
|
||||||
|
|
||||||
(evil-define-operator doom:align (&optional beg end bang pattern)
|
|
||||||
"Ex interface to `align-regexp'. Accepts vim-style regexps."
|
|
||||||
(interactive "<r><!><//>")
|
|
||||||
(align-regexp
|
|
||||||
beg end
|
|
||||||
(concat "\\(\\s-*\\)"
|
|
||||||
(if bang
|
|
||||||
(regexp-quote pattern)
|
|
||||||
(evil-transform-vim-style-regexp pattern)))
|
|
||||||
1 1)))
|
|
||||||
|
|
||||||
;; evil plugins
|
|
||||||
(use-package evil-numbers
|
|
||||||
:commands (evil-numbers/inc-at-pt evil-numbers/dec-at-pt))
|
|
||||||
|
|
||||||
(use-package evil-anzu
|
|
||||||
:defer t
|
|
||||||
:init
|
|
||||||
;; evil-anzu is strangely slow on startup. Byte compiling doesn't help. We use
|
|
||||||
;; this to lazy load it instead.
|
|
||||||
(defun doom*evil-search (&rest _)
|
|
||||||
(require 'evil-anzu)
|
|
||||||
(advice-remove 'evil-ex-start-search 'doom*evil-search))
|
|
||||||
(advice-add 'evil-ex-start-search :before 'doom*evil-search)
|
|
||||||
:config
|
|
||||||
(setq anzu-cons-mode-line-p nil
|
|
||||||
anzu-minimum-input-length 1
|
|
||||||
anzu-search-threshold 250))
|
|
||||||
|
|
||||||
(use-package evil-args
|
|
||||||
:commands (evil-inner-arg evil-outer-arg evil-forward-arg evil-backward-arg evil-jump-out-args)
|
|
||||||
:init (def-text-obj! "a" 'evil-inner-arg 'evil-outer-arg))
|
|
||||||
|
|
||||||
(use-package evil-commentary
|
|
||||||
:commands (evil-commentary evil-commentary-yank evil-commentary-line)
|
|
||||||
:config (evil-commentary-mode 1))
|
|
||||||
|
|
||||||
(use-package evil-exchange
|
|
||||||
:commands evil-exchange
|
|
||||||
:config (advice-add 'evil-force-normal-state :after 'doom*evil-exchange-off))
|
|
||||||
|
|
||||||
(use-package evil-multiedit
|
|
||||||
:commands (evil-multiedit-match-all
|
|
||||||
evil-multiedit-match-and-next
|
|
||||||
evil-multiedit-match-and-prev
|
|
||||||
evil-multiedit-match-symbol-and-next
|
|
||||||
evil-multiedit-match-symbol-and-prev
|
|
||||||
evil-multiedit-toggle-or-restrict-region
|
|
||||||
evil-multiedit-next
|
|
||||||
evil-multiedit-prev
|
|
||||||
evil-multiedit-abort
|
|
||||||
evil-multiedit-ex-match)
|
|
||||||
:config (evil-multiedit-default-keybinds))
|
|
||||||
|
|
||||||
(use-package evil-indent-plus
|
|
||||||
:commands (evil-indent-plus-i-indent
|
|
||||||
evil-indent-plus-a-indent
|
|
||||||
evil-indent-plus-i-indent-up
|
|
||||||
evil-indent-plus-a-indent-up
|
|
||||||
evil-indent-plus-i-indent-up-down
|
|
||||||
evil-indent-plus-a-indent-up-down)
|
|
||||||
:init
|
|
||||||
(def-text-obj! "i" 'evil-indent-plus-i-indent 'evil-indent-plus-a-indent)
|
|
||||||
(def-text-obj! "I" 'evil-indent-plus-i-indent-up 'evil-indent-plus-a-indent-up)
|
|
||||||
(def-text-obj! "J" 'evil-indent-plus-i-indent-up-down 'evil-indent-plus-a-indent-up-down))
|
|
||||||
|
|
||||||
(use-package evil-matchit
|
|
||||||
:commands (evilmi-jump-items evilmi-text-object global-evil-matchit-mode)
|
|
||||||
:config (global-evil-matchit-mode 1)
|
|
||||||
:init (def-text-obj! "%" 'evilmi-text-object))
|
|
||||||
|
|
||||||
(use-package evil-textobj-anyblock
|
|
||||||
:commands (evil-textobj-anyblock-inner-block evil-textobj-anyblock-a-block)
|
|
||||||
:init (def-text-obj! "B" 'evil-textobj-anyblock-inner-block 'evil-textobj-anyblock-a-block))
|
|
||||||
|
|
||||||
(use-package evil-search-highlight-persist
|
|
||||||
:config
|
|
||||||
(global-evil-search-highlight-persist t)
|
|
||||||
(advice-add 'evil-force-normal-state :after 'evil-search-highlight-persist-remove-all))
|
|
||||||
|
|
||||||
(use-package evil-easymotion
|
|
||||||
:defer 1
|
|
||||||
:init (defvar doom--evil-snipe-repeat-fn)
|
|
||||||
:config
|
|
||||||
(evilem-default-keybindings "g SPC")
|
|
||||||
(evilem-define (kbd "g SPC n") 'evil-ex-search-next)
|
|
||||||
(evilem-define (kbd "g SPC N") 'evil-ex-search-previous)
|
|
||||||
(evilem-define "gs" 'evil-snipe-repeat
|
|
||||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
|
||||||
:bind ((evil-snipe-scope 'buffer)
|
|
||||||
(evil-snipe-enable-highlight)
|
|
||||||
(evil-snipe-enable-incremental-highlight)))
|
|
||||||
(evilem-define "gS" 'evil-snipe-repeat-reverse
|
|
||||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
|
||||||
:bind ((evil-snipe-scope 'buffer)
|
|
||||||
(evil-snipe-enable-highlight)
|
|
||||||
(evil-snipe-enable-incremental-highlight)))
|
|
||||||
|
|
||||||
(setq doom--evil-snipe-repeat-fn
|
|
||||||
(evilem-create 'evil-snipe-repeat
|
|
||||||
:bind ((evil-snipe-scope 'whole-buffer)
|
|
||||||
(evil-snipe-enable-highlight)
|
|
||||||
(evil-snipe-enable-incremental-highlight)))))
|
|
||||||
|
|
||||||
(use-package evil-snipe
|
|
||||||
:init
|
|
||||||
(setq-default
|
|
||||||
evil-snipe-smart-case t
|
|
||||||
evil-snipe-repeat-keys nil ; using space to repeat
|
|
||||||
evil-snipe-scope 'line
|
|
||||||
evil-snipe-repeat-scope 'visible
|
|
||||||
evil-snipe-override-evil-repeat-keys nil ; causes problems with remapped ;
|
|
||||||
evil-snipe-char-fold t
|
|
||||||
evil-snipe-aliases '((?\[ "[[{(]")
|
|
||||||
(?\] "[]})]")
|
|
||||||
(?\; "[;:]")))
|
|
||||||
:config
|
|
||||||
(evil-snipe-mode 1)
|
|
||||||
(evil-snipe-override-mode 1)
|
|
||||||
|
|
||||||
(define-key evil-snipe-parent-transient-map (kbd "C-;") 'doom/evil-snipe-easymotion)
|
|
||||||
|
|
||||||
(def-repeat! evil-snipe-f evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-F evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-t evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-T evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-s evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-S evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-x evil-snipe-repeat evil-snipe-repeat-reverse)
|
|
||||||
(def-repeat! evil-snipe-X evil-snipe-repeat evil-snipe-repeat-reverse))
|
|
||||||
|
|
||||||
(use-package evil-surround
|
|
||||||
:commands (global-evil-surround-mode
|
|
||||||
evil-surround-edit
|
|
||||||
evil-Surround-edit
|
|
||||||
evil-surround-region)
|
|
||||||
:config
|
|
||||||
(global-evil-surround-mode 1))
|
|
||||||
|
|
||||||
(use-package evil-embrace
|
|
||||||
:after evil-surround
|
|
||||||
:config
|
|
||||||
(setq evil-embrace-show-help-p nil)
|
|
||||||
(evil-embrace-enable-evil-surround-integration)
|
|
||||||
(push (cons ?\\ (make-embrace-pair-struct
|
|
||||||
:key ?\\
|
|
||||||
:read-function 'doom/embrace-escaped
|
|
||||||
:left-regexp "\\[[{(]"
|
|
||||||
:right-regexp "\\[]})]"))
|
|
||||||
(default-value 'embrace--pairs-list))
|
|
||||||
|
|
||||||
(add-hook 'LaTeX-mode-hook 'embrace-LaTeX-mode-hook)
|
|
||||||
(add-hook 'org-mode-hook 'embrace-org-mode-hook)
|
|
||||||
(add-hook! emacs-lisp-mode
|
|
||||||
(embrace-add-pair ?\` "`" "'"))
|
|
||||||
(add-hook! (emacs-lisp-mode lisp-mode)
|
|
||||||
(embrace-add-pair-regexp ?f "([^ ]+ " ")" 'doom/embrace-elisp-fn))
|
|
||||||
(add-hook! (org-mode latex-mode)
|
|
||||||
(embrace-add-pair-regexp ?l "\\[a-z]+{" "}" 'doom/embrace-latex)))
|
|
||||||
|
|
||||||
(use-package evil-visualstar
|
|
||||||
:commands (global-evil-visualstar-mode
|
|
||||||
evil-visualstar/begin-search
|
|
||||||
evil-visualstar/begin-search-forward
|
|
||||||
evil-visualstar/begin-search-backward)
|
|
||||||
:config
|
|
||||||
(global-evil-visualstar-mode 1)
|
|
||||||
|
|
||||||
(def-repeat! evil-visualstar/begin-search-forward
|
|
||||||
evil-ex-search-next evil-ex-search-previous)
|
|
||||||
(def-repeat! evil-visualstar/begin-search-backward
|
|
||||||
evil-ex-search-previous evil-ex-search-next))
|
|
||||||
|
|
||||||
(use-package evil-escape
|
|
||||||
:config
|
|
||||||
(setq evil-escape-key-sequence "jk"
|
|
||||||
evil-escape-delay 0.25)
|
|
||||||
(push 'neotree-mode evil-escape-excluded-major-modes)
|
|
||||||
;; evil-escape causes noticable lag in commands that start with j, so we
|
|
||||||
;; enable it only where we need it.
|
|
||||||
(defun doom|evil-escape-disable () (evil-escape-mode -1))
|
|
||||||
(defun doom|evil-escape-enable () (evil-escape-mode +1))
|
|
||||||
(add-hook 'evil-insert-state-entry-hook 'doom|evil-escape-enable)
|
|
||||||
(add-hook 'evil-insert-state-exit-hook 'doom|evil-escape-disable)
|
|
||||||
(add-hook 'evil-replace-state-entry-hook 'doom|evil-escape-enable)
|
|
||||||
(add-hook 'evil-replace-state-exit-hook 'doom|evil-escape-disable))
|
|
||||||
|
|
||||||
(provide 'core-evil)
|
(provide 'core-evil)
|
||||||
;;; core-evil.el ends here
|
;;; core-evil.el ends here
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
;;; core-helm.el
|
|
||||||
|
|
||||||
(use-package helm
|
|
||||||
:init
|
|
||||||
(setq helm-quick-update t
|
|
||||||
;; Speedier without fuzzy matching
|
|
||||||
helm-mode-fuzzy-match nil
|
|
||||||
helm-buffers-fuzzy-matching nil
|
|
||||||
helm-apropos-fuzzy-match nil
|
|
||||||
helm-M-x-fuzzy-match nil
|
|
||||||
helm-recentf-fuzzy-match nil
|
|
||||||
helm-projectile-fuzzy-match nil
|
|
||||||
;; Display extraineous helm UI elements
|
|
||||||
helm-display-header-line nil
|
|
||||||
helm-ff-auto-update-initial-value nil
|
|
||||||
helm-find-files-doc-header nil
|
|
||||||
;; Don't override evil-ex's completion
|
|
||||||
helm-mode-handle-completion-in-region nil
|
|
||||||
helm-candidate-number-limit 50
|
|
||||||
;; Don't wrap item cycling
|
|
||||||
helm-move-to-line-cycle-in-source t)
|
|
||||||
|
|
||||||
:config
|
|
||||||
(defvar helm-global-prompt "››› ")
|
|
||||||
|
|
||||||
(map! "M-x" 'helm-M-x
|
|
||||||
"A-x" 'helm-M-x
|
|
||||||
"M-X" 'helm-apropos
|
|
||||||
"A-X" 'helm-apropos
|
|
||||||
"A-X" 'helm-apropos
|
|
||||||
"M-o" 'helm-find-files
|
|
||||||
|
|
||||||
(:map helm-map
|
|
||||||
"C-S-n" 'helm-next-source
|
|
||||||
"C-S-p" 'helm-previous-source
|
|
||||||
"C-u" 'helm-delete-minibuffer-contents
|
|
||||||
"C-w" 'backward-kill-word
|
|
||||||
"M-v" 'clipboard-yank
|
|
||||||
"C-r" 'evil-paste-from-register ; Evil registers in helm! Glorious!
|
|
||||||
"C-b" 'backward-word
|
|
||||||
"<left>" 'backward-char
|
|
||||||
"<right>" 'forward-char
|
|
||||||
"<escape>" 'helm-keyboard-quit
|
|
||||||
"ESC" 'helm-keyboard-quit
|
|
||||||
[escape] 'helm-keyboard-quit
|
|
||||||
"<tab>" 'helm-execute-persistent-action)
|
|
||||||
|
|
||||||
(:map* helm-generic-files-map
|
|
||||||
:e "ESC" 'helm-keyboard-quit))
|
|
||||||
|
|
||||||
;;; Popup setup
|
|
||||||
(def-popup! "\\` ?\\*[hH]elm.*?\\*\\'" :align below :size 14 :select t :regexp t)
|
|
||||||
|
|
||||||
;;; Helm hacks
|
|
||||||
(defconst doom-helm-header-fg (face-attribute 'helm-source-header :foreground))
|
|
||||||
;; Shrink source headers if there is only one source
|
|
||||||
(add-hook 'helm-after-initialize-hook 'doom*helm-hide-source-header-maybe)
|
|
||||||
;; A simpler prompt: see `helm-global-prompt'
|
|
||||||
(advice-add 'helm :filter-args 'doom*helm-replace-prompt)
|
|
||||||
;; Hide mode-line in helm windows
|
|
||||||
(advice-add 'helm-display-mode-line :override 'doom*helm-hide-header)
|
|
||||||
|
|
||||||
(require 'helm-mode)
|
|
||||||
(helm-mode +1))
|
|
||||||
|
|
||||||
(use-package helm-locate
|
|
||||||
:defer t
|
|
||||||
:init
|
|
||||||
(defvar helm-generic-files-map (make-sparse-keymap)
|
|
||||||
"Generic Keymap for files.")
|
|
||||||
:config (set-keymap-parent helm-generic-files-map helm-map))
|
|
||||||
|
|
||||||
(use-package helm-buffers
|
|
||||||
:commands (helm-buffers-list helm-mini)
|
|
||||||
:config (advice-add 'helm-buffer-list :override 'helm*buffer-list))
|
|
||||||
|
|
||||||
(use-package helm-tags
|
|
||||||
:commands (helm-tags-get-tag-file helm-etags-select))
|
|
||||||
|
|
||||||
(use-package helm-bookmark
|
|
||||||
:commands (helm-bookmarks helm-filtered-bookmarks)
|
|
||||||
:config (setq-default helm-bookmark-show-location t))
|
|
||||||
|
|
||||||
(use-package helm-projectile
|
|
||||||
:commands (helm-projectile-find-other-file
|
|
||||||
helm-projectile-switch-project
|
|
||||||
helm-projectile-find-file
|
|
||||||
helm-projectile-find-dir)
|
|
||||||
:init
|
|
||||||
(defvar helm-projectile-find-file-map (make-sparse-keymap))
|
|
||||||
:config
|
|
||||||
(set-keymap-parent helm-projectile-find-file-map helm-map)
|
|
||||||
(setq projectile-completion-system 'helm))
|
|
||||||
|
|
||||||
(use-package helm-files
|
|
||||||
:commands (helm-browse-project helm-find helm-find-files helm-for-files helm-multi-files helm-recentf)
|
|
||||||
:config
|
|
||||||
(map! :map helm-find-files-map
|
|
||||||
"C-w" 'helm-find-files-up-one-level
|
|
||||||
"TAB" 'helm-execute-persistent-action)
|
|
||||||
(mapc (lambda (r) (push r helm-boring-file-regexp-list))
|
|
||||||
(list "\\.projects$" "\\.DS_Store$")))
|
|
||||||
|
|
||||||
(use-package helm-ag
|
|
||||||
:commands (helm-ag
|
|
||||||
helm-ag-mode
|
|
||||||
helm-do-ag
|
|
||||||
helm-do-ag-this-file
|
|
||||||
helm-do-ag-project-root
|
|
||||||
helm-do-ag-buffers
|
|
||||||
helm-ag-project-root
|
|
||||||
helm-ag-pop-stack
|
|
||||||
helm-ag-buffers
|
|
||||||
helm-ag-clear-stack)
|
|
||||||
:config
|
|
||||||
(map! :map helm-ag-map
|
|
||||||
"<backtab>" 'helm-ag-edit
|
|
||||||
:map helm-ag-edit-map
|
|
||||||
"<escape>" 'helm-ag--edit-abort
|
|
||||||
:n "zx" 'helm-ag--edit-abort))
|
|
||||||
|
|
||||||
(use-package helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss
|
|
||||||
:commands (helm-css-scss
|
|
||||||
helm-css-scss-multi
|
|
||||||
helm-css-scss-insert-close-comment)
|
|
||||||
:config
|
|
||||||
(setq helm-css-scss-split-direction 'split-window-vertically
|
|
||||||
helm-css-scss-split-with-multiple-windows t))
|
|
||||||
|
|
||||||
(use-package helm-swoop ; https://github.com/ShingoFukuyama/helm-swoop
|
|
||||||
:defines (helm-swoop-last-prefix-number)
|
|
||||||
:commands (helm-swoop helm-multi-swoop helm-multi-swoop-all)
|
|
||||||
:config
|
|
||||||
(setq helm-swoop-use-line-number-face t
|
|
||||||
helm-swoop-candidate-number-limit 200
|
|
||||||
helm-swoop-speed-or-color t
|
|
||||||
helm-swoop-pre-input-function (lambda () "")))
|
|
||||||
|
|
||||||
(use-package helm-describe-modes :commands helm-describe-modes)
|
|
||||||
(use-package helm-ring :commands helm-show-kill-ring)
|
|
||||||
(use-package helm-semantic :commands helm-semantic-or-imenu)
|
|
||||||
(use-package helm-elisp :commands helm-apropos)
|
|
||||||
(use-package helm-command :commands helm-M-x)
|
|
||||||
|
|
||||||
|
|
||||||
;; Popup hacks
|
|
||||||
(after! helm
|
|
||||||
;; This is a good alternative to either popwin or shackle, specifically for
|
|
||||||
;; helm. If either fail me (for the last time), this is where I'll turn.
|
|
||||||
;;(add-to-list 'display-buffer-alist
|
|
||||||
;; `(,(rx bos "*helm" (* not-newline) "*" eos)
|
|
||||||
;; (display-buffer-in-side-window)
|
|
||||||
;; (inhibit-same-window . t)
|
|
||||||
;; (window-height . 0.4)))
|
|
||||||
|
|
||||||
;; Helm tries to clean up after itself, but shackle has already done this.
|
|
||||||
;; This fixes that. To reproduce, add a helm rule in `shackle-rules', open two
|
|
||||||
;; splits side-by-side, move to the buffer on the right and invoke helm. It
|
|
||||||
;; will close all but the left-most buffer.
|
|
||||||
(setq-default helm-reuse-last-window-split-state t
|
|
||||||
helm-split-window-in-side-p t))
|
|
||||||
|
|
||||||
(after! helm-swoop
|
|
||||||
(setq helm-swoop-split-window-function (lambda (b) (doom/popup-buffer b))))
|
|
||||||
|
|
||||||
(after! helm-ag
|
|
||||||
;; This prevents helm-ag from switching between windows and buffers.
|
|
||||||
(defadvice helm-ag--edit-abort (around helm-ag-edit-abort-popup-compat activate)
|
|
||||||
(cl-letf (((symbol-function 'select-window) 'ignore)) ad-do-it)
|
|
||||||
(doom/popup-close nil t))
|
|
||||||
(defadvice helm-ag--edit-commit (around helm-ag-edit-commit-popup-compat activate)
|
|
||||||
(cl-letf (((symbol-function 'select-window) 'ignore)) ad-do-it)
|
|
||||||
(doom/popup-close nil t))
|
|
||||||
(defadvice helm-ag--edit (around helm-ag-edit-popup-compat activate)
|
|
||||||
(cl-letf (((symbol-function 'other-window) 'ignore)
|
|
||||||
((symbol-function 'switch-to-buffer) 'doom/popup-buffer))
|
|
||||||
ad-do-it)))
|
|
||||||
|
|
||||||
(provide 'core-helm)
|
|
||||||
;;; core-helm.el ends here
|
|
|
@ -1,43 +0,0 @@
|
||||||
;;; core-ivy.el
|
|
||||||
;; see defuns/defuns-ivy.el
|
|
||||||
|
|
||||||
(use-package ivy
|
|
||||||
:init
|
|
||||||
(setq projectile-completion-system 'ivy
|
|
||||||
ivy-height 14
|
|
||||||
ivy-do-completion-in-region nil
|
|
||||||
ivy-wrap t
|
|
||||||
;; fontify until EOL
|
|
||||||
ivy-format-function 'ivy-format-function-line)
|
|
||||||
|
|
||||||
:config
|
|
||||||
(ivy-mode +1)
|
|
||||||
(map! :map ivy-minibuffer-map
|
|
||||||
[escape] 'keyboard-escape-quit
|
|
||||||
"C-r" 'evil-paste-from-register
|
|
||||||
"M-v" 'clipboard-yank
|
|
||||||
"C-w" 'backward-kill-word
|
|
||||||
"C-u" 'backward-kill-sentence
|
|
||||||
"C-b" 'backward-word
|
|
||||||
"C-f" 'forward-word)
|
|
||||||
|
|
||||||
(after! magit (setq magit-completing-read-function 'ivy-completing-read))
|
|
||||||
(after! smex (setq smex-completion-method 'ivy))
|
|
||||||
(after! yasnippet (push 'doom/yas-ivy-prompt yas-prompt-functions))
|
|
||||||
|
|
||||||
;;
|
|
||||||
(require 'counsel)
|
|
||||||
|
|
||||||
(add-hook! doom-popup-mode
|
|
||||||
(when (eq major-mode 'ivy-occur-grep-mode)
|
|
||||||
(ivy-wgrep-change-to-wgrep-mode)))
|
|
||||||
|
|
||||||
(advice-add 'counsel-ag-function :override 'doom*counsel-ag-function)
|
|
||||||
(define-key counsel-ag-map [backtab] 'doom/counsel-ag-occur)
|
|
||||||
|
|
||||||
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)"))
|
|
||||||
|
|
||||||
(use-package counsel-projectile :after projectile)
|
|
||||||
|
|
||||||
(provide 'core-ivy)
|
|
||||||
;;; core-ivy.el ends here
|
|
247
core/core-lib.el
Normal file
247
core/core-lib.el
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
;;; core-lib.el
|
||||||
|
|
||||||
|
(defmacro λ! (&rest body)
|
||||||
|
"A shortcut for inline keybind lambdas."
|
||||||
|
`(lambda () (interactive) ,@body))
|
||||||
|
|
||||||
|
(defmacro after! (feature &rest forms)
|
||||||
|
"A smart wrapper around `with-eval-after-load', that supresses warnings
|
||||||
|
during compilation."
|
||||||
|
(declare (indent defun) (debug t))
|
||||||
|
`(,(if (or (not (boundp 'byte-compile-current-file))
|
||||||
|
(not byte-compile-current-file)
|
||||||
|
(if (symbolp feature)
|
||||||
|
(require feature nil :no-error)
|
||||||
|
(load feature :no-message :no-error)))
|
||||||
|
'progn
|
||||||
|
(message "after: cannot find %s" feature)
|
||||||
|
'with-no-warnings)
|
||||||
|
(with-eval-after-load ',feature ,@forms)))
|
||||||
|
|
||||||
|
(defmacro add-hook! (hook &rest func-or-forms)
|
||||||
|
"A convenience macro for `add-hook'.
|
||||||
|
|
||||||
|
HOOK can be one hook or a list of hooks. If the hook(s) are not quoted, -hook is
|
||||||
|
appended to them automatically. If they are quoted, they are used verbatim.
|
||||||
|
|
||||||
|
FUNC-OR-FORMS can be a quoted symbol, a list of quoted symbols, or forms. Forms will be
|
||||||
|
wrapped in a lambda. A list of symbols will expand into a series of add-hook calls.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
(add-hook! 'some-mode-hook 'enable-something)
|
||||||
|
(add-hook! some-mode '(enable-something and-another))
|
||||||
|
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
|
||||||
|
(add-hook! (one-mode second-mode) 'enable-something)
|
||||||
|
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))"
|
||||||
|
(declare (indent defun) (debug t))
|
||||||
|
(unless func-or-forms
|
||||||
|
(error "add-hook!: FUNC-OR-FORMS is empty"))
|
||||||
|
(let* ((val (car func-or-forms))
|
||||||
|
(quoted (eq (car-safe hook) 'quote))
|
||||||
|
(hook (if quoted (cadr hook) hook))
|
||||||
|
(funcs (if (eq (car-safe val) 'quote)
|
||||||
|
(if (cdr-safe (cadr val))
|
||||||
|
(cadr val)
|
||||||
|
(list (cadr val)))
|
||||||
|
(list func-or-forms)))
|
||||||
|
(forms '()))
|
||||||
|
(mapc (lambda (f)
|
||||||
|
(let ((func (if (symbolp f) `(quote ,f) `(lambda (&rest _) ,@func-or-forms))))
|
||||||
|
(mapc (lambda (h)
|
||||||
|
(push `(add-hook ',(if quoted h (intern (format "%s-hook" h))) ,func) forms))
|
||||||
|
(-list hook))))
|
||||||
|
funcs)
|
||||||
|
(macroexp-progn forms)))
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
(defmacro add-lambda-hook! (hooks func-name &rest forms))
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
(defmacro remove-hooks! (hooks &rest funcs))
|
||||||
|
|
||||||
|
(defmacro associate! (mode &rest rest)
|
||||||
|
"Associate a major or minor mode to certain patterns and project files."
|
||||||
|
(declare (indent 1))
|
||||||
|
(let ((minor (plist-get rest :minor))
|
||||||
|
(in (plist-get rest :in))
|
||||||
|
(match (plist-get rest :match))
|
||||||
|
(files (plist-get rest :files))
|
||||||
|
(pred (plist-get rest :when)))
|
||||||
|
`(progn
|
||||||
|
(,@(cond ((or files in pred)
|
||||||
|
(when (and files (not (or (listp files) (stringp files))))
|
||||||
|
(user-error "associate! :files expects a string or list of strings"))
|
||||||
|
(let ((hook-name (intern (format "doom--init-mode-%s" mode))))
|
||||||
|
`(progn
|
||||||
|
(defun ,hook-name ()
|
||||||
|
(when (and ,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t)
|
||||||
|
(or ,(not files)
|
||||||
|
(and (boundp ',mode)
|
||||||
|
(not ,mode)
|
||||||
|
(doom-project-has-files ,@(-list files))))
|
||||||
|
(or (not ,pred)
|
||||||
|
(funcall ,pred buffer-file-name)))
|
||||||
|
(,mode 1)))
|
||||||
|
,@(if (and in (listp in))
|
||||||
|
(mapcar (lambda (h) `(add-hook ',h ',hook-name))
|
||||||
|
(mapcar (lambda (m) (intern (format "%s-hook" m))) in))
|
||||||
|
`((add-hook 'find-file-hook ',hook-name))))))
|
||||||
|
(match
|
||||||
|
`(add-to-list ',(if minor 'doom-auto-minor-mode-alist 'auto-mode-alist)
|
||||||
|
(cons ,match ',mode)))
|
||||||
|
(t (user-error "associate! invalid rules for mode [%s] (in %s) (match %s) (files %s)"
|
||||||
|
mode in match files)))))))
|
||||||
|
|
||||||
|
;; Register keywords for proper indentation (see `map!')
|
||||||
|
(put ':prefix 'lisp-indent-function 'defun)
|
||||||
|
(put ':map 'lisp-indent-function 'defun)
|
||||||
|
(put ':map* 'lisp-indent-function 'defun)
|
||||||
|
(put ':after 'lisp-indent-function 'defun)
|
||||||
|
(put ':when 'lisp-indent-function 'defun)
|
||||||
|
(put ':unless 'lisp-indent-function 'defun)
|
||||||
|
(put ':leader 'lisp-indent-function 'defun)
|
||||||
|
(put ':localleader 'lisp-indent-function 'defun)
|
||||||
|
|
||||||
|
(defmacro map! (&rest rest)
|
||||||
|
"A nightmare of a key-binding macro that will use `evil-define-key',
|
||||||
|
`evil-define-key*', `define-key' and `global-set-key' depending on context and
|
||||||
|
plist key flags. It was designed to make binding multiple keys more concise,
|
||||||
|
like in vim.
|
||||||
|
|
||||||
|
Yes, it tries to do too much. Yes, I only did it to make the \"frontend\" config
|
||||||
|
that little bit more concise. Yes, I could simply have used the above functions.
|
||||||
|
But it takes a little insanity to custom write your own emacs.d, so what else
|
||||||
|
were you expecting?
|
||||||
|
|
||||||
|
States
|
||||||
|
:n normal
|
||||||
|
:v visual
|
||||||
|
:i insert
|
||||||
|
:e emacs
|
||||||
|
:o operator
|
||||||
|
:m motion
|
||||||
|
:r replace
|
||||||
|
:L local
|
||||||
|
|
||||||
|
These can be combined (order doesn't matter), e.g. :nvi will apply to
|
||||||
|
normal, visual and insert mode. The state resets after the following
|
||||||
|
key=>def pair.
|
||||||
|
|
||||||
|
Capitalize the state flag to make it a local binding.
|
||||||
|
|
||||||
|
If omitted, the keybind will be defined globally.
|
||||||
|
|
||||||
|
Flags
|
||||||
|
:unset [KEY] ; unset key
|
||||||
|
(:map [KEYMAP] [...]) ; apply inner keybinds to KEYMAP
|
||||||
|
(:map* [KEYMAP] [...]) ; apply inner keybinds to KEYMAP (deferred)
|
||||||
|
(:prefix [PREFIX] [...]) ; assign prefix to all inner keybindings
|
||||||
|
(:after [FEATURE] [...]) ; apply keybinds when [FEATURE] loads
|
||||||
|
|
||||||
|
Conditional keybinds
|
||||||
|
(:when [CONDITION] [...])
|
||||||
|
(:unless [CONDITION] [...])
|
||||||
|
|
||||||
|
Example
|
||||||
|
(map! :map magit-mode-map
|
||||||
|
:m \"C-r\" 'do-something ; assign C-r in motion state
|
||||||
|
:nv \"q\" 'magit-mode-quit-window ; assign to 'q' in normal and visual states
|
||||||
|
\"C-x C-r\" 'a-global-keybind
|
||||||
|
|
||||||
|
(:when IS-MAC
|
||||||
|
:n \"M-s\" 'some-fn
|
||||||
|
:i \"M-o\" (lambda (interactive) (message \"Hi\"))))"
|
||||||
|
(let ((keymaps (if (boundp 'keymaps) keymaps))
|
||||||
|
(defer (if (boundp 'defer) defer))
|
||||||
|
(prefix (if (boundp 'prefix) prefix))
|
||||||
|
(state-map '(("n" . normal)
|
||||||
|
("v" . visual)
|
||||||
|
("i" . insert)
|
||||||
|
("e" . emacs)
|
||||||
|
("o" . operator)
|
||||||
|
("m" . motion)
|
||||||
|
("r" . replace)))
|
||||||
|
local key def states forms)
|
||||||
|
(while rest
|
||||||
|
(setq key (pop rest))
|
||||||
|
(push
|
||||||
|
(reverse
|
||||||
|
(cond
|
||||||
|
;; it's a sub expr
|
||||||
|
((listp key)
|
||||||
|
`(,(macroexpand `(map! ,@key))))
|
||||||
|
|
||||||
|
;; it's a flag
|
||||||
|
((keywordp key)
|
||||||
|
(when (cond ((eq key :leader)
|
||||||
|
(push doom-evil-leader rest))
|
||||||
|
((eq key :localleader)
|
||||||
|
(push doom-evil-localleader rest)))
|
||||||
|
(setq key :prefix))
|
||||||
|
(pcase key
|
||||||
|
(:prefix (setq prefix (concat prefix (kbd (pop rest)))) nil)
|
||||||
|
(:map (setq keymaps (-list (pop rest))) nil)
|
||||||
|
(:map* (setq defer t keymaps (-list (pop rest))) nil)
|
||||||
|
(:unset `(,(macroexpand `(map! ,(kbd (pop rest)) nil))))
|
||||||
|
(:after (prog1 `((after! ,(pop rest) ,(macroexpand `(map! ,@rest)))) (setq rest '())))
|
||||||
|
(:when (prog1 `((if ,(pop rest) ,(macroexpand `(map! ,@rest)))) (setq rest '())))
|
||||||
|
(:unless (prog1 `((if (not ,(pop rest)) ,(macroexpand `(map! ,@rest)))) (setq rest '())))
|
||||||
|
(otherwise ; might be a state prefix
|
||||||
|
(mapc (lambda (letter)
|
||||||
|
(cond ((assoc letter state-map)
|
||||||
|
(push (cdr (assoc letter state-map)) states))
|
||||||
|
((string= letter "L")
|
||||||
|
(setq local t))
|
||||||
|
(t (user-error "Invalid mode prefix %s in key %s" letter key))))
|
||||||
|
(split-string (substring (symbol-name key) 1) "" t))
|
||||||
|
(unless states
|
||||||
|
(user-error "Unrecognized keyword %s" key))
|
||||||
|
(when (assoc "L" states)
|
||||||
|
(cond ((= (length states) 1)
|
||||||
|
(user-error "local keybinding for %s must accompany another state" key))
|
||||||
|
((> (length keymaps) 0)
|
||||||
|
(user-error "local keybinding for %s cannot accompany a keymap" key))))
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
;; It's a key-def pair
|
||||||
|
((or (stringp key)
|
||||||
|
(characterp key)
|
||||||
|
(vectorp key))
|
||||||
|
(when (stringp key)
|
||||||
|
(setq key (kbd key)))
|
||||||
|
(when prefix
|
||||||
|
(setq key (cond ((vectorp key) (vconcat prefix key))
|
||||||
|
(t (concat prefix key)))))
|
||||||
|
(unless (> (length rest) 0)
|
||||||
|
(user-error "Map has no definition for %s" key))
|
||||||
|
(setq def (pop rest))
|
||||||
|
(let (out-forms)
|
||||||
|
(cond ((and keymaps states)
|
||||||
|
(mapc (lambda (keymap)
|
||||||
|
(push `(,(if defer 'evil-define-key 'evil-define-key*)
|
||||||
|
',states ,keymap ,key ,def)
|
||||||
|
out-forms))
|
||||||
|
keymaps))
|
||||||
|
(keymaps
|
||||||
|
(mapc (lambda (keymap) (push `(define-key ,keymap ,key ,def) out-forms))
|
||||||
|
keymaps))
|
||||||
|
(states
|
||||||
|
(mapc (lambda (state)
|
||||||
|
(push `(define-key
|
||||||
|
(evil-state-property ',state ,(if local :local-keymap :keymap) t)
|
||||||
|
,key ,def)
|
||||||
|
out-forms))
|
||||||
|
states))
|
||||||
|
(t (push `(,(if local 'local-set-key 'global-set-key)
|
||||||
|
,key ,def)
|
||||||
|
out-forms)))
|
||||||
|
(setq states '()
|
||||||
|
local nil)
|
||||||
|
out-forms))
|
||||||
|
|
||||||
|
(t (user-error "Invalid key %s" key))))
|
||||||
|
forms))
|
||||||
|
`(progn ,@(apply #'nconc (delete nil (delete (list nil) (reverse forms)))))))
|
||||||
|
|
||||||
|
(provide 'core-lib)
|
||||||
|
;;; core-lib.el ends here
|
|
@ -1,6 +1,6 @@
|
||||||
;;; core-modeline.el
|
;;; core-modeline.el --- make mode-lines sexy again
|
||||||
|
|
||||||
;; This file tries to be an almost self-contained configuration of my mode-line.
|
;; This file tries to be a self-contained configuration of my mode-line.
|
||||||
|
|
||||||
;;; These are the invisible dependencies
|
;;; These are the invisible dependencies
|
||||||
;; Required
|
;; Required
|
||||||
|
@ -17,22 +17,25 @@
|
||||||
;;(require 'iedit)
|
;;(require 'iedit)
|
||||||
;;(require 'evil-multiedit)
|
;;(require 'evil-multiedit)
|
||||||
|
|
||||||
(require 'powerline)
|
(package! powerline)
|
||||||
(require 'all-the-icons)
|
|
||||||
|
(package! all-the-icons :demand t)
|
||||||
|
|
||||||
|
(package! eldoc-eval :demand t
|
||||||
|
:config
|
||||||
|
(setq eldoc-in-minibuffer-show-fn 'doom-eldoc-show-in-mode-line)
|
||||||
|
(eldoc-in-minibuffer-mode +1))
|
||||||
|
|
||||||
|
|
||||||
;; all-the-icons doesn't work in the terminal, so we "disable" it.
|
|
||||||
(unless window-system
|
|
||||||
(defun all-the-icons-octicon (&rest _) "" "")
|
|
||||||
(defun all-the-icons-faicon (&rest _) "" "")
|
|
||||||
(defun all-the-icons-fileicon (&rest _) "" "")
|
|
||||||
(defun all-the-icons-wicon (&rest _) "" "")
|
|
||||||
(defun all-the-icons-alltheicon (&rest _) "" ""))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Variables
|
;; Variables
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
(defvar doom-modeline-formats '()
|
||||||
|
"")
|
||||||
|
|
||||||
(defvar doom-modeline-height 29
|
(defvar doom-modeline-height 29
|
||||||
"How tall the mode-line should be (only respected in GUI emacs).")
|
"How tall the mode-line should be (only respected in GUI emacs).")
|
||||||
|
|
||||||
|
@ -44,30 +47,37 @@
|
||||||
;; Custom faces
|
;; Custom faces
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defface doom-modeline-buffer-path '((t (:inherit mode-line :bold t)))
|
(defface doom-modeline-buffer-path
|
||||||
|
'((t (:inherit mode-line :bold t)))
|
||||||
"Face used for the dirname part of the buffer path.")
|
"Face used for the dirname part of the buffer path.")
|
||||||
|
|
||||||
(defface doom-modeline-buffer-project
|
(defface doom-modeline-buffer-project
|
||||||
'((t (:inherit doom-modeline-buffer-path :bold nil)))
|
'((t (:inherit doom-modeline-buffer-path :bold nil)))
|
||||||
"Face used for the filename part of the mode-line buffer path.")
|
"Face used for the filename part of the mode-line buffer path.")
|
||||||
|
|
||||||
(defface doom-modeline-buffer-modified '((t (:inherit highlight :background nil)))
|
(defface doom-modeline-buffer-modified
|
||||||
|
'((t (:inherit highlight :background nil)))
|
||||||
"Face used for the 'unsaved' symbol in the mode-line.")
|
"Face used for the 'unsaved' symbol in the mode-line.")
|
||||||
|
|
||||||
(defface doom-modeline-buffer-major-mode '((t (:inherit mode-line :bold t)))
|
(defface doom-modeline-buffer-major-mode
|
||||||
|
'((t (:inherit mode-line :bold t)))
|
||||||
"Face used for the major-mode segment in the mode-line.")
|
"Face used for the major-mode segment in the mode-line.")
|
||||||
|
|
||||||
(defface doom-modeline-highlight '((t (:inherit mode-line)))
|
(defface doom-modeline-highlight
|
||||||
|
'((t (:inherit mode-line)))
|
||||||
"Face for bright segments of the mode-line.")
|
"Face for bright segments of the mode-line.")
|
||||||
|
|
||||||
(defface doom-modeline-panel '((t (:inherit mode-line)))
|
(defface doom-modeline-panel
|
||||||
|
'((t (:inherit mode-line)))
|
||||||
"Face for 'X out of Y' segments, such as `*anzu', `*evil-substitute' and
|
"Face for 'X out of Y' segments, such as `*anzu', `*evil-substitute' and
|
||||||
`iedit'")
|
`iedit'")
|
||||||
|
|
||||||
(defface doom-modeline-info `((t (:inherit success)))
|
(defface doom-modeline-info
|
||||||
|
`((t (:inherit success)))
|
||||||
"Face for info-level messages in the modeline. Used by `*vc'.")
|
"Face for info-level messages in the modeline. Used by `*vc'.")
|
||||||
|
|
||||||
(defface doom-modeline-warning `((t (:inherit warning)))
|
(defface doom-modeline-warning
|
||||||
|
`((t (:inherit warning)))
|
||||||
"Face for warnings in the modeline. Used by `*flycheck'")
|
"Face for warnings in the modeline. Used by `*flycheck'")
|
||||||
|
|
||||||
(defface doom-modeline-urgent `((t (:inherit error)))
|
(defface doom-modeline-urgent `((t (:inherit error)))
|
||||||
|
@ -86,37 +96,41 @@ active.")
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Functions
|
;; Bootstrap
|
||||||
;;
|
;;
|
||||||
|
|
||||||
;; Where (py|rb)env version strings will be stored
|
;; all-the-icons doesn't work in the terminal, so we "disable" it.
|
||||||
(defvar-local doom-ml--env-version nil)
|
(unless window-system
|
||||||
(defvar-local doom-ml--env-command nil)
|
(defun all-the-icons-octicon (&rest _) "" "")
|
||||||
|
(defun all-the-icons-faicon (&rest _) "" "")
|
||||||
|
(defun all-the-icons-fileicon (&rest _) "" "")
|
||||||
|
(defun all-the-icons-wicon (&rest _) "" "")
|
||||||
|
(defun all-the-icons-alltheicon (&rest _) "" ""))
|
||||||
|
|
||||||
(add-hook 'focus-in-hook 'doom-ml|env-update)
|
(defmacro modeline! (name &rest def)
|
||||||
(add-hook 'find-file-hook 'doom-ml|env-update)
|
(declare (indent defun))) ;; TODO
|
||||||
|
|
||||||
(defun doom-ml|env-update ()
|
(defvar-local doom-modeline-env-version nil)
|
||||||
"Update (py|rb)env version string in `doom-ml--env-version', generated with
|
(defvar-local doom-modeline-env-command nil)
|
||||||
`doom-ml--env-command'."
|
(add-hook 'focus-in-hook 'doom-modeline|update-env)
|
||||||
(when doom-ml--env-command
|
(add-hook 'find-file-hook 'doom-modeline|update-env)
|
||||||
(let* ((default-directory (doom/project-root))
|
(defun doom-modeline|update-env ()
|
||||||
|
(when doom-modeline-env-command
|
||||||
|
(let* ((default-directory (doom-project-root))
|
||||||
(s (shell-command-to-string doom-ml--env-command)))
|
(s (shell-command-to-string doom-ml--env-command)))
|
||||||
(setq doom-ml--env-version (if (string-match "[ \t\n\r]+\\'" s)
|
(setq doom-modeline-env-version (if (string-match "[ \t\n\r]+\\'" s)
|
||||||
(replace-match "" t t s)
|
(replace-match "" t t s)
|
||||||
s)))))
|
s)))))
|
||||||
|
|
||||||
(defmacro def-version-cmd! (mode command)
|
(doom-define-setting 'env
|
||||||
"Define a COMMAND for MODE that will set `doom-ml--env-command' when that mode
|
"Command used to set the interpreter version in the current buffer."
|
||||||
is activated, which should return the version number of the current environment.
|
:type '(stringp functionp)
|
||||||
It is used by `doom-ml|env-update' to display a version number in the modeline.
|
:hook (lambda (command) (setq doom-modeline-env-command x)))
|
||||||
For instance:
|
|
||||||
|
|
||||||
(def-version-cmd! ruby-mode \"ruby --version | cut -d' ' -f2\")
|
;; (set! python-mode :env "python --version 2>&1 | cut -d' ' -f2")
|
||||||
|
;; (set! ruby-mode :env "ruby --version 2>&1 | cut -d' ' -f2")
|
||||||
|
|
||||||
This will display the ruby version in the modeline in ruby-mode buffers. It is
|
(defsubst active() (eq (selected-window) powerline-selected-window))
|
||||||
cached the first time."
|
|
||||||
`(add-hook ',mode (lambda () (setq doom-ml--env-command ,command))))
|
|
||||||
|
|
||||||
(defun doom-ml-flycheck-count (state)
|
(defun doom-ml-flycheck-count (state)
|
||||||
"Return flycheck information for the given error type STATE."
|
"Return flycheck information for the given error type STATE."
|
||||||
|
@ -127,6 +141,9 @@ cached the first time."
|
||||||
|
|
||||||
(defun doom-make-xpm (color height width)
|
(defun doom-make-xpm (color height width)
|
||||||
"Create an XPM bitmap."
|
"Create an XPM bitmap."
|
||||||
|
(unless (featurep 'powerline)
|
||||||
|
(require 'powerline)
|
||||||
|
(pl/memoize 'doom-make-xpm))
|
||||||
(when window-system
|
(when window-system
|
||||||
(propertize
|
(propertize
|
||||||
" " 'display
|
" " 'display
|
||||||
|
@ -140,7 +157,7 @@ cached the first time."
|
||||||
project root). Excludes the file basename. See `doom-buffer-name' for that."
|
project root). Excludes the file basename. See `doom-buffer-name' for that."
|
||||||
(if buffer-file-name
|
(if buffer-file-name
|
||||||
(let* ((default-directory (f-dirname buffer-file-name))
|
(let* ((default-directory (f-dirname buffer-file-name))
|
||||||
(buffer-path (f-relative buffer-file-name (doom/project-root)))
|
(buffer-path (f-relative buffer-file-name (doom-project-root)))
|
||||||
(max-length (truncate (* (window-body-width) 0.4))))
|
(max-length (truncate (* (window-body-width) 0.4))))
|
||||||
(when (and buffer-path (not (equal buffer-path ".")))
|
(when (and buffer-path (not (equal buffer-path ".")))
|
||||||
(if (> (length buffer-path) max-length)
|
(if (> (length buffer-path) max-length)
|
||||||
|
@ -159,16 +176,35 @@ project root). Excludes the file basename. See `doom-buffer-name' for that."
|
||||||
buffer-path)))
|
buffer-path)))
|
||||||
"%b"))
|
"%b"))
|
||||||
|
|
||||||
(defsubst active () (eq (selected-window) powerline-selected-window))
|
(defun doom-eldoc-show-in-mode-line (input)
|
||||||
|
"Display string STR in the mode-line next to minibuffer."
|
||||||
;; Memoize for optimization
|
(with-current-buffer (eldoc-current-buffer)
|
||||||
(pl/memoize 'doom-make-xpm)
|
(let* ((max (window-width (selected-window)))
|
||||||
(pl/memoize 'face-background)
|
(str (and (stringp input) (concat " " input)))
|
||||||
(pl/memoize 'all-the-icons-octicon)
|
(len (length str))
|
||||||
|
(tmp-str str)
|
||||||
|
(mode-line-format (or (and str (doom-eldoc-modeline))
|
||||||
|
mode-line-format))
|
||||||
|
roll mode-line-in-non-selected-windows)
|
||||||
|
(catch 'break
|
||||||
|
(if (and (> len max) eldoc-mode-line-rolling-flag)
|
||||||
|
(progn
|
||||||
|
(while (setq roll (sit-for 0.3))
|
||||||
|
(setq tmp-str (substring tmp-str 2)
|
||||||
|
mode-line-format (concat tmp-str " [<]" str))
|
||||||
|
(force-mode-line-update)
|
||||||
|
(when (< (length tmp-str) 2) (setq tmp-str str)))
|
||||||
|
(unless roll
|
||||||
|
(when eldoc-mode-line-stop-rolling-on-input
|
||||||
|
(setq eldoc-mode-line-rolling-flag nil))
|
||||||
|
(throw 'break nil)))
|
||||||
|
(force-mode-line-update)
|
||||||
|
(sit-for eldoc-show-in-mode-line-delay))))
|
||||||
|
(force-mode-line-update)))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Mode-line segments
|
;; Segments
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defun *buffer-project ()
|
(defun *buffer-project ()
|
||||||
|
@ -179,7 +215,7 @@ project root). Excludes the file basename. See `doom-buffer-name' for that."
|
||||||
:face face
|
:face face
|
||||||
:v-adjust -0.05
|
:v-adjust -0.05
|
||||||
:height 1.25)
|
:height 1.25)
|
||||||
(propertize (concat " " (abbreviate-file-name (doom/project-root)))
|
(propertize (concat " " (abbreviate-file-name (doom-project-root)))
|
||||||
'face face))))
|
'face face))))
|
||||||
|
|
||||||
(defun *buffer-info ()
|
(defun *buffer-info ()
|
||||||
|
@ -230,7 +266,7 @@ directory, the file name, and its state (modified, read-only or non-existent)."
|
||||||
(propertize
|
(propertize
|
||||||
(concat (format-mode-line mode-name)
|
(concat (format-mode-line mode-name)
|
||||||
(if (stringp mode-line-process) mode-line-process)
|
(if (stringp mode-line-process) mode-line-process)
|
||||||
(if doom-ml--env-version (concat " " doom-ml--env-version))
|
(if doom-modeline-env-version (concat " " doom-modeline-env-version))
|
||||||
(and (featurep 'face-remap)
|
(and (featurep 'face-remap)
|
||||||
(/= text-scale-mode-amount 0)
|
(/= text-scale-mode-amount 0)
|
||||||
(format " (%+d)" text-scale-mode-amount)))
|
(format " (%+d)" text-scale-mode-amount)))
|
||||||
|
@ -411,96 +447,59 @@ lines are selected, or the NxM dimensions of a block selection."
|
||||||
(let ((size (image-size (image-get-display-property) :pixels)))
|
(let ((size (image-size (image-get-display-property) :pixels)))
|
||||||
(format " %dx%d " (car size) (cdr size))))))
|
(format " %dx%d " (car size) (cdr size))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
(defun doom-modeline (&optional id)
|
|
||||||
`(:eval
|
|
||||||
(let* ((meta (concat (*macro-recording)
|
|
||||||
(*anzu)
|
|
||||||
(*evil-substitute)
|
|
||||||
(*iedit)))
|
|
||||||
(lhs (list (doom-make-xpm (face-background (if (active)
|
|
||||||
'doom-modeline-bar
|
|
||||||
'doom-modeline-inactive-bar))
|
|
||||||
doom-modeline-height
|
|
||||||
doom-modeline-bar-width)
|
|
||||||
,(unless (eq id 'scratch)
|
|
||||||
'(if (and (= (length meta) 0)
|
|
||||||
(not doom-ediff-enabled))
|
|
||||||
" %I "
|
|
||||||
meta))
|
|
||||||
" "
|
|
||||||
,(cond ((eq id 'scratch)
|
|
||||||
'(*buffer-project))
|
|
||||||
((eq id 'media)
|
|
||||||
'(*media-info))
|
|
||||||
(t
|
|
||||||
'(list (*buffer-info)
|
|
||||||
" %l:%c %p "
|
|
||||||
(*selection-info)
|
|
||||||
)))))
|
|
||||||
(rhs ,(if id
|
|
||||||
'(list (*major-mode))
|
|
||||||
'(list (*buffer-encoding)
|
|
||||||
(*vc)
|
|
||||||
(*major-mode)
|
|
||||||
(*flycheck)
|
|
||||||
)))
|
|
||||||
(mid (propertize
|
|
||||||
" " 'display `((space :align-to (- (+ right right-fringe right-margin)
|
|
||||||
,(+ 1 (string-width (format-mode-line rhs)))))))))
|
|
||||||
(list lhs mid rhs))))
|
|
||||||
|
|
||||||
(setq-default mode-line-format (doom-modeline))
|
|
||||||
|
|
||||||
(add-hook! image-mode
|
|
||||||
(setq mode-line-format (doom-modeline 'media)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Eldoc-in-mode-line support (for `eval-expression')
|
;; Mode lines
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defun doom-eldoc-modeline ()
|
(doom-modeline-define 'main
|
||||||
`(:eval
|
`(let* ((meta (concat (*macro-recording)
|
||||||
(list (list ,(when window-system
|
(*anzu)
|
||||||
`(doom-make-xpm (face-background 'doom-modeline-eldoc-bar)
|
(*evil-substitute)
|
||||||
doom-modeline-height
|
(*iedit)))
|
||||||
doom-modeline-bar-width))
|
(lhs (list (doom-make-xpm (face-background (if (active)
|
||||||
(and (bound-and-true-p str) str))
|
'doom-modeline-bar
|
||||||
(propertize " " 'display `((space :align-to (1- (+ right right-fringe right-margin))))))))
|
'doom-modeline-inactive-bar))
|
||||||
|
doom-modeline-height
|
||||||
|
doom-modeline-bar-width)
|
||||||
|
(if (= (length meta) 0) " %I " meta)
|
||||||
|
" "
|
||||||
|
(*buffer-info)
|
||||||
|
" %l:%c %p "
|
||||||
|
(*selection-info)))
|
||||||
|
(rhs (list (*buffer-encoding)
|
||||||
|
(*vc)
|
||||||
|
(*major-mode)
|
||||||
|
(*flycheck)))
|
||||||
|
(mid (propertize
|
||||||
|
" " 'display `((space :align-to (- (+ right right-fringe right-margin)
|
||||||
|
,(+ 1 (string-width (format-mode-line rhs)))))))))
|
||||||
|
(list lhs mid rhs)))
|
||||||
|
|
||||||
(defun doom-eldoc-show-in-mode-line (input)
|
(doom-modeline-define 'eldoc
|
||||||
"Display string STR in the mode-line next to minibuffer."
|
`(list (list ,(when window-system
|
||||||
(with-current-buffer (eldoc-current-buffer)
|
`(doom-make-xpm (face-background 'doom-modeline-eldoc-bar)
|
||||||
(let* ((max (window-width (selected-window)))
|
doom-modeline-height
|
||||||
(str (and (stringp input) (concat " " input)))
|
doom-modeline-bar-width))
|
||||||
(len (length str))
|
(and (bound-and-true-p str) str))
|
||||||
(tmp-str str)
|
(propertize " " 'display `((space :align-to (1- (+ right right-fringe right-margin)))))))
|
||||||
(mode-line-format (or (and str (doom-eldoc-modeline))
|
|
||||||
mode-line-format))
|
|
||||||
roll mode-line-in-non-selected-windows)
|
|
||||||
(catch 'break
|
|
||||||
(if (and (> len max) eldoc-mode-line-rolling-flag)
|
|
||||||
(progn
|
|
||||||
(while (setq roll (sit-for 0.3))
|
|
||||||
(setq tmp-str (substring tmp-str 2)
|
|
||||||
mode-line-format (concat tmp-str " [<]" str))
|
|
||||||
(force-mode-line-update)
|
|
||||||
(when (< (length tmp-str) 2) (setq tmp-str str)))
|
|
||||||
(unless roll
|
|
||||||
(when eldoc-mode-line-stop-rolling-on-input
|
|
||||||
(setq eldoc-mode-line-rolling-flag nil))
|
|
||||||
(throw 'break nil)))
|
|
||||||
(force-mode-line-update)
|
|
||||||
(sit-for eldoc-show-in-mode-line-delay))))
|
|
||||||
(force-mode-line-update)))
|
|
||||||
|
|
||||||
;; Show eldoc in the mode-line when using `eval-expression'.
|
(doom-modeline-define 'minimal
|
||||||
(use-package eldoc-eval
|
`(let* ((lhs (list (doom-make-xpm (face-background (if (active)
|
||||||
:config
|
'doom-modeline-bar
|
||||||
(setq eldoc-in-minibuffer-show-fn 'doom-eldoc-show-in-mode-line)
|
'doom-modeline-inactive-bar))
|
||||||
(eldoc-in-minibuffer-mode +1))
|
doom-modeline-height
|
||||||
|
doom-modeline-bar-width)
|
||||||
|
" "
|
||||||
|
(*buffer-project)))
|
||||||
|
(rhs (list (*major-mode)))
|
||||||
|
(mid (propertize
|
||||||
|
" " 'display `((space :align-to (- (+ right right-fringe right-margin)
|
||||||
|
,(+ 1 (string-width (format-mode-line rhs)))))))))
|
||||||
|
(list lhs mid rhs)))
|
||||||
|
|
||||||
|
;;
|
||||||
|
(setq-default mode-line-format (assq 'main doom-modeline-formats))
|
||||||
|
|
||||||
(provide 'core-modeline)
|
(provide 'core-modeline)
|
||||||
;;; core-modeline.el ends here
|
;;; core-modeline.el ends here
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
;;; core-os-linux.el --- Debian-specific settings
|
|
||||||
|
|
||||||
(setq x-super-keysym 'alt
|
|
||||||
x-meta-keysym 'meta)
|
|
||||||
|
|
||||||
(defun doom-open-with (command &rest args)
|
|
||||||
"Open PATH in APP-NAME, using xdg-open."
|
|
||||||
(interactive)
|
|
||||||
(unless args
|
|
||||||
(setq args (f-full (s-replace "'" "\\'"
|
|
||||||
(or path (if (eq major-mode 'dired-mode)
|
|
||||||
(dired-get-file-for-visit)
|
|
||||||
(buffer-file-name)))))))
|
|
||||||
(let ((command (apply 'format command
|
|
||||||
(mapcar (lambda (a) (shell-quote-argument a))
|
|
||||||
args))))
|
|
||||||
(message "Running: %s" command)
|
|
||||||
(shell-command command)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; OS-specific functions
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun os-open-in-browser ()
|
|
||||||
"Open the current file in the browser."
|
|
||||||
(interactive)
|
|
||||||
(browse-url buffer-file-name))
|
|
||||||
|
|
||||||
(defun os-open-in-default-program ()
|
|
||||||
"Open the current file (or selected file in dired) with xdg-open."
|
|
||||||
(interactive)
|
|
||||||
(doom-open-with "xdg-open '%s'"))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Plugins
|
|
||||||
;;
|
|
||||||
|
|
||||||
(use-package openwith
|
|
||||||
:config
|
|
||||||
(openwith-mode t)
|
|
||||||
(setq openwith-associations
|
|
||||||
'(("\\.\\(pdf\\|jpe?g\\|gif\\|docx?\\|pptx?\\|xlsx?\\|zip\\|tar\\(\\.gz\\)?\\|rar\\)$"
|
|
||||||
"xdg-open" (file)))))
|
|
||||||
|
|
||||||
(provide 'core-os-linux)
|
|
||||||
;;; core-os-linux.el ends here
|
|
|
@ -1,126 +0,0 @@
|
||||||
;;; core-os-osx.el --- Mac-specific settings
|
|
||||||
|
|
||||||
(global-set-key (kbd "M-q") 'kill-emacs)
|
|
||||||
|
|
||||||
(setq ;; Prefixes: Command = M, Alt = A
|
|
||||||
mac-command-modifier 'meta
|
|
||||||
mac-option-modifier 'alt
|
|
||||||
;; sane trackpad/mouse scroll settings
|
|
||||||
mac-redisplay-dont-reset-vscroll t
|
|
||||||
mac-mouse-wheel-smooth-scroll nil
|
|
||||||
mouse-wheel-scroll-amount '(5 ((shift) . 2)) ; one line at a time
|
|
||||||
mouse-wheel-progressive-speed nil ; don't accelerate scrolling
|
|
||||||
;; Curse Lion and its sudden but inevitable fullscreen mode!
|
|
||||||
;; NOTE Meaningless to railwaycat's emacs-mac build
|
|
||||||
ns-use-native-fullscreen nil
|
|
||||||
;; Don't open files from the workspace in a new frame
|
|
||||||
ns-pop-up-frames nil)
|
|
||||||
|
|
||||||
;; On OSX, in GUI Emacs, `exec-path' isn't populated properly (it should match
|
|
||||||
;; $PATH in my shell). `exe-path-from-shell' fixes this.
|
|
||||||
(when window-system
|
|
||||||
(setenv "SHELL" "/usr/local/bin/zsh")
|
|
||||||
;; `exec-path-from-shell' is slow, so bring out the cache
|
|
||||||
(setq exec-path
|
|
||||||
(eval-when-compile
|
|
||||||
(require 'exec-path-from-shell)
|
|
||||||
(exec-path-from-shell-initialize)
|
|
||||||
exec-path)))
|
|
||||||
|
|
||||||
;; Enable mouse support in terminal
|
|
||||||
(unless window-system
|
|
||||||
(require 'mouse)
|
|
||||||
(xterm-mouse-mode t)
|
|
||||||
(global-set-key [mouse-4] (λ! (scroll-down 4)))
|
|
||||||
(global-set-key [mouse-5] (λ! (scroll-up 4)))
|
|
||||||
|
|
||||||
(defun track-mouse (e))
|
|
||||||
(setq mouse-sel-mode t))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; OSX-related plugins + hacks
|
|
||||||
;;
|
|
||||||
|
|
||||||
(use-package applescript-mode
|
|
||||||
:mode "\\.applescript$"
|
|
||||||
:init (add-hook 'applescript-mode-hook 'nlinum-mode)
|
|
||||||
:config
|
|
||||||
(def-docset! applescript-mode "applescript")
|
|
||||||
(after! quickrundb
|
|
||||||
(quickrun-add-command
|
|
||||||
"applescript" `((:command . ,as-osascript-command)
|
|
||||||
(:cmdopt . "-ss %s")
|
|
||||||
(:description . "Run applescript"))
|
|
||||||
:mode 'applescript-mode)))
|
|
||||||
|
|
||||||
(def-project-type! lb6 "lb6"
|
|
||||||
:match "\\.lb\\(action\\|ext\\)/.+$"
|
|
||||||
:build (lambda ()
|
|
||||||
(awhen (f-traverse-upwards (lambda (f) (f-ext? f "lbaction")))
|
|
||||||
(shell-command (format "open '%s'" it)))))
|
|
||||||
|
|
||||||
(after! evil
|
|
||||||
;; On OSX, stop copying each visual state move to the clipboard:
|
|
||||||
;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on
|
|
||||||
;; Most of this code grokked from:
|
|
||||||
;; http://stackoverflow.com/questions/15873346/elisp-rename-macro
|
|
||||||
(when (or (featurep 'mac) (featurep 'ns))
|
|
||||||
(advice-add 'evil-visual-update-x-selection :override 'ignore)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; OS-specific functions
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun doom-open-with (&optional app-name path)
|
|
||||||
"Send PATH to APP-NAME on OSX."
|
|
||||||
(interactive)
|
|
||||||
(let* ((path (f-full (s-replace "'" "\\'"
|
|
||||||
(or path (if (eq major-mode 'dired-mode)
|
|
||||||
(dired-get-file-for-visit)
|
|
||||||
(buffer-file-name))))))
|
|
||||||
(command (format "open %s"
|
|
||||||
(if app-name
|
|
||||||
(format "-a %s '%s'" (shell-quote-argument app-name) path)
|
|
||||||
(format "'%s'" path)))))
|
|
||||||
(message "Running: %s" command)
|
|
||||||
(shell-command command)))
|
|
||||||
|
|
||||||
(defmacro def-open-with! (id &optional app dir)
|
|
||||||
`(defun ,(intern (format "os-%s" id)) ()
|
|
||||||
(interactive)
|
|
||||||
(doom-open-with ,app ,dir)))
|
|
||||||
|
|
||||||
(def-open-with! open-in-default-program)
|
|
||||||
(def-open-with! open-in-browser "Google Chrome")
|
|
||||||
(def-open-with! reveal "Finder" default-directory)
|
|
||||||
(def-open-with! reveal-project "Finder" (doom/project-root))
|
|
||||||
(def-open-with! upload "Transmit")
|
|
||||||
(def-open-with! upload-folder "Transmit" default-directory)
|
|
||||||
(def-open-with! send-to-launchbar "LaunchBar")
|
|
||||||
(def-open-with! send-project-to-launchbar "LaunchBar" (doom/project-root))
|
|
||||||
|
|
||||||
(defun os-switch-to-term ()
|
|
||||||
(interactive)
|
|
||||||
(do-applescript "tell application \"iTerm\" to activate"))
|
|
||||||
|
|
||||||
(defun os-switch-to-term-and-cd ()
|
|
||||||
(interactive)
|
|
||||||
(doom:send-to-tmux (format "cd %s" (shell-quote-argument default-directory)))
|
|
||||||
(doom-switch-to-iterm))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Plugins
|
|
||||||
;;
|
|
||||||
|
|
||||||
(use-package openwith
|
|
||||||
:config
|
|
||||||
(openwith-mode t)
|
|
||||||
(setq openwith-associations
|
|
||||||
'(("\\.\\(pdf\\|jpe?g\\|gif\\|docx?\\|pptx?\\|xlsx?\\|zip\\|tar\\(\\.gz\\)?\\|rar\\)$"
|
|
||||||
"open" (file)))))
|
|
||||||
|
|
||||||
(provide 'core-os-osx)
|
|
||||||
;;; core-os-osx.el ends here
|
|
|
@ -1,8 +0,0 @@
|
||||||
;;; core-os-win32.el --- Windows-specific settings
|
|
||||||
|
|
||||||
(defun doom-open-with (&optional app-name path)
|
|
||||||
(interactive)
|
|
||||||
(error "Not yet implemented"))
|
|
||||||
|
|
||||||
(provide 'core-os-win32)
|
|
||||||
;;; core-os-win32.el ends here
|
|
|
@ -1,28 +1,59 @@
|
||||||
;;; core-os.el
|
;;; core-os.el --- consistent behavior across OSes
|
||||||
|
|
||||||
(defconst IS-MAC (eq system-type 'darwin))
|
(defconst IS-MAC (eq system-type 'darwin))
|
||||||
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
||||||
(defconst IS-WINDOWS (eq system-type 'windows-nt))
|
(defconst IS-WINDOWS (eq system-type 'windows-nt))
|
||||||
|
|
||||||
(setq
|
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)
|
||||||
;; Use a shared clipboard
|
;; Use a shared clipboard
|
||||||
x-select-enable-clipboard t
|
select-enable-clipboard t
|
||||||
select-enable-clipboard t
|
select-enable-primary t)
|
||||||
;; Treat clipboard input as UTF-8 string first; compound text next, etc.
|
|
||||||
x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
|
|
||||||
|
|
||||||
;; Stubs, these should be defined in all OS modules
|
|
||||||
(noop! doom-open-with (&optional app-name path))
|
|
||||||
(noop! os-open-in-browser)
|
|
||||||
(noop! os-open-in-default-program)
|
|
||||||
(noop! os-reveal)
|
|
||||||
(noop! os-reveal-project)
|
|
||||||
(noop! os-switch-to-term)
|
|
||||||
(noop! os-switch-to-term-and-cd)
|
|
||||||
|
|
||||||
(cond (IS-MAC (require 'core-os-osx))
|
;;;
|
||||||
(IS-LINUX (require 'core-os-linux))
|
;; OS-specific configs
|
||||||
(IS-WINDOWS (require 'core-os-win32)))
|
(cond (IS-MAC
|
||||||
|
;; Prefixes: Command = M, Alt = A
|
||||||
|
(setq mac-command-modifier 'meta
|
||||||
|
mac-option-modifier 'alt
|
||||||
|
;; sane trackpad/mouse scroll settings
|
||||||
|
mac-redisplay-dont-reset-vscroll t
|
||||||
|
mac-mouse-wheel-smooth-scroll nil
|
||||||
|
mouse-wheel-scroll-amount '(5 ((shift) . 2)) ; one line at a time
|
||||||
|
mouse-wheel-progressive-speed nil ; don't accelerate scrolling
|
||||||
|
;; Curse Lion and its sudden but inevitable fullscreen mode!
|
||||||
|
;; NOTE Meaningless to railwaycat's emacs-mac build
|
||||||
|
ns-use-native-fullscreen nil
|
||||||
|
;; Don't open files from the workspace in a new frame
|
||||||
|
ns-pop-up-frames nil)
|
||||||
|
|
||||||
|
;; On OSX, in GUI Emacs, `exec-path' isn't populated properly (it should
|
||||||
|
;; match $PATH in my shell). `exe-path-from-shell' fixes this.
|
||||||
|
(package! exec-path-from-shell)
|
||||||
|
(when (display-graphic-p)
|
||||||
|
(setenv "SHELL" "/usr/local/bin/zsh")
|
||||||
|
;; `exec-path-from-shell' is slow, so bring out the cache
|
||||||
|
(setq exec-path
|
||||||
|
(or (persistent-soft-fetch 'exec-path "emacs")
|
||||||
|
(persistent-soft-store
|
||||||
|
'exec-path
|
||||||
|
(progn
|
||||||
|
(require 'exec-path-from-shell)
|
||||||
|
(exec-path-from-shell-initialize)
|
||||||
|
exec-path)
|
||||||
|
"emacs"))))
|
||||||
|
|
||||||
|
(after! evil
|
||||||
|
;; On OSX, stop copying each visual state move to the clipboard:
|
||||||
|
;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on
|
||||||
|
;; Most of this code grokked from:
|
||||||
|
;; http://stackoverflow.com/questions/15873346/elisp-rename-macro
|
||||||
|
(when (or (featurep 'mac) (featurep 'ns))
|
||||||
|
(advice-add 'evil-visual-update-x-selection :override 'ignore))))
|
||||||
|
|
||||||
|
(IS-LINUX
|
||||||
|
(setq x-super-keysym 'meta
|
||||||
|
x-meta-keysym 'alt)))
|
||||||
|
|
||||||
(provide 'core-os)
|
(provide 'core-os)
|
||||||
;;; core-os.el ends here
|
;;; core-os.el ends here
|
||||||
|
|
211
core/core-packages.el
Normal file
211
core/core-packages.el
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
;;; core-packages.el
|
||||||
|
|
||||||
|
;; Emacs has always been opinionated about package management. Unfortunately, so
|
||||||
|
;; have I. I used to use Cask, but found it very unreliable, so the result is
|
||||||
|
;; this: a mini-package manager I've written by combining the functionality of
|
||||||
|
;; package.el, quelpa and use-package.
|
||||||
|
;;
|
||||||
|
;; Why all the trouble? Because I want to be able to call an
|
||||||
|
;; 'update-all-packages' function from a shell script and the like. I want to be
|
||||||
|
;; able to manage my Emacs' packages from the command line, because I have tools
|
||||||
|
;; in my dotfiles to help me auto-update everything with a one-liner.
|
||||||
|
|
||||||
|
(defvar doom-init nil
|
||||||
|
"Whether doom's package system has been initialized or not. It may not be if
|
||||||
|
you have byte-compiled your configuration (as intended).")
|
||||||
|
|
||||||
|
(defvar doom-packages '(quelpa-use-package)
|
||||||
|
"List of enabled packages.")
|
||||||
|
|
||||||
|
(defvar doom-modules nil
|
||||||
|
"List of installed modules.")
|
||||||
|
|
||||||
|
(defvar doom-packages-auto-p (not noninteractive)
|
||||||
|
"")
|
||||||
|
|
||||||
|
(defvar doom--load-path load-path
|
||||||
|
"A backup of `load-path' before it was initialized.")
|
||||||
|
|
||||||
|
(setq load-prefer-newer nil
|
||||||
|
package--init-file-ensured t
|
||||||
|
package-user-dir (expand-file-name "elpa" doom-packages-dir)
|
||||||
|
package-enable-at-startup nil
|
||||||
|
package-archives
|
||||||
|
'(("gnu" . "http://elpa.gnu.org/packages/")
|
||||||
|
("melpa" . "http://melpa.org/packages/")
|
||||||
|
("org" . "http://orgmode.org/elpa/"))
|
||||||
|
|
||||||
|
use-package-always-ensure t
|
||||||
|
use-package-always-defer t
|
||||||
|
quelpa-checkout-melpa-p nil
|
||||||
|
quelpa-update-melpa-p nil
|
||||||
|
quelpa-dir (expand-file-name "quelpa" doom-packages-dir))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Bootstrap
|
||||||
|
;;
|
||||||
|
|
||||||
|
(autoload 'use-package "use-package")
|
||||||
|
|
||||||
|
(defun doom-package-init (&optional force-p)
|
||||||
|
"Initialize DOOM, its essential packages and package.el. This must be used on
|
||||||
|
first run. If you byte compile core/core.el, this file is avoided to speed up
|
||||||
|
startup."
|
||||||
|
(when (or (not doom-init) force-p)
|
||||||
|
(package-initialize)
|
||||||
|
(unless (file-exists-p package-user-dir)
|
||||||
|
(package-refresh-contents))
|
||||||
|
(unless (package-installed-p 'quelpa-use-package)
|
||||||
|
(package-install 'quelpa-use-package t))
|
||||||
|
|
||||||
|
(require 'quelpa)
|
||||||
|
(require 'use-package)
|
||||||
|
(when doom-packages-auto-p
|
||||||
|
(setq use-package-always-ensure t)
|
||||||
|
(require 'quelpa-use-package)
|
||||||
|
(quelpa-use-package-activate-advice))
|
||||||
|
|
||||||
|
(add-to-list 'load-path doom-modules-dir)
|
||||||
|
(add-to-list 'load-path doom-private-dir)
|
||||||
|
(add-to-list 'load-path doom-core-dir)
|
||||||
|
|
||||||
|
(setq doom-init t)))
|
||||||
|
|
||||||
|
(defmacro package! (name &rest rest)
|
||||||
|
"Declare a package. Wraps around `use-package', and takes the same arguments
|
||||||
|
that it does."
|
||||||
|
(declare (indent defun))
|
||||||
|
(add-to-list 'doom-packages name)
|
||||||
|
(unless doom-packages-auto-p
|
||||||
|
(when (and (plist-member rest :ensure)
|
||||||
|
(plist-get rest :ensure))
|
||||||
|
(setq rest (plist-put rest :ensure nil)))
|
||||||
|
(when (plist-member rest :quelpa)
|
||||||
|
(use-package-plist-delete rest :quelpa)))
|
||||||
|
(macroexpand-all `(use-package ,name ,@rest)))
|
||||||
|
|
||||||
|
(defmacro load-internal! (module package)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
(defmacro load! (plugin)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Commands
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defun doom-package-outdated-p (package &optional inhibit-refresh)
|
||||||
|
"Determine whether PACKAGE (a symbol) is outdated or not. If INHIBIT-REFRESH
|
||||||
|
is non-nil, don't run `package-refresh-contents' (which is slow. Use for batch
|
||||||
|
processing, and run `package-refresh-contents' once, beforehand)."
|
||||||
|
(unless inhibit-refresh
|
||||||
|
(package-refresh-contents))
|
||||||
|
(when (and (package-installed-p package)
|
||||||
|
(cadr (assq package package-archive-contents)))
|
||||||
|
(let* ((newest-desc (cadr (assq package package-archive-contents)))
|
||||||
|
(installed-desc (cadr (or (assq package package-alist)
|
||||||
|
(assq package package--builtins))))
|
||||||
|
(newest-version (package-desc-version newest-desc))
|
||||||
|
(installed-version (package-desc-version installed-desc)))
|
||||||
|
(not (version-list-<= newest-version installed-version)))))
|
||||||
|
|
||||||
|
(defun doom/packages-reload ()
|
||||||
|
"Reload DOOM Emacs. This includes the `load-path'"
|
||||||
|
(interactive)
|
||||||
|
(setq load-path doom--load-path)
|
||||||
|
(doom-package-init t)
|
||||||
|
(when (called-interactively-p 'interactive)
|
||||||
|
(message "Reloaded %s packages" (length package-alist))))
|
||||||
|
|
||||||
|
(defun doom/packages-install ()
|
||||||
|
"Activate `doom-packages-auto-p' and evaluation your emacs configuration
|
||||||
|
again, in order to auto-install all packages that are missing."
|
||||||
|
(interactive)
|
||||||
|
(setq doom-packages-auto-p t)
|
||||||
|
(doom-package-init t)
|
||||||
|
(load (expand-file-name "init.el" doom-emacs-dir) nil nil t))
|
||||||
|
|
||||||
|
(defun doom/packages-update ()
|
||||||
|
"Update all installed packages. This includes quelpa itself, quelpa-installed
|
||||||
|
packages, and ELPA packages."
|
||||||
|
(interactive)
|
||||||
|
(doom-package-init t)
|
||||||
|
(quelpa-upgrade) ; upgrade quelpa + quelpa-installed packages
|
||||||
|
(package-refresh-contents) ; ...then packages.el
|
||||||
|
(mapc (lambda (package)
|
||||||
|
(condition-case ex
|
||||||
|
(let ((desc (cadr (assq package package-alist))))
|
||||||
|
(delete-directory (package-desc-dir desc) t)
|
||||||
|
(package-install-from-archive (cadr (assoc package package-archive-contents))))
|
||||||
|
('error (message "ERROR: %s" ex)))) ;; TODO
|
||||||
|
(-uniq (--filter (or (assq it quelpa-cache)
|
||||||
|
(doom-package-outdated-p it t))
|
||||||
|
(package--find-non-dependencies)))))
|
||||||
|
|
||||||
|
(defun doom/packages-clean ()
|
||||||
|
"Delete unused packages."
|
||||||
|
(interactive)
|
||||||
|
(doom-package-init t)
|
||||||
|
(let* ((package-selected-packages (-intersection (package--find-non-dependencies) doom-packages))
|
||||||
|
(packages-to-delete (package--removable-packages))
|
||||||
|
quelpa-modified-p)
|
||||||
|
(cond ((not package-selected-packages)
|
||||||
|
(message "No packages installed!"))
|
||||||
|
((not packages-to-delete)
|
||||||
|
(message "No unused packages to remove."))
|
||||||
|
((not (y-or-n-p
|
||||||
|
(format "%s packages will be deleted:\n%s\n\nProceed?"
|
||||||
|
(length packages-to-delete)
|
||||||
|
(mapconcat 'symbol-name (reverse packages-to-delete) ", "))))
|
||||||
|
(message "Aborted."))
|
||||||
|
(t
|
||||||
|
(dolist (package packages-to-delete)
|
||||||
|
(package-delete package t)
|
||||||
|
(when (assq package quelpa-cache)
|
||||||
|
(setq quelpa-cache (assq-delete-all package quelpa-cache)
|
||||||
|
quelpa-modified-p t)))
|
||||||
|
(when quelpa-modified-p
|
||||||
|
(quelpa-save-cache))))))
|
||||||
|
|
||||||
|
(defun doom/byte-compile ()
|
||||||
|
"Byte (re)compile the important files in your emacs configuration. No more no
|
||||||
|
less."
|
||||||
|
(interactive)
|
||||||
|
(doom-package-init)
|
||||||
|
(mapc 'byte-compile-file
|
||||||
|
(append (list (expand-file-name "init.el" doom-emacs-dir)
|
||||||
|
(expand-file-name "core.el" doom-core-dir))
|
||||||
|
(reverse
|
||||||
|
(file-expand-wildcards
|
||||||
|
(expand-file-name "core*.el" doom-core-dir)))
|
||||||
|
(file-expand-wildcards
|
||||||
|
(expand-file-name "*/*/packages.el" doom-modules-dir)))))
|
||||||
|
|
||||||
|
(defun doom/refresh-autoloads (&optional inhibit-require)
|
||||||
|
"Refreshes your emacs config's autoloads file. Use this if you modify an
|
||||||
|
autoload.el file in any module."
|
||||||
|
(interactive)
|
||||||
|
(let ((generated-autoload-file (concat doom-modules-dir "autoloads.el"))
|
||||||
|
(interactive-p (called-interactively-p 'interactive))
|
||||||
|
(autoload-files
|
||||||
|
(file-expand-wildcards
|
||||||
|
(expand-file-name "*/*/autoload.el" doom-modules-dir))))
|
||||||
|
(when (file-exists-p generated-autoload-file)
|
||||||
|
(delete-file generated-autoload-file)
|
||||||
|
(when interactive-p (message "Deleted old autoloads.el")))
|
||||||
|
(dolist (file autoload-files)
|
||||||
|
(update-file-autoloads file t)
|
||||||
|
(when interactive-p
|
||||||
|
(message "Detected: %s"
|
||||||
|
(file-relative-name (directory-file-name parent)
|
||||||
|
doom-emacs-dir))))
|
||||||
|
(when interactive-p (message "Done!"))
|
||||||
|
(with-demoted-errors "WARNING: %s"
|
||||||
|
(load "autoloads"))))
|
||||||
|
|
||||||
|
(provide 'core-packages)
|
||||||
|
;;; core-packages.el ends here
|
|
@ -1,159 +0,0 @@
|
||||||
;;; core-popup.el --- taming stray windows
|
|
||||||
|
|
||||||
;; I use a slew of hackery to get Emacs to treat 'pop-ups' consistently. It goes
|
|
||||||
;; through great lengths to tame helm, flycheck, help buffers--*even* the beast
|
|
||||||
;; that is org-mode, with the help of `display-buffer-alist' and shackle.
|
|
||||||
;;
|
|
||||||
;; Be warned, an update could break this.
|
|
||||||
|
|
||||||
(use-package shackle
|
|
||||||
:config
|
|
||||||
(shackle-mode 1)
|
|
||||||
(setq shackle-rules
|
|
||||||
`(;; Util
|
|
||||||
("^\\*.+-Profiler-Report .+\\*$" :align below :size 0.3 :regexp t)
|
|
||||||
("*esup*" :align below :size 0.4 :noselect t)
|
|
||||||
("*minor-modes*" :align below :size 0.5 :noselect t)
|
|
||||||
("*eval*" :align below :size 16 :noselect t)
|
|
||||||
;; Doom
|
|
||||||
(" *doom*" :align below :size 35 :select t)
|
|
||||||
("^\\*doom:.+\\*$" :align below :size 35 :select t :regexp t)
|
|
||||||
("^\\*doom.+\\*$" :align below :size 12 :noselect t :regexp t)
|
|
||||||
;; Emacs
|
|
||||||
("*Pp Eval Output*" :align below :size 0.3)
|
|
||||||
("*Apropos*" :align below :size 0.3)
|
|
||||||
("*Backtrace*" :align below :size 25 :noselect t)
|
|
||||||
("*Help*" :align below :size 16 :select t)
|
|
||||||
("*Messages*" :align below :size 15 :select t)
|
|
||||||
("*Warnings*" :align below :size 10 :noselect t)
|
|
||||||
(compilation-mode :align below :size 15 :noselect t)
|
|
||||||
(eww-mode :align below :size 30 :select t)
|
|
||||||
("*command-log*" :align right :size 28 :noselect t)
|
|
||||||
;; vcs
|
|
||||||
("*vc-diff*" :align below :size 15 :noselect t)
|
|
||||||
("*vc-change-log*" :align below :size 15 :select t)
|
|
||||||
(vc-annotate-mode :same t)))
|
|
||||||
|
|
||||||
;; Emacs 25.1+ properly shows the completion window at the bottom of the
|
|
||||||
;; current frame.
|
|
||||||
(unless (version< emacs-version "25.1")
|
|
||||||
(push '("*Completions*" :align below :size 30 :noselect t) shackle-rules))
|
|
||||||
|
|
||||||
;; :noesc = Can't be closed with a single ESC
|
|
||||||
;; :nokill = Won't be killed when closed (only buried)
|
|
||||||
(defvar doom-popup-rules
|
|
||||||
'(("^\\*doom\\(:scratch\\)?\\*$" :noesc :nokill)
|
|
||||||
("^\\*doom.*\\*$" :noesc :nokill)
|
|
||||||
(ivy-occur-grep-mode :noesc)
|
|
||||||
(compilation-mode :noesc)
|
|
||||||
(comint-mode :noesc :nokill)
|
|
||||||
(eshell-mode :noesc :nokill)
|
|
||||||
(messages-buffer-mode :nokill)
|
|
||||||
(esup-mode :noesc)
|
|
||||||
(tabulated-list-mode :noesc)))
|
|
||||||
|
|
||||||
;; There is no shackle-popup hook, so I created one:
|
|
||||||
(advice-add 'shackle-display-buffer :around 'doom*popup-init)
|
|
||||||
;; Tell these functions not to mess with popups:
|
|
||||||
(advice-add 'balance-windows :around 'doom*save-neotree)
|
|
||||||
(advice-add 'balance-windows :around 'doom*save-popup)
|
|
||||||
(advice-add 'doom/evil-window-move :around 'doom*save-popup)
|
|
||||||
|
|
||||||
(advice-add 'evil-window-move-very-bottom :around 'doom*save-popup)
|
|
||||||
(advice-add 'evil-window-move-very-top :around 'doom*save-popup)
|
|
||||||
(advice-add 'evil-window-move-far-left :around 'doom*save-popup)
|
|
||||||
(advice-add 'evil-window-move-far-right :around 'doom*save-popup)
|
|
||||||
|
|
||||||
(advice-add 'evil-window-move-very-bottom :around 'doom*save-neotree)
|
|
||||||
(advice-add 'evil-window-move-very-top :around 'doom*save-neotree)
|
|
||||||
(advice-add 'evil-window-move-far-left :around 'doom*save-neotree)
|
|
||||||
(advice-add 'evil-window-move-far-right :around 'doom*save-neotree)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Hacks
|
|
||||||
;;
|
|
||||||
|
|
||||||
(after! help-mode
|
|
||||||
;; Help buffers use itself (or `other-window') to decide where to open
|
|
||||||
;; followed links, which can be unpredictable. It should *only* replace the
|
|
||||||
;; original buffer we opened the popup from. To fix this these three button
|
|
||||||
;; types need to be redefined to set aside the popup before following a link.
|
|
||||||
(define-button-type 'help-function-def
|
|
||||||
:supertype 'help-xref
|
|
||||||
'help-function (lambda (fun file)
|
|
||||||
(require 'find-func)
|
|
||||||
(when (eq file 'C-source)
|
|
||||||
(setq file (help-C-file-name (indirect-function fun) 'fun)))
|
|
||||||
(let ((location (find-function-search-for-symbol fun nil file)))
|
|
||||||
(doom/popup-close)
|
|
||||||
(switch-to-buffer (car location) nil t)
|
|
||||||
(if (cdr location)
|
|
||||||
(goto-char (cdr location))
|
|
||||||
(message "Unable to find location in file")))))
|
|
||||||
|
|
||||||
(define-button-type 'help-variable-def
|
|
||||||
:supertype 'help-xref
|
|
||||||
'help-function (lambda (var &optional file)
|
|
||||||
(when (eq file 'C-source)
|
|
||||||
(setq file (help-C-file-name var 'var)))
|
|
||||||
(let ((location (find-variable-noselect var file)))
|
|
||||||
(doom/popup-close)
|
|
||||||
(switch-to-buffer (car location) nil t)
|
|
||||||
(if (cdr location)
|
|
||||||
(goto-char (cdr location))
|
|
||||||
(message "Unable to find location in file")))))
|
|
||||||
|
|
||||||
(define-button-type 'help-face-def
|
|
||||||
:supertype 'help-xref
|
|
||||||
'help-function (lambda (fun file)
|
|
||||||
(require 'find-func)
|
|
||||||
(let ((location
|
|
||||||
(find-function-search-for-symbol fun 'defface file)))
|
|
||||||
(doom/popup-close)
|
|
||||||
(switch-to-buffer (car location) nil t)
|
|
||||||
(if (cdr location)
|
|
||||||
(goto-char (cdr location))
|
|
||||||
(message "Unable to find location in file"))))))
|
|
||||||
|
|
||||||
(add-hook! org-load
|
|
||||||
;; Ensures org-src-edit yields control of its buffer to shackle.
|
|
||||||
(defun org-src-switch-to-buffer (buffer context)
|
|
||||||
(pop-to-buffer buffer))
|
|
||||||
|
|
||||||
;; And these for org-todo, org-link and org-agenda
|
|
||||||
(defun org-pop-to-buffer-same-window (&optional buffer-or-name norecord label)
|
|
||||||
"Pop to buffer specified by BUFFER-OR-NAME in the selected window."
|
|
||||||
(display-buffer buffer-or-name))
|
|
||||||
|
|
||||||
(defun org-switch-to-buffer-other-window (&rest args)
|
|
||||||
(car-safe
|
|
||||||
(mapc (lambda (b)
|
|
||||||
(let ((buf (if (stringp b) (get-buffer-create b) b)))
|
|
||||||
(pop-to-buffer buf t t)))
|
|
||||||
args)))
|
|
||||||
|
|
||||||
(defun doom/org-agenda-quit ()
|
|
||||||
"Necessary to finagle org-agenda into shackle popups and behave properly on quit."
|
|
||||||
(interactive)
|
|
||||||
(if org-agenda-columns-active
|
|
||||||
(org-columns-quit)
|
|
||||||
(let ((buf (current-buffer)))
|
|
||||||
(and (not (eq org-agenda-window-setup 'current-window))
|
|
||||||
(not (one-window-p))
|
|
||||||
(delete-window))
|
|
||||||
(kill-buffer buf)
|
|
||||||
(setq org-agenda-archives-mode nil
|
|
||||||
org-agenda-buffer nil))))
|
|
||||||
|
|
||||||
(after! org-agenda
|
|
||||||
(map! :map org-agenda-mode-map
|
|
||||||
:e "<escape>" 'doom/org-agenda-quit
|
|
||||||
:e "ESC" 'doom/org-agenda-quit
|
|
||||||
:e [escape] 'doom/org-agenda-quit
|
|
||||||
"q" 'doom/org-agenda-quit
|
|
||||||
"Q" 'doom/org-agenda-quit)))
|
|
||||||
|
|
||||||
(provide 'core-popup)
|
|
||||||
;;; core-popup.el ends here
|
|
351
core/core-popups.el
Normal file
351
core/core-popups.el
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
;;; core-popups.el --- taming sudden yet inevitable windows
|
||||||
|
|
||||||
|
;; I'd like certain buffers--like prompts or informational/terminal/temporary
|
||||||
|
;; buffers--to act independently from my work buffers, to minimize the context
|
||||||
|
;; switch between them. To do this, I relegate them to disposable "popup
|
||||||
|
;; windows" that can be invoked from anywhere.
|
||||||
|
;;
|
||||||
|
;; I use a slew of hackery to get Emacs to treat these popups consistently. It
|
||||||
|
;; goes through great lengths to tame helm, flycheck, help buffers--*even* the
|
||||||
|
;; beast that is org-mode, with the help of `display-buffer-alist' and
|
||||||
|
;; `shackle'.
|
||||||
|
;;
|
||||||
|
;; Be warned, this could break.
|
||||||
|
|
||||||
|
(package! shackle :demand t
|
||||||
|
:config
|
||||||
|
(shackle-mode 1)
|
||||||
|
(setq shackle-default-alignment 'below
|
||||||
|
shackle-rules
|
||||||
|
`(;; Doom
|
||||||
|
(" *doom*" :size 35 :select t)
|
||||||
|
("^ ?\\*doom:.+\\*$" :size 35 :select t :regexp t)
|
||||||
|
("^ ?\\*doom.+\\*$" :size 12 :noselect t :regexp t)
|
||||||
|
("^\\*.+-Profiler-Report .+\\*$" :size 0.3 :regexp t)
|
||||||
|
("*esup*" :size 0.4 :noselect t)
|
||||||
|
("*minor-modes*" :size 0.5 :noselect t)
|
||||||
|
("*eval*" :size 16 :noselect t)
|
||||||
|
;; Emacs
|
||||||
|
("*Pp Eval Output*" :size 0.3)
|
||||||
|
("*Apropos*" :size 0.3)
|
||||||
|
("*Backtrace*" :size 25 :noselect t)
|
||||||
|
("*Help*" :size 16 :select t)
|
||||||
|
("*Messages*" :size 15 :select t)
|
||||||
|
("*Warnings*" :size 10 :noselect t)
|
||||||
|
(compilation-mode :size 15 :noselect t)
|
||||||
|
(eww-mode :size 30 :select t)
|
||||||
|
("*command-log*" :size 28 :noselect t :align right)
|
||||||
|
;; evil
|
||||||
|
("*evil-registers*" :size 0.3)
|
||||||
|
("*Command Line*" :size 8 :select t)
|
||||||
|
;; git-gutter
|
||||||
|
("^\\*git-gutter.+\\*$" :regexp t :size 15 :noselect t)
|
||||||
|
;; vcs
|
||||||
|
("*vc-diff*" :size 15 :noselect t)
|
||||||
|
("*vc-change-log*" :size 15 :select t)
|
||||||
|
(vc-annotate-mode :same t)
|
||||||
|
))
|
||||||
|
|
||||||
|
;; :noesc = Can't be closed with a single ESC
|
||||||
|
;; :nokill = Won't be killed when closed (only buried)
|
||||||
|
(defvar doom-popup-rules
|
||||||
|
'(("^\\*doom\\(:scratch\\)?\\*$" :noesc :nokill)
|
||||||
|
("^\\*doom.*\\*$" :noesc :nokill)
|
||||||
|
(ivy-occur-grep-mode :noesc)
|
||||||
|
(compilation-mode :noesc)
|
||||||
|
(comint-mode :noesc :nokill)
|
||||||
|
(eshell-mode :noesc :nokill)
|
||||||
|
(messages-buffer-mode :nokill)
|
||||||
|
(esup-mode :noesc)
|
||||||
|
(tabulated-list-mode :noesc)))
|
||||||
|
|
||||||
|
(defvar-local doom-popup-rule nil
|
||||||
|
"A list of rules applied to this popup.")
|
||||||
|
(put 'doom-popup-rule 'permanent-local t)
|
||||||
|
|
||||||
|
(defvar doom-popup-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map [remap doom/kill-real-buffer] 'doom/popup-close)
|
||||||
|
(define-key map [remap evil-window-delete] 'doom/popup-close)
|
||||||
|
(define-key map [remap evil-window-move-very-bottom] 'ignore)
|
||||||
|
(define-key map [remap evil-window-move-very-top] 'ignore)
|
||||||
|
(define-key map [remap evil-window-move-far-left] 'ignore)
|
||||||
|
(define-key map [remap evil-window-move-far-right] 'ignore)
|
||||||
|
(define-key map [remap evil-window-split] 'ignore)
|
||||||
|
(define-key map [remap evil-window-vsplit] 'ignore)
|
||||||
|
(define-key map [remap evil-force-normal-state] 'doom/popup-close-maybe)
|
||||||
|
(define-key map [escape] 'doom/popup-close-maybe)
|
||||||
|
(define-key map (kbd "ESC") 'doom/popup-close-maybe)
|
||||||
|
map)
|
||||||
|
"Active keymap in popup windows.")
|
||||||
|
|
||||||
|
(define-minor-mode doom-popup-mode
|
||||||
|
"Minor mode for pop-up windows. Enables local keymaps and sets state
|
||||||
|
variables."
|
||||||
|
:global nil
|
||||||
|
:init-value nil
|
||||||
|
:keymap doom-popup-mode-map
|
||||||
|
(let ((rules (--any (let ((key (car it)))
|
||||||
|
(when (cond ((symbolp key)
|
||||||
|
(or (eq major-mode key)
|
||||||
|
(derived-mode-p key)))
|
||||||
|
((stringp key)
|
||||||
|
(string-match-p key (buffer-name))))
|
||||||
|
(cdr it)))
|
||||||
|
doom-popup-rules)))
|
||||||
|
(set-window-dedicated-p nil doom-popup-mode)
|
||||||
|
(setq doom-last-popup (current-buffer))
|
||||||
|
(setq-local doom-popup-rule rules)))
|
||||||
|
(put 'doom-popup-mode 'permanent-local t)
|
||||||
|
|
||||||
|
(defun doom*popup-init (orig-fn &rest args)
|
||||||
|
"Enables `doom-popup-mode' in every popup window and returns the window."
|
||||||
|
(let ((window (apply orig-fn args)))
|
||||||
|
(with-selected-window window
|
||||||
|
(doom-popup-mode +1))
|
||||||
|
;; NOTE orig-fn returns a window, so `doom*popup-init' must too
|
||||||
|
window))
|
||||||
|
|
||||||
|
(defun doom*popup-save (orig-fun &rest args)
|
||||||
|
"Prevents messing up a popup buffer on window changes."
|
||||||
|
(let ((in-popup-p (doom-popup-p))
|
||||||
|
(popups-p (and doom-last-popup
|
||||||
|
(window-live-p (get-buffer-window doom-last-popup)))))
|
||||||
|
(when popups-p
|
||||||
|
(mapc (lambda (w) (doom/popup-close w t))
|
||||||
|
(-filter 'doom-popup-p (window-list))))
|
||||||
|
(unwind-protect (apply orig-fun args)
|
||||||
|
(when popups-p
|
||||||
|
(let ((origin-win (selected-window)))
|
||||||
|
(doom/popup-last-buffer)
|
||||||
|
(when in-popup-p
|
||||||
|
(select-window origin-win)))))))
|
||||||
|
|
||||||
|
;; There is no shackle-popup hook, so I created one:
|
||||||
|
(advice-add 'shackle-display-buffer :around 'doom*popup-init)
|
||||||
|
;; Order matters for these two
|
||||||
|
(advice-add 'balance-windows :around 'doom*popup-save))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Hacks
|
||||||
|
;;
|
||||||
|
|
||||||
|
(after! evil
|
||||||
|
;; Tell these functions not to mess with popups:
|
||||||
|
(advice-add 'doom-evil-window-move :around 'doom*popup-save)
|
||||||
|
(advice-add 'evil-window-move-very-bottom :around 'doom*popup-save)
|
||||||
|
(advice-add 'evil-window-move-very-top :around 'doom*popup-save)
|
||||||
|
(advice-add 'evil-window-move-far-left :around 'doom*popup-save)
|
||||||
|
(advice-add 'evil-window-move-far-right :around 'doom*popup-save)
|
||||||
|
|
||||||
|
(defun doom*evil-command-window (hist cmd-key execute-fn)
|
||||||
|
"The evil command window has a mind of its own (uses `switch-to-buffer'). We
|
||||||
|
monkey patch it to use pop-to-buffer."
|
||||||
|
(when (eq major-mode 'evil-command-window-mode)
|
||||||
|
(user-error "Cannot recursively open command line window"))
|
||||||
|
(dolist (win (window-list))
|
||||||
|
(when (equal (buffer-name (window-buffer win))
|
||||||
|
"*Command Line*")
|
||||||
|
(kill-buffer (window-buffer win))
|
||||||
|
(delete-window win)))
|
||||||
|
(setq evil-command-window-current-buffer (current-buffer))
|
||||||
|
(ignore-errors (kill-buffer "*Command Line*"))
|
||||||
|
(with-current-buffer (pop-to-buffer "*Command Line*")
|
||||||
|
(setq-local evil-command-window-execute-fn execute-fn)
|
||||||
|
(setq-local evil-command-window-cmd-key cmd-key)
|
||||||
|
(evil-command-window-mode)
|
||||||
|
(evil-command-window-insert-commands hist)))
|
||||||
|
|
||||||
|
(advice-add 'evil-command-window :override 'doom*evil-command-window))
|
||||||
|
|
||||||
|
(after! help-mode
|
||||||
|
;; Help buffers use itself (or `other-window') to decide where to open
|
||||||
|
;; followed links, which can be unpredictable. It should *only* replace the
|
||||||
|
;; original buffer we opened the popup from. To fix this these three button
|
||||||
|
;; types need to be redefined to set aside the popup before following a link.
|
||||||
|
(define-button-type 'help-function-def
|
||||||
|
:supertype 'help-xref
|
||||||
|
'help-function (lambda (fun file)
|
||||||
|
(require 'find-func)
|
||||||
|
(when (eq file 'C-source)
|
||||||
|
(setq file (help-C-file-name (indirect-function fun) 'fun)))
|
||||||
|
(let ((location (find-function-search-for-symbol fun nil file)))
|
||||||
|
(doom/popup-close)
|
||||||
|
(switch-to-buffer (car location) nil t)
|
||||||
|
(if (cdr location)
|
||||||
|
(progn
|
||||||
|
(goto-char (cdr location))
|
||||||
|
(recenter nil))
|
||||||
|
(message "Unable to find location in file")))))
|
||||||
|
|
||||||
|
(define-button-type 'help-variable-def
|
||||||
|
:supertype 'help-xref
|
||||||
|
'help-function (lambda (var &optional file)
|
||||||
|
(when (eq file 'C-source)
|
||||||
|
(setq file (help-C-file-name var 'var)))
|
||||||
|
(let ((location (find-variable-noselect var file)))
|
||||||
|
(doom/popup-close)
|
||||||
|
(switch-to-buffer (car location) nil t)
|
||||||
|
(if (cdr location)
|
||||||
|
(progn
|
||||||
|
(goto-char (cdr location))
|
||||||
|
(recenter nil))
|
||||||
|
(message "Unable to find location in file")))))
|
||||||
|
|
||||||
|
(define-button-type 'help-face-def
|
||||||
|
:supertype 'help-xref
|
||||||
|
'help-function (lambda (fun file)
|
||||||
|
(require 'find-func)
|
||||||
|
(let ((location
|
||||||
|
(find-function-search-for-symbol fun 'defface file)))
|
||||||
|
(doom/popup-close)
|
||||||
|
(switch-to-buffer (car location) nil t)
|
||||||
|
(if (cdr location)
|
||||||
|
(progn
|
||||||
|
(goto-char (cdr location))
|
||||||
|
(recenter nil))
|
||||||
|
(message "Unable to find location in file"))))))
|
||||||
|
|
||||||
|
(after! magit
|
||||||
|
;; Don't open files (from magit) in the magit popup
|
||||||
|
(advice-add 'magit-display-file-buffer-traditional :around 'doom*popup-save))
|
||||||
|
|
||||||
|
(after! neotree
|
||||||
|
(defun doom*save-neotree (orig-fun &rest args)
|
||||||
|
"Prevents messing up the neotree buffer on window changes."
|
||||||
|
(let ((neo-p (and (featurep 'neotree) (neo-global--window-exists-p))))
|
||||||
|
(when neo-p
|
||||||
|
(neotree-hide)
|
||||||
|
(balance-windows))
|
||||||
|
(unwind-protect (apply orig-fun args)
|
||||||
|
(when neo-p
|
||||||
|
(save-selected-window
|
||||||
|
(neotree-show))))))
|
||||||
|
|
||||||
|
;; Prevent neotree from interfering with popups
|
||||||
|
(advice-add 'shackle-display-buffer :around 'doom*save-neotree)
|
||||||
|
;; Prevents messing up the neotree buffer on window changes
|
||||||
|
(advice-add 'doom-evil-window-move :around 'doom*save-neotree)
|
||||||
|
;; (advice-add 'doom-popup-buffer :around 'doom*save-neotree)
|
||||||
|
;; Don't let neotree interfere with moving, splitting or rebalancing windows
|
||||||
|
(advice-add 'balance-windows :around 'doom*save-neotree)
|
||||||
|
(advice-add 'split-window :around 'doom*save-neotree)
|
||||||
|
(advice-add 'shackle-display-buffer :around 'doom*save-neotree)
|
||||||
|
(advice-add 'evil-window-move-very-bottom :around 'doom*save-neotree)
|
||||||
|
(advice-add 'evil-window-move-very-top :around 'doom*save-neotree)
|
||||||
|
(advice-add 'evil-window-move-far-left :around 'doom*save-neotree)
|
||||||
|
(advice-add 'evil-window-move-far-right :around 'doom*save-neotree))
|
||||||
|
|
||||||
|
(add-hook! org-load
|
||||||
|
;; Ensures org-src-edit yields control of its buffer to shackle.
|
||||||
|
(defun org-src-switch-to-buffer (buffer context)
|
||||||
|
(pop-to-buffer buffer))
|
||||||
|
|
||||||
|
;; And these for org-todo, org-link and org-agenda
|
||||||
|
(defun org-pop-to-buffer-same-window (&optional buffer-or-name norecord label)
|
||||||
|
"Pop to buffer specified by BUFFER-OR-NAME in the selected window."
|
||||||
|
(display-buffer buffer-or-name))
|
||||||
|
|
||||||
|
(defun org-switch-to-buffer-other-window (&rest args)
|
||||||
|
(car-safe
|
||||||
|
(mapc (lambda (b)
|
||||||
|
(let ((buf (if (stringp b) (get-buffer-create b) b)))
|
||||||
|
(pop-to-buffer buf t t)))
|
||||||
|
args)))
|
||||||
|
|
||||||
|
(defun doom/org-agenda-quit ()
|
||||||
|
"Necessary to finagle org-agenda into shackle popups and behave properly on quit."
|
||||||
|
(interactive)
|
||||||
|
(if org-agenda-columns-active
|
||||||
|
(org-columns-quit)
|
||||||
|
(let ((buf (current-buffer)))
|
||||||
|
(and (not (eq org-agenda-window-setup 'current-window))
|
||||||
|
(not (one-window-p))
|
||||||
|
(delete-window))
|
||||||
|
(kill-buffer buf)
|
||||||
|
(setq org-agenda-archives-mode nil
|
||||||
|
org-agenda-buffer nil))))
|
||||||
|
|
||||||
|
(after! org-agenda
|
||||||
|
(map! :map org-agenda-mode-map
|
||||||
|
:e "<escape>" 'doom/org-agenda-quit
|
||||||
|
:e "ESC" 'doom/org-agenda-quit
|
||||||
|
:e [escape] 'doom/org-agenda-quit
|
||||||
|
"q" 'doom/org-agenda-quit
|
||||||
|
"Q" 'doom/org-agenda-quit)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Functions
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defun doom-popup-p (&optional window)
|
||||||
|
"Whether WINDOW is a popup window or not. If WINDOW is nil, use current
|
||||||
|
window. Returns nil or the popup window."
|
||||||
|
(setq window (or window (selected-window)))
|
||||||
|
(and (window-live-p window)
|
||||||
|
(buffer-local-value 'doom-popup-mode (window-buffer window))
|
||||||
|
window))
|
||||||
|
|
||||||
|
(defun doom-popup-buffer (buffer &optional plist)
|
||||||
|
"Display BUFFER in a shackle popup."
|
||||||
|
(let* ((buffer-name (cond ((stringp buffer) buffer)
|
||||||
|
((bufferp buffer) (buffer-name buffer))
|
||||||
|
(t (error "Not a valid buffer"))))
|
||||||
|
(buffer (get-buffer-create buffer-name)))
|
||||||
|
(when (doom/real-buffer-p (window-buffer))
|
||||||
|
(setq doom-last-window (selected-window)))
|
||||||
|
(shackle-display-buffer
|
||||||
|
buffer
|
||||||
|
nil (or plist (shackle-match buffer-name)))))
|
||||||
|
|
||||||
|
(defun doom/popup-messages ()
|
||||||
|
"Pop up the messages buffer."
|
||||||
|
(interactive)
|
||||||
|
(doom-popup-buffer (messages-buffer))
|
||||||
|
(goto-char (point-max)))
|
||||||
|
|
||||||
|
(defun doom/popup-last-buffer ()
|
||||||
|
"Restore the last popup."
|
||||||
|
(interactive)
|
||||||
|
(unless (buffer-live-p doom-last-popup)
|
||||||
|
(setq doom-last-popup nil)
|
||||||
|
(error "No popup to restore"))
|
||||||
|
(doom-popup-buffer doom-last-popup))
|
||||||
|
|
||||||
|
(defun doom/popup-close (&optional window dont-kill)
|
||||||
|
"Find and close the currently active popup (if available)."
|
||||||
|
(interactive)
|
||||||
|
(setq window (or window (selected-window)))
|
||||||
|
(when (doom-popup-p window)
|
||||||
|
(with-selected-window window
|
||||||
|
;; If REPL...
|
||||||
|
(when (bound-and-true-p repl-toggle-mode)
|
||||||
|
(setq rtog/--last-buffer nil))
|
||||||
|
(doom-popup-mode -1)
|
||||||
|
(unless (or dont-kill (memq :nokill doom-popup-rule))
|
||||||
|
(let ((kill-buffer-query-functions
|
||||||
|
(delq 'process-kill-buffer-query-function
|
||||||
|
kill-buffer-query-functions)))
|
||||||
|
(kill-buffer (window-buffer window)))))
|
||||||
|
(delete-window window)))
|
||||||
|
|
||||||
|
(defun doom/popup-close-maybe ()
|
||||||
|
"Close the current popup *if* its buffer doesn't have a :noesc rule in
|
||||||
|
`doom-popup-rules'."
|
||||||
|
(interactive)
|
||||||
|
(if (memq :noesc doom-popup-rule)
|
||||||
|
(call-interactively 'evil-force-normal-state)
|
||||||
|
(doom/popup-close)))
|
||||||
|
|
||||||
|
(defun doom/popup-close-all (&optional dont-kill)
|
||||||
|
"Closes all popups (kill them if DONT-KILL-BUFFERS is non-nil)."
|
||||||
|
(interactive)
|
||||||
|
(let ((orig-win (selected-window)))
|
||||||
|
(mapc (lambda (w) (doom/popup-close w dont-kill))
|
||||||
|
(--filter (and (doom-popup-p it) (not (eq it orig-win)))
|
||||||
|
(window-list)))))
|
||||||
|
|
||||||
|
(provide 'core-popups)
|
||||||
|
;;; core-popups.el ends here
|
|
@ -1,41 +1,52 @@
|
||||||
;;; core-project.el --- all your (basic) project navigational needs
|
;;; core-project.el --- tools for getting around your project
|
||||||
|
|
||||||
(setq ;; Always copy/delete recursively
|
;; I want Emacs project-aware. i.e. To know what project I'm in, and to be able
|
||||||
dired-recursive-copies 'always
|
;; to tell me about it. `projectile' helps me with this. It also provides nifty
|
||||||
dired-recursive-deletes 'top
|
;; tools for digging out files I want from a project of any size.
|
||||||
;; Auto refresh dired, but be quiet about it
|
;;
|
||||||
global-auto-revert-non-file-buffers t
|
;; `neotree', on the other hand, allows me to browse my project files. I
|
||||||
auto-revert-verbose nil)
|
;; occasionally like having a birds-eye view of my files.
|
||||||
|
|
||||||
;; List directories first
|
(package! projectile :demand t
|
||||||
(defun doom|dired-sort ()
|
:init
|
||||||
"Dired sort hook to list directories first."
|
(setq projectile-cache-file (concat doom-temp-dir "/projectile.cache")
|
||||||
(save-excursion
|
projectile-completion-system 'ivy
|
||||||
(let (buffer-read-only)
|
projectile-enable-caching t
|
||||||
(forward-line 2) ;; beyond dir. header
|
projectile-file-exists-remote-cache-expire nil
|
||||||
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max))))
|
projectile-globally-ignored-directories `(,doom-temp-dir ".sync")
|
||||||
(and (featurep 'xemacs)
|
projectile-globally-ignored-file-suffixes '(".elc" ".pyc" ".o")
|
||||||
(fboundp 'dired-insert-set-properties)
|
projectile-globally-ignored-files '(".DS_Store" "Icon
")
|
||||||
(dired-insert-set-properties (point-min) (point-max)))
|
projectile-indexing-method 'alien
|
||||||
(set-buffer-modified-p nil))
|
projectile-known-projects-file (concat doom-temp-dir "/projectile.projects")
|
||||||
(add-hook 'dired-after-readin-hook 'doom|dired-sort)
|
projectile-project-root-files '(".git" ".hg" ".svn" ".project")
|
||||||
|
projectile-require-project-root nil)
|
||||||
|
|
||||||
(use-package dired-k
|
|
||||||
:after dired
|
|
||||||
:config
|
:config
|
||||||
(setq dired-k-style 'git)
|
(mapc (lambda (r) (push r projectile-other-file-alist))
|
||||||
(add-hook 'dired-initial-position-hook 'dired-k)
|
'(("less" "css")
|
||||||
(add-hook 'dired-after-readin-hook #'dired-k-no-revert))
|
("styl" "css")
|
||||||
|
("sass" "css")
|
||||||
|
("scss" "css")
|
||||||
|
("css" "scss" "sass" "less" "styl")
|
||||||
|
("jade" "html")
|
||||||
|
("pug" "html")
|
||||||
|
("html" "jade" "pug" "jsx" "tsx")))
|
||||||
|
|
||||||
;; Automatically create missing directories when creating new files
|
(defun doom*projectile-cache-current-file (orig-fun &rest args)
|
||||||
(defun doom|create-non-existent-directory ()
|
"Don't cache ignored files."
|
||||||
(let ((parent-directory (file-name-directory buffer-file-name)))
|
(unless (--any (f-descendant-of? buffer-file-name it)
|
||||||
(when (and (not (file-exists-p parent-directory))
|
(projectile-ignored-directories))
|
||||||
(y-or-n-p (format "Directory `%s' does not exist! Create it?" parent-directory)))
|
(apply orig-fun args)))
|
||||||
(make-directory parent-directory t))))
|
(advice-add 'projectile-cache-current-file :around 'doom*projectile-cache-current-file)
|
||||||
(push 'doom|create-non-existent-directory find-file-not-found-functions)
|
|
||||||
|
|
||||||
(use-package neotree
|
(projectile-global-mode +1))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Autoloaded Packages
|
||||||
|
;;
|
||||||
|
|
||||||
|
(package! neotree
|
||||||
:commands (neotree-show
|
:commands (neotree-show
|
||||||
neotree-hide
|
neotree-hide
|
||||||
neotree-toggle
|
neotree-toggle
|
||||||
|
@ -51,23 +62,30 @@
|
||||||
neo-window-width 25
|
neo-window-width 25
|
||||||
neo-show-updir-line nil
|
neo-show-updir-line nil
|
||||||
neo-theme 'nerd ; fallback
|
neo-theme 'nerd ; fallback
|
||||||
neo-banner-message nil)
|
neo-banner-message nil
|
||||||
|
neo-show-hidden-files nil
|
||||||
|
neo-hidden-regexp-list
|
||||||
|
'(;; vcs folders
|
||||||
|
"^\\.\\(git\\|hg\\|svn\\)$"
|
||||||
|
;; compiled files
|
||||||
|
"\\.\\(pyc\\|o\\|elc\\|lock\\|css.map\\)$"
|
||||||
|
;; generated files, caches or local pkgs
|
||||||
|
"^\\(node_modules\\|vendor\\|.\\(project\\|cask\\|yardoc\\|sass-cache\\)\\)$"
|
||||||
|
;; org-mode folders
|
||||||
|
"^\\.\\(sync\\|export\\|attach\\)$"
|
||||||
|
"~$"
|
||||||
|
"^#.*#$"))
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(evil-set-initial-state 'neotree-mode 'motion)
|
(evil-set-initial-state 'neotree-mode 'motion)
|
||||||
(add-hook 'neo-after-create-hook 'doom-hide-mode-line-mode)
|
|
||||||
|
|
||||||
;; Don't ask for confirmation when creating files
|
|
||||||
(advice-add 'neotree-create-node :around 'doom*neotree-create-node)
|
|
||||||
;; Prevents messing up the neotree buffer on window changes
|
|
||||||
(advice-add 'doom/evil-window-move :around 'doom*save-neotree)
|
|
||||||
(advice-add 'doom/popup-buffer :around 'doom*save-neotree)
|
|
||||||
;; Adding keybindings to `neotree-mode-map' wouldn't work for me (they get
|
;; Adding keybindings to `neotree-mode-map' wouldn't work for me (they get
|
||||||
;; overridden when the neotree buffer is spawned). So we bind them in a hook.
|
;; overridden when the neotree buffer is spawned). So we bind them in a hook.
|
||||||
(add-hook 'neo-after-create-hook 'doom|neotree-init-keymap)
|
(add-hook 'neo-after-create-hook 'doom|neotree-init-keymap)
|
||||||
(defun doom|neotree-init-keymap (&rest _)
|
(defun doom|neotree-init-keymap (&rest _)
|
||||||
(map! :Lm "\\\\" 'evil-window-prev
|
(map! :Lm "\\\\" 'evil-window-prev
|
||||||
:Lm "ESC ESC" 'doom/neotree-close
|
:Lm "ESC ESC" 'neotree-hide
|
||||||
:Lm "q" 'doom/neotree-close
|
:Lm "q" 'neotree-hide
|
||||||
:Lm [return] 'neotree-enter
|
:Lm [return] 'neotree-enter
|
||||||
:Lm "RET" 'neotree-enter
|
:Lm "RET" 'neotree-enter
|
||||||
:Lm "<return>" 'neotree-enter
|
:Lm "<return>" 'neotree-enter
|
||||||
|
@ -83,32 +101,5 @@
|
||||||
:Lm "r" 'neotree-rename-node
|
:Lm "r" 'neotree-rename-node
|
||||||
:Lm "R" 'neotree-change-root)))
|
:Lm "R" 'neotree-change-root)))
|
||||||
|
|
||||||
(use-package projectile
|
|
||||||
:config
|
|
||||||
(setq projectile-require-project-root nil
|
|
||||||
projectile-enable-caching t
|
|
||||||
projectile-cache-file (concat doom-temp-dir "/projectile.cache")
|
|
||||||
projectile-known-projects-file (concat doom-temp-dir "/projectile.projects")
|
|
||||||
projectile-indexing-method 'alien
|
|
||||||
projectile-file-exists-remote-cache-expire nil
|
|
||||||
projectile-project-root-files '(".git" ".hg" ".svn" ".project"))
|
|
||||||
|
|
||||||
;; Don't cache ignored files!
|
|
||||||
(defun doom*projectile-cache-current-file (orig-fun &rest args)
|
|
||||||
(unless (--any (f-descendant-of? buffer-file-name it)
|
|
||||||
(projectile-ignored-directories))
|
|
||||||
(apply orig-fun args)))
|
|
||||||
(advice-add 'projectile-cache-current-file :around 'doom*projectile-cache-current-file)
|
|
||||||
|
|
||||||
(push doom-temp-dir projectile-globally-ignored-directories)
|
|
||||||
(push "assets" projectile-globally-ignored-directories)
|
|
||||||
(push ".cask" projectile-globally-ignored-directories)
|
|
||||||
(push ".sync" projectile-globally-ignored-directories)
|
|
||||||
(push ".elc" projectile-globally-ignored-file-suffixes)
|
|
||||||
(push ".project" projectile-globally-ignored-file-suffixes)
|
|
||||||
(push "Icon
" projectile-globally-ignored-files)
|
|
||||||
|
|
||||||
(projectile-global-mode +1))
|
|
||||||
|
|
||||||
(provide 'core-project)
|
(provide 'core-project)
|
||||||
;;; core-project.el ends here
|
;;; core-project.el ends here
|
||||||
|
|
6
core/core-repl.el
Normal file
6
core/core-repl.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;;; core-repl.el
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
|
||||||
|
(provide 'core-repl)
|
||||||
|
;;; core-repl.el ends here
|
|
@ -1,196 +0,0 @@
|
||||||
;;; core-scratch.el
|
|
||||||
|
|
||||||
(setq initial-major-mode 'doom-mode
|
|
||||||
initial-scratch-message "\n Loading..."
|
|
||||||
inhibit-startup-screen t
|
|
||||||
;; shuts up emacs at startup
|
|
||||||
inhibit-startup-echo-area-message user-login-name)
|
|
||||||
|
|
||||||
(defvar doom-buffer nil
|
|
||||||
"The global and persistent scratch buffer for doom.")
|
|
||||||
|
|
||||||
(defvar doom-scratch-name " *doom*"
|
|
||||||
"The name of the doom scratch buffer.")
|
|
||||||
|
|
||||||
(defvar doom-scratch-edited nil
|
|
||||||
"If non-nil, the scratch buffer has been edited.")
|
|
||||||
|
|
||||||
(defvar doom-scratch-inhibit-refresh nil
|
|
||||||
"If non-nil, the doom buffer won't be refreshed.")
|
|
||||||
|
|
||||||
(defvar doom-scratch-modeline (doom-modeline 'scratch)
|
|
||||||
"Modeline format for doom scratch buffer.")
|
|
||||||
|
|
||||||
(defvar doom-scratch-widgets '(banner shortmenu loaded)
|
|
||||||
"List of widgets to display in a blank scratch buffer.")
|
|
||||||
|
|
||||||
(define-derived-mode doom-mode fundamental-mode
|
|
||||||
(concat "v" doom-version)
|
|
||||||
"Major mode for the DOOM scratch buffer.")
|
|
||||||
|
|
||||||
(defvar doom-scratch--width 0)
|
|
||||||
(defvar doom-scratch--height 0)
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
(add-hook 'emacs-startup-hook 'doom-scratch)
|
|
||||||
(add-hook! 'kill-buffer-query-functions (not (doom-scratch-buffer-p)))
|
|
||||||
(add-hook! window-setup
|
|
||||||
(add-hook 'window-configuration-change-hook 'doom-scratch-reload)
|
|
||||||
(doom-scratch-reload))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
(defun doom-scratch-buffer-p (&optional buffer)
|
|
||||||
(let ((buffer (or buffer (current-buffer))))
|
|
||||||
(and (buffer-live-p buffer)
|
|
||||||
(eq buffer doom-buffer))))
|
|
||||||
|
|
||||||
(defun doom-scratch-buffer ()
|
|
||||||
"Ensure the scratch buffer exists and is alive (otherwise create it)."
|
|
||||||
;; Rename the old scratch buffer, if it exists.
|
|
||||||
(let ((old-scratch (get-buffer "*scratch*")))
|
|
||||||
(when old-scratch (kill-buffer old-scratch)))
|
|
||||||
;; Ensure the doom buffer is alive!
|
|
||||||
(unless (buffer-live-p doom-buffer)
|
|
||||||
(setq doom-buffer nil))
|
|
||||||
(unless doom-buffer
|
|
||||||
(setq doom-buffer (get-buffer-create doom-scratch-name)))
|
|
||||||
doom-buffer)
|
|
||||||
|
|
||||||
(defun doom-scratch ()
|
|
||||||
(interactive)
|
|
||||||
(doom-scratch-reload)
|
|
||||||
(switch-to-buffer doom-buffer)
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(defun doom-scratch-force-reload ()
|
|
||||||
(setq doom-scratch-edited nil)
|
|
||||||
(doom-scratch-reload))
|
|
||||||
|
|
||||||
(defun doom|scratch-clear-on-insert ()
|
|
||||||
"Erase the buffer and prepare it to be used like a normal buffer."
|
|
||||||
(erase-buffer)
|
|
||||||
;; (set-window-margins (get-buffer-window doom-buffer) 0 0)
|
|
||||||
(setq doom-scratch-edited t
|
|
||||||
mode-line-format (doom-modeline))
|
|
||||||
(remove-hook 'evil-insert-state-entry-hook 'doom|mode-erase-on-insert t))
|
|
||||||
|
|
||||||
(defun doom-scratch-reload (&optional dir)
|
|
||||||
"Update the DOOM scratch buffer (or create it, if it doesn't exist)."
|
|
||||||
(when (and (not doom-scratch-inhibit-refresh)
|
|
||||||
(not (minibuffer-window-active-p (minibuffer-window)))
|
|
||||||
(get-buffer-window-list doom-buffer nil t)
|
|
||||||
(or (not doom-scratch-edited) dir))
|
|
||||||
(let ((old-pwd (or dir default-directory)))
|
|
||||||
(with-current-buffer (doom-scratch-buffer)
|
|
||||||
(doom-mode)
|
|
||||||
(add-hook 'evil-insert-state-entry-hook 'doom|scratch-clear-on-insert nil t)
|
|
||||||
(add-hook 'after-change-major-mode-hook 'doom|scratch-clear-on-insert nil t)
|
|
||||||
(setq doom-scratch-edited nil)
|
|
||||||
|
|
||||||
(erase-buffer)
|
|
||||||
(let ((doom-scratch--width (1- (window-width (get-buffer-window doom-buffer))))
|
|
||||||
(doom-scratch--height (window-height (get-buffer-window doom-buffer))))
|
|
||||||
(insert (make-string (max 0 (- (truncate (/ doom-scratch--height 2)) 12)) ?\n))
|
|
||||||
(mapc (lambda (widget-name)
|
|
||||||
(funcall (intern (format "doom-scratch-widget-%s" widget-name)))
|
|
||||||
(insert "\n\n"))
|
|
||||||
doom-scratch-widgets))
|
|
||||||
|
|
||||||
(setq default-directory old-pwd)
|
|
||||||
(setq mode-line-format (doom-modeline 'scratch)))))
|
|
||||||
t)
|
|
||||||
|
|
||||||
(defun doom-scratch-widget-banner ()
|
|
||||||
(mapc (lambda (line)
|
|
||||||
(insert "\n")
|
|
||||||
(insert (propertize (s-center doom-scratch--width line)
|
|
||||||
'face 'font-lock-comment-face) " "))
|
|
||||||
'("================= =============== =============== ======== ========"
|
|
||||||
"\\\\ . . . . . . .\\\\ //. . . . . . .\\\\ //. . . . . . .\\\\ \\\\. . .\\\\// . . //"
|
|
||||||
"||. . ._____. . .|| ||. . ._____. . .|| ||. . ._____. . .|| || . . .\\/ . . .||"
|
|
||||||
"|| . .|| ||. . || || . .|| ||. . || || . .|| ||. . || ||. . . . . . . ||"
|
|
||||||
"||. . || || . .|| ||. . || || . .|| ||. . || || . .|| || . | . . . . .||"
|
|
||||||
"|| . .|| ||. _-|| ||-_ .|| ||. . || || . .|| ||. _-|| ||-_.|\\ . . . . ||"
|
|
||||||
"||. . || ||-' || || `-|| || . .|| ||. . || ||-' || || `|\\_ . .|. .||"
|
|
||||||
"|| . _|| || || || || ||_ . || || . _|| || || || |\\ `-_/| . ||"
|
|
||||||
"||_-' || .|/ || || \\|. || `-_|| ||_-' || .|/ || || | \\ / |-_.||"
|
|
||||||
"|| ||_-' || || `-_|| || || ||_-' || || | \\ / | `||"
|
|
||||||
"|| `' || || `' || || `' || || | \\ / | ||"
|
|
||||||
"|| .===' `===. .==='.`===. .===' /==. | \\/ | ||"
|
|
||||||
"|| .==' \\_|-_ `===. .===' _|_ `===. .===' _-|/ `== \\/ | ||"
|
|
||||||
"|| .==' _-' `-_ `=' _-' `-_ `=' _-' `-_ /| \\/ | ||"
|
|
||||||
"|| .==' _-' '-__\\._-' '-_./__-' `' |. /| | ||"
|
|
||||||
"||.==' _-' `' | /==.||"
|
|
||||||
"==' _-' E M A C S \\/ `=="
|
|
||||||
"\\ _-' `-_ /"
|
|
||||||
" `'' ``'")))
|
|
||||||
|
|
||||||
(defun doom-scratch-widget-loaded ()
|
|
||||||
(insert
|
|
||||||
(s-center (1- doom-scratch--width)
|
|
||||||
(propertize
|
|
||||||
(format "Loaded %d packages in %s"
|
|
||||||
(length doom-packages)
|
|
||||||
(emacs-init-time))
|
|
||||||
'face '(:inherit font-lock-comment-face
|
|
||||||
:height 0.9)))))
|
|
||||||
|
|
||||||
(defun doom-scratch-widget-shortmenu ()
|
|
||||||
(let ((all-the-icons-scale-factor 1.3)
|
|
||||||
(all-the-icons-default-adjust -0.05)
|
|
||||||
(start (point))
|
|
||||||
(sep " ")
|
|
||||||
(last-session-p (and (featurep 'workgroups2)
|
|
||||||
(f-exists-p wg-session-file)))
|
|
||||||
end)
|
|
||||||
(unless last-session-p
|
|
||||||
(setq sep " "))
|
|
||||||
(insert
|
|
||||||
(s-center (- doom-scratch--width 5)
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-text-button
|
|
||||||
(concat (all-the-icons-octicon
|
|
||||||
"mark-github"
|
|
||||||
:face 'font-lock-keyword-face)
|
|
||||||
(propertize " Homepage" 'face 'font-lock-keyword-face))
|
|
||||||
'action '(lambda (_) (browse-url "https://github.com/hlissner/.emacs.d"))
|
|
||||||
'follow-link t)
|
|
||||||
|
|
||||||
(insert sep " ")
|
|
||||||
|
|
||||||
(insert-text-button
|
|
||||||
(concat (all-the-icons-octicon
|
|
||||||
"file-text"
|
|
||||||
:face 'font-lock-keyword-face)
|
|
||||||
(propertize " Recent files" 'face 'font-lock-keyword-face))
|
|
||||||
'action '(lambda (_) (call-interactively 'counsel-recentf))
|
|
||||||
'follow-link t)
|
|
||||||
|
|
||||||
(insert sep)
|
|
||||||
|
|
||||||
(insert-text-button
|
|
||||||
(concat (all-the-icons-octicon
|
|
||||||
"tools"
|
|
||||||
:face 'font-lock-keyword-face)
|
|
||||||
(propertize " Edit emacs.d" 'face 'font-lock-keyword-face))
|
|
||||||
'action '(lambda (_) (find-file (f-expand "init.el" doom-emacs-dir)))
|
|
||||||
'follow-link t)
|
|
||||||
|
|
||||||
(when last-session-p
|
|
||||||
(insert sep)
|
|
||||||
|
|
||||||
(insert-text-button
|
|
||||||
(concat (all-the-icons-octicon
|
|
||||||
"history"
|
|
||||||
:face 'font-lock-keyword-face)
|
|
||||||
(propertize " Reload last session" 'face 'font-lock-keyword-face))
|
|
||||||
'action '(lambda (_) (doom:workgroup-load))
|
|
||||||
'follow-link t))
|
|
||||||
|
|
||||||
(setq end (point))
|
|
||||||
(buffer-string))))))
|
|
||||||
|
|
||||||
(provide 'core-scratch)
|
|
||||||
;;; core-scratch.el ends here
|
|
6
core/core-sessions.el
Normal file
6
core/core-sessions.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;;; core-sessions.el
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
|
||||||
|
(provide 'core-sessions)
|
||||||
|
;;; core-sessions.el ends here
|
22
core/core-settings.el
Normal file
22
core/core-settings.el
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
;;; core-settings.el --- centralized inter-package configuration
|
||||||
|
|
||||||
|
(defvar doom-settings '()
|
||||||
|
"docstring")
|
||||||
|
|
||||||
|
(defun doom-define-setting (name &optional docs &rest args))
|
||||||
|
|
||||||
|
(defmacro config! (package-name &rest args)
|
||||||
|
(declare (indent defun))
|
||||||
|
`(let ((doom-current-package ',package-name))
|
||||||
|
,(macroexpand-progn args))
|
||||||
|
;; 1. Check for `set!' calls
|
||||||
|
;; 2. Append mode
|
||||||
|
)
|
||||||
|
|
||||||
|
(defmacro set! (&rest args))
|
||||||
|
|
||||||
|
(defun doom-set (mode key value)
|
||||||
|
(declare (indent defun)))
|
||||||
|
|
||||||
|
(provide 'core-settings)
|
||||||
|
;;; core-settings.el ends here
|
6
core/core-snippets.el
Normal file
6
core/core-snippets.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;;; core-snippets.el
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
|
||||||
|
(provide 'core-snippets)
|
||||||
|
;;; core-snippets.el ends here
|
6
core/core-states.el
Normal file
6
core/core-states.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;;; core-states.el
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'core-states)
|
||||||
|
;;; core-states.el ends here
|
|
@ -1,6 +1,6 @@
|
||||||
;;; core-flycheck.el --- check yourself before you shrek yourself
|
;;; core-syntax-checking.el --- tasing you for every forgotten semicolon
|
||||||
|
|
||||||
(use-package flycheck
|
(package! flycheck
|
||||||
:commands (flycheck-mode flycheck-list-errors flycheck-buffer)
|
:commands (flycheck-mode flycheck-list-errors flycheck-buffer)
|
||||||
:init
|
:init
|
||||||
(setq flycheck-indication-mode 'right-fringe
|
(setq flycheck-indication-mode 'right-fringe
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
flycheck-display-errors-delay 0.5)
|
flycheck-display-errors-delay 0.5)
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(def-popup! " ?\\*Flycheck.+\\*" :align below :size 14 :noselect t :regexp t)
|
;; (def-popup! " ?\\*Flycheck.+\\*" :align below :size 14 :noselect t :regexp t)
|
||||||
|
|
||||||
(map! :map flycheck-error-list-mode-map
|
(map! :map flycheck-error-list-mode-map
|
||||||
:n "C-n" 'flycheck-error-list-next-error
|
:n "C-n" 'flycheck-error-list-next-error
|
||||||
|
@ -23,16 +23,20 @@
|
||||||
:n "RET" 'flycheck-error-list-goto-error)
|
:n "RET" 'flycheck-error-list-goto-error)
|
||||||
|
|
||||||
;; Flycheck buffer on ESC in normal mode.
|
;; Flycheck buffer on ESC in normal mode.
|
||||||
|
(defun doom*flycheck-buffer ()
|
||||||
|
(when (bound-and-true-p flycheck-mode) (flycheck-buffer)))
|
||||||
(advice-add 'evil-force-normal-state :after 'doom*flycheck-buffer)
|
(advice-add 'evil-force-normal-state :after 'doom*flycheck-buffer)
|
||||||
|
|
||||||
(define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
|
(define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
|
||||||
[0 0 0 0 0 4 12 28 60 124 252 124 60 28 12 4 0 0 0 0])
|
[0 0 0 0 0 4 12 28 60 124 252 124 60 28 12 4 0 0 0 0]))
|
||||||
|
|
||||||
(when (eq window-system 'mac)
|
;; NOTE Looks bad on emacs-mac build on MacOS
|
||||||
(require 'flycheck-pos-tip)
|
(package! flycheck-pos-tip
|
||||||
(flycheck-pos-tip-mode +1)))
|
:unless (eq window-system 'ns)
|
||||||
|
:after flycheck
|
||||||
|
:config (flycheck-pos-tip-mode +1))
|
||||||
|
|
||||||
(use-package flyspell :commands flyspell-mode)
|
(package! flyspell :commands flyspell-mode)
|
||||||
|
|
||||||
(provide 'core-flycheck)
|
(provide 'core-syntax-checking)
|
||||||
;;; core-flycheck.el ends here
|
;;; core-syntax-checking.el ends here
|
470
core/core-ui.el
470
core/core-ui.el
|
@ -1,4 +1,4 @@
|
||||||
;;; core-ui.el
|
;; core-ui.el --- draw me like one of your French editors
|
||||||
|
|
||||||
(defvar doom-ui-fringe-size '3
|
(defvar doom-ui-fringe-size '3
|
||||||
"Default fringe width")
|
"Default fringe width")
|
||||||
|
@ -14,204 +14,40 @@
|
||||||
(font-spec :family "Fira Sans" :size 12)
|
(font-spec :family "Fira Sans" :size 12)
|
||||||
"The font currently in use.")
|
"The font currently in use.")
|
||||||
|
|
||||||
|
(defvar doom-ui-unicode-font
|
||||||
|
(font-spec :family "DejaVu Sans Mono" :size 12)
|
||||||
|
"Fallback font for unicode glyphs.")
|
||||||
|
|
||||||
;;
|
(setq bidi-display-reordering nil ; disable bidirectional text for tiny performance boost
|
||||||
;; Configuration
|
blink-matching-paren nil ; don't blink--too distracting
|
||||||
;;
|
cursor-in-non-selected-windows nil
|
||||||
|
echo-keystrokes 0.02
|
||||||
(setq-default
|
frame-inhibit-implied-resize t
|
||||||
mode-line-default-help-echo nil ; don't say anything on mode-line mouseover
|
;; remove continuation arrow on right fringe
|
||||||
indicate-buffer-boundaries nil ; don't show where buffer starts/ends
|
fringe-indicator-alist (delq (assq 'continuation fringe-indicator-alist)
|
||||||
indicate-empty-lines nil ; don't show empty lines
|
fringe-indicator-alist)
|
||||||
fringes-outside-margins t ; switches order of fringe and margin
|
highlight-nonselected-window nil
|
||||||
;; Keep cursors and highlights in current window only
|
image-animate-loop t
|
||||||
cursor-in-non-selected-windows nil
|
indicate-buffer-boundaries nil
|
||||||
highlight-nonselected-windows nil
|
indicate-empty-lines nil
|
||||||
;; Disable bidirectional text support for slight performance bonus
|
jit-lock-defer-time nil
|
||||||
bidi-display-reordering nil
|
jit-lock-stealth-nice 0.1
|
||||||
;; Remove continuation arrow on right fringe
|
jit-lock-stealth-time 0.2
|
||||||
fringe-indicator-alist (delq (assq 'continuation fringe-indicator-alist)
|
jit-lock-stealth-verbose nil
|
||||||
fringe-indicator-alist)
|
max-mini-window-height 0.3
|
||||||
|
mode-line-default-help-echo nil ; disable mode-line mouseovers
|
||||||
blink-matching-paren nil ; don't blink--too distracting
|
redisplay-dont-pause t ; don't pause display on input
|
||||||
show-paren-delay 0.075
|
resize-mini-windows 'grow-only ; Minibuffer resizing
|
||||||
show-paren-highlight-openparen t
|
show-help-function nil ; hide :help-echo text
|
||||||
show-paren-when-point-inside-paren t
|
show-paren-delay 0.075
|
||||||
uniquify-buffer-name-style nil
|
show-paren-highlight-openparen t
|
||||||
visible-bell nil
|
show-paren-when-point-inside-paren t
|
||||||
visible-cursor nil
|
split-width-threshold nil ; favor horizontal splits
|
||||||
x-stretch-cursor t
|
uniquify-buffer-name-style nil
|
||||||
use-dialog-box nil ; always avoid GUI
|
use-dialog-box nil ; always avoid GUI
|
||||||
redisplay-dont-pause t ; don't pause display on input
|
visible-bell nil
|
||||||
split-width-threshold nil ; favor horizontal splits
|
visible-cursor nil
|
||||||
show-help-function nil ; hide :help-echo text
|
x-stretch-cursor t)
|
||||||
jit-lock-defer-time nil
|
|
||||||
jit-lock-stealth-nice 0.1
|
|
||||||
jit-lock-stealth-time 0.2
|
|
||||||
jit-lock-stealth-verbose nil
|
|
||||||
;; Minibuffer resizing
|
|
||||||
resize-mini-windows 'grow-only
|
|
||||||
max-mini-window-height 0.3
|
|
||||||
image-animate-loop t
|
|
||||||
;; Ask for confirmation on exit only if there are real buffers left
|
|
||||||
confirm-kill-emacs
|
|
||||||
(lambda (_)
|
|
||||||
(if (ignore-errors (doom/get-real-buffers))
|
|
||||||
(y-or-n-p "››› Quit?")
|
|
||||||
t)))
|
|
||||||
|
|
||||||
;; A subtle bell: flash the mode-line
|
|
||||||
;; TODO More flexible colors (only suits dark themes)
|
|
||||||
(defvar doom--modeline-bg nil)
|
|
||||||
|
|
||||||
(setq ring-bell-function
|
|
||||||
(lambda ()
|
|
||||||
(unless doom--modeline-bg
|
|
||||||
(setq doom--modeline-bg (face-attribute 'mode-line :background)))
|
|
||||||
(set-face-attribute 'mode-line nil :background "#54252C")
|
|
||||||
(run-with-timer
|
|
||||||
0.1 nil
|
|
||||||
(lambda () (set-face-attribute 'mode-line nil :background doom--modeline-bg)))))
|
|
||||||
|
|
||||||
|
|
||||||
;; y/n instead of yes/no
|
|
||||||
(fset 'yes-or-no-p 'y-or-n-p)
|
|
||||||
|
|
||||||
;; mode-line is unimportant in help/compile/completion candidate windows
|
|
||||||
(with-current-buffer "*Messages*" (doom-hide-mode-line-mode +1))
|
|
||||||
(add-hook! (help-mode
|
|
||||||
compilation-mode
|
|
||||||
messages-buffer-mode
|
|
||||||
completion-list-mode)
|
|
||||||
'doom-hide-mode-line-mode)
|
|
||||||
|
|
||||||
;; Eldoc is enabled globally on Emacs 25. No thank you, I'll do it myself.
|
|
||||||
(when (bound-and-true-p global-eldoc-mode)
|
|
||||||
(global-eldoc-mode -1))
|
|
||||||
|
|
||||||
;; TODO/FIXME/NOTE highlighting in comments
|
|
||||||
(add-hook! (prog-mode emacs-lisp-mode css-mode)
|
|
||||||
(font-lock-add-keywords
|
|
||||||
nil '(("\\<\\(TODO\\(?:(.*)\\)?:?\\)\\>" 1 'warning prepend)
|
|
||||||
("\\<\\(FIXME\\(?:(.*)\\)?:?\\)\\>" 1 'error prepend)
|
|
||||||
("\\<\\(NOTE\\(?:(.*)\\)?:?\\)\\>" 1 'success prepend))))
|
|
||||||
|
|
||||||
;; `window-divider-mode' gives us finer control over the border between windows.
|
|
||||||
;; The native border "consumes" a pixel of the fringe on righter-most splits (in
|
|
||||||
;; Yamamoto's emacs-mac at least), window-divider does not.
|
|
||||||
;; NOTE Only available on Emacs 25.1+
|
|
||||||
(when (boundp 'window-divider-mode)
|
|
||||||
(setq window-divider-default-places t
|
|
||||||
window-divider-default-bottom-width 1
|
|
||||||
window-divider-default-right-width 1)
|
|
||||||
(window-divider-mode +1))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Plugins
|
|
||||||
;;
|
|
||||||
|
|
||||||
(use-package doom-themes
|
|
||||||
:config
|
|
||||||
(setq doom-neotree-enable-variable-pitch t
|
|
||||||
doom-neotree-file-icons 'simple
|
|
||||||
doom-neotree-line-spacing 3)
|
|
||||||
(load-theme doom-ui-theme t)
|
|
||||||
;; brighter source buffers
|
|
||||||
(add-hook 'find-file-hook 'doom-buffer-mode)
|
|
||||||
;; Custom neotree theme
|
|
||||||
(when window-system
|
|
||||||
(require 'doom-neotree)))
|
|
||||||
|
|
||||||
(use-package beacon
|
|
||||||
:config
|
|
||||||
(beacon-mode +1)
|
|
||||||
(setq beacon-color (face-attribute 'highlight :background nil t)
|
|
||||||
beacon-blink-when-buffer-changes t
|
|
||||||
beacon-blink-when-point-moves-vertically 10))
|
|
||||||
|
|
||||||
(use-package hl-line
|
|
||||||
:init (add-hook 'prog-mode-hook 'hl-line-mode)
|
|
||||||
:config
|
|
||||||
;; stickiness doesn't play nice with emacs 25+
|
|
||||||
(setq hl-line-sticky-flag nil
|
|
||||||
global-hl-line-sticky-flag nil)
|
|
||||||
|
|
||||||
;; Remember whether hl-line was initially on or off in the current buffer
|
|
||||||
(defvar-local doom--hl-line-mode nil)
|
|
||||||
(defun doom|hl-line-on () (if doom--hl-line-mode (hl-line-mode +1)))
|
|
||||||
(defun doom|hl-line-off () (if doom--hl-line-mode (hl-line-mode -1)))
|
|
||||||
(add-hook! hl-line-mode (if hl-line-mode (setq doom--hl-line-mode t))))
|
|
||||||
|
|
||||||
(use-package highlight-indentation
|
|
||||||
:commands (highlight-indentation-mode
|
|
||||||
highlight-indentation-current-column-mode)
|
|
||||||
:init
|
|
||||||
(after! editorconfig
|
|
||||||
(advice-add 'highlight-indentation-guess-offset
|
|
||||||
:override 'doom*hl-indent-guess-offset))
|
|
||||||
;; Since empty lines are stripped on save, the indentation highlights will
|
|
||||||
;; have unseemly breaks in them. These hooks will indent empty lines so that
|
|
||||||
;; the highlights are consistent, without affecting the saved output.
|
|
||||||
(add-hook! highlight-indentation-mode
|
|
||||||
(if highlight-indentation-mode
|
|
||||||
(progn
|
|
||||||
(doom/add-whitespace)
|
|
||||||
(add-hook 'after-save-hook 'doom/add-whitespace nil t))
|
|
||||||
(remove-hook 'after-save-hook 'doom/add-whitespace t)
|
|
||||||
(delete-trailing-whitespace))))
|
|
||||||
|
|
||||||
(use-package highlight-numbers :commands (highlight-numbers-mode))
|
|
||||||
|
|
||||||
(use-package nlinum
|
|
||||||
:commands nlinum-mode
|
|
||||||
:preface
|
|
||||||
(setq linum-format "%3d ")
|
|
||||||
(defvar nlinum-format "%4d ")
|
|
||||||
(defvar doom--hl-nlinum-overlay nil)
|
|
||||||
(defvar doom--hl-nlinum-line nil)
|
|
||||||
:init
|
|
||||||
(add-hook!
|
|
||||||
(markdown-mode prog-mode scss-mode web-mode conf-mode groovy-mode
|
|
||||||
nxml-mode snippet-mode php-mode)
|
|
||||||
'nlinum-mode)
|
|
||||||
;; FIXME This only works if hl-line is active! Why?
|
|
||||||
(add-hook! nlinum-mode
|
|
||||||
(if nlinum-mode-hook
|
|
||||||
(add-hook 'post-command-hook 'doom|nlinum-hl-line nil t)
|
|
||||||
(remove-hook 'post-command-hook 'doom|nlinum-hl-line t)))
|
|
||||||
:config
|
|
||||||
;; Calculate line number column width beforehand
|
|
||||||
(add-hook! nlinum-mode
|
|
||||||
(setq nlinum--width (length (save-excursion (goto-char (point-max))
|
|
||||||
(format-mode-line "%l")))))
|
|
||||||
|
|
||||||
;; Disable nlinum when making frames, otherwise we get linum face error
|
|
||||||
;; messages that prevent frame creation.
|
|
||||||
(add-hook 'before-make-frame-hook 'doom|nlinum-disable)
|
|
||||||
(add-hook 'after-make-frame-functions 'doom|nlinum-enable))
|
|
||||||
|
|
||||||
(use-package rainbow-delimiters
|
|
||||||
:commands rainbow-delimiters-mode
|
|
||||||
:config (setq rainbow-delimiters-max-face-count 3)
|
|
||||||
:init
|
|
||||||
(add-hook! (emacs-lisp-mode lisp-mode js-mode css-mode c-mode-common)
|
|
||||||
'rainbow-delimiters-mode))
|
|
||||||
|
|
||||||
;; NOTE hl-line-mode and rainbow-mode don't play well together
|
|
||||||
(use-package rainbow-mode
|
|
||||||
:commands rainbow-mode
|
|
||||||
:init (after! hl-line (add-hook 'rainbow-mode-hook 'doom|hl-line-off)))
|
|
||||||
|
|
||||||
(use-package stripe-buffer
|
|
||||||
:commands stripe-buffer-mode
|
|
||||||
:init (add-hook 'dired-mode-hook 'stripe-buffer-mode))
|
|
||||||
|
|
||||||
(use-package visual-fill-column :defer t
|
|
||||||
:config
|
|
||||||
(setq-default visual-fill-column-center-text nil
|
|
||||||
visual-fill-column-width fill-column
|
|
||||||
split-window-preferred-function 'visual-line-mode-split-window-sensibly))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -229,9 +65,11 @@
|
||||||
(with-demoted-errors "FONT ERROR: %s"
|
(with-demoted-errors "FONT ERROR: %s"
|
||||||
(set-frame-font doom-ui-font t t)
|
(set-frame-font doom-ui-font t t)
|
||||||
;; Fallback to `doom-unicode-font' for Unicode characters
|
;; Fallback to `doom-unicode-font' for Unicode characters
|
||||||
(set-fontset-font t 'unicode doom-unicode-font)
|
(when doom-ui-unicode-font
|
||||||
|
(set-fontset-font t 'unicode doom-ui-unicode-font))
|
||||||
;; Set font for variable-pitch mode
|
;; Set font for variable-pitch mode
|
||||||
(set-face-attribute 'variable-pitch nil :font doom-ui-variable-pitch-font))
|
(when doom-ui-variable-pitch-font
|
||||||
|
(set-face-attribute 'variable-pitch nil :font doom-ui-variable-pitch-font)))
|
||||||
;; standardize fringe width
|
;; standardize fringe width
|
||||||
(fringe-mode doom-ui-fringe-size)
|
(fringe-mode doom-ui-fringe-size)
|
||||||
(push `(left-fringe . ,doom-ui-fringe-size) default-frame-alist)
|
(push `(left-fringe . ,doom-ui-fringe-size) default-frame-alist)
|
||||||
|
@ -244,5 +82,237 @@
|
||||||
(set-fringe-bitmap-face 'tilde 'fringe)
|
(set-fringe-bitmap-face 'tilde 'fringe)
|
||||||
(setcdr (assq 'empty-line fringe-indicator-alist) 'tilde))
|
(setcdr (assq 'empty-line fringe-indicator-alist) 'tilde))
|
||||||
|
|
||||||
|
(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no
|
||||||
|
(global-eldoc-mode -1) ; auto-enabled in Emacs 25+; I'd rather do this myself
|
||||||
|
|
||||||
|
;;; TODO Smart quit-confirmation prompt
|
||||||
|
;; Only prompt if there are real buffers left (see ;; `doom-real-buffer-p')
|
||||||
|
;;(setq confirm-kill-emacs
|
||||||
|
;; (lambda (_)
|
||||||
|
;; (if (ignore-errors (doom-get-real-buffers))
|
||||||
|
;; (y-or-n-p "››› Quit?")
|
||||||
|
;; t)))
|
||||||
|
|
||||||
|
;;; Flash the mode-line on error
|
||||||
|
;; TODO More flexible colors (only suits dark themes)
|
||||||
|
;; FIXME With a rapid key-repeat setting the mode-line bg can get stuck
|
||||||
|
(defvar doom--visual-bell-bg nil)
|
||||||
|
(setq ring-bell-function 'doom-visual-bell)
|
||||||
|
(defun doom-visual-bell ()
|
||||||
|
(unless doom--visual-bell-bg
|
||||||
|
(setq doom--visual-bell-bg (face-attribute 'mode-line :background)))
|
||||||
|
(set-face-attribute 'mode-line nil :background "#54252C")
|
||||||
|
(run-with-timer
|
||||||
|
0.1 nil
|
||||||
|
(lambda () (set-face-attribute 'mode-line nil :background doom--visual-bell-bg))))
|
||||||
|
|
||||||
|
;;; TODO/FIXME/NOTE highlighting in comments
|
||||||
|
(add-hook! (prog-mode emacs-lisp-mode css-mode)
|
||||||
|
(font-lock-add-keywords
|
||||||
|
nil '(("\\<\\(TODO\\(?:(.*)\\)?:?\\)\\>" 1 'warning prepend)
|
||||||
|
("\\<\\(FIXME\\(?:(.*)\\)?:?\\)\\>" 1 'error prepend)
|
||||||
|
("\\<\\(NOTE\\(?:(.*)\\)?:?\\)\\>" 1 'success prepend))))
|
||||||
|
|
||||||
|
;;; More reliable inter-window border
|
||||||
|
;; The native border "consumes" a pixel of the fringe on righter-most splits (in
|
||||||
|
;; Yamamoto's emacs-mac at least), `window-divider' does not.
|
||||||
|
;; NOTE available since Emacs 25.1
|
||||||
|
(setq window-divider-default-places t
|
||||||
|
window-divider-default-bottom-width 1
|
||||||
|
window-divider-default-right-width 1)
|
||||||
|
(window-divider-mode +1)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Mode-line hiding minor mode
|
||||||
|
(defvar doom-hide-mode-line-format nil
|
||||||
|
"Format to use when `doom-hide-mode-line-mode' replaces the modeline")
|
||||||
|
|
||||||
|
(defvar-local doom--old-mode-line nil)
|
||||||
|
|
||||||
|
(define-minor-mode doom-hide-mode-line-mode
|
||||||
|
"Minor mode to hide the mode-line in the current buffer."
|
||||||
|
:init-value nil
|
||||||
|
:global nil
|
||||||
|
(if doom-hide-mode-line-mode
|
||||||
|
(setq doom--old-mode-line mode-line-format
|
||||||
|
mode-line-format doom-hide-mode-line-format)
|
||||||
|
(setq mode-line-format doom--old-mode-line
|
||||||
|
doom--mode-line doom-hide-mode-line-format))
|
||||||
|
(force-mode-line-update))
|
||||||
|
|
||||||
|
;; Ensure major-mode or theme changes don't overwrite these variables
|
||||||
|
(put 'doom--old-mode-line 'permanent-local t)
|
||||||
|
(put 'doom-hide-mode-line-mode 'permanent-local t)
|
||||||
|
|
||||||
|
;; mode-line is unimportant in some windows
|
||||||
|
(with-current-buffer "*Messages*" (doom-hide-mode-line-mode +1))
|
||||||
|
(add-hook! (help-mode compilation-mode messages-buffer-mode completion-list-mode)
|
||||||
|
'doom-hide-mode-line-mode)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Plugins
|
||||||
|
;;
|
||||||
|
|
||||||
|
;; Causes a flash around the cursor when it moves across a "large" distance.
|
||||||
|
;; Usually between windows, or across files. This makes it easier to keep track
|
||||||
|
;; where your cursor is, which I find helpful on my 30" 2560x1600 display.
|
||||||
|
(package! beacon
|
||||||
|
:config (beacon-mode +1)
|
||||||
|
(setq beacon-color (let ((bg (face-attribute 'highlight :background nil t)))
|
||||||
|
(if (eq bg 'unspecified) (face-attribute 'highlight :foreground nil t) bg))
|
||||||
|
beacon-blink-when-buffer-changes t
|
||||||
|
beacon-blink-when-point-moves-vertically 10))
|
||||||
|
|
||||||
|
;; I modified the built-in `hideshow' package to be prettier, autoload when
|
||||||
|
;; needed, and to behave as much like folding in vim does as possible. A better
|
||||||
|
;; option might be `origami', but certain bugs in it are preventing the switch
|
||||||
|
;; for now.
|
||||||
|
(package! hideshow :ensure nil
|
||||||
|
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
|
||||||
|
:init
|
||||||
|
(defun doom*load-hs-minor-mode ()
|
||||||
|
(hs-minor-mode 1)
|
||||||
|
(advice-remove 'evil-toggle-fold 'doom-load-hs-minor-mode))
|
||||||
|
(advice-add 'evil-toggle-fold :before 'doom*load-hs-minor-mode)
|
||||||
|
|
||||||
|
:config
|
||||||
|
;; Prettify code folding in emacs
|
||||||
|
(defface doom-folded-face '((t (:background "#ff8")))
|
||||||
|
"Face to hightlight `hideshow' overlays."
|
||||||
|
:group 'hideshow)
|
||||||
|
(setq hs-set-up-overlay
|
||||||
|
(lambda (ov)
|
||||||
|
(when (eq 'code (overlay-get ov 'hs))
|
||||||
|
(overlay-put
|
||||||
|
ov 'display (propertize " [...] " 'face 'doom-folded-face))))))
|
||||||
|
|
||||||
|
;; Show unintrusive indentation markers, and do some whitespace voodoo to
|
||||||
|
;; prevent the lack-of-indent-guides-on-blank-lines problem.
|
||||||
|
(package! highlight-indent-guides
|
||||||
|
:commands highlight-indent-guides-mode
|
||||||
|
:config
|
||||||
|
(setq highlight-indent-guides-method 'character)
|
||||||
|
|
||||||
|
(defun doom|highlight-indent-guides-adjust-whitespace (&optional start end)
|
||||||
|
"Consider this the opposite of `delete-trailing-whitespace'. Injects
|
||||||
|
whitespace into buffer so that `highlight-indent-guides-mode' will display
|
||||||
|
consistent, unbroken indent markers. This whitespace is stripped out on save, as
|
||||||
|
not to affect the resulting file."
|
||||||
|
(interactive (progn (barf-if-buffer-read-only)
|
||||||
|
(if (use-region-p)
|
||||||
|
(list (region-beginning) (region-end))
|
||||||
|
(list nil nil))))
|
||||||
|
(unless indent-tabs-mode
|
||||||
|
(save-match-data
|
||||||
|
(save-excursion
|
||||||
|
(let ((end-marker (copy-marker (or end (point-max))))
|
||||||
|
(start (or start (point-min))))
|
||||||
|
(goto-char start)
|
||||||
|
(while (and (re-search-forward "^$" end-marker t) (not (>= (point) end-marker)))
|
||||||
|
(let (line-start line-end next-start next-end)
|
||||||
|
(save-excursion
|
||||||
|
;; Check previous line indent
|
||||||
|
(forward-line -1)
|
||||||
|
(setq line-start (point)
|
||||||
|
line-end (save-excursion (back-to-indentation) (point)))
|
||||||
|
;; Check next line indent
|
||||||
|
(forward-line 2)
|
||||||
|
(setq next-start (point)
|
||||||
|
next-end (save-excursion (back-to-indentation) (point)))
|
||||||
|
;; Back to origin
|
||||||
|
(forward-line -1)
|
||||||
|
;; Adjust indent
|
||||||
|
(let* ((line-indent (- line-end line-start))
|
||||||
|
(next-indent (- next-end next-start))
|
||||||
|
(indent (min line-indent next-indent)))
|
||||||
|
(insert (make-string (if (zerop indent) 0 (1+ indent)) ? )))))
|
||||||
|
(forward-line 1)))))
|
||||||
|
(set-buffer-modified-p nil))
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(add-hook! highlight-indent-guides-mode
|
||||||
|
(if highlight-indent-guides-mode
|
||||||
|
(progn
|
||||||
|
(doom|highlight-indent-guides-adjust-whitespace)
|
||||||
|
(add-hook 'after-save-hook 'doom|highlight-indent-guides-adjust-whitespace nil t))
|
||||||
|
(remove-hook 'after-save-hook 'doom|highlight-indent-guides-adjust-whitespace t)
|
||||||
|
(delete-trailing-whitespace)))
|
||||||
|
|
||||||
|
;; If all else fails, this package tries to guess the indentation, but does it
|
||||||
|
;; naively, so get default indentation from editorconfig instead.
|
||||||
|
(defun doom*highlight-indentation-guess-offset (&rest _)
|
||||||
|
(when (featurep 'editorconfig)
|
||||||
|
(setq-local highlight-indentation-offset
|
||||||
|
(string-to-int (gethash 'indent_size (editorconfig-get-properties))))))
|
||||||
|
(advice-add 'highlight-indentation-guess-offset :before 'doom*highlight-indentation-guess-offset))
|
||||||
|
|
||||||
|
;; Some modes don't adequately highlight numbers, therefore...
|
||||||
|
(package! highlight-numbers :commands highlight-numbers-mode)
|
||||||
|
|
||||||
|
;; Line highlighting (built-in)
|
||||||
|
(package! hl-line :ensure nil
|
||||||
|
:config
|
||||||
|
;; stickiness doesn't play nice with emacs 25+
|
||||||
|
(setq hl-line-sticky-flag nil
|
||||||
|
global-hl-line-sticky-flag nil)
|
||||||
|
|
||||||
|
;; Remember whether hl-line was initially on or off in the current buffer
|
||||||
|
(defvar-local doom--hl-line-mode nil)
|
||||||
|
(defun doom|hl-line-on () (if doom--hl-line-mode (hl-line-mode +1)))
|
||||||
|
(defun doom|hl-line-off () (if doom--hl-line-mode (hl-line-mode -1)))
|
||||||
|
(add-hook! hl-line-mode (if hl-line-mode (setq doom--hl-line-mode t))))
|
||||||
|
|
||||||
|
;; A faster (or equal, in the worst case) line number plugin than `linum'. I've
|
||||||
|
;; modified it to highlight the current line, and fixed some glaring problems
|
||||||
|
;; with nlinum and frames.
|
||||||
|
(package! nlinum
|
||||||
|
:commands nlinum-mode
|
||||||
|
:preface (defvar nlinum-format "%4d ")
|
||||||
|
:init
|
||||||
|
(add-hook!
|
||||||
|
(markdown-mode prog-mode scss-mode web-mode conf-mode groovy-mode
|
||||||
|
nxml-mode snippet-mode php-mode)
|
||||||
|
'nlinum-mode)
|
||||||
|
|
||||||
|
:config
|
||||||
|
(defun doom/nlinum-toggle ()
|
||||||
|
"Toggle `nlinum-mode'."
|
||||||
|
(interactive)
|
||||||
|
(nlinum-mode (if (bound-and-true-p nlinum-mode) -1 +1)))
|
||||||
|
|
||||||
|
;; Optimization: calculate line number column width beforehand
|
||||||
|
(add-hook! nlinum-mode
|
||||||
|
(setq nlinum--width (length (save-excursion (goto-char (point-max))
|
||||||
|
(format-mode-line "%l")))))
|
||||||
|
|
||||||
|
;; Disable nlinum when making frames, otherwise we get linum face error
|
||||||
|
;; messages that prevent frame creation.
|
||||||
|
(defun doom|nlinum-off () (nlinum-mode -1))
|
||||||
|
(add-hook 'before-make-frame-hook 'doom|nlinum-off)
|
||||||
|
(add-hook 'after-make-frame-functions 'doom|nlinum-off))
|
||||||
|
|
||||||
|
;; Makes distinguishing stacked delimiters apart much, much easier. Especially
|
||||||
|
;; in parentheses-drunk languages like Lisp.
|
||||||
|
(package! rainbow-delimiters
|
||||||
|
:commands rainbow-delimiters-mode
|
||||||
|
:config (setq rainbow-delimiters-max-face-count 3)
|
||||||
|
:init
|
||||||
|
(add-hook! (emacs-lisp-mode lisp-mode js-mode css-mode c-mode-common)
|
||||||
|
'rainbow-delimiters-mode))
|
||||||
|
|
||||||
|
;; Give color codes or names a background in that color. Nifty for css. Note
|
||||||
|
;; that hl-line and rainbow-mode don't play nicely together.
|
||||||
|
(package! rainbow-mode
|
||||||
|
:commands rainbow-mode
|
||||||
|
:init (after! hl-line (add-hook 'rainbow-mode-hook 'doom|hl-line-off)))
|
||||||
|
|
||||||
|
;; This makes distractions-free mode possible, but modifying window margins on
|
||||||
|
;; the fly and centering the buffer.
|
||||||
|
(package! visual-fill-column
|
||||||
|
:config
|
||||||
|
(add-hook! visual-fill-column-mode
|
||||||
|
(setq-local split-window-preferred-function 'visual-line-mode-split-window-sensibly)))
|
||||||
|
|
||||||
(provide 'core-ui)
|
(provide 'core-ui)
|
||||||
;;; core-ui.el ends here
|
;;; core-ui.el ends here
|
||||||
|
|
110
core/core-vcs.el
110
core/core-vcs.el
|
@ -1,27 +1,23 @@
|
||||||
;;; core-vcs.el --- version control awareness
|
;;; core-vcs.el
|
||||||
|
|
||||||
(use-package gitconfig-mode
|
(package! gitconfig-mode
|
||||||
:mode ("/\\.?git/?config$" "/\\.gitmodules$")
|
:mode "/\\.?git/?config$"
|
||||||
|
:mode "/\\.gitmodules$"
|
||||||
:init (add-hook 'gitconfig-mode-hook 'flyspell-mode))
|
:init (add-hook 'gitconfig-mode-hook 'flyspell-mode))
|
||||||
|
|
||||||
(use-package gitignore-mode
|
(package! gitignore-mode
|
||||||
:mode ("/\\.gitignore$"
|
:mode "/\\.gitignore$"
|
||||||
"/\\.git/info/exclude$"
|
:mode "/\\.git/info/exclude$"
|
||||||
"/git/ignore$"))
|
:mode "/git/ignore$")
|
||||||
|
|
||||||
(use-package git-gutter
|
(package! git-gutter-fringe
|
||||||
:commands (git-gutter-mode doom/vcs-next-hunk doom/vcs-prev-hunk
|
:commands git-gutter-mode
|
||||||
doom/vcs-show-hunk doom/vcs-stage-hunk doom/vcs-revert-hunk)
|
:init (add-hook! (text-mode prog-mode conf-mode) 'git-gutter-mode)
|
||||||
:init
|
|
||||||
(add-hook! (text-mode prog-mode conf-mode) 'git-gutter-mode)
|
|
||||||
:config
|
:config
|
||||||
(require 'git-gutter-fringe)
|
;; places the git gutter outside the margins.
|
||||||
(def-popup! "^\\*git-gutter.+\\*$" :align below :size 15 :noselect t :regexp t)
|
(setq-default fringes-outside-margins t)
|
||||||
|
|
||||||
;; NOTE If you want the git gutter to be on the outside of the margins (rather
|
;; thin fringe bitmaps
|
||||||
;; than inside), `fringes-outside-margins' should be non-nil.
|
|
||||||
|
|
||||||
;; colored fringe "bars"
|
|
||||||
(define-fringe-bitmap 'git-gutter-fr:added
|
(define-fringe-bitmap 'git-gutter-fr:added
|
||||||
[224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224]
|
[224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224 224]
|
||||||
nil nil 'center)
|
nil nil 'center)
|
||||||
|
@ -32,35 +28,15 @@
|
||||||
[0 0 0 0 0 0 0 0 0 0 0 0 0 128 192 224 240 248]
|
[0 0 0 0 0 0 0 0 0 0 0 0 0 128 192 224 240 248]
|
||||||
nil nil 'center)
|
nil nil 'center)
|
||||||
|
|
||||||
;; Refreshing git-gutter
|
;; Refreshing git-gutter on ESC and focus
|
||||||
(advice-add 'evil-force-normal-state :after 'git-gutter)
|
(advice-add 'evil-force-normal-state :after 'git-gutter)
|
||||||
(add-hook 'focus-in-hook 'git-gutter:update-all-windows)
|
(add-hook 'focus-in-hook 'git-gutter:update-all-windows))
|
||||||
|
|
||||||
(defalias 'doom/vcs-next-hunk 'git-gutter:next-hunk)
|
(package! magit
|
||||||
(defalias 'doom/vcs-prev-hunk 'git-gutter:previous-hunk)
|
:commands magit-status
|
||||||
(defalias 'doom/vcs-show-hunk 'git-gutter:popup-hunk)
|
|
||||||
(defalias 'doom/vcs-stage-hunk 'git-gutter:stage-hunk)
|
|
||||||
(defalias 'doom/vcs-revert-hunk 'git-gutter:revert-hunk))
|
|
||||||
|
|
||||||
(use-package git-messenger
|
|
||||||
:commands git-messenger:popup-message
|
|
||||||
:init (defvar git-messenger-map (make-sparse-keymap))
|
|
||||||
:config
|
:config
|
||||||
(def-popup! "*git-messenger*" :align left :size 55 :select t)
|
|
||||||
(setq git-messenger:show-detail t)
|
|
||||||
(map! :map git-messenger-map
|
|
||||||
"<escape>" 'git-messenger:popup-close
|
|
||||||
"q" 'git-messenger:popup-close))
|
|
||||||
|
|
||||||
(use-package magit
|
|
||||||
:commands (magit-status)
|
|
||||||
:config
|
|
||||||
(def-popup! "^\\*magit.+" :align below :regexp t)
|
|
||||||
;; Prevent magit + evil-snipe conflicts
|
;; Prevent magit + evil-snipe conflicts
|
||||||
(add-hook 'magit-mode-hook 'turn-off-evil-snipe-override-mode)
|
(add-hook 'magit-mode-hook 'turn-off-evil-snipe-override-mode)
|
||||||
(require 'evil-magit)
|
|
||||||
|
|
||||||
(setq magit-display-file-buffer-function 'doom/magit-pop-to-buffer)
|
|
||||||
|
|
||||||
(map! :map magit-mode-map
|
(map! :map magit-mode-map
|
||||||
;; Don't let Tab binding in my-bindings conflict with Tab in magit
|
;; Don't let Tab binding in my-bindings conflict with Tab in magit
|
||||||
|
@ -69,6 +45,11 @@
|
||||||
:nv "C-j" nil
|
:nv "C-j" nil
|
||||||
:nv "C-k" nil))
|
:nv "C-k" nil))
|
||||||
|
|
||||||
|
(package! evil-magit :after magit)
|
||||||
|
|
||||||
|
(package! browse-at-remote
|
||||||
|
:commands (browse-at-remote/browse browse-at-remote/get-url))
|
||||||
|
|
||||||
(after! vc-annotate
|
(after! vc-annotate
|
||||||
(evil-set-initial-state 'vc-annotate-mode 'normal)
|
(evil-set-initial-state 'vc-annotate-mode 'normal)
|
||||||
(evil-set-initial-state 'vc-git-log-view-mode 'normal)
|
(evil-set-initial-state 'vc-git-log-view-mode 'normal)
|
||||||
|
@ -82,24 +63,41 @@
|
||||||
:n [tab] 'vc-annotate-toggle-annotation-visibility
|
:n [tab] 'vc-annotate-toggle-annotation-visibility
|
||||||
:n "RET" 'vc-annotate-find-revision-at-line))
|
:n "RET" 'vc-annotate-find-revision-at-line))
|
||||||
|
|
||||||
(use-package browse-at-remote
|
|
||||||
:commands (browse-at-remote/browse browse-at-remote/get-url))
|
|
||||||
|
|
||||||
;; Ediff
|
;;
|
||||||
(defvar doom-ediff-enabled nil)
|
;; Defuns
|
||||||
(add-hook! ediff-load
|
;;
|
||||||
(setq ediff-diff-options "-w"
|
|
||||||
ediff-split-window-function 'split-window-horizontally
|
|
||||||
ediff-window-setup-function 'ediff-setup-windows-plain) ; no extra frames
|
|
||||||
|
|
||||||
;; Brighten other buffers
|
(defun doom-git-root ()
|
||||||
(add-hook 'ediff-prepare-buffer-hook 'doom-buffer-mode)
|
"Get git url root."
|
||||||
|
(when-let (url (car-safe (browse-at-remote--remote-ref buffer-file-name)))
|
||||||
|
(cdr (browse-at-remote--get-url-from-remote url))))
|
||||||
|
|
||||||
;; TODO Custom modeline for ediff buffers
|
(defun doom/git-browse-issues ()
|
||||||
|
"Open the github issues page for current repo."
|
||||||
|
(interactive)
|
||||||
|
(if-let (root (doom-git-root))
|
||||||
|
(browse-url (concat root "/issues"))
|
||||||
|
(user-error "No git root found!")))
|
||||||
|
|
||||||
;; For modeline awareness
|
(evil-define-command doom:git-browse (&optional bang)
|
||||||
(add-hook! ediff-startup (setq doom-ediff-enabled t))
|
"Open the website for the current (or specified) version controlled FILE. If
|
||||||
(add-hook! ediff-quit (setq doom-ediff-enabled nil)))
|
BANG, then copy it to clipboard. Fallback to repository root."
|
||||||
|
(interactive "<!>")
|
||||||
|
(let (url)
|
||||||
|
(condition-case err
|
||||||
|
(setq url (browse-at-remote-get-url))
|
||||||
|
(error
|
||||||
|
(setq url (shell-command-to-string "hub browse -u --"))
|
||||||
|
(setq url (if url
|
||||||
|
(concat (s-trim url) "/" (f-relative (buffer-file-name) (doom-project-root))
|
||||||
|
(when (use-region-p) (format "#L%s-L%s"
|
||||||
|
(line-number-at-pos (region-beginning))
|
||||||
|
(line-number-at-pos (region-end)))))))))
|
||||||
|
(when url
|
||||||
|
(if bang
|
||||||
|
(message "Url copied to clipboard: %s" (kill-new url))
|
||||||
|
(browse-url url)))))
|
||||||
|
|
||||||
(provide 'core-vcs)
|
(provide 'core-vcs)
|
||||||
;;; core-vcs.el ends here
|
;;; core-vcs.el ends here
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
;;; core-workgroups.el
|
|
||||||
|
|
||||||
;; I use workgroups to accomplish two things:
|
|
||||||
;; 1. Vim-like tab emulation (type :tabs to see a list of tabs -- maybe I'll
|
|
||||||
;; add some code to make a permanent frame header to display these some
|
|
||||||
;; day)
|
|
||||||
;; 2. Session persistence (with :ss and :sl)
|
|
||||||
;; 3. Tab names reflect the project open in them, unless they've been
|
|
||||||
;; explicitly named with :tabrename <name>
|
|
||||||
|
|
||||||
(defvar doom-wg-frames '()
|
|
||||||
"A list of all the frames opened as separate workgroups. See
|
|
||||||
defuns/defuns-workgroups.el.")
|
|
||||||
|
|
||||||
(defvar doom-wg-names '()
|
|
||||||
"Keeps track of the fixed names for workgroups (set with :tabrename), so that
|
|
||||||
these workgroups won't be auto-renamed.")
|
|
||||||
|
|
||||||
(use-package workgroups2
|
|
||||||
:when window-system
|
|
||||||
:init
|
|
||||||
(setq-default
|
|
||||||
wg-session-file (concat doom-temp-dir "/workgroups/last")
|
|
||||||
wg-workgroup-directory (concat doom-temp-dir "/workgroups/")
|
|
||||||
wg-first-wg-name "*untitled*"
|
|
||||||
wg-session-load-on-start nil
|
|
||||||
wg-mode-line-display-on nil
|
|
||||||
wg-mess-with-buffer-list nil
|
|
||||||
wg-emacs-exit-save-behavior 'save ; Options: 'save 'ask nil
|
|
||||||
wg-workgroups-mode-exit-save-behavior 'save
|
|
||||||
wg-log-level 0
|
|
||||||
|
|
||||||
;; NOTE: Some of these make workgroup-restoration unstable
|
|
||||||
wg-restore-mark t
|
|
||||||
wg-restore-frame-position t
|
|
||||||
wg-restore-remote-buffers nil
|
|
||||||
wg-restore-scroll-bars nil
|
|
||||||
wg-restore-fringes nil
|
|
||||||
wg-restore-margins nil
|
|
||||||
wg-restore-point-max t ; Throws silent errors if non-nil
|
|
||||||
|
|
||||||
wg-list-display-decor-divider " "
|
|
||||||
wg-list-display-decor-left-brace ""
|
|
||||||
wg-list-display-decor-right-brace "| "
|
|
||||||
wg-list-display-decor-current-left ""
|
|
||||||
wg-list-display-decor-current-right ""
|
|
||||||
wg-list-display-decor-previous-left ""
|
|
||||||
wg-list-display-decor-previous-right "")
|
|
||||||
|
|
||||||
:config
|
|
||||||
;; Remember fixed workgroup names between sessions
|
|
||||||
(push 'doom-wg-names savehist-additional-variables)
|
|
||||||
|
|
||||||
;; `wg-mode-line-display-on' wasn't enough
|
|
||||||
(advice-add 'wg-change-modeline :override 'ignore)
|
|
||||||
|
|
||||||
;; Don't remember popup and neotree windows
|
|
||||||
(add-hook 'kill-emacs-hook 'doom|wg-cleanup)
|
|
||||||
|
|
||||||
(after! projectile
|
|
||||||
;; Create a new workgroup on switch-project
|
|
||||||
(setq projectile-switch-project-action 'doom/wg-projectile-switch-project))
|
|
||||||
|
|
||||||
;; This helps abstract some of the underlying functions away, just in case I want to
|
|
||||||
;; switch to a different package in the future, like persp-mode, eyebrowse or wconf.
|
|
||||||
(defalias 'doom/tab-display 'doom/workgroup-display)
|
|
||||||
(defalias 'doom/helm-tabs 'doom:helm-wg)
|
|
||||||
(defalias 'doom/close-window-or-tab 'doom/close-window-or-workgroup)
|
|
||||||
(defalias 'doom:tab-create 'doom:workgroup-new)
|
|
||||||
(defalias 'doom:tab-rename 'doom:workgroup-rename)
|
|
||||||
(defalias 'doom:kill-tab 'doom:workgroup-delete)
|
|
||||||
(defalias 'doom:kill-other-tabs 'doom:kill-other-workgroups)
|
|
||||||
(defalias 'doom:switch-to-tab 'doom:switch-to-workgroup-at-index)
|
|
||||||
(defalias 'doom:switch-to-tab-left 'wg-switch-to-workgroup-left)
|
|
||||||
(defalias 'doom:switch-to-tab-right 'wg-switch-to-workgroup-right)
|
|
||||||
(defalias 'doom:switch-to-tab-last 'wg-switch-to-previous-workgroup)
|
|
||||||
|
|
||||||
(add-hook! emacs-startup
|
|
||||||
(workgroups-mode +1)
|
|
||||||
(wg-create-workgroup wg-first-wg-name)))
|
|
||||||
|
|
||||||
(unless window-system
|
|
||||||
(defalias 'wg-workgroup-associated-buffers 'ignore)
|
|
||||||
(defalias 'wg-current-workgroup 'ignore)
|
|
||||||
(defalias 'wg-save-session 'ignore))
|
|
||||||
|
|
||||||
(provide 'core-workgroups)
|
|
||||||
;;; core-workgroups.el ends here
|
|
6
core/core-workspaces.el
Normal file
6
core/core-workspaces.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;;; core-workspaces.el
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'core-workspaces)
|
||||||
|
;;; core-workspaces.el ends here
|
|
@ -1,53 +0,0 @@
|
||||||
;;; core-yasnippet.el
|
|
||||||
|
|
||||||
(use-package yasnippet
|
|
||||||
:mode ("emacs\\.d/private/\\(snippets\\|templates\\)/.+$" . snippet-mode)
|
|
||||||
:commands (yas-minor-mode
|
|
||||||
yas-minor-mode-on
|
|
||||||
yas-expand
|
|
||||||
yas-insert-snippet
|
|
||||||
yas-new-snippet
|
|
||||||
yas-visit-snippet-file)
|
|
||||||
:init
|
|
||||||
(defvar yas-minor-mode-map (make-sparse-keymap))
|
|
||||||
(setq yas-verbosity 0
|
|
||||||
yas-indent-line 'auto
|
|
||||||
yas-also-auto-indent-first-line t
|
|
||||||
yas-prompt-functions '(yas-ido-prompt yas-no-prompt)
|
|
||||||
;; Only load personal snippets
|
|
||||||
yas-snippet-dirs (list (concat doom-private-dir "/snippets")
|
|
||||||
(concat doom-private-dir "/templates")))
|
|
||||||
|
|
||||||
(add-hook! (text-mode prog-mode snippet-mode markdown-mode org-mode)
|
|
||||||
'yas-minor-mode-on)
|
|
||||||
|
|
||||||
:config
|
|
||||||
(yas-reload-all)
|
|
||||||
(map! :map yas-keymap
|
|
||||||
"C-e" 'doom/yas-goto-end-of-field
|
|
||||||
"C-a" 'doom/yas-goto-start-of-field
|
|
||||||
"<M-right>" 'doom/yas-goto-end-of-field
|
|
||||||
"<M-left>" 'doom/yas-goto-start-of-field
|
|
||||||
"<S-tab>" 'yas-prev-field
|
|
||||||
"<M-backspace>" 'doom/yas-clear-to-sof
|
|
||||||
"<escape>" 'evil-normal-state
|
|
||||||
[backspace] 'doom/yas-backspace
|
|
||||||
"<delete>" 'doom/yas-delete)
|
|
||||||
|
|
||||||
;; Fix an error caused by smartparens interfering with yasnippet bindings
|
|
||||||
(advice-add 'yas-expand :before 'sp-remove-active-pair-overlay)
|
|
||||||
;; Exit snippets on ESC in normal mode
|
|
||||||
(advice-add 'evil-force-normal-state :before 'yas-exit-all-snippets)
|
|
||||||
;; Once you're in normal mode, you're out
|
|
||||||
(add-hook 'evil-normal-state-entry-hook 'yas-abort-snippet)
|
|
||||||
;; Strip out whitespace before a line selection
|
|
||||||
(add-hook 'yas-before-expand-snippet-hook 'doom|yas-before-expand)
|
|
||||||
;; Fix previous hook persisting yas-selected-text between expansions
|
|
||||||
(add-hook 'yas-after-exit-snippet-hook 'doom|yas-after-expand))
|
|
||||||
|
|
||||||
(use-package auto-yasnippet
|
|
||||||
:commands (aya-create aya-expand aya-open-line aya-persist-snippet)
|
|
||||||
:config (setq aya-persist-snippets-dir (concat doom-private-dir "auto-snippets/")))
|
|
||||||
|
|
||||||
(provide 'core-yasnippet)
|
|
||||||
;;; core-yasnippet.el ends here
|
|
319
core/core.el
319
core/core.el
|
@ -1,99 +1,56 @@
|
||||||
;;; core.el --- The heart of the beast
|
;;; core.el --- The heart of the beast
|
||||||
;;
|
|
||||||
;;; Naming conventions:
|
;;; Naming conventions:
|
||||||
;;
|
;;
|
||||||
;; doom-... A public variable/constant or function
|
;; doom-... A public variable or function (non-interactive use)
|
||||||
;; doom--... An internal variable or function (non-interactive)
|
;; doom--... A private variable, function (non-interactive use) or macro
|
||||||
;; doom/... An autoloaded function
|
;; doom/... An interactive function
|
||||||
;; doom:... An ex command
|
;; doom:... An evil operator, motion or command
|
||||||
;; doom|... A hook
|
;; doom|... A hook
|
||||||
;; doom*... An advising function
|
;; doom*... An advising function
|
||||||
;; ...! Macro, shortcut alias or subst defun
|
;; ...! Macro, shortcut alias or defsubst
|
||||||
;; @... Autoloaded interactive lambda macro for keybinds
|
;; @... lambda macro for keybinds
|
||||||
|
;; +... Any of the above, but part of a module, e.g. +emacs-lisp|init-hook
|
||||||
;;
|
;;
|
||||||
;;; Autoloaded functions are in {core,modules}/defuns/defuns-*.el
|
;;; Autoloaded functions are in {core,modules}/defuns/defuns-*.el
|
||||||
|
|
||||||
;; Premature optimization for faster startup
|
(when (version< emacs-version "25.1")
|
||||||
(setq-default gc-cons-threshold 339430400
|
(error "DOOM Emacs no longer supports Emacs <25.1! Time to upgrade!"))
|
||||||
gc-cons-percentage 0.6)
|
|
||||||
|
|
||||||
;;
|
;;;
|
||||||
;; Global Constants
|
(defvar doom-version "2.0.0"
|
||||||
;;
|
|
||||||
|
|
||||||
(defconst doom-version "1.3.1"
|
|
||||||
"Current version of DOOM emacs")
|
"Current version of DOOM emacs")
|
||||||
|
|
||||||
(defconst doom-emacs-dir
|
(defvar doom-emacs-dir user-emacs-directory
|
||||||
(expand-file-name user-emacs-directory)
|
|
||||||
"The path to this emacs.d directory")
|
"The path to this emacs.d directory")
|
||||||
|
|
||||||
(defconst doom-core-dir
|
(defvar doom-core-dir (concat doom-emacs-dir "core/")
|
||||||
(expand-file-name "core" doom-emacs-dir)
|
|
||||||
"Where essential files are stored")
|
"Where essential files are stored")
|
||||||
|
|
||||||
(defconst doom-modules-dir
|
(defvar doom-modules-dir (concat doom-emacs-dir "modules/")
|
||||||
(expand-file-name "modules" doom-emacs-dir)
|
|
||||||
"Where configuration modules are stored")
|
"Where configuration modules are stored")
|
||||||
|
|
||||||
(defconst doom-private-dir
|
(defvar doom-private-dir (concat doom-emacs-dir "private/")
|
||||||
(expand-file-name "private" doom-emacs-dir)
|
|
||||||
"Where private configuration filse and assets are stored (like snippets)")
|
"Where private configuration filse and assets are stored (like snippets)")
|
||||||
|
|
||||||
(defconst doom-packages-dir
|
(defvar doom-scripts-dir (concat doom-emacs-dir "scripts/")
|
||||||
(expand-file-name
|
|
||||||
(format ".cask/%s.%s/elpa" emacs-major-version emacs-minor-version)
|
|
||||||
doom-emacs-dir)
|
|
||||||
"Where plugins are installed (by cask)")
|
|
||||||
|
|
||||||
(defconst doom-ext-dir
|
|
||||||
(expand-file-name "ext" doom-emacs-dir)
|
|
||||||
"Where external dependencies are stored (like libraries or binaries)")
|
"Where external dependencies are stored (like libraries or binaries)")
|
||||||
|
|
||||||
(defconst doom-themes-dir
|
(defvar doom-packages-dir (concat doom-private-dir "packages/")
|
||||||
(expand-file-name "themes" doom-private-dir)
|
"Where package.el and quelpa plugins (and their caches) are kept.")
|
||||||
|
|
||||||
|
(defvar doom-themes-dir (concat doom-private-dir "themes/")
|
||||||
"Where theme files and subfolders go")
|
"Where theme files and subfolders go")
|
||||||
|
|
||||||
(defconst doom-temp-dir
|
(defvar doom-temp-dir
|
||||||
(format "%s/cache/%s" doom-private-dir (system-name))
|
(concat doom-private-dir "cache/" (system-name) "/")
|
||||||
"Hostname-based elisp temp directories")
|
"Hostname-based elisp temp directories")
|
||||||
|
|
||||||
(defconst doom-org-dir
|
(defvar doom-org-dir "~/org/"
|
||||||
(expand-file-name "~/org")
|
|
||||||
"Where to find org notes")
|
"Where to find org notes")
|
||||||
|
|
||||||
;; window-system is deprecated. Not on my watch!
|
|
||||||
(unless (boundp 'window-system)
|
|
||||||
(defvar window-system (framep-on-display)))
|
|
||||||
|
|
||||||
;;
|
|
||||||
(defconst doom-leader "," "Prefix for <leader> bindings")
|
|
||||||
(defconst doom-localleader "\\" "Prefix for <localleader> bindings")
|
|
||||||
|
|
||||||
(defvar doom-unreal-buffers
|
|
||||||
'("^ ?\\*.+" image-mode dired-mode reb-mode messages-buffer-mode
|
|
||||||
tabulated-list-mode comint-mode magit-mode)
|
|
||||||
"A list of regexps or modes whose buffers are considered unreal, and will be
|
|
||||||
ignored when using `doom:next-real-buffer' and `doom:previous-real-buffer' (or
|
|
||||||
killed by `doom/kill-unreal-buffers', or after `doom/kill-real-buffer').")
|
|
||||||
|
|
||||||
(defvar doom-cleanup-processes-alist
|
|
||||||
'(("pry" . ruby-mode)
|
|
||||||
("irb" . ruby-mode)
|
|
||||||
("ipython" . python-mode))
|
|
||||||
"An alist of (process-name . major-mode) that `doom/kill-process-buffers'
|
|
||||||
checks before killing processes. If there are no buffers with matching
|
|
||||||
major-modes, the process gets killed.")
|
|
||||||
|
|
||||||
(defvar doom-unicode-font
|
|
||||||
(font-spec :family "DejaVu Sans Mono" :size 12)
|
|
||||||
"Fallback font for unicode glyphs.")
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Core configuration
|
|
||||||
;;
|
|
||||||
|
|
||||||
|
;;;
|
||||||
;; UTF-8 as the default coding system, please
|
;; UTF-8 as the default coding system, please
|
||||||
(set-charset-priority 'unicode) ; pretty
|
(set-charset-priority 'unicode) ; pretty
|
||||||
(prefer-coding-system 'utf-8) ; pretty
|
(prefer-coding-system 'utf-8) ; pretty
|
||||||
|
@ -101,93 +58,35 @@ major-modes, the process gets killed.")
|
||||||
(set-keyboard-coding-system 'utf-8) ; perdy
|
(set-keyboard-coding-system 'utf-8) ; perdy
|
||||||
(set-selection-coding-system 'utf-8) ; please
|
(set-selection-coding-system 'utf-8) ; please
|
||||||
(setq locale-coding-system 'utf-8) ; with sugar on top
|
(setq locale-coding-system 'utf-8) ; with sugar on top
|
||||||
|
(setq-default buffer-file-coding-system 'utf-8)
|
||||||
|
|
||||||
;; default-buffer-file-coding-system is deprecated on 23.2
|
;; Configuration
|
||||||
(if (boundp 'buffer-file-coding-system)
|
(setq ad-redefinition-accept 'accept ; silence advised function warnings
|
||||||
(setq-default buffer-file-coding-system 'utf-8)
|
apropos-do-all t ; make `apropos' more useful
|
||||||
(setq default-buffer-file-coding-system 'utf-8))
|
byte-compile-warnings nil
|
||||||
|
compilation-always-kill t
|
||||||
;; Don't pester me package.el. Cask is my one and only.
|
compilation-ask-about-save nil
|
||||||
(setq-default
|
compilation-scroll-output t
|
||||||
package--init-file-ensured t
|
|
||||||
package-user-dir doom-packages-dir
|
|
||||||
package-enable-at-startup nil
|
|
||||||
package-archives
|
|
||||||
'(("gnu" . "http://elpa.gnu.org/packages/")
|
|
||||||
("melpa" . "http://melpa.org/packages/")
|
|
||||||
("org" . "http://orgmode.org/elpa/")))
|
|
||||||
|
|
||||||
;; Core settings
|
|
||||||
(setq ad-redefinition-action 'accept ; silence the advised function warnings
|
|
||||||
apropos-do-all t ; make `apropos' more useful
|
|
||||||
byte-compile-warnings nil
|
|
||||||
compilation-always-kill t ; kill compl. process before spawning another
|
|
||||||
compilation-ask-about-save nil ; save all buffers before compiling
|
|
||||||
compilation-scroll-output t ; scroll with output while compiling
|
|
||||||
confirm-nonexistent-file-or-buffer t
|
confirm-nonexistent-file-or-buffer t
|
||||||
delete-by-moving-to-trash t
|
enable-recursive-minibuffers nil
|
||||||
echo-keystrokes 0.02 ; show me what I type
|
idle-update-delay 5
|
||||||
enable-recursive-minibuffers nil ; no minibufferception
|
minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)
|
||||||
idle-update-delay 5 ; update a little less often
|
save-interprogram-paste-before-kill nil)
|
||||||
major-mode 'text-mode
|
|
||||||
save-interprogram-paste-before-kill nil
|
;; History & backup settings
|
||||||
sentence-end-double-space nil
|
(setq auto-save-default nil
|
||||||
;; http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html
|
auto-save-list-file-name (concat doom-temp-dir "/autosave")
|
||||||
minibuffer-prompt-properties
|
backup-directory-alist (list (cons ".*" (concat doom-temp-dir "/backup/")))
|
||||||
'(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)
|
create-lockfiles nil
|
||||||
;; persistent bookmarks
|
history-length 1000
|
||||||
bookmark-save-flag t
|
make-backup-files nil
|
||||||
bookmark-default-file (concat doom-temp-dir "/bookmarks")
|
vc-make-backup-files nil)
|
||||||
;; Disable backups (that's what git/dropbox are for)
|
|
||||||
history-length 1000
|
|
||||||
vc-make-backup-files nil
|
|
||||||
auto-save-default nil
|
|
||||||
auto-save-list-file-name (concat doom-temp-dir "/autosave")
|
|
||||||
make-backup-files nil
|
|
||||||
create-lockfiles nil
|
|
||||||
backup-directory-alist `((".*" . ,(concat doom-temp-dir "/backup/")))
|
|
||||||
;; Remember undo history
|
|
||||||
undo-tree-auto-save-history nil
|
|
||||||
undo-tree-history-directory-alist `(("." . ,(concat doom-temp-dir "/undo/"))))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;;
|
||||||
;; Bootstrap
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defvar doom--load-path load-path
|
|
||||||
"Initial `load-path', used as a base so we don't clobber it on consecutive
|
|
||||||
reloads.")
|
|
||||||
|
|
||||||
(defvar doom-packages '()
|
|
||||||
"A list of all installed packages. Filled internally; do not edit it!")
|
|
||||||
|
|
||||||
;; Just the bear necessities... ♫
|
|
||||||
(setq load-path (append (list doom-core-dir) doom--load-path))
|
|
||||||
|
|
||||||
;; Populate load-path manually. This way, cask (and `cask-initialize') won't be
|
|
||||||
;; an internal dependency -- they slow down startup a lot!
|
|
||||||
(require 'core-defuns)
|
|
||||||
(let ((paths (eval-when-compile (doom-reload))))
|
|
||||||
(setq load-path (car paths)
|
|
||||||
custom-theme-load-path (nth 1 paths)
|
|
||||||
doom-packages (nth 2 paths)))
|
|
||||||
|
|
||||||
;; Many functions are lazy-loaded. The autoloads.el file contains info on where
|
|
||||||
;; to find them if they're called. Tries to generate autoloads.el if one isn't
|
|
||||||
;; found.
|
|
||||||
(unless (require 'autoloads nil t)
|
|
||||||
(doom-reload-autoloads)
|
|
||||||
(unless (require 'autoloads nil t)
|
|
||||||
(error "Autoloads weren't generated! Run `make autoloads`")))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Automatic minor modes
|
;; Automatic minor modes
|
||||||
;;
|
|
||||||
|
|
||||||
(defvar doom-auto-minor-mode-alist '()
|
(defvar doom-auto-minor-mode-alist '()
|
||||||
"Alist of filename patterns vs corresponding minor mode functions, see
|
"Alist mapping filename patterns to corresponding minor mode functions, like
|
||||||
`auto-mode-alist'. All elements of this alist are checked, meaning you can
|
`auto-mode-alist'. All elements of this alist are checked, meaning you can
|
||||||
enable multiple minor modes for the same regexp.")
|
enable multiple minor modes for the same regexp.")
|
||||||
|
|
||||||
|
@ -211,37 +110,105 @@ enable multiple minor modes for the same regexp.")
|
||||||
(add-hook 'find-file-hook 'doom|enable-minor-mode-maybe)
|
(add-hook 'find-file-hook 'doom|enable-minor-mode-maybe)
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;; Bootstrap
|
||||||
|
(setq gc-cons-threshold 339430400
|
||||||
|
gc-cons-percentage 0.6)
|
||||||
|
|
||||||
|
(let (file-name-handler-list)
|
||||||
|
(eval-and-compile
|
||||||
|
(load (concat doom-core-dir "core-packages") nil t))
|
||||||
|
(eval-when-compile
|
||||||
|
;; Ensure cache folder exists
|
||||||
|
(unless (file-exists-p doom-temp-dir)
|
||||||
|
(make-directory doom-temp-dir t))
|
||||||
|
(doom-package-init))
|
||||||
|
|
||||||
|
(setq load-path (eval-when-compile load-path)
|
||||||
|
custom-theme-load-path (append (list doom-themes-dir) custom-theme-load-path))
|
||||||
|
|
||||||
|
;;; Essential packages
|
||||||
|
(require 'core-lib)
|
||||||
|
(package! dash :demand t)
|
||||||
|
(package! s :demand t)
|
||||||
|
(package! f :demand t)
|
||||||
|
|
||||||
|
;;; Helper packages (autoloaded)
|
||||||
|
(package! async
|
||||||
|
:commands (async-start
|
||||||
|
async-start-process
|
||||||
|
async-byte-recompile-directory))
|
||||||
|
|
||||||
|
(package! persistent-soft
|
||||||
|
:commands (persistent-soft-exists-p
|
||||||
|
persistent-soft-fetch
|
||||||
|
persistent-soft-flush
|
||||||
|
persistent-soft-store)
|
||||||
|
:init (defvar pcache-directory (concat doom-temp-dir "/pcache/")))
|
||||||
|
|
||||||
|
(package! smex :commands smex)
|
||||||
|
|
||||||
|
;;; Let 'er rip! (order matters!)
|
||||||
|
;; (require 'core-settings) ; configuration management system
|
||||||
|
;; (require 'core-popups) ; taming sudden yet inevitable windows
|
||||||
|
(require 'core-evil) ; come to the dark side, we have cookies
|
||||||
|
;; (require 'core-project)
|
||||||
|
;; (require 'core-os)
|
||||||
|
;; (require 'core-ui)
|
||||||
|
;; (require 'core-modeline)
|
||||||
|
;; (require 'core-editor)
|
||||||
|
;; (require 'core-completion)
|
||||||
|
;; (require 'core-syntax-checking)
|
||||||
|
;; (require 'core-snippets)
|
||||||
|
;; (require 'core-repl)
|
||||||
|
;; (require 'core-sessions)
|
||||||
|
;; (require 'core-workspaces)
|
||||||
|
;; (require 'core-vcs)
|
||||||
|
;; (require 'core-dashboard)
|
||||||
|
|
||||||
|
(unless (require 'autoloads nil t)
|
||||||
|
(doom/refresh-autoloads t)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
;;
|
;;
|
||||||
;; Essential plugins
|
(defmacro doom! (&rest packages)
|
||||||
;;
|
(let (paths)
|
||||||
|
(dolist (p packages)
|
||||||
|
(if (memq p '(:apps :emacs :lang :lib :private :ui))
|
||||||
|
(setq mode p)
|
||||||
|
(unless mode
|
||||||
|
(error "No namespace specified on `doom!' for %s" p))
|
||||||
|
(pushnew (format "%s%s/%s/" doom-modules-dir (substring (symbol-name mode) 1) (symbol-name p))
|
||||||
|
paths)))
|
||||||
|
|
||||||
(require 'dash)
|
`(let (file-name-handler-alist)
|
||||||
(require 's)
|
(unless noninteractive
|
||||||
(require 'f)
|
(load "~/.emacs.local.el" t t))
|
||||||
|
|
||||||
(autoload 'use-package "use-package" "" nil 'macro)
|
(with-demoted-errors "ERROR: %s"
|
||||||
|
,@(mapcar
|
||||||
|
(lambda (path)
|
||||||
|
(macroexp-progn
|
||||||
|
(mapcar (lambda (file)
|
||||||
|
(when noninteractive (setq file (file-name-sans-extension file)))
|
||||||
|
`(load ,(expand-file-name file path) t t (not noninteractive)))
|
||||||
|
(append (list "packages.el")
|
||||||
|
(unless noninteractive (list "config.el"))))))
|
||||||
|
paths))
|
||||||
|
|
||||||
(use-package anaphora
|
(unless noninteractive
|
||||||
:commands (awhen aif acond awhile))
|
(require 'my-bindings)
|
||||||
|
(require 'my-commands)
|
||||||
|
|
||||||
(use-package persistent-soft
|
(when (display-graphic-p)
|
||||||
:commands (persistent-soft-store
|
(require 'server)
|
||||||
persistent-soft-fetch
|
(unless (server-running-p)
|
||||||
persistent-soft-exists-p
|
(server-start)))
|
||||||
persistent-soft-flush
|
|
||||||
persistent-soft-location-readable
|
|
||||||
persistent-soft-location-destroy)
|
|
||||||
:init (defvar pcache-directory (concat doom-temp-dir "/pcache/")))
|
|
||||||
|
|
||||||
(use-package async
|
;; Prevent any auto-displayed text + benchmarking
|
||||||
:commands (async-start
|
(advice-add 'display-startup-echo-area-message :override 'ignore)
|
||||||
async-start-process
|
(message "")))))
|
||||||
async-get
|
|
||||||
async-wait
|
|
||||||
async-inject-variables))
|
|
||||||
|
|
||||||
(use-package json
|
|
||||||
:commands (json-read-from-string json-encode json-read-file))
|
|
||||||
|
|
||||||
(provide 'core)
|
(provide 'core)
|
||||||
;;; core.el ends here
|
;;; core.el ends here
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
;;; defuns-auto-insert.el
|
|
||||||
;; for ../core-auto-insert.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/auto-insert-snippet (key &optional mode project-only)
|
|
||||||
"Auto insert a snippet of yasnippet into new file."
|
|
||||||
(interactive)
|
|
||||||
(when (if project-only (doom/project-p) t)
|
|
||||||
(let ((is-yasnippet-on (not (cond ((functionp yas-dont-activate)
|
|
||||||
(funcall yas-dont-activate))
|
|
||||||
((consp yas-dont-activate)
|
|
||||||
(some #'funcall yas-dont-activate))
|
|
||||||
(yas-dont-activate))))
|
|
||||||
(snippet (let ((template (cdar (mapcan #'(lambda (table) (yas--fetch table key))
|
|
||||||
(yas--get-snippet-tables mode)))))
|
|
||||||
(if template (yas--template-content template) nil))))
|
|
||||||
(when (and is-yasnippet-on snippet)
|
|
||||||
(yas-expand-snippet snippet)
|
|
||||||
(when (and (featurep 'evil) evil-mode)
|
|
||||||
(evil-initialize-state 'insert))))))
|
|
||||||
|
|
||||||
(provide 'defuns-auto-insert)
|
|
||||||
;;; defuns-auto-insert.el ends here
|
|
|
@ -1,330 +0,0 @@
|
||||||
;;; defuns-buffers.el
|
|
||||||
|
|
||||||
(defvar doom-buffer)
|
|
||||||
(defvar-local doom--narrowed-origin nil)
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:narrow "defuns-buffers" nil t)
|
|
||||||
(evil-define-operator doom:narrow (&optional beg end bang)
|
|
||||||
"Restrict editing in this buffer to the current region, indirectly. With BANG,
|
|
||||||
clone the buffer and hard-narrow the selection. If mark isn't active, then widen
|
|
||||||
the buffer (if narrowed).
|
|
||||||
|
|
||||||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
|
||||||
(interactive "<r><!>")
|
|
||||||
(if (region-active-p)
|
|
||||||
(progn
|
|
||||||
(deactivate-mark)
|
|
||||||
(when bang
|
|
||||||
(let ((old-buf (current-buffer)))
|
|
||||||
(switch-to-buffer (clone-indirect-buffer nil nil))
|
|
||||||
(setq doom--narrowed-origin old-buf)))
|
|
||||||
(narrow-to-region beg end))
|
|
||||||
(if doom--narrowed-origin
|
|
||||||
(progn
|
|
||||||
(kill-this-buffer)
|
|
||||||
(switch-to-buffer doom--narrowed-origin)
|
|
||||||
(setq doom--narrowed-origin nil))
|
|
||||||
(widen))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/set-read-only-region (begin end)
|
|
||||||
"Mark a region as read-only (http://stackoverflow.com/questions/7410125)"
|
|
||||||
(let ((modified (buffer-modified-p)))
|
|
||||||
(add-text-properties begin end '(read-only t))
|
|
||||||
(set-buffer-modified-p modified)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/set-region-writeable (begin end)
|
|
||||||
"Undoes `doom/set-read-only-region' (http://stackoverflow.com/questions/7410125)"
|
|
||||||
(let ((modified (buffer-modified-p))
|
|
||||||
(inhibit-read-only t))
|
|
||||||
(remove-text-properties begin end '(read-only t))
|
|
||||||
(set-buffer-modified-p modified)))
|
|
||||||
|
|
||||||
|
|
||||||
;; Buffer Life and Death ;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-buffers (&optional all-p)
|
|
||||||
"Get all buffers in the current project, in the current workgroup.
|
|
||||||
|
|
||||||
If ALL-P is non-nil, get all buffers across all projects in current
|
|
||||||
workgroup."
|
|
||||||
(let ((buffers (if (wg-current-workgroup t)
|
|
||||||
(doom/get-buffers-in-workgroup)
|
|
||||||
(buffer-list)))
|
|
||||||
(project-root (and (not all-p) (doom/project-root t))))
|
|
||||||
(append (if project-root
|
|
||||||
(funcall (if (eq all-p 'not) '-remove '-filter)
|
|
||||||
(lambda (b) (projectile-project-buffer-p b project-root))
|
|
||||||
buffers)
|
|
||||||
buffers)
|
|
||||||
(list doom-buffer))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-buffers-in-workgroup ()
|
|
||||||
"Get a list of buffers in current workgroup. Returns nil if workgroups2 isn't
|
|
||||||
loaded."
|
|
||||||
(when (featurep 'workgroups2)
|
|
||||||
(let ((assoc-bufs (wg-workgroup-associated-buffers nil)))
|
|
||||||
(--filter (memq it assoc-bufs) (buffer-list)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-buffer-names (&optional buffer-list)
|
|
||||||
"Get a list of names of buffers in the current workgroup, OR return the names
|
|
||||||
of the buffers in BUFFER-LIST."
|
|
||||||
(mapcar #'buffer-name (or buffer-list (doom/get-buffers))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-visible-windows (&optional window-list)
|
|
||||||
"Get a list of the visible windows in the current frame (that aren't popups),
|
|
||||||
OR return only the visible windows in WINDOW-LIST."
|
|
||||||
(-remove #'doom/popup-p (or window-list (window-list))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-visible-buffers (&optional buffer-list)
|
|
||||||
"Get a list of unburied buffers in the current project and workgroup, OR
|
|
||||||
return only the unburied buffers in BUFFER-LIST (a list of BUFFER-OR-NAMEs)."
|
|
||||||
(-filter #'get-buffer-window (or buffer-list (doom/get-buffers))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-buried-buffers (&optional buffer-list)
|
|
||||||
"Get a list of buried buffers in the current project and workgroup, OR return
|
|
||||||
only the buried buffers in BUFFER-LIST (a list of BUFFER-OR-NAMEs)."
|
|
||||||
(-remove 'get-buffer-window (or buffer-list (doom/get-buffers))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-matching-buffers (pattern &optional buffer-list)
|
|
||||||
"Get a list of all buffers (in the current workgroup OR in BUFFER-LIST) that
|
|
||||||
match the regex PATTERN."
|
|
||||||
(--filter (string-match-p pattern (buffer-name it))
|
|
||||||
(or buffer-list (doom/get-buffers))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-buffers-in-modes (modes &optional buffer-list)
|
|
||||||
"Get a list of all buffers (in the current workgroup OR in BUFFER-LIST) whose
|
|
||||||
`major-mode' is one of MODES."
|
|
||||||
(--filter (memq (buffer-local-value 'major-mode it) modes)
|
|
||||||
(or buffer-list (doom/get-buffers))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/get-real-buffers (&optional buffer-list)
|
|
||||||
"Get a list of all buffers (in the current workgroup OR in BUFFER-LIST) that
|
|
||||||
`doom/real-buffer-p' returns non-nil for."
|
|
||||||
(-filter #'doom/real-buffer-p (or buffer-list (doom/get-buffers))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/kill-real-buffer (&optional arg)
|
|
||||||
"Kill buffer then switch to a real buffer. Only buries the buffer if it is
|
|
||||||
being displayed in another window.
|
|
||||||
|
|
||||||
NOTE: only buries scratch buffer.
|
|
||||||
|
|
||||||
See `doom/real-buffer-p' for what 'real' means."
|
|
||||||
(interactive (list t))
|
|
||||||
(let* ((scratch-p (doom-scratch-buffer-p))
|
|
||||||
(old-project (doom/project-root))
|
|
||||||
(buffer (current-buffer))
|
|
||||||
(only-buffer-window-p (= (length (get-buffer-window-list buffer nil t)) 1)))
|
|
||||||
(unless scratch-p
|
|
||||||
(when (and buffer-file-name only-buffer-window-p (buffer-modified-p))
|
|
||||||
(if (yes-or-no-p "Buffer is unsaved, save it?")
|
|
||||||
(save-buffer)
|
|
||||||
(set-buffer-modified-p nil)))
|
|
||||||
(when arg
|
|
||||||
(doom/previous-real-buffer)
|
|
||||||
(unless (eq (current-buffer) buffer)
|
|
||||||
(when only-buffer-window-p
|
|
||||||
(kill-buffer buffer)
|
|
||||||
(unless (doom/real-buffer-p)
|
|
||||||
(doom/previous-real-buffer)))))))
|
|
||||||
(when (doom-scratch-buffer-p)
|
|
||||||
(doom-scratch-force-reload))
|
|
||||||
t)
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/kill-unreal-buffers ()
|
|
||||||
"Kill all buried buffers in current frame that match any of the rules in
|
|
||||||
`doom-unreal-buffers'."
|
|
||||||
(interactive)
|
|
||||||
(let ((kill-list (-remove 'doom/real-buffer-p
|
|
||||||
(doom/get-buried-buffers (buffer-list)))))
|
|
||||||
(mapc 'kill-buffer kill-list)
|
|
||||||
(doom/kill-process-buffers)
|
|
||||||
(message "Cleaned up %s buffers" (length kill-list))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/kill-process-buffers ()
|
|
||||||
"Kill all buried buffers that represent running processes."
|
|
||||||
(interactive)
|
|
||||||
(let ((buffer-list (buffer-list))
|
|
||||||
(killed-processes 0))
|
|
||||||
(dolist (p (process-list))
|
|
||||||
(let* ((process-name (process-name p))
|
|
||||||
(assoc (assoc process-name doom-cleanup-processes-alist)))
|
|
||||||
(when (and assoc
|
|
||||||
(not (string= process-name "server"))
|
|
||||||
(process-live-p p)
|
|
||||||
(not (--any? (let ((mode (buffer-local-value 'major-mode it)))
|
|
||||||
(eq mode (cdr assoc)))
|
|
||||||
buffer-list)))
|
|
||||||
(delete-process p)
|
|
||||||
(incf killed-processes))))
|
|
||||||
(message "Cleaned up %s processes" killed-processes)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/kill-matching-buffers (pattern &optional buffer-list)
|
|
||||||
"Kill all buffers (in current workgroup OR in BUFFER-LIST) that match the
|
|
||||||
regex PATTERN."
|
|
||||||
(interactive)
|
|
||||||
(let ((i 0))
|
|
||||||
(mapc (lambda (b)
|
|
||||||
(when (string-match-p pattern (buffer-name b))
|
|
||||||
(kill-buffer b)
|
|
||||||
(setq i (1+ i))))
|
|
||||||
(if buffer-list buffer-list (doom/get-buffers)))
|
|
||||||
(message "Killed %s matches" i)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/cycle-real-buffers (&optional n)
|
|
||||||
"Switch to the previous buffer, skipping over special buffers. If there's
|
|
||||||
nothing left, create a scratch buffer."
|
|
||||||
(let* ((start-buffer (current-buffer))
|
|
||||||
(move-func (if (> n 0) 'switch-to-next-buffer 'switch-to-prev-buffer))
|
|
||||||
(max 25)
|
|
||||||
(i 0)
|
|
||||||
(continue t)
|
|
||||||
(buffers (doom/get-real-buffers (doom/get-buffers t)))
|
|
||||||
(fail-buffer (if (> (length (get-buffer-window-list doom-buffer nil t)) 1)
|
|
||||||
start-buffer
|
|
||||||
doom-buffer))
|
|
||||||
destbuf)
|
|
||||||
(setq destbuf
|
|
||||||
(catch 'goto
|
|
||||||
(if (or (not buffers)
|
|
||||||
(= (length buffers) 1))
|
|
||||||
(progn (message "No other buffers in workgroup")
|
|
||||||
(throw 'goto fail-buffer))
|
|
||||||
(funcall move-func)
|
|
||||||
(while (not (memq (current-buffer) buffers))
|
|
||||||
(if (or (eq (current-buffer) start-buffer)
|
|
||||||
(>= i max))
|
|
||||||
(throw 'goto fail-buffer)
|
|
||||||
(funcall move-func))
|
|
||||||
(cl-incf i))
|
|
||||||
(current-buffer))))
|
|
||||||
(when (eq destbuf doom-buffer)
|
|
||||||
(doom-scratch-reload)
|
|
||||||
(message "Nowhere to go"))
|
|
||||||
(switch-to-buffer destbuf)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/real-buffer-p (&optional buffer)
|
|
||||||
"Returns whether BUFFER a 'real' buffer or not. Real means: a) it isn't a
|
|
||||||
popup (or temporary) window and b) it isn't a special buffer (e.g. scratch or
|
|
||||||
*messages* buffer)."
|
|
||||||
(setq buffer (or (and (bufferp buffer) buffer)
|
|
||||||
(and (stringp buffer) (get-buffer buffer))
|
|
||||||
(current-buffer)))
|
|
||||||
(when (buffer-live-p buffer)
|
|
||||||
(with-current-buffer buffer
|
|
||||||
(not (or (apply #'derived-mode-p (-filter 'symbolp doom-unreal-buffers))
|
|
||||||
(--any? (string-match-p it (buffer-name buffer))
|
|
||||||
(-filter 'stringp doom-unreal-buffers)))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/next-real-buffer ()
|
|
||||||
"Switch to the next real buffer, skipping special buffers. See
|
|
||||||
`doom/real-buffer-p'."
|
|
||||||
(interactive)
|
|
||||||
(doom/cycle-real-buffers +1))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/previous-real-buffer ()
|
|
||||||
"Switch to the previous real buffer, skipping special buffers. See
|
|
||||||
`doom/real-buffer-p'."
|
|
||||||
(interactive)
|
|
||||||
(doom/cycle-real-buffers -1))
|
|
||||||
|
|
||||||
(defun doom--kill-buffers (buffers &optional filter-func)
|
|
||||||
(let ((buffers (if filter-func (-filter filter-func buffers) buffers))
|
|
||||||
(affected 0))
|
|
||||||
(mapc (lambda (b) (when (kill-buffer b) (incf affected))) buffers)
|
|
||||||
(unless (doom/real-buffer-p)
|
|
||||||
(doom/previous-real-buffer))
|
|
||||||
(message "Killed %s buffers" affected)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:kill-all-buffers "defuns-buffers" nil t)
|
|
||||||
(evil-define-command doom:kill-all-buffers (&optional bang)
|
|
||||||
"Kill all project buffers. If BANG, kill *all* buffers (in workgroup)."
|
|
||||||
(interactive "<!>")
|
|
||||||
(doom--kill-buffers (--filter (not (eq it doom-buffer))
|
|
||||||
(doom/get-buffers (not bang))))
|
|
||||||
(delete-other-windows)
|
|
||||||
(switch-to-buffer doom-buffer))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:kill-other-buffers "defuns-buffers" nil t)
|
|
||||||
(evil-define-command doom:kill-other-buffers (&optional bang)
|
|
||||||
"Kill all other project buffers. If BANG, kill *all* other buffers (in workgroup)."
|
|
||||||
(interactive "<!>")
|
|
||||||
(doom--kill-buffers (doom/get-buffers (not bang))
|
|
||||||
(lambda (b) (not (eq b (current-buffer)))))
|
|
||||||
(when bang
|
|
||||||
(delete-other-windows)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:kill-buried-buffers "defuns-buffers" nil t)
|
|
||||||
(evil-define-command doom:kill-buried-buffers (&optional bang)
|
|
||||||
"Kill buried project buffers in current workgroup and report how many it
|
|
||||||
found. If BANG, then include buffers that aren't part of the current project."
|
|
||||||
(interactive "<!>")
|
|
||||||
(doom--kill-buffers (doom/get-buried-buffers (doom/get-buffers (not bang)))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:kill-buried-buffers "defuns-buffers" nil t)
|
|
||||||
(evil-define-command doom:kill-matching-buffers (&optional bang pattern)
|
|
||||||
"Kill project buffers in current workgroup that match regex PATTERN. If BANG,
|
|
||||||
then include buffers that aren't part of the current project."
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(doom--kill-buffers (doom/get-matching-buffers pattern (doom/get-buffers (not bang)))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:scratch-buffer "defuns-buffers" nil t)
|
|
||||||
(evil-define-operator doom:scratch-buffer (&optional beg end bang)
|
|
||||||
"Send a region to and pop up the scratch buffer. If BANG, don't use a popup
|
|
||||||
(use the current window)."
|
|
||||||
:move-point nil
|
|
||||||
:type inclusive
|
|
||||||
(interactive "<r><!>")
|
|
||||||
(let ((text (when (and (evil-visual-state-p) beg end)
|
|
||||||
(buffer-substring beg end)))
|
|
||||||
(mode major-mode)
|
|
||||||
(old-project (doom/project-root))
|
|
||||||
(new-buf (get-buffer-create "*doom:scratch*")))
|
|
||||||
(with-current-buffer new-buf
|
|
||||||
(setq default-directory old-project)
|
|
||||||
(setq mode-line-format (doom-modeline))
|
|
||||||
(when (and (not (eq major-mode mode))
|
|
||||||
(functionp mode))
|
|
||||||
(funcall mode))
|
|
||||||
(if text (insert text)))
|
|
||||||
(if bang (switch-to-buffer new-buf) (doom/popup-buffer new-buf))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:cd "defuns-buffers" nil t)
|
|
||||||
(evil-define-command doom:cd (dir)
|
|
||||||
"Change the `default-directory' to DIR (alias for `cd')"
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<f>")
|
|
||||||
(cd (if (zerop (length dir)) "~" dir)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/kill-workgroup-and-quit ()
|
|
||||||
"Wipe the current workgroup session and save the blank slate."
|
|
||||||
(interactive)
|
|
||||||
(let (confirm-kill-emacs)
|
|
||||||
(mapc 'kill-buffer (doom/get-buffers t))
|
|
||||||
(kill-this-buffer)
|
|
||||||
(delete-other-windows)
|
|
||||||
(wg-save-session t)
|
|
||||||
(save-buffers-kill-terminal)))
|
|
||||||
|
|
||||||
(provide 'defuns-buffers)
|
|
||||||
;;; defuns-buffers.el ends here
|
|
|
@ -1,70 +0,0 @@
|
||||||
;;; defuns-company.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/company-evil-complete-next (&optional arg)
|
|
||||||
"dabbrev wrapper for `evil-complete-next'"
|
|
||||||
(call-interactively 'company-dabbrev)
|
|
||||||
(if (eq company-candidates-length 1)
|
|
||||||
(company-complete)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/company-evil-complete-previous (&optional arg)
|
|
||||||
"dabbrev wrapper for `evil-complete-previous'"
|
|
||||||
(let ((company-selection-wrap-around t))
|
|
||||||
(call-interactively 'company-dabbrev)
|
|
||||||
(if (eq company-candidates-length 1)
|
|
||||||
(company-complete)
|
|
||||||
(call-interactively 'company-select-previous))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/company-complete-common-or-complete-full ()
|
|
||||||
(interactive)
|
|
||||||
(when (company-manual-begin)
|
|
||||||
(if (eq last-command #'company-complete-common-or-cycle)
|
|
||||||
(let ((company-selection-wrap-around t))
|
|
||||||
(call-interactively #'company-complete-selection))
|
|
||||||
(let ((buffer-mod-tick (buffer-chars-modified-tick)))
|
|
||||||
(call-interactively #'company-complete-common)
|
|
||||||
(when (= buffer-mod-tick (buffer-chars-modified-tick))
|
|
||||||
(call-interactively #'company-complete-selection)
|
|
||||||
(call-interactively #'company-complete))))))
|
|
||||||
|
|
||||||
(defun doom--company-whole-lines ()
|
|
||||||
(split-string
|
|
||||||
(replace-regexp-in-string
|
|
||||||
"^[\t\s]+" ""
|
|
||||||
(concat (buffer-substring-no-properties (point-min) (line-beginning-position))
|
|
||||||
(buffer-substring-no-properties (line-end-position) (point-max))))
|
|
||||||
"\\(\r\n\\|[\n\r]\\)" t))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/company-whole-lines (command &optional arg &rest ignored)
|
|
||||||
"`company-mode' completion backend that completes whole-lines, akin to vim's
|
|
||||||
C-x C-l."
|
|
||||||
(interactive (list 'interactive))
|
|
||||||
(require 'company)
|
|
||||||
(unless (bound-and-true-p company-mode) (company-mode))
|
|
||||||
(let ((lines (doom--company-whole-lines)))
|
|
||||||
(cl-case command
|
|
||||||
(interactive (company-begin-backend 'doom/company-whole-lines))
|
|
||||||
(prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
|
|
||||||
(candidates (all-completions arg lines)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/company-dict-or-keywords ()
|
|
||||||
(interactive)
|
|
||||||
(let ((company-backends '((company-keywords company-dict))))
|
|
||||||
(call-interactively 'company-complete)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/company-complete ()
|
|
||||||
"Bring up the completion popup. If only one result, complete it."
|
|
||||||
(interactive)
|
|
||||||
(require 'company)
|
|
||||||
(unless (bound-and-true-p company-mode) (company-mode))
|
|
||||||
(when (and (company-manual-begin)
|
|
||||||
(= company-candidates-length 1))
|
|
||||||
(company-complete-common)))
|
|
||||||
|
|
||||||
(provide 'defuns-company)
|
|
||||||
;;; defuns-company.el ends here
|
|
|
@ -1,31 +0,0 @@
|
||||||
;;; defuns-docs.el
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:docs-lookup "defuns-docs" nil t)
|
|
||||||
(evil-define-command doom:docs-lookup (&optional bang input)
|
|
||||||
"Look up INPUT (otherwise the current selection) in Dash or Zeal."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(let ((query input))
|
|
||||||
(when (evil-visual-state-p)
|
|
||||||
(setq query (concat (buffer-substring-no-properties (region-beginning) (region-end))
|
|
||||||
" " query)))
|
|
||||||
(when (or (not query) (zerop (length query)))
|
|
||||||
(setq query (thing-at-point 'symbol)))
|
|
||||||
(doom-docs-lookup query bang)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:google-search "defuns-docs" nil t)
|
|
||||||
(evil-define-command doom:google-search (&optional bang search)
|
|
||||||
"Opens a browser and performs the entered google search. If BANG, use 'I'm
|
|
||||||
feeling lucky'."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(if search
|
|
||||||
(google-this-parse-and-search-string
|
|
||||||
search nil
|
|
||||||
(if bang (google-this-lucky-search-url)))
|
|
||||||
(cond ((eq major-mode 'c++-mode)
|
|
||||||
(google-this-cpp-reference))
|
|
||||||
((evil-visual-state-p)
|
|
||||||
(google-this-region nil))
|
|
||||||
(t (google-this-symbol nil)))))
|
|
||||||
|
|
||||||
(provide 'defuns-docs)
|
|
||||||
;;; defuns-docs.el ends here
|
|
|
@ -1,58 +0,0 @@
|
||||||
;;; defuns-editor.el
|
|
||||||
;; for ../core-editor.el
|
|
||||||
|
|
||||||
(defvar *linum-mdown-line* nil)
|
|
||||||
|
|
||||||
(defun doom--line-at-click ()
|
|
||||||
(save-excursion
|
|
||||||
(let ((click-y (cdr (cdr (mouse-position))))
|
|
||||||
(line-move-visual-store line-move-visual))
|
|
||||||
(setq line-move-visual t)
|
|
||||||
(goto-char (window-start))
|
|
||||||
(next-line (1- click-y))
|
|
||||||
(setq line-move-visual line-move-visual-store)
|
|
||||||
;; If you are using tabbar substitute the next line with
|
|
||||||
;; (line-number-at-pos))))
|
|
||||||
(1+ (line-number-at-pos)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/mouse-drag-line ()
|
|
||||||
(interactive)
|
|
||||||
(goto-line (doom--line-at-click))
|
|
||||||
(set-mark (point))
|
|
||||||
(setq *linum-mdown-line* (line-number-at-pos)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/mouse-select-line ()
|
|
||||||
(interactive)
|
|
||||||
(when *linum-mdown-line*
|
|
||||||
(let (mu-line)
|
|
||||||
(setq mu-line (doom--line-at-click))
|
|
||||||
(goto-line *linum-mdown-line*)
|
|
||||||
(if (> mu-line *linum-mdown-line*)
|
|
||||||
(progn
|
|
||||||
(set-mark (point))
|
|
||||||
(goto-line mu-line)
|
|
||||||
(end-of-line))
|
|
||||||
(set-mark (line-end-position))
|
|
||||||
(goto-line mu-line)
|
|
||||||
(beginning-of-line))
|
|
||||||
(setq *linum-mdown-line* nil))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/reselect-paste ()
|
|
||||||
"Go back into visual mode and reselect the last pasted region."
|
|
||||||
(interactive)
|
|
||||||
(evil-goto-mark ?\[)
|
|
||||||
(evil-visual-state)
|
|
||||||
(evil-goto-mark ?\]))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/delete-forward-word ()
|
|
||||||
"Delete the word in front of the cursor."
|
|
||||||
(interactive)
|
|
||||||
(evil-forward-word)
|
|
||||||
(evil-delete-backward-word))
|
|
||||||
|
|
||||||
(provide 'defuns-editor)
|
|
||||||
;;; defuns-editor.el ends here
|
|
|
@ -1,35 +0,0 @@
|
||||||
;;; defuns-embrace.el
|
|
||||||
|
|
||||||
(defun doom--embrace-get-pair (char)
|
|
||||||
(acond ((cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist))
|
|
||||||
`(,(car it) . ,(cdr it)))
|
|
||||||
((assoc-default char embrace--pairs-list)
|
|
||||||
(if (functionp (embrace-pair-struct-read-function it))
|
|
||||||
(let ((pair (funcall (embrace-pair-struct-read-function it))))
|
|
||||||
`(,(car pair) . ,(cdr pair)))
|
|
||||||
`(,(embrace-pair-struct-left it) . ,(embrace-pair-struct-right it))))
|
|
||||||
(t `(,char . ,char))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/embrace-escaped ()
|
|
||||||
"Backslash-escaped surround character support for embrace."
|
|
||||||
(let ((char (read-char "\\")))
|
|
||||||
(if (eq char 27)
|
|
||||||
(cons "" "")
|
|
||||||
(let ((pair (doom--embrace-get-pair (string char)))
|
|
||||||
(text (if (sp-point-in-string) "\\\\%s" "\\%s")))
|
|
||||||
(cons (format text (car pair))
|
|
||||||
(format text (cdr pair)))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/embrace-latex ()
|
|
||||||
"LaTeX command support for embrace."
|
|
||||||
(cons (format "\\%s{" (read-string "\\")) "}"))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/embrace-elisp-fn ()
|
|
||||||
"Elisp function support for embrace."
|
|
||||||
(cons (format "(%s " (or (read-string "(") "")) ")"))
|
|
||||||
|
|
||||||
(provide 'defuns-embrace)
|
|
||||||
;;; defuns-embrace.el ends here
|
|
|
@ -1,253 +0,0 @@
|
||||||
;;; defuns-evil.el
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom/evil-open-folds "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom/evil-open-folds (count)
|
|
||||||
"Instead of `evil-open-folds'; accepts COUNT for dictating fold level."
|
|
||||||
(interactive "P")
|
|
||||||
(unless (bound-and-true-p hs-minor-mode)
|
|
||||||
(hs-minor-mode 1))
|
|
||||||
(if count (hs-hide-level count) (evil-open-folds)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom/evil-close-folds "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom/evil-close-folds (count)
|
|
||||||
"Instead of `evil-close-folds'; accepts COUNT for dictating fold level."
|
|
||||||
(interactive "P")
|
|
||||||
(unless (bound-and-true-p hs-minor-mode)
|
|
||||||
(hs-minor-mode 1))
|
|
||||||
(if count (hs-hide-level count) (evil-close-folds)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom/multi-next-line "defuns-evil" nil t)
|
|
||||||
(evil-define-motion doom/multi-next-line (count)
|
|
||||||
"Move down 6 lines."
|
|
||||||
:type line
|
|
||||||
(let ((line-move-visual visual-line-mode))
|
|
||||||
(evil-line-move (* 6 (or count 1)))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom/multi-previous-line "defuns-evil" nil t)
|
|
||||||
(evil-define-motion doom/multi-previous-line (count)
|
|
||||||
"Move up 6 lines."
|
|
||||||
:type line
|
|
||||||
(let ((line-move-visual visual-line-mode))
|
|
||||||
(evil-line-move (- (* 6 (or count 1))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-visual-line-state-p ()
|
|
||||||
"Returns non-nil if in visual-line mode, nil otherwise."
|
|
||||||
(and (evil-visual-state-p)
|
|
||||||
(eq (evil-visual-type) 'line)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*evil-exchange-off ()
|
|
||||||
(when evil-exchange--overlays
|
|
||||||
(evil-exchange-cancel)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom/evil-macro-on-all-lines "defuns-evil" nil t)
|
|
||||||
(evil-define-operator doom/evil-macro-on-all-lines (beg end &optional macro)
|
|
||||||
"Apply macro to each line."
|
|
||||||
:motion nil
|
|
||||||
:move-point nil
|
|
||||||
(interactive "<r><a>")
|
|
||||||
(unless (and beg end)
|
|
||||||
(setq beg (region-beginning)
|
|
||||||
end (region-end)))
|
|
||||||
(evil-ex-normal beg end
|
|
||||||
(concat "@"
|
|
||||||
(single-key-description
|
|
||||||
(or macro (read-char "@-"))))))
|
|
||||||
|
|
||||||
;;; Custom argument handlers
|
|
||||||
(defvar doom-buffer-match-global evil-ex-substitute-global "")
|
|
||||||
(defun doom--evil-ex-match-init (name &optional face update-hook)
|
|
||||||
(with-current-buffer evil-ex-current-buffer
|
|
||||||
(cond
|
|
||||||
((eq flag 'start)
|
|
||||||
(evil-ex-make-hl name
|
|
||||||
:face (or face 'evil-ex-substitute-matches)
|
|
||||||
:update-hook (or update-hook #'evil-ex-pattern-update-ex-info))
|
|
||||||
(setq flag 'update))
|
|
||||||
|
|
||||||
((eq flag 'stop)
|
|
||||||
(evil-ex-delete-hl name)))))
|
|
||||||
|
|
||||||
(defun doom--evil-ex-buffer-match (arg &optional hl-name flags beg end)
|
|
||||||
(when (and (eq flag 'update)
|
|
||||||
evil-ex-substitute-highlight-all
|
|
||||||
(not (zerop (length arg))))
|
|
||||||
(condition-case lossage
|
|
||||||
(let ((pattern (evil-ex-make-substitute-pattern
|
|
||||||
(if evil-ex-bang (regexp-quote arg) arg)
|
|
||||||
(or flags (list))))
|
|
||||||
(range (or (evil-copy-range evil-ex-range)
|
|
||||||
(evil-range (or beg (line-beginning-position))
|
|
||||||
(or end (line-end-position))
|
|
||||||
'line
|
|
||||||
:expanded t))))
|
|
||||||
(evil-expand-range range)
|
|
||||||
(evil-ex-hl-set-region hl-name
|
|
||||||
(max (evil-range-beginning range) (window-start))
|
|
||||||
(min (evil-range-end range) (window-end)))
|
|
||||||
(evil-ex-hl-change hl-name pattern))
|
|
||||||
(end-of-file
|
|
||||||
(evil-ex-pattern-update-ex-info nil "incomplete replacement"))
|
|
||||||
(user-error
|
|
||||||
(evil-ex-pattern-update-ex-info nil (format "?%s" lossage))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-ex-buffer-match (flag &optional arg)
|
|
||||||
(let ((hl-name 'evil-ex-buffer-match))
|
|
||||||
(with-selected-window (minibuffer-selected-window)
|
|
||||||
(doom--evil-ex-match-init hl-name)
|
|
||||||
(doom--evil-ex-buffer-match arg hl-name (list (if doom-buffer-match-global ?g))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-ex-global-match (flag &optional arg)
|
|
||||||
(let ((hl-name 'evil-ex-global-match))
|
|
||||||
(with-selected-window (minibuffer-selected-window)
|
|
||||||
(doom--evil-ex-match-init hl-name)
|
|
||||||
(let ((result (car-safe (evil-ex-parse-global arg))))
|
|
||||||
(doom--evil-ex-buffer-match result hl-name nil (point-min) (point-max))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-ex-undefine-cmd (cmd)
|
|
||||||
(if (string-match "^[^][]*\\(\\[\\(.*\\)\\]\\)[^][]*$" cmd)
|
|
||||||
(let ((abbrev (replace-match "" nil t cmd 1))
|
|
||||||
(full (replace-match "\\2" nil nil cmd 1)))
|
|
||||||
(setq evil-ex-commands (delq (assoc full evil-ex-commands) evil-ex-commands))
|
|
||||||
(setq evil-ex-commands (delq (assoc abbrev evil-ex-commands) evil-ex-commands)))
|
|
||||||
(setq evil-ex-commands (delq (assoc cmd evil-ex-commands) evil-ex-commands))))
|
|
||||||
|
|
||||||
(defvar doom:map-maps '())
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:map "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom:map (bang input &optional mode)
|
|
||||||
"Map ex commands to keybindings. INPUT should be in the format [KEY] [EX COMMAND]."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(let* ((parts (s-split-up-to " " input 2 t))
|
|
||||||
(mode (or mode 'normal))
|
|
||||||
(key (kbd (car parts)))
|
|
||||||
(command (s-join " " (cdr parts)))
|
|
||||||
(map (cl-case mode
|
|
||||||
('normal evil-normal-state-local-map)
|
|
||||||
('insert evil-insert-state-local-map)
|
|
||||||
('visual evil-visual-state-local-map)
|
|
||||||
('motion evil-motion-state-local-map)
|
|
||||||
('operator evil-operator-state-local-map)))
|
|
||||||
(fn `(lambda () (interactive) (evil-ex-eval ,command))))
|
|
||||||
(if bang
|
|
||||||
(evil-define-key mode nil key fn)
|
|
||||||
(define-key map key fn))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:nmap "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom:nmap (bang input &optional mode)
|
|
||||||
(interactive "<!><a>") (doom:map bang input 'normal))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:imap "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom:imap (bang input &optional mode)
|
|
||||||
(interactive "<!><a>") (doom:map bang input 'insert))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:vmap "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom:vmap (bang input &optional mode)
|
|
||||||
(interactive "<!><a>") (doom:map bang input 'visual))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:mmap "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom:mmap (bang input &optional mode)
|
|
||||||
(interactive "<!><a>") (doom:map bang input 'motion))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:omap "defuns-evil" nil t)
|
|
||||||
(evil-define-command doom:omap (bang input &optional mode)
|
|
||||||
(interactive "<!><a>") (doom:map bang input 'operator))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-snipe-easymotion ()
|
|
||||||
(interactive)
|
|
||||||
(require 'evil-easymotion)
|
|
||||||
(call-interactively doom--evil-snipe-repeat-fn))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-matchit ()
|
|
||||||
(interactive)
|
|
||||||
(if (ignore-errors (hs-already-hidden-p))
|
|
||||||
(hs-toggle-hiding)
|
|
||||||
(call-interactively 'evilmi-jump-items)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*evil-command-window (hist cmd-key execute-fn)
|
|
||||||
"The evil command window has a mind of its own (uses `switch-to-buffer'). We
|
|
||||||
monkey patch it to use pop-to-buffer."
|
|
||||||
(when (eq major-mode 'evil-command-window-mode)
|
|
||||||
(user-error "Cannot recursively open command line window"))
|
|
||||||
(dolist (win (window-list))
|
|
||||||
(when (equal (buffer-name (window-buffer win))
|
|
||||||
"*Command Line*")
|
|
||||||
(kill-buffer (window-buffer win))
|
|
||||||
(delete-window win)))
|
|
||||||
(setq evil-command-window-current-buffer (current-buffer))
|
|
||||||
(ignore-errors (kill-buffer "*Command Line*"))
|
|
||||||
(with-current-buffer (pop-to-buffer "*Command Line*")
|
|
||||||
(setq-local evil-command-window-execute-fn execute-fn)
|
|
||||||
(setq-local evil-command-window-cmd-key cmd-key)
|
|
||||||
(evil-command-window-mode)
|
|
||||||
(evil-command-window-insert-commands hist)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*evil-esc-quit ()
|
|
||||||
"Close popups, disable search highlights and quit the minibuffer if open."
|
|
||||||
(let ((minib-p (minibuffer-window-active-p (minibuffer-window)))
|
|
||||||
(evil-hl-p (evil-ex-hl-active-p 'evil-ex-search)))
|
|
||||||
(when minib-p (abort-recursive-edit))
|
|
||||||
(when evil-hl-p (evil-ex-nohighlight))
|
|
||||||
;; Close non-repl popups and clean up `doom-popup-windows'
|
|
||||||
(unless (or minib-p evil-hl-p)
|
|
||||||
(doom/popup-close-all))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*evil-ex-replace-special-filenames (file-name)
|
|
||||||
"Replace special symbols in FILE-NAME."
|
|
||||||
(let ((regexp (concat "\\(?:^\\|[^\\\\]\\)"
|
|
||||||
"\\([#%@]\\)"
|
|
||||||
"\\(\\(?::\\(?:[phtreS~.]\\|g?s[^: $]+\\)\\)*\\)"))
|
|
||||||
case-fold-search)
|
|
||||||
(dolist (match (s-match-strings-all regexp file-name))
|
|
||||||
(let ((flags (split-string (caddr match) ":" t))
|
|
||||||
(path (file-relative-name
|
|
||||||
(pcase (cadr match)
|
|
||||||
("@" (doom/project-root))
|
|
||||||
("%" (buffer-file-name))
|
|
||||||
("#" (and (other-buffer) (buffer-file-name (other-buffer)))))
|
|
||||||
default-directory))
|
|
||||||
flag global)
|
|
||||||
(when path
|
|
||||||
(while flags
|
|
||||||
(setq flag (pop flags))
|
|
||||||
(when (string-suffix-p "\\" flag)
|
|
||||||
(setq flag (concat flag (pop flags))))
|
|
||||||
(when (string-prefix-p "gs" flag)
|
|
||||||
(setq global t
|
|
||||||
flag (string-remove-prefix "g" flag)))
|
|
||||||
(setq path
|
|
||||||
(or (pcase (substring flag 0 1)
|
|
||||||
("p" (expand-file-name path))
|
|
||||||
("~" (file-relative-name path "~"))
|
|
||||||
("." (file-relative-name path default-directory))
|
|
||||||
("h" (directory-file-name path))
|
|
||||||
("t" (file-name-nondirectory (directory-file-name path)))
|
|
||||||
("r" (file-name-sans-extension path))
|
|
||||||
("e" (file-name-extension path))
|
|
||||||
("s" (let* ((args (evil-delimited-arguments (substring flag 1) 2))
|
|
||||||
(pattern (evil-transform-vim-style-regexp (car args)))
|
|
||||||
(replace (cadr args)))
|
|
||||||
(replace-regexp-in-string
|
|
||||||
(if global pattern (concat "\\(" pattern "\\).*\\'"))
|
|
||||||
(evil-transform-vim-style-regexp replace) path t t
|
|
||||||
(unless global 1))))
|
|
||||||
("S" (shell-quote-argument path))
|
|
||||||
(_ path))
|
|
||||||
"")))
|
|
||||||
(setq file-name
|
|
||||||
(replace-regexp-in-string (format "\\(?:^\\|[^\\\\]\\)\\(%s\\)"
|
|
||||||
(string-trim-left (car match)))
|
|
||||||
path file-name t t 1)))))
|
|
||||||
(setq file-name (replace-regexp-in-string regexp "\\1" file-name t))))
|
|
||||||
|
|
||||||
(provide 'defuns-evil)
|
|
||||||
;;; defuns-evil.el ends here
|
|
|
@ -1,72 +0,0 @@
|
||||||
;;; defuns-file.el
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:file-delete "defuns-file" nil t)
|
|
||||||
(evil-define-command doom:file-delete (&optional bang filename)
|
|
||||||
"Delete current buffer's file. If BANG, kill buffer afterwards."
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<!><f>")
|
|
||||||
(let ((filename (file-truename (or filename (buffer-file-name)))))
|
|
||||||
(if (not (file-exists-p filename))
|
|
||||||
(error "File doesn't exist: %s" filename)
|
|
||||||
(when (or bang (and (not bang) (y-or-n-p (format "Delete %s?" (f-base filename)))))
|
|
||||||
(set-buffer-modified-p nil)
|
|
||||||
(delete-file filename)
|
|
||||||
(kill-this-buffer)
|
|
||||||
(unless (doom/real-buffer-p)
|
|
||||||
(doom/previous-real-buffer))
|
|
||||||
(save-place-forget-unreadable-files)
|
|
||||||
(message "File successfully deleted: %s" filename)))))
|
|
||||||
|
|
||||||
(defun doom--save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit))
|
|
||||||
;;;###autoload (autoload 'doom:file-create "defuns-file" nil t)
|
|
||||||
(evil-define-command doom:file-create (path &optional bang)
|
|
||||||
"Deploy files (and their associated templates) quickly. Will prompt
|
|
||||||
you to fill in each snippet field before buffer closes unless BANG is
|
|
||||||
provided."
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<f><!>")
|
|
||||||
(let ((dir (f-dirname path))
|
|
||||||
(fullpath (f-full path))
|
|
||||||
(is-auto t))
|
|
||||||
(when (and bang (not (f-exists? dir)))
|
|
||||||
(mkdir dir))
|
|
||||||
(if (f-exists? dir)
|
|
||||||
(if (f-exists? fullpath)
|
|
||||||
(error "File already exists: %s" path)
|
|
||||||
(find-file fullpath)
|
|
||||||
(add-hook 'yas-after-exit-snippet-hook 'doom--save-exit)
|
|
||||||
(if bang (doom--save-exit)))
|
|
||||||
(error "Directory doesn't exist: %s" dir))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:file-move "defuns-file" nil t)
|
|
||||||
(evil-define-command doom:file-move (path)
|
|
||||||
"Move current buffer's file to PATH. Replaces %, # and other variables (see
|
|
||||||
`evil-ex-replace-special-filenames')"
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<f>")
|
|
||||||
(let* ((old-path (buffer-file-name))
|
|
||||||
(new-path (cond ((f-dir? path)
|
|
||||||
(f-expand (f-filename old-path) path))
|
|
||||||
((f-dir? (f-dirname path))
|
|
||||||
(f-full path))
|
|
||||||
(t (user-error "Not a valid destination: %s" path))))
|
|
||||||
(project-root (doom/project-root)))
|
|
||||||
;; Move all attachments if in org-mode
|
|
||||||
(when (eq major-mode 'org-mode)
|
|
||||||
(mapc (lambda (file)
|
|
||||||
(when (and (file-exists-p file) (not (f-same? old-path new-path)))
|
|
||||||
(rename-file file (f-expand (f-filename old-path) (f-dirname new-path)) t)))
|
|
||||||
(doom/org-attachments)))
|
|
||||||
(when (buffer-modified-p)
|
|
||||||
(save-buffer))
|
|
||||||
(rename-file old-path new-path 1)
|
|
||||||
(rename-buffer (f-filename new-path))
|
|
||||||
(set-visited-file-name new-path)
|
|
||||||
(set-buffer-modified-p nil)
|
|
||||||
(save-place-forget-unreadable-files)
|
|
||||||
(setq doom--spaceline-file-path nil)
|
|
||||||
(message "File '%s' successfully renamed to '%s'"
|
|
||||||
(f-relative old-path project-root) (f-relative new-path project-root))))
|
|
||||||
|
|
||||||
(provide 'defuns-file)
|
|
||||||
;;; defuns-file.el ends here
|
|
|
@ -1,33 +0,0 @@
|
||||||
;;; defuns-flycheck.el
|
|
||||||
;; for ../core-flycheck.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*flycheck-buffer ()
|
|
||||||
(when (bound-and-true-p flycheck-mode)
|
|
||||||
(flycheck-buffer)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/flycheck-next-error ()
|
|
||||||
(interactive)
|
|
||||||
(call-interactively
|
|
||||||
(if (bound-and-true-p flycheck-mode)
|
|
||||||
'flycheck-next-error
|
|
||||||
'next-error)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/flycheck-previous-error ()
|
|
||||||
(interactive)
|
|
||||||
(call-interactively
|
|
||||||
(if (bound-and-true-p flycheck-mode)
|
|
||||||
'flycheck-previous-error
|
|
||||||
'previous-error)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/flycheck-errors ()
|
|
||||||
(interactive)
|
|
||||||
(when (bound-and-true-p flycheck-mode)
|
|
||||||
(flycheck-buffer)
|
|
||||||
(flycheck-list-errors)))
|
|
||||||
|
|
||||||
(provide 'defuns-flycheck)
|
|
||||||
;;; defuns-flycheck.el ends here
|
|
|
@ -1,41 +0,0 @@
|
||||||
;;; defuns-git.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/git-root ()
|
|
||||||
(awhen (car-safe (browse-at-remote/remote-ref buffer-file-name))
|
|
||||||
(cdr (browse-at-remote/get-url-from-remote it))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/git-issues ()
|
|
||||||
"Open the github issues page for current repo."
|
|
||||||
(interactive)
|
|
||||||
(awhen (doom/git-root)
|
|
||||||
(browse-url (concat it "/issues"))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/git-magit ()
|
|
||||||
(interactive)
|
|
||||||
(call-interactively 'magit-status))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:git-browse "defuns-git" nil t)
|
|
||||||
(evil-define-command doom:git-browse (&optional bang)
|
|
||||||
"Open the website for the current (or specified) version controlled FILE. If
|
|
||||||
BANG, then use hub to do it."
|
|
||||||
(interactive "<!>")
|
|
||||||
(let (url)
|
|
||||||
(condition-case err
|
|
||||||
(setq url (browse-at-remote/get-url))
|
|
||||||
(error
|
|
||||||
(setq url (shell-command-to-string "hub browse -u --"))
|
|
||||||
(setq url (if url
|
|
||||||
(concat (s-trim url) "/" (f-relative (buffer-file-name) (doom/project-root))
|
|
||||||
(when (use-region-p) (format "#L%s-L%s"
|
|
||||||
(line-number-at-pos (region-beginning))
|
|
||||||
(line-number-at-pos (region-end)))))))))
|
|
||||||
(when url
|
|
||||||
(if bang
|
|
||||||
(message "Url copied to clipboard: %s" (kill-new url))
|
|
||||||
(browse-url url)))))
|
|
||||||
|
|
||||||
(provide 'defuns-git)
|
|
||||||
;;; defuns-git.el ends here
|
|
|
@ -1,90 +0,0 @@
|
||||||
;;; defuns-helm.el
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:helm-recentf "defuns-helm" nil t)
|
|
||||||
(evil-define-command doom:helm-recentf (&optional bang)
|
|
||||||
"Ex-mode interface for `helm-recentf' and `helm-projectile-recentf'."
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<!>")
|
|
||||||
(if bang (helm-recentf) (helm-projectile-recentf)))
|
|
||||||
|
|
||||||
;; Ex-mode interface for `helm-ag'. If `bang', then `search' is interpreted as
|
|
||||||
;; regexp.
|
|
||||||
;;;###autoload (autoload 'doom:helm-ag-search "defuns-helm" nil t)
|
|
||||||
(evil-define-operator doom:helm-ag-search (beg end search regex-p &optional dir)
|
|
||||||
"Preform an helm-ag search with SEARCH. If SEARCH is nil and in visual mode, use the
|
|
||||||
selection, otherwise activate live ag searching in helm.
|
|
||||||
|
|
||||||
If REGEX-P is non-nil, SEARCH will be treated as a regular expression.
|
|
||||||
DIR specifies the default-directory from which ag is run."
|
|
||||||
:type inclusive
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<r><a><!>")
|
|
||||||
(require 'helm-ag)
|
|
||||||
(let* ((helm-ag--default-directory (or dir (f-slash (doom/project-root))))
|
|
||||||
(helm-ag-command-option (unless regex-p "-Q "))
|
|
||||||
(input "")
|
|
||||||
(header-name (format "Search in %s" helm-ag--default-directory)))
|
|
||||||
(if search
|
|
||||||
(progn
|
|
||||||
(helm-attrset 'search-this-file nil helm-ag-source)
|
|
||||||
(setq helm-ag--last-query search))
|
|
||||||
(if (and beg end (/= beg (1- end)))
|
|
||||||
(setq input (buffer-substring-no-properties beg end))))
|
|
||||||
(helm-attrset 'name header-name helm-ag-source)
|
|
||||||
(helm :sources (if search helm-ag-source '(helm-source-do-ag))
|
|
||||||
:buffer "*helm-ag*"
|
|
||||||
:keymap helm-ag-map
|
|
||||||
:input input)))
|
|
||||||
|
|
||||||
;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted
|
|
||||||
;; as regexp
|
|
||||||
;;;###autoload (autoload 'doom:helm-ag-search-cwd "defuns-helm" nil t)
|
|
||||||
(evil-define-operator doom:helm-ag-search-cwd (beg end &optional search bang)
|
|
||||||
:type inclusive :repeat nil
|
|
||||||
(interactive "<r><a><!>")
|
|
||||||
(doom:helm-ag-search beg end search bang default-directory))
|
|
||||||
|
|
||||||
;; Ex-mode interface for `helm-swoop', `helm-multi-swoop-all' (if `bang'), or
|
|
||||||
;; `helm-css-scss' and `helm-css-scss-multi' (if `bang') if major-mode is
|
|
||||||
;; `scss-mode'
|
|
||||||
;;;###autoload (autoload 'doom:helm-swoop "defuns-helm" nil t)
|
|
||||||
(evil-define-command doom:helm-swoop (&optional search bang)
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<a><!>")
|
|
||||||
(if bang (helm-multi-swoop-all search) (helm-swoop :$query search)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/helm-buffers-dwim (&optional all-p)
|
|
||||||
"Displays open buffers in current project. If ALL-P, then show all open
|
|
||||||
buffers."
|
|
||||||
(interactive)
|
|
||||||
(let ((doom-helm-force-project-buffers (and (not all-p) (doom/project-p))))
|
|
||||||
(helm-buffers-list)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*helm-replace-prompt (plist)
|
|
||||||
(if (keywordp (car plist))
|
|
||||||
(setq plist (plist-put plist :prompt helm-global-prompt))
|
|
||||||
(setcar (nthcdr 2 plist) helm-global-prompt))
|
|
||||||
plist)
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*helm-hide-header (source &optional force)
|
|
||||||
(doom-hide-mode-line-mode +1))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*helm-hide-source-header-maybe ()
|
|
||||||
(if (<= (length helm-sources) 1)
|
|
||||||
(set-face-attribute 'helm-source-header nil :height 0.1 :foreground "#111111")
|
|
||||||
(set-face-attribute 'helm-source-header nil :height 1.0 :foreground doom-helm-header-fg)))
|
|
||||||
|
|
||||||
(defvar doom-helm-force-project-buffers nil
|
|
||||||
"If non-nil, helm-buffers-list will only show project buffers.")
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun helm*buffer-list (&rest _)
|
|
||||||
(append (doom/get-buffer-names doom-helm-force-project-buffers)
|
|
||||||
(list doom-buffer-name)))
|
|
||||||
|
|
||||||
(provide 'defuns-helm)
|
|
||||||
;;; defuns-helm.el ends here
|
|
|
@ -1,45 +0,0 @@
|
||||||
;;; defuns-highlight-indentation.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/add-whitespace (&optional start end)
|
|
||||||
"Maintain indentation whitespace in buffer. Used so that highlight-indentation will
|
|
||||||
display consistent guides. Whitespace is stripped out on save, so this doesn't affect the
|
|
||||||
end file."
|
|
||||||
(interactive (progn (barf-if-buffer-read-only)
|
|
||||||
(if (use-region-p)
|
|
||||||
(list (region-beginning) (region-end))
|
|
||||||
(list nil nil))))
|
|
||||||
(unless indent-tabs-mode
|
|
||||||
(save-match-data
|
|
||||||
(save-excursion
|
|
||||||
(let ((end-marker (copy-marker (or end (point-max))))
|
|
||||||
(start (or start (point-min))))
|
|
||||||
(goto-char start)
|
|
||||||
(while (and (re-search-forward "^$" end-marker t) (not (>= (point) end-marker)))
|
|
||||||
(let (line-start line-end next-start next-end)
|
|
||||||
(save-excursion
|
|
||||||
;; Check previous line indent
|
|
||||||
(forward-line -1)
|
|
||||||
(setq line-start (point)
|
|
||||||
line-end (save-excursion (back-to-indentation) (point)))
|
|
||||||
;; Check next line indent
|
|
||||||
(forward-line 2)
|
|
||||||
(setq next-start (point)
|
|
||||||
next-end (save-excursion (back-to-indentation) (point)))
|
|
||||||
;; Back to origin
|
|
||||||
(forward-line -1)
|
|
||||||
;; Adjust indent
|
|
||||||
(let* ((line-indent (- line-end line-start))
|
|
||||||
(next-indent (- next-end next-start))
|
|
||||||
(indent (min line-indent next-indent)))
|
|
||||||
(insert (make-string (if (zerop indent) 0 (1+ indent)) ? )))))
|
|
||||||
(forward-line 1)))))
|
|
||||||
(set-buffer-modified-p nil))
|
|
||||||
nil)
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*hl-indent-guess-offset ()
|
|
||||||
(string-to-int (gethash 'indent_size (editorconfig-get-properties))))
|
|
||||||
|
|
||||||
(provide 'defuns-highlight-indentation)
|
|
||||||
;;; defuns-highlight-indentation.el ends here
|
|
|
@ -1,60 +0,0 @@
|
||||||
;;; defuns-ido.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*ido-sort-mtime ()
|
|
||||||
"Sort ido filelist by mtime instead of alphabetically."
|
|
||||||
(setq ido-temp-list
|
|
||||||
(sort ido-temp-list
|
|
||||||
(lambda (a b)
|
|
||||||
(ignore-errors
|
|
||||||
(time-less-p
|
|
||||||
(sixth (file-attributes (concat ido-current-directory b)))
|
|
||||||
(sixth (file-attributes (concat ido-current-directory a))))))))
|
|
||||||
(ido-to-end ;; move . files to end (again)
|
|
||||||
(delq nil (mapcar
|
|
||||||
(lambda (x) (and (char-equal (string-to-char x) ?.) x))
|
|
||||||
ido-temp-list))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|ido-setup-home-keybind ()
|
|
||||||
"Go to $HOME with ~"
|
|
||||||
(define-key ido-file-completion-map (kbd "~")
|
|
||||||
(λ! (if (looking-back "/")
|
|
||||||
(insert "~/")
|
|
||||||
(call-interactively 'self-insert-command)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ido-find-file (&optional dir)
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory (or dir default-directory)))
|
|
||||||
(ido-find-file)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ido-find-file-other-window (&optional dir)
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory (or dir default-directory)))
|
|
||||||
(ido-find-file-other-window)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ido-find-project-file ()
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory (doom/project-root)))
|
|
||||||
(ido-find-file)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ido-recentf ()
|
|
||||||
"Use `ido-completing-read' to \\[find-file] a recent file"
|
|
||||||
(interactive)
|
|
||||||
(if (find-file (ido-completing-read "Find recent file: " recentf-list))
|
|
||||||
(message "Opening file...")
|
|
||||||
(message "Aborting")))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:ido-find-file-in-emacsd "defuns-ido" nil t)
|
|
||||||
(evil-define-command doom:ido-find-file-in-emacsd (&optional bang) :repeat nil
|
|
||||||
(interactive "<!>")
|
|
||||||
(if bang
|
|
||||||
(ido-find-file-in-dir doom-modules-dir)
|
|
||||||
(ido-find-file-in-dir doom-emacs-dir)))
|
|
||||||
|
|
||||||
(provide 'defuns-ido)
|
|
||||||
;;; defuns-ido.el ends here
|
|
|
@ -1,140 +0,0 @@
|
||||||
;;; defuns-ivy.el
|
|
||||||
|
|
||||||
;; Show more information in ivy-switch-buffer; and only display
|
|
||||||
;; project/workgroup-relevant buffers.
|
|
||||||
(defun doom-ivy-get-buffers (&optional buffer-list)
|
|
||||||
(let ((min-name 5)
|
|
||||||
(min-mode 5)
|
|
||||||
(proot (doom/project-root)))
|
|
||||||
(mapcar
|
|
||||||
(lambda (b) (format (format "%%-%ds %%-%ds %%s" min-name min-mode)
|
|
||||||
(nth 0 b)
|
|
||||||
(nth 1 b)
|
|
||||||
(or (nth 2 b) "")))
|
|
||||||
(mapcar (lambda (b)
|
|
||||||
(with-current-buffer b
|
|
||||||
(let ((buffer-name (buffer-name b))
|
|
||||||
(mode-name (symbol-name major-mode)))
|
|
||||||
(when (> (length buffer-name) min-name)
|
|
||||||
(setq min-name (+ (length buffer-name) 10)))
|
|
||||||
(when (> (length mode-name) min-mode)
|
|
||||||
(setq min-mode (+ (length mode-name) 3)))
|
|
||||||
(list
|
|
||||||
(concat
|
|
||||||
(propertize buffer-name
|
|
||||||
'face (cond ((string-match-p "^ ?\\*" buffer-name)
|
|
||||||
'font-lock-comment-face)
|
|
||||||
((not (string= proot (doom/project-root)))
|
|
||||||
'font-lock-keyword-face)
|
|
||||||
(buffer-read-only
|
|
||||||
'error)))
|
|
||||||
(when (and buffer-file-name (buffer-modified-p))
|
|
||||||
(propertize "[+]" 'face 'doom-modeline-buffer-modified)))
|
|
||||||
(propertize mode-name 'face 'font-lock-constant-face)
|
|
||||||
(when buffer-file-name
|
|
||||||
(f-slash (abbreviate-file-name (f-dirname buffer-file-name))))))))
|
|
||||||
(or buffer-list (doom/get-buffers))))))
|
|
||||||
|
|
||||||
(defun doom--ivy-select-buffer-action (buffer)
|
|
||||||
(ivy--switch-buffer-action
|
|
||||||
(s-chop-suffix
|
|
||||||
"[+]"
|
|
||||||
(substring buffer 0 (s-index-of " " buffer)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ivy-switch-project-buffer (&optional all-p)
|
|
||||||
"Displays open buffers in current project and workspace. If ALL-P, then show
|
|
||||||
all open buffers."
|
|
||||||
(interactive)
|
|
||||||
(ivy-read (format "%s buffers: " (if all-p "All" "Project"))
|
|
||||||
(doom-ivy-get-buffers (if all-p (buffer-list)))
|
|
||||||
:matcher #'ivy--switch-buffer-matcher
|
|
||||||
:action #'doom--ivy-select-buffer-action
|
|
||||||
:keymap ivy-switch-buffer-map
|
|
||||||
:caller 'doom/ivy-switch-project-buffer))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ivy-switch-buffer ()
|
|
||||||
"Displays all open buffers, across projects and workspaces."
|
|
||||||
(interactive)
|
|
||||||
(doom/ivy-switch-project-buffer t))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ivy-kill-ring ()
|
|
||||||
(interactive)
|
|
||||||
(ivy-read "Kill ring:" (--filter (not (or (< (length it) 3)
|
|
||||||
(string-match-p "\\`[\n[:blank:]]+\\'" it)))
|
|
||||||
(remove-duplicates kill-ring :test 'equal))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:ivy-recentf "defuns-ivy" nil t)
|
|
||||||
(evil-define-command doom:ivy-recentf (&optional bang)
|
|
||||||
"Ex-mode interface for `ivy-recentf' and `projectile-recentf'."
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<!>")
|
|
||||||
(if bang (ivy-recentf) (projectile-recentf)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:ivy-swiper "defuns-ivy" nil t)
|
|
||||||
(evil-define-command doom:ivy-swiper (&optional search)
|
|
||||||
(interactive "<a>")
|
|
||||||
(swiper (or search (thing-at-point 'symbol))))
|
|
||||||
|
|
||||||
(defvar doom-ivy-ag-last-search nil)
|
|
||||||
;;;###autoload (autoload 'doom:ivy-ag-search "defuns-ivy" nil t)
|
|
||||||
(evil-define-operator doom:ivy-ag-search (beg end search regex-p &optional dir)
|
|
||||||
"Preform a counsel search with SEARCH. If SEARCH is nil and in visual mode,
|
|
||||||
use the selection, otherwise activate live ag searching in helm.
|
|
||||||
|
|
||||||
If REGEX-P is non-nil, SEARCH will be treated as a regular expression.
|
|
||||||
DIR specifies the default-directory from which ag is run."
|
|
||||||
:type inclusive :repeat nil
|
|
||||||
(interactive "<r><a><!>")
|
|
||||||
(let ((search (or search
|
|
||||||
(and (evil-visual-state-p)
|
|
||||||
(and beg end (rxt-quote-pcre (buffer-substring-no-properties beg end))))
|
|
||||||
doom-ivy-ag-last-search)))
|
|
||||||
(setq doom-ivy-ag-last-search search)
|
|
||||||
(counsel-ag search (or dir (f-slash (doom/project-root)))
|
|
||||||
(concat "--nocolor --nogroup" (if regex-p " -Q")))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:ivy-ag-search-cwd "defuns-ivy" nil t)
|
|
||||||
(evil-define-operator doom:ivy-ag-search-cwd (beg end search regex-p)
|
|
||||||
:type inclusive :repeat nil
|
|
||||||
(interactive "<r><a><!>")
|
|
||||||
(doom:ivy-ag-search beg end search regex-p default-directory))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/ivy-tasks ()
|
|
||||||
(interactive)
|
|
||||||
;; TODO Something a little nicer
|
|
||||||
(counsel-ag " (TODO|FIXME|NOTE) " (doom/project-root)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*counsel-ag-function (string base-cmd extra-ag-args)
|
|
||||||
"Advice to get rid of the character limit from `counsel-ag-function', which
|
|
||||||
interferes with my custom :ag ex command `doom:ivy-ag-search'."
|
|
||||||
(when (null extra-ag-args)
|
|
||||||
(setq extra-ag-args ""))
|
|
||||||
(if (< (length string) 1)
|
|
||||||
(counsel-more-chars 1)
|
|
||||||
(let ((default-directory counsel--git-grep-dir)
|
|
||||||
(regex (counsel-unquote-regex-parens
|
|
||||||
(setq ivy--old-re
|
|
||||||
(ivy--regex string)))))
|
|
||||||
(let ((ag-cmd (format base-cmd
|
|
||||||
(concat extra-ag-args
|
|
||||||
" -- "
|
|
||||||
(shell-quote-argument regex)))))
|
|
||||||
(if (file-remote-p default-directory)
|
|
||||||
(split-string (shell-command-to-string ag-cmd) "\n" t)
|
|
||||||
(counsel--async-command ag-cmd)
|
|
||||||
nil)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/counsel-ag-occur ()
|
|
||||||
"Invoke the search+replace wgrep buffer on the current ag search results."
|
|
||||||
(interactive)
|
|
||||||
(require 'wgrep)
|
|
||||||
(call-interactively 'ivy-occur))
|
|
||||||
|
|
||||||
(provide 'defuns-ivy)
|
|
||||||
;;; defuns-ivy.el ends here
|
|
|
@ -1,13 +0,0 @@
|
||||||
;;; defuns-magit.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/magit-pop-to-buffer (buffer)
|
|
||||||
"Pop to buffer in non-magit buffer."
|
|
||||||
(let (pt)
|
|
||||||
(doom/popup-save
|
|
||||||
(pop-to-buffer buffer)
|
|
||||||
(setq pt (point)))
|
|
||||||
(goto-char pt)))
|
|
||||||
|
|
||||||
(provide 'defuns-magit)
|
|
||||||
;;; defuns-magit.el ends here
|
|
|
@ -1,55 +0,0 @@
|
||||||
;;; defuns-neotree.el
|
|
||||||
;; for ../core-project.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/neotree ()
|
|
||||||
"Toggle the neotree window"
|
|
||||||
(interactive)
|
|
||||||
(let ((in-neotree (and (neo-global--window-exists-p)
|
|
||||||
(window-live-p neo-global--buffer)
|
|
||||||
(eq (current-buffer) neo-global--buffer)))
|
|
||||||
(path buffer-file-name))
|
|
||||||
(if in-neotree
|
|
||||||
(neotree-hide)
|
|
||||||
(let ((project-root (doom/project-root)))
|
|
||||||
(unless (and (neo-global--window-exists-p)
|
|
||||||
(f-same? (neo-global--with-buffer neo-buffer--start-node) project-root))
|
|
||||||
(neotree-dir project-root))
|
|
||||||
(neotree-find path project-root)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/neotree-close ()
|
|
||||||
(interactive)
|
|
||||||
(when (neo-global--window-exists-p)
|
|
||||||
(with-selected-window neo-global--window
|
|
||||||
(evil-window-delete))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro doom/neotree-save (&rest body)
|
|
||||||
`(let ((neo-p (neo-global--window-exists-p)))
|
|
||||||
(when neo-p (doom/neotree-close))
|
|
||||||
,@body
|
|
||||||
(when neo-p
|
|
||||||
(save-selected-window
|
|
||||||
(neotree-show)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|neotree-close-on-window-change (&rest _)
|
|
||||||
"Close neotree to prevent ensuing mindow buggery."
|
|
||||||
(unless (and (neo-global--window-exists-p)
|
|
||||||
(eq (current-buffer) (neo-global--get-buffer)))
|
|
||||||
(neotree-hide)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*save-neotree (orig-fun &rest args)
|
|
||||||
"Prevents messing up the neotree buffer on window changes"
|
|
||||||
(doom/neotree-save (apply orig-fun args)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*neotree-create-node (orig-fun &rest args)
|
|
||||||
"Don't ask for confirmation when creating files"
|
|
||||||
(cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t)))
|
|
||||||
(apply orig-fun args)))
|
|
||||||
|
|
||||||
(provide 'defuns-neotree)
|
|
||||||
;;; defuns-neotree.el ends here
|
|
|
@ -1,50 +0,0 @@
|
||||||
;;; defuns-nlinum.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/nlinum-toggle ()
|
|
||||||
(interactive)
|
|
||||||
(if (bound-and-true-p nlinum-mode)
|
|
||||||
(doom|nlinum-disable)
|
|
||||||
(doom|nlinum-enable)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|nlinum-enable (&rest _)
|
|
||||||
(nlinum-mode +1)
|
|
||||||
(add-hook 'post-command-hook 'doom|nlinum-hl-line nil t)
|
|
||||||
(doom--nlinum-unhl-line))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|nlinum-disable (&rest _)
|
|
||||||
(nlinum-mode -1)
|
|
||||||
(remove-hook 'post-command-hook 'doom|nlinum-hl-line t)
|
|
||||||
(doom--nlinum-unhl-line))
|
|
||||||
|
|
||||||
(defun doom--nlinum-unhl-line ()
|
|
||||||
"Unhighlight line number"
|
|
||||||
(when doom--hl-nlinum-overlay
|
|
||||||
(let* ((disp (get-text-property
|
|
||||||
0 'display (overlay-get doom--hl-nlinum-overlay 'before-string)))
|
|
||||||
(str (nth 1 disp)))
|
|
||||||
(put-text-property 0 (length str) 'face 'linum str)
|
|
||||||
(setq doom--hl-nlinum-overlay nil)
|
|
||||||
disp)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|nlinum-hl-line (&rest _)
|
|
||||||
"Highlight line number"
|
|
||||||
(let* ((pbol (line-beginning-position))
|
|
||||||
(peol (1+ pbol))
|
|
||||||
(max (point-max)))
|
|
||||||
;; Handle EOF case
|
|
||||||
(when (>= peol max)
|
|
||||||
(setq peol max))
|
|
||||||
(jit-lock-fontify-now pbol peol)
|
|
||||||
(let ((ov (--first (overlay-get it 'nlinum) (overlays-in pbol peol))))
|
|
||||||
(doom--nlinum-unhl-line)
|
|
||||||
(when ov
|
|
||||||
(let ((str (nth 1 (get-text-property 0 'display (overlay-get ov 'before-string)))))
|
|
||||||
(put-text-property 0 (length str) 'face 'doom-nlinum-highlight str)
|
|
||||||
(setq doom--hl-nlinum-overlay ov))))))
|
|
||||||
|
|
||||||
(provide 'defuns-nlinum)
|
|
||||||
;;; defuns-nlinum.el ends here
|
|
|
@ -1,158 +0,0 @@
|
||||||
;;; defuns-popups.el
|
|
||||||
|
|
||||||
(defvar doom-last-popup nil
|
|
||||||
"The last popup buffer open (or group thereof).")
|
|
||||||
|
|
||||||
(defvar-local doom-popup-rule nil
|
|
||||||
"A list of rules applied to this popup.")
|
|
||||||
|
|
||||||
(defvar doom-popup-mode-map
|
|
||||||
(let ((map (make-sparse-keymap)))
|
|
||||||
(define-key map [remap doom/kill-real-buffer] 'doom/popup-close)
|
|
||||||
(define-key map [remap evil-window-delete] 'doom/popup-close)
|
|
||||||
(define-key map [remap evil-window-move-very-bottom] 'ignore)
|
|
||||||
(define-key map [remap evil-window-move-very-top] 'ignore)
|
|
||||||
(define-key map [remap evil-window-move-far-left] 'ignore)
|
|
||||||
(define-key map [remap evil-window-move-far-right] 'ignore)
|
|
||||||
(define-key map [remap evil-window-split] 'ignore)
|
|
||||||
(define-key map [remap evil-window-vsplit] 'ignore)
|
|
||||||
(define-key map [remap evil-force-normal-state] 'doom/popup-close-maybe)
|
|
||||||
(define-key map [escape] 'doom/popup-close-maybe)
|
|
||||||
(define-key map (kbd "ESC") 'doom/popup-close-maybe)
|
|
||||||
map)
|
|
||||||
"Active keymap in popup windows.")
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(define-minor-mode doom-popup-mode
|
|
||||||
"Minor mode for pop-up windows. Enables local keymaps and sets state
|
|
||||||
variables."
|
|
||||||
:global nil
|
|
||||||
:init-value nil
|
|
||||||
:keymap doom-popup-mode-map
|
|
||||||
(let ((rules (--any (let ((key (car it)))
|
|
||||||
(when (cond ((symbolp key)
|
|
||||||
(or (eq major-mode key)
|
|
||||||
(derived-mode-p key)))
|
|
||||||
((stringp key)
|
|
||||||
(string-match-p key (buffer-name))))
|
|
||||||
(cdr it)))
|
|
||||||
doom-popup-rules)))
|
|
||||||
(set-window-dedicated-p nil doom-popup-mode)
|
|
||||||
(setq doom-last-popup (current-buffer))
|
|
||||||
(setq-local doom-popup-rule rules)))
|
|
||||||
(put 'doom-popup-mode 'permanent-local t)
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*popup-window-move (orig-fn &rest args)
|
|
||||||
(unless (doom/popup-p)
|
|
||||||
(apply orig-fn args)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-p (&optional window)
|
|
||||||
"Whether WINDOW is a popup window or not. If WINDOW is nil, use current
|
|
||||||
window. Returns nil or the popup window."
|
|
||||||
(setq window (or window (selected-window)))
|
|
||||||
(and (window-live-p window)
|
|
||||||
(buffer-local-value 'doom-popup-mode (window-buffer window))
|
|
||||||
window))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popups-p ()
|
|
||||||
"Whether there is a popup window open and alive somewhere."
|
|
||||||
(and doom-last-popup (window-live-p (get-buffer-window doom-last-popup))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro doom/popup-save (&rest body)
|
|
||||||
"Close popups before BODY and restore them afterwards."
|
|
||||||
`(let ((popup-p (doom/popups-p))
|
|
||||||
(in-popup-p (doom/popup-p)))
|
|
||||||
(when popup-p
|
|
||||||
(doom/popup-close-all t)
|
|
||||||
(doom/popup-close nil t))
|
|
||||||
(prog1
|
|
||||||
,@body
|
|
||||||
(when popup-p
|
|
||||||
(let ((origin-win (selected-window)))
|
|
||||||
(doom/popup-last-buffer)
|
|
||||||
(when in-popup-p
|
|
||||||
(select-window origin-win)))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-buffer (buffer &optional plist)
|
|
||||||
"Display BUFFER in a shackle popup."
|
|
||||||
(let* ((buffer-name (cond ((stringp buffer) buffer)
|
|
||||||
((bufferp buffer) (buffer-name buffer))
|
|
||||||
(t (error "Not a valid buffer"))))
|
|
||||||
(buffer (get-buffer-create buffer-name)))
|
|
||||||
(shackle-display-buffer
|
|
||||||
buffer
|
|
||||||
nil (or plist (shackle-match buffer-name)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-close (&optional window dont-kill)
|
|
||||||
"Find and close the currently active popup (if available)."
|
|
||||||
(interactive)
|
|
||||||
(setq window (or window (selected-window)))
|
|
||||||
(when (doom/popup-p window)
|
|
||||||
(with-selected-window window
|
|
||||||
;; If REPL...
|
|
||||||
(when (bound-and-true-p repl-toggle-mode)
|
|
||||||
(setq rtog/--last-buffer nil))
|
|
||||||
(doom-popup-mode -1)
|
|
||||||
(unless (or dont-kill (memq :nokill doom-popup-rule))
|
|
||||||
(let ((kill-buffer-query-functions
|
|
||||||
(delq 'process-kill-buffer-query-function
|
|
||||||
kill-buffer-query-functions)))
|
|
||||||
(kill-buffer (window-buffer window)))))
|
|
||||||
(delete-window window)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-close-maybe ()
|
|
||||||
"Close the current popup *if* its buffer doesn't have a :noesc rule in
|
|
||||||
`doom-popup-rules'."
|
|
||||||
(interactive)
|
|
||||||
(if (memq :noesc doom-popup-rule)
|
|
||||||
(call-interactively 'evil-force-normal-state)
|
|
||||||
(doom/popup-close)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-close-all (&optional dont-kill)
|
|
||||||
"Closes all popups (kill them if DONT-KILL-BUFFERS is non-nil)."
|
|
||||||
(interactive)
|
|
||||||
(let ((orig-win (selected-window)))
|
|
||||||
(mapc (lambda (w) (doom/popup-close w dont-kill))
|
|
||||||
(--filter (and (doom/popup-p it) (not (eq it orig-win)))
|
|
||||||
(window-list)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-last-buffer ()
|
|
||||||
"Restore the last popup."
|
|
||||||
(interactive)
|
|
||||||
(unless (buffer-live-p doom-last-popup)
|
|
||||||
(setq doom-last-popup nil)
|
|
||||||
(error "No popup to restore"))
|
|
||||||
(doom/popup-buffer doom-last-popup))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/popup-messages ()
|
|
||||||
"Pop up the messages buffer."
|
|
||||||
(interactive)
|
|
||||||
(doom/popup-buffer (messages-buffer))
|
|
||||||
(goto-char (point-max)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*popup-init (orig-fn &rest args)
|
|
||||||
"Enables `doom-popup-mode' in every popup window and returns the window."
|
|
||||||
(let ((window (apply orig-fn args)))
|
|
||||||
(with-selected-window window
|
|
||||||
(doom-popup-mode +1))
|
|
||||||
;; NOTE orig-fn returns a window, so `doom*popup-init' must too
|
|
||||||
window))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*save-popup (orig-fun &rest args)
|
|
||||||
"Prevents messing up a popup buffer on window changes"
|
|
||||||
(doom/popup-save (apply orig-fun args)))
|
|
||||||
|
|
||||||
(provide 'defuns-popups)
|
|
||||||
;;; defuns-popups.el ends here
|
|
|
@ -1,32 +0,0 @@
|
||||||
;;; defuns-projectile.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/project-root (&optional strict-p)
|
|
||||||
"Get the path to the root of your project."
|
|
||||||
(let (projectile-require-project-root strict-p)
|
|
||||||
(projectile-project-root)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/project-has-files (files &optional root)
|
|
||||||
"Return non-nil if FILES exist in the project root."
|
|
||||||
(let ((root (or root (doom/project-root)))
|
|
||||||
(files (if (listp files) files (list files)))
|
|
||||||
(found-p (if files t)))
|
|
||||||
(while (and found-p files)
|
|
||||||
(let ((file (expand-file-name (pop files) root)))
|
|
||||||
(setq found-p (if (string-suffix-p "/" file)
|
|
||||||
(file-directory-p file)
|
|
||||||
(file-exists-p file)))))
|
|
||||||
found-p))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/project-p (&optional strict-p)
|
|
||||||
"Whether or not this buffer is currently in a project or not."
|
|
||||||
(let ((projectile-require-project-root strict-p))
|
|
||||||
(projectile-project-p)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defalias 'doom/project-name 'projectile-project-name)
|
|
||||||
|
|
||||||
(provide 'defuns-projectile)
|
|
||||||
;;; defuns-projectile.el ends here
|
|
|
@ -1,35 +0,0 @@
|
||||||
;;; defuns-repl.el
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:repl "defuns-repl" nil t)
|
|
||||||
(evil-define-command doom:repl (&optional bang command)
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(if (and doom-repl-buffer (buffer-live-p doom-repl-buffer))
|
|
||||||
(doom/popup-buffer doom-repl-buffer)
|
|
||||||
(rtog/toggle-repl (if (use-region-p) 4))
|
|
||||||
(setq doom-repl-buffer (current-buffer))
|
|
||||||
(when command
|
|
||||||
(with-current-buffer doom-repl-buffer
|
|
||||||
(insert command)
|
|
||||||
(unless bang (comint-send-input))))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:repl-eval "defuns-repl" nil t)
|
|
||||||
(evil-define-operator doom:repl-eval (&optional beg end bang)
|
|
||||||
:type inclusive
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<r><!>")
|
|
||||||
(let ((region-p (use-region-p))
|
|
||||||
(selection (s-trim (buffer-substring-no-properties beg end))))
|
|
||||||
(doom:repl bang)
|
|
||||||
(when (and region-p beg end)
|
|
||||||
(let* ((buf doom-repl-buffer)
|
|
||||||
(win (get-buffer-window buf)))
|
|
||||||
(unless (eq buf (doom/popup-p (get-buffer-window buf)))
|
|
||||||
(doom/popup-buffer buf))
|
|
||||||
(when (and doom-repl-buffer (buffer-live-p doom-repl-buffer))
|
|
||||||
(with-current-buffer doom-repl-buffer
|
|
||||||
(goto-char (point-max))
|
|
||||||
(insert selection)))))))
|
|
||||||
|
|
||||||
(provide 'defuns-repl)
|
|
||||||
;;; defuns-repl.el ends here
|
|
|
@ -1,79 +0,0 @@
|
||||||
;;; defuns-ui.el
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:set-columns "defuns-ui" nil t)
|
|
||||||
(after! evil
|
|
||||||
(evil-define-command doom:set-columns (&optional bang columns)
|
|
||||||
"Adjusts visual-fill-column-width on the fly."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(if (or (= (length columns) 0) bang)
|
|
||||||
(progn
|
|
||||||
(setq visual-fill-column-width 80)
|
|
||||||
(when visual-fill-column-mode
|
|
||||||
(visual-fill-column-mode -1)))
|
|
||||||
(setq columns (string-to-number columns))
|
|
||||||
(when (> columns 30)
|
|
||||||
(setq visual-fill-column-width columns)))
|
|
||||||
(if visual-fill-column-mode
|
|
||||||
(visual-fill-column--adjust-window)
|
|
||||||
(visual-fill-column-mode 1))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/toggle-fullscreen ()
|
|
||||||
(interactive)
|
|
||||||
(set-frame-parameter nil 'fullscreen (if (not (frame-parameter nil 'fullscreen)) 'fullboth)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/reset-theme ()
|
|
||||||
(interactive)
|
|
||||||
(doom/load-theme doom-ui-theme))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/load-font (font)
|
|
||||||
(interactive)
|
|
||||||
(set-frame-font font t))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/load-theme (theme)
|
|
||||||
(interactive)
|
|
||||||
(when doom-ui-theme
|
|
||||||
(disable-theme doom-ui-theme))
|
|
||||||
(load-theme theme t))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/show-as (how &optional pred)
|
|
||||||
(let* ((beg (match-beginning 1))
|
|
||||||
(end (match-end 1))
|
|
||||||
(ok (or (not pred) (funcall pred beg end))))
|
|
||||||
(when ok
|
|
||||||
(compose-region beg end how 'decompose-region))
|
|
||||||
nil))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/imenu-list-quit ()
|
|
||||||
(interactive)
|
|
||||||
(quit-window)
|
|
||||||
(mapc (lambda (b) (with-current-buffer b
|
|
||||||
(when imenu-list-minor-mode
|
|
||||||
(imenu-list-minor-mode -1))))
|
|
||||||
(doom/get-visible-buffers (doom/get-real-buffers))))
|
|
||||||
|
|
||||||
(put 'doom-hide-mode-line-mode 'permanent-local t)
|
|
||||||
(put 'doom--mode-line 'permanent-local t)
|
|
||||||
|
|
||||||
(defvar doom-hide-mode-line-format nil
|
|
||||||
"Format to use when `doom-hide-mode-line-mode' replaces the modeline")
|
|
||||||
|
|
||||||
(defvar-local doom--mode-line nil)
|
|
||||||
;;;###autoload
|
|
||||||
(define-minor-mode doom-hide-mode-line-mode
|
|
||||||
"Minor mode to hide the mode-line in the current buffer."
|
|
||||||
:init-value nil
|
|
||||||
:global nil
|
|
||||||
(if doom-hide-mode-line-mode
|
|
||||||
(setq doom--mode-line mode-line-format
|
|
||||||
mode-line-format doom-hide-mode-line-format)
|
|
||||||
(setq mode-line-format doom--mode-line
|
|
||||||
doom--mode-line doom-hide-mode-line-format)))
|
|
||||||
|
|
||||||
(provide 'defuns-ui)
|
|
||||||
;;; defuns-ui.el ends here
|
|
|
@ -1,39 +0,0 @@
|
||||||
;;; defuns-util.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun what-face (pos)
|
|
||||||
"Tells you the name of the face (point) is on."
|
|
||||||
(interactive "d")
|
|
||||||
(let ((hl-line-p (bound-and-true-p hl-line-mode)))
|
|
||||||
(if hl-line-p (hl-line-mode -1))
|
|
||||||
(let ((face (or (get-char-property (point) 'read-face-name)
|
|
||||||
(get-char-property (point) 'face))))
|
|
||||||
(if face (message "Face: %s" face) (message "No face at %d" pos)))
|
|
||||||
(if hl-line-p (hl-line-mode 1))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun what-col ()
|
|
||||||
(interactive)
|
|
||||||
(message "Column %d" (current-column)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun what-bindings (key)
|
|
||||||
(list
|
|
||||||
(minor-mode-key-binding key)
|
|
||||||
(local-key-binding key)
|
|
||||||
(global-key-binding key)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun what-major-mode ()
|
|
||||||
(interactive)
|
|
||||||
(message "Mode: %s" major-mode))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:echo "defuns-util" nil t)
|
|
||||||
(evil-define-command doom:echo (bang message)
|
|
||||||
"Display MSG in echo-area without logging it in *Messages* buffer."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(let (message-log-max)
|
|
||||||
(message "%s%s" (if bang ">> " "") message)))
|
|
||||||
|
|
||||||
(provide 'defuns-util)
|
|
||||||
;;; defuns-util.el ends here
|
|
|
@ -1,198 +0,0 @@
|
||||||
;;; defuns-whitespace.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom--point-at-bol-non-blank()
|
|
||||||
(save-excursion (evil-first-non-blank) (point)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/surrounded-p ()
|
|
||||||
(and (looking-back "[[{(]\\(\s+\\|\n\\)?\\(\s\\|\t\\)*")
|
|
||||||
(let* ((whitespace (match-string 1))
|
|
||||||
(match-str (concat whitespace (match-string 2) "[])}]")))
|
|
||||||
(looking-at-p match-str))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/backward-kill-to-bol-and-indent ()
|
|
||||||
"Kill line to the first non-blank character. If invoked again
|
|
||||||
afterwards, kill line to column 1."
|
|
||||||
(interactive)
|
|
||||||
(let ((empty-line (sp-point-in-blank-line)))
|
|
||||||
(evil-delete (point-at-bol) (point))
|
|
||||||
(if (not empty-line)
|
|
||||||
(indent-according-to-mode))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/move-to-bol ()
|
|
||||||
"Moves cursor to the first non-blank character on the line. If
|
|
||||||
already there, move it to the true bol."
|
|
||||||
(interactive)
|
|
||||||
(evil-save-goal-column
|
|
||||||
(let ((point-at-bol (doom--point-at-bol-non-blank))
|
|
||||||
(point (point)))
|
|
||||||
(if (= point-at-bol point)
|
|
||||||
(evil-move-beginning-of-line)
|
|
||||||
(unless (= (point-at-bol) point)
|
|
||||||
(evil-first-non-blank))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/move-to-eol ()
|
|
||||||
(interactive)
|
|
||||||
(evil-save-goal-column
|
|
||||||
(let ((old-point (point)))
|
|
||||||
(when (comment-search-forward (point-at-eol) t)
|
|
||||||
(goto-char (match-beginning 0))
|
|
||||||
(skip-syntax-backward " ^<*" (doom--point-at-bol-non-blank))
|
|
||||||
|
|
||||||
(if (eq old-point (point)) ;
|
|
||||||
(evil-move-end-of-line))))))
|
|
||||||
|
|
||||||
;; Mimic expandtab in vim
|
|
||||||
;;;###autoload
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/backward-delete-whitespace-to-column ()
|
|
||||||
"Delete back to the previous column of whitespace, or as much whitespace as
|
|
||||||
possible, or just one char if that's not possible."
|
|
||||||
(interactive)
|
|
||||||
(let* ((context (sp--get-pair-list-context 'navigate))
|
|
||||||
(open-pair-re (sp--get-opening-regexp context))
|
|
||||||
(close-pair-re (sp--get-closing-regexp context))
|
|
||||||
open-len close-len)
|
|
||||||
(cond ;; When in strings (sp acts weird with quotes; this is the fix)
|
|
||||||
;; Also, skip closing delimiters
|
|
||||||
((and (and (sp--looking-back open-pair-re)
|
|
||||||
(setq open-len (- (match-beginning 0) (match-end 0))))
|
|
||||||
(and (looking-at close-pair-re)
|
|
||||||
(setq close-len (- (match-beginning 0) (match-end 0))))
|
|
||||||
(string= (plist-get (sp-get-thing t) :op)
|
|
||||||
(plist-get (sp-get-thing) :cl)))
|
|
||||||
(delete-backward-char open-len)
|
|
||||||
(delete-char close-len))
|
|
||||||
;; Delete up to the nearest tab column IF only whitespace between
|
|
||||||
;; point and bol.
|
|
||||||
((save-match-data (looking-back "^[\\t ]*" (line-beginning-position)))
|
|
||||||
(let ((movement (% (current-column) tab-width))
|
|
||||||
(p (point)))
|
|
||||||
(when (= movement 0)
|
|
||||||
(setq movement tab-width))
|
|
||||||
(save-match-data
|
|
||||||
(if (string-match "\\w*\\(\\s-+\\)$"
|
|
||||||
(buffer-substring-no-properties (- p movement) p))
|
|
||||||
(delete-backward-char (- (match-end 1) (match-beginning 1)))
|
|
||||||
(call-interactively 'delete-backward-char)))))
|
|
||||||
;; Otherwise do a regular delete
|
|
||||||
(t (call-interactively 'delete-backward-char)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/dumb-indent (&optional smart)
|
|
||||||
"Inserts a tab character (or spaces x tab-width). Checks if the
|
|
||||||
auto-complete window is open."
|
|
||||||
(interactive)
|
|
||||||
(if indent-tabs-mode
|
|
||||||
(insert "\t")
|
|
||||||
(let* ((movement (% (current-column) tab-width))
|
|
||||||
(spaces (if (zerop movement) tab-width (- tab-width movement))))
|
|
||||||
(insert (s-repeat spaces " ")))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/smart-indent ()
|
|
||||||
(interactive)
|
|
||||||
(save-excursion
|
|
||||||
(back-to-indentation)
|
|
||||||
(doom/dumb-indent)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/dumb-dedent ()
|
|
||||||
(interactive)
|
|
||||||
(if indent-tabs-mode
|
|
||||||
(call-interactively 'backward-delete-char)
|
|
||||||
(save-excursion
|
|
||||||
(unless (looking-back "^[\s\t]*")
|
|
||||||
(evil-first-non-blank))
|
|
||||||
(let* ((movement (% (current-column) tab-width))
|
|
||||||
(spaces (if (zerop movement) tab-width (- tab-width movement))))
|
|
||||||
(delete-char (- spaces))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/inflate-space-maybe ()
|
|
||||||
"Checks if point is surrounded by {} [] () delimiters and adds a
|
|
||||||
space on either side of the point if so."
|
|
||||||
(interactive)
|
|
||||||
(if (doom/surrounded-p)
|
|
||||||
(progn (call-interactively 'self-insert-command)
|
|
||||||
(save-excursion (call-interactively 'self-insert-command)))
|
|
||||||
(call-interactively 'self-insert-command)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/deflate-space-maybe ()
|
|
||||||
"Checks if point is surrounded by {} [] () delimiters, and deletes
|
|
||||||
spaces on either side of the point if so. Resorts to
|
|
||||||
`doom/backward-delete-whitespace-to-column' otherwise."
|
|
||||||
(interactive)
|
|
||||||
(save-match-data
|
|
||||||
(if (doom/surrounded-p)
|
|
||||||
(let ((whitespace-match (match-string 1)))
|
|
||||||
(cond ((not whitespace-match)
|
|
||||||
(call-interactively 'delete-backward-char))
|
|
||||||
((string-match "\n" whitespace-match)
|
|
||||||
(evil-delete (point-at-bol) (point))
|
|
||||||
(call-interactively 'delete-backward-char)
|
|
||||||
(save-excursion (call-interactively 'delete-char)))
|
|
||||||
(t (just-one-space 0))))
|
|
||||||
(doom/backward-delete-whitespace-to-column))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/newline-and-indent ()
|
|
||||||
(interactive)
|
|
||||||
(cond ((sp-point-in-string)
|
|
||||||
(newline))
|
|
||||||
((sp-point-in-comment)
|
|
||||||
(cond ((eq major-mode 'js2-mode)
|
|
||||||
(js2-line-break))
|
|
||||||
((-contains? '(java-mode php-mode) major-mode)
|
|
||||||
(c-indent-new-comment-line))
|
|
||||||
((-contains? '(c-mode c++-mode objc-mode css-mode scss-mode js2-mode) major-mode)
|
|
||||||
(newline-and-indent)
|
|
||||||
(insert "* ")
|
|
||||||
(indent-according-to-mode))
|
|
||||||
(t
|
|
||||||
;; Fix an off-by-one cursor-positioning issue
|
|
||||||
;; with `indent-new-comment-line'
|
|
||||||
(let ((col (save-excursion (comment-beginning) (current-column))))
|
|
||||||
(indent-new-comment-line)
|
|
||||||
(unless (= col (current-column))
|
|
||||||
(insert " "))))))
|
|
||||||
(t
|
|
||||||
(newline nil t)
|
|
||||||
(indent-according-to-mode))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:whitespace-retab "defuns-whitespace" nil t)
|
|
||||||
(evil-define-operator doom:whitespace-retab (beg end)
|
|
||||||
"Akin to vim's retab, this changes all tabs-to-spaces or spaces-to-tabs,
|
|
||||||
depending on `indent-tab-mode'. Untested."
|
|
||||||
:motion nil
|
|
||||||
:move-point nil
|
|
||||||
:type line
|
|
||||||
(interactive "<r>")
|
|
||||||
(unless (and beg end)
|
|
||||||
(setq beg (point-min))
|
|
||||||
(setq end (point-max)))
|
|
||||||
(if indent-tabs-mode
|
|
||||||
(tabify beg end)
|
|
||||||
(untabify beg end)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:whitespace-align "defuns-whitespace" nil t)
|
|
||||||
(evil-define-command doom:whitespace-align (beg end &optional regexp bang)
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<r><a><!>")
|
|
||||||
(when regexp
|
|
||||||
(align-regexp beg end
|
|
||||||
(concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/static-reindent ()
|
|
||||||
"Reindent without moving cursor."
|
|
||||||
(interactive)
|
|
||||||
(save-excursion (call-interactively 'evil-indent)))
|
|
||||||
|
|
||||||
(provide 'defuns-whitespace)
|
|
||||||
;;; defuns-whitespace.el ends here
|
|
|
@ -1,128 +0,0 @@
|
||||||
;;; defuns-window.el --- library for acting on windows
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*evil-window-split (orig-fn &rest args)
|
|
||||||
(interactive)
|
|
||||||
(doom/neotree-save
|
|
||||||
(apply orig-fn args)
|
|
||||||
(evil-window-down 1)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom*evil-window-vsplit (orig-fn &rest args)
|
|
||||||
(interactive)
|
|
||||||
(doom/neotree-save
|
|
||||||
(apply orig-fn args)
|
|
||||||
(evil-window-right 1)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-window-move (direction)
|
|
||||||
"Move current window to the next window in DIRECTION. If there are no windows
|
|
||||||
there and there is only one window, split in that direction and place this
|
|
||||||
window there. If there are no windows and this isn't the only window, use
|
|
||||||
evil-window-move-* (e.g. `evil-window-move-far-left')"
|
|
||||||
(let* ((this-window (get-buffer-window))
|
|
||||||
(this-buffer (current-buffer))
|
|
||||||
(that-window (windmove-find-other-window direction nil this-window))
|
|
||||||
(that-buffer (window-buffer that-window)))
|
|
||||||
(when (or (minibufferp that-buffer)
|
|
||||||
(doom/popup-p that-window))
|
|
||||||
(setq that-buffer nil that-window nil))
|
|
||||||
(if (not (or that-window (one-window-p t)))
|
|
||||||
(funcall (case direction
|
|
||||||
('left 'evil-window-move-far-left)
|
|
||||||
('right 'evil-window-move-far-right)
|
|
||||||
('up 'evil-window-move-very-top)
|
|
||||||
('down 'evil-window-move-very-bottom)))
|
|
||||||
(unless that-window
|
|
||||||
(setq that-window
|
|
||||||
(split-window this-window nil (cond ((eq direction 'up) 'above)
|
|
||||||
((eq direction 'down) 'below)
|
|
||||||
(t direction))))
|
|
||||||
(with-selected-window that-window
|
|
||||||
(switch-to-buffer doom-buffer))
|
|
||||||
(setq that-buffer (window-buffer that-window)))
|
|
||||||
(with-selected-window this-window
|
|
||||||
(switch-to-buffer that-buffer))
|
|
||||||
(with-selected-window that-window
|
|
||||||
(switch-to-buffer this-buffer))
|
|
||||||
(select-window that-window))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-window-move-l () (interactive) (doom/evil-window-move 'left))
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-window-move-d () (interactive) (doom/evil-window-move 'down))
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-window-move-u () (interactive) (doom/evil-window-move 'up))
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-window-move-r () (interactive) (doom/evil-window-move 'right))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/new-buffer ()
|
|
||||||
(interactive)
|
|
||||||
(switch-to-buffer (generate-new-buffer "*new*")))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/new-frame ()
|
|
||||||
(interactive)
|
|
||||||
(let ((nlinum-p (and (featurep 'nlinum)
|
|
||||||
(memq 'nlinum--setup-window window-configuration-change-hook))))
|
|
||||||
;; Disable nlinum to fix elusive "invalid face linum" bug
|
|
||||||
(remove-hook 'window-configuration-change-hook 'nlinum--setup-window t)
|
|
||||||
(let ((frame (new-frame))
|
|
||||||
(frame-name (format "*new-%s*" (length doom-wg-frames))))
|
|
||||||
(with-selected-frame frame
|
|
||||||
(wg-create-workgroup frame-name t)
|
|
||||||
(add-to-list 'doom-wg-frames (cons frame frame-name))))
|
|
||||||
(when nlinum-p
|
|
||||||
(add-hook 'window-configuration-change-hook 'nlinum--setup-window nil t))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/close-frame ()
|
|
||||||
(interactive)
|
|
||||||
(let ((frame (assq (selected-frame) doom-wg-frames)))
|
|
||||||
(if frame
|
|
||||||
(progn (wg-delete-workgroup (wg-get-workgroup (cdr frame)))
|
|
||||||
(delete-frame (car frame)))
|
|
||||||
(delete-frame))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/evil-window-resize (direction &optional count)
|
|
||||||
(interactive)
|
|
||||||
(let ((count (or count 1))
|
|
||||||
(next-window (window-in-direction direction)))
|
|
||||||
(when (or (not next-window) (not (doom/real-buffer-p (window-buffer next-window))))
|
|
||||||
(setq count (- count)))
|
|
||||||
(cond ((memq direction '(left right))
|
|
||||||
(evil-window-increase-width count))
|
|
||||||
((memq direction '(above below))
|
|
||||||
(evil-window-increase-height count)))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom/evil-window-resize-r "defuns-window" nil t)
|
|
||||||
(evil-define-command doom/evil-window-resize-r (&optional count)
|
|
||||||
(interactive "<c>") (doom/evil-window-resize 'right count))
|
|
||||||
;;;###autoload (autoload 'doom/evil-window-resize-l "defuns-window" nil t)
|
|
||||||
(evil-define-command doom/evil-window-resize-l (&optional count)
|
|
||||||
(interactive "<c>") (doom/evil-window-resize 'left count))
|
|
||||||
;;;###autoload (autoload 'doom/evil-window-resize-u "defuns-window" nil t)
|
|
||||||
(evil-define-command doom/evil-window-resize-u (&optional count)
|
|
||||||
:repeat nil
|
|
||||||
(interactive "<c>") (doom/evil-window-resize 'above count))
|
|
||||||
;;;###autoload (autoload 'doom/evil-window-resize-d "defuns-window" nil t)
|
|
||||||
(evil-define-command doom/evil-window-resize-d (&optional count)
|
|
||||||
(interactive "<c>") (doom/evil-window-resize 'below count))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/window-reorient ()
|
|
||||||
"Reorient all windows that are scrolled to the right."
|
|
||||||
(interactive)
|
|
||||||
(let ((i 0))
|
|
||||||
(mapc (lambda (w)
|
|
||||||
(with-selected-window w
|
|
||||||
(when (> (window-hscroll) 0)
|
|
||||||
(cl-incf i)
|
|
||||||
(evil-beginning-of-line))))
|
|
||||||
(doom/get-visible-windows))
|
|
||||||
(message "Reoriented %s windows" i)))
|
|
||||||
|
|
||||||
(provide 'defuns-window)
|
|
||||||
;;; defuns-window.el ends here
|
|
|
@ -1,204 +0,0 @@
|
||||||
;;; defuns-workgroup.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|wg-cleanup ()
|
|
||||||
"Remove unsavable windows and buffers before we save the window
|
|
||||||
configuration."
|
|
||||||
(let (doom-buffer-inhibit-refresh)
|
|
||||||
(doom/popup-close-all)
|
|
||||||
(when (and (featurep 'neotree) (neo-global--window-exists-p))
|
|
||||||
(neotree-hide))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/wg-projectile-switch-project ()
|
|
||||||
(let ((project-root (doom/project-root)))
|
|
||||||
(doom:workgroup-new nil (file-name-nondirectory (directory-file-name project-root)) t)
|
|
||||||
(doom-reload-scratch-buffer project-root)
|
|
||||||
(when (featurep 'neotree)
|
|
||||||
(neotree-projectile-action))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:workgroup-save "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:workgroup-save (&optional bang session-name)
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(doom|wg-cleanup)
|
|
||||||
(unless (wg-workgroup-list)
|
|
||||||
(wg-create-workgroup wg-first-wg-name))
|
|
||||||
(wg-save-session-as (if session-name
|
|
||||||
(concat wg-workgroup-directory session-name)
|
|
||||||
(if bang
|
|
||||||
(concat wg-workgroup-directory (f-filename (doom/project-root)))
|
|
||||||
wg-session-file))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:workgroup-load "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:workgroup-load (&optional bang session-name)
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(doom|wg-cleanup)
|
|
||||||
(let ((session-file (if session-name
|
|
||||||
(concat wg-workgroup-directory session-name)
|
|
||||||
(let ((sess (concat wg-workgroup-directory (f-filename (doom/project-root)))))
|
|
||||||
(if bang
|
|
||||||
(when (file-exists-p sess)
|
|
||||||
sess)
|
|
||||||
wg-session-file)))))
|
|
||||||
(unless session-file
|
|
||||||
(user-error "No session found"))
|
|
||||||
(wg-open-session session-file))
|
|
||||||
(doom/workgroup-display t))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/clear-sessions ()
|
|
||||||
"Delete all session files."
|
|
||||||
(interactive)
|
|
||||||
(mapc 'delete-file (f-glob (expand-file-name "*" wg-workgroup-directory))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:workgroup-new "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:workgroup-new (bang name &optional silent)
|
|
||||||
"Create a new workgroup named NAME. If BANG, overwrite any workgroup named
|
|
||||||
NAME. If NAME is omitted, autogenerate a name. If SILENT, then don't show the
|
|
||||||
tabs in the minibuffer afterwards."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(unless name
|
|
||||||
(setq name (format "#%s" (1+ (length (wg-session-workgroup-list (wg-current-session t)))))))
|
|
||||||
(let ((new-wg (wg-get-workgroup name t)))
|
|
||||||
(when (and new-wg bang)
|
|
||||||
(wg-delete-workgroup new-wg)
|
|
||||||
(setq new-wg nil))
|
|
||||||
(setq new-wg (or new-wg (wg-make-and-add-workgroup name t)))
|
|
||||||
(add-to-list 'doom-wg-names (wg-workgroup-uid new-wg))
|
|
||||||
(wg-switch-to-workgroup new-wg))
|
|
||||||
(unless silent
|
|
||||||
(doom--workgroup-display (wg-previous-workgroup t)
|
|
||||||
(format "Created %s" name)
|
|
||||||
'success)))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:workgroup-rename "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:workgroup-rename (&optional bang new-name)
|
|
||||||
"Rename the current workgroup to NEW-NAME. If BANG and this workgroup has a
|
|
||||||
fixed name, un-fix it."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(let* ((wg (wg-current-workgroup))
|
|
||||||
(wg-uid (wg-workgroup-uid wg))
|
|
||||||
(old-name (wg-workgroup-name wg)))
|
|
||||||
(if bang
|
|
||||||
(setq doom-wg-names (delete wg-uid doom-wg-names))
|
|
||||||
(unless new-name
|
|
||||||
(user-error "You didn't enter in a name"))
|
|
||||||
(wg-rename-workgroup new-name wg)
|
|
||||||
(add-to-list 'doom-wg-names wg-uid)
|
|
||||||
(doom--workgroup-display wg (format "Renamed '%s'->'%s'" old-name new-name) 'success))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:workgroup-delete "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:workgroup-delete (&optional bang name)
|
|
||||||
"Delete the workgroup specified by NAME. If NAME is omitted, delete the
|
|
||||||
current workgroup. If BANG, prompts the user for which workgroup to delete."
|
|
||||||
(interactive "<!><a>")
|
|
||||||
(let* ((current-wg (wg-current-workgroup))
|
|
||||||
(wg-name (or name (wg-workgroup-name current-wg))))
|
|
||||||
(when bang
|
|
||||||
(setq wg-name (wg-read-workgroup-name)))
|
|
||||||
(let ((wg (wg-get-workgroup name)))
|
|
||||||
(setq doom-wg-names (delete (wg-workgroup-uid wg) doom-wg-names))
|
|
||||||
(if (eq wg current-wg)
|
|
||||||
(wg-kill-workgroup)
|
|
||||||
(wg-delete-workgroup wg))
|
|
||||||
(doom--workgroup-display nil (format "Deleted %s" wg-name) 'success))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom:kill-other-workgroups ()
|
|
||||||
"Kill all other workgroups."
|
|
||||||
(interactive)
|
|
||||||
(let (workgroup (wg-current-workgroup))
|
|
||||||
(dolist (w (wg-session-workgroup-list (wg-current-session t)))
|
|
||||||
(unless (wg-current-workgroup-p w)
|
|
||||||
(wg-kill-workgroup w)))))
|
|
||||||
|
|
||||||
(defun doom--workgroup-display (&optional suppress-update message message-face)
|
|
||||||
(message "%s%s" (doom/workgroup-display suppress-update t)
|
|
||||||
(propertize message 'face message-face)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/workgroup-display (&optional suppress-update return-p message)
|
|
||||||
(interactive)
|
|
||||||
(awhen (wg-current-session t)
|
|
||||||
(unless (eq suppress-update t)
|
|
||||||
(doom/workgroup-update-names (if (wg-workgroup-p suppress-update) suppress-update)))
|
|
||||||
(let ((output (wg-display-internal
|
|
||||||
(lambda (workgroup index)
|
|
||||||
(if (not workgroup) wg-nowg-string
|
|
||||||
(wg-element-display
|
|
||||||
workgroup
|
|
||||||
(format " [%d] %s " (1+ index) (wg-workgroup-name workgroup))
|
|
||||||
'wg-current-workgroup-p)))
|
|
||||||
(wg-session-workgroup-list it))))
|
|
||||||
(if return-p
|
|
||||||
output
|
|
||||||
(message "%s%s" output (or message ""))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/workgroup-update-names (&optional wg)
|
|
||||||
(let ((wg (or wg (wg-current-workgroup))))
|
|
||||||
(unless (member (wg-workgroup-uid wg) doom-wg-names)
|
|
||||||
(ignore-errors
|
|
||||||
(let ((old-name (wg-workgroup-name wg))
|
|
||||||
(new-name (f-filename (doom/project-root))))
|
|
||||||
(unless (string= new-name old-name)
|
|
||||||
(wg-rename-workgroup new-name wg)))))))
|
|
||||||
|
|
||||||
(defun doom--switch-to-workgroup (direction &optional count)
|
|
||||||
(interactive "<c>")
|
|
||||||
(assert (memq direction '(left right)))
|
|
||||||
(condition-case err
|
|
||||||
(progn
|
|
||||||
(if count
|
|
||||||
(wg-switch-to-workgroup-at-index (1- count))
|
|
||||||
(funcall (intern (format "wg-switch-to-workgroup-%s" direction))))
|
|
||||||
(doom/workgroup-display t))
|
|
||||||
(error (doom/workgroup-display t nil (format "Nope! %s" (cadr err))))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:switch-to-workgroup-left "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:switch-to-workgroup-left (count)
|
|
||||||
(interactive "<c>")
|
|
||||||
(doom--switch-to-workgroup 'left))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:switch-to-workgroup-right "defuns-workgroup" nil t)
|
|
||||||
(evil-define-command doom:switch-to-workgroup-right (count)
|
|
||||||
(interactive "<c>")
|
|
||||||
(doom--switch-to-workgroup 'right))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom:switch-to-workgroup-at-index (index)
|
|
||||||
(interactive)
|
|
||||||
(doom/workgroup-update-names)
|
|
||||||
(let ((wg (nth index (wg-workgroup-list-or-error)))
|
|
||||||
msg)
|
|
||||||
(if wg
|
|
||||||
(unless (eq wg (wg-current-workgroup t))
|
|
||||||
(wg-switch-to-workgroup-at-index index))
|
|
||||||
(setq msg (format "No tab #%s" (1+ index))))
|
|
||||||
(doom/workgroup-display t nil msg)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/undo-window-change ()
|
|
||||||
(interactive)
|
|
||||||
(call-interactively (if (wg-current-workgroup t) 'wg-undo-wconfig-change 'winner-undo)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/redo-window-change ()
|
|
||||||
(interactive)
|
|
||||||
(call-interactively (if (wg-current-workgroup t) 'wg-redo-wconfig-change 'winner-redo)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/close-window-or-workgroup ()
|
|
||||||
(interactive)
|
|
||||||
(if (doom/popup-p)
|
|
||||||
(doom/popup-close)
|
|
||||||
(when (doom/kill-real-buffer)
|
|
||||||
(if (and (one-window-p t)
|
|
||||||
(> (length (wg-workgroup-list)) 1))
|
|
||||||
(if (string= (wg-workgroup-name (wg-current-workgroup)) wg-first-wg-name)
|
|
||||||
(evil-window-delete)
|
|
||||||
(doom:workgroup-delete))
|
|
||||||
(evil-window-delete)))))
|
|
||||||
|
|
||||||
(provide 'defuns-workgroup)
|
|
||||||
;;; defuns-workgroup.el ends here
|
|
|
@ -1,103 +0,0 @@
|
||||||
;;; defuns-yasnippet.el
|
|
||||||
;; for ../core-yasnippet.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|yas-before-expand ()
|
|
||||||
"Strip out the shitespace before a line selection."
|
|
||||||
(when (doom/evil-visual-line-state-p)
|
|
||||||
(setq-local
|
|
||||||
yas-selected-text
|
|
||||||
(replace-regexp-in-string
|
|
||||||
"\\(^ *\\|\n? $\\)" ""
|
|
||||||
(buffer-substring-no-properties (region-beginning)
|
|
||||||
(1- (region-end)))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom|yas-after-expand ()
|
|
||||||
"Switch to insert mode when expanding a template via backtab, or go back to
|
|
||||||
normal mode if there are no fields."
|
|
||||||
(setq yas-selected-text nil))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-insert-snippet ()
|
|
||||||
"Switch to insert mode when expanding a template via backtab, or go back to
|
|
||||||
normal mode if there are no fields."
|
|
||||||
(interactive)
|
|
||||||
(when (evil-visual-state-p)
|
|
||||||
(let ((end (region-end)))
|
|
||||||
(evil-visual-select
|
|
||||||
(region-beginning)
|
|
||||||
(if (eq evil-this-type 'line) end (1+ end))
|
|
||||||
'inclusive)))
|
|
||||||
(yas-insert-snippet)
|
|
||||||
(let* ((snippet (first (yas--snippets-at-point)))
|
|
||||||
(fields (yas--snippet-fields snippet)))
|
|
||||||
(evil-insert-state +1)
|
|
||||||
(unless fields (evil-change-state 'normal))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-goto-start-of-field ()
|
|
||||||
"Go to the beginning of a field."
|
|
||||||
(interactive)
|
|
||||||
(let* ((snippet (car (yas--snippets-at-point)))
|
|
||||||
(position (yas--field-start (yas--snippet-active-field snippet))))
|
|
||||||
(if (= (point) position)
|
|
||||||
(move-beginning-of-line 1)
|
|
||||||
(goto-char position))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-goto-end-of-field ()
|
|
||||||
(interactive)
|
|
||||||
(let* ((snippet (car (yas--snippets-at-point)))
|
|
||||||
(position (yas--field-end (yas--snippet-active-field snippet))))
|
|
||||||
(if (= (point) position)
|
|
||||||
(move-end-of-line 1)
|
|
||||||
(goto-char position))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-backspace (&optional field)
|
|
||||||
"Prevents Yas from stepping on my toes when I use backspace."
|
|
||||||
(interactive)
|
|
||||||
(let ((field (or field (and yas--active-field-overlay
|
|
||||||
(overlay-buffer yas--active-field-overlay)
|
|
||||||
(overlay-get yas--active-field-overlay 'yas--field)))))
|
|
||||||
(cond ((eq (point) (marker-position (yas--field-start field))) nil)
|
|
||||||
(t (delete-char -1)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-delete (&optional field)
|
|
||||||
(interactive)
|
|
||||||
(let ((field (or field (and yas--active-field-overlay
|
|
||||||
(overlay-buffer yas--active-field-overlay)
|
|
||||||
(overlay-get yas--active-field-overlay 'yas--field)))))
|
|
||||||
(cond ((and field
|
|
||||||
(not (yas--field-modified-p field))
|
|
||||||
(eq (point) (marker-position (yas--field-start field))))
|
|
||||||
(yas--skip-and-clear field)
|
|
||||||
(yas-next-field 1))
|
|
||||||
((eq (point) (marker-position (yas--field-end field))) nil)
|
|
||||||
(t (delete-char 1)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-clear-to-sof (&optional field)
|
|
||||||
(interactive)
|
|
||||||
(let* ((field (or field (and yas--active-field-overlay
|
|
||||||
(overlay-buffer yas--active-field-overlay)
|
|
||||||
(overlay-get yas--active-field-overlay 'yas--field))))
|
|
||||||
(sof (marker-position (yas--field-start field))))
|
|
||||||
(when (and field (> (point) sof))
|
|
||||||
(delete-region sof (point)))))
|
|
||||||
|
|
||||||
;; Snippet helpers ;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-find-file ()
|
|
||||||
"Browse through snippets folder"
|
|
||||||
(interactive)
|
|
||||||
(projectile-find-file-in-directory (car yas-snippet-dirs)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/yas-ivy-prompt (prompt choices &optional display-fn)
|
|
||||||
(yas-completing-prompt prompt choices display-fn #'ivy-completing-read))
|
|
||||||
|
|
||||||
(provide 'defuns-yasnippet)
|
|
||||||
;;; nlinum-defuns.el ends here
|
|
|
@ -1,24 +0,0 @@
|
||||||
;;; macros-company.el --- macros for company-mode
|
|
||||||
;; for ../core-company.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-company-backend! (hooks backends)
|
|
||||||
"Register a company backend for a mode."
|
|
||||||
(let* ((hooks (if (listp hooks) hooks (list hooks)))
|
|
||||||
(def-name (intern (format "doom--init-company-%s"
|
|
||||||
(mapconcat 'identity (mapcar 'symbol-name hooks) "-"))))
|
|
||||||
(quoted (eq (car-safe backends) 'quote)))
|
|
||||||
`(progn
|
|
||||||
(defun ,def-name ()
|
|
||||||
(require 'company)
|
|
||||||
(set (make-local-variable 'company-backends)
|
|
||||||
(append '((,@(mapcar (lambda (backend)
|
|
||||||
(if quoted
|
|
||||||
backend
|
|
||||||
(intern (format "company-%s" backend))))
|
|
||||||
(if quoted (cadr backends) backends))))
|
|
||||||
company-backends)))
|
|
||||||
(add-hook! ,hooks ',def-name))))
|
|
||||||
|
|
||||||
(provide 'macros-company)
|
|
||||||
;;; macros-company.el ends here
|
|
|
@ -1,38 +0,0 @@
|
||||||
;;; macros-editor.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-electric! (modes &rest rest)
|
|
||||||
"Declare :words (list of strings) or :chars (lists of chars) in MODES that
|
|
||||||
trigger electric indentation."
|
|
||||||
(declare (indent 1))
|
|
||||||
(let ((modes (-list modes))
|
|
||||||
(chars (plist-get rest :chars))
|
|
||||||
(words (plist-get rest :words)))
|
|
||||||
(when (or chars words)
|
|
||||||
(let ((fn-name (intern (format "doom--electric-%s" (s-join "-" (mapcar 'symbol-name modes))))))
|
|
||||||
`(progn
|
|
||||||
(defun ,fn-name ()
|
|
||||||
(electric-indent-local-mode +1)
|
|
||||||
,(if chars `(setq electric-indent-chars ',chars))
|
|
||||||
,(if words `(setq doom-electric-indent-words ',words)))
|
|
||||||
(add-hook! ,modes ',fn-name))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-rotate! (modes &rest rest)
|
|
||||||
"Declare :symbols, :words or :patterns that `rotate-text' will cycle through."
|
|
||||||
(declare (indent 1))
|
|
||||||
(let ((modes (if (listp modes) modes (list modes)))
|
|
||||||
(symbols (plist-get rest :symbols))
|
|
||||||
(words (plist-get rest :words))
|
|
||||||
(patterns (plist-get rest :patterns)))
|
|
||||||
(when (or symbols words patterns)
|
|
||||||
(let ((fn-name (intern (format "doom--rotate-%s" (s-join "-" (mapcar 'symbol-name modes))))))
|
|
||||||
`(progn
|
|
||||||
(defun ,fn-name ()
|
|
||||||
,(if symbols `(setq-local rotate-text-local-symbols ',symbols))
|
|
||||||
,(if words `(setq-local rotate-text-local-words ',words))
|
|
||||||
,(if patterns `(setq-local rotate-text-local-patterns ',patterns)))
|
|
||||||
(add-hook! ,modes ',fn-name))))))
|
|
||||||
|
|
||||||
(provide 'macros-editor)
|
|
||||||
;;; macros-editor.el ends here
|
|
|
@ -1,23 +0,0 @@
|
||||||
;;; macros-eval.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-builder! (mode command &optional build-file)
|
|
||||||
"Register major/minor MODE with build COMMAND. If FILES are provided, do an additional
|
|
||||||
check to make sure they exist in the project root."
|
|
||||||
(let ((fn (intern (format "doom--init-builder-%s" mode))))
|
|
||||||
`(progn
|
|
||||||
(defun ,fn ()
|
|
||||||
(when (or (null ,build-file)
|
|
||||||
(doom/project-has-files ,build-file))
|
|
||||||
(setq doom--build-command '(,command . ,build-file))))
|
|
||||||
,(when (eq major-mode mode)
|
|
||||||
(funcall fn))
|
|
||||||
(add-hook! ,mode ',fn))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-repl! (mode command)
|
|
||||||
"Define a REPL for a mode."
|
|
||||||
`(push '(,mode . ,command) rtog/mode-repl-alist))
|
|
||||||
|
|
||||||
(provide 'macros-eval)
|
|
||||||
;;; macros-eval.el ends here
|
|
|
@ -1,31 +0,0 @@
|
||||||
;;; macros-evil.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defsubst def-text-obj! (key inner-fn &optional outer-fn)
|
|
||||||
(define-key evil-inner-text-objects-map key inner-fn)
|
|
||||||
(define-key evil-outer-text-objects-map key (or outer-fn inner-fn)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-tmp-excmd! (cmd-on cmd-off &rest commands)
|
|
||||||
"Creates a toggle for a set of ex commands, named CMD-ON and CMD-OFF."
|
|
||||||
(declare (indent 2))
|
|
||||||
`(progn
|
|
||||||
(defun ,cmd-on (&rest _)
|
|
||||||
(mapc (lambda (cmd) (evil-ex-define-cmd (car cmd) (cdr cmd)))
|
|
||||||
',commands))
|
|
||||||
(defun ,cmd-off (&rest _)
|
|
||||||
(mapc (lambda (cmd) (doom/evil-ex-undefine-cmd (car cmd)))
|
|
||||||
',commands))))
|
|
||||||
|
|
||||||
;; Shortcuts for the evil expression register
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro $= (str &rest args) `(calc-eval (format ,str ,@args)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro $r (char) `(evil-get-register ,char))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro $expand (path) `(evil-ex-replace-special-filenames ,path))
|
|
||||||
|
|
||||||
(provide 'macros-evil)
|
|
||||||
;;; macros-evil.el ends here
|
|
|
@ -1,8 +0,0 @@
|
||||||
;;; macros-popups.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-popup! (&rest params)
|
|
||||||
`(push ',params shackle-rules))
|
|
||||||
|
|
||||||
(provide 'macros-popups)
|
|
||||||
;;; macros-popups.el ends here
|
|
|
@ -1,24 +0,0 @@
|
||||||
;;; macros-rotate-text.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-rotate! (modes &rest rest)
|
|
||||||
(declare (indent 1))
|
|
||||||
(let ((modes (if (listp modes) modes (list modes)))
|
|
||||||
(symbols (plist-get rest :symbols))
|
|
||||||
(words (plist-get rest :words))
|
|
||||||
(patterns (plist-get rest :patterns))
|
|
||||||
fn-name)
|
|
||||||
(setq fn-name (intern (format "doom--rotate-%s"
|
|
||||||
(s-join "-" (mapcar 'symbol-name modes)))))
|
|
||||||
`(progn
|
|
||||||
(defun ,fn-name ()
|
|
||||||
,(when symbols
|
|
||||||
`(setq-local rotate-text-local-symbols ',symbols))
|
|
||||||
,(when words
|
|
||||||
`(setq-local rotate-text-local-words ',words))
|
|
||||||
,(when patterns
|
|
||||||
`(setq-local rotate-text-local-patterns ',patterns)))
|
|
||||||
(add-hook! ,modes ',fn-name))))
|
|
||||||
|
|
||||||
(provide 'macros-rotate-text)
|
|
||||||
;;; macros-rotate-text.el ends here
|
|
|
@ -1,13 +0,0 @@
|
||||||
;;; macros-yasnippet.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defmacro def-yas-mode! (mode)
|
|
||||||
"Register minor MODES in yasnippet."
|
|
||||||
`(after! yasnippet
|
|
||||||
(add-hook! ,mode
|
|
||||||
(if ,mode
|
|
||||||
(yas-activate-extra-mode ,mode)
|
|
||||||
(yas-deactivate-extra-mode ,mode)))))
|
|
||||||
|
|
||||||
(provide 'macros-yasnippet)
|
|
||||||
;;; macros-yasnippet.el ends here
|
|
Loading…
Add table
Add a link
Reference in a new issue