Skip to content

Instantly share code, notes, and snippets.

@Wilfred
Created May 4, 2013 23:35
Show Gist options
  • Save Wilfred/5519156 to your computer and use it in GitHub Desktop.
Save Wilfred/5519156 to your computer and use it in GitHub Desktop.
show-your-colours.el --- an HTTP server showing the current buffer fontified
;;; show-your-colours --- an HTTP server showing the current buffer fontified
;; Author: Wilfred Hughes <me@wilfred.me.uk>
;; Version: 0.1
;; Package-Requires: ((s "1.3.0"))
;;; Commentary:
;; Allow others to see what you're editing in Emacs. For live
;; screencasts, or general Emacs advocacy. If you have multiple
;; buffers open, this will show the currently focused buffer.
;; FIXME: Crashes with rainbow-delimeters.
(require 'elnode)
(require 's)
(defvar show-your-colours-buffer nil
"The buffer currently being visited by the user.")
(defvar syc--port 9000)
;; todo: wrap this in a minor mode
(defadvice ido-switch-buffer (after set-syc--buffer)
"Set `syc--buffer' to the current buffer.
Since `switch-to-buffer' is very low-level and used everywhere,
we assume a buffer change by a user always uses `ido-switch-buffer"
(setq syc--buffer (current-buffer)))
;; todo: is there a way we can just activate our advice?
(ad-activate 'ido-switch-buffer)
(defadvice other-window (after set-syc--buffer)
"Set `syc--buffer' to the current buffer.
Since `switch-to-buffer' is very low-level and used everywhere,
we assume a buffer change by a user always uses `ido-switch-buffer"
(setq syc--buffer (current-buffer)))
;; todo: is there a way we can just activate our advice?
(ad-activate 'other-window)
;; todo: automatic reload
(defun syc--buffer-as-html ()
"Get the current buffer and return a string of HTML.
The HTML is styled according to the buffer's fontification."
;; htmlize-buffer calls message, stop that
(flet ((message (&rest args)))
(condition-case nil
(let ((htmlize-buffer (htmlize-buffer syc--buffer))
html)
(save-excursion
(switch-to-buffer htmlize-buffer)
(setq html
(buffer-substring-no-properties (point-min) (point-max)))
(kill-buffer htmlize-buffer))
html)
(error "<html><body>Could not fontify buffer.</body></html>"))))
(defun syc--append-reload (html)
"Given a piece of HTML, return a new string with
a JS automatic reload script appended."
(s-replace
"</body>"
"<script type=\"text/javascript\">setTimeout(function() { location.reload(true); }, 1000);</script>
</body>"
html))
;; todo: why can't I let-bind this inside syc--handler?
(setq elnode-error-log-to-messages nil)
(defun syc--handler (httpcon)
(elnode-http-start httpcon 200 '("Content-Type" . "text/html"))
(elnode-http-return
httpcon
(syc--append-reload
(syc--buffer-as-html))))
(elnode-start 'syc--handler :port syc--port :host "localhost")
@leoc
Copy link

leoc commented May 5, 2013

Very nice! Though I needed to add a (save-selected-window) around (save-excursion) otherwise I was thrown out of the mini buffer when the website reloads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment