2.7. Geliştirme ortamı olarak EMACS'ı kullanmak

UNIX sistemleri ne yazık ki her istediğiniz bir pakette toplamış bir geliştirme ortamı ile birlikte gelmiyor. Ama yine de kendi ortamınızı kurabilirsiniz. Diğerleri kadar entegre olmasada ihtiyaçlarınızı karşılamaya yeterli olacaktır.Üstelik bedava olacak , gerektiğinde üzerinde geliştirme yapabilecek ve ortamın kaynak kodlarına siz sahip olacaksınız.

Herşeyin anahtarı EMACS.Bazı insanlar Emacs'tan hoşlanmasa genel itibarı ile insanlar Emac'ı kullanışlı bulur. Eğer ilk bahsedilenlerdenseniz korkarım bu bölüm sizin için değil. Ayrıca programı çalıştırmak için biraz belleğe ihtiyacınız olacak.8mb komut sistemine 16Mb Xwindows sisteminde en az gereken alandır.

Emacs basit bir tanımla : çok esnek , değiştirilebilir bir editördür. Değiştirilebilirliği noktasında bir editörden çok bir işletim sistemi gibi davranır.Birçok geliştirici ve sistem yöneticisi oturum açmaları ihmal edersek. zamanının çoğunu EMACS altında geçirir

Emacs da bulunan her şeyi burada özetlemek imkansız. Ama burada geliştiricilerin ilgisini çekecek bazı özellikler var.

Daha burada nice zikrine muvaffak olamayacağımız özelliği var.

Emacs FreeBSD de emacs portunu (http://www.FreeBSD.org/ports/editors.html)kullanarak kurulabilir.

Kurduktan sonra yeni başlangıç için C-h t ile tutorial sayfasını okuyabilirsiniz.(C-h t : kontrol tuşuna basılı tutup h sonra t tuşuna yalnız olarak basınız). X windows altında fare ile kontrol de edebilirsiniz.

Emacs menülere sahip olmasına rağmen klavye kısayolları sayesinde yapacağınız işleri çok hızlı bir şekilde halledebilirsiniz.Bu yöntem fare ile bir menüyü açıp aradığı şeyi bulduktan sonra tıklamadan çok daha pratiktir.Tecrübeli Emacs kullanıcıları ile konuştuğunuzda M-x replace-s RET foo RET bar RET gibi kullandığını göreceksiniz.

Tuş kombinasyonlarını öğrenmek için menüyü kullanabilirsiniz. Komut sisteminde f10 tuşu ile xwindows altında fare ile hareket ederek bunu gerçekleştirmek mümkün.Ama emacs menu çubuklarına sığmayacak kadar çok özelliği içerisinde barındırıyor.Bizim tavsiyemiz alışıncaya kada menu çubuklarını kullanmanız yönünde.Mesela dosya açmak için ilk başlarda menu kullanabilirsiniz alıştıkça C-x C-f tuş kombinasyonunu tercih edeceksiniz.

Eğer bir tuş kombinasyonunun ne işe yaradığından emin değilseniz help menüsündeki Describe key seçeneği ile tuş kombinasyonunu girerek ne işe yaradığını öğrenebilirsiniz.Ayrıca Command Apropos aracını kullanarak belli bir kelimeyi içeren bütün komutları listeleyip yanında ilişkilendirilmiş tuş kombinasyonunu görebilirsiniz.

Unutmadan yukarıdaki tuş kombinasyonu Meta tuşuna basılı durumda x sonra replace-s komutu (replace-string in kısa ifadesi). Sonra enter tuşu değiştirilmek istenen isim sonra bu ismin yerine ne konacağı yazılıyor. Yukarıdaki komut foo isimlerinin yerine bar kelimesini (string) koyuyor.

Meta tuşu genellikle UNIX bilgisayarlada bulunur ama PC lerde ne yazık ki bulunmadığından onu yerine alt tuşu veya esc tuşu olabilir.

Emacs'tan çıkmak için C-x C-c tuş kombinasyonu kullanılır. Eğer bazı kaydedilmemiş dosyalar varsa Emacs size kaydetmek isteyip istemediğinizi soracaktır.C-z ile Emacs ı arka plana atıp shell'e geçmekte mümkündür.

2.7.1. Emacs'ı özelleştirmek

Emacs çok mükemmel şeyler yapabiliyor, bazıları önceden yapılmış bazıları ise bazı ayarlar ile sağlanabiliyor.

Konfigrasyon için özel bir makro dili kullanmaktansa Lisp'in editörler için düzenlenmiş bir versiyonunu olan Emacs Lisp 'i tercih ediyor. Emacs Lisp ile uğraşmak eğer ileride Common Lisp gibi bir dile başlamak istiyorsanız oldukça faydalı olacaktır. Emacs Lisp Common Lisp'ten gelen bir çok özelliği vardır fakat biraz daha küçük bir dildir ve daha kolaydır.

Emacs Lisp'i öğrenmenin en iyi yolu tutorial'i alıp incelemektir.

(ftp://ftp.gnu.org/old-gnu/emacs/elisp-manual-19-2.4.tar.gz)

Aslında Emacs'ı düzenlemek için her hangi bir lisp bilgisine ihtiyacınız olmayacak. Aşağıda örnek bir .emacs dosyası var ve bu başlangıç için yeterli bir döküman. Bunu sisteminizde ev dizininize kopyaladığınız zaman EMACS bir sonraki açılışta buradaki ayarlara göre konfigüre olacaktır.

2.7.2. Örnek bir .emacs dosyası

Ne yazık ki burada bütün detaylara değinemiyeceğiz ama bir iki önemli noktayı dikkatlerinize arz edelim;

Example 2-1. A sample .emacs file

;;-*-Emacs-Lisp-*-

;;Herhangi bir sorunla karşılaşmamak için dosyanın bir
        kere işlendiğine dair değer atıyoruz.

;; -*-Emacs-Lisp-*-

;; This file is designed to be re-evaled; use the variable first-time
;; to avoid any problems with this.
(defvar first-time t
  "Flag signifying this is the first time that .emacs has been evaled")

;; Meta
(global-set-key "\M- " 'set-mark-command)
(global-set-key "\M-\C-h" 'backward-kill-word)
(global-set-key "\M-\C-r" 'query-replace)
(global-set-key "\M-r" 'replace-string)
(global-set-key "\M-g" 'goto-line)
(global-set-key "\M-h" 'help-command)

;; Function keys
(global-set-key [f1] 'manual-entry)
(global-set-key [f2] 'info)
(global-set-key [f3] 'repeat-complex-command)
(global-set-key [f4] 'advertised-undo)
(global-set-key [f5] 'eval-current-buffer)
(global-set-key [f6] 'buffer-menu)
(global-set-key [f7] 'other-window)
(global-set-key [f8] 'find-file)
(global-set-key [f9] 'save-buffer)
(global-set-key [f10] 'next-error)
(global-set-key [f11] 'compile)
(global-set-key [f12] 'grep)
(global-set-key [C-f1] 'compile)
(global-set-key [C-f2] 'grep)
(global-set-key [C-f3] 'next-error)
(global-set-key [C-f4] 'previous-error)
(global-set-key [C-f5] 'display-faces)
(global-set-key [C-f8] 'dired)
(global-set-key [C-f10] 'kill-compilation)

;; Keypad bindings
(global-set-key [up] "\C-p")
(global-set-key [down] "\C-n")
(global-set-key [left] "\C-b")
(global-set-key [right] "\C-f")
(global-set-key [home] "\C-a")
(global-set-key [end] "\C-e")
(global-set-key [prior] "\M-v")
(global-set-key [next] "\C-v")
(global-set-key [C-up] "\M-\C-b")
(global-set-key [C-down] "\M-\C-f")
(global-set-key [C-left] "\M-b")
(global-set-key [C-right] "\M-f")
(global-set-key [C-home] "\M-<")
(global-set-key [C-end] "\M->")
(global-set-key [C-prior] "\M-<")
(global-set-key [C-next] "\M->")

;; Mouse
(global-set-key [mouse-3] 'imenu)

;; Misc
(global-set-key [C-tab] "\C-q\t")	; Control tab quotes a tab.
(setq backup-by-copying-when-mismatch t)

;; Treat 'y' or <CR> as yes, 'n' as no.
(fset 'yes-or-no-p 'y-or-n-p)
(define-key query-replace-map [return] 'act)
(define-key query-replace-map [?\C-m] 'act)

;; Load packages
(require 'desktop)
(require 'tar-mode)

;; Pretty diff mode
(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
(autoload 'ediff-files-remote "ediff"
  "Intelligent Emacs interface to diff")

(if first-time
    (setq auto-mode-alist
	  (append '(("\\.cpp$" . c++-mode)
		    ("\\.hpp$" . c++-mode)
		    ("\\.lsp$" . lisp-mode)
		    ("\\.scm$" . scheme-mode)
		    ("\\.pl$" . perl-mode)
		    ) auto-mode-alist)))

;; Auto font lock mode
(defvar font-lock-auto-mode-list
  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
  "List of modes to always start in font-lock-mode")

(defvar font-lock-mode-keyword-alist
  '((c++-c-mode . c-font-lock-keywords)
    (perl-mode . perl-font-lock-keywords))
  "Associations between modes and keywords")

(defun font-lock-auto-mode-select ()
  "Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list"
  (if (memq major-mode font-lock-auto-mode-list)
      (progn
	(font-lock-mode t))
    )
  )

(global-set-key [M-f1] 'font-lock-fontify-buffer)

;; New dabbrev stuff
;(require 'new-dabbrev)
(setq dabbrev-always-check-other-buffers t)
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
(add-hook 'emacs-lisp-mode-hook
	  '(lambda ()
	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
	     (set (make-local-variable 'dabbrev-case-replace) nil)))
(add-hook 'c-mode-hook
	  '(lambda ()
	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
	     (set (make-local-variable 'dabbrev-case-replace) nil)))
(add-hook 'text-mode-hook
	  '(lambda ()
	     (set (make-local-variable 'dabbrev-case-fold-search) t)
	     (set (make-local-variable 'dabbrev-case-replace) t)))

;; C++ and C mode...
(defun my-c++-mode-hook ()
  (setq tab-width 4)
  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
  (define-key c++-mode-map "\C-ce" 'c-comment-edit)
  (setq c++-auto-hungry-initial-state 'none)
  (setq c++-delete-function 'backward-delete-char)
  (setq c++-tab-always-indent t)
  (setq c-indent-level 4)
  (setq c-continued-statement-offset 4)
  (setq c++-empty-arglist-indent 4))

(defun my-c-mode-hook ()
  (setq tab-width 4)
  (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
  (define-key c-mode-map "\C-ce" 'c-comment-edit)
  (setq c-auto-hungry-initial-state 'none)
  (setq c-delete-function 'backward-delete-char)
  (setq c-tab-always-indent t)
;; BSD-ish indentation style
  (setq c-indent-level 4)
  (setq c-continued-statement-offset 4)
  (setq c-brace-offset -4)
  (setq c-argdecl-indent 0)
  (setq c-label-offset -4))

;; Perl mode
(defun my-perl-mode-hook ()
  (setq tab-width 4)
  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
  (setq perl-indent-level 4)
  (setq perl-continued-statement-offset 4))

;; Scheme mode...
(defun my-scheme-mode-hook ()
  (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))

;; Emacs-Lisp mode...
(defun my-lisp-mode-hook ()
  (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
  (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
  (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))

;; Add all of the hooks...
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
(add-hook 'c-mode-hook 'my-c-mode-hook)
(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
(add-hook 'perl-mode-hook 'my-perl-mode-hook)

;; Complement to next-error
(defun previous-error (n)
  "Visit previous compilation error message and corresponding source programlisting."
  (interactive "p")
  (next-error (- n)))

;; Misc...
(transient-mark-mode 1)
(setq mark-even-if-inactive t)
(setq visible-bell nil)
(setq next-line-add-newlines nil)
(setq compile-command "make")
(setq suggest-key-bindings nil)
(put 'eval-expression 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'set-goal-column 'disabled nil)
(if (>= emacs-major-version 21)
	(setq show-trailing-whitespace t))

;; Elisp archive searching
(autoload 'format-lisp-programlisting-directory "lispdir" nil t)
(autoload 'lisp-dir-apropos "lispdir" nil t)
(autoload 'lisp-dir-retrieve "lispdir" nil t)
(autoload 'lisp-dir-verify "lispdir" nil t)

;; Font lock mode
(defun my-make-face (face color &optional bold)
  "Create a face from a color and optionally make it bold"
  (make-face face)
  (copy-face 'default face)
  (set-face-foreground face color)
  (if bold (make-face-bold face))
  )

(if (eq window-system 'x)
    (progn
      (my-make-face 'blue "blue")
      (my-make-face 'red "red")
      (my-make-face 'green "dark green")
      (setq font-lock-comment-face 'blue)
      (setq font-lock-string-face 'bold)
      (setq font-lock-type-face 'bold)
      (setq font-lock-keyword-face 'bold)
      (setq font-lock-function-name-face 'red)
      (setq font-lock-doc-string-face 'green)
      (add-hook 'find-file-hooks 'font-lock-auto-mode-select)

      (setq baud-rate 1000000)
      (global-set-key "\C-cmm" 'menu-bar-mode)
      (global-set-key "\C-cms" 'scroll-bar-mode)
      (global-set-key [backspace] 'backward-delete-char)
					;      (global-set-key [delete] 'delete-char)
      (standard-display-european t)
      (load-library "iso-transl")))

;; X11 or PC using direct screen writes
(if window-system
    (progn
      ;;      (global-set-key [M-f1] 'hilit-repaint-command)
      ;;      (global-set-key [M-f2] [?\C-u M-f1])
      (setq hilit-mode-enable-list
	    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
		  scheme-mode)
	    hilit-auto-highlight nil
	    hilit-auto-rehighlight 'visible
	    hilit-inhibit-hooks nil
	    hilit-inhibit-rebinding t)
      (require 'hilit19)
      (require 'paren))
  (setq baud-rate 2400)			; For slow serial connections
  )

;; TTY type terminal
(if (and (not window-system)
	 (not (equal system-type 'ms-dos)))
    (progn
      (if first-time
	  (progn
	    (keyboard-translate ?\C-h ?\C-?)
	    (keyboard-translate ?\C-? ?\C-h)))))

;; Under UNIX
(if (not (equal system-type 'ms-dos))
    (progn
      (if first-time
	  (server-start))))

;; Add any face changes here
(add-hook 'term-setup-hook 'my-term-setup-hook)
(defun my-term-setup-hook ()
  (if (eq window-system 'pc)
      (progn
;;	(set-face-background 'default "red")
	)))

;; Restore the "desktop" - do this as late as possible
(if first-time
    (progn
      (desktop-load-default)
      (desktop-read)))

;; Indicate that this file has been read at least once
(setq first-time nil)

;; No need to debug anything now

(setq debug-on-error nil)

;; All done
(message "All done, %s%s" (user-login-name) ".")
	

2.7.3. Emacs'ın anlayacağı şekilde dillerin alanını genişletmek

Evet bu ayarlar C, C++ Perl ,Lisp ve Sheme dillerinde programlama yapacağınız zaman çok güzel peki ya "whizbang" dili için programlama yapacak olsanız.

Öncelikle yapacağınız iş whizbang ile birlikte gelen .el uzantılı Emacs'a dili tanıtan bir dosyayı bulmak olacaktır. Örnek olarak port içinde şu şekilde aranabilir.

% find /usr/ports/lang/whizbang -name "*.el"
        -print

Bu dosyayı Emacs programının dosyalarının bulunduğu gerekli yerlere kopyalayın bu dizin FreeBSD 2.1 için

/usr/local/share/emacs/site-lisp.

Eğer sizin bulunuğunuz dosya örnek olarak aşağıdaki gibi bir dizinde ise ;

/usr/ports/lang/whizbang/work/misc/whizbang.el

Yapacağınız işlem

# cp /usr/ports/lang/whizbang/work/misc/whizbang.el
        /usr/local/share/emacs/site-lisp

Bundan sonra yapmamız gereken whizbang dili için bir uzantı belirlemek. Diyelim ki .wiz uzantılı olsunlar. Sonra .emacs dosyası altına outo-mode-list yazısının bulunduğu yere aşağıdaki kodları ekleyin

. . . ("\\.lsp$" . lisp-mode) ("\\.wiz$" . whizbang-mode) ("\\.scm$" . scheme-mode) . . .

Bu demek oluyor ki eğer sizin uzantınız .wiz ise otamatik olarak whizbang-moduna geçeceksiniz.

Ayrıca font-lock-outo-mode-list kodunun altında şöyle bir değişiklik yapmanız icab ediyor.

;;Auto font lock mode (defvar font-lock-auto-mode-list (list ’c-mode ’c++-mode ’c++-c-mode ’emacs-lisp-mode
        ’whizbang-mode ’lisp-mode ’perl-mode ’scheme- "List of modes to always start in
        font-lock-mode")

Bu söz dizimine göre renklendirme ayarlarını gerçekleştirecektir.

Bütün yapmanız gereken bu kadar. Eğer bunun dışında bazı şeylerin otomatik olarak gerçekleşmesini istiyorsanız whizbang-mode-hook kodu eklemeniz gerekecektir.