5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

emacs-inline.patchをEmacs HEAD(24.4.50.2)に当ててみました

Last updated at Posted at 2014-06-11

MacEmacs JPで配布されているemacs-inline.patchEmacs HEADのGitレポジトリ(24.4.50.2)に当ててみました。もちろんそのままではうまく当たりませんでしたが、手パッチを繰り返した結果が以下のdiffです。

emacs-inline-for-HEAD.patch
diff --git a/configure.ac b/configure.ac
index 084dccc..367b004 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1792,7 +1792,7 @@ if test "${HAVE_NS}" = yes; then
      INSTALL_ARCH_INDEP_EXTRA=
   fi
 
-  NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o $macfont_file"
+  NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o $macfont_file macim.o"
 fi
 CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
@@ -4829,7 +4829,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 -framework Cocoa"
      if test "$NS_IMPL_COCOA" = "yes"; then
         libs_nsgui="$libs_nsgui -framework IOKit"
      fi
diff --git a/lisp/term/common-win.el b/lisp/term/common-win.el
index ba59c75..90f52c0 100644
--- a/lisp/term/common-win.el
+++ b/lisp/term/common-win.el
@@ -136,6 +136,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 a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 47d953a..e122486 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -168,6 +168,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
@@ -253,14 +254,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.
@@ -268,17 +285,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
@@ -308,19 +327,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?
@@ -964,6 +1045,466 @@ 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 <taiichi2@mac.com>
+;;
+
+(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.atok21.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese.HalfWidthEiji"
+     (title . "半英")
+     (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))
+    ("com.justsystems.inputmethod.atok25.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.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 a/src/Makefile.in b/src/Makefile.in
index bda4623..e5649d0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -365,7 +365,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 macfont.o \
+  nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o macim.o \
   w32.o w32console.o w32fns.o w32heap.o w32inevt.o w32notify.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 a/src/keyboard.c b/src/keyboard.c
index dcf8913..f57c15c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3961,8 +3961,10 @@ kbd_buffer_get_event (KBOARD **kbp,
         {
           if (event->code == KEY_NS_PUT_WORKING_TEXT)
             obj = list1 (intern ("ns-put-working-text"));
-          else
+          else if (event->code == KEY_NS_UNPUT_WORKING_TEXT)
             obj = list1 (intern ("ns-unput-working-text"));
+          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;
@@ -11704,6 +11706,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 a/src/macim.m b/src/macim.m
new file mode 100644
index 0000000..6545f5f
--- /dev/null
+++ b/src/macim.m
@@ -0,0 +1,173 @@
+/* Implementation of Input Method Extension for MacOS X.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Taiichi Hashimoto <taiichi2@mac.com>.
+*/
+
+#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"
+
+#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 a/src/nsfns.m b/src/nsfns.m
index 5f9588a..98866e6 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -546,7 +546,6 @@ x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
   ns_set_name_internal (f, name);
 }
 
-
 void
 ns_set_name_as_filename (struct frame *f)
 {
@@ -2950,6 +2949,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);
@@ -2993,6 +3010,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
+
   as_status = 0;
   as_script = Qnil;
   as_result = 0;
diff --git a/src/nsterm.h b/src/nsterm.h
index d2c42c5..bd1eecf 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -482,6 +482,8 @@ extern EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
 #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 a/src/nsterm.m b/src/nsterm.m
index 6b617be..3905f51 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4240,6 +4240,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);
 
@@ -4507,6 +4510,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
 /* --------------------------------------------------------------------------
@@ -5260,7 +5278,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] */
@@ -5275,7 +5294,16 @@ not_in_argv (NSString *arg)
               ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT;
 
           emacs_event->code = code;
-          EV_TRAILER (theEvent);
+          if (emacs_event->kind == NON_ASCII_KEYSTROKE_EVENT
+              || !mac_pass_key_to_system (code, flags
+                                          & (NSShiftKeyMask
+                                             | NSControlKeyMask
+                                             | NSAlternateKeyMask
+                                             | NSCommandKeyMask)))
+            {
+              EV_TRAILER (theEvent);
+              return;
+            }
           processingCompose = NO;
           return;
         }
@@ -5377,10 +5405,19 @@ not_in_argv (NSString *arg)
            (unsigned long)selRange.length,
            (unsigned long)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;
@@ -5390,7 +5427,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);
 }
 
@@ -5445,15 +5484,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];
@@ -7719,6 +7766,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 (Qns, Qnil);
 
diff --git a/src/termhooks.h b/src/termhooks.h
index f9bf9d7..b16c77d 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -49,8 +49,9 @@ enum output_method
   output_x_window,
   output_msdos_raw,
   output_w32,
+  output_mac,
   output_ns
-};
+} output_method;
 
 /* Input queue declarations and hooks.  */
 

以上のdiffは、EmacsのGitレポジトリを手元にcloneしてからspikeブランチを切ってspikeブランチにコミット、その後git diff master spikeすることで生成しています。パッチとしてはいつ当たらなくなるか分かりませんので、以前やったようにこのパッチを使ったEmacsのFormulaをHomebrewに対してpull requestする、といったことは考えていません。
なお、私はbrew diyしてからインストールしています。

5
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?