diff options
Diffstat (limited to 'emacs.d/lisp/cursor-chg.el')
-rw-r--r-- | emacs.d/lisp/cursor-chg.el | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/emacs.d/lisp/cursor-chg.el b/emacs.d/lisp/cursor-chg.el new file mode 100644 index 0000000..159d4e1 --- /dev/null +++ b/emacs.d/lisp/cursor-chg.el @@ -0,0 +1,348 @@ +;;; cursor-chg.el --- Change cursor dynamically, depending on the context. +;; +;; Filename: cursor-chg.el +;; Description: Change cursor dynamically, depending on the context. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2006-2009, Drew Adams, all rights reserved. +;; Created: Tue Aug 29 11:23:06 2006 +;; Version: 20.1 +;; Last-Updated: Sat Aug 1 15:14:46 2009 (-0700) +;; By: dradams +;; Update #: 191 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/cursor-chg.el +;; Keywords: cursor, accessibility +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This library provides three kinds of changes to the text cursor: +;; +;; 1. When a buffer is read-only or is in overwrite mode, the cursor +;; type changes to `curchg-overwrite/read-only-cursor-type'. This +;; is controlled by command `change-cursor-mode' and user option +;; `curchg-change-cursor-on-overwrite/read-only-flag'. +;; +;; 2. When an input method is in use, the cursor color changes to +;; `curchg-input-method-cursor-color'. This is controlled by +;; command `change-cursor-mode' and user option +;; `curchg-change-cursor-on-input-method-flag'. +;; +;; 3. When Emacs is idle, the cursor type changes to +;; `curchg-idle-cursor-type'. This is controlled by command +;; `toggle-cursor-type-when-idle'. +;; +;; To turn on all three types of cursor change by default, put the +;; following in your Emacs init file (~/.emacs): +;; +;; (require 'cursor-chg) ; Load this library +;; (change-cursor-mode 1) ; On for overwrite/read-only/input mode +;; (toggle-cursor-type-when-idle 1) ; On when idle +;; +;; Note: Library `oneonone.el' provides the same functionality as +;; library `cursor-chg.el', and more. If you use library +;; `oneonone.el', then do NOT also use library `cursor-chg.el'. +;; +;; Note for Emacs 20: There is a bug in Emacs 20 which can lead to a +;; fatal error (Emacs crash) when using `query-replace' with +;; idle-cursor change enabled. If you use Emacs 20, then consider +;; using `toggle-cursor-type-when-idle' to disable idle-cursor change +;; while you use `query-replace'. +;; +;; User options defined here: +;; +;; `curchg-change-cursor-on-input-method-flag', +;; `curchg-change-cursor-on-overwrite/read-only-flag', +;; `curchg-default-cursor-color', `curchg-default-cursor-type', +;; `curchg-idle-cursor-type', `curchg-input-method-cursor-color', +;; `curchg-overwrite/read-only-cursor-type'. +;; +;; Commands defined here: +;; +;; `change-cursor-mode', `curchg-change-cursor-when-idle-interval', +;; `curchg-set-cursor-type', `curchg-toggle-cursor-type-when-idle', +;; `set-cursor-type', `toggle-cursor-type-when-idle'. +;; +;; Internal variables defined here: +;; +;; `curchg-change-cursor-when-idle-p', `curchg-idle-interval', +;; `curchg-idle-timer', `curchg-last-cursor-type'. +;; +;; Non-interactive functions defined here: +;; +;; `curchg-change-cursor-on-input-method', +;; `curchg-change-cursor-on-overwrite/read-only', +;; `curchg-change-cursor-to-idle-type', +;; `curchg-change-cursor-to-idle-type-off'. +;; +;; Acknowledgements: +;; +;; The cursor-changing on input method and read-only was inspired by +;; Juri Linkov <juri@jurta.org>. Joe Casadonte <joc@netaxs.com> +;; wrote a similar hook (`joc-cursor-type-set-hook'), which he got +;; from Steve Kemp... +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2006/10/28 dadams +;; curchg-default-cursor-color, curchg-input-method-cursor-color: +;; Changed :type to 'color for Emacs 21+. +;; 2006/09/04 dadams +;; curchg-idle-timer: Cancel beforehand, and cancel after defining. +;; curchg-toggle-cursor-type-when-idle: +;; Use curchg-change-cursor-to-idle-type-off on pre-command-hook. +;; Don't read an event; just turn it on. +;; Added: curchg-change-cursor-to-idle-type-off. +;; 2006/09/03 dadams +;; Created. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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: + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;------- User Options ------------------------------------- + +;; Emacs 20 only +(unless (fboundp 'define-minor-mode) + (defcustom change-cursor-mode nil + "*Toggle changing cursor type and color. +Setting this variable directly does not take effect; +use either \\[customize] or command `change-cursor-mode'." + :set (lambda (symbol value) (change-cursor-mode (if value 1 -1))) + :initialize 'custom-initialize-default + :type 'boolean :group 'cursor :require 'cursor-chg)) + +(defcustom curchg-change-cursor-on-input-method-flag t + "*Non-nil means to use a different cursor when using an input method." + :type 'boolean :group 'cursor) + +(defcustom curchg-change-cursor-on-overwrite/read-only-flag t + "*Non-nil means use a different cursor for overwrite mode or read-only." + :type 'boolean :group 'cursor) + +(defcustom curchg-default-cursor-color (or (cdr (assq 'cursor-color default-frame-alist)) + "Red") + "*Default text cursor color for non-special frames." + :type (if (>= emacs-major-version 21) 'color 'string) :group 'cursor) + +(defcustom curchg-default-cursor-type 'bar "*Default text cursor type." + :type 'symbol :group 'cursor) + +(defcustom curchg-idle-cursor-type 'box + "*Text cursor type when Emacs is idle." + :type 'symbol :group 'cursor) + +(defcustom curchg-input-method-cursor-color "Orange" + "*Default cursor color if using an input method. +This has no effect if `curchg-change-cursor-on-input-method-flag' is nil." + :type (if (>= emacs-major-version 21) 'color 'string) :group 'cursor) + +(defcustom curchg-overwrite/read-only-cursor-type 'box + "*Default text cursor type for overwrite mode or read-only buffer. +This applies only to non-special frames. This has no effect if +`curchg-change-cursor-on-overwrite/read-only-flag' is nil." + :type 'symbol :group 'cursor) + + +;;------- Internal Variables ------------------------------- + +(defvar curchg-last-cursor-type curchg-default-cursor-type "Saved last cursor type.") + +(defvar curchg-idle-interval 2 + "Number of seconds to wait before changing to alternate cursor type. +The alternate cursor type is `curchg-idle-cursor-type'. +Do NOT change this yourself to change the wait period; instead, use +`\\[curchg-change-cursor-when-idle-interval]'.") + +(defvar curchg-idle-timer + (progn ; Cancel to prevent duplication. + (when (boundp 'curchg-idle-timer) (cancel-timer curchg-idle-timer)) + (run-with-idle-timer curchg-idle-interval t 'curchg-change-cursor-to-idle-type)) + "Timer used to change the cursor to alternate type when Emacs is idle.") + +;; Turn it off, by default. You must use `toggle-cursor-type-when-idle' to turn it on. +(cancel-timer curchg-idle-timer) + +(defvar curchg-change-cursor-when-idle-p nil + "Non-nil means to use an alternate cursor type whenever Emacs is idle. +Do NOT change this yourself; instead, use `\\[toggle-cursor-type-when-idle]'.") + + +;;------- Commands ----------------------------------------- + +(unless (fboundp 'set-cursor-type) (defalias 'set-cursor-type 'curchg-set-cursor-type)) +;; This is essentially from Juri Linkov <juri@jurta.org>. +(defun curchg-set-cursor-type (cursor-type) + "Set the cursor type of the selected frame to CURSOR-TYPE. +When called interactively, prompt for the type to use. +To get the frame's current cursor type, use `frame-parameters'." + (interactive + (list (intern (completing-read "Cursor type: " + (mapcar 'list '("box" "hollow" "bar" "hbar" nil)))))) + (modify-frame-parameters (selected-frame) (list (cons 'cursor-type cursor-type)))) + +(defalias 'toggle-cursor-type-when-idle 'curchg-toggle-cursor-type-when-idle) +(defun curchg-toggle-cursor-type-when-idle (&optional arg) +"Turn on or off automatically changing cursor type when Emacs is idle. +When on, use `curchg-idle-cursor-type' whenever Emacs is idle. +With prefix argument, turn on if ARG > 0; else turn off." + (interactive "P") + (setq curchg-change-cursor-when-idle-p + (if arg (> (prefix-numeric-value arg) 0) (not curchg-change-cursor-when-idle-p))) + (cond (curchg-change-cursor-when-idle-p + (timer-activate-when-idle curchg-idle-timer) + (add-hook 'pre-command-hook 'curchg-change-cursor-to-idle-type-off) + (message "Turned ON changing cursor when Emacs is idle.")) + (t + (cancel-timer curchg-idle-timer) + (remove-hook 'pre-command-hook 'curchg-change-cursor-to-idle-type-off) + (message "Turned OFF changing cursor when Emacs is idle.")))) + +(defun curchg-change-cursor-when-idle-interval (secs) + "Set wait until automatically change cursor type when Emacs is idle. +Whenever Emacs is idle for this many seconds, the cursor type will +change to `curchg-idle-cursor-type'. + +To turn on or off automatically changing the cursor type when idle, +use `\\[toggle-cursor-type-when-idle]." + (interactive + "nSeconds to idle, before changing cursor type: ") + (timer-set-idle-time curchg-idle-timer + (setq curchg-idle-interval secs) + t)) + +(if (fboundp 'define-minor-mode) + ;; Emacs 21 and later. + (define-minor-mode change-cursor-mode + "Toggle changing cursor type and color. +With numeric ARG, turn cursor changing on if and only if ARG is positive. + +When this mode is on, `curchg-change-cursor-on-input-method' and +`curchg-change-cursor-on-overwrite/read-only-flag' control cursor +changing." + :init-value nil :global t :group 'frames + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +cursor-chg.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" "http://www.emacswiki.org/cgi-bin/wiki/cursor-chg.el") + :link '(url-link :tag "Description" + "http://www.emacswiki.org/cgi-bin/wiki/ChangingCursorDynamically") + :link '(emacs-commentary-link :tag "Commentary" "cursor-chg") + (cond (change-cursor-mode + (if curchg-change-cursor-on-overwrite/read-only-flag + (add-hook 'post-command-hook 'curchg-change-cursor-on-overwrite/read-only) + (curchg-set-cursor-type curchg-default-cursor-type) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-overwrite/read-only)) + (if curchg-change-cursor-on-input-method-flag + (add-hook 'post-command-hook 'curchg-change-cursor-on-input-method) + (setq current-input-method nil) + (curchg-change-cursor-on-input-method) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-input-method))) + (t + (curchg-set-cursor-type curchg-default-cursor-type) + (setq current-input-method nil) + (curchg-change-cursor-on-input-method) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-overwrite/read-only) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-input-method)))) + + ;; Emacs 20 + (defun change-cursor-mode (&optional arg) + "Toggle changing cursor type and color. +With numeric ARG, turn cursor changing on if and only if ARG is positive. + +When this mode is on, `curchg-change-cursor-on-input-method' and +`curchg-change-cursor-on-overwrite/read-only-flag' control cursor +changing." + (interactive "P") + (setq change-cursor-mode + (if arg (> (prefix-numeric-value arg) 0) (not change-cursor-mode))) + (cond (change-cursor-mode + (if curchg-change-cursor-on-overwrite/read-only-flag + (add-hook 'post-command-hook 'curchg-change-cursor-on-overwrite/read-only) + (curchg-set-cursor-type curchg-default-cursor-type) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-overwrite/read-only)) + (if curchg-change-cursor-on-input-method-flag + (add-hook 'post-command-hook 'curchg-change-cursor-on-input-method) + (setq current-input-method nil) + (curchg-change-cursor-on-input-method) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-input-method)) + (message "Change cursor on overwrite/read-only: %s; on input method: %s" + (if curchg-change-cursor-on-overwrite/read-only-flag "ON" "OFF") + (if curchg-change-cursor-on-input-method-flag "ON" "OFF"))) + (t + (curchg-set-cursor-type curchg-default-cursor-type) + (setq current-input-method nil) + (curchg-change-cursor-on-input-method) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-overwrite/read-only) + (remove-hook 'post-command-hook 'curchg-change-cursor-on-input-method) + (message "Turned OFF changing cursor on overwrite/read-only and input method"))))) + + +;;------- Non-Interactive Functions ------------------------ + +;; This is inspired by code from Juri Linkov <juri@jurta.org>. +(defun curchg-change-cursor-on-input-method () + "Set cursor type depending on whether an input method is used or not." + (set-cursor-color (if current-input-method + curchg-input-method-cursor-color + curchg-default-cursor-color))) + +;; This is from Juri Linkov <juri@jurta.org>, with read-only added. +(defun curchg-change-cursor-on-overwrite/read-only () + "Set cursor type differently for overwrite mode and read-only buffer. +That is, use one cursor type for overwrite mode and read-only buffers, +and another cursor type otherwise." + (curchg-set-cursor-type (if (or buffer-read-only overwrite-mode) + curchg-overwrite/read-only-cursor-type + curchg-default-cursor-type))) + +(defun curchg-change-cursor-to-idle-type () + "Change the cursor to `curchg-idle-cursor-type' when Emacs is idle." + (let ((type (cdr (assoc 'cursor-type (frame-parameters))))) + (unless (eq type curchg-idle-cursor-type) + (setq curchg-last-cursor-type type) + (curchg-set-cursor-type curchg-idle-cursor-type)))) + +(defun curchg-change-cursor-to-idle-type-off () + "Turn off changing the cursor to `curchg-idle-cursor-type' when idle." + (when curchg-last-cursor-type (curchg-set-cursor-type curchg-last-cursor-type))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'cursor-chg) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; cursor-chg.el ends here |