;;;; -*-Mode:LISP; Package:LISP; Base:10; Syntax:EmacsLisp -*-
;;;; Date:   2022/07/19
;;;; Title:  .emacs
;;;; Author: C. Jullien

(require 'cc-mode)
(require 'ido)

(autoload 'View-scroll-line-forward  "view" nil t)
(autoload 'View-scroll-line-backward "view" nil t)
(autoload 'bat-mode                  "bat-mode" "DOS and WIndows BAT files" t)

;; Set up the keyboard so the delete key on both the regular keyboard
;; and the keypad delete the character under the cursor and to the
;; right under X, instead of the default, backspace behavior.

(global-set-key [delete]    'delete-char)
(global-set-key [kp-delete] 'delete-char)
(global-set-key (kbd "C-$") 'dabbrev-expand)
(global-set-key (kbd "M-$") 'compare-windows)
(global-set-key (kbd "M-g") 'goto-line) ;; Default is M-gg or M-gM-g
(global-set-key [f5]        'undo)
(global-set-key [f9]        'call-last-kbd-macro)
(global-set-key [C-home]    'View-scroll-line-backward)
(global-set-key [C-end]     'View-scroll-line-forward)
(global-set-key [f1]        (lambda ()
                               (interactive)
                               (manual-entry (current-word))))

;; Special keys on macOS
;;
;; Missing characters
;;  '{'       = Alt + (
;;  '}'       = Alt + )
;;  '['       = Alt + Shift + (
;;  ']'       = Alt + Shift + )
;;  '|'       = Alt + Shift + L
;;  '\'       = Alt + Shift + /
;;  '~'       = Alt + n
;; 
;; Navigation
;;  HOME      = fn + up arrow
;;  END       = fn + down arrow
;;  Page Down = fn + righ arraow
;;  Page Up   = fn + left arraow

;; c-mode-base-map is common to C/C++/Java ...

(define-key c-mode-base-map "\C-m"   'newline-and-indent)

;; Always end a file with a newline

(setq require-final-newline t)

;; Required with Emacs 23 so that C-n and C-p move to physical line
(setq line-move-visual nil)
(setq visible-bell nil)

;; Stop at the end of the file, not just add lines

(setq next-line-add-newlines nil)

;; Warn only when opening files bigger than 100MB
(setq large-file-warning-threshold 100000000)

(defvar max-width    80)
(defvar max-height   25)

;; New?
;; (setq x-select-enable-clipboard t)
;; (setq interprogram-paste-function 'x-cut-buffer-or-selection-value)

;;
;; set font
;;

(defvar current-font
        nil
;       "-outline-Courier New-normal-r-*-*-13-97-*-*-c-*-*-iso8859-1"
)

(defvar use-cmd-shell nil) ;; t == cmdproxy

;;; Known system-type values:
;;;  gnu         compiled for a GNU Hurd system.
;;;  gnu/linux   compiled for a GNU/Linux system.
;;;  darwin      compiled for Darwin (GNU-Darwin, Mac OS X, ...).
;;;  ms-dos      compiled as an MS-DOS application.
;;;  windows-nt  compiled as a native W32 application.
;;;  cygwin      compiled using the Cygwin library.

(cond
      ((eq system-type 'windows-nt)
       ;; (cd (getenv "HOME"))
       ;; Add support for nmake
       ;;
       (setq compile-command '("nmake " . 6))
       ;;
       ;; This  assumes  that  Cygwin  is  installed in C:\cygwin (the
       ;; default)  and  that  C:\cygwin\bin  is  not  already in your
       ;; Windows Path (it generally should not be).
       ;;
       ;; (setq exec-path (cons "C:/cygwin/bin" exec-path))
       ;; (setenv "PATH" (concat "C:\\cygwin\\bin;" (getenv "PATH")))
       ;;
       ;; NT-emacs assumes a Windows command shell, which you change
       ;; here.
       ;;
       (cond
             (use-cmd-shell
              (setq explicit-shell-file-name "cmdproxy")
              (setq shell-file-name "cmdproxy")
              (setq shell-command-switch "\\/u")
              (setq w32-quote-process-args t))
             (t
              (setq process-coding-system-alist '(("bash" . undecided-unix)))
              (setq w32-quote-process-args ?\")
              (setq shell-file-name "bash")
              (setenv "SHELL" shell-file-name)
              (setq explicit-shell-file-name shell-file-name)))
       (setq current-top  0)
       (setq current-left 72) ;; leave room for icons.
       ;;
       ;; This removes unsightly ^M characters that would otherwise
       ;; appear in the output of java applications.
       ;;
       (add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m))
      ((eq system-type 'darwin)
       (cd (getenv "HOME"))
       (setq current-left 72) ;; leave room for icons.
       (set-face-attribute 'default nil :height 150) ;; was 200
       (setq default-input-method "MacOSX")
       (setq mac-command-modifier 'meta)
       (setq mac-option-modifier nil)
       (setq mac-allow-anti-aliasing t)
       (setq mac-command-key-is-meta t)
       ;; (global-set-key "\M-(" (lambda () (interactive) (insert "{")))
       ;; (global-set-key "\M-)" (lambda () (interactive) (insert "}")))
       ;; (global-set-key "\M-8" (lambda () (interactive) (insert "[")))
       ;; (global-set-key "\M-9" (lambda () (interactive) (insert "]")))
       t)
      (t
       ;; Clipboard
       (setq x-select-enable-clipboard t)
       (setq interprogram-paste-function 'x-cut-buffer-or-selection-value)
       (setq current-left 72) ;; leave room for icons.
       t))

(defvar current-top  28)   ;; 10
(defvar current-left 28)   ;; 10

(when window-system
      ;; mouse ptr when cursor is too close
      (mouse-avoidance-mode 'jump)
      ;; ScrollBar on the right
      (set-scroll-bar-mode 'right)
      (let ((screen-height (x-display-pixel-height))
            (screen-width  (x-display-pixel-width)))
        (when current-font
          (set-default-font current-font))
        (setq max-height (/ screen-height (frame-char-height)))
        ;; reserve some characters (for menu bar).
        (cond
          ((eq system-type 'windows-nt)
           (setq max-height (- max-height 8)))
          (t
           (setq max-height (- max-height 8))))))

;; Don't display welcome message when Emacs starts.

(setq inhibit-startup-message t)

;; With default-frame-alist, we set the top left corner of new frames
;; to be at pixel offset +10+10, the width and height to be computed,
;; the cursor to be white, the foreground to be white, the background
;; to be NavyBlue, and the font to be Courier 10.  With
;; initial-frame-alist, we override the top left corner of the initial
;; frame to be at pixel offset +10+10, and inherit the remaining
;; properties from initial-frame-alist.

(setq default-frame-alist
      (list
            (cons 'fullscreen       'fullheight)
            (cons 'width            max-width)
;           (cons 'height           max-height)
;           (cons 'font             current-font)
            (cons 'top              current-top)
            (cons 'left             current-left)
            (cons 'cursor-type      'box)
            (cons 'cursor-color     "white")
            (cons 'foreground-color "LightBlue")
            (cons 'background-color "rgb:00/20/60"))) ;; "NavyBlue"

(setq initial-frame-alist default-frame-alist) ;; '((top . 10) (left . 10))

(setq frame-title-format (concat "%b - emacs@" system-name))

;; The above code uses the default faces for decoration.  If you would
;; like to customize the attributes of the faces, you can use the
;; following startup code to get started

(cond
      ((fboundp 'global-font-lock-mode)
       ;; Load the font-lock package.
       (require 'font-lock)
       ;; Customize face attributes
       (custom-set-faces
        '(left-margin ((t (:background "black"))) t)
        `(font-lock-builtin-face       ((t (:foreground "Light Steel Blue"))))
        '(font-lock-comment-face       ((t (:foreground "Green" :italic t))))
        '(font-lock-constant-face      ((t (:foreground "Orchid"))))
        '(font-lock-doc-face           ((t (:foreground "Wheat3"))))
        '(font-lock-doc-string-face    ((t (:foreground "Wheat3"))))
        '(font-lock-function-name-face ((t (:foreground "Orange" t))))
        '(font-lock-keyword-face       ((t (:foreground "Cyan" :bold t))))
        '(font-lock-preprocessor-face  ((t (:foreground "Wheat" t))))
        '(font-lock-reference-face     ((t (:foreground "orangered"))))
        '(font-lock-string-face        ((t (:foreground "Yellow"))))
        '(font-lock-type-face          ((t (:foreground "Grey" t))))
        '(font-lock-variable-name-face ((t (:foreground "LightGrey" t))))
        '(font-lock-warning-face       ((t (:foreground "Red" t))))
        )
       ;; Maximum colors
       (setq font-lock-maximum-decoration t)
       ;; Turn on font-lock in all modes that support it
       (global-font-lock-mode t)))

;; To highlight the region between the point and the mark, use the
;; function transient-mark-mode:

(transient-mark-mode t)

;; To highlight matching parenthesis
(show-paren-mode 1)

(add-hook 'sh-mode-hook
          ;; works for shell-script-mode, shell-mode which are aliases
          ;; to sh-mode main function.
          (lambda ()
            (setq indent-tabs-mode nil)
            (setq comint-completion-addsuffix '("/" . ""))))

;; Tune Lisp mode

(add-hook 'lisp-mode-hook
          ;; Lisp uses spaces instead of tabs.
          (lambda ()
            (setq indent-tabs-mode nil)))

(add-to-list 'auto-mode-alist '("\\.lap\\'" . lisp-mode))

(setq auto-mode-alist
      (append
         '(("\\.[bB][aA][tT]$" . bat-mode))
         ;; For DOS init files
         '(("CONFIG\\."        . bat-mode))
         '(("AUTOEXEC\\."      . bat-mode))
         auto-mode-alist))

(defun unicode-shell ()
   ;; Execute the shell buffer in UTF-8 encoding.
   ;; Note that you'll need to set the environment variable LANG and others
   ;; appropriately.
   (interactive)
   (let ((coding-system-for-read 'utf-16)
         (coding-system-for-write 'utf-16)
         (coding-system-require-warning t))
        (call-interactively 'shell)))

(transient-mark-mode 1)

;; (add-hook 'c-mode-common-hook '(lambda () (setq c-basic-offset 8)) t)

(setq line-indent-mode t)

(defun my-c-mode-hook ()
   "Hook for running C file..."
   ;;don't indent braces
   (c-set-offset 'substatement-open 0)
   (c-set-offset 'statement-case-open 0)
   (c-set-offset 'case-label 0) ; '+ to indent
   (setq tab-width 8)       ; 2 'modern code'
   (setq c-basic-offset 8)  ; 2 'modern code'
   (setq c-auto-newline nil)
;  (setq c-indent-comments-syntactically-p t)
   ;; make sure spaces are used instead of tabs
   (setq indent-tabs-mode nil) ; nil 'modern' code
   t)

(add-hook 'c-mode-hook 'my-c-mode-hook)

(defun my-c++-mode-hook ()
   "Hook for running C++ file..."
   ;;don't indent braces
   (c-set-offset 'substatement-open 0)
   (c-set-offset 'statement-case-open 0)
   (c-set-offset 'case-label 0) ; '+ to indent
   (setq tab-width 2)
   (setq c-basic-offset 2)
   (setq c-auto-newline nil)
;  (setq c-indent-comments-syntactically-p t)
   ;; make sure spaces are used instead of tabs
   (setq indent-tabs-mode nil)
   t)

(add-hook 'c++-mode-hook 'my-c++-mode-hook)

(defun my-java-mode-hook ()
   "Hook for running Java file..."
   ;;don't indent braces
   (c-set-offset 'substatement-open 0)
   (c-set-offset 'statement-case-open 0)
   (c-set-offset 'case-label 0) ; '+ to indent
   (setq tab-width 2)
   (setq c-basic-offset 2)
   (setq c-auto-newline nil)
;  (setq c-indent-comments-syntactically-p t)
   ;; make sure spaces are used instead of tabs
   (setq indent-tabs-mode nil)
   t)

(add-hook 'java-mode-hook 'my-java-mode-hook)

(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

(mapc (lambda (mode)
        (font-lock-add-keywords
            mode
            '(("^[^\n]\\{80\\}\\(.*\\)$" 1 font-lock-warning-face prepend))))
      '(c-mode c++-mode java-mode lisp-mode python-mode))

;; Add more 'makefile' patterns

(setq auto-mode-alist
      (append
         '(("makefile\\." . makefile-mode)
           ("\\.mak"      . makefile-mode)
           ("Makefile\\." . makefile-mode))
         auto-mode-alist))

;; Add PHP extension to c-mode mode.

(setq auto-mode-alist
      (append
         '(("\\.php\\'" . c-mode))
         auto-mode-alist))

;; Add BAT extension to bat-mode mode.

(setq auto-mode-alist
      (append
         '(("\\.[bB][aA][tT]$" . bat-mode))
         ;; For DOS init files
         '(("CONFIG\\."        . bat-mode))
         '(("AUTOEXEC\\."      . bat-mode))
         auto-mode-alist))

;; Customize c-mode

(setq c-default-style     '((other . "user")))

;; Basic indent is 8 characters.
(setq c-basic-offset      8)

;; insert a tab if point is in the middle of a line.
(setq c-tab-always-indent nil)
(setq indent-tabs-mode nil)

;; Make searches case sensitive by default (in all buffers that do not
;; override this).

(setq-default case-fold-search nil)

;; Add support for European character sets

;(standard-display-european 1)

(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(font-lock-builtin-face ((t (:foreground "Light Steel Blue"))))
 '(font-lock-comment-face ((t (:foreground "Green" :italic t))))
 '(font-lock-constant-face ((t (:foreground "Orchid"))))
 '(font-lock-doc-face ((t (:foreground "Wheat3"))))
 '(font-lock-doc-string-face ((t (:foreground "Wheat3"))))
 '(font-lock-function-name-face ((t (:foreground "Orange" t))))
 '(font-lock-keyword-face ((t (:foreground "Cyan" :bold t))))
 '(font-lock-preprocessor-face ((t (:foreground "Wheat" t))))
 '(font-lock-reference-face ((t (:foreground "orangered"))))
 '(font-lock-string-face ((t (:foreground "Yellow"))))
 '(font-lock-type-face ((t (:foreground "Grey" t))))
 '(font-lock-variable-name-face ((t (:foreground "LightGrey" t))))
 '(font-lock-warning-face ((t (:foreground "Red" t))))
 '(left-margin ((t (:background "black"))) t))

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(safe-local-variable-values
   '((syntax . islisp)
     (base . 10)
     (package . lisp)
     (Syntax . ANSI-Common-Lisp)
     (Syntax . EmacsLisp)
     (Mode . LISP)
     (Package . LISP)
     (Base . 10)
     (Syntax . ISLISP)
     (Encoding . utf-8)
     (Encoding . utf-16))))

(defun clozure (&optional and-go)
   "Run Clozure"
   (interactive)
   (cond
         ((eq system-type 'windows-nt)
          (setq inferior-lisp-program "f:/ccl/wx86cl64.exe") ;; your Lisp
          (add-to-list 'load-path "f:/slime/")) ; your SLIME directory
         (t
          (setq inferior-lisp-program "f:/ccl/wx86cl64.exe"))) ;; your Lisp
   (require 'slime)
   (slime-setup)
   (slime))

(defun sbcl (&optional and-go)
   "Run sbcl"
   (interactive)
   (setq inferior-lisp-program "sbcl") ;; your Lisp
   ;; (add-to-list 'load-path "f:/slime/")) ; your SLIME directory
   (require 'slime)
   (slime-setup)
   (slime))

(defun check-openlisp (path)
   ;; check if openlisp.el exists and load it.
   (let ((path     (getenv path))
         (found    nil)
         (openlisp nil))
        (when path
              (setq openlisp (concat path "/emacs/openlisp.el"))
              (when (file-exists-p openlisp)
                    (load openlisp)
                    (setf found t)))
        found))

; (visit-tags-table "~/nstools/lib/trunk/TAGS" )

(or
    (check-openlisp "HOME")
    (check-openlisp "HOMEPATH")
    (check-openlisp "OPENLISP"))

(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)

;(setq inferior-lisp-program "/collabwork/nstools/ccl/lx86cl64")
;(add-to-list 'load-path "~/slime-2.22")
;(add-to-list 'slime-contribs 'slime-fancy)
;(require 'slime-autoloads)
;(setq slime-contribs '(slime-scratch slime-editing-commands))
;(setq slime-contribs '(slime-fancy)) ; almost everything
;(add-hook 'lisp-mode-hook
;         (lambda ()
;           (slime-mode t)
;           (setq indent-tabs-mode nil)))
;(add-hook 'inferior-lisp-mode-hook (lambda () (inferior-slime-mode t)))