Major optimization refactor, across the board

+ enable lexical-scope everywhere (lexical-binding = t): ~5-10% faster
  startup; ~5-20% general boost
+ reduce consing, function calls & garbage collection by preferring
  cl-loop & dolist over lambda closures (for mapc[ar], add-hook, and
  various cl-lib filter/map/reduce functions) -- where possible
+ prefer functions with dedicated opcodes, like assq (see byte-defop's
  in bytecomp.el for more)
+ prefer pcase & cond (faster) over cl-case
+ general refactor for code readability
+ ensure naming & style conventions are adhered to
+ appease byte-compiler by marking unused variables with underscore
+ defer minor mode activation to after-init, emacs-startup or
  window-setup hooks; a customization opportunity for users + ensures
  custom functionality won't interfere with startup.
This commit is contained in:
Henrik Lissner 2017-06-08 11:47:56 +02:00
parent 64a142b3fc
commit c7254e7bdc
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
154 changed files with 1101 additions and 1118 deletions

View file

@ -1,15 +1,15 @@
;;; app/email/autoload/email.el
;;; app/email/autoload/email.el -*- lexical-binding: t; -*-
;;;###autoload
(defun =email ()
"Start email client."
(interactive)
(call-interactively 'mu4e))
(call-interactively #'mu4e))
;;;###autoload
(defun +email/compose ()
"Compose a new email."
(interactive)
;; TODO Interactively select email account
(call-interactively 'mu4e-compose-new))
(call-interactively #'mu4e-compose-new))

View file

@ -1,4 +1,4 @@
;;; app/email/autoload/evil.el
;;; app/email/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +email/mark (&optional beg end)
@ -8,11 +8,12 @@
(let* ((beg (or (and (region-active-p) evil-visual-beginning) (line-beginning-position)))
(end (or (and (region-active-p) evil-visual-end) (line-end-position)))
(key (this-command-keys))
(command (car (cl-find-if (lambda (mark) (equal (car (plist-get (cdr mark) :char)) key))
mu4e-marks))))
(command
(car (cl-find-if (lambda (mark) (equal (car (plist-get (cdr mark) :char)) key))
mu4e-marks))))
(unless command
(error "Not a valid mark command: %s" key))
(when (featurep 'evil)
(when (bound-and-true-p evil-mode)
(evil-normal-state))
(goto-char beg)
(dotimes (_ (count-lines beg end))

View file

@ -1,4 +1,4 @@
;;; app/email/config.el
;;; app/email/config.el -*- lexical-binding: t; -*-
;; I want to live in Emacs. Living is incomplete without email, so Emacs needs
;; to give me the ability to read, search, write and send my email. It does so
@ -16,9 +16,9 @@
(def-setting! :email (label letvars &optional default)
"Registers an email address for mu4e."
(let* ((name (or (cdr (assq 'user-full-name letvars)) user-full-name))
(address (cdr (assq 'user-mail-address letvars))))
(dolist (var letvars letvars)
(let ((name (or (cdr (assq 'user-full-name letvars)) user-full-name))
(address (cdr (assq 'user-mail-address letvars))))
(dolist (var letvars)
(let ((val (cdr var)))
(when (and (stringp val) (string-match-p "%s" val))
(setcdr var (format val label)))))
@ -96,15 +96,15 @@
("mime:image/*" "Messages with images" ?p)))
;; Add a column to display what email account the email belongs to.
(push '(:account
:name "Account"
:shortname "Account"
:help "Which account this email belongs to"
:function
(lambda (msg)
(let ((maildir (mu4e-message-field msg :maildir)))
(format "%s" (substring maildir 1 (string-match-p "/" maildir 1))))))
mu4e-header-info-custom)
(cl-pushnew '(:account
:name "Account"
:shortname "Account"
:help "Which account this email belongs to"
:function
(lambda (msg)
(let ((maildir (mu4e-message-field msg :maildir)))
(format "%s" (substring maildir 1 (string-match-p "/" maildir 1))))))
mu4e-header-info-custom)
;; In my workflow, emails won't be moved at all. Only their flags/labels are
;; changed. Se we redefine the trash and refile marks not to do any moving.

View file

@ -1,4 +1,4 @@
;;; app/present/autoload.el
;;; app/present/autoload.el -*- lexical-binding: t; -*-
;; --- impatient-mode -------------------------------------------------------------
@ -14,8 +14,9 @@
(+present--cleanup-impatient-mode)))
(defun +present--cleanup-impatient-mode ()
(unless (cl-remove-if-not (lambda (buf) (buffer-local-value 'impatient-mode buf))
(doom-buffer-list))
(unless (cl-loop for buf in (doom-buffer-list)
if (buffer-local-value 'impatient-mode buf)
return t)
(httpd-stop)
(remove-hook 'kill-buffer-hook '+present--cleanup-impatient-mode)))
@ -60,8 +61,9 @@
(text-scale-set +present-scale)))
(defun +present--cleanup-org-tree-slides-mode ()
(unless (cl-remove-if-not (lambda (buf) (buffer-local-value 'org-tree-slide-mode buf))
(doom-buffers-in-mode 'org-mode))
(unless (cl-loop for buf in (doom-buffers-in-mode 'org-mode)
if (buffer-local-value 'org-tree-slide-mode buf)
return t)
(org-tree-slide-mode -1)
(remove-hook 'kill-buffer-hook #'+present--cleanup-org-tree-slides-mode)))

View file

@ -1,4 +1,4 @@
;;; app/present/config.el
;;; app/present/config.el -*- lexical-binding: t; -*-
;; Sometimes you just get that urge to show off. I don't have a fancy car, so
;; my code or Emacs will have to do.
@ -68,7 +68,8 @@
(add-hook! 'org-tree-slide-mode-after-narrow-hook
#'(+present|detect-slide +present|add-overlays org-display-inline-images))
(add-hook! 'org-tree-slide-mode-hook
(defun +present|org-tree-present-mode ()
"TODO"
(doom/window-zoom)
(let ((arg (if org-tree-slide-mode +1 -1)))
(centered-window-mode arg)
@ -87,8 +88,10 @@
(set-face-attribute 'org-level-2 nil :height 1.0)
(+present|remove-overlays)
(org-remove-inline-images)))))
(add-hook 'org-tree-slide-mode-hook #'+present|org-tree-present-mode)
(defun +present*org-tree-slide-narrow-exclude-header (orig-fn &rest args)
"TODO"
(cl-letf (((symbol-function 'org-narrow-to-subtree)
(lambda () (save-excursion
(save-match-data

View file

@ -1,4 +1,4 @@
;;; app/rss/autoload.el
;;; app/rss/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun =rss ()

View file

@ -1,4 +1,4 @@
;;; app/rss/config.el
;;; app/rss/config.el -*- lexical-binding: t; -*-
;; This is an opinionated workflow that turns Emacs into an RSS reader, inspired
;; by apps Reeder and Readkit. It can be invoked via `=rss'. Otherwise, if you
@ -31,8 +31,8 @@
(make-directory elfeed-db-directory t)
;; Ensure elfeed buffers are treated as real
(push (lambda (buf) (string-match-p "^\\*elfeed" (buffer-name buf)))
doom-real-buffer-functions)
(cl-pushnew (lambda (buf) (string-match-p "^\\*elfeed" (buffer-name buf)))
doom-real-buffer-functions)
;; Enhance readability of a post
(add-hook 'elfeed-show-mode-hook #'+rss|elfeed-wrap)

View file

@ -1,4 +1,4 @@
;;; app/twitter/autoload.el
;;; app/twitter/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun =twitter ()
@ -7,7 +7,7 @@
(delete-other-windows)
(condition-case ex
(progn
(call-interactively 'twit)
(call-interactively #'twit)
(unless (get-buffer (car twittering-initial-timeline-spec-string))
(error "Failed to open twitter"))
(switch-to-buffer (car twittering-initial-timeline-spec-string))

View file

@ -1,4 +1,4 @@
;;; app/twitter/config.el
;;; app/twitter/config.el -*- lexical-binding: t; -*-
(def-package! twittering-mode
:commands twit

View file

@ -1,7 +1,8 @@
;;; app/write/autoload.el
;;; app/write/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(define-minor-mode +write-mode
"TODO"
:init-value nil
:keymap nil
(let ((arg (if +write-mode +1 -1))

View file

@ -1,4 +1,4 @@
;;; company.el
;;; completion/company/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +company/complete ()
@ -15,17 +15,18 @@
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 '+company/whole-lines))
(prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
(candidates (all-completions arg lines)))))
(pcase command
('interactive (company-begin-backend '+company/whole-lines))
('prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
('candidates
(all-completions
arg
(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 +company/dict-or-keywords ()

View file

@ -1,12 +1,11 @@
;;; completion/company/config.el
;;; completion/company/config.el -*- lexical-binding: t; -*-
(def-setting! :company-backend (modes backends)
"Register company BACKENDS to MODES."
(let* ((modes (if (listp modes) modes (list modes)))
(backends (if (listp backends) backends (list backends)))
(def-name (intern (format "doom--init-company-%s"
(mapconcat #'identity (mapcar #'symbol-name modes) "-"))))
(quoted (eq (car-safe backends) 'quote)))
(mapconcat #'identity (mapcar #'symbol-name modes) "-")))))
;; TODO more type checks
`(prog1
(defun ,def-name ()

View file

@ -1,7 +1,7 @@
;;; emacs/ido/config.el
;;; completion/ido/config.el -*- lexical-binding: t; -*-
(def-package! ido
:init
:config
(setq ido-ignore-buffers
'("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer"
"^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-"
@ -16,7 +16,6 @@
ido-enable-last-directory-history t
ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
:config
(push "\\`.DS_Store$" ido-ignore-files)
(push "Icon\\?$" ido-ignore-files)
@ -24,15 +23,15 @@
(ido-everywhere 1)
(require 'ido-ubiquitous)
(add-hook! ido-setup
(defun +ido|init ()
(require 'ido-vertical-mode)
(require 'flx-ido)
(require 'crm-custom)
(map! :map (ido-common-completion-map ido-completion-map ido-file-completion-map)
"C-n" #'ido-next-match
"C-p" #'ido-prev-match
"C-w" #'ido-delete-backward-word-updir))
(add-hook 'ido-setup-hook #'+ido|init)
(defun +ido*sort-mtime ()
"Sort ido filelist by mtime instead of alphabetically."
@ -43,16 +42,16 @@
(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))))
(cl-loop for x in ido-temp-list
if (char-equal (string-to-char x) ?.)
collect x)))
(advice-add #'ido-sort-mtime :override #'+ido*sort-mtime)
(add-hook! (ido-make-file-list ido-make-dir-list) #'+ido*sort-mtime)
(defun +ido|setup-home-keybind ()
"Go to $HOME with ~"
(define-key ido-file-completion-map (kbd "~")
(λ! (if (looking-back "/")
(λ! (if (looking-back "/" (point-min))
(insert "~/")
(call-interactively #'self-insert-command)))))
(add-hook 'ido-setup-hook #'+ido|setup-home-keybind))

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; emacs/ido/packages.el
;;; completion/ido/packages.el
(package! flx-ido)
(package! ido-ubiquitous)

View file

@ -1,4 +1,4 @@
;;; completion/ivy/autoload/evil.el
;;; completion/ivy/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+ivy:swiper "completion/ivy/autoload/evil" nil t)
(evil-define-command +ivy:swiper (&optional search)
@ -19,7 +19,7 @@
(defvar +ivy--file-search-recursion-p t)
(defvar +ivy--file-search-all-files-p nil)
(defun +ivy--file-search (engine beg end query &optional directory prompt)
(defun +ivy--file-search (engine beg end query &optional directory)
(let* ((directory (or directory (doom-project-root)))
(recursion-p +ivy--file-search-recursion-p)
(all-files-p +ivy--file-search-all-files-p)

View file

@ -1,4 +1,4 @@
;;; completion/ivy/autoload/ivy.el
;;; completion/ivy/autoload/ivy.el -*- lexical-binding: t; -*-
;; Show more information in ivy-switch-buffer; and only display
;; workgroup-relevant buffers.
@ -6,33 +6,35 @@
(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) 15)))
(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
(abbreviate-file-name (file-name-directory buffer-file-name)))))))
(or buffer-list (doom-buffer-list))))))
(cl-loop for buf in (or buffer-list (doom-buffer-list))
collect
(destructuring-bind (type mode path)
(+ivy--get-buffer-attrs buf proot)
(format (format "%%-%ds %%-%ds %%s" min-name min-mode)
type mode (or path ""))))))
(defun +ivy--get-buffer-attrs (b &optional project-root)
(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) 15)))
(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)
((and project-root
(not (string= project-root (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
(abbreviate-file-name (file-name-directory buffer-file-name)))))))
(defun +ivy--select-buffer-action (buffer)
(ivy--switch-buffer-action
@ -66,54 +68,54 @@ limit to buffers in the current workspace."
:keymap ivy-switch-buffer-map
:caller '+ivy/switch-workspace-buffer))
;; TODO refactor ivy task candidate functions (messy!)
(defun +ivy--tasks-candidates (tasks)
"Generate a list of task tags (specified by `+ivy-task-tags') for
`+ivy/tasks'."
(let* ((max-type-width (seq-max (mapcar #'length (mapcar #'car +ivy-task-tags))))
(max-desc-width (seq-max (mapcar #'length (mapcar #'cl-cdadr tasks))))
(max-width (max 25 (min (- (frame-width) (+ max-type-width 1))
max-desc-width)))
(fmt (format "%%-%ds %%-%ds%%s%%s:%%s" max-type-width max-desc-width))
lines)
(dolist (alist tasks (nreverse lines))
(let-alist alist
(push (format fmt
(propertize .type 'face (cdr (assoc .type +ivy-task-tags)))
(substring .desc 0 (min max-desc-width (length .desc)))
(propertize " | " 'face 'font-lock-comment-face)
(propertize (abbreviate-file-name .file) 'face 'font-lock-keyword-face)
(propertize .line 'face 'font-lock-constant-face))
lines)))))
(let* ((max-type-width
(cl-loop for task in +ivy-task-tags maximize (length (car task))))
(max-desc-width
(cl-loop for task in tasks maximize (length (cl-cdadr task))))
(max-width (max (- (frame-width) (1+ max-type-width) max-desc-width)
25)))
(cl-loop
with fmt = (format "%%-%ds %%-%ds%%s%%s:%%s" max-type-width max-width)
for alist in tasks
collect
(let-alist alist
(format fmt
(propertize .type 'face (cdr (assoc .type +ivy-task-tags)))
(substring .desc 0 (min max-desc-width (length .desc)))
(propertize " | " 'face 'font-lock-comment-face)
(propertize (abbreviate-file-name .file) 'face 'font-lock-keyword-face)
(propertize .line 'face 'font-lock-constant-face))))))
(defun +ivy--tasks (target)
(let (case-fold-search)
(delq
nil
(mapcar (lambda (x)
(save-match-data
(when (string-match (concat "^\\([^:]+\\):\\([0-9]+\\):.+\\("
(string-join (mapcar #'car +ivy-task-tags) "\\|")
"\\):?\\s-*\\(.+\\)")
x)
`((type . ,(match-string 3 x))
(desc . ,(match-string 4 x))
(file . ,(match-string 1 x))
(line . ,(match-string 2 x))))))
(let ((command (or (let ((bin (executable-find "rg")))
(and bin (concat bin " --line-number")))
(let ((bin (executable-find "ag")))
(and bin (concat bin " --numbers")))
(error "Neither ripgrep or the_silver_searcher is available")))
(args (concat " -- "
(shell-quote-argument
(concat "\\s("
(string-join (mapcar #'car +ivy-task-tags) "|")
")([\\s:]|\\([^)]+\\):?)")))))
(when-let (out (shell-command-to-string
(format "%s -H -S --no-heading %s %s"
command args target)))
(split-string out "\n" t)))))))
(let* (case-fold-search
(task-tags (mapcar #'car +ivy-task-tags))
(cmd
(format "%s -H -S --no-heading -- %s %s"
(or (when-let (bin (executable-find "rg"))
(concat bin " --line-number"))
(when-let (bin (executable-find "ag"))
(concat bin " --numbers"))
(error "ripgrep & the_silver_searcher are unavailable"))
(shell-quote-argument
(concat "\\s("
(string-join task-tags "|")
")([\\s:]|\\([^)]+\\):?)"))
target)))
(save-match-data
(cl-loop with out = (shell-command-to-string cmd)
for x in (and out (split-string out "\n" t))
when (string-match
(concat "^\\([^:]+\\):\\([0-9]+\\):.+\\("
(string-join task-tags "\\|")
"\\):?\\s-*\\(.+\\)")
x)
collect `((type . ,(match-string 3 x))
(desc . ,(match-string 4 x))
(file . ,(match-string 1 x))
(line . ,(match-string 2 x)))))))
(defun +ivy--tasks-open-action (x)
"Jump to the file and line of the current task."
@ -180,27 +182,27 @@ counsel-rg)."
(defun +ivy/wgrep-occur ()
"Invoke the search+replace wgrep buffer on the current ag/rg search results."
(interactive)
(if (not (window-minibuffer-p))
(user-error "No completion session is active")
(require 'wgrep)
(let* ((caller (ivy-state-caller ivy-last))
(occur-fn (plist-get ivy--occurs-list caller))
(buffer
(generate-new-buffer
(format "*ivy-occur%s \"%s\"*"
(if caller (concat " " (prin1-to-string caller)) "")
ivy-text))))
(with-current-buffer buffer
(let ((inhibit-read-only t))
(erase-buffer)
(funcall occur-fn))
(setf (ivy-state-text ivy-last) ivy-text)
(setq ivy-occur-last ivy-last)
(setq-local ivy--directory ivy--directory))
(ivy-exit-with-action
`(lambda (_)
(pop-to-buffer ,buffer)
(ivy-wgrep-change-to-wgrep-mode))))))
(unless (window-minibuffer-p)
(user-error "No completion session is active"))
(require 'wgrep)
(let* ((caller (ivy-state-caller ivy-last))
(occur-fn (plist-get ivy--occurs-list caller))
(buffer
(generate-new-buffer
(format "*ivy-occur%s \"%s\"*"
(if caller (concat " " (prin1-to-string caller)) "")
ivy-text))))
(with-current-buffer buffer
(let ((inhibit-read-only t))
(erase-buffer)
(funcall occur-fn))
(setf (ivy-state-text ivy-last) ivy-text)
(setq ivy-occur-last ivy-last)
(setq-local ivy--directory ivy--directory))
(ivy-exit-with-action
`(lambda (_)
(pop-to-buffer ,buffer)
(ivy-wgrep-change-to-wgrep-mode)))))
;;;###autoload
(defun +ivy-yas-prompt (prompt choices &optional display-fn)

View file

@ -1,7 +1,8 @@
;;; completion/ivy/packages.el
;;; completion/ivy/config.el -*- lexical-binding: t; -*-
(defvar +ivy-task-tags '(("TODO" . warning)
("FIXME" . error))
(defvar +ivy-task-tags
'(("TODO" . warning)
("FIXME" . error))
"An alist of tags for `+ivy/tasks' to include in its search, whose CDR is the
face to render it with.")
@ -20,7 +21,8 @@ session)."
;; Packages
;;
(def-package! ivy :demand t
(def-package! ivy
:demand t
:config
(setq ivy-height 12
ivy-do-completion-in-region nil
@ -38,7 +40,7 @@ session)."
(after! magit (setq magit-completing-read-function #'ivy-completing-read))
(after! yasnippet (push #'+ivy-yas-prompt yas-prompt-functions))
(ivy-mode +1)
(add-hook 'window-setup-hook #'ivy-mode)
(map! :map ivy-mode-map
[remap describe-face] #'counsel-describe-face
@ -79,12 +81,16 @@ session)."
;; Configure `counsel-rg', `counsel-ag' & `counsel-pt'
(set! :popup 'ivy-occur-grep-mode :size (+ 2 ivy-height) :regexp t :autokill t)
(dolist (cmd '(counsel-ag counsel-rg counsel-pt))
(ivy-add-actions
cmd
'(("O" +ivy-git-grep-other-window-action "open in other window"))))
;; 1. Remove character limit from `counsel-ag-function'
;; 2. Disable ivy's over-zealous parentheses quoting behavior (if i want
;; literal parentheses, I'll escape them myself).
;; 3. This may need to be updated frequently, to meet changes upstream
;; 4. counsel-ag, counsel-rg and counsel-pt all use this function
(advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function))

View file

@ -1,42 +0,0 @@
;;; feature/debug/autoload.el
;;;###autoload
(defun +debug/quit ()
(interactive)
(ignore-errors (call-interactively 'realgud:cmd-quit))
(doom/popup-close)
(evil-normal-state))
;;;###autoload (autoload '+debug:debug-toggle-breakpoint "feature/debug/autoload" nil t)
;;;###autoload (autoload '+debug:run "feature/debug/autoload" nil t)
(after! evil
(evil-define-command +debug:run (&optional path)
"Initiate debugger for current major mode"
(interactive "<f>")
(let ((default-directory (doom-project-root)))
(cond ((memq major-mode '(c-mode c++-mode))
(realgud:gdb (if path (concat "gdb " path))))
((memq major-mode '(ruby-mode enh-ruby-mode))
(doom:repl nil (format "run '%s'" (file-name-nondirectory (or path buffer-file-name)))))
((eq major-mode 'sh-mode)
(let ((shell sh-shell))
(when (string= shell "sh")
(setq shell "bash"))
(cond ((string= shell "bash")
(realgud:bashdb (if path (concat "bashdb " path))))
((string= shell "zsh")
(realgud:zshdb (if path (concat "zshdb " path))))
(t (user-error "No shell debugger for %s" shell)))))
;; TODO Add python debugging
((memq major-mode '(js-mode js2-mode js3-mode))
(realgud:trepanjs))
((eq major-mode 'haskell-mode)
(haskell-debug))
(t (user-error "No debugger for %s" major-mode)))))
(evil-define-command +debug:debug-toggle-breakpoint (&optional bang)
(interactive "<!>")
(call-interactively (if bang 'realgud:cmd-clear 'realgud:cmd-break))))

View file

@ -0,0 +1,9 @@
;;; feature/debug/autoload/debug.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +debug/quit ()
(interactive)
(ignore-errors (call-interactively 'realgud:cmd-quit))
(doom/popup-close)
(evil-normal-state))

View file

@ -0,0 +1,31 @@
;;; feature/debug/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+debug:run "feature/debug/autoload/evil" nil t)
(evil-define-command +debug:run (&optional path)
"Initiate debugger for current major mode"
(interactive "<f>")
(let ((default-directory (doom-project-root)))
(cond ((memq major-mode '(c-mode c++-mode))
(realgud:gdb (if path (concat "gdb " path))))
((memq major-mode '(ruby-mode enh-ruby-mode))
(doom:repl nil (format "run '%s'" (file-name-nondirectory (or path buffer-file-name)))))
((eq major-mode 'sh-mode)
(let ((shell sh-shell))
(when (string= shell "sh")
(setq shell "bash"))
(cond ((string= shell "bash")
(realgud:bashdb (if path (concat "bashdb " path))))
((string= shell "zsh")
(realgud:zshdb (if path (concat "zshdb " path))))
(t (user-error "No shell debugger for %s" shell)))))
;; TODO Add python debugging
((memq major-mode '(js-mode js2-mode js3-mode))
(realgud:trepanjs))
((eq major-mode 'haskell-mode)
(haskell-debug))
(t (user-error "No debugger for %s" major-mode)))))
;;;###autoload (autoload '+debug:toggle-breakpoint "feature/debug/autoload/evil" nil t)
(evil-define-command +debug:toggle-breakpoint (&optional bang)
(interactive "<!>")
(call-interactively (if bang 'realgud:cmd-clear 'realgud:cmd-break)))

View file

@ -1,4 +1,4 @@
;;; feature/debug/config.el
;;; feature/debug/config.el -*- lexical-binding: t; -*-
(def-package! realgud
:commands (realgud:gdb realgud:trepanjs realgud:bashdb realgud:zshdb)
@ -11,7 +11,7 @@
;; (def-tmp-excmd! doom:def-debug-on doom:def-debug-off
;; ("n[ext]" . realgud:cmd-next)
;; ("s[tep]" . realgud:cmd-step)
;; ("b[reak]" . doom:debug-toggle-breakpoint)
;; ("b[reak]" . +debug:toggle-breakpoint)
;; ("c[ontinue]" . realgud:cmd-continue))
;; (advice-add #'realgud-cmdbuf-init :after #'doom:def-debug-on)
;; (advice-add #'realgud:cmd-quit :after #'doom:def-debug-off)
@ -21,28 +21,26 @@
;; FIXME Causes realgud:cmd-* to focus popup on every invocation
(defun +debug*realgud-run-process
(debugger-name script-filename cmd-args minibuffer-history &optional no-reset)
(let ((cmd-buf))
(setq cmd-buf
(apply #'realgud-exec-shell debugger-name script-filename
(car cmd-args) no-reset (cdr cmd-args)))
(let ((process (get-buffer-process cmd-buf)))
(if (and process (eq 'run (process-status process)))
(progn
(pop-to-buffer cmd-buf)
(define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debug/quit)
(realgud:track-set-debugger debugger-name)
(realgud-cmdbuf-info-in-debugger?= 't)
(realgud-cmdbuf-info-cmd-args= cmd-args)
(when cmd-buf
(switch-to-buffer cmd-buf)
(when realgud-cmdbuf-info
(let* ((info realgud-cmdbuf-info)
(cmd-args (realgud-cmdbuf-info-cmd-args info))
(cmd-str (mapconcat #'identity cmd-args " ")))
(set minibuffer-history
(list-utils-uniq (cons cmd-str (eval minibuffer-history))))))))
(if cmd-buf (switch-to-buffer cmd-buf))
(message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
(let* ((cmd-buf (apply #'realgud-exec-shell debugger-name script-filename
(car cmd-args) no-reset (cdr cmd-args)))
(process (get-buffer-process cmd-buf)))
(cond ((and process (eq 'run (process-status process)))
(pop-to-buffer cmd-buf)
(define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debug/quit)
(realgud:track-set-debugger debugger-name)
(realgud-cmdbuf-info-in-debugger?= 't)
(realgud-cmdbuf-info-cmd-args= cmd-args)
(when cmd-buf
(switch-to-buffer cmd-buf)
(when realgud-cmdbuf-info
(let* ((info realgud-cmdbuf-info)
(cmd-args (realgud-cmdbuf-info-cmd-args info))
(cmd-str (mapconcat #'identity cmd-args " ")))
(set minibuffer-history
(list-utils-uniq (cons cmd-str (eval minibuffer-history))))))))
(t
(if cmd-buf (switch-to-buffer cmd-buf))
(message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
cmd-buf))
(advice-add #'realgud:run-process :override #'+debug*realgud-run-process))

View file

@ -1,4 +1,4 @@
;;; feature/eval/autoload/build.el
;;; feature/eval/autoload/build.el -*- lexical-binding: t; -*-
(defvar-local +eval-last-builder nil
"The last builder run in the current buffer.")
@ -22,9 +22,7 @@ functions.")
:key 'cdr))
(if (= (length builders) 1)
(car builders)
(when-let (builder (completing-read "Build: "
(mapcar #'car builders)
nil t))
(when-let (builder (completing-read "Build: " (mapcar #'car builders) nil t))
(assq (intern builder) builders)))))
;;;###autoload
@ -36,9 +34,8 @@ functions.")
(error "No builder for this buffer"))))
(unless builder
(error "Builder not found in registered builders"))
(let* ((name (car builder))
(plist (cdr builder))
(fn (plist-get plist :fn)))
(let ((name (car builder))
(fn (plist-get (cdr builder) :fn)))
(message "Running %s" name)
(if (or (functionp fn)
(and (symbolp fn) (fboundp fn)))

View file

@ -1,4 +1,4 @@
;;; feature/eval/autoload/eval.el
;;; feature/eval/autoload/eval.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +eval/buffer ()

View file

@ -1,4 +1,4 @@
;;; feature/eval/autoload/evil.el
;;; feature/eval/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+eval:region "feature/eval/autoload/evil" nil t)
(evil-define-operator +eval:region (beg end)

View file

@ -1,28 +1,28 @@
;;; feature/eval/autoload/repl.el
;;; feature/eval/autoload/repl.el -*- lexical-binding: t; -*-
(defvar +eval-repl-buffer nil
"The buffer of the last open repl.")
(defun +eval--ensure-in-repl-buffer (&optional command)
(if (eq (current-buffer) +eval-repl-buffer)
t
(if (and +eval-repl-buffer (buffer-live-p +eval-repl-buffer))
(if-let (win (get-buffer-window +eval-repl-buffer))
(select-window win)
(doom-popup-buffer +eval-repl-buffer))
(when command
(let ((repl-buffer (save-window-excursion (call-interactively command))))
(unless (bufferp repl-buffer)
(error "REPL command didn't return a buffer"))
(with-current-buffer repl-buffer (+eval-repl-mode +1))
(setq +eval-repl-buffer repl-buffer)
(select-window (doom-popup-buffer repl-buffer)))))
(when (eq (current-buffer) +eval-repl-buffer)
(goto-char (if (and (derived-mode-p 'comint-mode)
(cdr comint-last-prompt))
(cdr comint-last-prompt)
(point-max)))
t)))
(or (eq (current-buffer) +eval-repl-buffer)
(progn
(if (and +eval-repl-buffer (buffer-live-p +eval-repl-buffer))
(if-let (win (get-buffer-window +eval-repl-buffer))
(select-window win)
(doom-popup-buffer +eval-repl-buffer))
(when command
(let ((repl-buffer (save-window-excursion (call-interactively command))))
(unless (bufferp repl-buffer)
(error "REPL command didn't return a buffer"))
(with-current-buffer repl-buffer (+eval-repl-mode +1))
(setq +eval-repl-buffer repl-buffer)
(select-window (doom-popup-buffer repl-buffer)))))
(when (eq (current-buffer) +eval-repl-buffer)
(goto-char (if (and (derived-mode-p 'comint-mode)
(cdr comint-last-prompt))
(cdr comint-last-prompt)
(point-max)))
t))))
;;;###autoload
(defun +eval/repl ()
@ -31,8 +31,8 @@ the cursor at the prompt."
(interactive)
(when-let (command (cdr (assq major-mode +eval-repls)))
(when (+eval--ensure-in-repl-buffer command)
(when (and (featurep 'evil) evil-mode)
(call-interactively 'evil-append-line))
(when (bound-and-true-p evil-mode)
(call-interactively #'evil-append-line))
t)))
;;;###autoload
@ -43,8 +43,8 @@ execute it immediately after."
(let ((selection (buffer-substring-no-properties beg end)))
(unless (+eval--ensure-in-repl-buffer)
(error "No REPL open"))
(when (and (featurep 'evil) evil-mode)
(call-interactively 'evil-append-line))
(when (bound-and-true-p evil-mode)
(call-interactively #'evil-append-line))
(insert (string-trim selection))
(when auto-execute-p
;; I don't use `comint-send-input' because different REPLs may have their

View file

@ -1,4 +1,4 @@
;;; feature/eval/config.el
;;; feature/eval/config.el -*- lexical-binding: t; -*-
;;
;; Code building

View file

@ -1,4 +1,4 @@
;;; feature/evil/autoload/evil-mc.el
;;; feature/evil/autoload/evil-mc.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +evil/mc-toggle-cursors ()
@ -21,9 +21,7 @@ cursors."
(interactive)
(cond ((memq evil-this-type '(block line))
(let ((col (evil-column))
(line-at-pt (line-number-at-pos))
(beg evil-visual-beginning)
(end evil-visual-end))
(line-at-pt (line-number-at-pos)))
;; Fix off-by-one error
(when (= evil-visual-direction 1)
(cl-decf col)
@ -36,7 +34,7 @@ cursors."
(move-to-column col)
(when (= (current-column) col)
(evil-mc-make-cursor-here))))
beg
evil-visual-beginning
(if (eq evil-this-type 'line) (1- evil-visual-end) evil-visual-end)
nil)
(evil-exit-visual-state))))

View file

@ -1,4 +1,4 @@
;;; feature/evil/autoload/evil.el
;;; feature/evil/autoload/evil.el -*- lexical-binding: t; -*-
(eval-when-compile (require 'subr-x))
@ -36,16 +36,13 @@ flags. See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers
"\\([#%]\\)"
"\\(\\(?::\\(?:[PphtreS~.]\\|g?s[^:\t\n ]+\\)\\)*\\)"))
(matches
(let ((all-strings ())
(i 0))
(while (and (< i (length file-name))
(string-match regexp file-name i))
(setq i (1+ (match-beginning 0)))
(let (strings)
(push (dotimes (i (/ (length (match-data)) 2) (nreverse strings))
(push (match-string i file-name) strings))
all-strings)))
(nreverse all-strings))))
(cl-loop with i = 0
while (and (< i (length file-name))
(string-match regexp file-name i))
do (setq i (1+ (match-beginning 0)))
and collect
(cl-loop for j to (/ (length (match-data)) 2)
collect (match-string j file-name)))))
(dolist (match matches)
(let ((flags (split-string (car (cdr (cdr match))) ":" t))
(path (and buffer-file-name
@ -113,16 +110,18 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
(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)))
(funcall (pcase 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))))
(split-window this-window nil
(pcase direction
('up 'above)
('down 'below)
(_ direction))))
(with-selected-window that-window
(switch-to-buffer doom-buffer))
(setq that-buffer (window-buffer that-window)))
@ -172,20 +171,22 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
;; --- custom arg handlers ----------------
(defvar +evil--flag nil)
(defun +evil--ex-match-init (name &optional face update-hook)
(with-current-buffer evil-ex-current-buffer
(cond
((eq flag 'start)
((eq +evil--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))
(setq +evil--flag 'update))
((eq flag 'stop)
((eq +evil--flag 'stop)
(evil-ex-delete-hl name)))))
(defun +evil--ex-buffer-match (arg &optional hl-name flags beg end)
(when (and (eq flag 'update)
(when (and (eq +evil--flag 'update)
evil-ex-substitute-highlight-all
(not (zerop (length arg))))
(condition-case lossage
@ -209,21 +210,24 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
;;;###autoload
(defun +evil-ex-buffer-match (flag &optional arg)
(let ((hl-name 'evil-ex-buffer-match))
(let ((hl-name 'evil-ex-buffer-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name)
(+evil--ex-buffer-match arg hl-name (list (if evil-ex-substitute-global ?g))))))
;;;###autoload
(defun +evil-ex-global-match (flag &optional arg)
(let ((hl-name 'evil-ex-global-match))
(let ((hl-name 'evil-ex-global-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name)
(+evil--ex-buffer-match arg hl-name nil (point-min) (point-max)))))
;;;###autoload
(defun +evil-ex-global-delim-match (flag &optional arg)
(let ((hl-name 'evil-ex-global-delim-match))
(let ((hl-name 'evil-ex-global-delim-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name)
(let ((result (car-safe (evil-delimited-arguments arg 2))))
@ -249,7 +253,7 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
"A wrapper around `evil-delete' for `wgrep' buffers that will invoke
`wgrep-mark-deletion' on lines you try to delete."
(interactive "<R><x><y>")
(condition-case ex
(condition-case _ex
(evil-delete beg end type register yank-handler)
('text-read-only
(evil-apply-on-block

View file

@ -1,4 +1,4 @@
;;; feature/evil/autoload/files.el
;;; feature/evil/autoload/files.el -*- lexical-binding: t; -*-
(defun +evil--forget-file (old-path &optional new-path)
"Ensure `recentf', `projectile' and `save-place' forget OLD-PATH."
@ -23,11 +23,9 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
(buf (current-buffer)))
(cond ((not (file-exists-p fname))
(error "File doesn't exist: %s" fname))
((not (or force-p (y-or-n-p (format "Really delete %s?" fbase))))
(message "Aborted")
nil)
(t
(unwind-protect
(progn (delete-file fname) t)
@ -38,8 +36,7 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
;; to real buffers (`doom-real-buffer-p')
(doom-force-kill-buffer buf t)
(+evil--forget-file fname)
(message "Successfully deleted %s" short-path)
)))))))
(message "Successfully deleted %s" short-path))))))))
(defun +evil--copy-file (old-path new-path &optional force-p)
(let* ((new-path (expand-file-name new-path))

View file

@ -1,9 +1,9 @@
;;; feature/evil/autoload/folds.el
;;; feature/evil/autoload/folds.el -*- lexical-binding: t; -*-
;; It's frustrating how hideshow is a decent code folding implementation, but it
;; won't let you create custom folds. Meanwhile, evil-vimish-fold offers custom
;; folds, but essentially ignores any other type of folding (indent or custom
;; markers, which hs-minor-mode gives you).
;; `hideshow' is a decent code folding implementation, but it won't let you
;; create custom folds. `evil-vimish-fold' offers custom folds, but essentially
;; ignores any other type of folding (indent or custom markers, which
;; hs-minor-mode gives you).
;;
;; So this is my effort to combine them.

View file

@ -1,4 +1,4 @@
;;; feature/evil/config.el
;;; feature/evil/config.el -*- lexical-binding: t; -*-
;; I'm a vimmer at heart. Its modal philosophy suits me better, and this module
;; strives to make Emacs a much better vim than vim was.
@ -41,7 +41,7 @@
shift-select-mode nil)
:config
(evil-mode +1)
(add-hook 'emacs-startup-hook #'evil-mode)
(evil-select-search-module 'evil-search-module 'evil-search)
(set! :popup
@ -170,7 +170,7 @@ across windows."
(def-package! evil-easymotion
:defer 1
:after evil-snipe
:config
(defvar +evil--snipe-repeat-fn
(evilem-create #'evil-snipe-repeat
@ -185,7 +185,6 @@ across windows."
(setq evil-embrace-show-help-p nil)
(evil-embrace-enable-evil-surround-integration)
;; Defuns
(defun +evil--embrace-get-pair (char)
(if-let (pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist)))
pair
@ -234,15 +233,15 @@ across windows."
(def-package! evil-escape
:demand t
:commands evil-escape-mode
:init
(setq evil-escape-excluded-states '(normal visual multiedit emacs)
evil-escape-excluded-major-modes '(neotree-mode)
evil-escape-key-sequence "jk"
evil-escape-delay 0.25)
(add-hook 'emacs-startup-hook #'evil-escape-mode)
:config
(evil-escape-mode +1)
(map! :irvo "C-g" #'evil-escape))
@ -330,7 +329,7 @@ the new algorithm is confusing, like in python or ruby."
(?\] "[]})]")
(?\; "[;:]")))
:config
(evil-snipe-override-mode +1))
(add-hook 'emacs-startup-hook #'evil-snipe-override-mode))
(def-package! evil-surround

View file

@ -1,4 +1,4 @@
;;; feature/file-templates/config.el
;;; feature/file-templates/config.el -*- lexical-binding: t; -*-
(require! :feature snippets)
@ -31,12 +31,13 @@
(overlay-get yas--active-field-overlay 'yas--field)))
(evil-initialize-state 'insert))))
(defun +file-templates|add (regexp trigger mode &optional project-only-p)
(define-auto-insert
regexp
(vector `(lambda () (+file-templates--expand ,trigger ',mode ,project-only-p)))))
(defun +file-templates-add (args)
(destructuring-bind (regexp trigger mode &optional project-only-p) args
(define-auto-insert
regexp
(vector `(lambda () (+file-templates--expand ,trigger ',mode ,project-only-p))))))
(mapc (lambda (args) (apply #'+file-templates|add args))
(mapc #'+file-templates-add
;; General
'(("/\\.gitignore$" "__" gitignore-mode)
("/Dockerfile$" "__" dockerfile-mode)

View file

@ -1,3 +1,3 @@
;;; `(file-relative-name buffer-file-name doom-modules-dir)`
;;; `(file-relative-name buffer-file-name doom-modules-dir)` -*- lexical-binding: t; -*-
$0

View file

@ -1,4 +1,4 @@
;;; `(file-name-nondirectory buffer-file-name)`${1: --- ${2:description}}
;;; `(file-name-nondirectory buffer-file-name)`${1: --- ${2:description}} -*- lexical-binding: t; -*-
$0

View file

@ -1,4 +1,4 @@
;;; feature/jump/autoload/evil.el
;;; feature/jump/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+jump:online "feature/jump/autoload/evil" nil t)
(evil-define-command +jump:online (query &optional bang)
@ -6,11 +6,12 @@
reuse it on consecutive uses of this command. If BANG, always prompt for search
engine."
(interactive "<a><!>")
(setq query (or query (thing-at-point 'symbol t)))
(unless query
(user-error "The search query is empty"))
(let ((engine (or (and (not bang) (bound-and-true-p +jump--online-last))
(completing-read (format "Search on (%s): " query)
(mapcar #'car +jump-search-url-alist)
nil t))))
(+jump/online engine query)))
(let ((query (or query (thing-at-point 'symbol t))))
(unless query
(user-error "The search query is empty"))
(+jump/online
(or (and (not bang) (bound-and-true-p +jump--online-last))
(completing-read (format "Search on (%s): " query)
(mapcar #'car +jump-search-url-alist)
nil t))
query)))

View file

@ -1,4 +1,4 @@
;;; feature/jump/autoload.el
;;; feature/jump/autoload.el -*- lexical-binding: t; -*-
(defvar +jump--rg-installed-p (executable-find "rg"))
(defvar +jump--ag-installed-p (executable-find "ag"))
@ -42,12 +42,11 @@ Tries xref and falls back to `dumb-jump', then rg/ag, then
((and (featurep 'evil)
evil-mode
(let ((bounds (bounds-of-thing-at-point 'symbol))
(orig-pt (point)))
(destructuring-bind (beg end) (bounds-of-thing-at-point 'symbol)
(evil-goto-definition)
(let ((pt (point)))
(not (and (>= pt (car bounds))
(< pt (cdr bounds))))))))
(not (and (>= pt beg)
(< pt end)))))))
(t (user-error "Couldn't find '%s'" sym)))))
@ -58,9 +57,8 @@ Tries xref and falls back to `dumb-jump', then rg/ag, then
Tries `xref-find-references' and falls back to rg/ag."
(interactive)
(let ((sym (thing-at-point 'symbol t)))
(cond ((progn
(ignore-errors (xref-find-references sym)
t)))
(cond ((ignore-errors (xref-find-references sym)
t))
((and sym
(featurep 'counsel)
@ -87,7 +85,7 @@ Interactively, you are prompted to choose a source from
(mapcar #'car +jump-search-url-alist)
nil t))
(thing-at-point 'symbol t)))
(condition-case ex
(condition-case _ex
(let ((url (cdr (assoc where +jump-search-url-alist))))
(unless url
(error "'%s' is an invalid search engine" where))

View file

@ -1,4 +1,4 @@
;;; feature/jump/config.el
;;; feature/jump/config.el -*- lexical-binding: t; -*-
;; "What am I looking at?"
;;

View file

@ -1,4 +1,4 @@
;;; feature/snippets/autoload/evil.el
;;; feature/snippets/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +snippets/expand-on-region ()

View file

@ -1,4 +1,4 @@
;;; feature/snippets/autoload/snippets.el
;;; feature/snippets/autoload/snippets.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +snippets/goto-start-of-field ()

View file

@ -1,4 +1,4 @@
;;; feature/snippets/config.el
;;; feature/snippets/config.el -*- lexical-binding: t; -*-
;; Snippets! I've thrown together a few hacks to make `yasnippet' and `evil'
;; behave together.

View file

@ -1,4 +1,4 @@
;;; feature/spellcheck/config.el
;;; feature/spellcheck/config.el -*- lexical-binding: t; -*-
(def-package! flyspell ; built-in
:commands flyspell-mode

View file

@ -1,4 +1,4 @@
;;; feature/syntax-checker/config.el
;;; feature/syntax-checker/config.el -*- lexical-binding: t; -*-
;; pkg-info doesn't get autoloaded when `flycheck-version' needs it, so we do
;; it ourselves:

View file

@ -1,4 +1,4 @@
;;; feature/version-control/+git.el
;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
(def-package! gitconfig-mode
:mode "/\\.?git/?config$"

View file

@ -1,4 +1,4 @@
;;; feature/version-control/autoload.el
;;; feature/version-control/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +vcs-root ()
@ -15,8 +15,8 @@
"Open the website for the current version controlled file. Fallback to
repository root."
(interactive)
(let ((git-link-open-in-browser t))
(call-interactively 'git-link)))
(destructuring-bind (beg end) (if buffer-file-name (git-link--get-region))
(git-link (git-link--select-remote) beg end)))
;;;###autoload
(defun +vcs/git-browse-issues ()

View file

@ -1,4 +1,4 @@
;;; feature/version-control/config.el
;;; feature/version-control/config.el -*- lexical-binding: t; -*-
(setq vc-make-backup-files nil)

View file

@ -1,4 +1,4 @@
;;; feature/workspaces/autoload/evil.el
;;; feature/workspaces/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+workspace:save-session "feature/workspaces/autoload/evil" nil t)
(evil-define-command +workspace:save-session (&optional bang name)

View file

@ -1,4 +1,4 @@
;;; feature/workspaces/autoload/workspaces.el
;;; feature/workspaces/autoload/workspaces.el -*- lexical-binding: t; -*-
(defvar +workspace-workspace-file "_workspaces"
"The file basename in which to store single workspace perspectives.")
@ -139,12 +139,11 @@ perspective or its hash table."
(persp-frame-switch name))
(defun +workspace--generate-id ()
(let ((numbers (mapcar (lambda (it) (string-to-number (substring it 1)))
(cl-remove-if-not (lambda (it) (string-match-p "^#[0-9]+$" it))
(+workspace-list)))))
(if numbers
(1+ (car (sort numbers (lambda (it other) (> it other)))))
1)))
(or (cl-loop for name in (+workspace-list)
when (string-match-p "^#[0-9]+$" name)
maximize (string-to-number (substring name 1)) into max
finally return (if max (1+ max)))
1))
(defun +workspace-protected-p (name)
(or (equal name persp-nil-name)
@ -373,17 +372,16 @@ the workspace and move to the next."
(defun +workspace--tabline (&optional names)
(let ((names (or names (+workspace-list)))
(current-name (+workspace-current-name))
(i 0))
(current-name (+workspace-current-name)))
(mapconcat
#'identity
(mapcar (lambda (it)
(cl-incf i)
(propertize (format " [%d] %s " i it)
'face (if (equal current-name it)
'+workspace-tab-selected-face
'+workspace-tab-face)))
names)
(cl-loop for name in names
for i to (length names)
collect
(propertize (format " [%d] %s " i name)
'face (if (equal current-name name)
'+workspace-tab-selected-face
'+workspace-tab-face)))
" ")))
(defun +workspace--message-body (message &optional type)

View file

@ -1,4 +1,4 @@
;;; feature/workspaces/config.el
;;; feature/workspaces/config.el -*- lexical-binding: t; -*-
;; `persp-mode' gives me workspaces, a workspace-restricted `buffer-list', and
;; file-based session persistence. I had used workgroups2 before this, but
@ -24,7 +24,8 @@ renamed.")
;; Plugins
;;
(def-package! persp-mode :demand t
(def-package! persp-mode
:demand t
:config
(setq persp-autokill-buffer-on-remove 'kill-weak
persp-nil-name "nil"
@ -44,35 +45,34 @@ renamed.")
(defun +workspaces|init (&rest _)
(unless persp-mode
(persp-mode +1))
;; The default perspective persp-mode makes (defined by `persp-nil-name') is
;; special and doesn't actually represent a real persp object, so buffers
;; can't really be assigned to it, among other quirks. We create a *real*
;; main workspace to fill this role.
(persp-add-new +workspaces-main)
;; Switch to it if we aren't auto-loading the last session
(when (or (= persp-auto-resume-time -1)
(equal (safe-persp-name (get-current-persp)) persp-nil-name))
(persp-frame-switch +workspaces-main)))
(persp-mode +1)
;; The default perspective persp-mode makes (defined by `persp-nil-name')
;; is special and doesn't actually represent a real persp object, so
;; buffers can't really be assigned to it, among other quirks. We create a
;; *real* main workspace to fill this role.
(persp-add-new +workspaces-main)
;; Switch to it if we aren't auto-loading the last session
(when (or (= persp-auto-resume-time -1)
(equal (safe-persp-name (get-current-persp)) persp-nil-name))
(persp-frame-switch +workspaces-main))))
(add-hook! 'after-init-hook
(if (display-graphic-p)
(+workspaces|init)
(add-hook 'after-make-frame-functions #'+workspaces|init)))
(add-hook 'emacs-startup-hook #'+workspaces|init)
(add-hook 'after-make-frame-functions #'+workspaces|init)
(define-key persp-mode-map [remap delete-window] #'+workspace/close-window-or-workspace)
;; Spawn a perspective for each new frame
(setq persp-init-new-frame-behaviour-override nil
persp-interactive-init-frame-behaviour-override
(lambda (frame &optional new-frame-p)
(lambda (frame &optional _new-frame-p)
(select-frame frame)
(+workspace/new)
(set-frame-parameter frame 'assoc-persp (+workspace-current-name))))
(defun +workspaces*delete-frame-and-persp (frame)
"Delete workspace associated with current frame IF it has no real buffers."
(when (and (string= (or (frame-parameter frame 'assoc-persp) "") (+workspace-current-name))
(when (and (string= (or (frame-parameter frame 'assoc-persp) "")
(+workspace-current-name))
(not (delq (doom-fallback-buffer) (doom-real-buffers-list))))
(+workspace/delete persp-name)))
(add-hook 'delete-frame-functions #'+workspaces*delete-frame-and-persp)

View file

@ -1,4 +1,4 @@
;;; lang/assembly/config.el
;;; lang/assembly/config.el -*- lexical-binding: t; -*-
(def-package! mips-mode :mode "\\.mips$")

View file

@ -1,4 +1,4 @@
;;; lang/cc/autoload.el
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +cc/autoclose->-maybe ()

View file

@ -1,4 +1,4 @@
;;; lang/cc/config.el --- C, C++, and Objective-C
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
(def-package! cc-mode
:commands (c-mode c++-mode objc-mode java-mode)
@ -67,7 +67,7 @@
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close '0)
(defun +cc--c-lineup-inclass (langelem)
(defun +cc--c-lineup-inclass (_langelem)
(if (memq major-mode '(c-mode c++-mode))
(let ((inclass (assq 'inclass c-syntactic-context)))
(save-excursion
@ -115,12 +115,15 @@
(def-package! irony
:after cc-mode
:commands irony-install-server
:init
(add-hook! 'c-mode-common-hook
(when (memq major-mode '(c-mode c++-mode objc-mode))
(irony-mode +1)))
:config
:preface
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
:init
(defun +cc|init-irony-mode ()
(when (memq major-mode '(c-mode c++-mode objc-mode))
(when (file-directory-p irony-server-install-prefix)
(irony-mode +1))))
(add-hook 'c-mode-common-hook #'+cc|init-irony-mode)
:config
(add-hook! 'irony-mode-hook #'(irony-eldoc flycheck-mode))
(add-hook! 'c++-mode-hook
(make-local-variable 'irony-additional-clang-options)

View file

@ -1,4 +1,4 @@
;;; lang/clojure/config.el
;;; lang/clojure/config.el -*- lexical-binding: t; -*-
(def-package! clojure-mode
:mode "\\.clj$")
@ -6,5 +6,4 @@
(def-package! cider
:commands (cider-jack-in cider-mode)
:config
(setq
nrepl-hide-special-buffers t))
(setq nrepl-hide-special-buffers t))

View file

@ -1,4 +1,4 @@
;;; module-crystal.el
;;; lang/crystal/config.el -*- lexical-binding: t; -*-
(def-package! crystal-mode
:mode "\\.cr$"

View file

@ -1,4 +1,4 @@
;;; module-csharp.el
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
(def-package! csharp-mode :mode "\\.cs$")

View file

@ -1,4 +1,4 @@
;;; module-data.el
;;; lang/data/config.el -*- lexical-binding: t; -*-
(push '("/sxhkdrc" . conf-mode) auto-mode-alist)

View file

@ -1,2 +1,2 @@
;;; lang/elixir/autoload/elixir.el
;;; lang/elixir/autoload/elixir.el -*- lexical-binding: t; -*-

View file

@ -1,10 +1,9 @@
;;; lang/elixir/config.el
;;; lang/elixir/config.el -*- lexical-binding: t; -*-
(def-package! elixir-mode
:mode ("\\.ex$")
:mode "\\.ex$"
:init
(add-hook 'elixir-mode-hook #'turn-off-smartparens-mode)
(add-hook 'elixir-mode-hook #'alchemist)
(add-hook! 'elixir-mode-hook #'(turn-off-smartparens-mode alchemist))
:config
(set! :company-backend 'elixir-mode '(alchemist-company company-yasnippet)))

View file

@ -1,4 +1,4 @@
;;; lang/elm/config.el
;;; lang/elm/config.el -*- lexical-binding: t; -*-
(def-package! elm-mode
:mode "\\.elm$"

View file

@ -1,4 +1,4 @@
;;; lang/emacs-lisp/autoload.el
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +emacs-lisp/repl ()
@ -20,18 +20,16 @@ to a pop up buffer."
(buf (get-buffer-create "*doom eval*"))
(inhibit-read-only t)
lines)
(unwind-protect
(progn
(with-current-buffer buf
(read-only-mode +1)
(erase-buffer)
(setq-local scroll-margin 0)
(emacs-lisp-mode)
(prin1 result buf)
(pp-buffer)
(setq lines (count-lines (point-min) (point-max)))
(goto-char (point-min))
(if (> lines 1)
(doom-popup-buffer buf)
(message "%s" (buffer-substring (point-min) (point-max)))
(kill-buffer buf)))))))
(with-current-buffer buf
(read-only-mode +1)
(erase-buffer)
(setq-local scroll-margin 0)
(emacs-lisp-mode)
(prin1 result buf)
(pp-buffer)
(setq lines (count-lines (point-min) (point-max)))
(goto-char (point-min))
(if (> lines 1)
(doom-popup-buffer buf)
(message "%s" (buffer-substring (point-min) (point-max)))
(kill-buffer buf)))))

View file

@ -1,10 +1,9 @@
;;; lang/emacs-lisp/config.el
;;; lang/emacs-lisp/config.el -*- lexical-binding: t; -*-
(def-package! elisp-mode ; built-in
:mode ("/Cask$" . emacs-lisp-mode)
:init
(add-hook 'emacs-lisp-mode-hook #'+emacs-lisp|hook)
:config
(set! :repl 'emacs-lisp-mode #'+emacs-lisp/repl)
(set! :eval 'emacs-lisp-mode #'+emacs-lisp-eval)

View file

@ -1,4 +1,4 @@
;;; lang/go/autoload.el
;;; lang/go/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
;; TODO (defun +go/build ())

View file

@ -1,4 +1,4 @@
;;; lang/go/config.el
;;; lang/go/config.el -*- lexical-binding: t; -*-
(def-package! go-mode
:mode "\\.go$"

View file

@ -1,4 +1,4 @@
;;; module-haskell.el
;;; lang/haskell/config.el -*- lexical-binding: t; -*-
(def-package! haskell-mode
:mode "\\.hs$"
@ -10,7 +10,6 @@
(load "haskell-mode-autoloads" nil t)
(set! :repl 'haskell-mode #'switch-to-haskell)
(push ".hi" completion-ignored-extensions)
(autoload 'switch-to-haskell "inf-haskell" nil t)

View file

@ -1,4 +1,4 @@
;;; lang/java/config.el
;;; lang/java/config.el -*- lexical-binding: t; -*-
;; yasnippet defuns
;;;###autoload
@ -9,7 +9,7 @@
;;;###autoload
(defun +java-android-mode-in-tags (&rest tags)
(-contains? tags (android-mode-tag-name)))
(cl-find (android-mode-tag-name) tags))
;;;###autoload
(defun +java-android-mode-tag-name ()

View file

@ -1,4 +1,4 @@
;;; lang/java/config.el
;;; lang/java/config.el -*- lexical-binding: t; -*-
(def-package! meghanada
:commands meghanada-mode

View file

@ -1,4 +1,4 @@
;;; lang/javascript/+screeps.el
;;; lang/javascript/+screeps.el -*- lexical-binding: t; -*-
;; TODO Constants may be out-of-date
@ -171,8 +171,9 @@
:match "/screeps/.+$"
:modes (+javascript-npm-mode))
(add-hook! '+javascript-screeps-mode-hook
(defun +javascript|init-screeps-mode ()
(when (eq major-mode 'js2-mode)
(push 'javascript-jshint flycheck-disabled-checkers)
(cl-pushnew 'javascript-jshint flycheck-disabled-checkers)
(setq js2-additional-externs (append '("_") screeps-objects screeps-constants))))
(add-hook '+javascript-screeps-mode-hook #'+javascript|init-screeps-mode)

View file

@ -1,4 +1,4 @@
;;; lang/javascript/autoload.el
;;; lang/javascript/autoload.el -*- lexical-binding: t; -*-
(defvar +javascript-npm-conf (make-hash-table :test 'equal))
@ -17,13 +17,13 @@ ignore the cache."
;;;###autoload
(defun +javascript-npm-dep-p (packages &optional project-root refresh-p)
(when-let (data (and (bound-and-true-p +javascript-npm-mode)
(+javascript-npm-conf)))
(+javascript-npm-conf project-root refresh-p)))
(let ((deps (append (cdr (assq 'dependencies data))
(cdr (assq 'devDependencies data)))))
(cond ((listp packages)
(funcall (if (eq (car packages) 'and)
'cl-every
'cl-some)
#'cl-every
#'cl-some)
(lambda (pkg) (assq pkg deps))
(if (listp packages) packages (list packages))))
((symbolp packages)

View file

@ -1,4 +1,4 @@
;; lang/javascript/config.el
;;; lang/javascript/config.el -*- lexical-binding: t; -*-
(load! +screeps)
@ -17,12 +17,13 @@
(add-hook! 'js2-mode-hook (setq js-switch-indent-offset js-indent-level))
;; Favor local eslint over global, if available
(add-hook! 'flycheck-mode-hook
(defun +javascript|init-flycheck-elint ()
(when (derived-mode-p 'js-mode 'js2-mode)
(when-let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" (doom-project-root)))
(exists-p (file-exists-p eslint))
(executable-p (file-executable-p eslint)))
(setq-local flycheck-javascript-eslint-executable eslint))))
(add-hook 'flycheck-mode-hook #'+javascript|init-flycheck-elint)
(set! :repl 'js2-mode '+javascript/repl)
(set! :electric 'js2-mode :chars '(?\} ?\) ?.))

View file

@ -1,4 +1,4 @@
;;; lang/julia/autoload.el
;;; lang/julia/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +julia/repl ()

View file

@ -1,4 +1,4 @@
;;; lang/julia/config.el
;;; lang/julia/config.el -*- lexical-binding: t; -*-
(use-package julia-mode
:mode "\\.jl$"

View file

@ -1,4 +1,4 @@
;;; lang/latex/config.el
;;; lang/latex/config.el -*- lexical-binding: t; -*-
(defvar +latex-bibtex-dir "~/work/writing/biblio/"
"Where bibtex files are kept.")

View file

@ -1,9 +1,9 @@
;;; lang/lua/autoload.el
;;; lang/lua/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +lua/repl ()
"Open Lua REPL."
(interactive)
(lua-start-process "lua" "lua")
(pop-to-buffer lua-process-buffer))

View file

@ -1,4 +1,4 @@
;;; lang/lua/config.el --- lua + Love2D
;;; lang/lua/config.el --- lua + Love2D -*- lexical-binding: t; -*-
(def-package! lua-mode
:mode "\\.lua$"

View file

@ -1,7 +1,7 @@
;;; lang/markdown/autoload.el
;;; lang/markdown/autoload.el -*- lexical-binding: t; -*-
;; Implement strike-through formatting
(defvar +text--markdown-regex-del
(defvar +markdown--regex-del
"\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)")
;;;###autoload
@ -11,12 +11,13 @@
(let ((delim "~~"))
(if (markdown-use-region-p)
;; Active region
(let ((bounds (markdown-unwrap-things-in-region
(region-beginning) (region-end)
+text--markdown-regex-del 2 4)))
(markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds)))
(destructuring-bind (beg end)
(markdown-unwrap-things-in-region
(region-beginning) (region-end)
+markdown--regex-del 2 4)
(markdown-wrap-or-insert delim delim nil beg end))
;; Bold markup removal, bold word at point, or empty markup insertion
(if (thing-at-point-looking-at +text--markdown-regex-del)
(if (thing-at-point-looking-at +markdown--regex-del)
(markdown-unwrap-thing-at-point nil 2 4)
(markdown-wrap-or-insert delim delim 'word nil nil)))))

View file

@ -1,4 +1,4 @@
;;; lang/markdown/config.el
;;; lang/markdown/config.el -*- lexical-binding: t; -*-
(def-package! markdown-mode
:mode ("\\.m\\(d\\|arkdown\\)$" "/README$"

View file

@ -1,4 +1,4 @@
;;; lang/php/autoload.el
;;; lang/php/autoload.el -*- lexical-binding: t; -*-
(defvar +php-composer-conf (make-hash-table :test 'equal))

View file

@ -1,4 +1,4 @@
;;; lang/php/config.el
;;; lang/php/config.el -*- lexical-binding: t; -*-
;; (def-package! hack-mode
;; :mode "\\.hh$"
@ -52,7 +52,8 @@
;; company will set up itself
(advice-add #'php-extras-company-setup :override #'ignore)
:config
(setq php-extras-eldoc-functions-file (concat doom-etc-dir "php-extras-eldoc-functions"))
(setq php-extras-eldoc-functions-file
(concat doom-etc-dir "php-extras-eldoc-functions"))
;; Make expensive php-extras generation async
(unless (file-exists-p (concat php-extras-eldoc-functions-file ".el"))

View file

@ -1,25 +1,20 @@
;;; lang/purescript/config.el
;;; lang/purescript/config.el -*- lexical-binding: t; -*-
(def-package! purescript-mode
:mode "\\.purs$"
:config
(add-hook! 'purescript-mode-hook #'flycheck-mode)
(add-hook! 'purescript-mode-hook #'company-mode)
(add-hook! 'purescript-mode-hook #'purescript-indentation-mode)
(add-hook! 'purescript-mode-hook #'rainbow-delimiters-mode)
(load "purescript-mode-autoloads" nil t)
)
(add-hook! 'purescript-mode-hook
#'(flycheck-mode purescript-indentation-mode rainbow-delimiters-mode))
(load "purescript-mode-autoloads" nil t))
;; (def-package! flycheck-purescript
;; :after purescript-mode
;; :config
;; (add-hook! 'flycheck-mode-hook #'flycheck-purescript-setup)
;; )
;; (add-hook 'flycheck-mode-hook #'flycheck-purescript-setup))
(def-package! psc-ide
:after purescript-mode
:config
(require 'psc-ide)
(add-hook! 'purescript-mode-hook #'psc-ide-mode)
)
(add-hook 'purescript-mode-hook #'psc-ide-mode))

View file

@ -2,10 +2,10 @@
;;; lang/purescript/packages.el
;; As far as I can tell, at the moment, flycheck-purescript does not work well
;; due to expecting the compiler to be psc rather than purs.
;; However, one of purescript-mode or psc-ide seems to handle flycheck, so it
;; might be unnecessary altogether.
;; (package! flycheck-purescript)
;; due to expecting the compiler to be psc rather than purs. However, one of
;; purescript-mode or psc-ide seems to handle flycheck, so it might be
;; unnecessary altogether.
;;(package! flycheck-purescript)
(package! psc-ide)
(package! purescript-mode)

View file

@ -1,4 +1,4 @@
;;; lang/python/autoload.el
;;; lang/python/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +python/repl ()

View file

@ -1,4 +1,4 @@
;;; lang/python/config.el
;;; lang/python/config.el -*- lexical-binding: t; -*-
(def-package! python
:commands python-mode

View file

@ -1,4 +1,4 @@
;;; lang/rest/config.el
;;; lang/rest/config.el -*- lexical-binding: t; -*-
(def-package! restclient
:commands restclient-mode

View file

@ -1,4 +1,4 @@
;;; lang/ruby/config.el
;;; lang/ruby/config.el -*- lexical-binding: t; -*-
(def-package! ruby-mode
:mode ("\\.rb$" "\\.rake$" "\\.gemspec$" "\\.?pryrc$"

View file

@ -1,4 +1,4 @@
;;; lang/rust/autoload.el
;;; lang/rust/autoload.el -*- lexical-binding: t; -*-
;; TODO (defun +rust/run-cargo () (interactive))

View file

@ -1,4 +1,4 @@
;;; module-rust.el
;;; lang/rust/config.el -*- lexical-binding: t; -*-
(defvar +rust-ext-dir (concat doom-etc-dir "rust/")
"TODO")
@ -16,11 +16,14 @@
:after rust-mode
:preface
:init
(add-hook! rust-mode '(racer-mode eldoc-mode flycheck-rust-setup))
(add-hook! 'rust-mode-hook #'(racer-mode eldoc-mode flycheck-rust-setup))
:config
(setq racer-cmd (expand-file-name "racer/target/release/racer" +rust-ext-dir)
racer-rust-src-path (expand-file-name "rust/src/" +rust-ext-dir))
(unless (file-exists-p racer-cmd)
(warn "rust-mode: racer binary can't be found; auto-completion is disabled"))
;; TODO Unit test keybinds
(map! :map rust-mode-map :m "gd" #'racer-find-definition))

View file

@ -1,4 +1,4 @@
;;; lang/scala/config.el
;;; lang/scala/config.el -*- lexical-binding: t; -*-
(def-package! scala-mode
:mode "\\.s\\(cala\\|bt\\)$"

View file

@ -1,5 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; lang/sh/config.el
;;; lang/sh/autoload.el -*- lexical-binding: t; -*-
(defvar sh-extra-font-lock--keywords
`((+sh--match-var-in-double-quoted-string
@ -13,8 +12,7 @@
;;;###autoload
(defun +sh--in-double-quoted-string-p ()
"Non-nil if point in inside a double-quoted string."
(let ((state (syntax-ppss)))
(eq (nth 3 state) ?\")))
(eq (nth 3 (syntax-ppss)) ?\"))
;;;###autoload
(defun +sh--match-var-in-double-quoted-string (limit)
@ -39,6 +37,7 @@
(with-no-warnings
(font-lock-fontify-buffer)))))
(defvar sh-shell-file)
;;;###autoload
(defun +sh/repl ()
"Open a shell REPL."

View file

@ -1,4 +1,4 @@
;;; lang/sh/config.el
;;; lang/sh/config.el -*- lexical-binding: t; -*-
(def-package! sh-script ; built-in
:mode ("\\.zsh$" . sh-mode)

View file

@ -1,4 +1,4 @@
;;; lang/swift/config.el
;;; lang/swift/config.el -*- lexical-binding: t; -*-
;; TODO Set up emacs task runners for fruitstrap
@ -8,7 +8,7 @@
(add-hook 'swift-mode-hook #'flycheck-mode)
:config
(set! :repl 'swift-mode #'swift-mode-run-repl) ; TODO test this
(push 'swift flycheck-checkers))
(cl-pushnew 'swift flycheck-checkers))
(def-package! company-sourcekit

View file

@ -1,4 +1,4 @@
;;; lang/typescript/config.el
;;; lang/typescript/config.el -*- lexical-binding: t; -*-
(def-package! typescript-mode
:mode "\\.ts$"

View file

@ -1,4 +1,4 @@
;;; lang/web/+css.el
;;; lang/web/+css.el -*- lexical-binding: t; -*-
;; css-mode hooks apply to scss and less-css modes
(add-hook 'css-mode-hook #'rainbow-delimiters-mode)
@ -53,5 +53,5 @@
(def-package! stylus-mode
:mode "\\.styl$"
:init (add-hook! stylus-mode '(yas-minor-mode-on flycheck-mode)))
:init (add-hook! stylus-mode #'(yas-minor-mode-on flycheck-mode)))

View file

@ -1,14 +1,14 @@
;;; lang/web/config.el
;;; lang/web/+html.el -*- lexical-binding: t; -*-
(def-package! web-mode
:mode ("\\.p?html?$"
"\\.\\(tpl\\|blade\\)\\(\\.php\\)?$"
"\\.erb$"
"\\.jsp$"
"\\.as[cp]x$"
"\\.mustache$"
"\\.tsx$"
"wp-content/themes/.+/.+\\.php$")
:mode "\\.p?html?$"
:mode "\\.\\(tpl\\|blade\\)\\(\\.php\\)?$"
:mode "\\.erb$"
:mode "\\.jsp$"
:mode "\\.as[cp]x$"
:mode "\\.mustache$"
:mode "\\.tsx$"
:mode "wp-content/themes/.+/.+\\.php$"
:init
(add-hook 'web-mode-hook #'turn-off-smartparens-mode)
:config
@ -38,7 +38,8 @@
(def-package! pug-mode
:mode ("\\.jade$" "\\.pug$")
:mode "\\.jade$"
:mode "\\.pug$"
:config
(set! :company-backend 'pug-mode '(company-yasnippet))
(map! :map pug-mode-map

View file

@ -1,4 +1,4 @@
;;; lang/web/+css.el
;;; lang/web/autoload/css.el -*- lexical-binding: t; -*-
;;;###autoload
;; TODO (defun +css/scss-build ())
@ -12,10 +12,9 @@
(interactive)
;; TODO Remove evil dependency
(save-excursion
(let* ((bounds (or (ignore-errors (evil-a-curly))
(user-error "No block found")))
(beg (car bounds))
(end (cadr bounds)))
(destructuring-bind (beg end)
(or (ignore-errors (evil-a-curly))
(user-error "No block found"))
(if (= (line-number-at-pos beg) (line-number-at-pos end))
(save-excursion
(goto-char (1+ beg)) (insert "\n")

View file

@ -1,4 +1,4 @@
;;; lang/html/autoload/evil.el
;;; lang/html/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+web:encode-html-entities "lang/web/autoload/evil" nil t)
(evil-define-operator +web:encode-html-entities (beg end &optional input)

View file

@ -1,4 +1,4 @@
;;; lang/web/autoload/html.el
;;; lang/web/autoload/html.el -*- lexical-binding: t; -*-
;;;###autoload
(defvar +web-entities-list
@ -16,14 +16,12 @@ character.")
"HTML encode/decode TEXT. Based on Xah's replace HTML named entities function
@ http://ergoemacs.org/emacs/elisp_replace_html_entities_command.html"
(interactive "<!><r>")
(mapc (lambda (rep)
(let ((from (elt rep (if decode-p 0 1)))
(to (elt rep (if decode-p 1 0)))
(case-fold-search t))
(when (string-match-p (regexp-quote from) text)
(setq text (s-replace from to text)))))
+web-entities-list)
text)
(dolist (rep +web-entities-list text)
(let ((from (elt rep (if decode-p 0 1)))
(to (elt rep (if decode-p 1 0)))
(case-fold-search t))
(when (string-match-p (regexp-quote from) text)
(setq text (s-replace from to text))))))
(defun +web--entities-region (beg end &optional decode-p)
"HTML encode/decode the selected region. Based on Xah's replace HTML named entities
@ -31,11 +29,10 @@ function @ http://ergoemacs.org/emacs/elisp_replace_html_entities_command.html"
(save-restriction
(narrow-to-region beg end)
(let (case-fold-search)
(mapc (lambda (rep)
(goto-char (point-min))
(while (search-forward (elt rep (if decode-p 0 1)) nil t)
(replace-match (elt rep (if decode-p 1 0)) 'FIXEDCASE 'LITERAL)))
reps))))
(dolist (rep reps)
(goto-char (point-min))
(while (search-forward (elt rep (if decode-p 0 1)) nil t)
(replace-match (elt rep (if decode-p 1 0)) 'FIXEDCASE 'LITERAL))))))
;;;###autoload
(defun +web-encode-entities (text)

View file

@ -1,2 +1,2 @@
;;; lang/web/autoload/web.el
;;; lang/web/autoload/web.el -*- lexical-binding: t; -*-

View file

@ -1,4 +1,4 @@
;;; lang/web/config.el
;;; lang/web/config.el -*- lexical-binding: t; -*-
(load! +html)
(load! +css)
@ -39,9 +39,10 @@
:modes (web-mode js-mode coffee-mode css-mode haml-mode pug-mode)
:files (and "config.yml" (or "_layouts/" "_posts/"))
:init
(add-hook! '+web-jekyll-mode-hook
(defun +web|init-jekyll-mode ()
(when (eq major-mode 'web-mode)
(web-mode-set-engine "django"))))
(web-mode-set-engine "django")))
(add-hook '+web-jekyll-mode-hook #'+web|init-jekyll-mode))
(def-project-mode! +web-wordpress-mode
:modes (php-mode web-mode css-mode haml-mode pug-mode)

View file

@ -1,4 +1,4 @@
;;; private/hlissner/+bindings.el
;;; private/hlissner/+bindings.el -*- lexical-binding: t; -*-
;; I've swapped these keys on my keyboard
(setq x-super-keysym 'alt
@ -347,9 +347,7 @@
: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))))
:i "C-p" #'+company/dabbrev-code-previous)
(:after company
(:map company-active-map
;; Don't interfere with `evil-delete-backward-word' in insert mode

View file

@ -1,3 +1,5 @@
;;; private/hlissner/+commands.el -*- lexical-binding: t; -*-
(defalias 'ex! 'evil-ex-define-cmd)
;;; Commands defined elsewhere

View file

@ -1,4 +1,4 @@
;;; private/hlissner/autoload/evil.el
;;; private/hlissner/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+hlissner:multi-next-line "private/hlissner/autoload/evil" nil t)
(evil-define-motion +hlissner:multi-next-line (count)

Some files were not shown because too many files have changed in this diff Show more