summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <davet@gnu.org>2015-05-23 20:23:25 -0400
committerDavid Thompson <davet@gnu.org>2015-05-23 20:24:47 -0400
commit74e7e843c2e734a62716722339bf41af488cfcb0 (patch)
treeac851e32c10231cecd264b6dd62c0ee2d7a1dc3f
parent606ec63191f54758ee5da58caa0677b21f9d03ac (diff)
emacs: Add config.
-rw-r--r--dotfiles/.emacs.d/erc.el113
-rw-r--r--dotfiles/.emacs.d/init.el447
2 files changed, 560 insertions, 0 deletions
diff --git a/dotfiles/.emacs.d/erc.el b/dotfiles/.emacs.d/erc.el
new file mode 100644
index 0000000..3709f55
--- /dev/null
+++ b/dotfiles/.emacs.d/erc.el
@@ -0,0 +1,113 @@
+(require 'erc)
+(require 'erc-log)
+(require 'erc-notify)
+(require 'erc-spelling)
+(require 'erc-autoaway)
+(require 'erc-services)
+(require 'notifications)
+
+;; Notify the user of private messages
+(defun erc-private-message-notify (proc parsed)
+ (let ((nick (car (erc-parse-user (erc-response.sender parsed))))
+ (target (car (erc-response.command-args parsed)))
+ (msg (erc-response.contents parsed)))
+ (notifications-notify :title nick :body msg)))
+
+;; (add-hook 'erc-server-PRIVMSG-functions 'erc-private-message-notify)
+
+;; Notify the user when their nick is mentioned
+(defun erc-nick-mentioned-notify (match-type nick message)
+ "Shows a notification when user's nick is mentioned."
+ (when (and (not (posix-string-match "^\\** *Users on #" message))
+ (eq math-type 'current-nick))
+ (notifications-notify
+ :title nick
+ :body message
+ :app-icon "/usr/share/notify-osd/icons/gnome/scalable/status/notification-message-im.svg"
+ :urgency 'low)))
+
+;; (add-hook 'erc-text-matched-hook 'erc-nick-mentioned-notify)
+
+;; Nickname
+(setq erc-nick "davexunit")
+
+;; Interpret mIRC-style color commands in IRC chats
+(setq erc-interpret-mirc-color t)
+
+;; The following are commented out by default, but users of other
+;; non-Emacs IRC clients might find them useful.
+;; Kill buffers for channels after /part
+(setq erc-kill-buffer-on-part t)
+;; Kill buffers for private queries after quitting the server
+(setq erc-kill-queries-on-quit t)
+;; Kill buffers for server messages after quitting the server
+(setq erc-kill-server-buffer-on-quit t)
+
+;; open query buffers in the current window
+(setq erc-query-display 'buffer)
+
+;; exclude boring stuff from tracking
+(erc-track-mode t)
+(setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
+ "324" "329" "332" "333" "353" "477"))
+
+;; logging
+(setq erc-log-channels-directory "~/.erc/logs/")
+
+(if (not (file-exists-p erc-log-channels-directory))
+ (mkdir erc-log-channels-directory t))
+
+(setq erc-save-buffer-on-part t)
+
+;; truncate long irc buffers
+(erc-truncate-mode 1)
+
+;; enable spell checking
+(erc-spelling-mode 0)
+
+;; utf-8 always and forever
+(setq erc-server-coding-system '(utf-8 . utf-8))
+
+;; Auto-join channels
+(erc-autojoin-mode t)
+(setq erc-autojoin-channels-alist
+ '(("freenode.net" "#libre.fm" "#guile" "#guix" "#gnu"
+ "#gnu-webmasters" "#emacs" "#scheme" "#lispgames" "#fsf"
+ "#fsfsys" "#fsf-office" "#fsf-campaigns" "#fsf-licensing"
+ "#libreplanet" "##wizards" "#tox" "#tox-dev" "#sly")))
+;; Don't open channel buffers in place of the current buffer because
+;; that drives me fucking crazy.
+(setq erc-join-buffer 'bury)
+
+;; Secret password file
+(load "~/.emacs.d/.ercpasswords")
+
+;; Stuff to make authenticating with Rizon work
+(erc-services-mode t)
+(setq erc-prompt-for-nickserv-password nil)
+(setq erc-nickserv-identify-mode 'autodetect)
+(setq erc-nickserv-passwords
+ `((Rizon (("davexunit" . ,rizon-password)))))
+
+;; Start and stop erc
+(defun start-irc ()
+ "Connect to IRC."
+ (interactive)
+ (erc :server "irc.freenode.net"
+ :port 6667
+ :nick erc-nick
+ :password freenode-password))
+
+(defun filter-erc-server-buffers ()
+ (delq nil
+ (mapcar
+ (lambda (x) (and (erc-server-buffer-p x) x))
+ (buffer-list))))
+
+(defun stop-irc ()
+ "Disconnects from all irc servers"
+ (interactive)
+ (dolist (buffer (filter-erc-server-buffers))
+ (message "Server buffer: %s" (buffer-name buffer))
+ (with-current-buffer buffer
+ (erc-quit-server "Later"))))
diff --git a/dotfiles/.emacs.d/init.el b/dotfiles/.emacs.d/init.el
new file mode 100644
index 0000000..bdfcd9c
--- /dev/null
+++ b/dotfiles/.emacs.d/init.el
@@ -0,0 +1,447 @@
+;; Turn off mouse interface early in startup to avoid momentary display
+(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
+(if (fboundp 'menu-bar-mode) (menu-bar-mode -1))
+(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
+
+;; No splash screen.
+(setq inhibit-startup-message t)
+
+;; Use /bin/sh for shell.
+;;
+;; I like to use fish shell as my login shell, but there are
+;; incompatibilities with its scripting language.
+(setq shell-file-name "/bin/bash")
+
+;; Use screen in ansi-term and co.
+(setq explicit-shell-file-name "/usr/bin/screen")
+
+;;;
+;;; Packages
+;;;
+
+(require 'package)
+(add-to-list 'package-archives
+ '("melpa" . "http://melpa.milkbox.net/packages/") t)
+(package-initialize)
+
+;; Additional packages that I use.
+(setq required-packages
+ '(better-defaults
+ elfeed
+ emms
+ geiser
+ ido-ubiquitous
+ js2-mode
+ magit
+ notmuch
+ notmuch-unread
+ paredit
+ rainbow-delimiters
+ smex
+ web-mode
+ flx-ido
+ projectile
+ notmuch-unread))
+
+(defun install-missing-packages ()
+ "Install all required packages that haven't been installed."
+ (interactive)
+ (mapc (lambda (package)
+ (unless (package-installed-p package)
+ (package-install package)))
+ required-packages)
+ (message "Installed all missing packages!"))
+
+;;;
+;;; Look and Feel
+;;;
+
+(set-default-font "Inconsolata-11")
+(load-theme 'wombat t)
+(column-number-mode t)
+(which-function-mode t)
+
+(defun change-theme (theme)
+ "Disable all active themes and load THEME."
+ (interactive
+ (lexical-let ((themes (mapcar 'symbol-name (custom-available-themes))))
+ (list (intern (completing-read "Load custom theme: " themes)))))
+ (mapc 'disable-theme custom-enabled-themes)
+ (load-theme theme t))
+
+;;;
+;;; Dired
+;;;
+
+(require 'dired-x)
+
+;;;
+;;; Battery
+;;;
+
+(require 'battery)
+
+;; Display battery level in modeline only if a battery is present,
+;; otherwise display-battery-mode will throw an error.
+(when (and (boundp 'battery-status-function)
+ (not (null battery-status-function))
+ (not (string-match-p
+ "N/A"
+ (battery-format
+ "%B"
+ (funcall battery-status-function)))))
+ (display-battery-mode t))
+
+;;;
+;;; Buffers
+;;;
+
+;; ido is awesome for the minibuffer.
+(setq ido-everywhere t)
+(setq ido-enable-flex-matching t)
+(ido-mode t)
+(ido-ubiquitous-mode t)
+(flx-ido-mode t)
+
+;; Ignore compiled Guile files. This has the side-effect of looking
+;; like I hate GoLang.
+(setq ido-ignore-files (cons "\\.go$" ido-ignore-files))
+
+(projectile-global-mode)
+
+;; Remember open buffers for next session.
+(desktop-save-mode t)
+
+;; Kill buffers that haven't been modified in awhile.
+(require 'midnight)
+
+;; Save point position between sessions
+(require 'saveplace)
+(setq-default save-place t)
+(setq save-place-file (expand-file-name ".places" user-emacs-directory))
+
+(defun cleanup-buffer-safe ()
+ "Perform a bunch of safe operations on the whitespace content of a buffer.
+Does not indent buffer, because it is used for a before-save-hook, and that
+might be bad."
+ (interactive)
+ (delete-trailing-whitespace)
+ (set-buffer-file-coding-system 'utf-8))
+
+;; Various superfluous white-space. Just say no.
+(add-hook 'before-save-hook 'cleanup-buffer-safe)
+
+;; Snippets.
+(auto-insert-mode t)
+
+(setq ibuffer-saved-filter-groups
+ '(("default"
+ ("guile-2d" (filename . "Code/guile-2d/"))
+ ("dired" (mode . dired-mode))
+ ("org" (mode . org-mode))
+ ("erc" (mode . erc-mode)))))
+
+(add-hook 'ibuffer-mode-hook
+ (lambda ()
+ (ibuffer-switch-to-saved-filter-groups "default")))
+
+;;;
+;;; Tabs and Newlines
+;;;
+
+(setq-default indent-tabs-mode nil)
+(setq indent-tabs-mode nil)
+(setq tab-width 2)
+(electric-indent-mode t)
+(setq require-final-newline t)
+
+;;;
+;;; Version Control
+;;;
+
+;; I don't like magit's default local tracking branch naming strategy.
+(setq magit-default-tracking-name-function
+ 'magit-default-tracking-name-branch-only)
+
+;;;
+;;; Ediff
+;;;
+
+;; Don't break out a separate frame for ediff.
+(setq ediff-window-setup-function 'ediff-setup-windows-plain)
+
+(setq ediff-split-window-function 'split-window-horizontally)
+
+;;;
+;;; C
+;;;
+
+(setq c-default-style "k&r")
+(setq-default c-basic-offset 2)
+(setq-default c-basic-indent 2)
+
+;;;
+;;; Javascript
+;;;
+
+(setq js-indent-level 2)
+(setq js2-basic-offset 2)
+(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
+
+;;;
+;;; Web
+;;;
+
+(add-to-list 'auto-mode-alist '("\\.html$" . web-mode))
+(add-to-list 'auto-mode-alist '("\\.tpl$" . web-mode))
+
+;;;
+;;; PHP
+;;;
+
+(add-hook 'php-mode-hook (lambda () (setq c-basic-offset 2)))
+
+;;;
+;;; Lisp
+;;;
+
+;; Highlight matching parens, automatically insert pairs, use rainbow
+;; delimiters and use paredit for Lisp buffers.
+(require 'rainbow-delimiters)
+(require 'paredit)
+(global-rainbow-delimiters-mode t)
+(show-paren-mode t)
+(add-hook 'emacs-lisp-mode-hook (lambda () (paredit-mode t)))
+(add-hook 'lisp-mode-hook (lambda () (paredit-mode t)))
+(add-hook 'lisp-interaction-mode-hook (lambda () (paredit-mode t)))
+(add-hook 'scheme-mode-hook (lambda () (paredit-mode t)))
+
+(setq geiser-active-implementations '(guile))
+
+(put 'and-let* 'scheme-indent-function 1)
+(put 'syntax-parameterize 'scheme-indent-function 1)
+(put 'colambda 'scheme-indent-function 1)
+(put 'codefine 'scheme-indent-function 1)
+(put 'with-agenda 'scheme-indent-function 1)
+(put 'gl-begin 'scheme-indent-function 1)
+(put 'with-gl-push-matrix 'scheme-indent-function 0)
+(put 'with-gl-bind-texture 'scheme-indent-function 2)
+(put 'with-gl-client-state 'scheme-indent-function 1)
+(put 'with-gl-enable 'scheme-indent-function 1)
+(put 'with-mesh 'scheme-indent-function 1)
+(put 'with-vertex-buffer 'scheme-indent-function 1)
+(put 'with-texture 'scheme-indent-function 1)
+(put 'with-texture-maybe 'scheme-indent-function 1)
+(put 'with-shader-program 'scheme-indent-function 1)
+(put 'uniforms 'scheme-indent-function 1)
+(put 'with-sprite-batch 'scheme-indent-function 1)
+(put 'with-window 'scheme-indent-function 1)
+(put 'with-test-prefix 'scheme-indent-function 0)
+(put 'with-mutex 'scheme-indent-function 1)
+(put 'bind-key-commands 'scheme-indent-function 2)
+(put 'signal-let 'scheme-indent-function 1)
+(put 'signal-let* 'scheme-indent-function 1)
+(put 'test-group 'scheme-indent-function 1)
+(put 'mock 'scheme-indent-function 1)
+(put 'with-framebuffer 'scheme-indent-function 1)
+(put 'with-render-context 'scheme-indent-function 1)
+(put 'with-push-context 'scheme-indent-function 1)
+(put 'with-temp-transform 'scheme-indent-function 2)
+(put 'chain 'scheme-indent-function 1)
+(put 'call-with-port-or-input-file 'scheme-indent-function 1)
+(put 'call-with-port-or-output-file 'scheme-indent-function 1)
+
+(defun connect-to-guile-wm ()
+ "Connect to guile-wm's REPL server."
+ (interactive)
+ (geiser-connect 'guile "localhost" "37147"))
+
+;;;
+;;; Ruby
+;;;
+
+;; Rake files are ruby, too, as are gemspecs, rackup files, etc.
+(add-to-list 'auto-mode-alist '("\\.rake$" . ruby-mode))
+(add-to-list 'auto-mode-alist '("\\.gemspec$" . ruby-mode))
+(add-to-list 'auto-mode-alist '("\\.ru$" . ruby-mode))
+(add-to-list 'auto-mode-alist '("Rakefile$" . ruby-mode))
+(add-to-list 'auto-mode-alist '("Gemfile$" . ruby-mode))
+
+;; Use ruby-test-mode
+(add-hook 'ruby-mode-hook 'ruby-test-mode)
+
+;;;
+;;; SQL
+;;;
+
+;; Don't wrap lines so that table listings with a lot of columns
+;; remain readable.
+(add-hook 'sql-interactive-mode-hook
+ (lambda () (setq truncate-lines t)))
+
+;;;
+;;; RSS
+;;;
+
+(setq elfeed-feeds
+ '("http://planet.gnu.org/rss20.xml"
+ "http://cs.worcester.edu/blog/feed/"
+ "https://hacks.mozilla.org/feed/"
+ "http://ebb.org/bkuhn/blog/rss.xml"))
+
+;;;
+;;; GPG
+;;;
+ d
+(setf epg-gpg-program "gpg2")
+
+;;;
+;;; Mail
+;;;
+
+(require 'notmuch)
+(require 'notmuch-unread)
+
+(notmuch-unread-mode 1)
+
+(setq notmuch-fcc-dirs
+ '(("dthompson2@worcester.edu" . "WSU/Sent")
+ ("davet@fsf.org" . "FSF/INBOX.Sent")
+ ("davet@gnu.org" . "FSF/INBOX.Sent")
+ (".*" . "sent")))
+(setq send-mail-function 'smtpmail-send-it)
+(setq smtpmail-smtp-server "mail.fsf.org")
+(setq smtpmail-smtp-service 587)
+(setq smtpmail-stream-type 'starttls)
+;; (setq smtpmail-smtp-server "smtp.gmail.com")
+;; (setq smtpmail-smtp-service 465)
+;; (setq smtpmail-stream-type 'ssl)
+
+(setq notmuch-saved-searches
+ '((:name "unread" :query "tag:unread")
+ (:name "inbox" :query "tag:inbox")
+ (:name "important" :query "tag:important")
+ (:name "fsfsys" :query "tag:fsfsys")))
+
+(define-key notmuch-search-mode-map "u"
+ (lambda ()
+ "Remove 'unread' tag from message."
+ (interactive)
+ (notmuch-search-tag '("-unread"))
+ (notmuch-search-next-thread)))
+
+(define-key notmuch-search-mode-map "a"
+ (lambda ()
+ "Remove 'unread' and 'inbox' tags from message."
+ (interactive)
+ (notmuch-search-tag '("-unread" "-inbox"))
+ (notmuch-search-next-thread)))
+
+(define-key notmuch-search-mode-map "d"
+ (lambda ()
+ "Add 'deleted' tag to message."
+ (interactive)
+ (notmuch-search-tag '("+deleted"))
+ (notmuch-search-next-thread)))
+
+(define-key notmuch-search-mode-map "i"
+ (lambda ()
+ "Remove 'unread' and 'inbox' tags from message, and add the
+'important' tag."
+ (interactive)
+ (notmuch-search-tag '("-unread" "-inbox" "+important"))
+ (notmuch-search-next-thread)))
+
+(define-key notmuch-search-mode-map "s"
+ (lambda ()
+ "Remove 'unread' and 'inbox' tags from message, and add the
+'spam' tag."
+ (interactive)
+ (notmuch-search-tag '("-unread" "-inbox" "+spam"))
+ (notmuch-search-next-thread)))
+
+;;;
+;;; Calendar
+;;;
+
+(require 'org-caldav)
+
+(setq org-caldav-url
+ "https://my.owndrive.com/remote.php/caldav/calendars/davexunit")
+(setq org-caldav-calendar-id "defaultcalendar")
+(setq org-caldav-inbox "~/Documents/calendar.org")
+(setq org-caldav-files '())
+(setq org-icalendar-timezone "America/New_York")
+
+;;;
+;;; Music
+;;;
+
+(require 'emms-player-mpd)
+(require 'emms-mode-line)
+(require 'emms-browser)
+
+(emms-standard)
+(emms-mode-line 1)
+(setq emms-player-mpd-server-name "localhost"
+ emms-player-mpd-server-port "6600"
+ emms-volume-change-function 'emms-volume-mpd-change)
+(add-to-list 'emms-info-functions 'emms-info-mpd)
+(add-to-list 'emms-player-list 'emms-player-mpd)
+
+;;;
+;;; Other
+;;;
+
+;; Load machine specific emacs configuration
+(defvar local-config-filename "~/.emacs.d/local.el")
+(if (file-exists-p local-config-filename)
+ (load local-config-filename))
+
+;; IRC configuration
+(load "~/.emacs.d/erc.el")
+
+;;;
+;;; Keybindings
+;;;
+
+;; Handy functions courtesy of whattheemacs.d
+(defun open-line-below ()
+ (interactive)
+ (if (eolp)
+ (newline)
+ (end-of-line)
+ (newline))
+ (indent-for-tab-command))
+
+(defun open-line-above ()
+ (interactive)
+ (beginning-of-line)
+ (newline)
+ (forward-line -1)
+ (indent-for-tab-command))
+
+;; Easy window movement.
+(require 'windmove)
+(windmove-default-keybindings 'meta)
+
+(global-set-key (kbd "M-x") 'smex)
+(global-set-key (kbd "RET") 'newline-and-indent)
+(global-set-key (kbd "<C-return>") 'open-line-below)
+(global-set-key (kbd "<C-M-return>") 'open-line-above)
+(global-set-key (kbd "C-c g") 'magit-status)
+(global-set-key (kbd "C-c i") 'start-irc)
+(global-set-key (kbd "C-c p") 'package-list-packages)
+(global-set-key (kbd "C-c C-f") 'ff-find-other-file)
+(global-set-key (kbd "C-c s") 'connect-to-guile)
+(global-set-key (kbd "C-c e e") 'emms)
+(global-set-key (kbd "C-c e b") 'emms-browser)
+(global-set-key (kbd "C-c f") 'elfeed)
+(global-set-key (kbd "C-c m") 'notmuch)
+(global-set-key (kbd "M-%") 'query-replace-regexp)
+;; No more minimizing Emacs by accident.
+(global-unset-key (kbd "C-z"))
+
+;; Enable some disabled-by-default functions
+(put 'upcase-region 'disabled nil)
+(put 'downcase-region 'disabled nil)