;; setup packages (require 'package) (setq package-user-dir (expand-file-name "var/elpa" user-emacs-directory) package-enable-at-startup nil package-archives (append package-archives '(("melpa" . "https://melpa.milkbox.net/packages/")))) (package-initialize) (unless package-archive-contents (message "Refreshing ELPA package archives...") (package-refresh-contents)) ;; install the package 'use-package' unless it's already installed (unless (package-installed-p 'use-package) (progn (package-install 'use-package))) ;; ... and load 'use-package' (require 'use-package) (use-package settings :load-path (lambda () (expand-file-name "lib" user-emacs-directory))) (use-package funcs ;; Contains some functions :load-path (lambda () (expand-file-name "lib" user-emacs-directory)) :commands (fc/load-time) :bind (("s-=" . fc/scale-up-font) ("s--" . fc/scale-down-font) ("s-0" . fc/reset-font-size))) (use-package basic-theme ;; this is my own custom theme. No syntax highlighting :load-path (lambda () (expand-file-name "lib" user-emacs-directory)) :config (load-theme 'basic t)) (use-package bindings ;; my own custom bindings :load-path (lambda () (expand-file-name "lib" user-emacs-directory))) (use-package server ;; start emacs server if not already running :config (unless (server-running-p) (server-start))) (use-package diminish ;; remove clutter from the mode line :ensure t) (use-package ag ;; interface to the 'ag' tool :ensure t :commands (counsel-ag ag) :init (setq ag-reuse-buffers t ag-reuse-window t)) (use-package autorevert ;; automatically revert the buffer if the content changed on disk :diminish auto-revert-mode) (use-package counsel ;; completion functions for ivy :ensure t :bind* (("M-x" . counsel-M-x) ("C-s" . counsel-grep-or-swiper) ("C-x C-f" . counsel-find-file) ("C-x C-r" . counsel-recentf) ("C-c f" . counsel-git) ("C-c s" . counsel-git-grep) ("C-c /" . counsel-ag)) :config (setq counsel-find-file-at-point t)) (use-package dired ;; configuration for dired :bind ("C-x C-d" . dired) :config (let ((gls "/opt/twitter/bin/gls")) (if (file-exists-p gls) (setq insert-directory-program gls dired-listing-switches "-aBhl --group-directories-first"))) (use-package dired-x :init (add-hook 'dired-load-hook (lambda () (load "dired-x"))) :config (add-hook 'dired-mode-hook #'dired-omit-mode) (setq dired-omit-verbose nil) (setq dired-omit-files (concat dired-omit-files "\\|^.DS_Store$\\|^.projectile$\\|^.git$")))) (use-package dockerfile-mode ;; support for dockerfile mode :ensure t) (use-package lisp-mode ;; simple configuration for various lisp mode :config (add-hook 'emacs-lisp-mode-hook (lambda() (setq mode-name "λ")))) (use-package eldoc ;; documentation with eldoc :ensure t :commands eldoc-mode :diminish "" :init (add-hook 'emacs-lisp-mode-hook 'eldoc-mode) (add-hook 'lisp-interaction-mode-hook 'eldoc-mode)) (use-package eshell ;; configuration for eshell :ensure t :bind ("C-x e" . eshell) :init (progn (setq eshell-directory-name (expand-file-name "var/eshell/" user-emacs-directory)) (add-hook 'eshell-mode-hook '(lambda ()(exec-path-from-shell-initialize))) (add-hook 'eshell-mode-hook (lambda () (setenv "PAGER" "less") (setenv "EDITOR" "emacsclient")))) :config (progn (use-package em-term :defer t :config (setq eshell-destroy-buffer-when-process-dies t eshell-visual-commands (append '("less" "tmux" "ssh" "htop" "top") eshell-visual-commands))))) (use-package exec-path-from-shell ;; environment fixup for macOS. :ensure t :if (and (eq system-type 'darwin) (display-graphic-p)) :init (setq exec-path-from-shell-check-startup-files nil) (exec-path-from-shell-initialize) :config (setq exec-path-from-shell-debug t)) (use-package flycheck ;; check syntax :ensure t :config (progn (use-package flycheck-pos-tip :ensure t :config (setq flycheck-display-errors-function #'flycheck-pos-tip-error-messages) :init (flycheck-pos-tip-mode)) (add-hook 'prog-mode-hook 'flycheck-mode) (setq-default flycheck-disabled-checkers '(emacs-lisp-checkdoc)) (setq flycheck-highlighting-mode 'lines) (setq flycheck-check-syntax-automatically '(mode-enabled save)) (defun check-source-predicate () (and (executable-find "check.pex") (buffer-file-name) (string-match "src/source/.*\.py$" (buffer-file-name)))) ;;; errors are reported like this: ;;; E241:ERROR : (flycheck-define-checker source-check "A syntax checker for python source code in Source, using `check.pex'" :command ("check.pex" source) :error-patterns ((error line-start (id (1+ nonl)) ":ERROR" (1+ nonl) ":" line (message) line-end) (warning line-start (id (1+ nonl)) ":WARNING" (1+ nonl) ":" line (message) line-end)) :predicate check-source-predicate :modes (python-mode)) (add-to-list 'flycheck-checkers 'source-check) (defun fc/flycheck-modeline (errors-count warnings-count info-count) (concat (propertize (format "•%s " errors-count) 'face '(:foreground "#A20C41")) (propertize (format "•%s " warnings-count) 'face '(:foreground "#968B26")) (propertize (format "•%s " info-count) 'face '(:foreground "#21889B")))) (setq flycheck-mode-line '(:eval (pcase flycheck-last-status-change (`finished (let* ((count (flycheck-count-errors flycheck-current-errors)) (errors-count (cdr (assq 'error count))) (warnings-count (cdr (assq 'warning count))) (info-count (cdr (assq 'info count)))) (fc/flycheck-modeline (or errors-count 0) (or warnings-count 0) (or info-count 0)))) ;; the default is to show ? for the count (_ (fc/flycheck-modeline "?" "?" "?"))))))) (use-package flyspell ;; check the spelling :ensure t :init (progn (setq ispell-program-name "aspell" ispell-list-command "--list") (add-hook 'text-mode-hook 'flyspell-mode)) :config (use-package flyspell-popup :ensure t :bind ("C-:" . flyspell-popup-correct))) (use-package geiser ;; to work with various schemes :ensure t :config (progn (setq geiser-default-implementation 'racket geiser-racket-binary "~/src/devbox/racket/racket-repl.sh"))) (use-package gist ;; interface to gist.github.com :ensure t :bind ("C-c G" . gist-region-or-buffer)) (use-package go-mode ;; support for go :mode (("\\.go\\'" . go-mode)) :ensure t :config (when (memq window-system '(mac ns x)) (dolist (var '("GOPATH")) (unless (getenv var) (exec-path-from-shell-copy-env var)))) (use-package go-eldoc :ensure t :config (add-hook 'go-mode-hook 'go-eldoc-setup)) (use-package gotest :ensure t) (add-hook 'before-save-hook 'gofmt-before-save) (add-hook 'go-mode-hook (lambda () (setq-local tab-width 4)))) (use-package hl-line ;; highlight current line :defer t :init (progn (add-hook 'text-mode-hook 'hl-line-mode) (add-hook 'prog-mode-hook 'hl-line-mode))) (use-package ibuffer ;; configuration for ibuffer :ensure t :defer t :bind ("C-x C-b" . ibuffer) :init (setq ibuffer-show-empty-filter-groups nil ibuffer-saved-filter-groups (quote (("default" ("dired" (mode . dired-mode)) ("elisp" (mode . emacs-lisp-mode)) ("emacs" (or (name . "^\\*.*\\*$") (mode . fundamental-mode))) ("go" (mode . go-mode)) ("java" (mode . java-mode)) ("json" (mode . json-mode)) ("lisp" (mode . lisp-mode)) ("magit" (mode . magit-mode)) ("puppet" (mode . puppet-mode)) ("python" (mode . python-mode)) ("repl" (name . "repl")) ("ruby" (mode . ruby-mode)) ("sh" (mode . sh-mode)) ("text" (mode . text-mode)))))) (add-hook 'ibuffer-mode-hook ;; organise by filter-groups '(lambda () (ibuffer-auto-mode 1) (setq mode-name "≣") (ibuffer-switch-to-saved-filter-groups "default")))) (use-package ivy ;; completion system :diminish (ivy-mode . "") :bind ("C-c m" . ivy-switch-project) :config (ivy-mode 1) (setq ivy-use-virtual-buffers t ivy-height 10 ivy-count-format "(%d/%d) " ivy-initial-inputs-alist nil ivy-use-ignore-default 'always ivy-ignore-buffers '("company-statistics-cache.el" "company-statistics-autoload.el") ivy-re-builders-alist '((swiper . ivy--regex-ignore-order) (t . ivy--regex-fuzzy) (t . ivy--regex-ignore-order))) (defun ivy-switch-project () (interactive) (ivy-read "Switch to project: " (if (projectile-project-p) (cons (abbreviate-file-name (projectile-project-root)) (projectile-relevant-known-projects)) projectile-known-projects) :action #'projectile-switch-project-by-name)) (ivy-set-actions 'ivy-switch-project '(("d" dired "Open Dired in project's directory") ("v" counsel-projectile "Open project root in vc-dir or magit") ("c" projectile-compile-project "Compile project") ("r" projectile-remove-known-project "Remove project(s)")))) (use-package json-mode ;; mode to support json files :ensure t :mode "\\.json\\'" :config (setq json-reformat:indent-width 2)) (use-package magit ;; interface to git :ensure t :bind (("C-x g s" . magit-status) ("C-x g b" . magit-checkout)) :init (progn (setq magit-completing-read-function 'ivy-completing-read)) :config (progn (global-git-commit-mode) (use-package git-commit :ensure t :defer t) (setq magit-display-buffer-function 'magit-display-buffer-fullframe-status-v1) (add-hook 'magit-mode-hook (lambda() (setq mode-name "⎇"))) (add-hook 'magit-log-edit-mode-hook #'(lambda () (set-fill-column 72) (flyspell-mode))))) (use-package make-mode ;; mode to support Makefile :config (add-hook 'makefile-mode-hook #'(lambda () (setq-local tab-width 2)))) (use-package markdown-mode ;; mode to support files in the Markdown format :ensure t :commands (markdown-mode gfm-mode) :mode (("\\.md\\'" . gfm-mode) ("\\.markdown\\'" . gfm-mode)) :init (setq markdown-command "pandoc -f markdown_github -c https://goo.gl/OVmlwT --self-contained") :config (add-hook 'gfm-mode-hook 'visual-line-mode)) (use-package midnight ;; clean old buffers at midnight :ensure t) (use-package pants ;; interface to pants :load-path (lambda () (expand-file-name "~/src/pants.el/")) :config (setq pants-completion-system 'ivy pants-source-tree-root "/Users/fcuny/src/source" pants-bury-compilation-buffer t pants-extra-args "-q") :bind (("C-c b" . pants-find-build-file) ("C-c r" . pants-run-binary) ("C-c t" . pants-run-test))) (use-package phabricator ;; interface to phabricator :load-path (lambda () (expand-file-name "~/src/phabricator.el/")) :config (setq diffusion-repo-prefix-list '(("source" "source")))) (use-package projectile ;; library to interact with projects :ensure t :diminish "" :bind-keymap ("C-c p" . projectile-command-map) :init (add-hook 'after-init-hook #'projectile-mode) :config (use-package counsel-projectile :ensure t) (setq projectile-switch-project-action 'projectile-dired projectile-enable-caching t projectile-completion-system 'ivy projectile-known-projects-file (expand-file-name "var/projectile-bookmarks.eld" user-emacs-directory) projectile-cache-file (expand-file-name "var/projectile.cache" user-emacs-directory)) (add-to-list 'projectile-globally-ignored-files ".DS_Store")) (use-package puppet-mode ;; mode to support puppet and work with puppet :ensure t :mode ("\\.pp\\'" . puppet-mode) :init (add-hook 'puppet-mode-hook 'flycheck-mode) :config (when (memq window-system '(mac ns x)) (dolist (var '("GEM_HOME" "GEM_PATH" "MY_RUBY_HOME")) (unless (getenv var) (exec-path-from-shell-copy-env var)))) (setq flycheck-puppet-lint-rc "/Users/fcuny/src/twitter-ops/utilities/puppet/.puppet-lint.rc")) (use-package python ;; configuration for Python :mode(("\\.aurora$" . python-mode) ("BUILD$" . python-mode) ("\\.py$" . python-mode)) :interpreter ("python" . python-mode) :init (setq-default indent-tabs-mode nil) :config (setq python-indent-offset 2) (add-hook 'python-mode-hook 'eldoc-mode t) (add-hook 'python-mode-hook 'color-identifiers-mode)) (use-package recentf ;; configuration for recentf, to interact with recent files :config (setq recentf-save-file (expand-file-name "var/recentf" user-emacs-directory))) (use-package sh-script ;; configuration to interact with shell scripts :mode ("bashrc" . sh-mode) :config (defun set-sh-mode-indent () (setq sh-basic-offset 2 sh-indentation 2)) (add-hook 'sh-mode-hook 'set-sh-mode-indent) (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)) (use-package spaceline ;; configure the modeline :ensure t) (use-package spaceline-config ;; configuration for the modeline :ensure nil :after spaceline :config ;; colors (set-face-attribute 'powerline-active1 nil :background "grey22" :foreground "white" :inherit `mode-line) (set-face-attribute 'powerline-active2 nil :background "grey40" :foreground "white" :inherit `mode-line) (set-face-attribute 'powerline-inactive1 nil :background "grey22" :foreground "white" :inherit `mode-line-inactive) (set-face-attribute 'powerline-inactive2 nil :background "grey40" :foreground "white" :inherit `mode-line-inactive) (set-face-attribute (spaceline-highlight-face-default) nil :background "grey22" :foreground "white" :inherit `mode-line) (setq-default powerline-default-separator 'arrow) (spaceline-define-segment line-column "The current line and column numbers." "%2l : %2c") (spaceline-define-segment time "The current time." (format-time-string "%H:%M")) (spaceline-toggle-time-on) (spaceline-toggle-buffer-encoding-abbrev-off) (spaceline-toggle-flycheck-warning-off) (spaceline-toggle-flycheck-error-off) (spaceline-toggle-flycheck-info-off) (spaceline-toggle-buffer-modified-on) (spaceline-toggle-buffer-size-off) (spaceline-toggle-buffer-position-off) (spaceline-toggle-hud-off) (spaceline-emacs-theme 'projectile-root 'time)) (use-package swiper ;; install swiper :ensure t) (use-package term ;; configuration to manage multiple terminals inside emacs :bind (("C-x t" . fc/open-term) ("C-x m" . fc/switch-to-term-buffer)) :config (progn (defun fc/make-term (new-buffer-name cmd &rest switches) (setq term-ansi-buffer-name (concat "<" new-buffer-name ">")) (setq term-ansi-buffer-name (generate-new-buffer-name term-ansi-buffer-name)) (setq term-ansi-buffer-name (apply 'make-term term-ansi-buffer-name cmd nil switches)) (set-buffer term-ansi-buffer-name) (term-mode) (term-char-mode) (term-set-escape-char ?\C-x) (switch-to-buffer term-ansi-buffer-name)) (defun fc/open-term (name) (interactive "sName: ") (fc/make-term name "bash")) (defun fc/list-term-buffers () "Returns a list of term buffers" (delq nil (mapcar (lambda(x) (set-buffer x) (when (string= major-mode "term-mode") (buffer-name))) (buffer-list)))) (defun fc/switch-to-term-buffer () "Switch to a term buffer." (interactive) (let ((collection (fc/list-term-buffers))) (ivy-read "term buffers:" collection :action (lambda (x) (switch-to-buffer x)) :caller 'fc/find-term-buffers))))) (use-package thrift ;; mode to work with thrift files :ensure t :mode ("\\.thrift\\'" . thrift-mode) :config (setq thrift-indent-level 2)) (use-package tramp ;; configuration for tramp :config (setq tramp-default-method "ssh" tramp-persistency-file-name (expand-file-name "var/tramp" user-emacs-directory))) (use-package whitespace ;; highlight white spaces :config (setq whitespace-style '(face trailing tabs)) (add-hook 'prog-mode-hook 'whitespace-mode)) (use-package yaml-mode ;; mode to work wity YAML files :ensure t :init (add-hook 'yaml-mode-hook 'flycheck-mode) :mode ("\\.ya?ml\\'" . yaml-mode)) (add-hook 'emacs-startup-hook #'fc/load-time)