Write core initfiles + defuns

This commit is contained in:
Henrik Lissner 2015-06-15 09:05:52 +02:00
parent c0661f5293
commit b998f4ab08
52 changed files with 2444 additions and 706 deletions

44
core/benchmark.el Normal file
View file

@ -0,0 +1,44 @@
(defvar require-times nil
"A list of (FEATURE . LOAD-DURATION).
LOAD-DURATION is the time taken in milliseconds to load FEATURE.")
(defadvice require
(around build-require-times (feature &optional filename noerror) activate)
"Note in `require-times' the time taken to require each feature."
(let* ((already-loaded (memq feature features))
(require-start-time (and (not already-loaded) (current-time))))
(prog1
ad-do-it
(when (and (not already-loaded) (memq feature features))
(add-to-list 'require-times
(cons feature
(float-time (time-subtract (current-time) require-start-time)))
t)))))
(defun list-times ()
(interactive)
(let ((temp-buffer (get-buffer-create "*benchmark*"))
(sum 0.0))
(popwin:popup-buffer temp-buffer :stick t)
(erase-buffer)
(org-mode)
(dolist (feature require-times)
(if (eq feature 'null)
(progn
(insert "|----+----+----|\n")
(insert (format "| %6f | Subtotal |\n" sum))
(insert "|----+----+----|\n"))
(let ((time (cdr feature)))
(insert (format "| %6f | %s | %s |\n" time (car feature) (cond ((>= time 0.4) "XXX")
((>= time 0.1) "X")
((>= time 0.05) ".")
(t " "))))
(setq sum (+ sum time)))))
(save-excursion
(insert "|----+----+----|\n")
(insert (format "| %6f | Total |\n" sum))
(insert (format "| %s | On Init |\n" (emacs-init-time))))
(org-table-align)))
(provide 'benchmark)

78
core/core-auto-insert.el Normal file
View file

@ -0,0 +1,78 @@
;;; core-auto-insert.el --- file templates
(use-package autoinsert
:after yasnippet
:init
(setq auto-insert-query nil) ; Don't prompt before insertion
(setq auto-insert-alist '())
:config
(auto-insert-mode 1)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (add-template! "/\\.gitignore$" "%%" 'gitignore-mode)
;; C/C++
;; (add-template! "/Makefile$" "%%" 'makefile-gmake-mode)
;; (add-template! "/main\\.\\(cc\\|cpp\\)$" "%main.cpp%" 'c++-mode)
;; (add-template! "/win32_\\.\\(cc\\|cpp\\)$" "%winmain.cpp%" 'c++-mode)
;; (add-template! "\\.\\([Hh]\\|hpp\\)$" "%.h%" 'c++-mode)
;; (add-template! "\\.\\([Cc]\\|cc\\|cpp\\)$" "%.cpp%" 'c++-mode)
;; Shell scripts
;; (add-template! "\\.z?sh$" "%%" 'sh-mode)
;; Ruby
;; (add-template! "/spec_helper\\.rb$" "%helper%" 'rspec-mode t)
;; (add-template! "_spec\\.rb$" "%%" 'rspec-mode t)
;; (add-template! "/\\.rspec$" "%.rspec%" 'rspec-mode)
;; (add-template! "/Rakefile$" "%Rakefile%" 'ruby-mode t)
;; (add-template! "/Gemfile$" "%Gemfile%" 'ruby-mode t)
;; (add-template! "\\.gemspec$" "%.gemspec%" 'ruby-mode t)
;; (add-template! "/lib/.+\\.rb$" "%module%" 'ruby-mode t)
;; (add-template! "\\.rb$" "%%" 'ruby-mode)
;; ;; Python
;; (add-template! "tests?/test_.+\\.py$" "%%" 'nose-mode)
;; (add-template! "/setup\\.py$" "%setup%" 'python-mode)
;; (add-template! "\\.py$" "%%" 'python-mode)
;; ;; PHP
;; (add-template! "\\.class\\.php$" %class%" 'php-mode)
;; (add-template! "\\.php$" %%" 'php-mode)
;; ;; Markdown
;; (add-template! "\\.md$" "%%" 'markdown-mode)
;; (add-template! "/_posts/.+\\.md$" "%jekyll-post" 'markdown-mode)
;; (add-template! "/_layouts/.+\\.html$" "%jekyll-layout%" 'web-mode)
;; ;; Javascript
;; (add-template! "\\.lbaction/.+/Info.plist$" "%Info.plst%" 'lb6-mode)
;; (add-template! "\\.lbaction/.+/\\(default\\|suggestions\\)\\.js$" "%default.js%" 'lb6-mode)
;; (add-template! "/package\\.json$" "%package.json%" 'json-mode)
;; (add-template! "\\.\\(json\\|jshintrc\\)$" "%%" 'json-mode)
;; ;; SCSS
;; (add-template! "/master\\.scss$" "%master%" 'scss-mode)
;; (add-template! "/normalize\\.scss$" "%normalize%" 'scss-mode)
;; (add-template! "\\.scss$" "%%" 'scss-mode)
;; ;; HTML
;; (add-template! "\\.html$" "%%" 'web-mode)
;; Lua
;; (add-template! "\\.love/main\\.lua$" "%love.main%" 'lua-mode)
;; (add-template! "/conf\\.lua$" "@@love.conf" 'love-mode)
;; (add-template! "\\.lua$" "%%" 'lua-mode)
;; ;; Java
;; (add-template! "/src/.+/.+\\.java$" "@@" 'java-mode)
;; (add-template! "/build\\.gradle$" "@@gradle" 'android-mode)
;; ;; Elisp
(add-template! "\\.emacs\\.d/.+\\.el$" "@@initfile" 'emacs-lisp-mode)
;; (add-template! "\\.emacs\\.d/snippets/.+$" "@@" 'snippet-mode)
)
(provide 'core-auto-insert)
;;; core-auto-insert.el ends here

54
core/core-company.el Normal file
View file

@ -0,0 +1,54 @@
;;; core-company.el --- auto completion backend (Company-mode)
;; see lib/company-macros.el
(eval-when-compile (require 'core))
(use-package company
:diminish (company-mode . "=")
:commands (company-complete-common company-files company-tags
company-ispell company-yasnippet company-semantic
company-dabbrev-code)
:init
(after! abbrev (diminish 'abbrev-mode "A"))
(setq company-idle-delay nil
company-minimum-prefix-length 1
company-show-numbers nil
company-tooltip-limit 20
company-dabbrev-downcase nil
company-dabbrev-ignore-case nil
company-tooltip-align-annotations t
company-require-match 'never
company-global-modes '(not eshell-mode comint-mode org-mode erc-mode
message-mode help-mode)
company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
company-echo-metadata-frontend
company-preview-if-just-one-frontend)
company-dict-dir (concat narf-private-dir "dict/"))
:config
(global-company-mode +1)
;; (use-package company-dict :defer t)
;; (setq-default company-backends (append '(company-dict company-keywords) company-backends))
(setq-default company-backends (append '(company-keywords) company-backends))
;; TODO: Investigate yasnippet
(after! yasnippet
(setq-default company-backends (append '(company-capf company-yasnippet) company-backends)))
(add-to-list 'company-transformers 'company-sort-by-occurrence)
(add-company-backend! nxml-mode (nxml yasnippet))
(add-company-backend! emacs-lisp-mode (elisp yasnippet))
;; Rewrite evil-complete to use company-dabbrev
(setq company-dabbrev-code-other-buffers t
company-dabbrev-code-buffers nil
evil-complete-next-func 'narf/company-evil-complete-next
evil-complete-previous-func 'narf/company-evil-complete-previous)
(shut-up!
(setq company-statistics-file (! (concat narf-temp-dir "company-statistics-cache.el")))
(require 'company-statistics)
(company-statistics-mode)))
(provide 'core-company)
;;; core-company.el ends here

View file

@ -1,16 +1,23 @@
(! (defalias '@--concat-forms 'use-package-concat)
(defalias '@--normalize-symbols 'use-package-normalize-symlist)
(defalias '@--normalize-paths 'use-package-normalize-paths)
(eval-when-compile (require 'cl-lib))
;; Backwards compatible `with-eval-after-load'
(unless (fboundp 'with-eval-after-load)
;; Backwards compatible `with-eval-after-load'
(unless (fboundp 'with-eval-after-load)
(defmacro with-eval-after-load (file &rest body)
`(eval-after-load ,file
`(funcall (function ,(lambda () ,@body))))))
`(eval-after-load ,file (lambda () ,@body))))
(defmacro @after (feature &rest forms)
(declare (indent 1))
(defmacro λ (&rest body)
"A shortcut for: `(lambda () (interactive) ,@body)"
`(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)
@ -21,20 +28,7 @@
'with-no-warnings)
(with-eval-after-load ',feature ,@forms)))
(defmacro @shut-up (&rest body)
"Silence message output from code."
(declare (indent defun))
`(let (message-log-max) ,@body (message "")))
(defmacro @ (args &rest body)
"A shortcut for: `(lambda ,args ,@body)"
`(lambda ,args ,@body))
(defmacro λ (&rest body)
"A shortcut for: `(lambda () (interactive) ,@body)"
`(lambda () (interactive) ,@body))
(defmacro @add-hook (hook &rest func-or-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
@ -45,27 +39,27 @@ forms. Forms will be wrapped in one 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-hook 'enable-something)
=> (add-hook 'some-mode-hook 'enable-something)
(@add-hook some-mode '(enable-something and-another))
(add-hook! some-mode '(enable-something and-another))
=> (add-hook 'some-mode-hook 'enable-something)
(add-hook 'some-mode-hook 'and-another)
(@add-hook '(one-mode-hook second-mode-hook) 'enable-something)
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
=> (add-hook 'one-mode-hook 'enable-something)
(add-hook 'second-mode-hook 'enable-something)
(@add-hook (one-mode second-mode) 'enable-something)
(add-hook! (one-mode second-mode) 'enable-something)
=> (add-hook 'one-mode-hook 'enable-something)
(add-hook 'second-mode-hook 'enable-something)
(@add-hook (one-mode second-mode) (setq v 5) (setq a 2))
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
=> (add-hook 'one-mode-hook (lambda () (setq v 5) (setq a 2)))
(add-hook 'second-mode-hook (lambda () (setq v 5) (setq a 2)))"
(declare (indent 1))
(declare (indent defun) (debug t))
(unless func-or-forms
(error "@add-hook: FUNC-OR-FORMS is empty"))
(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))
@ -75,51 +69,57 @@ Examples:
(list (cadr val)))
(list func-or-forms)))
(forms '()))
(mapc (@ (f)
(let ((func (cond ((symbolp f) `(quote ,f))
(mapc
(lambda (f) (let ((func (cond ((symbolp f) `(quote ,f))
(t `(lambda () ,@func-or-forms)))))
(mapc (@ (h)
(push `(add-hook ',(if quoted h (intern (format "%s-hook" h))) ,func) forms))
(mapc
(lambda (h) (push `(add-hook ',(if quoted h (intern (format "%s-hook" h))) ,func) forms))
(if (listp hook) hook (list hook))))) funcs)
`(progn ,@forms)))
(cl-defmacro @associate (mode &key in
(cl-defmacro associate! (mode &key in
&key match
&key files
&allow-other-keys)
"Associate a major or minor mode to certain patterns and project files."
(let* ((minor-p (memq mode minor-mode-alist))
(modes (@--normalize-symbols ":in" in)))
(@--concat-forms
(when match
`(add-to-list ,(if minor-p 'narf-auto-minor-mode-alist 'auto-mode-alist)
(cons ,match ,mode)))
(when files
`(defun ,(intern (format "narf|init-mode-%s" 'lb6-mode)) ()
(when (and (assq major-mode '(,@(@--normalize-paths ":in" in)))
(narf-project-has-files ,@(@--normalize-paths ":files" files)))
(,mode 1)))))))
(declare (indent 1))
(let* ((minor-p (assoc mode minor-mode-alist)))
`(progn
(,@(when match
`(add-to-list ',(if minor-p 'narf-auto-minor-mode-alist 'auto-mode-alist)
(cons ,match ',mode))))
(,@(when files
(unless (or (listp files) (stringp files))
(user-error "associate! :files expects a string or list of strings"))
(let ((hook-name (intern (format "narf--init-mode-%s" mode))))
`(progn
(defun ,hook-name ()
(when (and (not ,mode)
(narf/project-has-files ,@(-list files)))
(,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))))))))))
(@after evil
;; Placeholders to correct binding indentation. Don't use these.
(defmacro :leader (key &rest rest) (declare (indent 1)))
(defmacro :localleader (key &rest rest) (declare (indent 1)))
(defmacro :map (key &rest rest) (declare (indent 1)))
(defmacro :after (key &rest rest) (declare (indent 1)))
(defmacro :when (key &rest rest) (declare (indent 1)))
(after! evil
;; Register keywords for proper indentation (see `bind!')
(put ':prefix '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)
(macroexpand `(@map (:map my-map "C-k" 'hello :n "C-p" 'goodbye)))
(defmacro @map (&rest rest)
(declare (indent defun))
(defmacro bind! (&rest rest)
(let ((i 0)
key def
first-set
prefix
internal
(default-keymaps '(narf-mode-map))
(keymaps (if (boundp 'keymaps) keymaps))
(states (if (boundp 'states) states '()))
(forms (if (boundp 'forms) forms))
(forms '())
(state-map '(("n" . normal)
("v" . visual)
("i" . insert)
@ -132,155 +132,67 @@ Examples:
(setq keymaps default-keymaps))
(while rest
(setq key (pop rest))
(message ">>> KEY: %s" key)
(add-to-list
'forms
(cond ((eq key '-)) ; skip this
(cond ((eq key '-) nil) ; skip this
((listp key) ; it's a sub exp
(macroexpand `(@map ,@key)))
`((bind! ,@key)))
((keywordp key)
(pcase key
;; TODO: Data checks
(:leader (setq prefix (kbd (pop rest))) nil)
(:localleader (setq prefix (kbd (pop rest))) nil)
(:prefix (setq prefix (kbd (pop rest)))
(if (= i 0) (setq first-set `(:prefix . ,prefix)))
nil)
(:map (setq keymaps (-list (pop rest)))
(if (= i 0) (setq first-set `(:map . ,keymaps)))
nil)
(:unset (prog1 `(@map ,(kbd (pop rest)) nil)))
(:after (prog1 `(@after ,(pop rest) ,(macroexp-progn `(@map ,@rest))) (setq rest '())))
(:when (prog1 `(when ,(pop rest) ,(macroexp-progn `(@map ,@rest))) (setq rest '())))
(:unless (prog1 `(unless ,(pop rest) ,(macroexp-progn `(@map ,@rest))) (setq rest '())))
(:unset `((bind! ,(kbd (pop rest)) nil)))
(:after (prog1 `((after! ,(pop rest) (bind! ,@rest))) (setq rest '())))
(:when (prog1 `((if ,(pop rest) (bind! ,@rest))) (setq rest '())))
(:unless (prog1 `((if (not ,(pop rest)) (bind! ,@rest))) (setq rest '())))
(otherwise ; might be a state prefix
(mapc (lambda (letter)
(when (assoc letter state-map)
(add-to-list 'states (cdr (assoc letter state-map)))))
(s-split "" (substring (symbol-name key) 1) t)) nil)))
(if (assoc letter state-map)
(add-to-list 'states (cdr (assoc letter state-map)))
(user-error "Invalid mode prefix %s in key %s" letter key)))
(s-split "" (substring (symbol-name key) 1) t))
(unless states
(user-error "Unrecognized keyword %s" key)) nil)))
;; It's a key-def pair
((or (stringp key)
(characterp key)
(vectorp key))
(when (stringp key)
(setq key (kbd key)))
(when prefix
(cond ((vectorp key)
(setq key (vconcat prefix key)))
(t
(setq key (concat prefix key)))))
(unless (car rest)
(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 ((first-key (car first-set))
(first-value (cdr first-set))
out-forms)
(dolist (keymap keymaps)
(if (not states)
(add-to-list 'out-forms `(define-key ,keymap ,key ,def) t)
;; (add-to-list 'out-forms `(define-key ,keymap ,key ,def) t)
(add-to-list 'out-forms `(evil-define-key nil ,keymap ,key ,def) t)
(dolist (state states)
(add-to-list 'out-forms `(define-key (evil-get-auxiliary-keymap ,keymap ,state t) ,key ,def) t))))
(add-to-list 'out-forms `(evil-define-key ',state ,keymap ,key ,def) t))))
;; (add-to-list 'out-forms `(define-key (evil-get-auxiliary-keymap ,keymap ',state) ,key ,def) t))))
(setq prefix (if (eq first-key :prefix) first-value))
(setq keymaps (if (eq first-key :map) first-value default-keymaps))
(setq states '())
out-forms))
(t (user-error "" key)))
(t (user-error "Invalid key %s" key)))
t)
(cl-incf i))
`(progn ,@(apply #'nconc (delete nil (delete (list nil) forms))))))
;; (defmacro @map (&rest keys)
;; "A minimalistic and evil-centric way of binding keys. KEYS is
;;made up of either:
;;
;;1. Any of the following keywords:
;;
;;:when CONDITION
;;:unless CONDITION
;;:prefix PREFIX Key(s) to prefix keymappings with
;;:map KEYMAP Keymaps to bind keys to. Can be a list.
;;:global Tags these keymaps for the global keymap
;;:local Ditto, but for local keymap
;;
;;
;;2. A key (as a vector e.g. [escape], a string \"<escape>\", or
;;character ?\^?).
;;
;;3. A key definition: a symbol or a lambda function. "
;; (declare (indent defun))
;; (let* ((keymaps (-list map))
;; (states (-list in))
;; (forms '())
;; item def)
;; (while keys
;; (setq item (pop keys))
;; (cond ((keywordp item)
;; (let ((val (pop keys)))
;; (pcase item
;; (:after)
;; (:when)
;; (:unless)
;; (:keymap)
;; (:in)
;; (otherwise)
;; )
;; ))
;;
;; ((or (and (symbolp item)
;; (evil-state-p item))
;; (and (listp item)
;; (--all? (evil-state-p it) item)))
;; (setq states (-list item)))
;;
;; ;; item-definition pairs
;; ((consp item)
;; (let ((def (cdr item))
;; (item (car item)))
;; (message "k %s : d %s" item def)
;;
;; ;;(or (stringp item)
;; ;; (vectorp item)
;; ;; (characterp item))
;; ;;(unless items (signal 'bind-no-definition item))
;; ;;(setq def (pop items))
;; (when condition
;; ;; Process the item
;; (cond ((stringp item) (setq item (kbd item)))
;; ((characterp item) (setq item (string item))))
;; (when prefix
;; (setq item (if (vectorp item)
;; (vconcat prefix item)
;; (concat (kbd prefix) item))))
;; ;; Do the binding
;; `(,@(if (null states)
;; (push (mapcar
;; (lambda (keymap) `(define-key ,keymap ,item ,def)) keymaps)
;; forms)
;; (push (mapcar (lambda (state)
;; (mapcar (lambda (keymap)
;; `(define-key (evil-get-auxiliary-keymap ,keymap ',state t) ,item ,def))
;; keymaps))
;; states) forms))))))
;;
;; ;; fallback
;; (t (signal 'bind-invalid-key key)))
;; `(progn ,@forms))))
(defmacro @exmap (command func)
(evil-ex-define-cmd
,command
,(cond ((autoloadp (symbol-function `,func))
`(lambda () (interactive) (call-interactively ,func)))
((symbolp `,func) func)
(t (user-error "Command for %s is invalid" command)))))))
`(progn ,@(apply #'nconc (delete nil (delete (list nil) forms)))))))
;; Hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -311,7 +223,7 @@ Examples:
(defun narf|update-scratch-buffer-cwd () ; see core-editor.el
"Make sure scratch buffer is always 'in a project.'"
(let ((dir (narf-project-root)))
(let ((dir (narf/project-root)))
(with-current-buffer (get-buffer-create "*scratch*")
(cd dir))))
@ -329,43 +241,26 @@ to abort the minibuffer."
(delete-windows-on "*Completions*"))
(abort-recursive-edit))))
;;;; Project defuns ;;;;;;;;;;;;;;;;;;;;
(defun narf-project-root (&optional strict-p)
"Get the path to the root of your project. Uses `narf-project-root-files' to
determine if a directory is a project."
(let ((home (file-truename "~")))
(catch 'found
(f-traverse-upwards
(lambda (path)
(let ((path (file-truename path)))
(if (file-equal-p home path)
(throw 'found (if strict-p nil default-directory))
(dolist (file narf-project-root-files)
(when (file-exists-p (expand-file-name file path))
(throw 'found path)))))) default-directory)
default-directory)))
(defun narf-project-has-files (files &optional root)
"Return non-nil if `file' exists in the project root."
(let ((root (or root (narf-project-root)))
(files (if (listp files) files (list files)))
found-p file)
(while (and files (not found-p))
(setq file (pop files))
(setq found-p (file-exists-p (narf-project-path-to file root))))
found-p))
(defun narf-project-path-to (file &optional root)
(let ((root (or root (narf-project-root))))
(expand-file-name file root)))
(defun narf-project-name (&optional root)
(file-name-nondirectory (directory-file-name (or root (narf-project-root)))))
(defun narf-project-p ()
(not (null (narf-project-root t))))
(after! evil
(evil-define-command narf:exit-mode-maybe ()
"Exits insert/replace mode using jk without the momentary pause caused by
key-chord-define."
:repeat change
(interactive)
(let ((modified (buffer-modified-p)))
(call-interactively 'self-insert-command)
(let ((evt (read-event nil nil 0.4)))
(cond
((null evt) (message ""))
((and (integerp evt) (or (char-equal evt ?k)
(char-equal evt ?K)))
(if (evil-replace-state-p)
(evil-replace-backspace)
(delete-char -1))
(set-buffer-modified-p modified)
(push 'escape unread-command-events))
(t
(setq unread-command-events (append unread-command-events (list evt)))))))))
(provide 'core-defuns)
;;; core-defuns.el ends here

BIN
core/core-defuns.elc Normal file

Binary file not shown.

View file

@ -1,3 +1,5 @@
;;; core-editor.el
;; see lib/editor-defuns.el
;;;; Editor behavior ;;;;;;;;;;;;;;;;
(setq-default
@ -12,7 +14,7 @@
fill-column 80
;; Sane scroll settings
scroll-margin 5
scroll-margin 0
scroll-conservatively 9999
scroll-preserve-screen-position t
@ -27,61 +29,14 @@
truncate-partial-width-windows nil)
;; Modes 'n hooks ;;;;;;;;;;;;;;;;;;;
(@associate text-mode :match "/LICENSE[^/]*$")
(@associate sh-mode :match "zsh\\(env\\|rc\\)?$")
(@associate sh-mode :match "z\\(profile\\|login\\|logout\\)?$")
(@associate sh-mode :match "zsh/")
(@associate applescript-mode :match "\\.applescript$")
(@associate emacs-lisp-mode :match "Cask$")
(@associate emacs-lisp-mode :match "\\.el\\.gz$")
(@associate makefile-gmake-mode :match "/Makefile$")
(@associate nxml-mode :match "\\.plist$")
(@add-hook help-mode 'visual-line-mode)
(@add-hook python-mode 'electric-indent-local-mode)
(@add-hook emacs-lisp-mode 'turn-on-eldoc-mode)
(@add-hook eldoc-mode (diminish 'eldoc-mode " ?"))
(@add-hook makefile-mode 'narf|enable-tabs) ; Use normal tabs in makefiles
;; Fix code folding
;; (@add-hook prog-mode (unless (bound-and-true-p hs-minor-mode)
;; (hs-minor-mode 1)
;; (diminish 'hs-minor-mode)))
(@add-hook find-file 'narf|update-scratch-buffer-cwd)
;; (add-hook 'before-save-hook 'delete-trailing-whitespace)
;; If file is oversized...
(@add-hook find-file (when (> (buffer-size) (* 1024 1024))
(setq buffer-read-only t)
(buffer-disable-undo)
(fundamental-mode)
(visual-line-mode)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (global-whitespace-mode 1) ; Show whitespace
(global-font-lock-mode t) ; Enable syntax highlighting for older emacs
(global-auto-revert-mode 1) ; revert buffers for changed files
(electric-indent-mode -1)
(winner-mode 1) ; window config undo/redo
;; Automatic minor modes ;;;;;;;;;;;
(defvar narf/auto-minor-mode-alist ()
"Alist of filename patterns vs correpsonding minor mode functions,
see `auto-mode-alist' All elements of this alist are checked, meaning
you can enable multiple minor modes for the same regexp.")
(defun narf|enable-minor-mode-maybe ()
"Check file name against `narf/auto-minor-mode-alist'."
"Check file name against `narf-auto-minor-mode-alist'."
(when buffer-file-name
(let ((name buffer-file-name)
(remote-id (file-remote-p buffer-file-name))
(alist narf/auto-minor-mode-alist))
(alist narf-auto-minor-mode-alist))
;; Remove backup-suffixes from file name.
(setq name (file-name-sans-versions name))
;; Remove remote file name identification.
@ -93,11 +48,63 @@ you can enable multiple minor modes for the same regexp.")
(funcall (cdar alist) 1))
(setq alist (cdr alist))))))
(@add-hook find-file 'narf|enable-minor-mode-maybe)
(add-hook! find-file 'narf|enable-minor-mode-maybe)
;; Modes 'n hooks ;;;;;;;;;;;;;;;;;;;
(associate! text-mode :match "/LICENSE[^/]*$")
(associate! sh-mode :match "z\\(profile\\|login\\|logout\\)?$")
(associate! sh-mode :match "zsh/")
(associate! applescript-mode :match "\\.applescript$")
(associate! emacs-lisp-mode :match "Cask$")
(associate! emacs-lisp-mode :match "\\.el\\.gz$")
(associate! makefile-gmake-mode :match "/Makefile$")
(associate! nxml-mode :match "\\.plist$")
(add-hook! help-mode 'visual-line-mode)
(add-hook! python-mode 'electric-indent-local-mode)
(add-hook! makefile-mode 'narf|enable-tabs) ; Use normal tabs in makefiles
(add-hook! before-save 'delete-trailing-whitespace)
(add-hook! eldoc-mode (diminish 'eldoc-mode " ?"))
;; Line wrapping
(add-hook! text-mode 'narf|enable-hard-wrap)
(add-hook! prog-mode 'narf|enable-comment-hard-wrap)
(add-hook! auto-fill-mode (diminish 'auto-fill-function))
;; If file is oversized...
(add-hook! find-file
(when (> (buffer-size) (* 1024 1024))
(setq buffer-read-only t)
(buffer-disable-undo)
(fundamental-mode)
(visual-line-mode)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (global-whitespace-mode 1) ; Show whitespace
(global-font-lock-mode t) ; Enable syntax highlighting for older emacs
(global-auto-revert-mode 1) ; revert buffers for changed files
(electric-indent-mode -1)
;; window config undo/redo
(winner-mode 1)
(add-hook! after-init (setq winner-boring-buffers narf-ignore-buffers))
;; Plugins ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package undo-tree
:defer t
:config
;; Shut up undo-tree's constant complaining: http://youtu.be/Z6woIRLnbmE
(defadvice undo-tree-load-history-hook (around undo-tree-load-history-shut-up activate)
(shut-up! ad-do-it))
(defadvice undo-tree-save-history-hook (around undo-tree-save-history-shut-up activate)
(shut-up! ad-do-it)))
(use-package ace-jump-mode
:functions (ace-jump-char-category ace-jump-do)
:commands (ace-jump-line-mode ace-jump-char-mode
@ -122,17 +129,13 @@ you can enable multiple minor modes for the same regexp.")
(char-to-string query-char-2))))))
(use-package ace-link
:commands
(ace-link-info ace-link-help ace-link-compilation ace-link-custom ace-link-org)
:commands (ace-link-info ace-link-help ace-link-compilation ace-link-custom ace-link-org)
:init
(after "help-mode"
(bind motion :map help-mode-map "go" 'ace-link-help))
(after "compile"
(bind motion :map compilation-mode-map "go" 'ace-link-compilation))
(after "info"
(bind motion :map Info-mode-map "go" 'ace-link-info))
(after "org"
(bind motion :map org-mode-map "go" 'ace-link-org)))
(bind!
(:after help-mode :map help-mode-map :m "go" 'ace-link-help)
(:after compile :map compilation-mode-map :m "go" 'ace-link-compilation)
(:after info :map Info-mode-map :m "go" 'ace-link-info)
(:after org :map org-mode-map :m "go" 'ace-link-org)))
(use-package ace-window
:commands ace-window
@ -147,47 +150,53 @@ you can enable multiple minor modes for the same regexp.")
(use-package expand-region
:commands (er/expand-region er/contract-region er/mark-symbol er/mark-word))
(use-package goto-last-change :defer 3)
(use-package goto-last-change :commands goto-last-change)
(use-package hl-todo
:commands hl-todo-mode
:init
(@add-hook prog-mode 'hl-todo-mode)
(defvar hl-todo-keyword-faces)
'(("\\(\\bTODO\\((.*)\\)?:?\\)" . "#cc9393")
("\\(\\bNOTE\\((.*)\\)?:?\\)" . "#d0bf8f")
("\\(\\bFIXME\\((.*)\\)?:?\\)" . "#cc9393")))
(add-hook! prog-mode 'hl-todo-mode)
(defvar hl-todo-keyword-faces
'(("TODO" . "#cc9393")
("NOTE" . "#d0bf8f")
("FIXME" . "#cc9393"))))
(use-package hideshow
:diminish hs-minor-mode
:init (@add-hook (prog-mode org-mode) 'hs-minor-mode))
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
:diminish hs-minor-mode)
(use-package rainbow-delimiters
:commands rainbow-delimiters-mode
:init (@add-hook (emacs-lisp-mode js2-mode scss-mode) 'rainbow-delimiters-mode)
:init (add-hook! (emacs-lisp-mode js2-mode scss-mode) 'rainbow-delimiters-mode)
:config (setq rainbow-delimiters-outermost-only-face-count 1))
(use-package rotate-text :commands (rotate-word-at-point rotate-region))
(use-package smart-forward
:commands (smart-up smart-down smart-left smart-right))
(use-package smart-forward :commands (smart-up smart-down smart-left smart-right))
(use-package smartparens
:diminish smartparens-mode
:commands smartparens-global-mode
:init (@add-init-hook evil-insert-state-entry 'smartparens-global-mode)
:functions sp-insert-pair
:commands (smartparens-global-mode
sp-pair
sp-local-pair
sp-point-in-string-or-comment)
:init (add-hook! evil-insert-state-entry (unless smartparens-global-mode (smartparens-global-mode 1)))
:config
(progn
(setq blink-matching-paren t
sp-autowrap-region nil ; let evil-surround handle this
sp-highlight-pair-overlay nil
sp-show-pair-delay 0)
(use-package smartparens-config)
(require 'smartparens-config)
;; Handle newlines + spaces
(sp-pair "{" "}" :post-handlers '(("||\n[i]" "RET") ("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p))
(sp-pair "(" ")" :post-handlers '(("||\n[i]" "RET") ("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p))
(sp-pair "{" "}"
:post-handlers '(("||\n[i]" "RET") ("| " " "))
:unless '(sp-point-before-word-p sp-point-before-same-p))
(sp-pair "(" ")"
:post-handlers '(("||\n[i]" "RET") ("| " " "))
:unless '(sp-point-before-word-p sp-point-before-same-p))
;; Auto-close more conservatively
(sp-pair "[" nil :unless '(sp-point-before-word-p sp-point-before-same-p))
(sp-pair "'" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p))
@ -203,21 +212,21 @@ you can enable multiple minor modes for the same regexp.")
(sp-local-pair "/*\n" "\n */" :post-handlers '(("||[i]" "RET"))))
(sp-with-modes '(c-mode c++-mode php-mode java-mode)
(sp-local-pair "/*" "" :post-handlers '((" ||\n[i]*/" "RET"))))
(sp-with-modes '(markdown-mode org-mode)
(sp-local-pair "*" "*" :unless '(sp-point-after-bol-p sp-point-before-same-p sp-point-after-same-p)))
(after "yasnippet"
(advice-add 'yas-expand :before 'sp-remove-active-pair-overlay))))
(after! yasnippet
(advice-add 'yas-expand :before 'sp-remove-active-pair-overlay)))
(use-package smex
:commands (smex smex-major-mode-commands smex-initialize smex-update)
:init (setq smex-save-file (! (expand-file-name "smex-items" TMP-DIR)))
:config
(smex-initialize)
:init (setq smex-save-file (! (concat narf-temp-dir "smex-items")))
:config (smex-initialize)
;; Hook up smex to auto-update, rather than update on every run
(defun smex-update-after-load (unused)
(when (boundp 'smex-cache) (smex-update)))
(add-hook 'after-load-functions 'smex-update-after-load))
(provide 'core-editor)
;;; core-editor.el ends here

View file

@ -1,24 +1,25 @@
;;; core-evil.el --- the root of all evil
;; see lib/evil-defuns.el
(use-package evil
:init
;; highlight matching delimiters where it's important
(defun show-paren-mode-off () (show-paren-mode -1))
(@add-hook evil-insert-state-entry 'show-paren-mode)
(@add-hook evil-insert-state-exit 'show-paren-mode-off)
(@add-hook evil-visual-state-entry 'show-paren-mode)
(@add-hook evil-visual-state-exit 'show-paren-mode-off)
(@add-hook evil-motion-state-entry 'show-paren-mode)
(@add-hook evil-motion-state-exit 'show-paren-mode-off)
(@add-hook evil-operator-state-entry 'show-paren-mode)
(@add-hook evil-operator-state-exit 'show-paren-mode-off)
(add-hook! evil-insert-state-entry 'show-paren-mode)
(add-hook! evil-insert-state-exit 'show-paren-mode-off)
(add-hook! evil-visual-state-entry 'show-paren-mode)
(add-hook! evil-visual-state-exit 'show-paren-mode-off)
(add-hook! evil-motion-state-entry 'show-paren-mode)
(add-hook! evil-motion-state-exit 'show-paren-mode-off)
(add-hook! evil-operator-state-entry 'show-paren-mode)
(add-hook! evil-operator-state-exit 'show-paren-mode-off)
;; Disable highlights on insert-mode
(@add-hook evil-insert-state-entry 'evil-ex-nohighlight)
(add-hook! evil-insert-state-entry 'evil-ex-nohighlight)
(@add-hook undo-tree-mode (diminish 'undo-tree-mode))
(add-hook! undo-tree-mode (diminish 'undo-tree-mode))
;; Always ensure evil-shift-width is consistent with tab-width
(@add-hook evil-local-mode (setq evil-shift-width tab-width))
(add-hook! evil-local-mode (setq evil-shift-width tab-width))
:config
(setq evil-magic t
evil-want-C-u-scroll t ; enable C-u for scrolling
@ -37,7 +38,8 @@
(evil-mode 1)
(evil-select-search-module 'evil-search-module 'evil-search)
(add-to-list 'evil-overriding-maps 'narf-mode-map)
(bind! :map evil-command-window-mode-map :n [escape] 'kill-buffer-and-window)
(defadvice evil-ex-hl-do-update-highlight (around evil-ex-hl-shut-up activate)
"Silence 'Error running timer `evil-ex-hl-do-update-highlight': (error
@ -50,176 +52,13 @@ See `https://bitbucket.org/lyro/evil/issue/527'"
(dolist (mode-map '((cider-repl-mode . emacs)
(comint-mode . emacs)
(term-mode . emacs)
(fundamental-mode . normal)
(fundamental-mode . motion)
(help-mode . normal)
(message-mode . normal)
(compilation-mode . normal)))
(compilation-mode . normal)
(text-mode . normal)))
(evil-set-initial-state `,(car mode-map) `,(cdr mode-map)))
(progn ; evil plugins
(use-package evil-anzu)
(use-package evil-commentary
:diminish evil-commentary-mode
:commands (evil-commentary
evil-commentary-mode
evil-commentary-yank
evil-commentary-line)
:config (evil-commentary-mode 1))
(use-package evil-ex-registers
:commands (evil-get-spec-register
evil-ex-paste-from-register))
(use-package evil-exchange
:commands evil-exchange
:config
(defadvice evil-force-normal-state (before evil-esc-quit-exchange activate)
"Remove `evil-exchange' overlays on ESC"
(when evil-exchange--overlays (evil-exchange-cancel))))
(lambda ()
(interactive)
(if (iedit-current-occurrence-string)
(progn
(save-excursion (iedit-restrict-region (region-beginning) (region-end)))
(evil-previous-line)
(evil-iedit-state/iedit-mode))
(call-interactively 'evil-ret)))
(use-package evil-iedit-state
:functions (iedit-current-occurrence-string iedit-restrict-region)
:commands (evil-iedit-state evil-iedit-state/iedit-mode)
:config
(@map ; Don't interfere with evil-snipe
:I :unset "s"
:I :unset "S"
:I "V" 'evil-visual-line
:I "C" 'evil-iedit-state/substitute ; instead of s/S
:I "za" 'iedit-toggle-unmatched-lines-visible
:v "SPC" (λ (if (iedit-current-occurrence-string)
(progn
(save-excursion (iedit-restrict-region (region-beginning) (region-end)))
(evil-previous-line)
(evil-iedit-state/iedit-mode))
(call-interactively 'evil-ret)))))
(use-package evil-indent-textobject
:commands (evil-indent-i-indent
evil-indent-a-indent
evil-indent-a-indent-lines)
:init
(@map :map evil-inner-text-objects-map
"i" 'evil-indent-i-indent
"i" 'evil-indent-a-indent
"I" 'evil-indent-a-indent-lines))
(use-package evil-jumper
:init
(setq evil-jumper-file (! (expand-file-name "jumplist" narf-temp-dir))
evil-jumper-auto-center t
evil-jumper-auto-save-interval 3600))
(use-package evil-matchit
:commands (evilmi-jump-items global-evil-matchit-mode)
:config (global-evil-matchit-mode 1))
(use-package evil-numbers
:commands (evil-numbers/inc-at-pt
evil-numbers/dec-at-pt))
(use-package evil-search-highlight-persist
:config (global-evil-search-highlight-persist t))
(use-package evil-snipe
:diminish evil-snipe-mode
:commands (evil-snipe-s evil-snipe-S
evil-snipe-x evil-snipe-X
evil-snipe-f evil-snipe-F
evil-snipe-t evil-snipe-T)
:init
(setq-default
evil-snipe-smart-case t
evil-snipe-scope 'line
evil-snipe-repeat-scope 'buffer
evil-snipe-override-evil-repeat-keys nil
evil-snipe-symbol-groups '((?\[ "[[{(]")
(?\] "[]})]")))
:config
(evil-snipe-mode 1)
(evil-snipe-override-mode 1))
(use-package evil-space
:diminish (evil-space-mode . "_")
:config
(progn
(add-to-list 'evil-overriding-maps 'evil-space-mode-map)
(evil-space-setup "/" "n" "N")
(evil-space-setup "?" "N" "n")
(@after evil-numbers
(let ((map (evil-get-auxiliary-keymap narf-mode-map 'normal)))
(evil-space-setup "g=" "g=" "g-" map)
(evil-space-setup "g-" "g-" "g=" map)))
(@after evil-snipe
(let ((map (evil-get-auxiliary-keymap evil-snipe-override-mode-map 'motion)))
(evil-space-setup "t" "C-;" "C-," map)
(evil-space-setup "f" "C-;" "C-," map)
(evil-space-setup "T" "C-," "C-;" map)
(evil-space-setup "F" "C-," "C-;" map))
(let ((map (evil-get-auxiliary-keymap evil-snipe-mode-map 'motion)))
(evil-space-setup "s" "C-;" "C-," map)
(evil-space-setup "S" "C-," "C-;" map)))
(@after evil-visualstar
(let ((map (evil-get-auxiliary-keymap evil-visualstar-mode-map 'visual)))
(evil-space-setup "*" "n" "N" map)
(evil-space-setup "#" "n" "N" map)))
(evil-space-mode)))
(use-package evil-surround
:commands (global-evil-surround-mode
evil-surround-edit
evil-Surround-edit
evil-surround-region)
:config
(global-evil-surround-mode 1)
;; Escaped surround characters
(defun evil-surround-escaped ()
(let* ((char (string (read-char "\\")))
(pair (cond ((string-match "[]})[{(]" char)
(let ((-pair (cdr (assoc (string-to-char char) evil-surround-pairs-alist))))
`(,(car -pair) . ,(cdr -pair))))
(t
`(,char . ,char))))
(format (if (sp-point-in-string) "\\\\%s" "\\%s")))
(cons (format format (car pair))
(format format (cdr pair)))))
(push '(?\\ . evil-surround-escaped) evil-surround-pairs-alist))
(use-package evil-visualstar
:commands (global-evil-visualstar-mode
evil-visualstar/begin-search
evil-visualstar/begin-search-forward
evil-visualstar/begin-search-backward)
:config
;; I cut this down because the original visualstar wouldn't remember
;; the last search if evil-search-module was 'evil-search.
(defun narf/evil-visualstar/begin-search (beg end direction)
(when (evil-visual-state-p)
(evil-exit-visual-state)
(let ((selection (regexp-quote (buffer-substring-no-properties beg end))))
(setq isearch-forward direction)
(evil-search selection direction t))))
(advice-add 'evil-visualstar/begin-search :override 'narf/evil-visualstar/begin-search)
(global-evil-visualstar-mode 1)))
(progn ; evil hacks
(defadvice evil-force-normal-state (before evil-esc-quit activate)
(ignore-errors
@ -236,27 +75,154 @@ See `https://bitbucket.org/lyro/evil/issue/527'"
(defadvice evil-window-vsplit (after evil-window-vsplit-jump activate)
(evil-window-right 1))
(@after isearch ; Restore vimmish ex-mode keymaps to isearch
;; Restore vimmish ex-mode keymaps to isearch
;; 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))
(@map :map isearch-mode-map
:unset "C-r"
(add-hook! isearch-mode (setq echo-keystrokes 0))
(add-hook! isearch-mode-end (setq echo-keystrokes 0.02))
(bind! :map isearch-mode-map
"C-r" nil
"C-r %" (λ (narf:isearch-paste-from-register ?%))
"C-r #" (λ (narf:isearch-paste-from-register ?#))
"C-r /" (λ (narf:isearch-paste-from-register ?/))
"C-r :" (λ (narf:isearch-paste-from-register ?:))
"C-r ." (λ (narf:isearch-paste-from-register ?.))
"C-r -" (λ (narf:isearch-paste-from-register ?-))
"C-r _" (λ (narf:isearch-paste-from-register ?_))
"C-r =" (λ (narf:isearch-paste-from-register ?=))
"C-r +" 'narf:isearch-paste-from-clipboard
"C-r %" (λ (narf/isearch-paste-from-register ?%))
"C-r #" (λ (narf/isearch-paste-from-register ?#))
"C-r /" (λ (narf/isearch-paste-from-register ?/))
"C-r :" (λ (narf/isearch-paste-from-register ?:))
"C-r ." (λ (narf/isearch-paste-from-register ?.))
"C-r -" (λ (narf/isearch-paste-from-register ?-))
"C-r _" (λ (narf/isearch-paste-from-register ?_))
"C-r =" (λ (narf/isearch-paste-from-register ?=))
"C-r +" 'narf/isearch-paste-from-clipboard
"C-w" 'narf:isearch-delete-word
"C-u" 'narf:isearch-delete-line
"M-v" 'narf:isearch-paste-from-clipboard))))
"C-w" 'narf/isearch-delete-word
"C-u" 'narf/isearch-delete-line
"M-v" 'narf/isearch-paste-from-clipboard)))
;; evil plugins
(use-package evil-anzu)
(use-package evil-commentary
:diminish evil-commentary-mode
:commands (evil-commentary
evil-commentary-yank
evil-commentary-line)
:config (evil-commentary-mode 1))
(use-package evil-ex-registers
:commands (evil-get-spec-register
evil-ex-paste-from-register))
(use-package evil-exchange
:commands evil-exchange
:config
(advice-add 'evil-force-normal :after 'narf*evil-exchange-off))
(use-package evil-iedit-state
:functions (iedit-current-occurrence-string iedit-restrict-region)
:commands (evil-iedit-state evil-iedit-state/iedit-mode)
:config
(bind! ; Don't interfere with evil-snipe
:I :unset "s"
:I :unset "S"
:I "V" 'evil-visual-line
:I "C" 'evil-iedit-state/substitute ; instead of s/S
:I "za" 'iedit-toggle-unmatched-lines-visible
:v "SPC" 'narf:iedit-restrict-to-region))
(use-package evil-indent-textobject
:commands (evil-indent-i-indent
evil-indent-a-indent
evil-indent-a-indent-lines)
:init
(bind! :map evil-inner-text-objects-map
"i" 'evil-indent-i-indent
"i" 'evil-indent-a-indent
"I" 'evil-indent-a-indent-lines))
(use-package evil-jumper
:init
(setq evil-jumper-file (! (concat narf-temp-dir "jumplist"))
evil-jumper-auto-center t
evil-jumper-auto-save-interval 3600))
(use-package evil-matchit
:commands (evilmi-jump-items global-evil-matchit-mode)
:config (global-evil-matchit-mode 1))
(use-package evil-numbers
:commands (evil-numbers/inc-at-pt
evil-numbers/dec-at-pt))
(use-package evil-search-highlight-persist
:config (global-evil-search-highlight-persist t))
(use-package evil-snipe
:diminish evil-snipe-mode
:commands (evil-snipe-s evil-snipe-S
evil-snipe-x evil-snipe-X
evil-snipe-f evil-snipe-F
evil-snipe-t evil-snipe-T
evil-snipe-repeat evil-snipe-repeat-reverse)
:init
(bind! :m "s" 'evil-snipe-s
:m "S" 'evil-snipe-S
:m "f" 'evil-snipe-f
:m "F" 'evil-snipe-F
:m "t" 'evil-snipe-t
:m "T" 'evil-snipe-T
:o "z" 'evil-snipe-s
:o "Z" 'evil-snipe-S
:o "x" 'evil-snipe-x
:o "X" 'evil-snipe-X)
(define-key evil-normal-state-map "s" nil)
(define-key evil-normal-state-map "S" nil)
:config
(setq-default
evil-snipe-smart-case t
evil-snipe-scope 'line
evil-snipe-repeat-scope 'buffer
evil-snipe-override-evil-repeat-keys nil
evil-snipe-symbol-groups '((?\[ "[[{(]")
(?\] "[]})]")))
(evil-snipe-mode 1)
(evil-snipe-override-mode 1))
(use-package evil-space
:diminish (evil-space-mode . "_")
:init (setq evil-space-auto-setup nil)
:config
(evil-space-mode 1)
(evil-space-setup "/" "n" "N")
(evil-space-setup "?" "N" "n")
(after! evil-snipe
(evil-space-setup 'evil-snipe-f 'evil-snipe-repeat 'evil-snipe-repeat-reverse)
(evil-space-setup 'evil-snipe-F 'evil-snipe-repeat 'evil-snipe-repeat-reverse)
(evil-space-setup 'evil-snipe-t 'evil-snipe-repeat 'evil-snipe-repeat-reverse)
(evil-space-setup 'evil-snipe-T 'evil-snipe-repeat 'evil-snipe-repeat-reverse)
(evil-space-setup 'evil-snipe-s 'evil-snipe-repeat 'evil-snipe-repeat-reverse)
(evil-space-setup 'evil-snipe-S 'evil-snipe-repeat 'evil-snipe-repeat-reverse))
(after! evil-visualstar
(evil-space-setup 'evil-visualstar/begin-search-forward "n" "N")
(evil-space-setup 'evil-visualstar/begin-search-backward "n" "N")))
(use-package evil-surround
:commands (global-evil-surround-mode
evil-surround-edit
evil-Surround-edit
evil-surround-region)
:config
(global-evil-surround-mode 1)
;; Escaped surround characters
(push '(?\\ . narf/evil-surround-escaped) evil-surround-pairs-alist))
(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))
(provide 'core-evil)
;;; core-evil.el ends here

40
core/core-flycheck.el Normal file
View file

@ -0,0 +1,40 @@
;;; core-flycheck.el --- check yourself before you shrek yourself
;; Related to: lib/defuns-flycheck.el
(use-package flycheck
:functions (flycheck-buffer)
:commands (flycheck-mode flycheck-list-errors)
:init
(setq flycheck-indication-mode 'right-fringe
;; Removed checks on idle/change for snappiness
flycheck-check-syntax-automatically '(save mode-enabled idle-change)
flycheck-disabled-checkers '(emacs-lisp-checkdoc make))
(add-hook! (ruby-mode
python-mode
php-mode
lua-mode
shell-mode
scss-mode
c++-mode
c-mode) 'flycheck-mode)
:config
;; TODO: Implement this
(add-unreal-buffer! "^\\*Flycheck.*\\*$")
(bind! :map flycheck-error-list-mode-map
:n [escape] 'kill-this-buffer
:n "q" 'kill-this-buffer)
(evil-initial-state 'flycheck-error-list-mode 'emacs)
;; Check buffer when normal mode is entered
(add-hook! evil-normal-state-entry 'narf*flycheck-buffer)
;; And on ESC in normal mode.
(advice-add 'evil-force-normal-state :after 'narf*flycheck-buffer)
(advice-add 'flycheck-mode-line-status-text :filter-return 'narf*fly-shorter-status))
(use-package flyspell :commands flyspell-mode)
(provide 'core-flycheck)
;;; core-flycheck.el ends here

128
core/core-helm.el Normal file
View file

@ -0,0 +1,128 @@
;;; core-helm.el
(use-package helm
:commands (helm
helm-etags-select
helm-show-kill-ring
helm-bookmarks
helm-wg
helm-ag
helm-alive-p
helm-attrset)
:init
(defvar helm-global-prompt ">>> ")
(setq helm-quick-update t
helm-idle-delay 0.05
helm-input-idle-delay 0.05
helm-reuse-last-window-split-state t
helm-buffers-fuzzy-matching t
helm-candidate-number-limit 40
helm-bookmark-show-location t
;; let popwin handle this
helm-split-window-default-side 'other
helm-split-window-preferred-function 'narf/helm-split-window)
:config
(require 'helm-ag)
(require 'helm-grep)
(evil-set-initial-state 'helm-mode 'emacs)
(add-popwin-rule! "\\`\\*helm.*?\\*\\'" :regexp t :position bottom :height 15)
(add-unreal-buffer! "^\\*[Hh]elm.*\\*$")
(after! winner
;; Tell winner-mode to ignore helm buffers
(dolist (bufname '("*helm recentf*"
"*helm projectile*"
"*helm imenu*"
"*helm company*"
"*helm buffers*"
;; "*helm tags*"
"*helm-ag*"
"*Helm Swoop*"))
(push bufname winner-boring-buffers)))
(bind! :map helm-map
"C-w" 'evil-delete-backward-word
"C-u" 'helm-delete-minibuffer-contents
"C-r" 'evil-ex-paste-from-register ; Evil registers in helm! Glorious!
[escape] 'helm-keyboard-quit)
(advice-add 'helm-display-mode-line :override 'narf*helm-hide-modeline))
(use-package helm-org
:commands (helm-org-in-buffer-headings
helm-org-agenda-files-headings
helm-org-capture-templates))
(use-package helm-files
:commands helm-recentf
:config
(defun helm-recentf ()
"Reconfigured `helm-recentf' to use `helm', instead of `helm-other-buffer'"
(interactive)
(let ((helm-ff-transformer-show-only-basename nil))
(helm :sources '(helm-source-recentf)
:buffer "*helm recentf*"
:prompt helm-global-prompt))))
(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))
(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-split-with-multiple-windows t
helm-swoop-speed-or-color t))
(use-package projectile
:diminish projectile-mode
:commands (projectile-ack projectile-ag projectile-compile-project projectile-dired
projectile-grep projectile-find-dir projectile-find-file projectile-find-tag
projectile-find-test-file projectile-invalidate-cache projectile-kill-buffers
projectile-multi-occur projectile-project-root projectile-recentf
projectile-regenerate-tags projectile-replace
projectile-run-async-shell-command-in-root projectile-run-shell-command-in-root
projectile-switch-project projectile-switch-to-buffer projectile-vc
projectile-project-p projectile-global-mode)
:config
(add-hook! kill-emacs 'narf|projectile-invalidate-cache-maybe)
(setq-default projectile-enable-caching t)
(setq projectile-sort-order 'recentf
projectile-cache-file (! (concat narf-temp-dir "projectile.cache"))
projectile-known-projects-file (! (concat narf-temp-dir "projectile.projects"))
projectile-indexing-method 'alien
projectile-project-root-files narf-project-root-files)
(add-to-list 'projectile-globally-ignored-files "ido.last")
(add-to-list 'projectile-globally-ignored-directories "assets")
(add-to-list 'projectile-other-file-alist '("scss" "css"))
(add-to-list 'projectile-other-file-alist '("css" "scss"))
(projectile-global-mode +1)
(advice-add 'projectile-prepend-project-name :override 'narf*projectile-replace-prompt))
(use-package helm-projectile
:commands (helm-projectile-switch-to-buffer
helm-projectile-find-file
helm-projectile-recentf
helm-projectile-find-other-file
helm-projectile-switch-project)
:config
(require 'helm)
(require 'projectile))
;; (use-package helm-c-yasnippet :commands helm-yas-visit-snippet-file)
(use-package helm-buffers :commands helm-buffers-list)
(use-package helm-semantic :commands helm-semantic-or-imenu)
(use-package helm-elisp :commands helm-apropos)
(use-package helm-command :commands helm-M-x)
(use-package helm-company :defer t)
(provide 'core-helm)
;;; core-helm.el ends here

View file

@ -4,6 +4,5 @@
(interactive)
(error "Not yet implemented"))
(provide 'core-os-linux)
;;; core-os-linux.el ends here

View file

@ -31,7 +31,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(@after evil
(after! evil
(when (featurep 'ns)
;; 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
@ -40,14 +40,13 @@
(defadvice evil-visual-update-x-selection (around clobber-x-select-text activate)
(unless (featurep 'ns) ad-do-it))))
;; Send current file to OSX apps
(defun narf-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 (concat "open " (when app-name (concat "-a " (shell-quote-argument app-name))) " '" path "'")))
(message "Running: %s" command)
(shell-command command)))
(provide 'core-os-osx)
;;; core-os-osx.el ends here

View file

@ -4,6 +4,5 @@
(interactive)
(error "Not yet implemented"))
(provide 'core-os-win32)
;;; core-os-win32.el ends here

96
core/core-project.el Normal file
View file

@ -0,0 +1,96 @@
;;; core-project.el --- all your (basic) project navigational needs
(use-package ido
:defines (flx-ido-mode ido-ubiquitous-debug-mode ido-context-switch-command ido-temp-list)
:functions (ido-to-end)
:commands (ido-mode ido-everywhere ido-vertical-mode
flx-ido-mode ido-ubiquitous-mode ido-find-file
ido-find-file-in-dir)
:init
(setq ido-ignore-buffers
'("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer"
"^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-"
"_region_" " output\\*$" "^TAGS$" "^\*Ido")
ido-use-faces nil
ido-confirm-unique-completion t
ido-case-fold t
ido-enable-tramp-completion nil
ido-enable-flex-matching t
ido-create-new-buffer 'always
ido-enable-tramp-completion t
ido-enable-last-directory-history t
ido-save-directory-list-file (! (concat narf-temp-dir "ido.last")))
:config
(add-to-list 'ido-ignore-files "\\`.DS_Store$")
(add-to-list 'ido-ignore-files "Icon\\?$")
(add-hook! ido-setup
(bind! :map (ido-completion-map ido-file-completion-map)
"C-w" 'ido-delete-backward-word-updir))
(ido-mode 1)
(ido-everywhere 1)
(require 'ido-vertical-mode)
(ido-vertical-mode 1)
(require 'flx-ido)
(flx-ido-mode 1)
(require 'ido-ubiquitous)
(ido-ubiquitous-mode 1)
(advice-add 'ido-sort-mtime :override 'narf*ido-sort-mtime)
(add-hook! (ido-make-file-list ido-make-dir-list) 'narf*ido-sort-mtime)
(add-hook! ido-setup 'narf|ido-setup-home-keybind))
(use-package neotree
:commands (neotree-show
neotree-hide
neotree-toggle
neotree-dir
neotree-find
neo-global--window-exists-p)
:functions (neo-buffer--unlock-width neo-buffer--lock-width)
:init
(setq neo-create-file-auto-open t
neo-mode-line-type 'none
neo-persist-show t
neo-window-width 22
neo-show-updir-line nil
neo-auto-indent-point t
neo-banner-message nil
;; requires <https://github.com/jeffplang/emacs-neotree> fork of
;; neotree (at least, until the PR is accepted). Causes neotree to
;; open in a vertical split that consumes the entire height of the
;; frame.
neo-modern-sidebar t)
:config
(defun narf|neotree-init-keymap ()
(bind! :map evil-motion-state-local-map
"ESC" 'neotree-hide
"\\\\" 'neotree-hide
"RET" 'neotree-enter
"J" 'neotree-select-next-sibling-node
"K" 'neotree-select-previous-sibling-node
"H" 'neotree-select-up-node
"L" 'neotree-select-down-node
"v" 'neotree-enter-vertical-split
"s" 'neotree-enter-horizontal-split
"c" 'neotree-create-node
"d" 'neotree-delete-node
"g" 'neotree-refresh
"q" 'neotree-hide
"r" 'neotree-rename-node
"R" 'neotree-change-root))
(add-hook! neotree-mode 'narf|neotree-init-keymap)
(add-hook! window-configuration-change 'narf|neotree-close-on-window-change)
(evil-set-initial-state 'neotree-mode 'motion)
(after! projectile
(setq projectile-switch-project-action 'neotree-projectile-action))
(advice-add 'neo-buffer--insert-fold-symbol :override 'narf*neo-buffer-fold-symbol))
(provide 'core-project)
;;; core-project.el ends here

13
core/core-quickrun.el Normal file
View file

@ -0,0 +1,13 @@
;;; core-quickrun.el
(use-package quickrun
:commands (quickrun
quickrun-region
quickrun-with-arg
quickrun-shell
quickrun-compile-only
quickrun-replace-region
helm-quickrun))
(provide 'core-quickrun)
;;; core-quickrun.el ends here

View file

@ -1,10 +1,23 @@
;;; core-ui.el --- interface settings
;; see lib/ui-defuns.el
(when (fboundp 'fringe-mode) (fringe-mode '(2 . 8)))
(when window-system ; more informative window title
;; This is kept separate so it can jumpstart emacs; this prevents the unstyled
;; flash of emacs pre-makeover.
(load-theme narf-default-theme t)
(when window-system
(set-frame-font (apply #'font-spec narf-default-font))
(scroll-bar-mode -1) ; no scrollbar
(tool-bar-mode -1) ; no toolbar
(menu-bar-mode -1) ; no menubar
(pcase (system-name)
("io" (set-frame-size (selected-frame) 326 119))
("ganymede.home" (set-frame-size (selected-frame) 318 83)))
(fringe-mode '(2 . 8))
;; more informative window title
(setq frame-title-format '(buffer-file-name "%f" ("%b"))))
;; theme and GUI elements are loaded in init.el early
(setq show-paren-delay 0)
@ -27,17 +40,14 @@
indicate-empty-lines nil
fringes-outside-margins t) ; fringes on the other side of line numbers
(@add-hook after-init
(add-hook! after-init
(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
"Prevent annoying \"Active processes exist\" query when you quit Emacs."
(flet ((process-list ())) ad-do-it)))
;;;; Line numbers ;;;;;;;;;;;;;;;;;;;;;;
(use-package nlinum
(use-package nlinum ; line numbers
:defer t
:defines nlinum--width
:commands nlinum-mode
:preface
(defface linum '((t (:inherit default)))
"Face for line numbers" :group 'nlinum-mode)
@ -89,17 +99,14 @@
(remove-hook 'post-command-hook 'narf|nlinum-hl-line)
(narf|nlinum-unhl-line))
(@add-hook text-mode 'narf|nlinum-enable)
(@add-hook prog-mode 'narf|nlinum-enable)
(@add-hook org-mode 'narf|nlinum-disable)
(add-hook! text-mode 'narf|nlinum-enable)
(add-hook! prog-mode 'narf|nlinum-enable)
(add-hook! org-mode 'narf|nlinum-disable)
;; Preset width nlinum
(@add-hook nlinum-mode
(add-hook! nlinum-mode
(setq nlinum--width (length (number-to-string (count-lines (point-min) (point-max)))))))
;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package smart-mode-line
(use-package smart-mode-line ; customized modeline
:init (setq-default
sml/no-confirm-load-theme t
sml/mode-width 'full
@ -116,13 +123,10 @@
sml/replacer-regexp-list '(("^~/Dropbox/Projects/" "PROJECTS:")
("^~/.emacs.d/" "EMACS.D:")
("^~/Dropbox/notes/" "NOTES:")
("^/usr/local/Cellar/" "HOMEBREW:"))
mode-line-misc-info
'((which-func-mode ("" which-func-format ""))
(global-mode-string ("" global-mode-string ""))))
("^/usr/local/Cellar/" "HOMEBREW:")))
:config
;; Hide evil state indicator
(@after evil (setq evil-mode-line-format nil))
(after! evil (setq evil-mode-line-format nil))
(sml/setup)
(sml/apply-theme 'respectful)
@ -175,14 +179,14 @@
(-3 (:propertize (:eval sml/position-percentage-format)
face sml/position-percentage help-echo "Buffer Relative Position\nmouse-1: Display Line and Column Mode Menu")))))
(@after anzu ; Add small gap for anzu
(after! anzu ; Add small gap for anzu
(defun narf--anzu-update-mode-line (here total)
(concat (anzu--update-mode-line-default here total) " "))
(setq anzu-mode-line-update-function 'narf--anzu-update-mode-line))
;; Rearrange and cleanup
(setq-default mode-line-format
'("%e "
'("%e"
mode-line-mule-info
mode-line-client
;; mode-line-remote
@ -196,6 +200,5 @@
" "
":" mode-line-position)))
(provide 'core-ui)
;;; core-ui.el ends here

View file

@ -16,19 +16,45 @@
(defconst narf--splash-buffer-name "*narf*")
(defvar narf-ignore-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*"
"*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*"
"*Buffer List*" "*Ibuffer*" "*esh command on file*")
"List of buffer names to ignore when using `switch-to-next-buffer',
`switch-to-previous-buffer', `winner-undo', `winner-redo', or
`narf:cleanup-buffers'")
(defvar narf-auto-minor-mode-alist '()
"Alist of filename patterns vs corresponding minor mode functions, see
`auto-mode-alist'. All elements of this alist are checked, meaning you can
enable multiple minor modes for the same regexp.")
(defvar narf-unreal-buffers '("^ \\*"
"^\\*scratch\\*"
"^\\*Backtrace\\*$"
"^\\*Warnings\\*$"
"^\\*Compile-Log\\*$"
"^\\*Ediff.*\\*$"
"^\\*helm.*\\*$"
"^\\*eval\\*$"
"^\\*Shell Command Output\\*$"
"^\\*Async Shell Command\\*$"
help-mode
image-mode
dired-mode
reb-mode
messages-buffer-mode)
"A list of regexps or modes whose buffers are considered unreal, and will be
ignored when using `narf:next-real-buffer' and `narf:previous-real-buffer', and
killed by `narf:kill-unreal-buffers'.
`narf:kill-this-buffer' will also gloss over these buffers when finding a new
buffer to display.")
(defvar narf-ignore-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*"
"*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*"
"*Buffer List*" "*Ibuffer*" "*esh command on file*")
"List of buffer names to ignore when using `switch-to-next-buffer',
`switch-to-previous-buffer', `winner-undo', `winner-redo', or
`narf:cleanup-buffers'")
"*Buffer List*" "*Ibuffer*" "*esh command on file*"
"*helm*")
"List of buffer names to ignore when using `winner-undo', or `winner-redo'")
(defvar narf-cleanup-processes-alist '(("pry" . ruby-mode)
("irb" . ruby-mode)
("ipython" . python-mode))
"An alist of (process-name . major-mode), that `narf:cleanup-processes' checks
before killing processes. If there are no buffers with matching major-modes, it
gets killed.")
(defvar narf-project-root-files
'(".git" ".hg" ".svn" ".project" "local.properties" "project.properties"

BIN
core/core-vars.elc Normal file

Binary file not shown.

32
core/core-vcs.el Normal file
View file

@ -0,0 +1,32 @@
;;; core-vcs.el --- version control awareness
(use-package git-commit-mode ;
:mode (("/COMMIT_EDITMSG\\'" . git-commit-mode)
("/NOTES_EDITMSG\\'" . git-commit-mode)
("/MERGE_MSG\\'" . git-commit-mode)
("/TAG_EDITMSG\\'" . git-commit-mode)
("/PULLREQ_EDITMSG\\'" . git-commit-mode))
:config
(evil-set-initial-state 'git-commit-mode 'insert))
(use-package git-rebase-mode
:mode ("/git-rebase-todo\\'" . git-rebase-mode)
:config
(evil-set-initial-state 'git-rebase-mode 'insert))
(use-package gitconfig-mode
:mode (("/\\.?git/?config\\'" . gitconfig-mode)
("/\\.gitmodules\\'" . gitconfig-mode))
:init (add-hook 'gitconfig-mode-hook 'flyspell-mode))
(use-package gitignore-mode
:mode (("/\\.gitignore\\'" . gitignore-mode)
("/\\.git/info/exclude\\'" . gitignore-mode)
("/git/ignore\\'" . gitignore-mode)))
(use-package diff-hl
:init (setq diff-hl-draw-borders nil)
:config (global-diff-hl-mode +1))
(provide 'core-vcs)
;;; core-vcs.el ends here

32
core/core-workgroups.el Normal file
View file

@ -0,0 +1,32 @@
;;; core-workgroups.el
;; see lib/workgroup-defuns.el
(use-package workgroups2
:init
(setq wg-session-file (! (expand-file-name "wg-default" narf-temp-dir))
wg-workgroup-directory (! (expand-file-name "workgroups" narf-temp-dir))
wg-first-wg-name "main"
wg-session-load-on-start t
wg-mode-line-display-on nil
wg-mess-with-buffer-list t
;; What to do on Emacs exit / workgroups-mode exit?
wg-emacs-exit-save-behavior 'save ; Options: 'save 'ask nil
wg-workgroups-mode-exit-save-behavior 'save)
:config
(defvar narf/helm-source-wg
'((name . "Workgroups")
(candidates . wg-workgroup-names)
(action . narf/wg-helm-switch-to-workgroup)))
(after! projectile
;; Turns projectile switch-project interface (or helm's interface to it)
;; create a new workgroup for the new project.
(setq projectile-switch-project-action 'narf/wg-projectile-switch-project))
;; Initialize!
(add-hook! after-init
(workgroups-mode 1)
(diminish 'workgroups-mode)))
(provide 'core-workgroups)
;;; core-workgroups.el ends here

74
core/core-yasnippet.el Normal file
View file

@ -0,0 +1,74 @@
;;; core-yasnippet.el --- For the lazy typist
;; see lib/yasnippet-defuns.el
;; see lib/yasnippet-macros.el
(use-package yasnippet
:mode (("emacs\\.d/snippets/.+$" . snippet-mode))
:diminish (yas-minor-mode . "Y")
:commands (yas-minor-mode
yas-minor-mode-on
yas-expand
yas-insert-snippet
yas-new-snippet
yas-visit-snippet-file)
:init
(add-hook! (prog-mode snippet-mode markdown-mode org-mode) 'yas-minor-mode-on)
(add-hook! snippet-mode 'narf|disable-final-newline)
(setq yas-verbosity 0
yas-indent-line 'auto
yas-also-auto-indent-first-line t
yas-wrap-around-region nil
;; Only load personal snippets
yas-snippet-dirs `(,@narf-snippet-dirs)
yas-prompt-functions '(yas-ido-prompt yas-no-prompt))
(bind! :i [(tab)] 'yas-expand
:v "<backtab>" 'narf/yas-insert-snippet)
(defvar yas-minor-mode-map
(let ((map (make-sparse-keymap)))
(evil-define-key 'insert map [(tab)] 'yas-expand)
(evil-define-key 'visual map (kbd "<backtab>") 'narf/yas-insert-snippet)
map))
:config
(after! helm (add-to-list 'yas-dont-activate 'helm-alive-p))
(yas-reload-all)
;; Simpler `yas-selected-text' alias for templates
(defvaralias '% 'yas-selected-text)
;; Undo global maps
(bind! :i [(tab)] nil
:v "<backtab>" nil)
;; keybinds
(bind! :map yas-keymap
"C-e" 'narf/yas-goto-end-of-field
"C-a" 'narf/yas-goto-start-of-field
"<M-right>" 'narf/yas-goto-end-of-field
"<M-left>" 'narf/yas-goto-start-of-field
"<S-tab>" 'yas-prev-field
"<M-backspace>" 'narf/yas-clear-to-sof
[backspace] 'narf/yas-backspace
"<delete>" 'narf/yas-delete)
;; Once you're in normal mode, you're out
(add-hook! evil-normal-state-entry 'yas-abort-snippet)
;; Strip out the shitespace before a line selection
(add-hook! yas-before-expand-snippet 'narf|yas-before-expand)
;; Previous hook causes yas-selected-text to persist between expansions.
;; This little hack gets around it.
(add-hook! yas-after-exit-snippet 'narf|yas-after-expand)
;; Exit snippets on ESC in normal mode
(advice-add 'evil-force-normal-state :before 'yas-exit-all-snippets)
;; Prevents evil's visual-line from mode gobbling up the newline on the
;; right due to an off-by-one issue.
(defadvice yas-expand-snippet (around yas-expand-snippet-visual-line activate)
(when (narf/evil-visual-line-state-p)
(ad-set-arg 2 (1- (ad-get-arg 2)))) ad-do-it))
(provide 'core-yasnippet)
;;; core-yasnippet.el ends here

View file

@ -65,7 +65,7 @@
(use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) state)
(apply #'nconc
(mapcar (lambda (feature)
`(,(macroexpand `(after! ,feature (require ',name-symbol)))))
`((after! ,feature (require ',name-symbol))))
(delete-dups arg))))))))
;; Make any folders needed

View file

@ -1,32 +0,0 @@
;;; defuns-compile.el
(! (require 'f)
(setq narf-important-dirs (append (list narf-core-dir narf-modules-dir narf-contrib-dir narf-private-dir)
(f-directories narf-core-dir nil t)
(f-directories narf-modules-dir nil t)
(f-directories narf-contrib-dir nil t))))
;;;###autoload (autoload 'narf:byte-compile "defuns-compile")
(evil-define-command narf:byte-compile (&optional bang)
:repeat nil
(interactive "<!>")
(when emacs-lisp-mode
(if (not bang)
(progn
(byte-recompile-file (! (f-expand "core-defuns.el" narf-core-dir)) t 0)
(byte-recompile-file (buffer-file-name) t 0))
(byte-recompile-file (! (f-expand "init.el" narf-emacs-dir)) nil 0)
(byte-recompile-file (! (f-expand "startup.el" narf-emacs-dir)) nil 0)
(dolist (dir (! narf-impotant-dirs))
(byte-recompile-directory dir 0 nil)))))
;;;###autoload (autoload 'narf:autoload-compile "defuns-compile")
(evil-define-command narf:autoload-compile (&optional bang)
:repeat nil
(interactive "<!>")
(defvar generated-autoload-file (! (f-expand "autoloads.el" narf-core-dir)))
(apply #'update-directory-autoloads (! narf-impotant-dirs)))
(provide 'defuns-compile)
;;; defuns-compile.el ends here

View file

@ -1,33 +0,0 @@
;;; defuns-evil.el
;;;###autoload (autoload 'narf:evil-open-folds "defuns-evil")
(evil-define-command narf/evil-open-folds (count)
"Instead of `evil-open-folds'. Accepts COUNT for dictating fold level."
(interactive "P")
(if count (hs-hide-level count) (evil-open-folds)))
;;;###autoload (autoload 'narf:evil-open-folds "defuns-evil")
(evil-define-command narf/evil-close-folds (count)
"Instead of `evil-close-folds'. Accepts COUNT for dictating fold level."
(interactive "P")
(if count (hs-hide-level count) (evil-close-folds)))
;;;; Ace Jump ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; https://github.com/winterTTr/ace-jump-mode/issues/23
;;;###autoload (autoload 'narf:evil-ace-jump-two-chars "defuns-evil")
(evil-define-motion narf/evil-ace-jump-two-chars (count)
:type exclusive
:repeat abort
(evil-without-repeat
(evil-enclose-ace-jump-for-motion
(call-interactively 'ace-jump-two-chars-mode))))
;;;###autoload
(defun narf/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)))
(provide 'defuns-evil)
;;; defuns-evil.el ends here

203
core/lib/defuns-buffers.el Normal file
View file

@ -0,0 +1,203 @@
;;; defuns-buffers.el
;;;###autoload
(defun narf:narrow (start end)
"Restrict editing in this buffer to the current region, indirectly.
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
(interactive "r")
(deactivate-mark)
(let ((buf (clone-indirect-buffer nil nil)))
(with-current-buffer buf
(narrow-to-region start end))
(switch-to-buffer buf)))
;;;###autoload
(defun narf:widen ()
(interactive)
(when (buffer-narrowed-p)
(widen)))
;;;###autoload
(defun narf/set-read-only-region (begin end)
"See 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 narf/set-region-writeable (begin end)
"See 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)))
;; Killing Life and Death ;;;;;;;;;;;;;;
;;;###autoload
(defun narf:kill-real-buffer ()
"Kill buffer (but only bury scratch buffer), then switch to a living buffer."
(interactive)
(let ((bname (buffer-name)))
(cond ((string-match-p "^\\*scratch\\*" bname)
(erase-buffer)
(bury-buffer))
((string-equal "*" (substring bname 0 1)))
(t (kill-this-buffer))))
(unless (narf/real-buffer-p (current-buffer))
(narf/previous-real-buffer)))
;;;###autoload
(defun narf/get-visible-buffers (&optional buffer-list)
"Get a list of buffers that are not buried (i.e. visible)"
(-remove #'get-buffer-window (or buffer-list (buffer-list))))
;;;###autoload
(defun narf/get-buried-buffers (&optional buffer-list)
"Get a list of buffers that are buried (i.e. not visible)"
(-filter #'get-buffer-window (or buffer-list (buffer-list))))
;;;###autoload
(defun narf/get-matching-buffers (pattern &optional buffer-list)
"Get a list of buffers that match the pattern"
(--filter (string-match-p pattern (buffer-name it)) (or buffer-list (buffer-list))))
;;;###autoload
(defun narf/get-real-buffers(&optional buffer-list)
(-filter (lambda (buffer)
(not (--any? (if (stringp it)
(string-match-p it (buffer-name buffer))
(eq (buffer-local-value 'major-mode buffer) it))
narf-unreal-buffers)))
(or buffer-list (buffer-list))))
;;;###autoload
(defun narf:kill-unreal-buffers ()
"Kill all buried, unreal buffers in current frame. See `narf-unreal-buffers'"
(interactive)
(let* ((real-buffers (narf/get-real-buffers))
(kill-list (--filter (not (memq it real-buffers)) narf/get-buried-buffers)))
(message "Cleaned up %s buffers" (length kill-list))
(mapc 'kill-buffer kill-list)
(narf:kill-process-buffers)))
;;;###autoload
(defun narf:kill-process-buffers ()
"Kill all buffers that represent running processes and aren't visible."
(interactive)
(let ((buffer-list (buffer-list)))
(dolist (p (process-list))
(let* ((process-name (process-name p))
(assoc (assoc process-name narf-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)))
(message "Cleanup: killing %s" process-name)
(delete-process p))))))
;;;###autoload
(defun narf:kill-matching-buffers (regexp &optional buffer-list)
(interactive)
(mapc (lambda (b)
(if (string-match-p regexp (buffer-name b))
(kill-buffer b)))
(if buffer-list buffer-list (buffer-list))))
;;;###autoload
(defun narf/cycle-real-buffers (&optional n)
"Switch to the previous buffer and avoid 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))
(real-buffers (narf/get-real-buffers)))
(funcall move-func)
(while (let ((current-buffer (current-buffer)))
(and (if (eq current-buffer start-buffer)
(ignore (switch-to-buffer "*scratch*"))
t)
(not (= n 0))
(not (eq current-buffer start-buffer))
(not (memq current-buffer real-buffers))))
(setq n (1- n))
(funcall move-func))))
;;;###autoload
(defun narf/real-buffer-p (&optional buffer-or-name)
(let ((buffer (if buffer-or-name (get-buffer buffer-or-name) (current-buffer))))
(when (buffer-live-p buffer)
(not (--any? (if (stringp it)
(string-match-p it (buffer-name buffer))
(eq (buffer-local-value 'major-mode buffer) it))
narf-unreal-buffers)))))
;; From spacemacs <https://github.com/syl20bnr/spacemacs/blob/master/spacemacs/funcs.el>
;;;###autoload
(defun narf/next-real-buffer ()
"Switch to the next buffer and avoid special buffers."
(interactive)
(narf/cycle-real-buffers +1))
;;;###autoload
(defun narf/previous-real-buffer ()
"Switch to the previous buffer and avoid special buffers."
(interactive)
(narf/cycle-real-buffers -1))
;;;###autoload (autoload 'narf:kill-buried-buffers "defuns-buffers" nil t)
(evil-define-command narf:kill-buried-buffers (&optional bang)
:repeat nil
(interactive "<!>")
(narf:kill-buried-buffers)
(mapc 'kill-buffer
(narf/get-buried-buffers (if bang (projectile-project-buffers) (buffer-list)))))
;;;###autoload (autoload 'narf:kill-all-buffers "defuns-buffers" nil t)
(evil-define-command narf:kill-all-buffers (&optional bang)
"Kill all project buffers. If BANG, kill *all* buffers."
:repeat nil
(interactive "<!>")
(if (and (not bang) (projectile-project-p))
(projectile-kill-buffers)
(mapc 'kill-buffer (buffer-list)))
(delete-other-windows)
(unless (narf/real-buffer-p)
(narf/previous-real-buffer)))
;;;###autoload (autoload 'narf:scratch-buffer "defuns-buffers" nil t)
(evil-define-operator narf:scratch-buffer (&optional beg end bang)
"Send a selection to the scratch buffer. If BANG, then send it to org-capture
instead."
:move-point nil
:type inclusive
(interactive "<r><!>")
(let ((mode major-mode)
(text (when (and (evil-visual-state-p) beg end)
(buffer-substring beg end))))
(if bang
;; use org-capture with bang
(if text
(org-capture-string text)
(org-capture))
;; or scratch buffer by default
(let* ((project-dir (narf/project-root t))
(buffer-name "*scratch*"))
(popwin:popup-buffer (get-buffer-create buffer-name))
(when (eq (get-buffer buffer-name) (current-buffer))
(when project-dir
(cd project-dir))
(if text (insert text))
(funcall mode))))))
;;;###autoload (autoload 'narf:cd "defuns-buffers" nil t)
(evil-define-command narf:cd (dir)
:repeat nil
(interactive "<f>")
(cd (if (zerop (length dir)) "~" dir)))
(provide 'defuns-buffers)
;;; defuns-buffers.el ends here

View file

@ -0,0 +1,18 @@
;;; defuns-company.el
;;;###autoload
(defun narf/company-evil-complete-next ()
(call-interactively 'company-dabbrev)
(if (eq company-candidates-length 1)
(company-complete)))
;;;###autoload
(defun narf/company-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))))
(provide 'defuns-company)
;;; defuns-company.el ends here

View file

@ -0,0 +1,34 @@
;;; defuns-compile.el
(! (require 'f))
(defun narf--compile-important-dirs ()
(append (list narf-core-dir narf-contrib-dir)
(list (concat narf-modules-dir "lib/")
(concat narf-core-dir "lib/"))
(f-directories narf-contrib-dir)
(list narf-modules-dir narf-private-dir)))
;;;###autoload (autoload 'narf:compile-el "defuns-compile" nil t)
(evil-define-command narf:compile-el (&optional bang)
:repeat nil
(interactive "<!>")
(when (eq major-mode 'emacs-lisp-mode)
(byte-recompile-file (! (f-expand "core-vars.el" narf-core-dir)) t 0)
(byte-recompile-file (! (f-expand "core-defuns.el" narf-core-dir)) t 0)
(if (not bang)
(byte-recompile-file (buffer-file-name) t 0)
(byte-recompile-file (! (f-expand "init-load-path.el" narf-emacs-dir)) nil 0)
(byte-recompile-file (! (f-expand "init.el" narf-emacs-dir)) nil 0)
(dolist (dir (narf--compile-important-dirs))
(byte-recompile-directory dir 0 nil)))))
;;;###autoload (autoload 'narf:compile-autoloads "defuns-compile" nil t)
(evil-define-command narf:compile-autoloads (&optional bang)
:repeat nil
(interactive "<!>")
(defvar generated-autoload-file (! (f-expand "autoloads.el" narf-core-dir)))
(apply #'update-directory-autoloads (narf--compile-important-dirs)))
(provide 'defuns-compile)
;;; defuns-compile.el ends here

31
core/lib/defuns-debug.el Normal file
View file

@ -0,0 +1,31 @@
;;; defuns-debug.el
;;;###autoload
(defun what-face (pos)
"Tells you the name of the face (point) is on."
(interactive "d")
(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))))
;;;###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 (autoload 'narf:echo "defuns-debug" nil t)
(evil-define-command narf:echo (bang message)
"Display MSG in echo-area without logging it in *Messages* buffer."
(interactive "<!><a>")
(let (message-log-max)
(message "%s%s" (if bang ">> " "") message)))
(provide 'defuns-debug)
;;; defuns-debug.el ends here

57
core/lib/defuns-editor.el Normal file
View file

@ -0,0 +1,57 @@
;;; defuns-editor.el
;; for ../core-editor.el
;; A hacky attempt to replace ace-jump line mode that incrementally shows where
;; you will land as you type the line number.
(defun narf--goto-line (line)
(let ((lines (count-lines (point-min) (point-max))))
(if (and (<= line (1+ lines))
(> line 0))
(narf/nlinum-hl-line line)
(narf/nlinum-hl-line))))
;;;###autoload
(defun narf/editor-goto-line ()
(interactive)
(let ((keys '())
(orig-point (point))
(echo-keystrokes 0))
(evil-save-echo-area
(catch 'abort
(while t
(let* ((keystr (concat keys))
(key (read-event (concat ":" keystr))))
(cond ((eq key 'escape)
(message "%s" key)
(throw 'abort t))
((eq key 'return)
(when keys
(goto-line (string-to-number keystr)))
(throw 'abort t))
((eq key 'backspace)
(let ((key-len (length keys)))
(if (= key-len 0)
(throw 'abort t)
(if (> key-len 1)
(progn
(nbutlast keys)
(narf--goto-line (string-to-number (concat keys))))
(setq keys '())
(narf/nlinum-hl-line)))))
((and (characterp key)
(s-numeric? (char-to-string key)))
(setq keys (append keys (list key)))
(narf--goto-line (string-to-number (concat keys))))
(t
(if (or (char-equal key ?\C-n)
(char-equal key ?\C-j))
(progn
(setq keys (number-to-string (1+ (string-to-number (concat keys)))))
(narf--goto-line (string-to-number (concat keys))))
(when (or (char-equal key ?\C-p)
(char-equal key ?\C-k))
(setq keys (number-to-string (1- (string-to-number (concat keys)))))
(narf--goto-line (string-to-number (concat keys)))))))))))))
(provide 'defuns-editor)
;;; defuns-editor.el ends here

66
core/lib/defuns-evil.el Normal file
View file

@ -0,0 +1,66 @@
;;; defuns-evil.el
;; for ../core-evil.el
;;;###autoload (autoload 'narf:evil-open-folds "defuns-evil" nil t)
(evil-define-command narf/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 'narf:evil-open-folds "defuns-evil" nil t)
(evil-define-command narf/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)))
;;;; Ace Jump ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; https://github.com/winterTTr/ace-jump-mode/issues/23
;;;###autoload (autoload 'narf:evil-ace-jump-two-chars "defuns-evil" nil t)
(evil-define-motion narf/evil-ace-jump-two-chars (count)
:type exclusive
:repeat abort
(evil-without-repeat
(evil-enclose-ace-jump-for-motion
(call-interactively 'ace-jump-two-chars-mode))))
;;;###autoload
(defun narf/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 narf:iedit-restrict-to-region ()
(interactive)
(if (iedit-current-occurrence-string)
(let ((current-prefix-arg '(4)))
(iedit-done)
(call-interactively 'iedit-mode)
(save-excursion (iedit-restrict-region (region-beginning) (region-end)))
(evil-previous-line))
(call-interactively 'evil-ret)))
;;;###autoload
(defun narf*evil-exchange-off ()
(when evil-exchange--overlays
(evil-exchange-cancel)))
;;;###autoload
(defun narf/evil-surround-escaped ()
"Escaped surround characters."
(let* ((char (string (read-char "\\")))
(pair (cond ((string-match "[]})[{(]" char)
(let ((-pair (cdr (assoc (string-to-char char) evil-surround-pairs-alist))))
`(,(car -pair) . ,(cdr -pair))))
(t
`(,char . ,char))))
(format (if (sp-point-in-string) "\\\\%s" "\\%s")))
(cons (format format (car pair))
(format format (cdr pair)))))
(provide 'defuns-evil)
;;; defuns-evil.el ends here

61
core/lib/defuns-file.el Normal file
View file

@ -0,0 +1,61 @@
;;; defuns-file.el
;;;###autoload (autoload 'narf:file-delete "defuns-file" nil t)
(evil-define-command narf:file-delete (&optional bang filename)
"Delete current buffer's file. If bang, then kill the buffer afterwards as well."
:repeat nil
(interactive "<!><f>")
(let ((filename (file-truename (or filename (buffer-file-name)))))
(if (not (file-exists-p filename))
(error "File doesn't exist: %s" filename)
(delete-file filename)
(when bang
(kill-this-buffer)
(unless (narf/real-buffer-p)
(narf/previous-real-buffer)))
(save-place-forget-unreadable-files)
(message "File successfully deleted: %s" filename))))
(defun narf--save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit))
;;;###autoload (autoload 'narf:file-create "defuns-file" nil t)
(evil-define-command narf:file-create (path &optional bang)
"Deploy files (and their associated templates) quickly. Will prompt
you to fill in each snippet field before buffer closes unless BANG is
provided."
:repeat nil
(interactive "<f><!>")
(let ((dir (f-dirname path))
(fullpath (f-full path))
(is-auto t))
(when (and bang (not (file-exists-p dir))) (f-mkdir dir))
(if (file-exists-p dir)
(if (file-exists-p fullpath)
(error "File already exists: %s" path)
(find-file fullpath)
(add-hook 'yas-after-exit-snippet-hook 'narf--save-exit)
(if bang (narf--save-exit)))
(error "Directory doesn't exist: %s" dir))))
;;;###autoload (autoload 'narf:file-move "defuns-file" nil t)
(evil-define-command narf:file-move (path)
"Move current buffer's file to PATH. Replaces %, # and other variables (see
`evil-ex-replace-special-filenames')"
:repeat nil
(interactive "<f>")
(let* ((old-path (buffer-file-name))
(new-path (cond ((f-dir? path)
(f-expand (f-filename old-path) path))
((f-dir? (f-dirname path))
(f-full path))
(t (user-error "Not a valid destination: %s" path))))
(project-root (narf/project-root)))
(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)
(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

View file

@ -0,0 +1,30 @@
;;; defuns-flycheck.el
;; for ../core-flycheck.el
;;;###autoload
(defun narf*fly-shorter-status (result)
(format "[%s]" (replace-regexp-in-string " FlyC:?" "" result)))
;;;###autoload
(defun narf*flycheck-buffer ()
(if (and (featurep 'flycheck) flycheck-mode)
(flycheck-buffer)))
;;;###autoload
(defun narf/flycheck-next-error ()
(interactive)
(call-interactively
(if (bound-and-true-p flycheck-mode)
'flycheck-next-error
'next-error)))
;;;###autoload
(defun narf/flycheck-previous-error ()
(interactive)
(call-interactively
(if (bound-and-true-p flycheck-mode)
'flycheck-previous-error
'previous-error)))
(provide 'defuns-flycheck)
;;; defuns-flycheck.el ends here

115
core/lib/defuns-helm.el Normal file
View file

@ -0,0 +1,115 @@
;;; defuns-helm.el
;; see ../core-helm.el
;;;###autoload
(defun narf|projectile-invalidate-cache-maybe ()
(when (narf/project-p)
(projectile-invalidate-cache nil)))
;;;###autoload
(defun narf*projectile-replace-prompt (&optional string)
"Don't show the project name in the prompts; I already know."
helm-global-prompt)
;;;###autoload
(defun narf*helm-hide-modeline (source &optional force)
"No persistent header."
(setq mode-line-format nil)
(setq header-line-format nil))
;;;###autoload
(defun narf/helm-split-window (window)
"Minimalistic split-fn; leaves popwin to handle helm buffers."
(if (one-window-p t)
(let ((helm-full-frame t))
(selected-window))
(other-window-for-scrolling)))
;;;###autoload
(defun narf/helm-get-org-candidates-in-file (filename min-depth max-depth &optional fontify nofname)
(with-current-buffer (pcase filename
((pred bufferp) filename)
((pred stringp) (find-file-noselect filename)))
(and fontify (jit-lock-fontify-now))
(let ((match-fn (if fontify 'match-string 'match-string-no-properties)))
(save-excursion
(goto-char (point-min))
(cl-loop with width = (window-width)
while (re-search-forward org-complex-heading-regexp nil t)
if (let ((num-stars (length (match-string-no-properties 1))))
(and (>= num-stars min-depth) (<= num-stars max-depth)))
collect `(,(let ((heading (funcall match-fn 4))
(file (unless nofname
(concat (f-no-ext (f-relative filename org-directory)) ":")))
(level (length (match-string-no-properties 1))))
(org-format-outline-path
(append (org-get-outline-path t level heading)
(list heading)) width file))
. ,(point-marker)))))))
;;;###autoload (autoload 'narf:helm-recentf "defuns-helm" nil t)
(evil-define-command narf:helm-recentf (&optional bang)
"Ex-mode interface for `helm-recentf' and `helm-projectile-recentf'. If
`bang', then `search' is interpreted as regexp."
: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 'narf:helm-search "defuns-helm" nil t)
(evil-define-operator narf:helm-search (beg end &optional search hidden-files-p pwd-p regex-p)
:type inclusive
:repeat nil
(interactive "<r><a><!>")
(require 'helm-ag)
(let* ((helm-ag--default-directory (if pwd-p default-directory (concat (narf/project-root) "/")))
(helm-ag-command-option (concat (unless regex-p "-Q ")
(if hidden-files-p "--hidden ")))
(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--select-source) '(helm-source-do-ag))
:buffer "*helm-ag*"
:input input
:prompt helm-global-prompt)))
;;;###autoload (autoload 'narf:helm-regex-search "defuns-helm" nil t)
(evil-define-operator narf:helm-regex-search (beg end &optional search bang)
:type inclusive :repeat nil
(interactive "<r><a><!>")
(narf:helm-search beg end search bang nil t))
;;;###autoload (autoload 'narf:helm-regex-cwd "defuns-helm" nil t)
(evil-define-operator narf:helm-search-cwd (beg end &optional search bang)
;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted
;; as regexp
:type inclusive :repeat nil
(interactive "<r><a><!>")
(narf:helm-search beg end search bang t nil))
;;;###autoload (autoload 'narf:helm-regex-search-cwd "defuns-helm" nil t)
(evil-define-operator narf:helm-regex-search-cwd (beg end &optional search bang)
:type inclusive :repeat nil
(interactive "<r><a><!>")
(narf:helm-search beg end search bang t t))
;; 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 'narf:helm-swoop "defuns-helm" nil t)
(evil-define-command narf:helm-swoop (&optional search bang)
:repeat nil
(interactive "<a><!>")
(if (eq major-mode 'scss-mode)
(if bang (helm-css-scss-multi search) (helm-css-scss search))
(if bang (helm-multi-swoop-all search) (helm-swoop :$query search))))
(provide 'defuns-helm)
;;; defuns-helm.el ends here

65
core/lib/defuns-ido.el Normal file
View file

@ -0,0 +1,65 @@
;;; defuns-ido.el
;;;###autoload
(defun narf*ido-sort-mtime ()
"Sort ido filelist by mtime instead of alphabetically."
(setq ido-temp-list
(sort ido-temp-list
(lambda (a b)
(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 narf|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 narf/ido-find-file (&optional dir)
(interactive)
(let ((default-directory (or dir default-directory)))
(ido-find-file)))
;;;###autoload
(defun narf/ido-find-file-other-window (&optional dir)
(interactive)
(let ((default-directory (or dir default-directory)))
(ido-find-file-other-window)))
;;;###autoload
(defun narf/ido-find-project-file ()
(interactive)
(let ((default-directory (narf/project-root)))
(ido-find-file)))
;;;###autoload
(defun narf/ido-find-org-file ()
(interactive)
(let ((default-directory org-directory))
(ido-find-file)))
;;;###autoload
(defun narf/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 'narf:ido-find-file-in-emacsd "defuns-ido" nil t)
(evil-define-command narf:ido-find-file-in-emacsd (&optional bang) :repeat nil
(interactive "<!>")
(if bang
(ido-find-file-in-dir narf-modules-dir)
(ido-find-file-in-dir narf-emacs-dir)))
(provide 'defuns-ido)
;;; defuns-ido.el ends here

View file

@ -1,3 +1,4 @@
;;; defuns-isearch.el
;;;###autoload
(defun narf/isearch-delete-word ()
@ -29,6 +30,5 @@
(interactive)
(narf:isearch-paste-from-register ?+))
(provide 'defuns-isearch)
;;; defuns-isearch.el ends here

View file

@ -0,0 +1,40 @@
;;; defuns-neotree.el
;; for ../core-project.el
;;;###autoload
(defun narf/neotree-open (&optional dir)
(interactive)
(neotree-dir (or dir (narf/project-root))))
;;;###autoload
(defun narf/neotree-toggle ()
(interactive)
(if (neo-global--window-exists-p)
(neotree-hide)
(narf/neotree-open)))
;;;###autoload
(defun narf/neotree-find ()
(interactive)
(save-excursion (narf/neotree-open))
(neotree-find))
;;;###autoload
(defun narf|neotree-close-on-window-change ()
"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 narf*neo-buffer-fold-symbol (name)
"Custom hybrid ascii theme with leading whitespace."
(let ((n-insert-symbol (lambda (n)
(neo-buffer--insert-with-face
n 'neo-expand-btn-face))))
(or (and (equal name 'open) (funcall n-insert-symbol "- "))
(and (equal name 'close) (funcall n-insert-symbol "> "))
(and (equal name 'leaf) (funcall n-insert-symbol " ")))))
(provide 'defuns-neotree)
;;; defuns-neotree.el ends here

View file

@ -7,6 +7,5 @@
(narf|nlinum-disable)
(narf|nlinum-enable)))
(provide 'defuns-nlinum)
;;; defuns-nlinum.el ends here

View file

@ -1,3 +1,5 @@
;;; defuns-popwin.el
;;;###autoload
(defun narf/popwin-toggle ()
(interactive)
@ -5,6 +7,5 @@
(popwin:close-popup-window)
(popwin:popup-last-buffer)))
(provide 'defuns-popwin)
;;; defuns-popwin.el ends here

View file

@ -0,0 +1,44 @@
;;; defuns-project.el
;;;###autoload
(defun narf/project-root (&optional strict-p)
"Get the path to the root of your project. Uses `narf-project-root-files' to
determine if a directory is a project."
(let ((home (file-truename "~")))
(catch 'found
(f-traverse-upwards
(lambda (path)
(let ((path (file-truename path)))
(if (file-equal-p home path)
(throw 'found (if strict-p nil default-directory))
(dolist (file narf-project-root-files)
(when (file-exists-p (expand-file-name file path))
(throw 'found path)))))) default-directory)
default-directory)))
;;;###autoload
(defun narf/project-has-files (files &optional root)
"Return non-nil if `file' exists in the project root."
(let ((root (or root (narf/project-root)))
(files (if (listp files) files (list files)))
found-p file)
(while (and files (not found-p))
(setq file (pop files))
(setq found-p (file-exists-p (narf/project-path-to file root))))
found-p))
;;;###autoload
(defun narf/project-path-to (file &optional root)
(let ((root (or root (narf/project-root))))
(expand-file-name file root)))
;;;###autoload
(defun narf/project-name (&optional root)
(file-name-nondirectory (directory-file-name (or root (narf/project-root)))))
;;;###autoload
(defun narf/project-p ()
(not (null (narf/project-root t))))
(provide 'defuns-project)
;;; defuns-project.el ends here

View file

@ -0,0 +1,71 @@
;;; defuns-quickrun.el
;;;; Code building ;;;;;;;;;;;;;;;;;;;;;;
(defvar narf--build-command '("make %s" . "Makefile"))
(make-variable-buffer-local 'narf--build-command)
;;;###autoload
(defun narf/set-build-command (command &optional file)
(when (or (null file)
(narf/project-has-files file))
(setq narf--build-command `(,command . ,file))))
;;;###autoload (autoload 'narf:build "defuns-quickrun" nil t)
(evil-define-command narf:build (arg)
"Call a build command in the current directory.
If ARG is nil this function calls `recompile', otherwise it calls
`compile' passing ARG as build command."
(interactive "<sh>")
(when (null narf--build-command)
(user-error "No build command was set"))
(let ((build-file (cdr narf--build-command))
(build-cmd (car narf--build-command)))
(if (narf/project-has-files build-file)
(compile (format "cd '%s' && %s" build-file (format build-cmd (or arg ""))))
(error "Could not find Makefile"))))
;;;; Code running ;;;;;;;;;;;;;;;;;;;;;;
;;;###autoload (autoload 'narf:eval-buffer "defuns-quickrun" nil t)
(evil-define-command narf:eval-buffer ()
:move-point nil
(interactive)
(cond ((eq major-mode 'emacs-lisp-mode)
(narf:eval-region (point-min) (point-max)))
(t (quickrun))))
;;;###autoload (autoload 'narf:eval-region "defuns-quickrun" nil t)
(evil-define-operator narf:eval-region (beg end)
:move-point nil
(interactive "<r>")
(cond ((eq major-mode 'emacs-lisp-mode)
(let* ((pp-escape-newlines nil)
(out (s-trim (pp-to-string (eval (read (buffer-substring-no-properties beg end))))))
(lines (length (s-lines out))))
(if (< lines 5)
(princ out t)
(let ((buf (get-buffer-create "*eval*")))
(with-current-buffer buf
(read-only-mode -1)
(emacs-lisp-mode)
(setq-local scroll-margin 0)
(erase-buffer)
(insert out)
(beginning-of-buffer)
(read-only-mode 1)
(popwin:popup-buffer buf :height (if (> lines 25) 25 (1+ lines))))))))
(t (quickrun-region beg end))))
;;;###autoload (autoload 'narf:eval-region-and-replace "defuns-quickrun" nil t)
(evil-define-operator narf:eval-region-and-replace (beg end)
(interactive "<r>")
(cond ((eq major-mode 'emacs-lisp-mode)
(kill-region beg end)
(condition-case nil
(prin1 (eval (read (current-kill 0)))
(current-buffer))
(error (message "Invalid expression")
(insert (current-kill 0)))))
(t (quickrun-replace-region beg end))))
(provide 'defuns-quickrun)
;;; defuns-quickrun.el ends here

35
core/lib/defuns-tmux.el Normal file
View file

@ -0,0 +1,35 @@
;;; defuns-tmux.el
(defun narf--tmux-send (command)
(shell-command (format "tmux send-keys %s" command)))
(evil-define-interactive-code "<tmux>"
"Ex tmux argument (a mix between <sh> <f> and <fsh>)"
:ex-arg shell
(list (when (evil-ex-p) (evil-ex-file-arg))))
;;;###autoload (autoload 'narf:tmux-run "defuns-tmux" nil t)
(evil-define-command narf:tmux-run (&optional command bang)
"Sends input to tmux. Use `bang' to append to tmux"
(interactive "<tmux><!>")
(nerf/tmux-send (format (if bang "C-u %s Enter" "%s")
(shell-quote-argument command)))
(when (evil-ex-p)
(message "[Tmux] %s" command)))
;;;###autoload (autoload 'narf:tmux-chdir "defuns-tmux" nil t)
(evil-define-command narf:tmux-chdir (&optional path bang)
"CDs in tmux using `narf/project-root'"
(interactive "<f><!>")
(let ((dir (shell-quote-argument
(if (and path (not (s-blank? path)))
(if (file-directory-p path)
(file-truename path)
(error "Directory doesn't exist %s" path))
(if bang default-directory (narf/project-root))))))
(nerf/tmux-send (format "C-u cd Space %s Enter" (shell-quote-argument dir)))
(when (evil-ex-p)
(message "[Tmux] cd %s" dir))))
(provide 'defuns-tmux)
;;; defuns-tmux.el ends here

29
core/lib/defuns-ui.el Normal file
View file

@ -0,0 +1,29 @@
;;; defuns-ui.el
;; for ../core-ui.el
;;;###autoload
(defun narf:toggle-transparency ()
(interactive)
(let* ((alpha (frame-parameter nil 'alpha))
(alpha-val (if (listp alpha) (car alpha) alpha)))
(if (/= alpha-val 97)
(set-frame-parameter nil 'alpha 100)
(set-frame-parameter nil 'alpha 0))))
;;;###autoload
(defun narf:toggle-fullscreen ()
(interactive)
(set-frame-parameter nil 'fullscreen
(when (not (frame-parameter nil 'fullscreen)) 'fullboth)))
(defvar narf--big-mode nil)
;;;###autoload
(defun narf:toggle-big-mode ()
(interactive)
(if narf--big-mode
(set-frame-font (apply #'font-spec narf-default-font))
(set-frame-font (apply #'font-spec narf-big-font)))
(setq narf--big-mode (not narf--big-mode)))
(provide 'defuns-ui)
;;; defuns-ui.el ends here

View file

@ -0,0 +1,168 @@
;;; defuns-whitespace.el
;;;###autoload
(defun narf--point-at-bol-non-blank()
(save-excursion (evil-first-non-blank) (point)))
;;;###autoload
(defun narf/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 narf/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 narf/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 (narf--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 narf/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 " ^<*" (narf--point-at-bol-non-blank))
(if (eq old-point (point)) ;
(evil-move-end-of-line))))))
;; Mimic expandtab in vim
;;;###autoload
(defun narf/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)
(cond ;; If in a string
((sp-point-in-string)
(call-interactively 'backward-delete-char-untabify))
;; If using tabs (or at bol), just delete normally
((or indent-tabs-mode
(= (point-at-bol) (point)))
(call-interactively 'backward-delete-char))
;; Delete up to the nearest tab column IF only whitespace between point
;; and bol.
((looking-back "^[\\t ]*" (point-at-bol))
(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))
(backward-delete-char (- (match-end 1) (match-beginning 1)))
(backward-delete-char-untabify 1)))))
;; Otherwise do a regular delete
(t (backward-delete-char-untabify 1))))
;;;###autoload
(defun narf/dumb-indent ()
"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 narf/inflate-space-maybe ()
"Checks if point is surrounded by {} [] () delimiters and adds a
space on either side of the point if so."
(interactive)
(if (narf/surrounded-p)
(progn (call-interactively 'self-insert-command)
(save-excursion (call-interactively 'self-insert-command)))
(call-interactively 'self-insert-command)))
;;;###autoload
(defun narf/deflate-space-maybe ()
"Checks if point is surrounded by {} [] () delimiters, and deletes
spaces on either side of the point if so. Resorts to
`narf/backward-delete-whitespace-to-column' otherwise."
(interactive)
(save-match-data
(if (narf/surrounded-p)
(let ((whitespace-match (match-string 1)))
(cond ((not whitespace-match)
(call-interactively 'sp-backward-delete-char))
((string-match "\n" whitespace-match)
(evil-delete (point-at-bol) (point))
(delete-char -1)
(save-excursion (delete-char 1)))
(t
(just-one-space 0))))
(narf/backward-delete-whitespace-to-column))))
;;;###autoload
(defun narf/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) major-mode)
(newline-and-indent)
(insert "* ")
(indent-according-to-mode))
(t (indent-new-comment-line))))
(t (newline-and-indent))))
;;;###autoload (autoload 'narf:whitespace-retab "defuns-whitespace" nil t)
(evil-define-operator narf:whitespace-retab (beg end)
"Akin to vim's retab, this changes all tabs-to-spaces or spaces-to-tabs,
depending on `indent-tab-mode'. Untested."
:motion nil
:move-point nil
:type line
(interactive "<r>")
(unless (and beg end)
(setq beg (point-min))
(setq end (point-max)))
(if indent-tabs-mode
(tabify beg end)
(untabify beg end)))
;;;###autoload (autoload 'narf:whitespace-align "defuns-whitespace" nil t)
(evil-define-command narf:whitespace-align (beg end &optional regexp bang)
:repeat nil
(interactive "<r><a><!>")
(when regexp
(align-regexp beg end
(concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1)))
;;;###autoload
(defun narf:toggle-delete-trailing-whitespace ()
(interactive)
(if (memq 'delete-trailing-whitespace before-save-hook)
(progn (message "Remove trailing whitespace: OFF")
(remove-hook 'before-save-hook 'delete-trailing-whitespace))
(message "Remove trailing whitespace: ON")
(add-hook 'before-save-hook 'delete-trailing-whitespace)))
(provide 'defuns-whitespace)
;;; defuns-whitespace.el ends here

View file

@ -0,0 +1,56 @@
;;; defuns-workgroup.el
;;;###autoload
(defun narf/wg-helm-switch-to-workgroup (name)
(wg-switch-to-workgroup (wg-get-workgroup name)))
;;;###autoload
(defun narf:helm-wg ()
(interactive)
(helm :sources '(narf/helm-source-wg)))
;;;###autoload
(defun narf/wg-projectile-switch-project ()
(let ((workgroup-name (file-name-nondirectory (directory-file-name (narf/project-root)))))
(wg-create-workgroup workgroup-name t)
(helm-projectile-find-file)))
;;;###autoload (autoload 'narf:save-session "defuns-workgroup" nil t)
(evil-define-command narf:save-session (&optional bang session-name)
(interactive "<!><a>")
(if session-name
(wg-save-session-as (concat wg-workgroup-directory session-name) (not bang))
(wg-save-session)))
;;;###autoload (autoload 'narf:load-session "defuns-workgroup" nil t)
(evil-define-command narf:load-session (&optional bang session-name)
(interactive "<!><a>")
(wg-open-session (if session-name
(concat wg-workgroup-directory session-name)
wg-session-file)))
;;;###autoload (autoload 'narf:workgroup-new "defuns-workgroup" nil t)
(evil-define-command narf:workgroup-new (bang name)
(interactive "<!><a>")
(unless name
(user-error "No name specified for new workgroup"))
(if bang
(wg-clone-workgroup (wg-current-workgroup) name)
(wg-create-workgroup name t)))
;;;###autoload (autoload 'narf:workgroup-rename "defuns-workgroup" nil t)
(evil-define-command narf:workgroup-rename (new-name)
(interactive "<a>")
(wg-rename-workgroup new-name))
;;;###autoload
(defun narf:kill-other-workgroups ()
"Kill all other workgroups."
(interactive)
(let (workgroup (wg-current-workgroup))
(dolist (w (wg-workgroup-list))
(unless (wg-current-workgroup-p w)
(wg-kill-workgroup w)))))
(provide 'defuns-workgroup)
;;; defuns-workgroup.el ends here

View file

@ -0,0 +1,120 @@
;;; defuns-yasnippet.el
;; for ../core-yasnippet.el
;;;###autoload
(defun narf|yas-before-expand ()
"Switch to insert mode when expanding a template via backtab, or go back to
normal mode if there are no fields."
;; Strip out the shitespace before a line selection.
(when (narf/evil-visual-line-state-p)
(setq yas-selected-text
(replace-regexp-in-string
"\\(^ *\\|\n? $\\)" ""
(buffer-substring-no-properties (region-beginning)
(1- (region-end))))))
(evil-insert-state +1))
;;;###autoload
(defun narf|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 narf/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)
(yas-insert-snippet)
(evil-insert-state +1))
;;;###autoload
(defun narf/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 narf/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 narf/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 narf/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 narf/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 !%! ()
"Snippet function. Shorthand defun to surround text with newlines if more
than one line."
(when %
(if (> (length (s-lines %)) 1)
(concat "\n" % "\n")
(s-trim %))))
;;;###autoload
(defun !% ()
"Snippet function. Shorthand defun for snippets: prepends a newline to
`yas-selected-text' IF it contains more than one line."
(when %
(if (> (length (s-lines %)) 1)
(concat "\n" %)
(s-trim %))))
;;;###autoload
(defun %1 ()
"Trim selection; do no further processing."
(s-trim %))
;;;###autoload (autoload 'narf:yas-snippets "defuns-yasnippet" nil t)
(evil-define-command narf:yas-snippets (&optional bang)
(interactive "<!>")
(if bang
(narf/ido-find-file (car narf-snippet-dirs))
(yas-visit-snippet-file)))
;;;###autoload
(defun narf:yas-file-templates ()
(interactive)
(narf/ido-find-file (cdr narf-snippet-dirs)))
(provide 'defuns-yasnippet)
;;; nlinum-defuns.el ends here

View file

@ -0,0 +1,18 @@
;;; macros-auto-insert.el
;; for ../core-auto-insert.el
;;;###autoload
(defmacro add-template! (regexp-or-major-mode uuid yas-mode &optional project-only)
`(define-auto-insert ,regexp-or-major-mode
(lambda ()
(unless (or (and ,project-only (not (narf/project-p)))
(not (or (eq major-mode ,yas-mode)
(symbol-value ,yas-mode))))
(insert ,uuid)
(yas-expand-from-trigger-key)
(if (string-equal ,uuid (s-trim (buffer-string)))
(erase-buffer)
(evil-insert-state 1))))))
(provide 'macros-auto-insert)
;;; macros-auto-insert.el ends here

View file

@ -0,0 +1,8 @@
;;; defuns-buffers.el
;;;###autoload
(defun add-unreal-buffer! (regexp)
(add-to-list 'narf-unreal-buffers regexp))
(provide 'defuns-buffers)
;;; defuns-buffers.el ends here

View file

@ -0,0 +1,22 @@
;;; macros-company.el --- macros for company-mode
;; for ../core-company.el
;;;###autoload
(defmacro add-company-backend! (hook backends)
"Register a company backend for a mode."
(let ((def-name (intern (format "narf--init-company-%s" hook)))
(quoted (eq (car-safe backends) 'quote)))
`(progn
(defun ,def-name ()
(set (make-local-variable 'company-backends)
(append '((,@(mapcar (lambda (backend)
(if quoted
backend
(intern (format "company-%s" backend))))
(if quoted (cadr backends) backends))
company-semantic))
company-backends)))
(add-hook ',(intern (format "%s-hook" hook)) ',def-name))))
(provide 'macros-company)
;;; macros-company.el ends here

View file

@ -1,14 +1,13 @@
;;; macros-popwin.el
;;;###autoload
(defmacro @popwin-register (&rest forms)
(defmacro add-popwin-rule! (&rest forms)
"Register a rule for popwin. See `popwin:special-display-config'.
Example:
(@popwin-register (\"^\\*Flycheck.*\\*$\" :regexp t :position bottom :height 0.25 :noselect t))"
(add-popwin-rule! \"^\\*Flycheck.*\\*$\" :regexp t :position bottom :height 0.25 :noselect t)"
(declare (indent defun))
`(push (,@forms) form))
`(push '(,@forms) popwin:special-display-config))
(provide 'macros-popwin)
;;; macros-popwin.el ends here

View file

@ -0,0 +1,13 @@
;;; macros-quickrun.el
;;;###autoload
(defmacro build-for! (mode command 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."
`(add-hook! ,mode
(when (or (null ,build-file)
(narf/project-has-files ,build-file))
(setq narf--build-command '(,command . ,build-file)))))
(provide 'macros-quickrun)
;;; macros-quickrun.el ends here

View file

@ -0,0 +1,17 @@
;;; macros-yasnippet.el
;; for ../core-yasnippet.el
;;;###autoload
(defmacro add-yas-minor-mode! (&rest modes)
"Register minor MODES in yasnippet."
`(after! yasnippet
(when (boundp 'yas-extra-modes)
,@(mapcar (lambda (mode)
`(after! ,(cadr mode)
(if (symbol-value ,mode)
(yas-activate-extra-mode ,mode)
(setq yas-extra-modes (delq ,mode yas-extra-modes)))))
modes))))
(provide 'macros-yasnippet)
;;; macros-yasnippet.el ends here

View file

@ -1,4 +0,0 @@
(provide 'macros-company)
;;; macros-company.el ends here