(defconst is-mac (eq system-type 'darwin)) (defconst is-linux (eq system-type 'gnu/linux)) (defconst is-windows (eq system-type 'windows-nt)) (when is-linux (add-to-list 'load-path "~/.cask")) (setq use-package-verbose DEBUG-MODE) (cd "~") ; instead of / ;; 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) (setq electric-indent-chars '(? ?: ?{)) ;;; window layout undo/redo (setq winner-boring-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*" "*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*" "*Buffer List*" "*Ibuffer*" "*esh command on file*")) (winner-mode 1) (setq semanticdb-default-save-directory (expand-file-name "semanticdb" my-tmp-dir)) (semantic-mode 1) ;;; 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 '(trailing 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? Yay! (setq-default enable-recursive-minibuffers t) ;; 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 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) ;; Don't save clipboard contents into kill-ring before replacing them (setq save-interprogram-paste-before-kill nil) ;; don't let the cursor go into minibuffer prompt ;; Tip taken from Xah Lee: http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html (setq minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)) ;; remove annoying ellipsis when printing sexp in message buffer (setq eval-expression-print-length nil eval-expression-print-level nil) ;;;; 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 (require 'savehist) (setq savehist-file (concat my-tmp-dir "savehist") ; keep the home clean history-length 1000 savehist-additional-variables '(kill-ring global-mark-ring search-ring regexp-search-ring extended-command-history)) (savehist-mode 1) ;; Save cursor location across sessions (require 'saveplace) (setq-default save-place-file (concat my-tmp-dir "saveplace")) ;; activate save-place only for files that exist (add-hook 'find-file-hook (lambda() (if (file-exists-p buffer-file-name) (setq save-place t)))) (require 'recentf) (setq recentf-save-file (concat my-tmp-dir "recentf")) (setq recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last\\'" "\\.revive\\'", "/TAGS\\'")) (setq recentf-max-menu-items 0) (setq recentf-max-saved-items 1000) (setq recentf-auto-cleanup 'never) (add-hook 'kill-emacs-hook 'recentf-cleanup) (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 t) (setq-default tab-width 4) (setq require-final-newline t) (setq delete-trailing-lines nil) (add-hook 'makefile-mode-hook (lambda () (setq indent-tabs-mode t))) ; Use normal tabs in makefiles ;; Project defuns ;;;;;;;;;;;;;;;;;;;;;; (require 'f) (defvar project-root-files '(".git" ".hg" ".svn" ".project" "local.properties" "project.properties") "A list of files that count as 'project files', which determine whether a folder is the root of a project or not.") (defun project-root (&optional strict-p) "Get the path to the root of your project. Uses `project-root-files' to determine if a directory is a project." (catch 'found (f-traverse-upwards (lambda (path) (let ((path (file-truename path)) (home (file-truename "~"))) (if (f-equal? home path) (throw 'found (if strict-p nil default-directory)) (dolist (file project-root-files) (when (f-exists? (expand-file-name file path)) (throw 'found path)))))) default-directory) default-directory)) (defun project-has-files (files &optional root) "Return non-nil if `file' exists in the project root." (let ((root (or root (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 (f-exists? (project-path-to file root)))) found-p)) (defun project-path-to (file &optional root) (let ((root (or root (project-root)))) (expand-file-name file root))) (defun project-name () (file-name-nondirectory (directory-file-name (project-root)))) (defun project-p () (not (null (project-root t)))) ;; Make sure scratch buffer is always "in a project" (defvar project-scratch-buffer nil) (defun project-create-scratch-buffer () (let* ((scratch-buffer (get-buffer-create "*scratch*")) (project-name (project-name)) (root (project-root))) (mapc (lambda (b) (if (string-match-p "\\*scratch\\* (.+)" (buffer-name b)) (kill-buffer b))) (buffer-list)) (save-window-excursion (switch-to-buffer scratch-buffer) (setq project-scratch-buffer scratch-buffer) (erase-buffer) (cd root) (rename-buffer (format "*scratch* (%s)" project-name))))) (add-hook 'find-file-hook 'project-create-scratch-buffer) ;; 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-path () "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-path) ;;;; Utility plugins ;;;;;;;;;;;;;;;;;; (require 'defuns) (require 'autoloads) ; use make autoloads to generate autoloads file (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 :config (progn ; popwin config (popwin-mode 1) (setq popwin:popup-window-height 0.45) ;; (setq display-buffer-function 'popwin:display-buffer) (push '("\\`\\*helm.*?\\*\\'" :regexp t :position bottom :height 15) popwin:special-display-config) (push '("^\\*Flycheck.*\\*$" :regexp t :position bottom :height 0.25 :noselect t) popwin:special-display-config) (push '(inf-enh-ruby-mode :position bottom :stick t) popwin:special-display-config) (push '(snippet-mode :position bottom :stick t) popwin:special-display-config) (push '("^\\*eclim.*\\*" :regexp t :position bottom :height 0.25) popwin:special-display-config) (push '("*ansi-term*" :position bottom :height 0.45 :stick t) popwin:special-display-config) (push '("*terminal*" :position bottom :height 0.45 :stick t) popwin:special-display-config) (push '("*Async Shell Command*" :position bottom) popwin:special-display-config) (push '("*Shell Command Output*" :position bottom :stick t :height 15) popwin:special-display-config) (push '("* Regexp Explain *" :position top :height 0.35) popwin:special-display-config) (push '("*anaconda-doc*" :position bottom :height 15 :noselect t) popwin:special-display-config) (push '("*anaconda-nav*" :position bottom :height 15 :stick t) popwin:special-display-config) (push '("^\\*Python.+\\*$" :regexp t :position bottom :height 20 :noselect t) popwin:special-display-config) (push '(help-mode :height 0.5 :position bottom :stick t) popwin:special-display-config) (push '(compilation-mode :height 0.5 :position bottom :noselect t) popwin:special-display-config) (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) (push '(image-mode) popwin:special-display-config) (defun popwin:toggle-popup-window () (interactive) (if (popwin:popup-window-live-p) (popwin:close-popup-window) (popwin:popup-last-buffer))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (cond (is-mac (require 'core-osx)) (is-linux (require 'core-linux)) (is-windows (require 'core-windows))) (require 'server) (unless (server-running-p) (server-start))) (provide 'core) ;;; core.el ends here