Created
March 12, 2013 00:13
-
-
Save ganta/5139150 to your computer and use it in GitHub Desktop.
Emacs 24.3への日本語環境用のパッチです
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git configure.ac configure.ac | |
index 62f53a3..850eaa4 100644 | |
--- configure.ac | |
+++ configure.ac | |
@@ -1571,7 +1571,7 @@ if test "${HAVE_NS}" = yes; then | |
leimdir="\${ns_appresdir}/leim" | |
INSTALL_ARCH_INDEP_EXTRA= | |
fi | |
- NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o" | |
+ NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macim.o" | |
fi | |
CFLAGS="$tmp_CFLAGS" | |
CPPFLAGS="$tmp_CPPFLAGS" | |
@@ -4322,7 +4322,7 @@ case "$opsys" in | |
## 0x690 is the total size of 30 segment load commands (at 56 | |
## each); under Cocoa 31 commands are required. | |
if test "$HAVE_NS" = "yes"; then | |
- libs_nsgui="-framework AppKit" | |
+ libs_nsgui="-framework AppKit -framework Carbon" | |
headerpad_extra=6C8 | |
else | |
libs_nsgui= | |
diff --git lisp/term/common-win.el lisp/term/common-win.el | |
index 8fe10dc..2100e28 100644 | |
--- lisp/term/common-win.el | |
+++ lisp/term/common-win.el | |
@@ -127,6 +127,7 @@ is not used)." | |
(cons (logior (lsh 0 16) 12) 'ns-new-frame) | |
(cons (logior (lsh 0 16) 13) 'ns-toggle-toolbar) | |
(cons (logior (lsh 0 16) 14) 'ns-show-prefs) | |
+ (cons (logior (lsh 0 16) 15) 'mac-change-input-method) | |
)))) | |
(set-terminal-parameter frame 'x-setup-function-keys t))) | |
diff --git lisp/term/ns-win.el lisp/term/ns-win.el | |
index 1aad645..1098599 100644 | |
--- lisp/term/ns-win.el | |
+++ lisp/term/ns-win.el | |
@@ -171,6 +171,7 @@ The properties returned may include `top', `left', `height', and `width'." | |
(define-key global-map [ns-new-frame] 'make-frame) | |
(define-key global-map [ns-toggle-toolbar] 'ns-toggle-toolbar) | |
(define-key global-map [ns-show-prefs] 'customize) | |
+(define-key global-map [mac-change-input-method] 'mac-change-input-method) | |
;; Set up a number of aliases and other layers to pretend we're using | |
@@ -256,14 +257,30 @@ The properties returned may include `top', `left', `height', and `width'." | |
;; editing window.) | |
(defface ns-working-text-face | |
- '((t :underline t)) | |
+ '((((background dark)) :underline "gray80") | |
+ (t :underline "gray20")) | |
"Face used to highlight working text during compose sequence insert." | |
:group 'ns) | |
+(defface ns-marked-text-face | |
+ '((((background dark)) :underline "gray80") | |
+ (t :underline "gray20")) | |
+ "Face used to highlight marked text during compose sequence insert." | |
+ :group 'ns) | |
+ | |
+(defface ns-unmarked-text-face | |
+ '((((background dark)) :underline "gray20") | |
+ (t :underline "gray80")) | |
+ "Face used to highlight marked text during compose sequence insert." | |
+ :group 'ns) | |
+ | |
(defvar ns-working-overlay nil | |
"Overlay used to highlight working text during compose sequence insert. | |
When text is in th echo area, this just stores the length of the working text.") | |
+(defvar ns-marked-overlay nil | |
+ "Overlay used to highlight marked text during compose sequence insert.") | |
+ | |
(defvar ns-working-text) ; nsterm.m | |
;; Test if in echo area, based on mac-win.el 2007/08/26 unicode-2. | |
@@ -271,17 +288,19 @@ When text is in th echo area, this just stores the length of the working text.") | |
(defun ns-in-echo-area () | |
"Whether, for purposes of inserting working composition text, the minibuffer | |
is currently being used." | |
- (or isearch-mode | |
- (and cursor-in-echo-area (current-message)) | |
- ;; Overlay strings are not shown in some cases. | |
- (get-char-property (point) 'invisible) | |
- (and (not (bobp)) | |
- (or (and (get-char-property (point) 'display) | |
- (eq (get-char-property (1- (point)) 'display) | |
- (get-char-property (point) 'display))) | |
- (and (get-char-property (point) 'composition) | |
- (eq (get-char-property (1- (point)) 'composition) | |
- (get-char-property (point) 'composition))))))) | |
+ (setq mac-in-echo-area | |
+ (or isearch-mode | |
+ (and cursor-in-echo-area (current-message)) | |
+ ;; Overlay strings are not shown in some cases. | |
+ (get-char-property (point) 'invisible) | |
+ (and (not (bobp)) | |
+ (or (and (get-char-property (point) 'display) | |
+ (eq (get-char-property (1- (point)) 'display) | |
+ (get-char-property (point) 'display))) | |
+ (and (get-char-property (point) 'composition) | |
+ (eq (get-char-property (1- (point)) 'composition) | |
+ (get-char-property (point) 'composition))))))) | |
+ mac-in-echo-area) | |
;; The 'interactive' here stays for subinvocations, so the ns-in-echo-area | |
;; always returns nil for some reason. If this WASN'T the case, we could | |
@@ -290,6 +309,7 @@ is currently being used." | |
(defun ns-put-working-text () | |
(interactive) | |
(if (ns-in-echo-area) (ns-echo-working-text) (ns-insert-working-text))) | |
+ | |
(defun ns-unput-working-text () | |
(interactive) | |
(ns-delete-working-text)) | |
@@ -311,19 +331,81 @@ The overlay is assigned the face `ns-working-text-face'." | |
(defun ns-echo-working-text () | |
"Echo contents of `ns-working-text' in message display area. | |
See `ns-insert-working-text'." | |
- (ns-delete-working-text) | |
(let* ((msg (current-message)) | |
- (msglen (length msg)) | |
- message-log-max) | |
+ (msglen (length msg)) | |
+ message-log-max) | |
+ (if (integerp ns-working-overlay) | |
+ (progn | |
+ (setq msg (substring msg 0 (- (length msg) ns-working-overlay))) | |
+ (setq msglen (length msg)))) | |
(setq ns-working-overlay (length ns-working-text)) | |
(setq msg (concat msg ns-working-text)) | |
(put-text-property msglen (+ msglen ns-working-overlay) | |
- 'face 'ns-working-text-face msg) | |
+ 'face 'ns-working-text-face msg) | |
+ (message "%s" msg))) | |
+ | |
+(defun ns-put-marked-text (event) | |
+ (interactive "e") | |
+ | |
+ (let ((pos (nth 1 event)) | |
+ (len (nth 2 event))) | |
+ (if (ns-in-echo-area) | |
+ (ns-echo-marked-text pos len) | |
+ (ns-insert-marked-text pos len)))) | |
+ | |
+(defun ns-insert-marked-text (pos len) | |
+ "Insert contents of `ns-working-text' as UTF-8 string and mark with | |
+`ns-working-overlay' and `ns-marked-overlay'. Any previously existing | |
+working text is cleared first. The overlay is assigned the faces | |
+`ns-working-text-face' and `ns-marked-text-face'." | |
+ (ns-delete-working-text) | |
+ (let ((start (point))) | |
+ (if (<= pos (length ns-working-text)) | |
+ (progn | |
+ (put-text-property pos len 'face 'ns-working-text-face ns-working-text) | |
+ (insert ns-working-text) | |
+ (if (= len 0) | |
+ (overlay-put (setq ns-working-overlay | |
+ (make-overlay start (point) (current-buffer) nil t)) | |
+ 'face 'ns-working-text-face) | |
+ (overlay-put (setq ns-working-overlay | |
+ (make-overlay start (point) (current-buffer) nil t)) | |
+ 'face 'ns-unmarked-text-face) | |
+ (overlay-put (setq ns-marked-overlay | |
+ (make-overlay (+ start pos) (+ start pos len) | |
+ (current-buffer) nil t)) | |
+ 'face 'ns-marked-text-face)) | |
+ (goto-char (+ start pos)))))) | |
+ | |
+(defun ns-echo-marked-text (pos len) | |
+ "Echo contents of `ns-working-text' in message display area. | |
+See `ns-insert-working-text'." | |
+ (let* ((msg (current-message)) | |
+ (msglen (length msg)) | |
+ message-log-max) | |
+ (when (integerp ns-working-overlay) | |
+ (setq msg (substring msg 0 (- (length msg) ns-working-overlay))) | |
+ (setq msglen (length msg))) | |
+ (setq ns-working-overlay (length ns-working-text)) | |
+ (setq msg (concat msg ns-working-text)) | |
+ (if (= len 0) | |
+ (put-text-property msglen (+ msglen ns-working-overlay) | |
+ 'face 'ns-working-text-face msg) | |
+ (put-text-property msglen (+ msglen ns-working-overlay) | |
+ 'face 'ns-unmarked-text-face msg) | |
+ (put-text-property (+ msglen pos) (+ msglen pos len) | |
+ 'face 'ns-marked-text-face msg)) | |
(message "%s" msg))) | |
(defun ns-delete-working-text() | |
- "Delete working text and clear `ns-working-overlay'." | |
+ "Delete working text and clear `ns-working-overlay' and `ns-marked-overlay'." | |
(interactive) | |
+ (when (and (overlayp ns-marked-overlay) | |
+ ;; Still alive | |
+ (overlay-buffer ns-marked-overlay)) | |
+ (with-current-buffer (overlay-buffer ns-marked-overlay) | |
+ (delete-overlay ns-marked-overlay))) | |
+ (setq ns-marked-overlay nil) | |
(cond | |
((and (overlayp ns-working-overlay) | |
;; Still alive? | |
@@ -943,6 +1025,426 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") | |
(add-to-list 'window-system-initialization-alist '(ns . ns-initialize-window-system)) | |
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
+;; | |
+;; Implementation of Input Method Extension for MacOS X | |
+;; written by Taiichi Hashimoto <[email protected]> | |
+;; | |
+ | |
+(defvar mac-input-method-parameters | |
+ '( | |
+ ("com.apple.inputmethod.Kotoeri.Roman" | |
+ (title . "A") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Kotoeri.Japanese" | |
+ (title . "あ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Kotoeri.Japanese.Katakana" | |
+ (title . "ア") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Kotoeri.Japanese.FullWidthRoman" | |
+ (title . "A") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Kotoeri.Japanese.HalfWidthKana" | |
+ (title . "ア") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.kotoeri.Ainu" | |
+ (title . "アイヌ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Korean.2SetKorean" | |
+ (title . "가2") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Korean.3SetKorean" | |
+ (title . "가3") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Korean.390Sebulshik" | |
+ (title . "가5") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Korean.GongjinCheongRomaja" | |
+ (title . "가G") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Korean.HNCRomaja" | |
+ (title . "가H") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Tamil.AnjalIM" | |
+ (title . "Anjal") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.Tamil.Tamil99" | |
+ (title . "Tamil") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.VietnameseIM.VietnameseSimpleTelex" | |
+ (title . "ST") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.VietnameseIM.VietnameseTelex" | |
+ (title . "TX") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.VietnameseIM.VietnameseVNI" | |
+ (title . "VN") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.VietnameseIM.VietnameseVIQR" | |
+ (title . "VQ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.SCIM.ITABC" | |
+ (title . "拼") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.SCIM.WBX" | |
+ (title . "型") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.SCIM.WBH" | |
+ (title . "画") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.TCIM.Zhuyin" | |
+ (title . "注") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.TCIM.Pinyin" | |
+ (title . "拼") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.TCIM.Cangjie" | |
+ (title . "倉") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.TCIM.Jianyi" | |
+ (title . "速") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.TCIM.Dayi" | |
+ (title . "易") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.apple.inputmethod.TCIM.Hanin" | |
+ (title . "漢") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.google.inputmethod.Japanese.Roman" | |
+ (title . "G") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.google.inputmethod.Japanese.base" | |
+ (title . "ぐ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.google.inputmethod.Japanese.Katakana" | |
+ (title . "グ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.google.inputmethod.Japanese.FullWidthRoman" | |
+ (title . "G") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.google.inputmethod.Japanese.HalfWidthKana" | |
+ (title . "グ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Roman" | |
+ (title . "K") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Japanese" | |
+ (title . "か") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Japanese.Katakana" | |
+ (title . "カ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Japanese.FullWidthRoman" | |
+ (title . "K") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Japanese.HalfWidthKana" | |
+ (title . "カ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Japanese.HalfWidthRoman" | |
+ (title . "_K") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("jp.monokakido.inputmethod.Kawasemi.Japanese.Code" | |
+ (title . "C") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok22.Roman" | |
+ (title . "A") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok22.Japanese" | |
+ (title . "あ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok22.Japanese.Katakana" | |
+ (title . "ア") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok22.Japanese.FullWidthRoman" | |
+ (title . "英") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok22.Japanese.HalfWidthEiji" | |
+ (title . "半英") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok23.Roman" | |
+ (title . "A") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok23.Japanese" | |
+ (title . "あ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok23.Japanese.Katakana" | |
+ (title . "ア") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok23.Japanese.FullWidthRoman" | |
+ (title . "英") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok23.Japanese.HalfWidthEiji" | |
+ (title . "半英") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok24.Roman" | |
+ (title . "A") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok24.Japanese" | |
+ (title . "あ") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok24.Japanese.Katakana" | |
+ (title . "ア") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok24.Japanese.FullWidthRoman" | |
+ (title . "英") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ("com.justsystems.inputmethod.atok24.Japanese.HalfWidthEiji" | |
+ (title . "半英") | |
+ (cursor-color) | |
+ (cursor-type)) | |
+ ) | |
+ "Alist of Mac script code vs parameters for input method on MacOSX.") | |
+ | |
+ | |
+(defun mac-get-input-method-parameter (is key) | |
+ "Function to get a parameter of a input method." | |
+ (interactive) | |
+ (assq key (cdr (assoc is mac-input-method-parameters)))) | |
+ | |
+(defun mac-get-input-method-title (&optional input-source) | |
+ "Return input method title of input source. | |
+ If input-source is nil, return one of current frame." | |
+ (if input-source | |
+ (cdr (mac-get-input-method-parameter input-source 'title)) | |
+ current-input-method-title)) | |
+ | |
+(defun mac-get-cursor-type (&optional input-source) | |
+ "Return cursor type of input source. | |
+ If input-source is nil, return one of current frame." | |
+ (if input-source | |
+ (or (cdr (mac-get-input-method-parameter input-source 'cursor-type)) | |
+ (cdr (assq 'cursor-type default-frame-alist)) | |
+ cursor-type) | |
+ (cdr (assq 'cursor-type (frame-parameters (selected-frame)))))) | |
+ | |
+(defun mac-get-cursor-color (&optional input-source) | |
+ "Return cursor color of input source. | |
+ If input-source is nil, return one of current frame." | |
+ (if input-source | |
+ (or (cdr (mac-get-input-method-parameter input-source 'cursor-color)) | |
+ (cdr (assq 'cursor-color default-frame-alist))) | |
+ (cdr (assq 'cursor-color (frame-parameters (selected-frame)))))) | |
+ | |
+ | |
+(defun mac-set-input-method-parameter (is key value) | |
+ "Function to set a parameter of a input method." | |
+ (let* ((is-param (assoc is mac-input-method-parameters)) | |
+ (param (assq key is-param))) | |
+ (if is-param | |
+ (if param | |
+ (setcdr param value) | |
+ (setcdr is-param (cons (cons key value) (cdr is-param)))) | |
+ (setq mac-input-method-parameters | |
+ (cons (list is (cons key value)) | |
+ mac-input-method-parameters))))) | |
+ | |
+ | |
+(defun mac-input-method-update (is) | |
+ "Funtion to update parameters of a input method." | |
+ (interactive) | |
+ | |
+ (let ((title (mac-get-input-method-title is)) | |
+ (type (mac-get-cursor-type is)) | |
+ (color (mac-get-cursor-color is))) | |
+ (if (and title (not (equal title (mac-get-input-method-title)))) | |
+ (setq current-input-method-title title)) | |
+ (if (and type (not (equal type (mac-get-cursor-type)))) | |
+ (setq cursor-type type)) | |
+ (if (and color (not (equal color (mac-get-cursor-color)))) | |
+ (set-cursor-color color)) | |
+ (force-mode-line-update) | |
+ (if isearch-mode (isearch-update)))) | |
+ | |
+ | |
+(defun mac-toggle-input-method (&optional arg) | |
+ "Function to toggle input method on MacOSX." | |
+ (interactive) | |
+ | |
+ (if arg | |
+ (progn | |
+ (make-local-variable 'input-method-function) | |
+ (setq inactivate-current-input-method-function 'mac-toggle-input-method) | |
+ (setq input-method-function nil) | |
+ (setq describe-current-input-method-function nil) | |
+ (mac-toggle-input-source t)) | |
+ (kill-local-variable 'input-method-function) | |
+ (setq describe-current-input-method-function nil) | |
+ (mac-toggle-input-source nil))) | |
+ | |
+ | |
+(defun mac-change-language-to-us () | |
+ "Function to change language to us." | |
+ (interactive) | |
+ (mac-toggle-input-method nil)) | |
+ | |
+ | |
+(defun mac-handle-input-method-change () | |
+ "Function run when a input method change." | |
+ (interactive) | |
+ | |
+ (if (equal default-input-method "MacOSX") | |
+ (let ((input-source (mac-get-current-input-source)) | |
+ (ascii-capable (mac-input-source-is-ascii-capable))) | |
+ | |
+ (cond ((and (not current-input-method) (not ascii-capable)) | |
+ (set-input-method "MacOSX")) | |
+ ((and (equal current-input-method "MacOSX") ascii-capable) | |
+ (toggle-input-method nil))) | |
+ (mac-input-method-update input-source)))) | |
+ | |
+;; | |
+;; Emacs input method for input method on MacOSX. | |
+;; | |
+(register-input-method "MacOSX" "MacOSX" 'mac-toggle-input-method | |
+ "Mac" "Input Method on MacOSX System") | |
+ | |
+ | |
+;; | |
+;; Minor mode of using input methods on MacOS X | |
+;; | |
+(define-minor-mode mac-input-method-mode | |
+ "Use input methods on MacOSX." | |
+ :init-value nil | |
+ :group 'ns | |
+ :global t | |
+ | |
+ (if mac-input-method-mode | |
+ (progn | |
+ (setq default-input-method "MacOSX") | |
+ (add-hook 'minibuffer-setup-hook 'mac-change-language-to-us) | |
+ (mac-translate-from-yen-to-backslash)) | |
+ (setq default-input-method nil))) | |
+ | |
+;; | |
+;; Valiable and functions to pass key(shortcut) to system. | |
+;; | |
+(defvar mac-keys-passed-to-system nil | |
+ "A list of keys passed to system on MacOSX.") | |
+ | |
+(defun mac-add-key-passed-to-system (key) | |
+ (let ((shift '(shift shft)) | |
+ (control '(control ctrl ctl)) | |
+ (option '(option opt alternate alt)) | |
+ (command '(command cmd))) | |
+ | |
+ (add-to-list 'mac-keys-passed-to-system | |
+ (cond ((symbolp key) | |
+ (cond ((memq key shift) | |
+ (cons ns-shift-key-mask nil)) | |
+ ((memq key control) | |
+ (cons ns-control-key-mask nil)) | |
+ ((memq key option) | |
+ (cons ns-alternate-key-mask nil)) | |
+ ((memq key command) | |
+ (cons ns-command-key-mask nil)) | |
+ (t (cons nil nil)))) | |
+ ((numberp key) (cons 0 key)) | |
+ ((listp key) | |
+ (let ((l key) (k nil) (m 0)) | |
+ (while l | |
+ (cond ((memq (car l) shift) | |
+ (setq m (logior m ns-shift-key-mask))) | |
+ ((memq (car l) control) | |
+ (setq m (logior m ns-control-key-mask))) | |
+ ((memq (car l) option) | |
+ (setq m (logior m ns-alternate-key-mask))) | |
+ ((memq (car l) command) | |
+ (setq m (logior m ns-command-key-mask))) | |
+ ((numberp (car l)) | |
+ (if (not k) (setq k (car l))))) | |
+ (setq l (cdr l))) | |
+ (cons m k))) | |
+ (t (cons nil nil)))))) | |
+ | |
+ | |
+;; | |
+;; Entry Emacs event for inline input method on MacOSX. | |
+;; | |
+(define-key special-event-map | |
+ [mac-change-input-method] 'mac-handle-input-method-change) | |
+ | |
+;; | |
+;; Convert yen to backslash for JIS keyboard. | |
+;; | |
+(defun mac-translate-from-yen-to-backslash () | |
+ ;; Convert yen to backslash for JIS keyboard. | |
+ (interactive) | |
+ | |
+ (define-key global-map [165] nil) | |
+ (define-key global-map [2213] nil) | |
+ (define-key global-map [3420] nil) | |
+ (define-key global-map [67109029] nil) | |
+ (define-key global-map [67111077] nil) | |
+ (define-key global-map [8388773] nil) | |
+ (define-key global-map [134219941] nil) | |
+ (define-key global-map [75497596] nil) | |
+ (define-key global-map [201328805] nil) | |
+ (define-key function-key-map [165] [?\\]) | |
+ (define-key function-key-map [2213] [?\\]) ;; for Intel | |
+ (define-key function-key-map [3420] [?\\]) ;; for PowerPC | |
+ (define-key function-key-map [67109029] [?\C-\\]) | |
+ (define-key function-key-map [67111077] [?\C-\\]) | |
+ (define-key function-key-map [8388773] [?\M-\\]) | |
+ (define-key function-key-map [134219941] [?\M-\\]) | |
+ (define-key function-key-map [75497596] [?\C-\M-\\]) | |
+ (define-key function-key-map [201328805] [?\C-\M-\\]) | |
+) | |
+ | |
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
+ | |
(provide 'ns-win) | |
;;; ns-win.el ends here | |
diff --git src/Makefile.in src/Makefile.in | |
index e96c788..a674ed2 100644 | |
--- src/Makefile.in | |
+++ src/Makefile.in | |
@@ -356,7 +356,7 @@ obj = $(base_obj) $(NS_OBJC_OBJ) | |
SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ | |
xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \ | |
fontset.o dbusbind.o cygw32.o \ | |
- nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \ | |
+ nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macim.o\ | |
w32.o w32console.o w32fns.o w32heap.o w32inevt.o \ | |
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \ | |
w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \ | |
diff --git src/keyboard.c src/keyboard.c | |
index 47d8780..76251bf 100644 | |
--- src/keyboard.c | |
+++ src/keyboard.c | |
@@ -3862,8 +3862,10 @@ kbd_buffer_get_event (KBOARD **kbp, | |
{ | |
if (event->code == KEY_NS_PUT_WORKING_TEXT) | |
obj = Fcons (intern ("ns-put-working-text"), Qnil); | |
- else | |
+ else if (event->code == KEY_NS_UNPUT_WORKING_TEXT) | |
obj = Fcons (intern ("ns-unput-working-text"), Qnil); | |
+ else if (event->code == KEY_NS_PUT_MARKED_TEXT) | |
+ obj = Fcons (intern ("ns-put-marked-text"), event->arg); | |
kbd_fetch_ptr = event + 1; | |
if (used_mouse_menu) | |
*used_mouse_menu = 1; | |
@@ -12088,6 +12090,8 @@ keys_of_keyboard (void) | |
"ns-put-working-text"); | |
initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text", | |
"ns-unput-working-text"); | |
+ initial_define_lispy_key (Vspecial_event_map, "ns-put-marked-text", | |
+ "ns-put-marked-text"); | |
/* Here we used to use `ignore-event' which would simple set prefix-arg to | |
current-prefix-arg, as is done in `handle-switch-frame'. | |
But `handle-switch-frame is not run from the special-map. | |
diff --git src/macim.m src/macim.m | |
new file mode 100644 | |
index 0000000..443770a | |
--- /dev/null | |
+++ src/macim.m | |
@@ -0,0 +1,183 @@ | |
+/* Implementation of Input Method Extension for MacOS X. | |
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | |
+ Taiichi Hashimoto <[email protected]>. | |
+*/ | |
+ | |
+#include "config.h" | |
+ | |
+#ifdef NS_IMPL_COCOA | |
+ | |
+#include <math.h> | |
+#include <sys/types.h> | |
+#include <time.h> | |
+#include <signal.h> | |
+#include <unistd.h> | |
+ | |
+#include <Carbon/Carbon.h> | |
+ | |
+#include "lisp.h" | |
+#include "blockinput.h" | |
+ | |
+enum output_method | |
+{ | |
+ output_initial, | |
+ output_termcap, | |
+ output_x_window, | |
+ output_msdos_raw, | |
+ output_w32, | |
+ output_mac, | |
+ output_ns | |
+} output_method; | |
+ | |
+#include "termhooks.h" | |
+#include "keyboard.h" | |
+#include "buffer.h" | |
+ | |
+//extern Lisp_Object Qcurrent_input_method; | |
+//extern int cursor_in_echo_area; | |
+static Lisp_Object Qmac_keys_passed_to_system; | |
+ | |
+void mac_init_input_method (); | |
+int mac_pass_key_to_system (int code, int modifiers); | |
+int mac_pass_key_directly_to_emacs (); | |
+int mac_store_change_input_method_event (); | |
+ | |
+DEFUN ("mac-input-source-is-ascii-capable", Fmac_input_source_is_ascii_capable, Smac_input_source_is_ascii_capable, | |
+ 0, 0, 0, | |
+ doc: /* Is current input source ascii capable? */) | |
+ (void) | |
+{ | |
+ TISInputSourceRef is = TISCopyCurrentKeyboardInputSource(); | |
+ CFBooleanRef ret = TISGetInputSourceProperty(is, kTISPropertyInputSourceIsASCIICapable); | |
+ | |
+ return CFBooleanGetValue(ret)? Qt : Qnil; | |
+} | |
+ | |
+DEFUN ("mac-get-input-source-list", Fmac_get_input_source_list, Smac_get_input_source_list, | |
+ 0, 0, 0, | |
+ doc: /* get input source list on MacOSX */) | |
+ (void) | |
+{ | |
+ NSArray *is_list = (NSArray *)TISCreateInputSourceList(NULL, false); | |
+ int list_size = [is_list count]; | |
+ Lisp_Object list[list_size]; | |
+ int i; | |
+ | |
+ for (i = 0; i < list_size; i++) { | |
+ TISInputSourceRef is = (TISInputSourceRef)[is_list objectAtIndex:i]; | |
+ NSString *id = (NSString *)TISGetInputSourceProperty(is, kTISPropertyInputSourceID); | |
+ list[i] = make_string([id UTF8String], | |
+ [id lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); | |
+ } | |
+ | |
+ return Flist(list_size, list); | |
+} | |
+ | |
+DEFUN ("mac-get-current-input-source", Fmac_get_current_input_source, Smac_get_current_input_source, | |
+ 0, 0, 0, | |
+ doc: /* get current input source on MacOSX */) | |
+ (void) | |
+{ | |
+ TISInputSourceRef is = TISCopyCurrentKeyboardInputSource(); | |
+ NSString *id = (NSString *)TISGetInputSourceProperty(is, kTISPropertyInputSourceID); | |
+ | |
+ return make_string([id UTF8String], | |
+ [id lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); | |
+} | |
+ | |
+DEFUN ("mac-toggle-input-source", Fmac_toggle_input_source, Smac_toggle_input_source, | |
+ 1, 1, 0, | |
+ doc: /* toggle input source on MacOSX */) | |
+ (arg) | |
+ Lisp_Object arg; | |
+{ | |
+ TISInputSourceRef is = NULL; | |
+ | |
+ if (NILP (arg)) | |
+ { | |
+ is = TISCopyCurrentASCIICapableKeyboardInputSource(); | |
+ } | |
+ else | |
+ { | |
+ NSString *locale; | |
+ NSArray *languages = [NSLocale preferredLanguages]; | |
+ if (languages != nil) { | |
+ locale = [languages objectAtIndex:0]; | |
+ } else { | |
+ locale = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; | |
+ } | |
+ is = TISCopyInputSourceForLanguage((CFStringRef)locale); | |
+ } | |
+ if (is) TISSelectInputSource(is); | |
+ | |
+ return arg; | |
+} | |
+ | |
+int | |
+mac_store_change_input_method_event () | |
+{ | |
+ Lisp_Object dim; | |
+ int ret = FALSE; | |
+ | |
+ dim = Fsymbol_value (intern ("default-input-method")); | |
+ if (STRINGP (dim) && strcmp(SDATA (dim), "MacOSX") == 0) | |
+ { | |
+ ret = TRUE; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+int | |
+mac_pass_key_to_system (int code, int modifiers) | |
+{ | |
+ Lisp_Object keys = Fsymbol_value (Qmac_keys_passed_to_system); | |
+ Lisp_Object m, k; | |
+ | |
+ while (!NILP (keys)) | |
+ { | |
+ m = XCAR (XCAR (keys)); | |
+ k = XCDR (XCAR (keys)); | |
+ keys = XCDR (keys); | |
+ | |
+ if (NUMBERP (m) && modifiers == XINT (m)) | |
+ if (NILP (k) | |
+ || (NUMBERP (k) && code == XINT (k))) | |
+ return TRUE; | |
+ } | |
+ | |
+ return FALSE; | |
+} | |
+ | |
+int | |
+mac_pass_key_directly_to_emacs (void) | |
+{ | |
+ | |
+ if (NILP (Fmac_input_source_is_ascii_capable())) | |
+ { | |
+ if (NILP (Vmac_use_input_method_on_system) | |
+ || this_command_key_count | |
+ || cursor_in_echo_area | |
+ || !NILP (BVAR (current_buffer, read_only))) | |
+ return TRUE; | |
+ } | |
+ | |
+ return FALSE; | |
+} | |
+ | |
+ | |
+void mac_init_input_method (void) | |
+{ | |
+ Qmac_keys_passed_to_system = intern ("mac-keys-passed-to-system"); | |
+ staticpro (&Qmac_keys_passed_to_system); | |
+ | |
+ DEFVAR_LISP ("mac-use-input-method-on-system", Vmac_use_input_method_on_system, | |
+ doc: /* If it is non-nil, use input method on system. */); | |
+ Vmac_use_input_method_on_system = Qt; | |
+ | |
+ defsubr (&Smac_input_source_is_ascii_capable); | |
+ defsubr (&Smac_get_input_source_list); | |
+ defsubr (&Smac_get_current_input_source); | |
+ defsubr (&Smac_toggle_input_source); | |
+} | |
+#endif | |
diff --git src/nsfns.m src/nsfns.m | |
index 9e89737..78cc927 100644 | |
--- src/nsfns.m | |
+++ src/nsfns.m | |
@@ -107,7 +107,6 @@ static ptrdiff_t image_cache_refcount; | |
========================================================================== */ | |
- | |
void | |
check_ns (void) | |
{ | |
@@ -2702,6 +2701,24 @@ be used as the image of the icon representing the frame. */); | |
doc: /* Toolkit version for NS Windowing. */); | |
Vns_version_string = ns_appkit_version_str (); | |
+ | |
+ DEFVAR_LISP ("ns-shift-key-mask", Vns_shift_key_mask, | |
+ doc: /* Shift key mask defined in system. */); | |
+ Vns_shift_key_mask = make_number (NSShiftKeyMask); | |
+ | |
+ DEFVAR_LISP ("ns-control-key-mask", Vns_control_key_mask, | |
+ doc: /* Control key mask defined in system. */); | |
+ Vns_control_key_mask = make_number (NSControlKeyMask); | |
+ | |
+ DEFVAR_LISP ("ns-alternate-key-mask", Vns_alternate_key_mask, | |
+ doc: /* Alternate key mask defined in system. */); | |
+ Vns_alternate_key_mask = make_number (NSAlternateKeyMask); | |
+ | |
+ DEFVAR_LISP ("ns-command-key-mask", Vns_command_key_mask, | |
+ doc: /* Command key mask defined in system. */); | |
+ Vns_command_key_mask = make_number (NSCommandKeyMask); | |
+ | |
+ | |
defsubr (&Sns_read_file_name); | |
defsubr (&Sns_get_resource); | |
defsubr (&Sns_set_resource); | |
@@ -2746,6 +2763,10 @@ be used as the image of the icon representing the frame. */); | |
defsubr (&Sx_show_tip); | |
defsubr (&Sx_hide_tip); | |
+#ifdef NS_IMPL_COCOA | |
+ mac_init_input_method (); | |
+#endif | |
+ | |
/* used only in fontset.c */ | |
check_window_system_func = check_ns; | |
diff --git src/nsterm.h src/nsterm.h | |
index 806cfcc..610ebe3 100644 | |
--- src/nsterm.h | |
+++ src/nsterm.h | |
@@ -420,6 +420,8 @@ typedef unsigned int NSUInteger; | |
#define KEY_NS_NEW_FRAME ((1<<28)|(0<<16)|12) | |
#define KEY_NS_TOGGLE_TOOLBAR ((1<<28)|(0<<16)|13) | |
#define KEY_NS_SHOW_PREFS ((1<<28)|(0<<16)|14) | |
+#define KEY_MAC_CHANGE_INPUT_METHOD ((1<<28)|(0<<16)|15) | |
+#define KEY_NS_PUT_MARKED_TEXT ((1<<28)|(0<<16)|16) | |
/* could use list to store these, but rest of emacs has a big infrastructure | |
for managing a table of bitmap "records" */ | |
diff --git src/nsterm.m src/nsterm.m | |
index a57e744..7b0e2e9 100644 | |
--- src/nsterm.m | |
+++ src/nsterm.m | |
@@ -4049,6 +4049,9 @@ ns_term_init (Lisp_Object display_name) | |
/* [[NSNotificationCenter defaultCenter] addObserver: NSApp | |
selector: @selector (logNotification:) | |
name: nil object: nil]; */ | |
+ [[NSDistributedNotificationCenter defaultCenter] addObserver: NSApp | |
+ selector: @selector (changeInputMethod:) | |
+ name: @"AppleSelectedInputSourcesChangedNotification" object: nil]; | |
dpyinfo = xzalloc (sizeof *dpyinfo); | |
@@ -4278,6 +4281,21 @@ ns_term_shutdown (int sig) | |
NSLog (@"notification: '%@'", [notification name]); | |
} | |
+- (void)changeInputMethod: (NSNotification *)notification | |
+{ | |
+ | |
+ struct frame *emacsframe = SELECTED_FRAME (); | |
+ | |
+ if (mac_store_change_input_method_event()) | |
+ { | |
+ if (!emacs_event) | |
+ return; | |
+ emacs_event->kind = NS_NONKEY_EVENT; | |
+ emacs_event->code = KEY_MAC_CHANGE_INPUT_METHOD; | |
+ emacs_event->modifiers = 0; | |
+ EV_TRAILER ((id)nil); | |
+ } | |
+} | |
- (void)sendEvent: (NSEvent *)theEvent | |
/* -------------------------------------------------------------------------- | |
@@ -4957,7 +4975,8 @@ not_in_argv (NSString *arg) | |
code, fnKeysym, flags, emacs_event->modifiers); | |
/* if it was a function key or had modifiers, pass it directly to emacs */ | |
- if (fnKeysym || (emacs_event->modifiers | |
+ if (mac_pass_key_directly_to_emacs () | |
+ ||fnKeysym || (emacs_event->modifiers | |
&& (emacs_event->modifiers != shift_modifier) | |
&& [[theEvent charactersIgnoringModifiers] length] > 0)) | |
/*[[theEvent characters] length] */ | |
@@ -4972,8 +4991,18 @@ not_in_argv (NSString *arg) | |
? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT; | |
emacs_event->code = code; | |
- EV_TRAILER (theEvent); | |
- return; | |
+ /* The function mac_pass_key_to_system decides | |
+ whether it is passed directly to emacs or not. */ | |
+ if (emacs_event->kind == NON_ASCII_KEYSTROKE_EVENT | |
+ || !mac_pass_key_to_system (code, flags | |
+ & (NSShiftKeyMask | |
+ | NSControlKeyMask | |
+ | NSAlternateKeyMask | |
+ | NSCommandKeyMask))) | |
+ { | |
+ EV_TRAILER (theEvent); | |
+ return; | |
+ } | |
} | |
} | |
@@ -5067,10 +5096,19 @@ not_in_argv (NSString *arg) | |
NSLog (@"setMarkedText '%@' len =%d range %d from %d", str, [str length], | |
selRange.length, selRange.location); | |
- if (workingText != nil) | |
- [self deleteWorkingText]; | |
if ([str length] == 0) | |
- return; | |
+ { | |
+ [self deleteWorkingText]; | |
+ return; | |
+ } | |
+ else | |
+ { | |
+ if (workingText != nil) { | |
+ [workingText release]; | |
+ workingText = nil; | |
+ processingCompose = NO; | |
+ } | |
+ } | |
if (!emacs_event) | |
return; | |
@@ -5080,7 +5118,9 @@ not_in_argv (NSString *arg) | |
ns_working_text = build_string ([workingText UTF8String]); | |
emacs_event->kind = NS_TEXT_EVENT; | |
- emacs_event->code = KEY_NS_PUT_WORKING_TEXT; | |
+ emacs_event->code = KEY_NS_PUT_MARKED_TEXT; | |
+ emacs_event->arg = Fcons (make_number (selRange.location), | |
+ Fcons (make_number (selRange.length), Qnil)); | |
EV_TRAILER ((id)nil); | |
} | |
@@ -5135,15 +5175,23 @@ not_in_argv (NSString *arg) | |
{ | |
NSRect rect; | |
NSPoint pt; | |
- struct window *win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)); | |
+ // struct window *win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)); | |
+ struct window *win; | |
if (NS_KEYLOG) | |
NSLog (@"firstRectForCharRange request"); | |
+ | |
+ if (NILP (Vmac_in_echo_area)) | |
+ win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)); | |
+ else if (WINDOWP (echo_area_window)) | |
+ win = XWINDOW (echo_area_window); | |
+ else | |
+ win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)); | |
rect.size.width = theRange.length * FRAME_COLUMN_WIDTH (emacsframe); | |
rect.size.height = FRAME_LINE_HEIGHT (emacsframe); | |
pt.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (win, win->phys_cursor.x); | |
pt.y = WINDOW_TO_FRAME_PIXEL_Y (win, win->phys_cursor.y | |
- +FRAME_LINE_HEIGHT (emacsframe)); | |
+ +FRAME_LINE_HEIGHT (emacsframe)+2); | |
pt = [self convertPoint: pt toView: nil]; | |
pt = [[self window] convertBaseToScreen: pt]; | |
@@ -7173,6 +7221,10 @@ variable `x-use-underline-position-properties', which is usually at the | |
baseline level. The default value is nil. */); | |
x_underline_at_descent_line = 0; | |
+ DEFVAR_LISP ("mac-in-echo-area", Vmac_in_echo_area, | |
+ doc: /* state of cursor in echo area. */); | |
+ Vmac_in_echo_area = Qnil; | |
+ | |
/* Tell emacs about this window system. */ | |
Fprovide (intern ("ns"), Qnil); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
inline_patchのRevision 583で他の2つのパッチが取り込まれたため、このgistに記載のパッチは不要になりました。