From 94d2fc1815a919734353c942f224db1de4b4fcb8 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Mon, 7 Mar 2011 09:04:49 +0100 Subject: Django, org * Added nxhtml, mostly for django support. * Changed some org settings. --- emacs.d/nxhtml/util/wrap-to-fill.el | 364 ++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 emacs.d/nxhtml/util/wrap-to-fill.el (limited to 'emacs.d/nxhtml/util/wrap-to-fill.el') diff --git a/emacs.d/nxhtml/util/wrap-to-fill.el b/emacs.d/nxhtml/util/wrap-to-fill.el new file mode 100644 index 0000000..223ce1b --- /dev/null +++ b/emacs.d/nxhtml/util/wrap-to-fill.el @@ -0,0 +1,364 @@ +;;; wrap-to-fill.el --- Make a fill-column wide space for editing +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2009-08-12 Wed +;; Version: +;; Last-Updated: x +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; 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 3, 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 'mumamo)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; Wrapping + +;;;###autoload +(defgroup wrap-to-fill nil + "Customizing of `wrap-to-fill-column-mode'." + :group 'convenience) + +;;;###autoload +(defcustom wrap-to-fill-left-marg nil + "Left margin handling for `wrap-to-fill-column-mode'. +Used by `wrap-to-fill-column-mode'. If nil then center the +display columns. Otherwise it should be a number which will be +the left margin." + :type '(choice (const :tag "Center" nil) + (integer :tag "Left margin")) + :group 'wrap-to-fill) +(make-variable-buffer-local 'wrap-to-fill-left-marg) + +(defvar wrap-to-fill--saved-state nil) +;;(make-variable-buffer-local 'wrap-to-fill--saved-state) +(put 'wrap-to-fill--saved-state 'permanent-local t) + +;;;###autoload +(defcustom wrap-to-fill-left-marg-modes + '(text-mode + fundamental-mode) + "Major modes where `wrap-to-fill-left-margin' may be nil." + :type '(repeat command) + :group 'wrap-to-fill) + + + ;;ThisisaVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongWord ThisisaVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongWord + +(defun wrap-to-fill-wider () + "Increase `fill-column' with 10." + (interactive) + (setq fill-column (+ fill-column 10)) + (wrap-to-fill-set-values-in-buffer-windows)) + +(defun wrap-to-fill-narrower () + "Decrease `fill-column' with 10." + (interactive) + (setq fill-column (- fill-column 10)) + (wrap-to-fill-set-values-in-buffer-windows)) + +(defun wrap-to-fill-normal () + "Reset `fill-column' to global value." + (interactive) + ;;(setq fill-column (default-value 'fill-column)) + (kill-local-variable 'fill-column) + (wrap-to-fill-set-values-in-buffer-windows)) + +(defvar wrap-to-fill-column-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [(control ?c) ?+] 'wrap-to-fill-wider) + (define-key map [(control ?c) ?-] 'wrap-to-fill-narrower) + (define-key map [(control ?c) ?0] 'wrap-to-fill-normal) + map)) + +;; Fix-me: Maybe make the `wrap-prefix' behavior an option or separate +;; minor mode. + +;; Fix-me: better handling of left-column in mumamo buffers (and other +;; if possible). + +;;;###autoload +(define-minor-mode wrap-to-fill-column-mode + "Use `fill-column' display columns in buffer windows. +By default the display columns are centered, but see the option +`wrap-to-fill-left-marg'. + +Fix-me: +Note 1: When turning this on `visual-line-mode' is also turned on. This +is not reset when turning off this mode. + +Note 2: The text properties 'wrap-prefix and 'wrap-to-fill-prefix +is set by this mode to indent continuation lines. + +Key bindings added by this minor mode: + +\\{wrap-to-fill-column-mode-map}" + :lighter " WrapFill" + :group 'wrap-to-fill + ;; (message "wrap-to-fill-column-mode %s, cb=%s, major=%s, multi=%s" wrap-to-fill-column-mode (current-buffer) + ;; major-mode mumamo-multi-major-mode) + (if wrap-to-fill-column-mode + (progn + ;; Old values (idea from visual-line-mode) + (set (make-local-variable 'wrap-to-fill--saved-state) nil) + (dolist (var '(visual-line-mode + ;;left-margin-width + ;;right-margin-width + )) + (push (list var (symbol-value var) (local-variable-p var)) + wrap-to-fill--saved-state)) + ;; Hooks + (add-hook 'window-configuration-change-hook 'wrap-to-fill-set-values nil t) + ;; Wrapping + (visual-line-mode 1) + (wrap-to-fill-set-values-in-buffer-windows)) + ;; Hooks + (remove-hook 'window-configuration-change-hook 'wrap-to-fill-set-values t) + ;; Old values + (dolist (saved wrap-to-fill--saved-state) + (let ((var (nth 0 saved)) + (val (nth 1 saved)) + (loc (nth 2 saved))) + (cond + ((eq var 'visual-line-mode) + (unless val (visual-line-mode -1))) + (t + (if loc + (set (make-local-variable var) val) + (kill-local-variable var)))))) + (kill-local-variable 'wrap-to-fill--saved-state) + ;; Margins + (dolist (win (get-buffer-window-list (current-buffer))) + (set-window-margins win left-margin-width right-margin-width)) + ;; Indentation + (let ((here (point)) + (inhibit-field-text-motion t) + beg-pos + end-pos) + (mumamo-with-buffer-prepared-for-jit-lock + (save-restriction + (widen) + (goto-char (point-min)) + (while (< (point) (point-max)) + (setq beg-pos (point)) + (setq end-pos (line-end-position)) + (when (equal (get-text-property beg-pos 'wrap-prefix) + (get-text-property beg-pos 'wrap-to-fill-prefix)) + (remove-list-of-text-properties + beg-pos end-pos + '(wrap-prefix))) + (forward-line)) + (remove-list-of-text-properties + (point-min) (point-max) + '(wrap-to-fill-prefix))) + (goto-char here)))) + (wrap-to-fill-font-lock wrap-to-fill-column-mode)) +(put 'wrap-to-fill-column-mode 'permanent-local t) + +(defcustom wrap-to-fill-major-modes '(org-mode + html-mode + nxhtml-mode) + "Major modes where to turn on `wrap-to-fill-column-mode'" + ;;:type '(repeat major-mode) + :type '(repeat command) + :group 'wrap-to-fill) + +(defun wrap-to-fill-turn-on-in-buffer () + "Turn on fun for globalization." + (when (catch 'turn-on + (dolist (m wrap-to-fill-major-modes) + (when (derived-mode-p m) + (throw 'turn-on t)))) + (wrap-to-fill-column-mode 1))) + +(define-globalized-minor-mode wrap-to-fill-column-global-mode wrap-to-fill-column-mode + wrap-to-fill-turn-on-in-buffer + :group 'wrap-to-fill) + +;; Fix-me: There is a confusion between buffer and window margins +;; here. Also the doc says that left-margin-width and dito right may +;; be nil. However they seem to be 0 by default, but when displaying a +;; buffer in a window then window-margins returns (nil). + +(defvar wrap-to-fill-timer nil) +(make-variable-buffer-local 'wrap-to-fill-timer) + +(defun wrap-to-fill-set-values () + (when (timerp wrap-to-fill-timer) + (cancel-timer wrap-to-fill-timer)) + (setq wrap-to-fill-timer + (run-with-idle-timer 0 nil 'wrap-to-fill-set-values-in-timer + (selected-window) (current-buffer)))) +(put 'wrap-to-fill-set-values 'permanent-local-hook t) + +(defun wrap-to-fill-set-values-in-timer (win buf) + (condition-case err + (when (buffer-live-p buf) + (wrap-to-fill-set-values-in-buffer-windows buf)) + (error (message "ERROR wrap-to-fill-set-values-in-timer: %s" + (error-message-string err))))) + +(defun wrap-to-fill-set-values-in-timer-old (win buf) + (when (and (window-live-p win) (buffer-live-p buf) + (eq buf (window-buffer win))) + (condition-case err + (with-current-buffer buf + (when wrap-to-fill-column-mode + (wrap-to-fill-set-values-in-window win))) + (error (message "ERROR wrap-to-fill-set-values: %s" + (error-message-string err)))))) + +(defun wrap-to-fill-set-values-in-buffer-windows (&optional buffer) + "Use `fill-column' display columns in buffer windows." + (let ((buf-windows (get-buffer-window-list (or buffer + (current-buffer)) + nil + t))) + (dolist (win buf-windows) + (if wrap-to-fill-column-mode + (wrap-to-fill-set-values-in-window win) + (set-window-buffer nil (current-buffer)))))) + +(defvar wrap-old-win-width nil) +(make-variable-buffer-local 'wrap-old-win-width) +;; Fix-me: compensate for left-margin-width etc +(defun wrap-to-fill-set-values-in-window (win) + (with-current-buffer (window-buffer win) + (when wrap-to-fill-column-mode + (let* ((win-width (window-width win)) + (win-margs (window-margins win)) + (win-full (+ win-width + (or (car win-margs) 0) + (or (cdr win-margs) 0))) + (extra-width (- win-full fill-column)) + (fill-left-marg (unless (memq major-mode wrap-to-fill-left-marg-modes) + (or (when (> left-margin-width 0) left-margin-width) + wrap-to-fill-left-marg))) + (left-marg (if fill-left-marg + fill-left-marg + (- (/ extra-width 2) 1))) + ;; Fix-me: Why do I have to subtract 1 here...??? + (right-marg (- win-full fill-column left-marg 1)) + (need-update nil) + ) + ;; (when wrap-old-win-width + ;; (unless (= wrap-old-win-width win-width) + ;; (message "-") + ;; (message "win-width 0: %s => %s, win-full=%s, e=%s l/r=%s/%s %S %S %S" wrap-old-win-width win-width win-full extra-width left-marg right-marg (window-edges) (window-inside-edges) (window-margins)) + ;; )) + (setq wrap-old-win-width win-width) + (unless (> left-marg 0) (setq left-marg 0)) + (unless (> right-marg 0) (setq right-marg 0)) + (unless nil;(= left-marg (or left-margin-width 0)) + ;;(setq left-margin-width left-marg) + (setq need-update t)) + (unless nil;(= right-marg (or right-margin-width 0)) + ;;(setq right-margin-width right-marg) + (setq need-update t)) + ;;(message "win-width a: %s => %s, win-full=%s, e=%s l/r=%s/%s %S %S %S" wrap-old-win-width win-width win-full extra-width left-margin-width right-margin-width (window-edges) (window-inside-edges) (window-margins)) + (when need-update + ;;(set-window-buffer win (window-buffer win)) + ;;(run-with-idle-timer 0 nil 'set-window-buffer win (window-buffer win)) + ;;(dolist (win (get-buffer-window-list (current-buffer))) + ;; Fix-me: check window width... + (set-window-margins win left-marg right-marg) + ;;) + ;;(message "win-width b: %s => %s, win-full=%s, e=%s l/r=%s/%s %S %S %S" wrap-old-win-width win-width win-full extra-width left-marg right-marg (window-edges) (window-inside-edges) (window-margins)) + ) + )))) + +;; (add-hook 'post-command-hook 'my-win-post-command nil t) +;; (remove-hook 'post-command-hook 'my-win-post-command t) +(defun my-win-post-command () + (message "win-post-command: l/r=%s/%s %S %S %S" left-margin-width right-margin-width (window-edges) (window-inside-edges) (window-margins)) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Font lock + +(defun wrap-to-fill-fontify (bound) + (save-restriction + (widen) + (while (< (point) bound) + (let ((this-bol (if (bolp) (point) + (1+ (line-end-position))))) + (unless (< this-bol bound) (setq this-bol nil)) + (when this-bol + (goto-char (+ this-bol 0)) + (let (ind-str + ind-str-fill + (beg-pos this-bol) + (end-pos (line-end-position))) + (when (equal (get-text-property beg-pos 'wrap-prefix) + (get-text-property beg-pos 'wrap-to-fill-prefix)) + ;; Find indentation + (skip-chars-forward "[:blank:]") + (setq ind-str (buffer-substring-no-properties beg-pos (point))) + ;; Any special markers like -, * etc + (if (and (< (1+ (point)) (point-max)) + (memq (char-after) '(?- ;; 45 + ?– ;; 8211 + ?* + )) + (eq (char-after (1+ (point))) ?\ )) + (setq ind-str-fill (concat " " ind-str)) + (setq ind-str-fill ind-str)) + ;;(setq ind-str-fill (concat " " ind-str)) + (mumamo-with-buffer-prepared-for-jit-lock + (put-text-property beg-pos end-pos 'wrap-prefix ind-str-fill) + (put-text-property beg-pos end-pos 'wrap-to-fill-prefix ind-str-fill)))))) + (forward-line 1)) + ;; Note: doing it line by line and returning t gave problem in mumamo. + (when nil ;this-bol + (set-match-data (list (point) (point))) + t))) + +(defun wrap-to-fill-font-lock (on) + ;; See mlinks.el + (let* ((add-or-remove (if on 'font-lock-add-keywords 'font-lock-remove-keywords)) + (fontify-fun 'wrap-to-fill-fontify) + (args (list nil `(( ,fontify-fun ( 0 'font-lock-warning-face t )))))) + (when fontify-fun + (when on (setq args (append args (list t)))) + (apply add-or-remove args) + (font-lock-mode -1) + (font-lock-mode 1)))) + +(provide 'wrap-to-fill) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; wrap-to-fill.el ends here -- cgit v1.2.3-54-g00ecf