summaryrefslogtreecommitdiffstats
path: root/emacs.d/lisp/cursor-chg.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs.d/lisp/cursor-chg.el')
-rw-r--r--emacs.d/lisp/cursor-chg.el348
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