Develop and Download Open Source Software

Browse Subversion Repository

Contents of /zenitani/CarbonEmacs/src/lisp/mac-key-mode.el

Parent Directory Parent Directory | Revision Log Revision Log


Revision 701 - (show annotations) (download)
Sun Jan 3 01:51:34 2010 UTC (3 years, 4 months ago) by zenitani
File size: 17932 byte(s)
update
1 ;;; mac-key-mode.el --- provide mac-style key bindings on Carbon Emacs
2
3 ;; Copyright (C) 2004-2010 Seiji Zenitani
4
5 ;; Author: Seiji Zenitani <zenitani@mac.com>
6 ;; $Id$
7 ;; Keywords: tools, mac
8 ;; Created: 2004-12-27
9 ;; Compatibility: Mac OS X 10.5 (Carbon Emacs)
10 ;; URL(jp): http://macwiki.sourceforge.jp/wiki/index.php/MacKeyMode
11 ;; URL(en): http://www.emacswiki.org/cgi-bin/emacs-en/MacKeyMode
12
13 ;; Contributors: Tetsuro Kurita, Nozomu Ando, Dave Peck
14
15 ;; This file is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 3, or (at your option)
18 ;; any later version.
19
20 ;; This file is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ;; GNU General Public License for more details.
24
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs; see the file COPYING. If not, write to
27 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 ;; Boston, MA 02111-1307, USA.
29
30 ;;; Commentary:
31
32 ;; This package provides mac-key-mode, a minor mode that provides
33 ;; mac-like key bindings and relevant elisp functions.
34 ;;
35 ;; To use this package, add these lines to your .emacs file:
36 ;;
37 ;; ;; (require 'redo+)
38 ;; (require 'mac-key-mode)
39 ;; (mac-key-mode 1)
40 ;;
41 ;; Note that mac-key-mode requires redo+.el.
42 ;; In order to set additional key bindings,
43 ;; modify mac-key-mode-map in your .emacs file:
44 ;;
45 ;; (require 'mac-key-mode)
46 ;; (define-key mac-key-mode-map [(alt l)] 'goto-line)
47 ;;
48 ;; When mac-key-mode is on, command key is recognized as 'alt' key,
49 ;; but option (alt) key is also recognized as 'alt' key.
50 ;; If you would like to use option (alt) key as meta key,
51 ;; add the below line to your .emacs.el.
52 ;;
53 ;; (add-hook 'mac-key-mode-hook
54 ;; (lambda()
55 ;; (interactive)
56 ;; (if mac-key-mode
57 ;; (setq mac-option-modifier 'meta)
58 ;; (setq mac-option-modifier nil)
59 ;; )))
60 ;;
61 ;; Mac-key-mode takes advantage of additional functions, provided by
62 ;; the mac-functions.patch <http://homepage.mac.com/zenitani/comp-e.html>.
63 ;; (e.g. mac-spotlight-search, mac-spotlight-search etc.)
64
65
66 ;;; Code:
67
68 ;; requires redo+
69 (require 'redo+)
70
71 (defgroup mac-key-mode nil
72 "Mac-style key-binding mode."
73 :group 'mac
74 :version "22.3")
75 (defconst mac-key-mode-lighter
76 (char-to-string 343416) ;; the command mark
77 ;; (char-to-string 323935) ;; the Apple mark
78 ;; (char-to-string (ucs-to-char 63743)) ;; the Apple mark
79 "A lighter string which is displayed in the modeline
80 when `mac-key-mode' is on.")
81
82 (defcustom mac-key-mode-hook nil
83 "The hook to run when mac-key-mode is toggled."
84 :type 'hook
85 :group 'mac-key-mode)
86
87 (defcustom mac-key-advanced-setting t
88 "If non-nil, `mac-key-mode' activates addional settings:
89 1) menu items are added to the File menu and the Edit menu, and
90 2) the SPC key invokes Quick Look information in dired-mode."
91 :group 'mac-key-mode
92 :type 'boolean)
93
94 (defvar mac-key-backup-command-modifier nil
95 "Internal variable. Do not use this.")
96
97
98 ;; process objects
99 (defvar mac-key-speech-process nil
100 "The process object for text-to-speech subprocess.")
101 (defvar mac-key-ql-process nil
102 "The process object for Quick Look subprocess.")
103
104
105 (defvar mac-key-mode-map
106 (let ((map (make-sparse-keymap)))
107 (define-key map [(alt o)] (lambda()(interactive)(let(last-nonmenu-event)(menu-find-file-existing))))
108 (define-key map [(alt w)] 'mac-key-close-window)
109 (define-key map [(alt s)] 'save-buffer)
110 (define-key map [(alt shift s)] 'mac-key-save-as)
111 (define-key map [(alt i)] 'mac-key-show-in-finder)
112 (define-key map [(alt p)] 'print-buffer)
113 (define-key map [(alt q)] 'save-buffers-kill-emacs)
114 (define-key map [(alt z)] 'undo)
115 (define-key map [(alt shift z)] 'redo) ; requires redo+
116 (define-key map [(alt x)] 'clipboard-kill-region)
117 (define-key map [(alt c)] 'clipboard-kill-ring-save)
118 (define-key map [(alt v)] 'clipboard-yank)
119 (define-key map [(alt a)] 'mark-whole-buffer)
120 (define-key map [(alt f)] 'isearch-forward)
121 (define-key map [(alt meta f)] 'occur)
122 (define-key map [(alt g)] 'isearch-repeat-forward)
123 (define-key map [(alt shift g)] 'isearch-repeat-backward)
124 (define-key map [(alt l)] 'goto-line)
125 (define-key map [(alt t)] 'mac-font-panel-mode)
126 (define-key map [(alt m)] 'iconify-frame)
127 (define-key map [(alt \`)] 'other-frame)
128 (define-key map [(alt shift n)] 'make-frame-command)
129 (define-key map [(alt shift w)] 'delete-frame)
130 (define-key map [(alt \?)] 'info)
131 (define-key map [(alt /)] 'info)
132 (define-key map [(alt .)] 'keyboard-quit)
133 (define-key map [(alt up)] 'beginning-of-buffer)
134 (define-key map [(alt down)] 'end-of-buffer)
135 (define-key map [(alt left)] 'beginning-of-line)
136 (define-key map [(alt right)] 'end-of-line)
137 (define-key map [A-mouse-1] 'browse-url-at-mouse)
138 (define-key map [C-down-mouse-1] 'mac-key-context-menu)
139 (define-key map [mouse-3] 'mac-key-context-menu)
140 ;; (define-key map [C-mouse-1] 'mac-key-context-menu)
141 (define-key map [A-S-mouse-1] 'mouse-buffer-menu)
142 (define-key map [S-down-mouse-1] 'mac-key-shift-mouse-select)
143
144 map)
145 "Keymap for `mac-key-mode'.")
146
147 ;; mode-line menu
148 (define-key-after mode-line-mode-menu [mac-key-mode]
149 `(menu-item ,(purecopy
150 (concat "Mac Key (" mac-key-mode-lighter ")"))
151 mac-key-mode :button (:toggle . mac-key-mode))
152 'highlight-changes-mode)
153
154 ;;;###autoload
155 (define-minor-mode mac-key-mode
156 "Toggle Mac Key mode.
157 With arg, turn Mac Key mode on if arg is positive.
158 When Mac Key mode is enabled, mac-style key bindings are provided."
159 :global t
160 :group 'mac-key-mode
161 :lighter (" " mac-key-mode-lighter)
162 :keymap 'mac-key-mode-map
163 (if mac-key-mode
164 (progn
165
166 (setq mac-key-backup-command-modifier mac-command-modifier)
167 (setq mac-command-modifier 'alt)
168 (if (boundp 'mac-key-mode-internal)
169 (setq mac-key-mode-internal t))
170
171 ;; turn on advanced settings
172 (when mac-key-advanced-setting
173
174 ;; menu items
175 (define-key-after menu-bar-file-menu [mac-key-file-separator]
176 '("--" . nil) 'recover-session)
177 (define-key-after menu-bar-file-menu [mac-key-show-in-finder]
178 '(menu-item "Show In Finder" mac-key-show-in-finder
179 :help "Display current file/directory in a Finder window"
180 :enable (or (and (boundp 'buffer-file-name) buffer-file-name)
181 (and (boundp 'dired-directory) dired-directory)))
182 'mac-key-file-separator)
183 (define-key-after menu-bar-file-menu [mac-key-open-terminal]
184 '(menu-item "Open Terminal" mac-key-open-terminal
185 :help "Launch Terminal.app and go to the relevant directory")
186 'mac-key-show-in-finder)
187 (define-key-after menu-bar-edit-menu [redo]
188 '(menu-item "Redo" redo
189 :help "Redo the most recent undo"
190 :enable (not (or (eq buffer-undo-list t)
191 (eq last-buffer-undo-list nil)
192 ;; ** one more thing here **
193 (eq buffer-undo-list pending-undo-list)
194 (eq (cdr buffer-undo-list) pending-undo-list)
195 )))
196 'undo)
197 (define-key-after menu-bar-edit-menu [mac-key-edit-separator]
198 '("--" . nil) 'redo)
199
200 ;; assign mac-key-quick-look to the SPC key
201 (if (boundp 'dired-mode-map)
202 (define-key dired-mode-map " " 'mac-key-quick-look)
203 (add-hook 'dired-mode-hook
204 (lambda () (interactive)
205 (define-key dired-mode-map " " 'mac-key-quick-look)))
206 )
207
208 ))
209 (progn
210
211 (setq mac-command-modifier mac-key-backup-command-modifier)
212 (if (boundp 'mac-key-mode-internal)
213 (setq mac-key-mode-internal nil))
214
215 ;; turn off advanced settings
216 (when mac-key-advanced-setting
217
218 ;; menu items
219 (global-unset-key [menu-bar file mac-key-file-separator])
220 (global-unset-key [menu-bar file mac-key-show-in-finder])
221 (global-unset-key [menu-bar file mac-key-open-terminal])
222 (global-unset-key [menu-bar edit redo])
223 (global-unset-key [menu-bar edit mac-key-edit-separator])
224
225 ;; restore SPC to dired-next-line (a bad way to deal with it)
226 (if (boundp 'dired-mode-map)
227 (define-key dired-mode-map " " 'dired-next-line))
228 (remove-hook 'dired-mode-hook
229 (lambda () (interactive)
230 (define-key dired-mode-map " " 'mac-key-quick-look)))
231
232 ))
233 ))
234
235
236 ;; close window (command + W)
237 (defun mac-key-close-window ()
238 "Close the Quick Look window or kill the current buffer."
239 (interactive)
240 (let ((mybuffer (and mac-key-ql-process
241 (process-buffer mac-key-ql-process))))
242 (if (buffer-live-p mybuffer)
243 (kill-buffer mybuffer)
244 (kill-this-buffer))
245 ))
246
247 ;; save as.. dialog (shift + command + S)
248 (defun mac-key-save-as (filename &optional wildcards)
249 "Write current buffer to another file using standard file open dialog."
250 (interactive
251 (let (last-nonmenu-event)
252 (find-file-read-args "Write file: " nil)))
253 (write-file filename))
254
255
256 ;; utf8 code by Ando-san
257 (defun mac-key-applescript-utf8data (str)
258 (let ((len (length str))
259 (len1 31) ;XXX: 254/2/4. utf-8 is 4byte per code point at most.
260 (reslist '(")"))
261 pos epos)
262 (setq pos len)
263 (while (> pos 0)
264 (setq epos pos)
265 (setq pos (max (- pos len1) 0))
266 (setq reslist (cons " & (\307data utf8"
267 (cons (mapconcat (lambda (ch) (format "%02X" ch))
268 (encode-coding-string
269 (substring str pos epos)
270 'utf-8) "")
271 (cons "\310 as Unicode text)"
272 reslist)))))
273 (apply 'concat "(\"\"" reslist)))
274
275
276 ;; Show In Finder (command + I)
277
278 (defun mac-key-show-in-finder (&optional path)
279 "Display current file/directory in a Finder window"
280 (interactive)
281 (let ((item (or path
282 (and (boundp 'buffer-file-name) buffer-file-name)
283 (and (eq major-mode 'dired-mode) default-directory)) ))
284
285 (cond
286 ((not (stringp item)))
287 ((file-remote-p item)
288 (error "This item is located on a remote system."))
289 (t
290 (setq item (expand-file-name item))
291 (condition-case err
292 (progn
293 (do-applescript
294 (concat
295 "tell application \"Finder\" to select ("
296 (mac-key-applescript-utf8data item)
297 " as POSIX file)"))
298 (if (fboundp 'mac-process-activate)
299 (mac-process-activate "com.apple.finder")
300 (do-applescript "tell application \"Finder\" to activate"))
301 )
302 (error err)))
303
304 )))
305
306
307 ;; Open Terminal.app
308
309 (defun mac-key-open-terminal (&optional path)
310 "Launch Terminal and go to the relevant directory"
311 (interactive)
312 (let ((item (or path default-directory)))
313
314 (cond
315 ((not (stringp item)))
316 ((file-remote-p item)
317 (error "This item is located on a remote system."))
318 ((file-directory-p item)
319 (setq item (expand-file-name item))
320 (condition-case err
321 (progn
322 (do-applescript
323 (concat "tell application \"Terminal\" to do script"
324 " with command \"cd \" & quoted form of "
325 (mac-key-applescript-utf8data item)))
326 (if (fboundp 'mac-process-activate)
327 (mac-process-activate "com.apple.Terminal")
328 (do-applescript "tell application \"Terminal\" to activate"))
329 )
330 (error err))
331 )
332 (t (error "An error occured"))
333 )))
334
335
336 ;; Text-to-Speech functions
337
338 (defun mac-key-speak-buffer ()
339 "Speak buffer contents."
340 (interactive)
341 (mac-key-speak-region (point-min)(point-max)))
342
343 (defun mac-key-speak-region (beg end)
344 "Speak the region contents."
345 (interactive "r")
346 (mac-key-stop-speaking)
347 (let ((buffer-file-coding-system 'utf-8-unix)
348 (tmp-file (make-temp-file "emacs-speech-" nil ".txt")))
349 (write-region beg end tmp-file nil)
350 (message "Invoking text-to-speech...")
351 (setq mac-key-speech-process
352 (start-process "text-to-speech" "*Text-to-Speech Output*"
353 "/usr/bin/say" "-f" tmp-file))
354 ))
355
356 (defun mac-key-stop-speaking ()
357 "Terminate the text-to-speech subprocess, if it is running."
358 (interactive)
359 (let ((mybuffer (and mac-key-speech-process
360 (process-buffer mac-key-speech-process))))
361 (when (buffer-live-p mybuffer)
362 (kill-buffer mybuffer)
363 (beep))
364 ))
365
366
367 ;; Quick Look
368 ;; inspired by http://journal.mycom.co.jp/column/osx/263/index.html
369
370 (defun mac-key-quick-look ()
371 "Display the Quick Look information for the current line's file.
372 You might use dired-mode-hook to use this function in dired mode,
373 like this:
374
375 \(add-hook 'dired-mode-hook
376 (lambda() (local-set-key \" \" 'mac-key-quick-look)))
377 "
378 (interactive)
379
380 (let ((mybuffer (and mac-key-ql-process
381 (process-buffer mac-key-ql-process)))
382 (item default-directory))
383 (cond
384 ((buffer-live-p mybuffer)
385 (kill-buffer mybuffer))
386 ;; (eq (process-status mac-key-ql-process) 'run)
387 ;; (kill-process mac-key-ql-process))
388 ((file-remote-p item)
389 (error "This item is located on a remote system."))
390 (t
391 (setq item (expand-file-name item))
392 (condition-case err
393 (setq item (dired-get-file-for-visit))
394 (error err))
395 (condition-case err
396 (setq mac-key-ql-process
397 (start-process "quicklook" "*QuickLook Output*"
398 "/usr/bin/qlmanage" "-p"
399 (shell-quote-argument item)))
400 (error err)))
401 )))
402
403 ;; shift+click
404 ;; Contributed by Dave Peck
405
406 (defun mac-key-shift-mouse-select (event)
407 "Set the mark and then move point to the position clicked on with
408 the mouse. This should be bound to a mouse click event type."
409 (interactive "e")
410 (mouse-minibuffer-check event)
411 (if mark-active (exchange-point-and-mark))
412 (set-mark-command nil)
413 ;; Use event-end in case called from mouse-drag-region.
414 ;; If EVENT is a click, event-end and event-start give same value.
415 (posn-set-point (event-end event)))
416
417
418 ;; Contextual menu
419
420 (defun mac-key-context-menu (event)
421 "Pop up a contextual menu."
422 (interactive "e")
423
424 (let ((editable (not buffer-read-only))
425 (pt (save-excursion (mouse-set-point last-nonmenu-event)))
426 beg end
427 )
428
429 ;; getting word boundaries
430 (if (and mark-active
431 (<= (region-beginning) pt) (<= pt (region-end)) )
432 (setq beg (region-beginning)
433 end (region-end))
434 (save-excursion
435 (goto-char pt)
436 (setq end (progn (forward-word) (point)))
437 (setq beg (progn (backward-word) (point)))
438 ))
439
440 ;; popup menu
441 (popup-menu
442 '(nil
443 ["Search in Spotlight"
444 (mac-spotlight-search (buffer-substring-no-properties beg end))
445 :active (fboundp 'mac-spotlight-search)
446 :help "Do a Spotlight search of word at cursor"]
447 ["Search in Google"
448 (browse-url
449 (concat "http://www.google.com/search?q="
450 (url-hexify-string (buffer-substring-no-properties beg end))))
451 :help "Ask a WWW browser to do a Google search"]
452 ["--" nil]
453 ["Look Up in Dictionary"
454 (browse-url
455 (concat "dict:///"
456 (url-hexify-string (buffer-substring-no-properties beg end))))
457 :active t
458 :help "Look up word at cursor in Dictionary.app"]
459 ["--" nil]
460 ["Cut" (clipboard-kill-region beg end) :active (and editable mark-active)
461 :help "Delete text in region and copy it to the clipboard"]
462 ["Copy" (clipboard-kill-ring-save beg end) :active mark-active
463 :help "Copy text in region to the clipboard"]
464 ["Paste" (clipboard-yank) :active editable
465 :help "Paste text from clipboard"]
466 ["--" nil]
467 ("Spelling"
468 ["Spelling..."
469 (progn (goto-char end)(ispell-word)) :active editable
470 :help "Spell-check word at cursor"]
471 ["Check Spelling" (ispell-buffer) :active editable
472 :help "Check spelling of the current buffer"]
473 ["Check Spelling as You Type"
474 (flyspell-mode)
475 :style toggle :selected flyspell-mode :active editable
476 :help "Check spelling while you edit the text"]
477 )
478 ("Font"
479 ["Show Fonts" (ignore) :active nil]
480 ["Bold" (ignore) :active nil]
481 ["Italic" (ignore) :active nil]
482 ["Underline" (ignore) :active nil]
483 ["Outline" (ignore) :active nil]
484 ["Styles..." (ignore) :active nil]
485 ["--" nil]
486 ["Show Colors" (ignore) :active nil]
487 )
488 ("Speech"
489 ["Start Speaking"
490 (if (and mark-active
491 (<= (region-beginning) pt) (<= pt (region-end)) )
492 (mac-key-speak-region beg end)
493 (mac-key-speak-buffer) )
494 :help "Speak text through the sound output"]
495 ["Stop Speaking" (mac-key-stop-speaking)
496 :active (and mac-key-speech-process
497 (eq (process-status mac-key-speech-process) 'run))
498 :help "Stop speaking"]
499 )
500 ["--" nil]
501 ["Buffers" mouse-buffer-menu
502 :help "Pop up a menu of buffers for selection with the mouse"]
503 ))))
504
505
506 (provide 'mac-key-mode)
507
508 ;;; mac-key-mode.el ends here.

Properties

Name Value
svn:keywords Id

SourceForge.JP is a Japanese version of SourceForge.net. For developments that are not related to Japan, we recommend you to use SourceForge.net.