;; -*- emacs-lisp -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; $Id: edit.el,v 1.26 2006/03/06 12:07:06 ole Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Edit initialization
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun my-text-mode-hook ()
  "My hook"
  (auto-fill-mode 1)
  (setq truncate-lines nil))

(add-hook 'text-mode-hook `my-text-mode-hook)

(setq tab-width 8
      ;; this will make sure spaces  are used instead of tabs
      indent-tabs-mode nil)

(if (fboundp 'turn-on-pending-delete)
    (turn-on-pending-delete))

(if (fboundp 'delete-selection-mode)
    (delete-selection-mode 1))

;; Anzeige von TABs und Blanks
(autoload 'blank-mode "blank-mode" "Toggle blank visualization." t)

(defun indent-region-rigidly ()
  (interactive "_")
  (indent-code-rigidly 4))

(defun set-tab-width (width)
  "set tab width"
  (interactive "p")
  (setq tab-width width))

(defun toggle-tab-width ()
  "toggle tab width between 8 and 4"
  (interactive)
  (set-tab-width (if (= tab-width 8) 4 8)))

(defun disable-abbrev-mode ()
   "unconditionally disable abbrev-mode"
   (interactive)
   (abbrev-mode 0))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Enable narrowing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(put 'narrow-to-defun 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'narrow-to-region 'disabled nil)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Open a Line with Indent
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun open-line-reindent (arg)
  "like `open-line' but preserves indentation."
  (interactive "p")
  (while (> arg 0)
    (beginning-of-line)
    (newline-and-indent)
    (previous-line 1)
    (indent-according-to-mode)
    (setq arg (- arg 1))))

(global-set-key [(control o)] 'open-line-reindent)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Ispell
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq-default ispell-dictionary "deutsch8")
(ispell-change-dictionary "deutsch8")
(defvar ispell-prefered-dictionaries '("deutsch8" "english"))

(defun ispell-toggle-dictionary ()
  "Toggle the dictionary use in turn every one out of `ispell-default-dictionarys'"
  (interactive)
  (let ((dict (or ispell-local-dictionary ispell-dictionary))
        (prefered (car ispell-prefered-dictionaries)))
    (when (string= dict prefered)
        (setq ispell-prefered-dictionaries (cdr ispell-prefered-dictionaries))
        (add-to-list 'ispell-prefered-dictionaries prefered t))
    (ispell-change-dictionary (car ispell-prefered-dictionaries))
    (message "Dictionary now: %s" (car ispell-prefered-dictionaries))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_  + Ispell Keys
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar ispell-keymap (make-sparse-keymap "Spelling")
  "Keymap used to globally access spell checking functions")
(define-key mode-specific-map [?i] ispell-keymap)

(define-key ispell-keymap [?i] 'ispell-complete-word)
(define-key ispell-keymap [?w] 'ispell-word)
(define-key ispell-keymap [?r] 'ispell-region)
(define-key ispell-keymap [?b] 'ispell-buffer)
(define-key ispell-keymap [?m] 'ispell-message)
(define-key ispell-keymap [?c] 'ispell-comments-and-strings)
(define-key ispell-keymap [?d] 'ispell-change-dictionary)
(define-key ispell-keymap [?t] 'ispell-toggle-dictionary)
(define-key ispell-keymap [?m] 'ispell-message)

(define-key ispell-keymap [?f] 'flyspell-mode)
;;(define-key flyspell-mode-map [(control c) tab] 'flyspell-auto-correct-previous-word)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Pager
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'pager)
(global-set-key "\C-v"     'pager-page-down)
(global-set-key [next]     'pager-page-down)
(global-set-key "\ev"      'pager-page-up)
(global-set-key [prior]    'pager-page-up)
(global-set-key '[M-up]    'pager-row-up)
(global-set-key '[M-kp-8]  'pager-row-up)
(global-set-key '[M-down]  'pager-row-down)
(global-set-key '[M-kp-2]  'pager-row-down)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Completion
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'hippie-exp)

(setq hippie-expand-try-functions-list
      '(try-complete-lisp-symbol
        try-complete-lisp-symbol-partially
        try-complete-file-name-partially
        try-complete-file-name
;       try-expand-list
;       try-expand-line
        ))

(defmacro make-region-indent-completion-function (completion-command &optional indent-command)
  (let ((mark-active (if (boundp mark-active) 'mark-active 'zmacs-region-active-p))
        (indent (or indent-command '(indent-for-tab-command))))
    `(lambda ()
       (interactive)
       (if ,mark-active
           (indent-region (mark) (point) nil)
         (if (save-excursion (skip-chars-backward " \t") (bolp))
             ,indent
           ,completion-command)))))


(add-to-list 'load-path (expand-file-name "predictive/" emacs-packages-dir))
(require 'predictive)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Generic Modes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq generic-define-unix-modes t
      generic-define-mswindows-modes t)
(require 'generic-x)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* More Editing / Movement Keys
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(global-set-key [(meta ?g)] 'goto-line)
(global-set-key [(control meta ?g)] ' keyboard-escape-quit)

(global-set-key [(control meta left)] 'windmove-left)
(global-set-key [(control meta right)] 'windmove-right)
(global-set-key [(control meta up)] 'windmove-up)
(global-set-key [(control meta down)] 'windmove-down)


;;;_* Dvorak Keyboard Remappings
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar oa:dvorak-keys
  `(("M-?" ,#'help-command)
    ("C-'" ,#'quoted-insert)
    ("C-c TAB" ,#'expand-abbrev)
    ("M-RET" ,#'indent-new-comment-line)
    ("M-p" ,#'pop-tag-mark)
    
    ;; Basic Movement
    ("C-n" ,#'forward-char)
    ("C-h" ,#'backward-char)
    ("C-t" ,#'previous-line)
    ("C-w" ,#'next-line)
    ("C-b" ,#'backward-delete-char)
    
    ("M-n" ,#'forward-sexp)
    ("M-h" ,#'backward-sexp)
    ("M-t" ,#'backward-up-list)
    ("M-w" ,#'down-list)
    ("M-b" ,#'backward-kill-sexp)

    ;; Word Movement
    ("C-M-n" ,#'forward-word)
    ("C-M-h" ,#'backward-word)
    ("C-M-t" ,#'backward-paragraph)
    ("C-M-w" ,#'forward-paragraph)
    ("C-M-b" ,#'backward-kill-word)
    
    ("M-S-u" ,#'upcase-word)
    ("M-S-l" ,#'downcase-word)
    ("M-S-c" ,#'capitalize-word)

    ;; killing and yanking
    ("C-," ,#'kill-region)
    ("M-," ,#'copy-region-as-kill)
    ("C-q" ,#'kill-line)
    ("C-j" ,#'yank)
    ("M-j" ,#'yank-pop)))

(defvar oa:de-keys
  `(("M-?" ,#'help-command)
    ("C-q" ,#'quoted-insert)
    ("C-z" ,#'advertised-undo)
    
     ;; Basic Movement
    ("C-l" ,#'forward-char)
    ("C-h" ,#'backward-char)
    ("C-k" ,#'previous-line)
    ("C-j" ,#'next-line)
    ("C-f" ,#'kill-line)
    ("C-b" ,#'backward-delete-char)

    ;; Word Movement
    ("M-l" ,#'forward-word)
    ("M-h" ,#'backward-word)
    ("M-k" ,#'backward-paragraph)
    ("M-j" ,#'forward-paragraph)
    ("M-b" ,#'backward-kill-word)
    ("M-n" ,#'forward-sentence)
    ("M-p" ,#'backward-sentence)

    ("C-M-l" ,#'end-of-buffer)
    ("C-M-h" ,#'beginning-of-buffer)
    ("C-M-k" ,#'pager-page-up)
    ("C-M-j" ,#'pager-page-down)
    ("C-M-b" ,#'backward-kill-paragraph)
    ("C-M-n" ,#'forward-list)
    ("C-M-p" ,#'backward-list)

    ("C-x k" ,#'scroll-other-window-down)
    ("C-x j" ,#'scroll-other-window)))

(defun oa:setup-keys (map bindings)
  (dolist (binding bindings)
    (let ((keyspec (car binding))
          (func (cadr binding)))
      (define-key map (read-kbd-macro keyspec) func))))

;; (oa:setup-keys global-map oa:de-keys)

(oa:setup-keys global-map oa:dvorak-keys)