OSXWS10.6のEmacsのデフォルト設定を提供する仕組み(変更案)

最終更新: 2011年1月28日

更新履歴

1月28日: 山本さんにコメントを頂き message を追加。

Emacs の設定ファイルを提供する仕組みについて、Vine Linuxメーリングリスト"vine-default の仕組みを新しくしました"というのがあった。たしかに現行では、hookを使わないとユーザの設定が上書きされて反映されない可能性がある。それをシンプルな方法で解決している。

一方今のOSXWS(10.6β)は、OSXWS 以外の Emacs (Carbon Emacs パッケージ/Aquamacs/自分でビルド) を起動した時に OSXWSがデフォルトで用意した設定を読み込まれないようにするために、init.el の条件分岐で init_osxws.el をロードしそこから各設定ファイルをロードするという込み入った仕組みにしている。init.el を編集することで設定を無効にすることは簡単だけど、一部を変更したいユーザーはどこに書くべきかを知らないといけないし、再びデフォルトを使いたくなった時に戻す方法も知らなければいけない。これらを考えると今の方法が良いとは言えない。

そこでOSXWSでもVine Linuxの新しい考え方をそのまま採用させてもらうことを提案したい(追記:採用してもらうことになった)。

提案の概要

これによってOSXWSが提供するEmacsは以下のような形になる。

  • OSXWS は Emacs をある程度設定した状態で提供する
  • ユーザは自由に init.el を書け、その設定が優先される。
  • 最初からOSXWSの設定を読み込みたくない場合は変数 osxws-default を nil にする
  • 一部の設定を読み込みたくない場合は対応する osxws-default-* を nilnil にする

新しく用意された osxws-default などの変数を設定する場所にだけ制約があるが、それさえ了解してもらえれば、より自然な形で Emacs を使うことができる。

仕組み

以下の手順で、目的が達成できる。

  • ユーザーの init.el を読む直前にロードされる osxws.el から、~/.emacs.d/setup-osxws-default.el を読みに行って osxws-default-* などの変数を拾ってくる。
  • その後に osxws.el から osxws-default.el をロードする。個々の設定の有効/無効は osxws-default.el の中の条件分岐を行う。
  • ユーザの init.el はその後にロードされる。

移行時にOSXWSがすること

  • 移行前にユーザのホームディレクトリにある ~/.emacs.d/init.el をリネーム。
  • OSX-Preferences パッケージは新しい ~/.emacs.d/init.el を提供。(ほぼ白紙かコメントのみ)
  • OSX-Preferences パッケージに ~/.emacs.d/setup-osxws-default.el を追加。
  • emacs-lisps パッケージに新しい osxws.el
  • emacs-lisps パッケージにデフォルト設定ファイル osxws-default.el
  • emacs-lisps パッケージにYaTeXのデフォルト設定ファイル osxws-default-yatex.el

この方法を採用する事になれば、以上のような変更を加える必要があるため、移行後にユーザは init_osxws.el などに書き加えた自分のカスタマイズが反映されないという状況になる。

あと考えなければいけない事は

  • この仕組みで不備はないか?Emacsの標準的な考え方、作法に違反していないか?
  • 将来の修正など、長期的なメンテナンスに耐えるか?
  • OSXWS10.6でいきなり変更して混乱しないか?

識者の方々の意見を聞きたい所です。(追記:Vine LinuxEmacsメンテナ山本さんにコメントを頂きました)

/usr/osxws/etc/emacs-23.2/site-start.d/99osxws.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  osxws.el for MacOS X WorkShop
;;            KOBAYASHI Taizo <xxxxxxx@xxxxxxx>
;; Time-stamp: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; setting the MacOS X WorkShop flag
(defconst osxws-emacs-flag t 
  "This is Emacs of MacOS X WorkShop.")

(setq emacs-build-system 
      (concat 
       emacs-build-system
       " - MacOS X WorkShop - 10.6 "))

(setq report-emacs-bug-address "osxws@xxxxxxxxxxx")

(defcustom osxws-default t
  "A boolean for all OSX Workshop default settings"
  :type 'boolean)

(defcustom osxws-default-base t
  "A boolean for loading osxws-setting section 0 (fundamental configurations)"
  :type 'boolean)

(defcustom osxws-default-language t
  "A boolean for loading osxws-setting section 1 (language)"
  :type 'boolean)

(defcustom osxws-default-appearance t
  "A boolean for loading osxws-setting section 2 (appearance)"
  :type 'boolean)

(defcustom osxws-default-keyboard t
  "A boolean for loading osxws-setting section 3 (keyboard/keybinding)"
  :type 'boolean)

(defcustom osxws-default-shell t
  "A boolean for loading osxws-setting section 4 (shell-command)"
  :type 'boolean)

(defcustom osxws-default-inlinepatch t
  "A boolean for loading osxws-setting section 5 (inline patch)"
  :type 'boolean)

(defcustom osxws-default-cocoaemacs t
  "A boolean for loading osxws-setting section 6 (Cocoa Emacs)"
  :type 'boolean)

(defcustom osxws-default-else t
  "A boolean for loading osxws-setting section 7 (anything else)"
  :type 'boolean)

(defcustom osxws-default-yatex t
  "A boolean for loading osxws-setting for YaTeX"
  :type 'boolean)

(if (file-exists-p (concat user-emacs-directory "setup-osxws-default.el"))
    (load-file (concat user-emacs-directory "setup-osxws-default.el")))

(when osxws-default
    (message "Starting osxws-default ...")
    (load-file "/usr/osxws/share/emacs/site-lisp/emacs-lisps/osxws-default.el")
    (if osxws-default-yatex
        (load-file "/usr/osxws/share/emacs/site-lisp/emacs-lisps/osxws-default-yatex.el")
    )
  )

(setq custom-file "~/.emacs.d/custom_osxws.el")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Local Variables:
;; mode: emacs-lisp
;; buffer-file-coding-system: junet-unix
;; End:

~/.emacs.d/setup-osxws-default.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  setup-osxws-default.el for MacOS X WorkShop
;;            KOBAYASHI Taizo <xxxxxxx@xxxxxxx>
;; Time-stamp: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MacOS X WorkShop provides the default setting for Emacs.
;; The setting is written in the following file:
;; /usr/osxws/share/emacs/site-lisp/emacs-lisps/osxws-default.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can inactivate all by setting the variable osxws-defaul to nil.
;; (setq osxws-default nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can inactivate each section of the setting by setting the variables osxws-defaul-* to nil.
;;(setq osxws-default-base nil)
;;(setq osxws-default-language nil)
;;(setq osxws-default-appearance nil)
;;(setq osxws-default-keyboard nil)
;;(setq osxws-default-shell nil)
;;(setq osxws-default-inlinepatch nil)
;;(setq osxws-default-cocoaemacs  nil)
;;(setq osxws-default-else nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can inactivate the default setting for YaTeX by
;;(setq osxws-default-yatex nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Local Variables:
;; mode: emacs-lisp
;; buffer-file-coding-system: junet-unix
;; End:

/usr/osxws/share/emacs/site-lisp/emacs-lisps/osxws-default.el は、これまでosxws-sec?.elと分割していたものを1つにまとめたもの。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; osxws-default.el for MacOS X WorkShop
;; Time-stamp: <2011-01-01 14:59:01 seto>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 0 fundamental configurations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-base 
  ;; path setting
  (setq exec-path
	(append
	 (list "/usr/osxws/bin" "~/bin") exec-path))
  (setenv "PATH" 
	  (concat '"/usr/osxws/bin:~/bin:" (getenv "PATH")))
  
  ;; save the position before you editing.
  (require 'saveplace)
  (setq-default save-place t)
  (setq save-place-file "~/Library/Application Support/OSXWS/emacs-places.txt")
  
  ;; copy foo to foo~ as a backup file
  (setq backup-by-copying t)
  ;; deleting files goes to OS's trash folder
  (setq delete-by-moving-to-trash t)
  ;; start emacsclient server
  (server-start)
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 1 language configurations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-language
  ;; japanese settings for Cocoa Emacs Package
  (if (equal (substring (shell-command-to-string "defaults read -g AppleLocale") 0 2) "jp")
      (progn
	(set-language-environment 'Japanese)
	(prefer-coding-system  'utf-8-unix)
	))
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 2 appearance setting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-appearance
  ;; hide tool-bar and menu-bar
  (if window-system
      (tool-bar-mode 0)
    (menu-bar-mode 0))

  ;; show the corresponding paren 
  (show-paren-mode)
  
  ;; do not font scaling
  (setq scalable-fonts-allowed nil)
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 3 keyboard/keybinding
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-keyboard
  ;; emulation of the standard CUA key bindings (Mac GUI)
  (cua-selection-mode t)

 ;; font resize short cut (Command +/-/0)
  (global-set-key [(s ?+)] (lambda () (interactive) (text-scale-increase 1)))
  (global-set-key [(s ?-)] (lambda () (interactive) (text-scale-decrease 1)))
  (global-set-key [(s ?0)] (lambda () (interactive) (text-scale-increase 0)))

  ;; Delete the following character by fn + delete 
  (define-key global-map [kp-delete] 'delete-char)
  
  ;;  fix yen key problem on JIS keyboard
  ;; Ando-san's code (see [Macemacsjp-users 1126])
  (define-key global-map [2213] nil)
  (define-key global-map [67111077] nil)
  (define-key function-key-map [2213] [?\\])
  (define-key function-key-map [67111077] [?\C-\\]) 
  
  (define-key global-map [3420] nil)
  (define-key global-map [67112284] nil)
  (define-key function-key-map [3420] [?\\])
  (define-key function-key-map [67112284] [?\C-\\])
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 4 shell-command
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-shell
  ;; hide password 
  (add-hook 'comint-output-filter-functions
	    'comint-watch-for-password-prompt)
  
  ;; escape sequence
  (autoload 'ansi-color-for-comint-mode-on "ansi-color"
    "Set `ansi-color-for-comint-mode' to t." t)
  (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 5 inline-patch by Hashimoto-san
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-inlinepatch
  (when window-system
    (setq default-input-method "MacOSX")
    (add-hook 'minibuffer-setup-hook 'mac-change-language-to-us)
    ;;  (mac-add-ignore-shortcut '(control))
    (mac-add-key-passed-to-system 'shift)
    (mac-set-input-method-parameter "com.apple.inputmethod.Kotoeri.Roman" `title "あ")
    (mac-set-input-method-parameter "com.apple.inputmethod.Kotoeri.Roman" `cursor-type 'box)
    (mac-set-input-method-parameter "com.apple.inputmethod.Kotoeri.Japanese" `cursor-color "red"))
  
  ;; start up by Command-Space
  (global-set-key [(alt \ )] 'toggle-input-method)
  ;; start up by Shift-Space
  (global-set-key [?\S-\ ] 'toggle-input-method)
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 6 CocoaEmacs window mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-cocoaemacs
  (when window-system
     (let* ((size 14)
           (asciifont "Menlo")
           ;;(asciifont "Monaco")
           ;;(asciifont "Courier")
           ;;(asciifont "Andale Mono")
           (jpfont "Hiragino Maru Gothic ProN")
           ;;(jpfont "Hiragino Kaku Gothic ProN")
           ;;(jpfont "Hiragino Mincho ProN")
           ;;(jpfont "Osaka")
           (h (* size 10))
           (fontspec (font-spec :family asciifont))
           (jp-fontspec (font-spec :family jpfont)))
      (set-face-attribute 'default nil :family asciifont :height h)
      (set-fontset-font nil 'japanese-jisx0213.2004-1 jp-fontspec)
      (set-fontset-font nil 'japanese-jisx0213-2 jp-fontspec)
      (set-fontset-font nil 'katakana-jisx0201 jp-fontspec) ; 半角カナ
      (set-fontset-font nil '(#x0370 . #x03FF) fontspec) ; ギリシャ文字 
    )
    (setq face-font-rescale-alist
    	'(("^-apple-hiragino.*" . 1.2)
   	  (".*osaka-bold.*" . 1.2)
	  (".*osaka-medium.*" . 1.2)
	  (".*courier-bold-.*-mac-roman" . 1.0)
	  (".*monaco cy-bold-.*-mac-cyrillic" . 0.9)
	  (".*monaco-bold-.*-mac-roman" . 0.9)
	  ("-cdac$" . 1.3)))
     
    ;;----------------------------------------------------------
    ;; smart-dnd 
    (require 'smart-dnd)
    
    ;; yahtml-mode:
    (add-hook
     'yahtml-mode-hook
     '(lambda ()
	(smart-dnd-setup
	 '(
	   ("\\.gif\\'" . "<img src=\"%R\">\n")
	   ("\\.jpg\\'" . "<img src=\"%R\">\n")
	   ("\\.png\\'" . "<img src=\"%R\">\n")
	   ("\\.css\\'" . "<link rel=\"stylesheet\" type=\"text/css\" href=\"%R\">\n" )
	   ("\\.js\\'"  . "<script type=\"text/javascript\" src=\"%R\"></script>\n" )
	   (".*" . "<a href=\"%R\">%f</a>\n")))))
    
    ;; yatex-mode:
    (add-hook
     'yatex-mode-hook
     '(lambda ()
	(smart-dnd-setup
	 '(
	   ("\\.tex\\'" . "\\input{%r}\n")
	   ("\\.cls\\'" . "\\documentclass{%f}\n")
	   ("\\.sty\\'" . "\\usepackage{%f}\n")
	   ("\\.eps\\'" . "\\includegraphics[clip]{%r}\n")
	   ("\\.ps\\'"  . "\\includegraphics[clip]{%r}\n")
	   ("\\.pdf\\'" . "\\includegraphics[clip]{%r}\n")
	   ("\\.jpg\\'" . "\\includegraphics[clip]{%r}\n")
	   ("\\.png\\'" . "\\includegraphics[clip]{%r}\n")
	   ("\\.bst\\'" . "\\bibliographystyle{%n}\n")
	   ("\\.bib\\'" . "\\bibliography{%n}\n")))))
    
    ;; C/C++ mode:
    (add-hook 
     'c-mode-common-hook
     '(lambda () (smart-dnd-setup '(("\\.h\\'" . "#include <%f>")))))
    ;;----------------------------------------------------------
    )
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 7 anything else
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(when osxws-default-else
  ;; The number of lines to scroll a window by when point moves out
  (setq scroll-step 1)
  
  ;; Time Stamp
  ;;   If you put 'Time-stamp: <>' or 'Time-stamp: ""' on
  ;;   top 8 lines of the file, the '<>' or '""' are filled with the date
  ;;   at saving the file.
  (require 'time-stamp)
  (if (not (memq 'time-stamp write-file-functions))
      (setq write-file-functions
	    (cons 'time-stamp write-file-functions)))
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Local Variables:
;; mode: emacs-lisp
;; buffer-file-coding-system: junet-unix
;; End: