;; Initialise the package system first of all. (require 'package) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t) (defvar fcuny-path-emacs-var (expand-file-name "var" user-emacs-directory) "Path to some files for Emacs.") (defvar fcuny-path-emacs-elpa (expand-file-name "elpa" fcuny-path-emacs-var) "Path to elpa's local files.") ;; where to store the packages (setq package-user-dir fcuny-path-emacs-elpa) ;; initialize it (package-initialize) ;; if use-package is not present, we install it (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (require 'use-package) (defvar fcuny-path-home (getenv "HOME") "Path to the user's home directory.") (defvar fcuny-path-workspace (expand-file-name "workspace" fcuny-path-home) "Path to the workspace.") (defvar fcuny-path-go (expand-file-name "go" fcuny-path-workspace) "Path to GOPATH.") (defvar fcuny-path-go-bin (expand-file-name "bin" fcuny-path-go) "Path to the go binaries.") (defvar fcuny-path-puppet-linter-svn (expand-file-name "twitter-ops/utilities/puppet/.puppet-lint.rc" fcuny-path-workspace) "Path to the linter's configuration for twitter-ops.") (defvar fcuny-projects-ignored-dirs '(".git" ".svn" "target" "elpa") "Ignore the following directories when browsing with projectile.") (defvar fcuny-bookmarks-dir (expand-file-name "bookmarks" fcuny-path-emacs-var) "Path to save the bookmarks") (defvar fcuny-custom-settings (expand-file-name "emacs-custom.el" fcuny-path-emacs-var) "Path to emacs custom variables.") (defun fc/rename-this-buffer-and-file () "Renames current buffer and file it is visiting." (interactive) (let ((name (buffer-name)) (filename (buffer-file-name)) (read-file-name-function 'read-file-name-default)) (if (not (and filename (file-exists-p filename))) (error "Buffer '%s' is not visiting a file!" name) (let ((new-name (read-file-name "New name: " filename))) (cond ((get-buffer new-name) (error "A buffer named '%s' already exists!" new-name)) (t (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil) (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name)))))))) (defun fc/check-work-machine-p () "Returns t if this is a work machine" (string-match "tw-mbp.*" (system-name))) (defun fc/check-source-p () "Finds if the current python file is in the `source' repository." (and (executable-find "check.pex") (buffer-file-name) (string-match "source/.*\.py$" (buffer-file-name)))) ;; set utf-8 as the default encoding (prefer-coding-system 'utf-8-unix) (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) ;; alias yes-or-no to y-or-n (fset 'yes-or-no-p 'y-or-n-p) (setq auto-save-default nil) ;; don't auto save files (setq auto-save-list-file-prefix nil) ;; no backups (setq create-lockfiles nil) ;; don't use a lock file (setq custom-file fcuny-custom-settings) ;; where to save custom settings (setq make-backup-files nil) ;; really no backups (setq minibuffer-message-timeout 0.5) ;; How long to display an echo-area message (setq next-screen-context-lines 5) ;; scroll 5 lines at a time (setq require-final-newline t) ;; ensure newline exists at the end of the file (setq ring-bell-function 'ignore) ;; really no bell (setq tab-always-indent 'complete) ;; when using TAB, always indent (setq visible-bell nil) ;; no bell (setq column-number-mode t) ;; show column number in the mode line (setq use-package-always-ensure t) ;; always ensure packages are present (setq-default indent-tabs-mode nil) ;; turn off tab indentation (setq-default cursor-type 'hbar) ;; cursor is a horizontal bar (set-face-attribute 'default nil :height 130 :weight 'normal :width 'normal) (fringe-mode '(8 . 8)) ;; size of the fringe (global-set-key (kbd "M-j") 'join-line) ;; Remap join-line to M-j where it's easier to get to. (global-set-key (kbd "") 'toggle-frame-fullscreen) ;; Shift-Return switch to full-screen (custom-set-variables '(tool-bar-mode nil) '(scroll-bar-mode nil) '(use-file-dialog nil) '(use-dialog-box nil) '(blink-cursor-mode nil) '(inhibit-startup-screen t) '(inhibit-startup-message t) '(inhibit-startup-echo-area-message t)) ;; when using darwin, I don't want to use the native fullscreen mode (it opens a new workspace) (when (eq system-type 'darwin) (setq ns-use-native-fullscreen nil)) (use-package auto-package-update :custom (auto-package-update-delete-old-versions t) (auto-package-update-hide-results t) (auto-package-update-last-update-day-filename (expand-file-name "last-package-update-day" fcuny-path-emacs-var)) :hook (after-init . auto-package-update-maybe)) (use-package bookmark :custom (bookmark-default-file fcuny-bookmarks-dir) (bookmark-save-flag 1)) (use-package autorevert :config (global-auto-revert-mode t)) (use-package midnight :config (midnight-mode t)) (use-package autorevert :config (setq global-auto-revert-non-file-buffers t) (setq auto-revert-verbose nil) (global-auto-revert-mode t)) (use-package recentf :config (setq recentf-save-file (expand-file-name "var/recentf" user-emacs-directory))) (use-package server :if window-system :init (add-hook 'after-init-hook 'server-start)) (use-package hl-line :config (global-hl-line-mode t)) (use-package tramp :custom (tramp-default-method "ssh") (tramp-persistency-file-name (expand-file-name "var/tramp" user-emacs-directory))) (use-package whitespace :custom (whitespace-style '(face trailing)) (show-trailing-whitespace t) :hook (whitespace-mode)) (use-package counsel :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)) :custom (counsel-find-file-at-point t) :config (use-package swiper) (use-package counsel-projectile)) (use-package ivy :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 projectile :diminish projectile-mode :bind-keymap ("C-c p" . projectile-command-map) :init (add-hook 'after-init-hook #'projectile-mode) :config (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) projectile-globally-ignored-directories (append fcuny-projects-ignored-dirs projectile-globally-ignored-directories) projectile-globally-ignored-files (append projectile-globally-ignored-files))) (use-package ag :bind (:map ag-mode-map ("p" . compilation-previous-error) ("n" . compilation-next-error) ("N" . compilation-next-file) ("P" . compilation-previous-file)) :custom (ag-highlight-search t) (ag-reuse-buffers t) (ag-reuse-window t)) (use-package dired :ensure nil :defer t :bind ("C-x C-d" . dired) :init (setq-default dired-dwim-target t) (setq dired-recursive-deletes 'always) (setq dired-recursive-copies 'always) (let ((gls (executable-find "/opt/twitter/bin/gls"))) (when gls (setq insert-directory-program gls)))) (use-package ibuffer :bind ("C-x C-b" . ibuffer)) (use-package flycheck :config (progn (add-hook 'prog-mode-hook 'flycheck-mode) (setq flycheck-highlighting-mode 'lines) (setq flycheck-check-syntax-automatically '(mode-enabled save)) (setq flycheck-checkers (delq 'emacs-lisp-checkdoc flycheck-checkers)) (if (fc/check-work-machine-p) (flycheck-define-checker fc/twitter-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 fc/check-source-p :modes (python-mode)) (add-to-list 'flycheck-checkers 'fc/twitter-source-check)))) (use-package ispell :config (when (executable-find "aspell") (setq ispell-program-name "aspell" ispell-list-command "--list"))) (use-package flyspell-correct) (use-package flyspell :hook ((text-mode-hook . flyspell-mode) (prog-mode-hook . flyspell-prog-mode))) (use-package markdown-mode :after (flyspell) :mode (("\\.md\\'" . gfm-mode) ("\\.markdown\\'" . gfm-mode)) :hook (markdown-mode . flyspell-mode) :init (setq markdown-command "pandoc -f markdown_github -c https://goo.gl/OVmlwT --self-contained" markdown-header-scaling 't) :config (add-hook 'gfm-mode-hook 'visual-line-mode)) (use-package exec-path-from-shell :if (memq window-system '(mac ns)) :config (exec-path-from-shell-initialize) (if (fc/check-work-machine-p) (dolist (var '("GEM_HOME" "GEM_PATH" "MY_RUBY_HOME")) (unless (getenv var) (exec-path-from-shell-copy-env var))))) ;; auto close bracket, parenthesis insertion (electric-pair-mode 1) (use-package paren :custom (show-paren-delay 0) :config (show-paren-mode 1)) (use-package lisp-mode :ensure f :bind (("C-c C-e" . eval-buffer) ("C-c C-r" . eval-region))) (use-package eldoc :ensure t :hook (emacs-lisp-mode-hook)) (use-package pants :load-path (lambda () (expand-file-name "github.com/fcuny/pants.el/" fcuny-path-workspace)) :custom (pants-completion-system 'ivy) (pants-source-tree-root (expand-file-name "git.twitter.biz/source" fcuny-path-workspace)) (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)) :init (if (fc/check-work-machine-p) (add-to-list 'auto-mode-alist '("BUILD" . python-mode)))) (use-package make-mode :ensure t :config (add-hook 'makefile-mode-hook (lambda () (setq-local tab-width 2)))) (use-package company :ensure t :diminish company-mode :config (global-company-mode) (setq company-global-modes '(not term-mode) company-idle-delay 0.3 company-minimum-prefix-length 3 company-selection-wrap-around t company-show-numbers t company-tooltip-align-annotations t company-require-match nil)) (use-package magit :ensure t :mode (("differential-update-comments" . git-commit-mode) ("new-commit" . git-commit-mode)) :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) ;; I don't care about other VC backend for work (if (fc/check-work-machine-p) (setf vc-handled-backends nil vc-follow-symlinks t)) (use-package git-commit :ensure t) (add-hook 'magit-log-edit-mode-hook #'(lambda () (set-fill-column 72) (flyspell-mode))))) (use-package go-mode :ensure t :after (company flycheck) :preface (defun fcuny/go-mode-setup () (add-hook 'go-mode-hook 'flycheck-mode) (setq-default) (setq tab-width 2)) :config (add-hook 'go-mode-hook #'fcuny/go-mode-setup)) (use-package go-eldoc :after go-mode :ensure t :hook (go-mode . go-eldoc-setup)) (use-package gotest :ensure t) (use-package go-guru :ensure t) (use-package go-imports :ensure t) (use-package golint :ensure t) (use-package go-projectile :ensure t) (use-package company-go :ensure t :after (company go-mode) :custom (company-go-show-annotation t) :config (add-hook 'go-mode-hook 'company-mode) (add-to-list 'company-backends 'company-go)) (use-package python :mode (("\\.py$" . python-mode)) :ensure t :commands python-mode :custom (python-indent-offset 2)) (use-package anaconda-mode :ensure t :after python :hook ((python-mode . anaconda-mode) (python-mode . eldoc-mode)) :custom (anaconda-mode-eldoc-as-single-line t)) (use-package company-anaconda :ensure t :after anaconda-mode :init (add-to-list 'company-backends 'company-anaconda)) (use-package scala-mode :ensure t) (use-package sh-script :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 dockerfile-mode :ensure t) (use-package puppet-mode :ensure t :mode ("\\.pp\\'" . puppet-mode) ;:hook (flycheck-mode) :config (if (fc/check-work-machine-p) (setq flycheck-puppet-lint-rc fcuny-path-puppet-linter-svn))) (use-package yaml-mode :ensure t :after (flycheck flyspell) :mode (("\\.yml?\\'" . yaml-mode) ("\\.yaml?\\'" . yaml-mode)) :hook ((yaml-mode . flycheck-mode) (yaml-mode . flyspell-prog-mode))) (use-package json-mode :ensure t :after (flycheck flyspell) :custom (json-reformat:indent-width 2) (js-indent-level 2) :hook ((json-mode . flyspell-prog-mode) (json-mode . flycheck-mode)) :init (if (fc/check-work-machine-p) (add-to-list 'auto-mode-alist '("\\.workflow$" . json-mode)))) (use-package thrift :ensure t :after (flycheck flyspell) :custom (thrift-indent-level 2) :hook ((thrift . flyspell-prog-mode) (thrift . flycheck-mode))) (use-package protobuf-mode :ensure t :after (flycheck flyspell) :hook ((protobuf-mode . flyspell-prog-mode) (protobuf-mode . flycheck-mode)))