From a0de2de8077af14d4b1360d56d194dd4b6bd8403 Mon Sep 17 00:00:00 2001 From: Diego Berrocal Date: Sun, 26 Apr 2015 21:48:32 -0400 Subject: [PATCH] ERC layer: Many improvements --- contrib/irc/erc/README.md | 10 + contrib/irc/erc/extensions.el | 15 ++ contrib/irc/erc/extensions/erc-tex/erc-tex.el | 176 ++++++++++++++++++ contrib/irc/erc/extensions/erc-yank/README.md | 19 ++ .../irc/erc/extensions/erc-yank/erc-yank.el | 106 +++++++++++ contrib/irc/erc/packages.el | 109 ++++++++++- 6 files changed, 431 insertions(+), 4 deletions(-) create mode 100644 contrib/irc/erc/extensions.el create mode 100644 contrib/irc/erc/extensions/erc-tex/erc-tex.el create mode 100644 contrib/irc/erc/extensions/erc-yank/README.md create mode 100644 contrib/irc/erc/extensions/erc-yank/erc-yank.el diff --git a/contrib/irc/erc/README.md b/contrib/irc/erc/README.md index 612075ff9..c53a44050 100644 --- a/contrib/irc/erc/README.md +++ b/contrib/irc/erc/README.md @@ -5,6 +5,7 @@ - [ERC contribution layer for Spacemacs](#erc-contribution-layer-for-spacemacs) - [Description](#description) + - [Features](#features) - [Install](#install) - [Key bindings](#key-bindings) @@ -14,6 +15,14 @@ Layer for [ERC IRC chat.](http://www.emacswiki.org/emacs/ERC) +## Features + +- Highlight nicks (using [erc-hl-nicks](https://github.com/leathekd/erc-hl-nicks)) +- Image inline support (using [erc-image](https://github.com/kidd/erc-image.el)) +- Logging to ~/.emacs.d/.cache/erc-logs and ViewLogMode for viewing logs (using [erc-view-log](https://github.com/Niluge-KiWi/erc-view-log)) +- YouTube videos Thumbnails inline (using [erc-yt](https://github.com/yhvh/erc-yt)) +- Social Graph for ERC messages (using [erc-social-graph](https://github.com/vibhavp/erc-social-graph)) + ## Install To use this contribution add it to your `~/.spacemacs` @@ -35,6 +44,7 @@ Key Binding | Description ` a i i` | Switch to next active ERC buffer ` m b` | Switch between ERC buffers ` m d` | Interactively input a user action and send it to IRC. +` m D` | Draw Social Graph using [erc-social-graph](https://github.com/vibhavp/erc-social-graph) (needs graphviz to be installed) ` m j` | Join a channel, executes the /join command ` m n` | Run "/names #channel" in the current channel. ` m l` | Run the /list command diff --git a/contrib/irc/erc/extensions.el b/contrib/irc/erc/extensions.el new file mode 100644 index 000000000..14b91ab81 --- /dev/null +++ b/contrib/irc/erc/extensions.el @@ -0,0 +1,15 @@ +(setq erc-post-extensions + '( + erc-tex + erc-yank + )) + +(defun erc/init-erc-tex () + (use-package erc-tex + :init + )) + +(defun erc/init-erc-yank () + (use-package erc-yank + :init + (bind-key "C-y" 'erc-yank erc-mode-map))) diff --git a/contrib/irc/erc/extensions/erc-tex/erc-tex.el b/contrib/irc/erc/extensions/erc-tex/erc-tex.el new file mode 100644 index 000000000..a85477aba --- /dev/null +++ b/contrib/irc/erc/extensions/erc-tex/erc-tex.el @@ -0,0 +1,176 @@ +;;; erc-tex.el --- LaTeX mathematical expressions rendering for ERC + +;; Copyright (C) 2009 David Vazquez + +;; Last-modified: <2009-09-14 02:11:53 david> + +;; Authors: David Vazquez +;; Created: 12 Sep 2009 +;; Keywords: comm, tex + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; erc-tex is a tiny ERC module which render LaTeX mathematical expressions +;; in your ERC chats. You will need both latex and dvipng in order to use this +;; module. +;; +;; Once erc-tex is avalaible for your Emacs, you can use `erc-tex-mode' to +;; toggle the module. This will render the text between $...$ as a LaTeX +;; expression. Indeed, you can use `erc-tex-image-edit', bound to `RET' on TeX +;; formulas to edit the TeX code in the prompt and resend the image. + +;;; TODO: +;; - Highlight the formulas according to ERC faces as erc-track. + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'erc) + + +(defvar erc-tex-latex-program "latex" + "Program name for invoking LaTeX.") + +(defvar erc-tex-dvipng-program "dvipng" + "Program name for invoking dvipng.") + +(defvar erc-tex-image-size 1.2 + "Ratio of magnification.") + + +;; Error condition signaled when it cannot render a LaTeX expression. +(put 'erc-tex-bad-expression-error + 'error-conditions '(error erc-tex-bad-expression-error)) + + +(defsubst erc-tex-run-latex (&rest arguments) + "Launch LaTeX program with some arguments." + (unless (zerop (apply #'call-process erc-tex-latex-program nil nil nil arguments)) + (signal 'erc-tex-bad-expression-error nil))) + +(defsubst erc-tex-run-dvipng (&rest arguments) + "Launch dvipng program with some arguments." + (unless (zerop (apply #'call-process erc-tex-dvipng-program nil nil nil arguments)) + (signal 'erc-tex-bad-expression-error nil))) + +;; Call to latex and dvipng in order to build a PNG image from the LaTeX +;; expression MATH-STRING. Return the image descriptor if it was sucessful, +;; NIL otherwise. +(defun erc-tex-make-image (math-expression fg bg) + (condition-case nil + (let* ((prefix (concat temporary-file-directory (make-temp-name "erc-tex-"))) + (tex-file (concat prefix ".tex")) + (dvi-file (concat prefix ".dvi")) + (png-file (concat prefix ".png"))) + + (with-temp-file tex-file + (insert "\\documentclass{article}\n" + "\\pagestyle{empty}\n" + "\\usepackage{amsmath, amssymb, amsthm}\n" + "\\begin{document}\n" + "\\par\n" + "$" math-expression "$" + "\\end{document}\n")) + + (erc-tex-run-latex (concat "-output-directory=" temporary-file-directory) tex-file) + + (flet ((colorize (color) + ;; Return a string which stand for COLOR in the format that + ;; dvipng understands. + (let ((max (car (color-values "#ffffff")))) + (destructuring-bind (r g b) + (color-values color) + (format "rgb %.02f %.02f %.02f" + (/ (float r) max) + (/ (float g) max) + (/ (float b) max)))))) + + (erc-tex-run-dvipng "-x" (number-to-string (floor (* 1000 erc-tex-image-size))) + "-T" "tight" + "-fg" (colorize fg) + "-bg" (colorize bg) + "-o" png-file + dvi-file)) + (delete-file tex-file) + (delete-file dvi-file) + (create-image png-file 'png nil :margin '(0 . 5) :ascent 'center)) + + ((erc-tex-bad-expression-error) + ;; We do not delete auxiliary files if any error ocurred. + ))) + + + +(defvar erc-tex-image-keymap + (let ((keymap (make-sparse-keymap))) + (define-key keymap (kbd "RET") 'erc-tex-image-edit) + keymap)) + +(defun erc-tex-image-edit () + (interactive) + (let* ((start (point)) + (i start) + (prop (get-char-property i 'display))) + (while (eq prop (get-char-property i 'display)) + (setq i (1+ i))) + (goto-char (point-max)) + (insert (buffer-substring-no-properties start i)))) + +(defun erc-tex-render (&optional fg bg) + (let ((fg (or fg (face-foreground 'default))) + (bg (or bg (face-background 'default)))) + (goto-char (point-min)) + (while (re-search-forward "\\$[^$]*\\$" nil t) + (let* ((match (match-string-no-properties 0)) + (descp (erc-tex-make-image match fg bg))) + (when descp + (let (start end) + (delete-region (match-beginning 0) (match-end 0)) + (setq start (point)) + (insert-image descp match) + (setq end (point)) + (put-text-property start end 'keymap erc-tex-image-keymap))))))) + + +;;; Minor mode + +(defun erc-tex-render-insert () + (erc-tex-render)) + +(defun erc-tex-render-send () + (erc-tex-render + (face-foreground 'erc-input-face) + (face-background 'erc-input-face))) + +(define-erc-module tex latex + "Display LaTeX mathematical expressions as images in ERC." + ((add-hook 'erc-insert-modify-hook 'erc-tex-render-insert t) + (add-hook 'erc-send-modify-hook 'erc-tex-render-send t)) + ((remove-hook 'erc-insert-modify-hook 'erc-tex-render-insert) + (remove-hook 'erc-send-modify-hook 'erc-tex-render-send))) + + +(provide 'erc-tex) + +;; Local variables: +;; fill-column: 78 +;; indent-tabs-mode: nil +;; time-stamp-pattern: "10/^;; Last-modified: <%%>$" +;; End: + +;;; erc-tex.el ends here diff --git a/contrib/irc/erc/extensions/erc-yank/README.md b/contrib/irc/erc/extensions/erc-yank/README.md new file mode 100644 index 000000000..29e241034 --- /dev/null +++ b/contrib/irc/erc/extensions/erc-yank/README.md @@ -0,0 +1,19 @@ +# erc-yank + +Automagically create a Gist if pasting more than 5 lines + +Hook in as follows: + + (add-hook 'erc-mode-hook + (lambda () (define-key erc-mode-map [(control ?y)] 'erc-yank))) + +Or, if you want to use my `use-package' macro: + + (use-package erc + :commands erc + :config + (use-package erc-yank + :init + (bind-key "C-y" 'erc-yank erc-mode-map))) + +This module requires gist.el, from: https://github.com/defunkt/gist.el diff --git a/contrib/irc/erc/extensions/erc-yank/erc-yank.el b/contrib/irc/erc/extensions/erc-yank/erc-yank.el new file mode 100644 index 000000000..62a49bfb9 --- /dev/null +++ b/contrib/irc/erc/extensions/erc-yank/erc-yank.el @@ -0,0 +1,106 @@ +;;; erc-yank --- Automagically create a Gist if pasting more than 5 lines + +;; Copyright (C) 2012 John Wiegley + +;; Author: John Wiegley +;; Created: 17 Jun 2012 +;; Version: 1.0 +;; Keywords: erc yank gist +;; X-URL: https://github.com/jwiegley/erc-yank + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Automagically create a Gist if pasting more than 5 lines. +;; +;; Hook in as follows: +;; +;; (add-hook 'erc-mode-hook +;; (lambda () (define-key erc-mode-map [(control ?y)] 'erc-yank))) +;; +;; Or, if you want to use my `use-package' macro: +;; +;; (use-package erc +;; :commands erc +;; :config +;; (use-package erc-yank +;; :init +;; (bind-key "C-y" 'erc-yank erc-mode-map))) +;; +;; This module requires gist.el, from: https://github.com/defunkt/gist.el + +;;; Code: + +(require 'gist) + +(defgroup erc-yank nil + "Automagically create a Gist if pasting more than 5 lines" + :group 'erc) + +(defcustom erc-yank-flood-limit 5 + "Maximum number of lines allowed to yank to an erc buffer." + :type 'integer + :group 'erc-yank) + +(defcustom erc-yank-query-before-gisting t + "If non-nil, ask the user before creating a new Gist." + :type 'boolean + :group 'erc-yank) + +(defcustom erc-yank-display-text-on-prompt t + "If non-nil, show the text to yank in another buffer when prompting." + :type 'boolean + :group 'erc-yank) + +(defun erc-yank (&optional arg) + "Yank or make a gist depending on the size of the yanked text." + (interactive "*P") + (let* ((kill-text (current-kill (cond + ((listp arg) 0) + ((eq arg '-) -2) + (t (1- arg))))) + (lines (length (split-string kill-text "\n")))) + (if (and (> lines erc-yank-flood-limit) + (or (not erc-yank-query-before-gisting) + (let ((query + (format (concat "Text to yank is %d lines;" + " create a Gist instead? ") lines))) + (if erc-yank-display-text-on-prompt + (save-window-excursion + (with-current-buffer (get-buffer-create "*Yank*") + (delete-region (point-min) (point-max)) + (insert kill-text) + (goto-char (point-min)) + (display-buffer (current-buffer)) + (fit-window-to-buffer + (get-buffer-window (current-buffer))) + (unwind-protect + (y-or-n-p query) + (kill-buffer (current-buffer))))) + (y-or-n-p query))))) + (let ((buf (current-buffer))) + (with-temp-buffer + (insert kill-text) + (gist-region (point-min) (point-max) nil + `(lambda (gist) + (with-current-buffer ,buf + (insert (oref gist :html-url))))))) + (yank arg)))) + +(provide 'erc-yank) + +;;; erc-yank.el ends here diff --git a/contrib/irc/erc/packages.el b/contrib/irc/erc/packages.el index 2a983f1c2..13062536f 100644 --- a/contrib/irc/erc/packages.el +++ b/contrib/irc/erc/packages.el @@ -10,7 +10,15 @@ ;; ;;; License: GPLv3 -(setq erc-packages '(erc)) +(setq erc-packages + '( + erc + erc-hl-nicks + erc-image + erc-social-graph + erc-view-log + erc-yt + )) (when (system-is-mac) (push 'erc-terminal-notifier erc-packages)) @@ -24,22 +32,48 @@ "aie" 'erc "aiE" 'erc-tls "aii" 'erc-track-switch-buffer) + ;; utf-8 always and forever + (setq erc-server-coding-system '(utf-8 . utf-8)) + ;; disable linum mode in erc + ;; check if this will not be efficient + (defun no-linum (&rest ignore) + (when (or 'linum-mode global-linum-mode) + (linum-mode 0))) + (add-hook 'erc-mode-hook 'no-linum) + (add-hook 'erc-hook 'no-linum) + (add-hook 'erc-insert-pre-hook 'no-linum) :config (progn - + (use-package erc-autoaway + :config + (setq erc-auto-discard-away t + erc-autoaway-idle-seconds 600 + erc-autoaway-use-emacs-idle t)) + (erc-services-mode 1) (defun erc-list-command () "execute the list command" (interactive) (insert "/list") (erc-send-current-line)) - (setq erc-kill-buffer-on-part t erc-kill-queries-on-quit t erc-kill-server-buffer-on-quit t) - + (add-hook 'erc-connect-pre-hook (lambda (x) (erc-update-modules))) (erc-track-mode t) (setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE") erc-server-coding-system '(utf-8 . utf-8)) + (setq erc-prompt (lambda () (concat "[" (buffer-name) "]"))) + + (require 'notifications) + (defun erc-global-notify (match-type nick message) + "Notify when a message is recieved." + (notifications-notify + :title nick + :body message + :app-icon "/home/io/.emacs.d/assets/spacemacs.svg" + :urgency 'low)) + + (add-hook 'erc-text-matched-hook 'erc-global-notify) ;; keybindings (evil-leader/set-key-for-mode 'erc-mode "md" 'erc-input-action @@ -49,4 +83,71 @@ "mp" 'erc-part-from-channel "mq" 'erc-quit-server)))) + +(defun erc/init-erc-hl-nicks () + (use-package erc-hl-nicks + :init + )) + +(defun erc/init-erc-social-graph () + (use-package erc-social-graph + :config + (erc-social-graph-enable) + (setq erc-social-graph-dynamic-graph t) + + (evil-leader/set-key-for-mode 'erc-mode + "mD" 'erc-social-graph-draw) + )) + +(defun erc/init-erc-yt () + (use-package erc-yt + :config + (add-to-list 'erc-modules 'youtube) + )) + +(defun erc/init-erc-view-log () + (use-package erc-view-log + :init + (add-to-list 'erc-modules 'log) + (setq erc-log-channels-directory + (expand-file-name + (concat spacemacs-cache-directory + "erc-logs"))) + (unless (file-exists-p erc-log-channels-directory) + (make-directory erc-log-channels-directory)) + + :config + ;; ERC Logging + (add-to-list 'auto-mode-alist + `(,(format "%s/.*\\.[log|txt]" + (regexp-quote + (expand-file-name + erc-log-channels-directory))) . erc-view-log-mode)) + ;; Following https://raw.githubusercontent.com/Niluge-KiWi/erc-view-log/master/erc-view-log.el + ;; installation instructions + (add-hook 'erc-view-log-mode-hook 'turn-on-auto-revert-tail-mode) + + + (defun spacemacs//erc-log-ms-documentation () + "Return the docstring for the workspaces micro-state." + (concat + "\n[r] to reload the log file" + "[>], [<] to go to the next/prev mention")) + + (spacemacs|define-micro-state erc-log + :doc (spacemacs//erc-log-ms-documentation) + :use-minibuffer t + :evil-leader "m." + :bindings + ("r" erc-view-log-reload-file) + (">" erc-view-log-next-mention) + ("<" erc-view-log-previous-mention)) + )) + +(defun erc/init-erc-image () + (use-package erc-image + :config + (add-to-list 'erc-modules 'image) + )) + (defun erc/init-erc-terminal-notifier ())