1 ;; emchat-utils.el --- misc utils for EMchat -*- Emacs-Lisp -*-
3 ;; Copyright (C) 2007 Steve Youngs
5 ;; Author: Steve Youngs <steve@emchat.org>
6 ;; Maintainer: Steve Youngs <steve@emchat.org>
7 ;; Created: <2007-09-01>
8 ;; Homepage: http://www.emchat.org/
9 ;; Keywords: utils ICQ emchat
11 ;; This file is part of EMchat.
13 ;; Redistribution and use in source and binary forms, with or without
14 ;; modification, are permitted provided that the following conditions
17 ;; 1. Redistributions of source code must retain the above copyright
18 ;; notice, this list of conditions and the following disclaimer.
20 ;; 2. Redistributions in binary form must reproduce the above copyright
21 ;; notice, this list of conditions and the following disclaimer in the
22 ;; documentation and/or other materials provided with the distribution.
24 ;; 3. Neither the name of the author nor the names of any contributors
25 ;; may be used to endorse or promote products derived from this
26 ;; software without specific prior written permission.
28 ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
29 ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 ;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 ;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
38 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ;; This is where any general-purpose utils for EMchat go
46 (defvar emchat-all-aliases))
48 (defcustom emchat-glyph-dir
49 (file-name-as-directory (or (locate-data-directory "emchat") ""))
50 "Directory where icons and logos live."
52 :group 'emchat-interface)
54 ;;; Internal variables
56 (defmacro emchat-do-in-xemacs (&rest body)
57 "Execute BODY if in XEmacs."
58 (when (featurep '(and xemacs (not sxemacs)))
61 (put 'emchat-do-in-xemacs 'lisp-indent-hook 'defun)
63 (defmacro emchat-do-in-sxemacs (&rest body)
64 "Execute BODY if in SXEmacs."
65 (when (featurep 'sxemacs)
68 (put 'emchat-do-in-sxemacs 'lisp-indent-hook 'defun)
70 (defun emchat-completing-read
71 (prompt table &optional predicate require-match initial-contents history)
72 "Args: PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-CONTENTS, HISTORY.
73 Same as `completing-read' but accepts strings as well as obarray."
77 table (mapcar 'list table))
78 predicate require-match initial-contents history))
80 (defun emchat-numeric-uin (uin)
81 "Return UIN as number.
82 UIN can be either a string or number."
83 (cond ((numberp uin) uin)
84 ((stringp uin) (string-to-number uin))
85 (t (error "Invalid UIN type" uin))))
87 (defun emchat-stringular-uin (uin)
88 "Return UIN as a string.
89 UIN can be either a string or a number."
90 (cond ((numberp uin) (number-to-string uin))
92 (t (error "Invalid UIN type" uin))))
94 (defun emchat-valid-uin-p (uin)
95 "Return non-nil if UIN is a valid uin."
96 (not (zerop (emchat-numeric-uin uin))))
98 (defun emchat-completing-aliases (prompt &optional single)
99 "Completing-read aliases/uin.
100 PROMPT is the prompt for reading.
101 SINGLE means read only one alias/uin.
103 Must at least complete one alias, use RET (empty string) to finish
104 entering. It first completing-reads from the union of `emchat-active-aliases'
105 and `emchat-connected-aliases'. If you hit RET and the input string is not in
106 the union it the completing-reads from `emchat-all-aliases'.
108 Tips: You can also enter an uin in place of an alias."
110 ;; a must for first one
111 (cons (emchat-completing-alias prompt 'required)
113 (loop collect (emchat-completing-alias prompt nil)
115 ;; empty string means abort
116 until (string= (car (last aliases)) "")
117 finally return (nbutlast aliases))))))
118 (delete-duplicates aliases :test 'string=)))
120 (defun emchat-completing-alias (prompt required)
121 "Completing only one alias/uin.
122 PROMPT is the prompt for reading.
123 REQUIRED means cannot abort.
124 Used by `emchat-completing-aliases'.
125 No abortion when `** ' is in prompt.
126 Abort by RET (empty string) when `++ ' is in prompt."
127 (let ((all emchat-all-aliases)
129 (emchat-completing-read
132 nil nil nil 'emchat-alias-history)))
137 (emchat-valid-uin-p alias)
139 (and (string= alias "")
143 (emchat-completing-read
144 (concat (if required "** " "++ ") prompt)
145 all nil t alias 'emchat-alias-history))
146 while (and (string= alias "") required)))
149 (defun emchat-switch-buffer (buffer)
151 (select-window (get-buffer-window buffer))))
155 (provide 'emchat-utils)
156 ;;; emchat-utils.el ends here