From 50ea98319f57f2d9a7df54281fbacaf8ec63eba4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 16 Jan 2017 23:15:48 -0500 Subject: [PATCH] Rewrite core libraries (WIP) --- core/core-autoinsert.el | 87 ---- core/core-autoload.el | 6 + core/core-company.el | 55 -- core/core-completion.el | 124 +++++ core/core-dashboard.el | 33 ++ core/core-defuns.el | 429 ---------------- core/core-docs.el | 42 -- core/core-editor.el | 427 +++++----------- core/core-eval.el | 49 -- core/core-evil.el | 301 +---------- core/core-helm.el | 180 ------- core/core-ivy.el | 43 -- core/core-lib.el | 247 +++++++++ core/core-modeline.el | 269 +++++----- core/core-os-linux.el | 48 -- core/core-os-osx.el | 126 ----- core/core-os-win32.el | 8 - core/core-os.el | 67 ++- core/core-packages.el | 211 ++++++++ core/core-popup.el | 159 ------ core/core-popups.el | 351 +++++++++++++ core/core-project.el | 127 +++-- core/core-repl.el | 6 + core/core-scratch.el | 196 -------- core/core-sessions.el | 6 + core/core-settings.el | 22 + core/core-snippets.el | 6 + core/core-states.el | 6 + ...re-flycheck.el => core-syntax-checking.el} | 24 +- core/core-ui.el | 470 ++++++++++-------- core/core-vcs.el | 110 ++-- core/core-workgroups.el | 88 ---- core/core-workspaces.el | 6 + core/core-yasnippet.el | 53 -- core/core.el | 319 ++++++------ core/defuns/defuns-auto-insert.el | 23 - core/defuns/defuns-buffers.el | 330 ------------ core/defuns/defuns-company.el | 70 --- core/defuns/defuns-docs.el | 31 -- core/defuns/defuns-editor.el | 58 --- core/defuns/defuns-embrace.el | 35 -- core/defuns/defuns-evil.el | 253 ---------- core/defuns/defuns-file.el | 72 --- core/defuns/defuns-flycheck.el | 33 -- core/defuns/defuns-git.el | 41 -- core/defuns/defuns-helm.el | 90 ---- core/defuns/defuns-highlight-indentation.el | 45 -- core/defuns/defuns-ido.el | 60 --- core/defuns/defuns-ivy.el | 140 ------ core/defuns/defuns-magit.el | 13 - core/defuns/defuns-neotree.el | 55 -- core/defuns/defuns-nlinum.el | 50 -- core/defuns/defuns-popups.el | 158 ------ core/defuns/defuns-projectile.el | 32 -- core/defuns/defuns-repl.el | 35 -- core/defuns/defuns-ui.el | 79 --- core/defuns/defuns-util.el | 39 -- core/defuns/defuns-whitespace.el | 198 -------- core/defuns/defuns-window.el | 128 ----- core/defuns/defuns-workgroup.el | 204 -------- core/defuns/defuns-yasnippet.el | 103 ---- core/defuns/macros-company.el | 24 - core/defuns/macros-editor.el | 38 -- core/defuns/macros-eval.el | 23 - core/defuns/macros-evil.el | 31 -- core/defuns/macros-popups.el | 8 - core/defuns/macros-rotate-text.el | 24 - core/defuns/macros-yasnippet.el | 13 - 68 files changed, 1892 insertions(+), 5345 deletions(-) delete mode 100644 core/core-autoinsert.el create mode 100644 core/core-autoload.el delete mode 100644 core/core-company.el create mode 100644 core/core-completion.el create mode 100644 core/core-dashboard.el delete mode 100644 core/core-defuns.el delete mode 100644 core/core-docs.el delete mode 100644 core/core-eval.el delete mode 100644 core/core-helm.el delete mode 100644 core/core-ivy.el create mode 100644 core/core-lib.el delete mode 100644 core/core-os-linux.el delete mode 100644 core/core-os-osx.el delete mode 100644 core/core-os-win32.el create mode 100644 core/core-packages.el delete mode 100644 core/core-popup.el create mode 100644 core/core-popups.el create mode 100644 core/core-repl.el delete mode 100644 core/core-scratch.el create mode 100644 core/core-sessions.el create mode 100644 core/core-settings.el create mode 100644 core/core-snippets.el create mode 100644 core/core-states.el rename core/{core-flycheck.el => core-syntax-checking.el} (61%) delete mode 100644 core/core-workgroups.el create mode 100644 core/core-workspaces.el delete mode 100644 core/core-yasnippet.el delete mode 100644 core/defuns/defuns-auto-insert.el delete mode 100644 core/defuns/defuns-buffers.el delete mode 100644 core/defuns/defuns-company.el delete mode 100644 core/defuns/defuns-docs.el delete mode 100644 core/defuns/defuns-editor.el delete mode 100644 core/defuns/defuns-embrace.el delete mode 100644 core/defuns/defuns-evil.el delete mode 100644 core/defuns/defuns-file.el delete mode 100644 core/defuns/defuns-flycheck.el delete mode 100644 core/defuns/defuns-git.el delete mode 100644 core/defuns/defuns-helm.el delete mode 100644 core/defuns/defuns-highlight-indentation.el delete mode 100644 core/defuns/defuns-ido.el delete mode 100644 core/defuns/defuns-ivy.el delete mode 100644 core/defuns/defuns-magit.el delete mode 100644 core/defuns/defuns-neotree.el delete mode 100644 core/defuns/defuns-nlinum.el delete mode 100644 core/defuns/defuns-popups.el delete mode 100644 core/defuns/defuns-projectile.el delete mode 100644 core/defuns/defuns-repl.el delete mode 100644 core/defuns/defuns-ui.el delete mode 100644 core/defuns/defuns-util.el delete mode 100644 core/defuns/defuns-whitespace.el delete mode 100644 core/defuns/defuns-window.el delete mode 100644 core/defuns/defuns-workgroup.el delete mode 100644 core/defuns/defuns-yasnippet.el delete mode 100644 core/defuns/macros-company.el delete mode 100644 core/defuns/macros-editor.el delete mode 100644 core/defuns/macros-eval.el delete mode 100644 core/defuns/macros-evil.el delete mode 100644 core/defuns/macros-popups.el delete mode 100644 core/defuns/macros-rotate-text.el delete mode 100644 core/defuns/macros-yasnippet.el diff --git a/core/core-autoinsert.el b/core/core-autoinsert.el deleted file mode 100644 index 67c41b710..000000000 --- a/core/core-autoinsert.el +++ /dev/null @@ -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 diff --git a/core/core-autoload.el b/core/core-autoload.el new file mode 100644 index 000000000..94e5697e3 --- /dev/null +++ b/core/core-autoload.el @@ -0,0 +1,6 @@ +;;; core-autoload.el + + + +(provide 'core-autoload) +;;; core-autoload.el ends here diff --git a/core/core-company.el b/core/core-company.el deleted file mode 100644 index 96ed1afdb..000000000 --- a/core/core-company.el +++ /dev/null @@ -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 diff --git a/core/core-completion.el b/core/core-completion.el new file mode 100644 index 000000000..b33f0b4fa --- /dev/null +++ b/core/core-completion.el @@ -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 diff --git a/core/core-dashboard.el b/core/core-dashboard.el new file mode 100644 index 000000000..62b3ec13a --- /dev/null +++ b/core/core-dashboard.el @@ -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 diff --git a/core/core-defuns.el b/core/core-defuns.el deleted file mode 100644 index f1d29a8cc..000000000 --- a/core/core-defuns.el +++ /dev/null @@ -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 diff --git a/core/core-docs.el b/core/core-docs.el deleted file mode 100644 index 53289adc4..000000000 --- a/core/core-docs.el +++ /dev/null @@ -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 diff --git a/core/core-editor.el b/core/core-editor.el index 6929f56b1..d4ae2ade8 100644 --- a/core/core-editor.el +++ b/core/core-editor.el @@ -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 -;; Enable syntax highlighting for older emacs -(unless (bound-and-true-p global-font-lock-mode) - (global-font-lock-mode t)) +;; Bookmarks +(setq bookmark-default-file (concat doom-temp-dir "/bookmarks") + bookmark-save-flag t) -(setq-default - ;; Formatting - delete-trailing-lines nil - fill-column 80 - ;; Spaces, not tabs - indent-tabs-mode nil - require-final-newline t - tab-always-indent t - tab-width 4 - ;; Wrapping - truncate-lines t - truncate-partial-width-windows 50 - visual-fill-column-center-text nil - word-wrap t - ;; Scrolling - hscroll-margin 1 - hscroll-step 1 - scroll-conservatively 1001 - scroll-margin 0 - scroll-preserve-screen-position t - ;; Regions - shift-select-mode t - ;; Whitespace - tabify-regexp "^\t* [ \t]+" - whitespace-line-column fill-column - whitespace-style '(face tabs tab-mark - trailing indentation lines-tail) - whitespace-display-mappings - '((tab-mark ?\t [?› ?\t]) - (newline-mark 10 [36 10]))) +;; Formatting +(setq delete-trailing-lines nil + fill-column 80 + sentence-end-double-space nil) + +;; Scrolling +(setq hscroll-margin 1 + hscroll-step 1 + scroll-conservatively 1001 + scroll-margin 0 + scroll-preserve-screen-position t) + +;; Whitespace (see `editorconfig') +(setq indent-tabs-mode nil + require-final-newline t + tab-always-indent t + tab-width 4 + tabify-regexp "^\t* [ \t]+" ; for :retab + whitespace-line-column fill-column + whitespace-style + '(face tabs tab-mark trailing indentation lines-tail) + whitespace-display-mappings + '((tab-mark ?\t [?› ?\t]) (newline-mark 10 [36 10]))) + +;; Wrapping +(setq truncate-lines t + truncate-partial-width-windows 50 + visual-fill-column-center-text nil + word-wrap t) + +;; Regions +(setq shift-select-mode t) ;; Save point across sessions (require 'saveplace) -(setq-default - save-place-file (concat doom-temp-dir "/saveplace") - save-place t) +(setq save-place-file (concat doom-temp-dir "saveplace") + save-place t) (when (>= emacs-major-version 25) (save-place-mode +1)) ;; Save history across sessions (require 'savehist) -(setq savehist-file (concat doom-temp-dir "/savehist") +(setq savehist-file (concat doom-temp-dir "savehist") savehist-save-minibuffer-history t savehist-additional-variables '(kill-ring search-ring regexp-search-ring)) (savehist-mode 1) -;; Remove text property cruft from history +;; Remove text-property cruft from history (defun unpropertize-savehist () (mapc (lambda (list) (when (boundp list) @@ -65,7 +65,7 @@ ;; Keep track of recently opened files (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$" "emacs\\.d/private/cache/.+" "emacs\\.d/workgroups/.+$" "wg-default" "/company-statistics-cache.el$" @@ -76,18 +76,21 @@ recentf-filename-handlers '(abbreviate-file-name)) (recentf-mode 1) -;; window config undo/redo -(setq winner-dont-bind-my-keys t) -(require 'winner) -;; Ignore all special buffers -(advice-add 'winner-window-list :filter-return 'doom*winner-window-list) -(defun doom*winner-window-list (windows) - (-remove (lambda (win) (string-match-p "^\\s-*\\*" (buffer-name (window-buffer win)))) - windows)) -(winner-mode 1) +;; Ediff +(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 -;; Let editorconfig handle global whitespace settings -(use-package editorconfig :demand t +;; revert buffers for changed files +(global-auto-revert-mode +1) + + +;; +;; Plugins +;; + +(package! editorconfig :demand t :mode ("\\.?editorconfig$" . editorconfig-conf-mode) :config (editorconfig-mode +1) (push 'doom-mode editorconfig-exclude-modes) @@ -95,164 +98,15 @@ (add-hook! 'editorconfig-custom-hooks (if indent-tabs-mode (whitespace-mode +1)))) - -;; -;; 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) +(package! smartparens :demand t :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 sp-highlight-pair-overlay nil sp-cancel-autoskip-on-backward-movement nil sp-show-pair-delay 0 sp-max-pair-length 3) + + :config (smartparens-global-mode 1) (require 'smartparens-config) ;; Smartparens interferes with Replace mode @@ -271,19 +125,78 @@ (sp-local-pair 'css-mode "/*" "*/" :post-handlers '(("[d-3]||\n[i]" "RET") ("| " "SPC"))) (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-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 - (setq smex-save-file (concat doom-temp-dir "/smex-items")) - (smex-initialize)) + (emr-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) :config (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-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! " " 'doom/mouse-drag-line - " " 'doom/mouse-select-line - " " '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 "" 'doom/dumb-indent - :i "" 'doom/dumb-dedent - :i "" 'indent-for-tab-command - :i "" (λ! (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 "" 'delete-char - ;; Fix osx keymappings and then some - :i "" 'doom/move-to-bol - :i "" 'doom/move-to-eol - :i "" 'beginning-of-buffer - :i "" 'end-of-buffer - :i "" 'smart-up - :i "" '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 "" '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) ;;; core-editor.el ends here diff --git a/core/core-eval.el b/core/core-eval.el deleted file mode 100644 index 46ed3cc5b..000000000 --- a/core/core-eval.el +++ /dev/null @@ -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 "" 'comint-next-input - :ei "" 'comint-previous-input)) - -(provide 'core-eval) -;;; core-eval.el ends here diff --git a/core/core-evil.el b/core/core-evil.el index 71c741609..e8f2b11e6 100644 --- a/core/core-evil.el +++ b/core/core-evil.el @@ -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 (setq evil-magic t evil-want-C-u-scroll t @@ -19,288 +32,16 @@ evil-emacs-state-tag "E" evil-operator-state-tag "O" evil-motion-state-tag "M" - 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) + evil-replace-state-tag "R") :config - (evil-mode 1) - (evil-select-search-module 'evil-search-module 'evil-search) + (evil-mode +1) + (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) - (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 "" - :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 "") - (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 "") - (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)) +;; +;; Autoloaded Packages +;; (provide 'core-evil) ;;; core-evil.el ends here diff --git a/core/core-helm.el b/core/core-helm.el deleted file mode 100644 index dbd34ebe3..000000000 --- a/core/core-helm.el +++ /dev/null @@ -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 - "" 'backward-char - "" 'forward-char - "" 'helm-keyboard-quit - "ESC" 'helm-keyboard-quit - [escape] 'helm-keyboard-quit - "" '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 - "" 'helm-ag-edit - :map helm-ag-edit-map - "" '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 diff --git a/core/core-ivy.el b/core/core-ivy.el deleted file mode 100644 index 2a103ec61..000000000 --- a/core/core-ivy.el +++ /dev/null @@ -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 diff --git a/core/core-lib.el b/core/core-lib.el new file mode 100644 index 000000000..9624b4ac8 --- /dev/null +++ b/core/core-lib.el @@ -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 diff --git a/core/core-modeline.el b/core/core-modeline.el index f781cabde..de1fe34b3 100644 --- a/core/core-modeline.el +++ b/core/core-modeline.el @@ -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 ;; Required @@ -17,22 +17,25 @@ ;;(require 'iedit) ;;(require 'evil-multiedit) -(require 'powerline) -(require 'all-the-icons) +(package! powerline) + +(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 ;; +(defvar doom-modeline-formats '() + "") + (defvar doom-modeline-height 29 "How tall the mode-line should be (only respected in GUI emacs).") @@ -44,30 +47,37 @@ ;; 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.") (defface doom-modeline-buffer-project '((t (:inherit doom-modeline-buffer-path :bold nil))) "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.") -(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.") -(defface doom-modeline-highlight '((t (:inherit mode-line))) +(defface doom-modeline-highlight + '((t (:inherit 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 `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'.") -(defface doom-modeline-warning `((t (:inherit warning))) +(defface doom-modeline-warning + `((t (:inherit warning))) "Face for warnings in the modeline. Used by `*flycheck'") (defface doom-modeline-urgent `((t (:inherit error))) @@ -86,37 +96,41 @@ active.") ;; -;; Functions +;; Bootstrap ;; -;; Where (py|rb)env version strings will be stored -(defvar-local doom-ml--env-version nil) -(defvar-local doom-ml--env-command nil) +;; 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 _) "" "")) -(add-hook 'focus-in-hook 'doom-ml|env-update) -(add-hook 'find-file-hook 'doom-ml|env-update) +(defmacro modeline! (name &rest def) + (declare (indent defun))) ;; TODO -(defun doom-ml|env-update () - "Update (py|rb)env version string in `doom-ml--env-version', generated with -`doom-ml--env-command'." - (when doom-ml--env-command - (let* ((default-directory (doom/project-root)) +(defvar-local doom-modeline-env-version nil) +(defvar-local doom-modeline-env-command nil) +(add-hook 'focus-in-hook 'doom-modeline|update-env) +(add-hook 'find-file-hook 'doom-modeline|update-env) +(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))) - (setq doom-ml--env-version (if (string-match "[ \t\n\r]+\\'" s) - (replace-match "" t t s) - s))))) + (setq doom-modeline-env-version (if (string-match "[ \t\n\r]+\\'" s) + (replace-match "" t t s) + s))))) -(defmacro def-version-cmd! (mode command) - "Define a COMMAND for MODE that will set `doom-ml--env-command' when that mode -is activated, which should return the version number of the current environment. -It is used by `doom-ml|env-update' to display a version number in the modeline. -For instance: +(doom-define-setting 'env + "Command used to set the interpreter version in the current buffer." + :type '(stringp functionp) + :hook (lambda (command) (setq doom-modeline-env-command x))) - (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 -cached the first time." - `(add-hook ',mode (lambda () (setq doom-ml--env-command ,command)))) +(defsubst active() (eq (selected-window) powerline-selected-window)) (defun doom-ml-flycheck-count (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) "Create an XPM bitmap." + (unless (featurep 'powerline) + (require 'powerline) + (pl/memoize 'doom-make-xpm)) (when window-system (propertize " " 'display @@ -140,7 +157,7 @@ cached the first time." project root). Excludes the file basename. See `doom-buffer-name' for that." (if 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)))) (when (and buffer-path (not (equal buffer-path "."))) (if (> (length buffer-path) max-length) @@ -159,16 +176,35 @@ project root). Excludes the file basename. See `doom-buffer-name' for that." buffer-path))) "%b")) -(defsubst active () (eq (selected-window) powerline-selected-window)) - -;; Memoize for optimization -(pl/memoize 'doom-make-xpm) -(pl/memoize 'face-background) -(pl/memoize 'all-the-icons-octicon) +(defun doom-eldoc-show-in-mode-line (input) + "Display string STR in the mode-line next to minibuffer." + (with-current-buffer (eldoc-current-buffer) + (let* ((max (window-width (selected-window))) + (str (and (stringp input) (concat " " input))) + (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 () @@ -179,7 +215,7 @@ project root). Excludes the file basename. See `doom-buffer-name' for that." :face face :v-adjust -0.05 :height 1.25) - (propertize (concat " " (abbreviate-file-name (doom/project-root))) + (propertize (concat " " (abbreviate-file-name (doom-project-root))) 'face face)))) (defun *buffer-info () @@ -230,7 +266,7 @@ directory, the file name, and its state (modified, read-only or non-existent)." (propertize (concat (format-mode-line mode-name) (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) (/= text-scale-mode-amount 0) (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))) (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 () - `(:eval - (list (list ,(when window-system - `(doom-make-xpm (face-background 'doom-modeline-eldoc-bar) - doom-modeline-height - doom-modeline-bar-width)) - (and (bound-and-true-p str) str)) - (propertize " " 'display `((space :align-to (1- (+ right right-fringe right-margin)))))))) +(doom-modeline-define 'main + `(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) + (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) - "Display string STR in the mode-line next to minibuffer." - (with-current-buffer (eldoc-current-buffer) - (let* ((max (window-width (selected-window))) - (str (and (stringp input) (concat " " input))) - (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))) +(doom-modeline-define 'eldoc + `(list (list ,(when window-system + `(doom-make-xpm (face-background 'doom-modeline-eldoc-bar) + doom-modeline-height + doom-modeline-bar-width)) + (and (bound-and-true-p str) str)) + (propertize " " 'display `((space :align-to (1- (+ right right-fringe right-margin))))))) -;; Show eldoc in the mode-line when using `eval-expression'. -(use-package eldoc-eval - :config - (setq eldoc-in-minibuffer-show-fn 'doom-eldoc-show-in-mode-line) - (eldoc-in-minibuffer-mode +1)) +(doom-modeline-define 'minimal + `(let* ((lhs (list (doom-make-xpm (face-background (if (active) + 'doom-modeline-bar + 'doom-modeline-inactive-bar)) + 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) ;;; core-modeline.el ends here diff --git a/core/core-os-linux.el b/core/core-os-linux.el deleted file mode 100644 index 54b93115a..000000000 --- a/core/core-os-linux.el +++ /dev/null @@ -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 diff --git a/core/core-os-osx.el b/core/core-os-osx.el deleted file mode 100644 index e720ba7af..000000000 --- a/core/core-os-osx.el +++ /dev/null @@ -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 diff --git a/core/core-os-win32.el b/core/core-os-win32.el deleted file mode 100644 index bdf3df84c..000000000 --- a/core/core-os-win32.el +++ /dev/null @@ -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 diff --git a/core/core-os.el b/core/core-os.el index 4748c2eae..a9cdd497b 100644 --- a/core/core-os.el +++ b/core/core-os.el @@ -1,28 +1,59 @@ -;;; core-os.el +;;; core-os.el --- consistent behavior across OSes (defconst IS-MAC (eq system-type 'darwin)) (defconst IS-LINUX (eq system-type 'gnu/linux)) (defconst IS-WINDOWS (eq system-type 'windows-nt)) -(setq - ;; Use a shared clipboard - x-select-enable-clipboard t - select-enable-clipboard t - ;; Treat clipboard input as UTF-8 string first; compound text next, etc. - x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) +(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING) + ;; Use a shared clipboard + select-enable-clipboard t + select-enable-primary t) -;; 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)) - (IS-WINDOWS (require 'core-os-win32))) +;;; +;; OS-specific configs +(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) ;;; core-os.el ends here diff --git a/core/core-packages.el b/core/core-packages.el new file mode 100644 index 000000000..58f363675 --- /dev/null +++ b/core/core-packages.el @@ -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 diff --git a/core/core-popup.el b/core/core-popup.el deleted file mode 100644 index c16bd2f5e..000000000 --- a/core/core-popup.el +++ /dev/null @@ -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 "" '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 diff --git a/core/core-popups.el b/core/core-popups.el new file mode 100644 index 000000000..63503018c --- /dev/null +++ b/core/core-popups.el @@ -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 "" '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 diff --git a/core/core-project.el b/core/core-project.el index 8a8e80fe0..f935af9ff 100644 --- a/core/core-project.el +++ b/core/core-project.el @@ -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 - dired-recursive-copies 'always - dired-recursive-deletes 'top - ;; Auto refresh dired, but be quiet about it - global-auto-revert-non-file-buffers t - auto-revert-verbose nil) +;; I want Emacs project-aware. i.e. To know what project I'm in, and to be able +;; to tell me about it. `projectile' helps me with this. It also provides nifty +;; tools for digging out files I want from a project of any size. +;; +;; `neotree', on the other hand, allows me to browse my project files. I +;; occasionally like having a birds-eye view of my files. -;; List directories first -(defun doom|dired-sort () - "Dired sort hook to list directories first." - (save-excursion - (let (buffer-read-only) - (forward-line 2) ;; beyond dir. header - (sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))) - (and (featurep 'xemacs) - (fboundp 'dired-insert-set-properties) - (dired-insert-set-properties (point-min) (point-max))) - (set-buffer-modified-p nil)) -(add-hook 'dired-after-readin-hook 'doom|dired-sort) +(package! projectile :demand t + :init + (setq projectile-cache-file (concat doom-temp-dir "/projectile.cache") + projectile-completion-system 'ivy + projectile-enable-caching t + projectile-file-exists-remote-cache-expire nil + projectile-globally-ignored-directories `(,doom-temp-dir ".sync") + projectile-globally-ignored-file-suffixes '(".elc" ".pyc" ".o") + projectile-globally-ignored-files '(".DS_Store" "Icon ") + projectile-indexing-method 'alien + projectile-known-projects-file (concat doom-temp-dir "/projectile.projects") + projectile-project-root-files '(".git" ".hg" ".svn" ".project") + projectile-require-project-root nil) -(use-package dired-k - :after dired :config - (setq dired-k-style 'git) - (add-hook 'dired-initial-position-hook 'dired-k) - (add-hook 'dired-after-readin-hook #'dired-k-no-revert)) + (mapc (lambda (r) (push r projectile-other-file-alist)) + '(("less" "css") + ("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|create-non-existent-directory () - (let ((parent-directory (file-name-directory buffer-file-name))) - (when (and (not (file-exists-p parent-directory)) - (y-or-n-p (format "Directory `%s' does not exist! Create it?" parent-directory))) - (make-directory parent-directory t)))) -(push 'doom|create-non-existent-directory find-file-not-found-functions) + (defun doom*projectile-cache-current-file (orig-fun &rest args) + "Don't cache ignored files." + (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) -(use-package neotree + (projectile-global-mode +1)) + + +;; +;; Autoloaded Packages +;; + +(package! neotree :commands (neotree-show neotree-hide neotree-toggle @@ -51,23 +62,30 @@ neo-window-width 25 neo-show-updir-line nil 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 (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 ;; overridden when the neotree buffer is spawned). So we bind them in a hook. (add-hook 'neo-after-create-hook 'doom|neotree-init-keymap) (defun doom|neotree-init-keymap (&rest _) (map! :Lm "\\\\" 'evil-window-prev - :Lm "ESC ESC" 'doom/neotree-close - :Lm "q" 'doom/neotree-close + :Lm "ESC ESC" 'neotree-hide + :Lm "q" 'neotree-hide :Lm [return] 'neotree-enter :Lm "RET" 'neotree-enter :Lm "" 'neotree-enter @@ -83,32 +101,5 @@ :Lm "r" 'neotree-rename-node :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) ;;; core-project.el ends here diff --git a/core/core-repl.el b/core/core-repl.el new file mode 100644 index 000000000..ab1884322 --- /dev/null +++ b/core/core-repl.el @@ -0,0 +1,6 @@ +;;; core-repl.el + +;; TODO + +(provide 'core-repl) +;;; core-repl.el ends here diff --git a/core/core-scratch.el b/core/core-scratch.el deleted file mode 100644 index f340411e5..000000000 --- a/core/core-scratch.el +++ /dev/null @@ -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 diff --git a/core/core-sessions.el b/core/core-sessions.el new file mode 100644 index 000000000..72245346c --- /dev/null +++ b/core/core-sessions.el @@ -0,0 +1,6 @@ +;;; core-sessions.el + +;; TODO + +(provide 'core-sessions) +;;; core-sessions.el ends here diff --git a/core/core-settings.el b/core/core-settings.el new file mode 100644 index 000000000..86583ee16 --- /dev/null +++ b/core/core-settings.el @@ -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 diff --git a/core/core-snippets.el b/core/core-snippets.el new file mode 100644 index 000000000..eba74827c --- /dev/null +++ b/core/core-snippets.el @@ -0,0 +1,6 @@ +;;; core-snippets.el + +;; TODO + +(provide 'core-snippets) +;;; core-snippets.el ends here diff --git a/core/core-states.el b/core/core-states.el new file mode 100644 index 000000000..250cc61a3 --- /dev/null +++ b/core/core-states.el @@ -0,0 +1,6 @@ +;;; core-states.el + + + +(provide 'core-states) +;;; core-states.el ends here diff --git a/core/core-flycheck.el b/core/core-syntax-checking.el similarity index 61% rename from core/core-flycheck.el rename to core/core-syntax-checking.el index 19f8009da..fbfa459b2 100644 --- a/core/core-flycheck.el +++ b/core/core-syntax-checking.el @@ -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) :init (setq flycheck-indication-mode 'right-fringe @@ -13,7 +13,7 @@ flycheck-display-errors-delay 0.5) :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 :n "C-n" 'flycheck-error-list-next-error @@ -23,16 +23,20 @@ :n "RET" 'flycheck-error-list-goto-error) ;; 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) (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) - (require 'flycheck-pos-tip) - (flycheck-pos-tip-mode +1))) +;; NOTE Looks bad on emacs-mac build on MacOS +(package! flycheck-pos-tip + :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) -;;; core-flycheck.el ends here +(provide 'core-syntax-checking) +;;; core-syntax-checking.el ends here diff --git a/core/core-ui.el b/core/core-ui.el index a83edc27e..21eca6aa9 100644 --- a/core/core-ui.el +++ b/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 "Default fringe width") @@ -14,204 +14,40 @@ (font-spec :family "Fira Sans" :size 12) "The font currently in use.") +(defvar doom-ui-unicode-font + (font-spec :family "DejaVu Sans Mono" :size 12) + "Fallback font for unicode glyphs.") -;; -;; Configuration -;; - -(setq-default - mode-line-default-help-echo nil ; don't say anything on mode-line mouseover - indicate-buffer-boundaries nil ; don't show where buffer starts/ends - indicate-empty-lines nil ; don't show empty lines - fringes-outside-margins t ; switches order of fringe and margin - ;; Keep cursors and highlights in current window only - cursor-in-non-selected-windows nil - highlight-nonselected-windows nil - ;; Disable bidirectional text support for slight performance bonus - bidi-display-reordering nil - ;; Remove continuation arrow on right fringe - fringe-indicator-alist (delq (assq 'continuation fringe-indicator-alist) - fringe-indicator-alist) - - blink-matching-paren nil ; don't blink--too distracting - show-paren-delay 0.075 - show-paren-highlight-openparen t - show-paren-when-point-inside-paren t - uniquify-buffer-name-style nil - visible-bell nil - visible-cursor nil - x-stretch-cursor t - use-dialog-box nil ; always avoid GUI - redisplay-dont-pause t ; don't pause display on input - split-width-threshold nil ; favor horizontal splits - show-help-function nil ; hide :help-echo text - 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)) +(setq bidi-display-reordering nil ; disable bidirectional text for tiny performance boost + blink-matching-paren nil ; don't blink--too distracting + cursor-in-non-selected-windows nil + echo-keystrokes 0.02 + frame-inhibit-implied-resize t + ;; remove continuation arrow on right fringe + fringe-indicator-alist (delq (assq 'continuation fringe-indicator-alist) + fringe-indicator-alist) + highlight-nonselected-window nil + image-animate-loop t + indicate-buffer-boundaries nil + indicate-empty-lines nil + jit-lock-defer-time nil + jit-lock-stealth-nice 0.1 + jit-lock-stealth-time 0.2 + jit-lock-stealth-verbose nil + max-mini-window-height 0.3 + mode-line-default-help-echo nil ; disable mode-line mouseovers + redisplay-dont-pause t ; don't pause display on input + resize-mini-windows 'grow-only ; Minibuffer resizing + show-help-function nil ; hide :help-echo text + show-paren-delay 0.075 + show-paren-highlight-openparen t + show-paren-when-point-inside-paren t + split-width-threshold nil ; favor horizontal splits + uniquify-buffer-name-style nil + use-dialog-box nil ; always avoid GUI + visible-bell nil + visible-cursor nil + x-stretch-cursor t) ;; @@ -229,9 +65,11 @@ (with-demoted-errors "FONT ERROR: %s" (set-frame-font doom-ui-font t t) ;; 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-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 (fringe-mode doom-ui-fringe-size) (push `(left-fringe . ,doom-ui-fringe-size) default-frame-alist) @@ -244,5 +82,237 @@ (set-fringe-bitmap-face 'tilde 'fringe) (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) ;;; core-ui.el ends here diff --git a/core/core-vcs.el b/core/core-vcs.el index e8833690c..16d13cc01 100644 --- a/core/core-vcs.el +++ b/core/core-vcs.el @@ -1,27 +1,23 @@ -;;; core-vcs.el --- version control awareness +;;; core-vcs.el -(use-package gitconfig-mode - :mode ("/\\.?git/?config$" "/\\.gitmodules$") +(package! gitconfig-mode + :mode "/\\.?git/?config$" + :mode "/\\.gitmodules$" :init (add-hook 'gitconfig-mode-hook 'flyspell-mode)) -(use-package gitignore-mode - :mode ("/\\.gitignore$" - "/\\.git/info/exclude$" - "/git/ignore$")) +(package! gitignore-mode + :mode "/\\.gitignore$" + :mode "/\\.git/info/exclude$" + :mode "/git/ignore$") -(use-package git-gutter - :commands (git-gutter-mode doom/vcs-next-hunk doom/vcs-prev-hunk - doom/vcs-show-hunk doom/vcs-stage-hunk doom/vcs-revert-hunk) - :init - (add-hook! (text-mode prog-mode conf-mode) 'git-gutter-mode) +(package! git-gutter-fringe + :commands git-gutter-mode + :init (add-hook! (text-mode prog-mode conf-mode) 'git-gutter-mode) :config - (require 'git-gutter-fringe) - (def-popup! "^\\*git-gutter.+\\*$" :align below :size 15 :noselect t :regexp t) + ;; places the git gutter outside the margins. + (setq-default fringes-outside-margins t) - ;; NOTE If you want the git gutter to be on the outside of the margins (rather - ;; than inside), `fringes-outside-margins' should be non-nil. - - ;; colored fringe "bars" + ;; thin fringe bitmaps (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] 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] nil nil 'center) - ;; Refreshing git-gutter + ;; Refreshing git-gutter on ESC and focus (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) - (defalias 'doom/vcs-prev-hunk 'git-gutter:previous-hunk) - (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)) +(package! magit + :commands magit-status :config - (def-popup! "*git-messenger*" :align left :size 55 :select t) - (setq git-messenger:show-detail t) - (map! :map git-messenger-map - "" '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 (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 ;; Don't let Tab binding in my-bindings conflict with Tab in magit @@ -69,6 +45,11 @@ :nv "C-j" 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 (evil-set-initial-state 'vc-annotate-mode 'normal) (evil-set-initial-state 'vc-git-log-view-mode 'normal) @@ -82,24 +63,41 @@ :n [tab] 'vc-annotate-toggle-annotation-visibility :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) -(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 +;; +;; Defuns +;; - ;; Brighten other buffers - (add-hook 'ediff-prepare-buffer-hook 'doom-buffer-mode) +(defun doom-git-root () + "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 - (add-hook! ediff-startup (setq doom-ediff-enabled t)) - (add-hook! ediff-quit (setq doom-ediff-enabled nil))) +(evil-define-command doom:git-browse (&optional bang) + "Open the website for the current (or specified) version controlled FILE. If +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) ;;; core-vcs.el ends here diff --git a/core/core-workgroups.el b/core/core-workgroups.el deleted file mode 100644 index 997e0d781..000000000 --- a/core/core-workgroups.el +++ /dev/null @@ -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 - -(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 diff --git a/core/core-workspaces.el b/core/core-workspaces.el new file mode 100644 index 000000000..9cedfd3af --- /dev/null +++ b/core/core-workspaces.el @@ -0,0 +1,6 @@ +;;; core-workspaces.el + + + +(provide 'core-workspaces) +;;; core-workspaces.el ends here diff --git a/core/core-yasnippet.el b/core/core-yasnippet.el deleted file mode 100644 index c009ddf2e..000000000 --- a/core/core-yasnippet.el +++ /dev/null @@ -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 - "" 'doom/yas-goto-end-of-field - "" 'doom/yas-goto-start-of-field - "" 'yas-prev-field - "" 'doom/yas-clear-to-sof - "" 'evil-normal-state - [backspace] 'doom/yas-backspace - "" '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 diff --git a/core/core.el b/core/core.el index 0c62c40d6..e15a4a582 100644 --- a/core/core.el +++ b/core/core.el @@ -1,99 +1,56 @@ ;;; core.el --- The heart of the beast -;; + ;;; Naming conventions: ;; -;; doom-... A public variable/constant or function -;; doom--... An internal variable or function (non-interactive) -;; doom/... An autoloaded function -;; doom:... An ex command -;; doom|... A hook -;; doom*... An advising function -;; ...! Macro, shortcut alias or subst defun -;; @... Autoloaded interactive lambda macro for keybinds +;; doom-... A public variable or function (non-interactive use) +;; doom--... A private variable, function (non-interactive use) or macro +;; doom/... An interactive function +;; doom:... An evil operator, motion or command +;; doom|... A hook +;; doom*... An advising function +;; ...! Macro, shortcut alias or defsubst +;; @... 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 -;; Premature optimization for faster startup -(setq-default gc-cons-threshold 339430400 - gc-cons-percentage 0.6) +(when (version< emacs-version "25.1") + (error "DOOM Emacs no longer supports Emacs <25.1! Time to upgrade!")) -;; -;; Global Constants -;; - -(defconst doom-version "1.3.1" +;;; +(defvar doom-version "2.0.0" "Current version of DOOM emacs") -(defconst doom-emacs-dir - (expand-file-name user-emacs-directory) +(defvar doom-emacs-dir user-emacs-directory "The path to this emacs.d directory") -(defconst doom-core-dir - (expand-file-name "core" doom-emacs-dir) +(defvar doom-core-dir (concat doom-emacs-dir "core/") "Where essential files are stored") -(defconst doom-modules-dir - (expand-file-name "modules" doom-emacs-dir) +(defvar doom-modules-dir (concat doom-emacs-dir "modules/") "Where configuration modules are stored") -(defconst doom-private-dir - (expand-file-name "private" doom-emacs-dir) +(defvar doom-private-dir (concat doom-emacs-dir "private/") "Where private configuration filse and assets are stored (like snippets)") -(defconst doom-packages-dir - (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) +(defvar doom-scripts-dir (concat doom-emacs-dir "scripts/") "Where external dependencies are stored (like libraries or binaries)") -(defconst doom-themes-dir - (expand-file-name "themes" doom-private-dir) +(defvar doom-packages-dir (concat doom-private-dir "packages/") + "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") -(defconst doom-temp-dir - (format "%s/cache/%s" doom-private-dir (system-name)) +(defvar doom-temp-dir + (concat doom-private-dir "cache/" (system-name) "/") "Hostname-based elisp temp directories") -(defconst doom-org-dir - (expand-file-name "~/org") +(defvar doom-org-dir "~/org/" "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 bindings") -(defconst doom-localleader "\\" "Prefix for 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 (set-charset-priority 'unicode) ; 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-selection-coding-system 'utf-8) ; please (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 -(if (boundp 'buffer-file-coding-system) - (setq-default buffer-file-coding-system 'utf-8) - (setq default-buffer-file-coding-system 'utf-8)) - -;; Don't pester me package.el. Cask is my one and only. -(setq-default - 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 +;; Configuration +(setq ad-redefinition-accept 'accept ; silence advised function warnings + apropos-do-all t ; make `apropos' more useful + byte-compile-warnings nil + compilation-always-kill t + compilation-ask-about-save nil + compilation-scroll-output t confirm-nonexistent-file-or-buffer t - delete-by-moving-to-trash t - echo-keystrokes 0.02 ; show me what I type - enable-recursive-minibuffers nil ; no minibufferception - idle-update-delay 5 ; update a little less often - major-mode 'text-mode - save-interprogram-paste-before-kill nil - sentence-end-double-space nil - ;; http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html - minibuffer-prompt-properties - '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt) - ;; persistent bookmarks - bookmark-save-flag t - bookmark-default-file (concat doom-temp-dir "/bookmarks") - ;; 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/")))) + enable-recursive-minibuffers nil + idle-update-delay 5 + minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt) + save-interprogram-paste-before-kill nil) + +;; History & backup settings +(setq auto-save-default nil + auto-save-list-file-name (concat doom-temp-dir "/autosave") + backup-directory-alist (list (cons ".*" (concat doom-temp-dir "/backup/"))) + create-lockfiles nil + history-length 1000 + make-backup-files nil + vc-make-backup-files nil) -;; -;; 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 -;; - (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 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) +;;; +;; 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) -(require 's) -(require 'f) + `(let (file-name-handler-alist) + (unless noninteractive + (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 - :commands (awhen aif acond awhile)) + (unless noninteractive + (require 'my-bindings) + (require 'my-commands) -(use-package persistent-soft - :commands (persistent-soft-store - persistent-soft-fetch - persistent-soft-exists-p - persistent-soft-flush - persistent-soft-location-readable - persistent-soft-location-destroy) - :init (defvar pcache-directory (concat doom-temp-dir "/pcache/"))) + (when (display-graphic-p) + (require 'server) + (unless (server-running-p) + (server-start))) -(use-package async - :commands (async-start - async-start-process - async-get - async-wait - async-inject-variables)) - -(use-package json - :commands (json-read-from-string json-encode json-read-file)) + ;; Prevent any auto-displayed text + benchmarking + (advice-add 'display-startup-echo-area-message :override 'ignore) + (message ""))))) (provide 'core) ;;; core.el ends here diff --git a/core/defuns/defuns-auto-insert.el b/core/defuns/defuns-auto-insert.el deleted file mode 100644 index 3e25c8054..000000000 --- a/core/defuns/defuns-auto-insert.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-buffers.el b/core/defuns/defuns-buffers.el deleted file mode 100644 index 2f6ab4434..000000000 --- a/core/defuns/defuns-buffers.el +++ /dev/null @@ -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 "") - (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 "") - (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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-company.el b/core/defuns/defuns-company.el deleted file mode 100644 index b107e110a..000000000 --- a/core/defuns/defuns-company.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-docs.el b/core/defuns/defuns-docs.el deleted file mode 100644 index e944c29c4..000000000 --- a/core/defuns/defuns-docs.el +++ /dev/null @@ -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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-editor.el b/core/defuns/defuns-editor.el deleted file mode 100644 index ae616af4f..000000000 --- a/core/defuns/defuns-editor.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-embrace.el b/core/defuns/defuns-embrace.el deleted file mode 100644 index 1c29d44b6..000000000 --- a/core/defuns/defuns-embrace.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-evil.el b/core/defuns/defuns-evil.el deleted file mode 100644 index 429b59b12..000000000 --- a/core/defuns/defuns-evil.el +++ /dev/null @@ -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 "") - (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 "") - (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 "") (doom:map bang input 'normal)) - -;;;###autoload (autoload 'doom:imap "defuns-evil" nil t) -(evil-define-command doom:imap (bang input &optional mode) - (interactive "") (doom:map bang input 'insert)) - -;;;###autoload (autoload 'doom:vmap "defuns-evil" nil t) -(evil-define-command doom:vmap (bang input &optional mode) - (interactive "") (doom:map bang input 'visual)) - -;;;###autoload (autoload 'doom:mmap "defuns-evil" nil t) -(evil-define-command doom:mmap (bang input &optional mode) - (interactive "") (doom:map bang input 'motion)) - -;;;###autoload (autoload 'doom:omap "defuns-evil" nil t) -(evil-define-command doom:omap (bang input &optional mode) - (interactive "") (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 diff --git a/core/defuns/defuns-file.el b/core/defuns/defuns-file.el deleted file mode 100644 index aa1ac19fb..000000000 --- a/core/defuns/defuns-file.el +++ /dev/null @@ -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 "") - (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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-flycheck.el b/core/defuns/defuns-flycheck.el deleted file mode 100644 index 2a13a30b0..000000000 --- a/core/defuns/defuns-flycheck.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-git.el b/core/defuns/defuns-git.el deleted file mode 100644 index 59e576674..000000000 --- a/core/defuns/defuns-git.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-helm.el b/core/defuns/defuns-helm.el deleted file mode 100644 index d84d679aa..000000000 --- a/core/defuns/defuns-helm.el +++ /dev/null @@ -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 "") - (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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-highlight-indentation.el b/core/defuns/defuns-highlight-indentation.el deleted file mode 100644 index abb7847aa..000000000 --- a/core/defuns/defuns-highlight-indentation.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-ido.el b/core/defuns/defuns-ido.el deleted file mode 100644 index 2b4e86c30..000000000 --- a/core/defuns/defuns-ido.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-ivy.el b/core/defuns/defuns-ivy.el deleted file mode 100644 index 29da7bfb5..000000000 --- a/core/defuns/defuns-ivy.el +++ /dev/null @@ -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 "") - (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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-magit.el b/core/defuns/defuns-magit.el deleted file mode 100644 index dafe90e56..000000000 --- a/core/defuns/defuns-magit.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-neotree.el b/core/defuns/defuns-neotree.el deleted file mode 100644 index 5708af532..000000000 --- a/core/defuns/defuns-neotree.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-nlinum.el b/core/defuns/defuns-nlinum.el deleted file mode 100644 index 83c28feb9..000000000 --- a/core/defuns/defuns-nlinum.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-popups.el b/core/defuns/defuns-popups.el deleted file mode 100644 index fb16026c8..000000000 --- a/core/defuns/defuns-popups.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-projectile.el b/core/defuns/defuns-projectile.el deleted file mode 100644 index 8b51ba4aa..000000000 --- a/core/defuns/defuns-projectile.el +++ /dev/null @@ -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 diff --git a/core/defuns/defuns-repl.el b/core/defuns/defuns-repl.el deleted file mode 100644 index fdd81e35b..000000000 --- a/core/defuns/defuns-repl.el +++ /dev/null @@ -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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-ui.el b/core/defuns/defuns-ui.el deleted file mode 100644 index 91b1f4cce..000000000 --- a/core/defuns/defuns-ui.el +++ /dev/null @@ -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 "") - (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 diff --git a/core/defuns/defuns-util.el b/core/defuns/defuns-util.el deleted file mode 100644 index bbf316ae5..000000000 --- a/core/defuns/defuns-util.el +++ /dev/null @@ -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 "") - (let (message-log-max) - (message "%s%s" (if bang ">> " "") message))) - -(provide 'defuns-util) -;;; defuns-util.el ends here diff --git a/core/defuns/defuns-whitespace.el b/core/defuns/defuns-whitespace.el deleted file mode 100644 index 81cf88a00..000000000 --- a/core/defuns/defuns-whitespace.el +++ /dev/null @@ -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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-window.el b/core/defuns/defuns-window.el deleted file mode 100644 index bf1487371..000000000 --- a/core/defuns/defuns-window.el +++ /dev/null @@ -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 "") (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 "") (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 "") (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 "") (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 diff --git a/core/defuns/defuns-workgroup.el b/core/defuns/defuns-workgroup.el deleted file mode 100644 index 39e5a2644..000000000 --- a/core/defuns/defuns-workgroup.el +++ /dev/null @@ -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 "") - (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 "") - (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 "") - (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 "") - (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 "") - (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 "") - (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 "") - (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 "") - (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 diff --git a/core/defuns/defuns-yasnippet.el b/core/defuns/defuns-yasnippet.el deleted file mode 100644 index 3e210e987..000000000 --- a/core/defuns/defuns-yasnippet.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-company.el b/core/defuns/macros-company.el deleted file mode 100644 index 551d72dcd..000000000 --- a/core/defuns/macros-company.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-editor.el b/core/defuns/macros-editor.el deleted file mode 100644 index 6558c7786..000000000 --- a/core/defuns/macros-editor.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-eval.el b/core/defuns/macros-eval.el deleted file mode 100644 index 439b59032..000000000 --- a/core/defuns/macros-eval.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-evil.el b/core/defuns/macros-evil.el deleted file mode 100644 index 5eca00f76..000000000 --- a/core/defuns/macros-evil.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-popups.el b/core/defuns/macros-popups.el deleted file mode 100644 index e68ed812b..000000000 --- a/core/defuns/macros-popups.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-rotate-text.el b/core/defuns/macros-rotate-text.el deleted file mode 100644 index 11ae591d5..000000000 --- a/core/defuns/macros-rotate-text.el +++ /dev/null @@ -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 diff --git a/core/defuns/macros-yasnippet.el b/core/defuns/macros-yasnippet.el deleted file mode 100644 index 3ceab5c58..000000000 --- a/core/defuns/macros-yasnippet.el +++ /dev/null @@ -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