summaryrefslogtreecommitdiffstats
path: root/emacs.d/nxhtml/util/as-external.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs.d/nxhtml/util/as-external.el')
-rw-r--r--emacs.d/nxhtml/util/as-external.el310
1 files changed, 310 insertions, 0 deletions
diff --git a/emacs.d/nxhtml/util/as-external.el b/emacs.d/nxhtml/util/as-external.el
new file mode 100644
index 0000000..b1330c1
--- /dev/null
+++ b/emacs.d/nxhtml/util/as-external.el
@@ -0,0 +1,310 @@
+;;; as-external.el --- Emacs as an external editor to other apps
+;;
+;; Author: Lennart Borgman (lennart O borgman A gmail O com)
+;; Created: Mon Jun 25 19:02:49 2007
+(defconst as-external:version "0.6") ;;Version:
+;; Last-Updated: 2009-08-04 Tue
+;; URL:
+;; Keywords:
+;; Compatibility:
+;;
+;; Features that might be required by this library:
+;;
+;; None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; This little library should make it easier to use Emacs as an
+;; external editor in certain cases. One such case is when want to
+;; use Emacs as the external editor with the Firefox add-on "It's All
+;; Text".
+;;
+;; See variable `as-external-mode' for more information.
+;;
+;;
+;;; A note on the implementation:
+;;
+;; You may wonder why this does not use `auto-mode-alist' since it
+;; checks the file name in nearly the same way? It is perhaps possible
+;; to use that, but there are two things to be aware of:
+;;
+;; 1. The choice made must override other possible choices.
+;;
+;; 2. Beside the file name the implementation here also checks if the
+;; buffer has clients waiting. That makes the check more reliable.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; 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 this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(eval-when-compile (require 'html-write nil t))
+(eval-when-compile (require 'mlinks nil t))
+(eval-when-compile (require 'mumamo nil t))
+(eval-when-compile (require 'nxhtml-mode nil t))
+(eval-when-compile (require 'ourcomments-util nil t))
+(eval-when-compile (require 'pause nil t))
+(eval-when-compile (require 'server))
+(eval-when-compile (require 'wikipedia-mode nil t))
+(eval-and-compile (require 'wrap-to-fill nil t))
+
+;;;###autoload
+(defgroup as-external nil
+ "Settings related to Emacs as external editor."
+ :group 'nxhtml
+ :group 'external)
+
+(defcustom as-external-its-all-text-regexp "/itsalltext/"
+ "Regular expression matching It's All Text buffer's file."
+ :type 'regexp
+ :group 'as-external)
+
+(defcustom as-external-alist
+ '(
+ ("/itsalltext/.*wiki" as-external-for-wiki)
+ ("/itsalltext/.*mail" as-external-for-mail-mode)
+ ("/itsalltext/" as-external-for-xhtml)
+ )
+ "List to determine setup if Emacs is used as an external Editor.
+Element in this list should have the form
+
+ \(FILE-REGEXP BUFFER-SETUP)
+
+where FILE-REGEXP should be a regular expression to match
+`buffer-file-name'. If it matches then BUFFER-SETUP should be
+called in the buffer.
+
+* Tip when using Firefox's add-on It's All Text: It looks like
+ the file name used will be constructed from the host url. For
+ example if your are editing something on
+ http://www.emacswiki.org/ the file name may be something like
+ 'www.emacswiki.org.283b1y212e.html'.
+
+
+The list is processed by `as-external-setup'. Note that the first
+match is used!
+
+The default entries in this list supports for Firefox addon It's
+All Text:
+
+- `as-external-for-xhtml'. For text areas on web pages where you
+ can enter some XHTML code, for example blog comment fields.
+
+- `as-external-for-mail-mode', for editing web mail messages.
+
+- `as-external-for-wiki', for mediawiki.
+
+See also `as-external-mode'."
+ :type '(repeat
+ (list (choice (variable :tag "Regexp variable")
+ regexp)
+ command))
+ :group 'as-external)
+
+(defcustom as-external-its-all-text-coding 'utf-8
+ "Coding system to use for It's All Text buffers.
+See also `as-external-for-xhtml'."
+ :type '(choice (const :tag "No special coding system" nil)
+ coding-system)
+ :group 'as-external)
+
+(defun as-external-fall-back (msg)
+ "Fallback to text-mode if necessary."
+ (text-mode)
+ (lwarn t :warning "%s. Using text-mode" msg))
+
+;;;###autoload
+(defun as-external-for-xhtml ()
+ "Setup for Firefox addon It's All Text to edit XHTML.
+It's All Text is a Firefox add-on for editing textareas with an
+external editor.
+See URL `https://addons.mozilla.org/en-US/firefox/addon/4125'.
+
+In this case Emacs is used to edit textarea fields on a web page.
+The text will most often be part of a web page later, like on a
+blog. Therefore turn on these:
+
+- `nxhtml-mode' since some XHTML tags may be allowed.
+- `nxhtml-validation-header-mode' since it is not a full page.
+- `wrap-to-fill-column-mode' to see what you are writing.
+- `html-write-mode' to see it even better.
+
+Also bypass the question for line end conversion when using
+emacsw32-eol."
+ (interactive)
+ (if (not (fboundp 'nxhtml-mode))
+ (as-external-fall-back "Can't find nXhtml")
+ (nxhtml-mode)
+ (nxhtml-validation-header-mode 1)
+ (set (make-local-variable 'wrap-to-fill-left-marg-modes)
+ '(nxhtml-mode fundamental-mode))
+ (wrap-to-fill-column-mode 1)
+ ;;(visible-point-mode 1)
+ (when (fboundp 'html-write-mode) (html-write-mode 1))
+ (when (boundp 'emacsw32-eol-ask-before-save)
+ (make-local-variable 'emacsw32-eol-ask-before-save)
+ (setq emacsw32-eol-ask-before-save nil))))
+
+
+(defvar as-external-mail-mode-comment-pattern "^>.*$"
+ "Regular expression for a comment line.")
+
+(defvar as-external-mail-mode-email-pattern
+ (concat "[a-z0-9$%(*-=?[_][^<>\")!;:,{}]*"
+ "\@"
+ "\\(?:[a-z0-9\-]+\.\\)+[a-z0-9]\\{2,4\\}")
+ "Regular expression for a mail address.")
+
+(defvar as-external-mail-mode-font-lock-keywords
+ (list
+ (list as-external-mail-mode-comment-pattern
+ '(0 font-lock-comment-face))
+ ;; (list as-external-mail-mode-email-pattern
+ ;; '(0 font-lock-keyword-face))
+ ))
+
+;;;###autoload
+(define-derived-mode as-external-for-mail-mode text-mode "ExtMail "
+ "Setup for Firefox addon It's All Text to edit mail.
+Set normal mail comment markers in column 1 (ie >).
+
+Set `fill-column' to 90 and enable `wrap-to-fill-column-mode' so
+that it will look similar to how it will look in the sent plain
+text mail.
+
+See also `as-external-mode'."
+ ;; To-do: Look at http://globs.org/articles.php?lng=en&pg=2
+ (set (make-local-variable 'comment-column) 0)
+ (set (make-local-variable 'comment-start) ">")
+ (set (make-local-variable 'comment-end) "")
+ (set (make-local-variable 'font-lock-defaults)
+ '((as-external-mail-mode-font-lock-keywords) nil))
+ (setq fill-column 90)
+ (mlinks-mode 1)
+ (wrap-to-fill-column-mode 1))
+
+;;;###autoload
+(defun as-external-for-wiki ()
+ "Setup for Firefox addon It's All Text to edit MediaWikis."
+ (interactive)
+ (require 'wikipedia-mode nil t)
+ (if (not (featurep 'wikipedia-mode))
+ (as-external-fall-back "Can't find file wikipedia-mode.el")
+ (wikipedia-mode)))
+
+
+;;;###autoload
+(define-minor-mode as-external-mode
+ "If non-nil check if Emacs is called as external editor.
+When Emacs is called as an external editor for example to edit
+text areas on a web page viewed with Firefox this library tries
+to help to setup the buffer in a useful way. It may for example
+set major and minor modes for the buffer.
+
+This can for example be useful when blogging or writing comments
+on blogs.
+
+See `as-external-alist' for more information."
+ :global t
+ :group 'as-external
+ ;;(modify-coding-system-alist 'file "/itsalltext/" as-external-its-all-text-coding)
+ (let ((coding-entry
+ (cons
+ as-external-its-all-text-regexp
+ (cons as-external-its-all-text-coding
+ as-external-its-all-text-coding))))
+ ;;(message "as-external-mode=%s" as-external-mode)
+ (if as-external-mode
+ (progn
+ (add-to-list 'file-coding-system-alist coding-entry)
+ (add-hook 'server-visit-hook 'as-external-setup t))
+ (setq file-coding-system-alist
+ (delq coding-entry file-coding-system-alist))
+ (remove-hook 'server-visit-hook 'as-external-setup))))
+
+(defun as-external-setup ()
+ "Check if Emacs is used as an external editor.
+If so then turn on useful major and minor modes.
+This is done by checking `as-external-alist'."
+ (condition-case err
+ (as-external-setup-1)
+ (error (message "as-external-setup error: %s" err))))
+
+(defvar as-external-my-frame nil)
+(make-variable-buffer-local 'as-external-my-frame)
+
+(defvar as-external-last-buffer nil)
+
+(defun as-external-server-window-fix-frames ()
+ (condition-case err
+ (with-current-buffer as-external-last-buffer
+ (unless (buffer-live-p pause-buffer)
+ (remove-hook 'pause-break-exit-hook 'as-external-server-window-fix-frames)
+ (setq as-external-my-frame (or as-external-my-frame
+ (make-frame)))
+ (dolist (f (frame-list))
+ (unless (eq f as-external-my-frame)
+ (lower-frame f)))
+ (raise-frame as-external-my-frame)))
+ (error (message "%s" (error-message-string err)))))
+
+(defun as-external-server-window (buffer)
+ (setq server-window nil)
+ (with-current-buffer buffer
+ (setq as-external-last-buffer (current-buffer))
+ (run-with-idle-timer 2 nil 'as-external-server-window-fix-frames)
+ (add-hook 'pause-break-exit-hook 'as-external-server-window-fix-frames)
+ (add-hook 'kill-buffer-hook 'as-external-delete-my-frame nil t)))
+
+(defun as-external-delete-my-frame ()
+ (let ((win (and (frame-live-p as-external-my-frame)
+ (get-buffer-window nil as-external-my-frame))))
+ (when (and win
+ (= 1 (length (window-list as-external-my-frame 'no-mini))))
+ (delete-frame as-external-my-frame)
+ (lower-frame))))
+
+(defun as-external-setup-1 ()
+ ;; Fix-me: How does one know if the file names are case sensitive?
+ (unless (when (boundp 'nowait) nowait) ;; dynamically bound in `server-visit-files'
+ (unless server-window
+ ;; `server-goto-toplevel' has been done here.
+ ;; Setup to use a new frame
+ (setq server-window 'as-external-server-window))
+ (catch 'done
+ (dolist (rec as-external-alist)
+ (let ((file-regexp (car rec))
+ (setup-fun (cadr rec)))
+ (when (symbolp file-regexp)
+ (setq file-regexp (symbol-value file-regexp)))
+ (when (string-match file-regexp (buffer-file-name))
+ (funcall setup-fun)
+ (throw 'done t)))))))
+
+(provide 'as-external)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; as-external.el ends here