Major overhaul

This commit is contained in:
Henrik Lissner 2014-12-10 15:54:36 -05:00
parent 4ab3ae1125
commit 6bda25da1f
76 changed files with 7431 additions and 571 deletions

294
core/autoloads.el Normal file
View file

@ -0,0 +1,294 @@
;;; autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads nil "../lib/help-fns+" "../lib/help-fns+.el" (21631
;;;;;; 21029 0 0))
;;; Generated autoloads from ../lib/help-fns+.el
(autoload 'describe-command "../lib/help-fns+" "\
Describe an Emacs command (interactive function).
Equivalent to using a prefix arg with `describe-function'.
If you use Icicles then in Icicle mode keys bound to the commands are
shown next to them in `*Completions*. You can toggle this keys
display on/off using `C-x C-a'.
\(fn FUNCTION)" t nil)
(autoload 'describe-option "../lib/help-fns+" "\
Describe an Emacs user variable (option).
Same as using a prefix arg with `describe-variable'.
\(fn VARIABLE &optional BUFFER)" t nil)
(autoload 'describe-option-of-type "../lib/help-fns+" "\
Describe an Emacs user OPTION (variable) of a given `defcustom' TYPE.
A prefix argument determines the type-checking behavior:
- None: OPTION is defined with TYPE or a subtype of TYPE.
- Plain `C-u': OPTION is defined with TYPE or a subtype of TYPE,
or its current value is compatible with TYPE.
- Negative: OPTION is defined with TYPE (exact match).
- Non-negative: OPTION is defined with TYPE (exact match),
or its current value is compatible with TYPE.
If TYPE is nil (default value) then *all* `defcustom' variables are
potential candidates. That is different from using `describe-option',
because `describe-option' includes user-variable candidates not
defined with `defcustom' (with `*'-prefixed doc strings).
\(fn TYPE OPTION)" t nil)
(autoload 'describe-file "../lib/help-fns+" "\
Describe the file named FILENAME.
If FILENAME is nil, describe current directory (`default-directory').
Starting with Emacs 22, if the file is an image file then:
* Show a thumbnail of the image as well.
* If you have command-line tool `exiftool' installed and in your
`$PATH' or `exec-path', then show EXIF data (metadata) about the
image. See standard Emacs library `image-dired.el' for more
information about `exiftool'.
If FILENAME is the name of an autofile bookmark and you use library
`Bookmark+', then show also the bookmark information (tags etc.). In
this case, a prefix arg shows the internal form of the bookmark.
In Lisp code:
Non-nil optional arg INTERNAL-FORM-P shows the internal form.
Non-nil optional arg NO-ERROR-P prints an error message but does not
raise an error.
\(fn FILENAME &optional INTERNAL-FORM-P NO-ERROR-P)" t nil)
;;;***
;;;### (autoloads nil "../lib/hl-todo" "../lib/hl-todo.el" (21619
;;;;;; 3856 0 0))
;;; Generated autoloads from ../lib/hl-todo.el
(autoload 'hl-todo-mode "../lib/hl-todo" "\
Highlight TODO tags in comments.
\(fn &optional ARG)" t nil)
(defvar global-hl-todo-mode nil "\
Non-nil if Global-Hl-Todo mode is enabled.
See the command `global-hl-todo-mode' for a description of this minor mode.
Setting this variable directly does not take effect;
either customize it (see the info node `Easy Customization')
or call the function `global-hl-todo-mode'.")
(custom-autoload 'global-hl-todo-mode "../lib/hl-todo" nil)
(autoload 'global-hl-todo-mode "../lib/hl-todo" "\
Toggle Hl-Todo mode in all buffers.
With prefix ARG, enable Global-Hl-Todo mode if ARG is positive;
otherwise, disable it. If called from Lisp, enable the mode if
ARG is omitted or nil.
Hl-Todo mode is enabled in all buffers where
`turn-on-hl-todo-mode-if-desired' would do it.
See `hl-todo-mode' for more information on Hl-Todo mode.
\(fn &optional ARG)" t nil)
;;;***
;;;### (autoloads nil "../lib/rotate-text" "../lib/rotate-text.el"
;;;;;; (21631 59390 0 0))
;;; Generated autoloads from ../lib/rotate-text.el
(autoload 'rotate-region "../lib/rotate-text" "\
Rotate all matches in `rotate-text-rotations' between point and mark.
\(fn BEG END)" t nil)
(autoload 'rotate-word-at-point "../lib/rotate-text" "\
Rotate word at point based on sets in `rotate-text-rotations'.
\(fn)" t nil)
;;;***
;;;### (autoloads nil "defuns-buffers" "defuns-buffers.el" (21630
;;;;;; 64935 0 0))
;;; Generated autoloads from defuns-buffers.el
(autoload 'my-narrow-to-region-indirect "defuns-buffers" "\
Restrict editing in this buffer to the current region, indirectly.
\(fn START END)" t nil)
(autoload 'my--cleanup-buffers-add "defuns-buffers" "\
\(fn REGEXP)" nil nil)
(autoload 'my-cleanup-buffers "defuns-buffers" "\
Kill left-over temporary, dired or buried special buffers
\(fn)" t nil)
(autoload 'my-kill-matching-buffers "defuns-buffers" "\
\(fn REGEXP &optional BUFFER-LIST)" t nil)
;;;***
;;;### (autoloads nil "defuns-text" "defuns-text.el" (21630 61093
;;;;;; 0 0))
;;; Generated autoloads from defuns-text.el
(autoload 'my--point-at-bol-non-blank "defuns-text" "\
\(fn)" nil nil)
(autoload 'my--surrounded-p "defuns-text" "\
\(fn)" nil nil)
(autoload 'my\.backward-kill-to-bol-and-indent "defuns-text" "\
Kill line to the first non-blank character. If invoked again
afterwards, kill line to column 1.
\(fn)" t nil)
(autoload 'my\.move-to-bol "defuns-text" "\
Moves cursor to the first non-blank character on the line. If
already there, move it to the true bol.
\(fn)" t nil)
(autoload 'my\.move-to-eol "defuns-text" "\
\(fn)" t nil)
(autoload 'my\.backward-delete-whitespace-to-column "defuns-text" "\
Delete back to the previous column of whitespace, or as much
whitespace as possible, or just one char if that's not possible.
\(fn)" t nil)
(autoload 'my\.dumb-indent "defuns-text" "\
Inserts a tab character (or spaces x tab-width). Checks if the
auto-complete window is open.
\(fn)" t nil)
(autoload 'my\.inflate-space-maybe "defuns-text" "\
Checks if point is surrounded by {} [] () delimiters and adds a
space on either side of the point if so.
\(fn)" t nil)
(autoload 'my\.deflate-space-maybe "defuns-text" "\
Checks if point is surrounded by {} [] () delimiters, and deletes
spaces on either side of the point if so. Resorts to
`my.backward-delete-whitespace-to-column' otherwise.
\(fn)" t nil)
(autoload 'my\.newline-and-indent "defuns-text" "\
Newline and indent; if in a comment, auto-comment and properly
indent the next line.
\(fn)" t nil)
;;;***
;;;### (autoloads nil "defuns-ui" "defuns-ui.el" (21635 60933 0 0))
;;; Generated autoloads from defuns-ui.el
(autoload 'load-dark-theme "defuns-ui" "\
\(fn)" t nil)
(autoload 'load-light-theme "defuns-ui" "\
\(fn)" t nil)
(autoload 'load-font "defuns-ui" "\
\(fn FONT SIZE)" t nil)
(autoload 'toggle-transparency "defuns-ui" "\
\(fn)" t nil)
(autoload 'toggle-theme "defuns-ui" "\
\(fn)" t nil)
(autoload 'toggle-presentation-mode "defuns-ui" "\
\(fn)" t nil)
;;;***
;;;### (autoloads nil "defuns-util" "defuns-util.el" (21631 18940
;;;;;; 0 0))
;;; Generated autoloads from defuns-util.el
(after "s" (defun s-count-lines (s) "Get number of lines in a string" (length (s-lines s))))
(after "f" (defmacro f--exists\? (file dir) `(f-exists\? (expand-file-name ,file ,dir))))
(after "projectile" (defun my--project-root (&optional force-pwd) (if (and (not force-pwd) (projectile-project-p)) (projectile-project-root) default-directory)))
(autoload 'what-face "defuns-util" "\
Tells you the name of the face (point) is on.
\(fn POS)" t nil)
(autoload 'what-col "defuns-util" "\
\(fn)" t nil)
(autoload 'what-bindings "defuns-util" "\
\(fn KEY)" nil nil)
;;;***
;;;### (autoloads nil nil ("../lib/evil-ex-registers.el" "../lib/evil-little-word.el"
;;;;;; "../lib/ruby-mode-indent-fix.el" "../lib/shaderlab-mode.el"
;;;;;; "../modules/init-auto-complete.el" "../modules/init-auto-insert.el"
;;;;;; "../modules/init-company.el" "../modules/init-cpp.el" "../modules/init-cscope.el"
;;;;;; "../modules/init-csharp.el" "../modules/init-dev.el" "../modules/init-elisp.el"
;;;;;; "../modules/init-eshell.el" "../modules/init-fly.el" "../modules/init-git.el"
;;;;;; "../modules/init-go.el" "../modules/init-helm.el" "../modules/init-ido.el"
;;;;;; "../modules/init-java.el" "../modules/init-js.el" "../modules/init-lua.el"
;;;;;; "../modules/init-org.el" "../modules/init-php.el" "../modules/init-project.el"
;;;;;; "../modules/init-projectile.el" "../modules/init-python.el"
;;;;;; "../modules/init-regex.el" "../modules/init-ruby.el" "../modules/init-scss.el"
;;;;;; "../modules/init-sh.el" "../modules/init-swift.el" "../modules/init-text.el"
;;;;;; "../modules/init-tmux.el" "../modules/init-web.el" "../modules/init-yasnippet.el"
;;;;;; "../my/my-bindings.el" "../my/my-settings.el" "core-editor.el"
;;;;;; "core-evil.el" "core-linux.el" "core-osx.el" "core-ui.el"
;;;;;; "core.el" "defuns.el") (21638 3439 736094 0))
;;;***
(provide 'autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; autoloads.el ends here

38
core/core-editor.el Normal file
View file

@ -0,0 +1,38 @@
;; Global editor behavior (+ evil)
(provide 'core-editor)
;;;; Editing plugins ;;;;;;;;;;;;;;;;;;;
(use-package expand-region
:commands (er/expand-region er/contract-region))
(use-package rotate-text
:commands (rotate-word-at-point rotate-region))
(use-package smartparens
:init (require 'smartparens-config)
:config
(progn
(smartparens-global-mode 1)
(setq blink-matching-paren t)
(setq sp-autowrap-region nil ; let evil-surround handle this
sp-highlight-pair-overlay nil
sp-show-pair-delay 0
sp-autoescape-string-quote nil)
;; Handle newlines
(sp-pair "{" nil :post-handlers '(("||\n[i]" "RET")))
(sp-pair "[" nil :post-handlers '(("||\n[i]" "RET")))
(sp-with-modes '(emacs-lisp-mode lisp-mode)
(sp-local-pair "[" nil :post-handlers '(("|" "RET"))))
;; Auto-close more conservatively
(sp-pair "[" nil :unless '(sp-point-before-word-p sp-point-before-same-p))
(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))
(sp-pair "'" nil :unless '(sp-point-after-word-p 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))
(after "yasnippet"
(defadvice yas-expand (before advice-for-yas-expand activate)
(sp-remove-active-pair-overlay)))))

372
core/core-evil.el Normal file
View file

@ -0,0 +1,372 @@
(provide 'core-evil)
;;;; Eeeeeeevil ;;;;;;;;;;;;;;;;;;;;;;;;
(use-package evil
:pre-load
(setq evil-want-visual-char-semi-exclusive t
evil-search-module 'evil-search
evil-magic 'very-magic
evil-want-C-u-scroll t ; enable C-u for scrolling
evil-ex-visual-char-range t ; column range for ex commands
evil-ex-search-vim-style-regexp t
;; Color-coded state cursors
evil-normal-state-cursor '("white" box)
evil-emacs-state-cursor '("cyan" bar)
evil-insert-state-cursor '("white" bar)
evil-god-state-cursor '("orange" box)
evil-visual-state-cursor 'hollow
ace-jump-mode-scope 'window
ace-jump-mode-move-keys (nconc (loop for i from ?a to ?z collect i)
(loop for i from ?A to ?Z collect i)))
:config
(progn
(evil-mode)
;; Always ensure evil-shift-width is consistent with tab-width
(add-hook! 'find-file-hook (setq evil-shift-width tab-width))
;; highlight matching delimiters where it's important
(defun show-paren-mode-off () (show-paren-mode -1))
(add-hook 'evil-insert-state-entry-hook 'show-paren-mode)
(add-hook 'evil-insert-state-exit-hook 'show-paren-mode-off)
(add-hook 'evil-visual-state-entry-hook 'show-paren-mode)
(add-hook 'evil-visual-state-exit-hook 'show-paren-mode-off)
(add-hook 'evil-motion-state-entry-hook 'show-paren-mode)
(add-hook 'evil-motion-state-exit-hook 'show-paren-mode-off)
(add-hook 'evil-operator-state-entry-hook 'show-paren-mode)
(add-hook 'evil-operator-state-exit-hook 'show-paren-mode-off)
;; Disable highlights on insert-mode
(add-hook 'evil-insert-state-entry-hook 'evil-ex-nohighlight)
;; modes to map to different default states
(dolist (mode-map '((cider-repl-mode . emacs)
(comint-mode . emacs)
(fundamental-mode . normal)
(help-mode . normal)
(term-mode . emacs)))
(evil-set-initial-state `,(car mode-map) `,(cdr mode-map)))
(progn ; evil plugins
(use-package evil-space :init (evil-space-default-setup))
(use-package evil-exchange
:config
(defadvice evil-force-normal-state (before evil-esc-quit-exchange activate)
(shut-up (evil-exchange-cancel))))
(use-package evil-ex-registers)
(use-package evil-indent-textobject) ; vii/vai/vaI
(use-package evil-numbers)
(use-package evil-god-state)
(use-package evil-matchit :init (global-evil-matchit-mode 1))
(use-package evil-snipe
:disabled t
:init (global-evil-snipe-mode 1)
:config
(progn
(evil-snipe-override-surround)
(setq evil-snipe-search-highlight t)
(setq evil-snipe-search-incremental-highlight t)))
(use-package evil-surround
:init (global-evil-surround-mode 1)
:config (evil-define-key 'visual evil-surround-mode-map (kbd "S") 'evil-surround-region))
(use-package evil-nerd-commenter
:pre-load (setq evilnc-hotkey-comment-operator "gc"))
(use-package evil-jumper
:pre-load (setq evil-jumper-file (expand-file-name "jumplist" my-tmp-dir))
:config
(progn
(setq evil-jumper-auto-center t
evil-jumper-auto-save-interval 3600)
(define-key evil-motion-state-map (kbd "H-i") 'evil-jumper/forward)))
(use-package ace-window
:config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))
(use-package evil-visualstar))
(bind evil-ex-completion-map
"C-r" #'evil-ex-paste-from-register ; registers in ex-mode
"C-a" 'move-beginning-of-line
"<s-left>" 'move-beginning-of-line
"<s-right>" 'move-beginning-of-line
"<s-backspace>" 'evil-delete-whole-line)
(progn ; evil hacks
(defadvice evil-force-normal-state (before evil-esc-quit activate)
(shut-up (evil-ex-nohighlight) ; turn off highlights
;; Exit minibuffer is alive
(if (minibuffer-window-active-p (minibuffer-window))
(my--minibuffer-quit))))
;; Popwin: close popup window, if any
(after "popwin"
(defadvice evil-force-normal-state (before evil-esc-quit-popwin activate)
(shut-up (popwin:close-popup-window))))
;; Ace-Jump: Enable half-cursor blink when using ace-jump
(defadvice evil-ace-jump-char-mode (before evil-ace-jump-char-mode-op activate)
(evil-half-cursor))
(defadvice evil-ace-jump-word-mode (before evil-ace-jump-word-mode-op activate)
(evil-half-cursor))
;; https://github.com/winterTTr/ace-jump-mode/issues/23
(evil-define-motion evil-ace-jump-two-chars-mode (count)
:type exclusive
:repeat abort
(evil-without-repeat
(evil-enclose-ace-jump-for-motion
(call-interactively 'ace-jump-two-chars-mode))))
(defun ace-jump-two-chars-mode (&optional query-char query-char-2)
"AceJump two chars mode"
(interactive)
(evil-half-cursor)
(setq query-char (or query-char (read-char ">")))
(setq query-char-2 (or query-char-2 (read-char (concat ">" (string query-char)))))
(if (eq (ace-jump-char-category query-char) 'other)
(error "[AceJump] Non-printable character"))
;; others : digit , alpha, punc
(setq ace-jump-query-char query-char)
(setq ace-jump-current-mode 'ace-jump-char-mode)
(ace-jump-do (regexp-quote (concat (char-to-string query-char)
(char-to-string query-char-2)))))
;; Jump to new splits
(defadvice evil-window-split (after evil-window-split-jump activate)
(evil-window-down 1))
(defadvice evil-window-vsplit (after evil-window-vsplit-jump activate)
(evil-window-right 1))
(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)))
(progn ; extensions
(defun 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)))
(defun evil-ex-replace-special-filenames (file-name)
"Replace special symbols in FILE-NAME.
% => full path to file (/project/src/thing.c)
# => alternative file path (/project/include/thing.h)
%:p => path to project root (/project/)
%:d => path to current directory (/project/src/)
%:e => the file's extension (c)
%:r => the full path without its extension (/project/src/thing)
%:t => the file's basename (thing.c)"
(let ((current-fname (buffer-file-name))
(alternate-fname (and (other-buffer)
(buffer-file-name (other-buffer)))))
(setq file-name
;; %:p:h => the project root (or current directory otherwise)
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:p\\)"
(my--project-root) file-name t t 2))
(setq file-name
;; %:p => the project root (or current directory otherwise)
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:d\\)"
default-directory file-name t t 2))
(when current-fname
(setq file-name
;; %:e => ext
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:e\\)"
(f-ext current-fname) file-name t t 2))
(setq file-name
;; %:r => filename
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:r\\)"
(f-no-ext current-fname) file-name t t 2))
(setq file-name
;; %:t => filename.ext
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:t\\)"
(f-base current-fname) file-name t t 2))
(setq file-name
;; % => file path for current frame
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)"
current-fname file-name t t 2)))
(when alternate-fname
(setq file-name
;; # => file path for alternative frame
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)"
alternate-fname file-name t t 2)))
(setq file-name
(replace-regexp-in-string "\\\\\\([#%]\\)"
"\\1" file-name t)))
file-name))
(progn ; ex-commands
(evil-ex-define-cmd "pres[ent]" 'toggle-theme)
(evil-ex-define-cmd "full[scr]" 'toggle-frame-fullscreen)
(evil-ex-define-cmd "k[ill]" 'kill-this-buffer) ; Kill current buffer
(evil-ex-define-cmd "k[ill]o" 'cleanup-buffers) ; Kill current project buffers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(evil-ex-define-cmd "echo" 'my:echo)
(evil-define-command my:echo (&optional output)
(interactive "<a>")
(message "%s" output))
(evil-ex-define-cmd "k[ill]all" 'my:kill-buffers) ; Kill all buffers (bang = project buffers only)
(evil-define-command my:kill-buffers (&optional bang)
:repeat nil
(interactive "<!>")
(if (and bang (projectile-project-p))
(projectile-kill-buffers)
(mapc 'kill-buffer (buffer-list)))
(delete-other-windows))
(evil-ex-define-cmd "ini" 'my:init-files)
(evil-define-command my:init-files (&optional bang)
:repeat nil
(interactive "<!>")
(if bang
(ido-find-file-in-dir my-modules-dir)
(ido-find-file-in-dir my-dir)))
(evil-ex-define-cmd "n[otes]" 'my:notes)
(evil-define-command my:notes ()
:repeat nil
(interactive)
(ido-find-file-in-dir org-directory))
(evil-ex-define-cmd "recompile" 'my:byte-compile)
(evil-define-command my:byte-compile (&optional bang)
:repeat nil
(interactive "<!>")
(if bang
(byte-recompile-directory (concat my-dir ".cask") 0 t)
(byte-recompile-directory my-dir 0 t)))
(evil-ex-define-cmd "build" 'my:build)
(evil-define-command my:build (arguments &optional bang)
:repeat t
(interactive "<a><!>")
(my-build arguments))
(evil-ex-define-cmd "cd" 'my:cd)
(evil-define-command my:cd (dir)
:repeat nil
(interactive "<f>")
(cd (if (zerop (length dir)) "~" dir)))
(defun --save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit))
(evil-ex-define-cmd "en[ew]" 'my:create-file)
(evil-define-command my:create-file (path &optional bang)
"Deploy files (and their associated templates) quickly. Will prompt
you to fill in each snippet field before buffer closes unless BANG is
provided."
:repeat nil
(interactive "<f><!>")
(let ((dir (f-dirname path))
(fullpath (f-full path))
(is-auto t))
(when (and bang (not (f-exists? dir))) (f-mkdir dir))
(if (f-exists? dir)
(if (f-exists? fullpath)
(error "File already exists: %s" path)
(find-file fullpath)
(add-hook 'yas-after-exit-snippet-hook '--save-exit)
(if bang (--save-exit)))
(error "Directory doesn't exist: %s" dir))))
(evil-ex-define-cmd "ren[ame]" 'my:rename-this-file) ; Rename file . Bang: Delete old one
(evil-define-command my:rename-this-file (new-name &optional bang)
"Renames current buffer and file it is visiting. Replaces %, # and other
variables (see `evil-ex-replace-special-filenames')"
:repeat nil
(interactive "<f><!>")
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file!" name)
(let ((new-name
(evil-ex-replace-special-filenames (if new-name
new-name
(read-file-name "New name: " filename)))))
(if (get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name)
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)
(save-place-forget-unreadable-files)
(when bang
(delete-file filename))
(message "File '%s' successfully renamed to '%s'"
name (file-name-nondirectory new-name)))))))
(evil-ex-define-cmd "x" 'my:scratch-buffer)
(evil-define-operator my:scratch-buffer (beg end &optional 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 (projectile-project-root))
(buffer-name (if (projectile-project-p)
(format "*scratch* (%s)" (projectile-project-name))
"*scratch*")))
(popwin:popup-buffer (get-buffer-create buffer-name))
(when (eq (get-buffer buffer-name) (current-buffer))
(cd project-dir)
(if text (insert text))
(funcall mode))))))
(evil-ex-define-cmd "al[ign]" 'my:align)
(evil-define-command my: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)))
(evil-ex-define-cmd "retab" 'my:retab)
(evil-define-operator my: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)))
(evil-ex-define-cmd "sq[uint]" 'my:narrow-indirect) ; Narrow buffer to selection
(evil-define-operator my:narrow-indirect (beg end)
"Indirectly narrow the region from BEG to END."
:move-point nil
:type exclusive
:repeat nil
(interactive "<r>")
(evil-normal-state)
(narrow-to-region-indirect beg end)))))

3
core/core-linux.el Normal file
View file

@ -0,0 +1,3 @@
(provide 'core-linux)
;; Nothing here yet

53
core/core-osx.el Normal file
View file

@ -0,0 +1,53 @@
;; Mac-specific settings
(provide 'core-osx)
;; Use a shared clipboard
(setq x-select-enable-clipboard t)
;; Curse Lion and its sudden but inevitable fullscreen mode!
(setq ns-use-native-fullscreen nil)
;; Don't open files from the workspace in a new frame
(setq ns-pop-up-frames nil)
;; (setq ns-auto-hide-menu-bar t)
;; fix emacs PATH on OSX (GUI only)
(use-package exec-path-from-shell
:if (memq window-system '(mac ns))
:init (exec-path-from-shell-initialize))
(after "evil"
;; On OSX, stop copying each visual state move to the clipboard:
;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on
;; Most of this code grokked from:
;; http://stackoverflow.com/questions/15873346/elisp-rename-macro
(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 my--open-file-with (path &optional appName)
(if (and appName
(stringp appName)
(not (string= "" appName)))
(setq appName (concat "-a " appName ".app")))
(shell-command (concat "open " appName " " (shell-quote-argument path))))
(defun my-open-with (appName)
(interactive "sApp name: ")
(my--open-file-with buffer-file-name appName))
(defun my-send-to-transmit ()
(interactive) (my-open-with "Transmit"))
(defun my-send-to-launchbar ()
(interactive) (my-open-with "LaunchBar"))
(defun my-send-dir-to-launchbar ()
(interactive) (my--open-file-with default-directory "LaunchBar"))
(defun my-send-dir-to-finder ()
(interactive) (my--open-file-with default-directory "Finder"))
(defun my-osx-psuedo-fullscreen ()
(interactive)
(set-frame-position nil 0 0)
(set-frame-size nil 362 112))

126
core/core-ui.el Normal file
View file

@ -0,0 +1,126 @@
;; User interface layout & behavior
(provide 'core-ui)
;;;; Load Theme ;;;;;;;;;;;;;;;;;;;;;;;;
(when window-system
;; No transparency!
(set-frame-parameter nil 'alpha 96)
(unless (member *default-font (font-family-list))
(error "Font %s isn't installed" *default-font))
(let ((font-str (concat *default-font "-" (number-to-string *default-font-size))))
(add-to-list 'default-frame-alist `(font . ,font-str))
(add-to-list 'initial-frame-alist `(font . ,font-str))))
(add-to-list 'custom-theme-load-path my-themes-dir)
(load-dark-theme)
;;;; GUI Settings ;;;;;;;;;;;;;;;;;;;;;;
(tooltip-mode -1)
(blink-cursor-mode 1) ; blink cursor
;; (global-hl-line-mode 1) ; highlight line
;; Multiple cursors across buffers cause a strange redraw delay for
;; some things, like auto-complete or evil-mode's cursor color
;; switching.
(setq-default cursor-in-non-selected-windows nil)
(setq-default visible-bell nil) ; silence of the bells
(setq-default use-dialog-box nil) ; avoid GUI
(setq-default redisplay-dont-pause t)
;; do not soft-wrap lines
(setq-default truncate-lines t)
(setq-default truncate-partial-width-windows nil)
(setq-default indicate-buffer-boundaries nil)
(setq-default indicate-empty-lines nil)
(when (functionp 'scroll-bar-mode) (scroll-bar-mode -1)) ; no scrollbar
(when (functionp 'tool-bar-mode) (tool-bar-mode -1)) ; no toolbar
(when (functionp 'menu-bar-mode) (menu-bar-mode -1)) ; no menubar
(when (fboundp 'fringe-mode) (fringe-mode '(5 . 10))) ; no nonsense
(when window-system
(setq frame-title-format '(buffer-file-name "%f" ("%b")))
(tooltip-mode -1)
(blink-cursor-mode 1))
;; Show full path in window title
(setq frame-title-format
'(:eval (if (buffer-file-name) (abbreviate-file-name (buffer-file-name)) "%b")))
;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package uniquify
:config (setq uniquify-buffer-name-style 'post-forward
uniquify-separator ":"
uniquify-ignore-buffers-re "^\\*"))
(use-package smart-mode-line
:config
(setq rm-blacklist
(mapconcat 'identity
'(" SP"
" Fill"
" yas"
" Fly"
" EvilOrg"
" Abbrev"
" WS"
" GitGutter"
" Undo-Tree"
" Projectile\\[.+\\]"
" hs"
" ElDoc"
) "\\|"))
:init
(progn
(setq sml/no-confirm-load-theme t
sml/mode-width 'full
sml/extra-filler (if window-system 1 0)
sml/show-remote nil
sml/modified-char "*"
sml/encoding-format nil)
(setq sml/replacer-regexp-list '(("^~/Dropbox/Projects/" "PROJECTS:")
("^~/.emacs.d/" "EMACS.D:")))
(after "evil" (setq evil-mode-line-format nil))
(setq-default mode-line-misc-info
'((which-func-mode ("" which-func-format ""))
(global-mode-string ("" global-mode-string ""))))
(add-hook! 'after-change-major-mode-hook
(setq mode-line-format
'((if window-system " ")
"%e"
mode-line-mule-info
mode-line-client
mode-line-remote
mode-line-frame-identification
mode-line-buffer-identification
mode-line-modified
mode-line-modes
mode-line-misc-info
(vc-mode vc-mode)
" "
mode-line-position
" "
mode-line-front-space
))
(add-to-list 'mode-line-modes
'(sml/buffer-identification-filling
sml/buffer-identification-filling
(:eval (setq sml/buffer-identification-filling
(sml/fill-for-buffer-identification))))))
(let ((-linepo mode-line-position))
(sml/setup)
(sml/apply-theme 'respectful)
(setq mode-line-position -linepo)
(sml/filter-mode-line-list 'mode-line-position))))

281
core/core.el Normal file
View file

@ -0,0 +1,281 @@
(provide 'core)
(cd "~") ; instead of /
(require 'cask)
(cask-initialize)
(defconst is-mac (eq system-type 'darwin))
(defconst is-linux (eq system-type 'gnu/linux))
;; Make sure undo/backup folders exist
(defconst my-tmp-dir-undo (expand-file-name "undo" my-tmp-dir))
(defconst my-tmp-dir-backup (expand-file-name "backup" my-tmp-dir))
(defconst my-tmp-dir-autosave (expand-file-name "autosave" my-tmp-dir))
(unless (file-directory-p my-tmp-dir)
(make-directory my-tmp-dir-undo t)
(make-directory my-tmp-dir-backup t)
(make-directory my-tmp-dir-autosave t))
(setq load-prefer-newer t)
(setq debug-on-quit *debug-mode)
(require 'shut-up)
(setq shut-up-ignore *debug-mode)
(when noninteractive (shut-up-silence-emacs)) ; http://youtu.be/Z6woIRLnbmE
(shut-up
;;;; Sane defaults ;;;;;;;;;;;;;;;;;;;;;;;
(line-number-mode 1) ; hide line no in modeline
(column-number-mode 1) ; hide col no in modeline
(auto-compression-mode t) ; Transparently open compressed files
(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) ; In case of emacs 24.4
;;; window layout undo/redo
(winner-mode 1)
(setq winner-boring-buffers '("*Completions*" "*Help*"))
;;; UTF-8 please
(setq locale-coding-system 'utf-8) ; pretty
(set-terminal-coding-system 'utf-8) ; pretty
(set-keyboard-coding-system 'utf-8) ; pretty
(set-selection-coding-system 'utf-8) ; please
(prefer-coding-system 'utf-8) ; with sugar on top
(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no
;;; Show tab characters
;; (global-whitespace-mode 1)
(setq whitespace-style '(face tabs tab-mark) ; needs to be re-set in every buffer
whitespace-display-mappings
'((tab-mark ?\t [?| ?\t] [?\\ ?\t])
(newline-mark 10 [36 10]))) ; for whitespace-newline-mode
;; avoid garbage collection (default is 400k)
(setq-default gc-cons-threshold 20000000)
(setq-default confirm-kill-emacs nil)
(setq-default fill-column 80)
;; minibufferception? Nay!
(setq-default enable-recursive-minibuffers nil)
;; Sane scroll settings
(setq scroll-margin 5)
(setq scroll-conservatively 9999)
(setq scroll-preserve-screen-position 1)
;; Show me those keystrokes
(setq echo-keystrokes 0.02)
;; I'll use visual mode, kthxbai
(setq shift-select-mode nil)
(setq ring-bell-function 'ignore)
(setq inhibit-startup-screen t) ; don't show EMACs start screen
(setq inhibit-splash-screen t)
(setq inhibit-startup-buffer-menu t)
(setq initial-major-mode 'text-mode) ; initial scratch buffer mode
(setq initial-scratch-message nil)
(setq initial-scratch-buffer nil) ; empty scratch buffer
(setq compilation-always-kill t)
(setq compilation-ask-about-save nil)
(setq compilation-scroll-output t)
(setq sentence-end-double-space nil) ; sentences end with periods. Period.
(setq eval-expression-print-level nil)
(setq show-paren-delay 0)
(setq ediff-diff-options "-w")
(setq ediff-split-window-function 'split-window-horizontally) ; side-by-side diffs
(setq ediff-window-setup-function 'ediff-setup-windows-plain) ; no extra frames
;; Fixes C-i's synonymity with TAB
(keyboard-translate ?\C-i ?\H-i)
;;;; Backup ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Disable all backups (that's what git/dropbox are for)
(setq bookmark-save-flag t)
(setq bookmark-default-file (expand-file-name "bookmarks" my-tmp-dir))
(setq auto-save-default nil)
(setq auto-save-list-file-name (expand-file-name ".auto-save" my-tmp-dir-autosave))
(setq auto-save-file-name-transforms `((".*" ,my-tmp-dir-autosave t)))
;; In case I want to reactivate backup files
(setq make-backup-files nil)
(setq create-lockfiles nil)
(setq backup-directory-alist `((".*" . ,my-tmp-dir-backup)))
;; Remember undo history
(setq-default undo-tree-auto-save-history t)
(setq-default undo-tree-history-directory-alist `(("." . ,my-tmp-dir-undo)))
;;;; Save history across sessions
(setq savehist-additional-variables '(search ring regexp-search-ring))
(setq savehist-file (f-expand "savehist" my-tmp-dir)) ; keep the home clean
(savehist-mode 1)
;; Save cursor location across sessions
(require 'saveplace)
(setq save-place-file (f-expand "saveplace" my-tmp-dir))
(add-hook 'find-file-hook ; activate save-place for files that exist
(lambda()
(if (file-exists-p buffer-file-name)
(setq save-place t))))
(require 'recentf)
(setq recentf-max-menu-items 0)
(setq recentf-max-saved-items 1000)
(setq recentf-auto-cleanup 'never)
(setq recentf-save-file (concat my-tmp-dir "recentf"))
(setq recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last\\'" "\\.revive\\'", "/TAGS\\'"))
(recentf-mode 1)
;; What we do every night, Pinkie...
(defun display-startup-echo-area-message ()
(message "What're we gonna do tonight, Brain? (Loaded in %s)" (emacs-init-time)))
;;;; Editor behavior ;;;;;;;;;;;;;;;;
;; spaces instead of tabs
(setq-default indent-tabs-mode nil) ; spaces instead of tabs
(setq-default tab-always-indent nil)
(setq-default tab-width 4)
(setq delete-trailing-lines nil)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(add-hook 'makefile-mode-hook 'indent-tabs-mode) ; Use normal tabs in makefiles
;; Make sure scratch buffer is always "in a project"
(add-hook 'find-file-hook
(lambda()
(let ((buffer (get-buffer "*scratch*"))
(pwd (my--project-root)))
(when (buffer-live-p buffer)
(save-window-excursion
(switch-to-buffer buffer)
(unless (eq (my--project-root) pwd)
(cd pwd)
(rename-buffer (format "*scratch* (%s)" (file-name-base (directory-file-name pwd))))))))))
;; My own minor mode!
(define-minor-mode my-mode :global t :keymap (make-sparse-keymap))
;;;; Behavior adjustments ;;;;;;;;;;;;;;;;
;; Skip special buffers on next/previous-buffer or kill-this-buffer
(defadvice next-buffer (after void-messages-buffer-in-next-buffer activate)
(let ((buffer-name (buffer-name)))
(when (and (string-match-p "\\`\\(\\*.+\\*\\|TAGS\\)$" buffer-name)
(not (string-match-p "\\`\\*scratch*" buffer-name)))
(next-buffer))))
(defadvice previous-buffer (after avoid-messages-buffer-in-previous-buffer activate)
(let ((buffer-name (buffer-name)))
(when (and (string-match-p "\\`\\(\\*.+\\*\\|TAGS\\)$" buffer-name)
(not (string-match-p "\\`\\*scratch*" buffer-name)))
(previous-buffer))))
(defadvice kill-this-buffer (after kill-this-buffer-no-switch-to-special-buffers activate)
(let ((buffer-name (buffer-name)))
(if (and (string-match-p "^\\*.+\\*" buffer-name)
(not (string-match-p "^\\*scratch\\*" buffer-name)))
(previous-buffer))))
;; Don't kill the scratch buffer, just empty and bury it
(defadvice kill-this-buffer (around kill-this-buffer-or-empty-scratch activate)
(if (string-match-p "^\\*scratch\\*" (buffer-name))
(bury-buffer)
ad-do-it))
;;;; Automatic minor modes ;;;;;;;;;;;;;;;
(defvar 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 enable-minor-mode-based-on-extension ()
"check file name against auto-minor-mode-alist to enable minor modes
the checking happens for all pairs in auto-minor-mode-alist"
(when buffer-file-name
(let ((name buffer-file-name)
(remote-id (file-remote-p buffer-file-name))
(alist auto-minor-mode-alist))
;; Remove backup-suffixes from file name.
(setq name (file-name-sans-versions name))
;; Remove remote file name identification.
(when (and (stringp remote-id)
(string-match-p (regexp-quote remote-id) name))
(setq name (substring name (match-end 0))))
(while (and alist (caar alist) (cdar alist))
(if (string-match (caar alist) name)
(funcall (cdar alist) 1))
(setq alist (cdr alist))))))
(add-hook 'find-file-hook 'enable-minor-mode-based-on-extension)
;;;; Utility plugins ;;;;;;;;;;;;;;;;;;
(require 'defuns) ; all the defuns
(require 'use-package) ; Package management bootstrap
(setq use-package-verbose *debug-mode)
;; Generate autoloads if necessary
(defun my-update-autoloads (&optional forcep)
(interactive)
(setq generated-autoload-file (concat my-core-dir "autoloads.el"))
(when (or forcep (not (file-exists-p generated-autoload-file)))
(if forcep (delete-file generated-autoload-file))
(update-directory-autoloads my-core-dir my-modules-dir my-personal-dir my-elisp-dir))
(require 'autoloads))
(my-update-autoloads)
;; Add elisp dirs to load-path
(let ((default-directory my-elisp-dir))
(normal-top-level-add-to-load-path '("."))
(normal-top-level-add-subdirs-to-load-path))
(use-package smex
:commands (smex smex-major-mode-commands)
:config
(progn
(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)))
(use-package popwin
:init (popwin-mode 1)
:config
(progn ; popwin config
(setq popwin:popup-window-height 0.45)
(push '(diff-mode :position bottom :stick t) popwin:special-display-config)
(push '("*Backtrace*") popwin:special-display-config)
(push '("*Warnings*") popwin:special-display-config)
(push '("*Process List*") popwin:special-display-config)
(push '("*Compile-Log*" :height 0.3 :position bottom :noselect t) popwin:special-display-config)
(push '(" *undo-tree*" :width 0.3 :position right) popwin:special-display-config)
(push '("^\\*scratch\\*.*" :regexp t :stick t) popwin:special-display-config)
(after "evil"
(evil-ex-define-cmd "l[ast]" 'popwin:popup-last-buffer)
(evil-ex-define-cmd "m[sg]" 'popwin:messages))
(defun popwin:toggle-popup-window ()
(interactive)
(if (popwin:popup-window-live-p)
(popwin:close-popup-window)
(popwin:popup-last-buffer)))))
;;;; Start the party ;;;;;;;;;;;;;;;;;;;
(if is-mac (require 'core-osx))
(require 'core-ui)
(require 'core-evil)
(require 'core-editor)
(require 'server)
(unless (server-running-p)
(server-start)))

82
core/defuns-buffers.el Normal file
View file

@ -0,0 +1,82 @@
;; Inspired by http://demonastery.org/2013/04/emacs-evil-narrow-region/
;;;###autoload
(defun my-narrow-to-region-indirect (start end)
"Restrict editing in this buffer to the current region, indirectly."
(interactive "r")
(deactivate-mark)
(let ((buf (clone-indirect-buffer nil nil)))
(with-current-buffer buf
(narrow-to-region start end))
(switch-to-buffer buf)))
;; Killing Buffers ;;;;;;;;;;;;;;;;;;;;;
;; Buffer defuns
(defvar my-cleanup-buffers-list '("^ \\*"
"^\\*Backtrace\\*$"
"^\\*Warnings\\*$"
"^\\*Compile-Log\\*$"
"^\\*Ediff.*\\*$"
help-mode
dired-mode
reb-mode)
"A list of buffer name regexps or major-mode symbols. If buried buffers
match/have that mode active, `cleanup-buffers' will kill them.")
(defvar my-cleanup-processes-alist '(("pry" . ruby-mode)
("irb" . ruby-mode)
("ipython" . python-mode))
"An alist of (process-name . major-mode), that `my-cleanup-processes' checks
before killing processes. If there are no buffers with matching major-modes, it
gets killed.")
;;;###autoload
(defun my--cleanup-buffers-add (regexp)
(add-to-list 'my-cleanup-buffers-list regexp))
;;;###autoload
(defun my-cleanup-buffers ()
"Kill left-over temporary, dired or buried special buffers"
(interactive)
(let* ((this-frame (selected-frame))
(kill-list (buffer-list this-frame)))
(setq kill-list
(-filter (lambda (b)
(unless (get-buffer-window b) ; don't kill if visible
(-any? (lambda (pred)
(cond ((stringp pred)
(s-matches? pred (buffer-name b)))
((symbolp pred)
(eq (buffer-local-value 'major-mode b) pred))))
my-cleanup-buffers-list)))
kill-list))
(message "Cleaned up %s buffers" (length kill-list))
(mapc 'kill-buffer kill-list)
(my-cleanup-processes)))
;;;###autoload
(defun my-cleanup-processes ()
(interactive)
(let ((buffer-list (buffer-list)))
(dolist (p (process-list))
(let* ((process-name (process-name p))
(assoc (assoc process-name my-cleanup-processes-alist)))
(when (and assoc
(not (string= process-name "server"))
(process-live-p p)
(not (-any? (lambda (b)
(let ((mode (buffer-local-value 'major-mode b)))
(eq mode (cdr assoc))))
buffer-list)))
(message "Cleanup: killing %s" process-name)
(delete-process p))))))
;;;###autoload
(defun my-kill-matching-buffers (regexp &optional buffer-list)
(interactive)
(mapc (lambda (b)
(if (s-matches? regexp (buffer-name b))
(kill-buffer b)))
(if buffer-list buffer-list (buffer-list))))

123
core/defuns-text.el Normal file
View file

@ -0,0 +1,123 @@
;;;###autoload
(defun my--point-at-bol-non-blank()
(save-excursion (evil-first-non-blank) (point)))
;;;###autoload
(defun my--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 my.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 my.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 (my--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 my.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 " ^<*" (my--point-at-bol-non-blank))
(if (eq old-point (point)) ;
(evil-move-end-of-line))))))
;; Mimic expandtab in vim
;;;###autoload
(defun my.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))
;; Otherwise, delete up to the nearest tab column
(t (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)))
(call-interactively 'backward-delete-char-untabify)))))))
;;;###autoload
(defun my.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 my.inflate-space-maybe ()
"Checks if point is surrounded by {} [] () delimiters and adds a
space on either side of the point if so."
(interactive)
(if (my--surrounded-p)
(progn (call-interactively 'self-insert-command)
(save-excursion (call-interactively 'self-insert-command)))
(call-interactively 'self-insert-command)))
;;;###autoload
(defun my.deflate-space-maybe ()
"Checks if point is surrounded by {} [] () delimiters, and deletes
spaces on either side of the point if so. Resorts to
`my.backward-delete-whitespace-to-column' otherwise."
(interactive)
(save-match-data
(if (my--surrounded-p)
(let ((whitespace-match (match-string 1)))
(cond ((not whitespace-match)
(call-interactively 'delete-backward-char))
((string-match "\n" whitespace-match)
(evil-delete (point-at-bol) (point))
(delete-char -1)
(save-excursion (delete-char 1)))
(t
(just-one-space 0))))
(my.backward-delete-whitespace-to-column))))
;;;###autoload
(defun my.newline-and-indent ()
"Newline and indent; if in a comment, auto-comment and properly
indent the next line."
(interactive)
(cond ((sp-point-in-string)
(evil-ret))
((evil-in-comment-p)
(if (eq major-mode 'js2-mode)
(js2-line-break)
(call-interactively 'indent-new-comment-line)))
(t
(evil-ret-and-indent))))

47
core/defuns-ui.el Normal file
View file

@ -0,0 +1,47 @@
(eval-when-compile (require 'cl))
(defvar my/dark-theme-p t)
(defvar my/presentation-mode-p nil)
;;;###autoload
(defun load-dark-theme()
(interactive)
;; (sml/apply-theme 'respectful)
(load-theme *dark-theme t))
;;;###autoload
(defun load-light-theme()
(interactive)
;; (sml/apply-theme 'light)
(load-theme *light-theme t))
;;;###autoload
(defun load-font (font size)
(interactive)
(when window-system
(let ((font-str (concat font "-" (number-to-string size))))
(if (member font (font-family-list))
(set-frame-font font-str t t)
(error "Font %s not installed" font)))))
;;;###autoload
(defun toggle-transparency ()
(interactive)
(if (/= (frame-parameter nil 'alpha) 96)
(set-frame-parameter nil 'alpha 96)
(set-frame-parameter nil 'alpha 0)))
;;;###autoload
(defun toggle-theme ()
(interactive)
(if my/dark-theme-p
(load-light-theme)
(load-dark-theme)))
;;;###autoload
(defun toggle-presentation-mode ()
(interactive)
(if my/presentation-mode-p
(load-font *default-font *default-font-size)
(load-font *presentation-font *presentation-font-size))
(setq my/presentation-mode-p (not my/presentation-mode-p)))

42
core/defuns-util.el Normal file
View file

@ -0,0 +1,42 @@
;; String Defuns ;;;;;;;;;;;;;;;;;;;;;;;
;;;###autoload
(after "s"
(defun s-count-lines (s)
"Get number of lines in a string"
(length (s-lines s))))
;; File Defuns ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;###autoload
(after "f"
(defmacro f--exists? (file dir)
`(f-exists? (expand-file-name ,file ,dir))))
;;;###autoload
(after "projectile"
(defun my--project-root (&optional force-pwd)
(if (and (not force-pwd)
(projectile-project-p))
(projectile-project-root)
default-directory)))
;; Misc Defuns ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;###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)))

110
core/defuns.el Normal file
View file

@ -0,0 +1,110 @@
(provide 'defuns)
;; Convenience ;;;;;;;;;;;;;;;;;;;;;
(defun associate-mode (match mode)
(add-to-list 'auto-mode-alist (cons match mode)))
(defun associate-minor-mode (match mode)
(add-to-list 'auto-minor-mode-alist (cons match mode)))
(defmacro λ (&rest body)
`(lambda () (interactive) ,@body))
(defmacro add-hook! (hook &rest body)
`(add-hook ,hook (lambda() ,@body)))
;; Backwards compatibility
(unless (fboundp 'with-eval-after-load)
(defmacro with-eval-after-load (file &rest body)
`(eval-after-load ,file
`(funcall (function ,(lambda () ,@body))))))
(defmacro after (feature &rest forms)
`(,(if (or (not (boundp 'byte-compile-current-file))
(not byte-compile-current-file)
(if (symbolp feature)
(require feature nil :no-error)
(load feature :no-message :no-error)))
'progn
(message "after: cannot find %s" feature)
'with-no-warnings)
(with-eval-after-load ',feature ,@forms)))
;; Keybindings ;;;;;;;;;;;;;;;;;;;;;;;;;
(defun bind (state &rest keys)
(let ((state-list state)
(is-global (or (stringp state)
(vectorp state)))
keymap)
(if is-global
(setq keys (-insert-at 0 state keys))
(progn
(if (keymapp (car keys))
(setq keymap (pop keys)))
(if (or (keymapp state)
(not (listp state)))
(setq state-list (list state)))))
(while keys
(let ((-key (pop keys))
(-def (pop keys)))
(if (stringp -key)
(setq -key (kbd -key)))
(if is-global
(global-set-key -key -def)
(dolist (-state state-list)
(cond ((evil-state-p -state)
(define-key
(if keymap
(evil-get-auxiliary-keymap keymap -state t)
(evil-state-property -state :keymap t)) -key -def))
((keymapp -state)
(define-key -state -key -def)))))))))
(after "evil"
(evil-define-command my--maybe-exit-insert-mode ()
"Exits insert mode using jk without the momentary pause caused by
key-chord-define."
:repeat change
(interactive)
(let ((modified (buffer-modified-p)))
(insert "j")
(let ((evt (read-event nil nil 0.4)))
(cond
((null evt) (message ""))
((and (integerp evt) (char-equal evt ?k))
(delete-char -1)
(set-buffer-modified-p modified)
(push 'escape unread-command-events))
(t (setq unread-command-events (append unread-command-events (list evt)))))))))
;; Hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun enable-comment-hard-wrap ()
(set (make-local-variable 'comment-auto-fill-only-comments) t)
(turn-on-auto-fill))
(defun enable-tab-width-2 ()
(setq tab-width 2 evil-shift-width 2))
(defun disable-final-newline ()
(set (make-local-variable 'require-final-newline) nil))
(defun load-init-files ()
;; (mapc 'require io-modules)
(dolist (module my-modules)
(message "%s" (symbol-name module))
(with-demoted-errors "#### ERROR: %s"
(require module))))
;;;; Global Defuns ;;;;;;;;;;;;;;;;;;;;;
(defun my--minibuffer-quit ()
"Abort recursive edit. In Delete Selection mode, if the mark is
active, just deactivate it; then it takes a second \\[keyboard-quit]
to abort the minibuffer."
(interactive)
(if (and delete-selection-mode transient-mark-mode mark-active)
(setq deactivate-mark t)
(when (get-buffer "*Completions*")
(delete-windows-on "*Completions*"))
(abort-recursive-edit)))