;;; elite-for-emacs.el - Elite for EMACS (defconst elite-for-emacs-version "0.1" "Version number of Elite for EMACS") ;; Elite for EMACS is based on Elite series by Ian Bell and David Braben. ;; Original Elite, (C) 1984 Ian Bell and David Braben. ;; Elite for EMACS uses code from original Elite and it is (C) 1984 Ian Bell and David Braben. ;; Additional code ;; Author: Sami Salkosuo (sami@roguemail.net) ;; This file is not part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;; Commentary: ;; ;; TAB is used for command completion. Shift-right arrow browses all commands. ;; Shift-up arrow browses command history. ;; ;; Installation: ;; ;; Add directory elite-for-emacs-0.1 to your load path and add ;; (require 'elite-for-emacs) ;; to .emacs ;; ;; Start Elite for EMACS M-x elite-for-emacs ;; (require 'cl) ;;Load Elite for EMACS functions (load "elite-for-emacs-commands") (load "elite-for-emacs-functions") (load "elite-for-emacs-commander") (load "elite-for-emacs-engine") (load "elite-for-emacs-bazaar") (defvar elite-for-emacs-current-command nil) (defvar elite-for-emacs-original-frame-title-format nil) (defvar elite-for-emacs-command-history nil) (defvar elite-for-emacs-command "") (defvar elite-for-emacs-buffer-name "*Elite for EMACS*") (defvar elite-for-emacs-buffer-name-offline "*Elite for EMACS*") (defvar elite-for-emacs-buffer-name-online "*Elite for EMACS (online)*") ;;Functions for prompt, modeline title. (defvar elite-for-emacs-prompt-function 'elite-for-emacs-prompt) (defvar elite-for-emacs-mode-line-function 'elite-for-emacs-mode-line) (defvar elite-for-emacs-frame-title-function 'ignore);elite-for-emacs-frame-title) (defvar elite-for-emacs-custom-post-command-function 'elite-for-emacs-post-command) (defvar elite-for-emacs-custom-pre-command-function 'elite-for-emacs-post-command) (defvar elite-for-emacs-kill-buffer-function 'elite-for-emacs-kill-buffer) (defvar elite-for-emacs-command-list nil) (defvar elite-for-emacs-suppress-message t) (defvar elite-for-emacs-suppress-default-newline-command nil) (defvar elite-for-emacs-online nil) (defvar elite-for-emacs-base-command-list ;;(setq elite-for-emacs-base-command-list (list (list "version" 'elite-for-emacs-version-info) (list "display-logo" 'elite-for-emacs-logo) (list "display-logo-no-text" 'elite-for-emacs-logo-no-text) ;;(list "changes" 'elite-for-emacs-changes) (list "cls" 'elite-for-emacs-clear) (list "help" 'elite-for-emacs-help) (list "exit" 'elite-for-emacs-exit) (list "quit" 'elite-for-emacs-exit) (list "script" 'elite-for-emacs-script-execute) ) ) ;;todo: save history variable (add-hook 'kill-buffer-hook 'elite-for-emacs-kill-buffer-hook) (defun elite-for-emacs () "Elite for EMACS." (interactive) (let ( (buffer) ) (if (get-buffer elite-for-emacs-buffer-name) (progn (switch-to-buffer elite-for-emacs-buffer-name) ) (progn (random t) (setq elite-for-emacs-command "") (setq elite-for-emacs-tab-command nil) (setq elite-for-emacs-tab-index 0) ;;buffer local variable, shell prompt ;;enter: executes command, adds new line, inserts prompt (setq buffer (get-buffer-create elite-for-emacs-buffer-name)) (switch-to-buffer buffer) (setq elite-for-emacs-command-loop-index 0) (setq elite-for-emacs-history-index 0) (insert (elite-for-emacs-set-prompt)) (local-set-key [tab] 'elite-for-emacs-tab) (setq elite-for-emacs-original-frame-title-format frame-title-format) (elite-for-emacs-set-mode-line) (elite-for-emacs-frame-title) ;;Set commands before game (setq elite-for-emacs-command-list (append (list (list "new" 'elite-for-emacs-new-commander) (list "load" 'elite-for-emacs-load-commander) ;;(list "start-script" 'elite-for-emacs-start-script) ) elite-for-emacs-base-command-list ) ) ;;todo: save history in kill hook, load here (setq elite-for-emacs-command-history (list)) ;;add handler to self-insert-command, post-command hook (add-hook 'pre-command-hook 'elite-for-emacs-pre-command-hook nil t) (add-hook 'post-command-hook 'elite-for-emacs-post-command-hook nil t) ) ) ) ) (defun elite-for-emacs-online () "Elite for EMACS online." ;;(interactive) (setq elite-for-emacs-online t) (setq elite-for-emacs-buffer-name elite-for-emacs-buffer-name-online) (elite-for-emacs) ) (defvar elite-for-emacs-command-loop-index 0) (defvar elite-for-emacs-history-index 0) (defun elite-for-emacs-post-command-hook () "Added to post-command-hook" (let ( (cmd) (completion) (event) (modifiers) (command-list) (temp) ) ;;special functions: tab, enter, up, down, left, right (condition-case error (progn ;;(message elite-for-emacs-command-output-string) (setq event last-command-event) (if (eq this-command 'self-insert-command) (progn ;; (setq elite-for-emacs-command (concat elite-for-emacs-command (list event))) ) ) (if (eq this-command 'delete-backward-char) (progn (if (> (length elite-for-emacs-command) 0) (setq elite-for-emacs-command (substring elite-for-emacs-command 0 (- (length elite-for-emacs-command) 1))) ) ) ) (if (eq this-command 'forward-char) (progn (setq modifiers (event-modifiers last-input-event)) (if (eq (car modifiers) 'shift) (progn (goto-char (point-max)) (beginning-of-line) (kill-line) (insert (concat (elite-for-emacs-set-prompt))) (setq cmd (car (nth elite-for-emacs-command-loop-index elite-for-emacs-command-list))) (setq elite-for-emacs-command cmd) (insert cmd) (setq elite-for-emacs-command-loop-index (1+ elite-for-emacs-command-loop-index)) (if (= elite-for-emacs-command-loop-index (length elite-for-emacs-command-list)) (setq elite-for-emacs-command-loop-index 0) ) ) ) ) ) (if (eq this-command 'backward-char) (progn (setq modifiers (event-modifiers last-input-event)) (if (eq (car modifiers) 'shift) (progn (goto-char (point-max)) (beginning-of-line) (kill-line) (insert (concat (elite-for-emacs-set-prompt))) (setq cmd (car (nth elite-for-emacs-command-loop-index elite-for-emacs-command-list))) (setq elite-for-emacs-command cmd) (insert cmd) (setq elite-for-emacs-command-loop-index (1- elite-for-emacs-command-loop-index)) (if (< elite-for-emacs-command-loop-index 0) (setq elite-for-emacs-command-loop-index (1- (length elite-for-emacs-command-list))) ) ) ) ) ) (if (eq this-command 'previous-line) (progn (setq modifiers (event-modifiers last-input-event)) (if (eq (car modifiers) 'shift) (progn (if (> (length elite-for-emacs-command-history) 0) (progn (goto-char (point-max)) (beginning-of-line) (kill-line) (insert (concat (elite-for-emacs-set-prompt))) (setq cmd (nth elite-for-emacs-history-index (reverse elite-for-emacs-command-history))) (setq elite-for-emacs-command cmd) (insert cmd) (setq elite-for-emacs-history-index (1+ elite-for-emacs-history-index)) (if (= elite-for-emacs-history-index (length elite-for-emacs-command-history)) (setq elite-for-emacs-history-index 0) ) ) ) ) ) ) (progn ;;set history to 0 if not previous line command (setq elite-for-emacs-history-index 0) ) ) (if (eq this-command 'newline) (progn (if (< (point) (point-max)) (progn ;;for some reason pre-command-hook newline (goto-char (point-max)) ;;does not work if we are not at the end of buffer (delete-backward-char 1) (goto-char (point-max)) (insert "\n") ) ) (if (not elite-for-emacs-suppress-default-newline-command) (progn ;;todo (documentation 'forward-char) ;;do command ;;(setq cmd (assoc elite-for-emacs-current-command elite-for-emacs-command-list)) ;;(setq cmd (cadr (assoc (car (split-string elite-for-emacs-command)) elite-for-emacs-command-list))) ;;(setq cmd (cadr (assoc elite-for-emacs-command-list))) ;; (setq temp (car (split-string elite-for-emacs-command))) ;; ;;(setq temp "versi") ;; (if temp ;; (progn ;; (setq cmd (cadr (assoc (try-completion temp elite-for-emacs-command-list) elite-for-emacs-command-list))) ;; (if (not cmd) ;; (setq cmd (cadr (assoc (car (split-string elite-for-emacs-command)) elite-for-emacs-command-list))) ;; ) ;; ) ;; (progn ;; (setq cmd "") ;; ) ;; ) ;;get first match (setq cmd (elite-for-emacs-get-first-command-match (car (split-string elite-for-emacs-command)))) (setq cmd (cadr (assoc cmd elite-for-emacs-command-list))) ;;act on command (if (or (commandp cmd) (functionp cmd)) (progn (if (commandp cmd) (command-execute cmd) (funcall cmd) ) ;;(insert (concat elite-for-emacs-current-command " executed.")) (if (current-message) (progn (insert (current-message)) (if elite-for-emacs-suppress-message (message nil) ) ) ) ;;(setq elite-for-emacs-command-history (remove elite-for-emacs-command elite-for-emacs-command-history)) ;;(setq elite-for-emacs-command-history (append elite-for-emacs-command-history (list elite-for-emacs-command))) ;;(setq elite-for-emacs-current-command nil) (if (not (eq cmd 'elite-for-emacs-clear)) (insert "\n") ) ) (progn ;;(funcall cmd) (if (not (string= elite-for-emacs-command "")) (insert "Bad command (" elite-for-emacs-command ").\n") ) ) ) (if (and elite-for-emacs-command (not (string= elite-for-emacs-command ""))) (setq elite-for-emacs-command-history (append elite-for-emacs-command-history (list elite-for-emacs-command))) ) (setq elite-for-emacs-command "") (insert (concat (elite-for-emacs-set-prompt))) (setq elite-for-emacs-tab-index 0) (setq elite-for-emacs-tab-ring nil) (setq elite-for-emacs-tab-command nil) (elite-for-emacs-set-mode-line) (elite-for-emacs-frame-title) ) ) ) ) (if (and elite-for-emacs-suppress-message (current-message)) (progn (message nil) ) ) (if (functionp elite-for-emacs-custom-post-command-function) (funcall elite-for-emacs-custom-post-command-function) ) ) (error (insert (error-message-string error) "\n") (setq elite-for-emacs-command "") (insert (concat (elite-for-emacs-set-prompt))) (setq elite-for-emacs-tab-index 0) (setq elite-for-emacs-tab-ring nil) (setq elite-for-emacs-tab-command nil) (elite-for-emacs-set-mode-line) (elite-for-emacs-frame-title) ) ) ) ) (defun elite-for-emacs-get-first-command-match (cmd) "" (let ( (command-list) (temp) (index) (command) ) (setq command "") ;;(setq cmd "") (if cmd (progn (setq command-list elite-for-emacs-command-list) (while command-list (setq temp (caar command-list)) (setq index (string-match cmd temp)) (if (and index (= index 0)) (progn (setq command-list nil) (setq command temp) ) ) (setq command-list (cdr command-list)) ) ) ) command ) ) (defvar elite-for-emacs-tab-index 0) (defvar elite-for-emacs-tab-command nil) (defvar elite-for-emacs-tab-ring nil) (defun elite-for-emacs-tab () (interactive) (let ( (completion) (cmd) ) ;;(setq completion nil) ;;(setq elite-for-emacs-command "3") (if elite-for-emacs-tab-command (setq completion (all-completions elite-for-emacs-tab-command elite-for-emacs-command-list)) (progn (if (string= elite-for-emacs-command "") (setq elite-for-emacs-tab-ring t) ) ;;(all-completions "r" '(("list" 'l) ("re" 'l) ("reeee" 'l))) (if elite-for-emacs-tab-ring (setq completion (all-completions "" elite-for-emacs-command-list)) (setq completion (all-completions elite-for-emacs-command elite-for-emacs-command-list)) ) ) ) (if completion (progn (if (and (not elite-for-emacs-tab-ring) (> (length completion) 1) (not elite-for-emacs-tab-command)) (progn (setq elite-for-emacs-tab-command elite-for-emacs-command) ) ) (if (>= elite-for-emacs-tab-index (length completion)) (setq elite-for-emacs-tab-index 0) ) (goto-char (point-max)) (beginning-of-line) (kill-line) (insert (elite-for-emacs-set-prompt)) (setq cmd (nth elite-for-emacs-tab-index completion)) (setq elite-for-emacs-command cmd) (insert cmd) (setq elite-for-emacs-tab-index (1+ elite-for-emacs-tab-index)) ) ) ) ) (defun elite-for-emacs-pre-command-hook () "Added to pre-command-hook" (let ( (cmd) (completion) ) (setq event last-command-event) ;;(message (number-to-string event)) (if (/= event 9);;TAB (progn (setq elite-for-emacs-tab-index 0) (setq elite-for-emacs-tab-ring nil) (setq elite-for-emacs-tab-command nil) ) ) (if (eq this-command 'self-insert-command) (progn ) ) (if (eq this-command 'newline) (progn ;;(message "pre command hook newline") (goto-char (point-max)) ) ) (if (functionp elite-for-emacs-custom-pre-command-function) (funcall elite-for-emacs-custom-pre-command-function) ) ) ) (defun elite-for-emacs-kill-buffer-hook () (let ( ) (if (string= (buffer-name) elite-for-emacs-buffer-name) (progn ;;clean up (remove-hook 'post-command-hook 'elite-for-emacs-post-command-hook t) (remove-hook 'pre-command-hook 'elite-for-emacs-pre-command-hook t) (setq frame-title-format elite-for-emacs-original-frame-title-format) (if (functionp elite-for-emacs-kill-buffer-function) (funcall elite-for-emacs-kill-buffer-function) ) ) ) ) ) (defun elite-for-emacs-set-prompt () "Function returns prompt" (let ( ) (if (and (functionp elite-for-emacs-prompt-function) (not (string= (symbol-name elite-for-emacs-prompt-function) "ignore"))) ;;(if (functionp elite-for-emacs-prompt-function) (funcall elite-for-emacs-prompt-function) "" ) ) ) (defun elite-for-emacs-set-mode-line () "Sets mode line for Simple Shell buffer" (let ( ) (if (and (functionp elite-for-emacs-mode-line-function) (not (string= (symbol-name elite-for-emacs-mode-line-function) "ignore"))) ;;(if (functionp elite-for-emacs-mode-line-function) (progn (setq mode-line-format (funcall elite-for-emacs-mode-line-function) ) ;;remember to use force at the end of mode-line function (force-mode-line-update) ) ) ) ) (defun elite-for-emacs-frame-title () "Sets frame title for Simple Shell buffer" (let ( ) (if (and (functionp elite-for-emacs-frame-title-function) (not (string= (symbol-name elite-for-emacs-frame-title-function) "ignore"))) (setq frame-title-format (funcall elite-for-emacs-frame-title-function)) ) ) ) (defun elite-for-emacs-default-frame-title () "Returns default frame title" (let ( ) "Simple Shell Title" ) ) (defun elite-for-emacs-default-mode-line () "Sets mode line" (let ( ) ;;custome modeline format (list "---" 'elite-for-emacs-command "-%-" ) ) ) (defun elite-for-emacs-default-prompt () "Function returns prompt" (let ( ) "SimpleShell>" ) ) (defun elite-for-emacs-test-function () (let ( ) (if (eq this-command 'newline) (insert "hello world") ) ) ) (defun elite-for-emacs-clear () "Clear screen." (let ( ) (erase-buffer) ) ) (defun elite-for-emacs-exit () "Exit Elite for EMACS." (let ( ) (insert "Use kill-buffer (\\C-x k) to exit.") ;;(call-interactively 'kill-buffer) ;;(call-interactively 'emacs-version) ) ) (defun elite-for-emacs-help () "Help." (let ( (temp) ) (setq temp (split-string elite-for-emacs-command)) ;;(insert "Commands:\nhelp This help\nhelp Command help\n" ) (insert "Commands:\n" ) (setq command-list elite-for-emacs-command-list) (while command-list (setq cmd (car command-list)) (insert (car cmd)) (if (>= (length (car cmd)) 16) (insert "\t") (progn (if (>= (length (car cmd)) 8) (insert "\t\t") (progn (insert "\t\t\t") ) ) ) ) (setq temp (documentation (cadr cmd))) (if temp (insert (documentation (cadr cmd)) "\n") (insert "\n") ) (setq command-list (cdr command-list)) ) ;;(setq elite-for-emacs-command-history (remove elite-for-emacs-command elite-for-emacs-command-history)) ;;(setq elite-for-emacs-command-history (append elite-for-emacs-command-history (list elite-for-emacs-command))) ) ) (defgroup elite-for-emacs nil "Elite for EMACS." :tag "Elite for EMACS" :prefix "elite-for-emacs-" :version "21.2.1" :group 'games) ;;custom variables: colors (online/offline)? (defcustom elite-for-emacs-save-confirmation-when-exit t "*If non-nil user is asked to save commander when killing Elite for EMACS buffer." :type 'boolean :group 'elite-for-emacs) ;;Online customization ;; (defgroup elite-for-emacs-online nil ;; "Elite for EMACS." ;; :tag "Elite for EMACS Online" ;; :prefix "elite-for-emacs-online" ;; :version "21.2.1" ;; :group 'elite-for-emacs) ;; ;; ;; (defcustom elite-for-emacs-online-autosave-dock nil ;; "*Non-nil saves commander when docking station." ;; :type 'boolean ;; :group 'elite-for-emacs-online) ;; ;; (defcustom elite-for-emacs-online-autosave-undock nil ;; "*Non-nil saves commander when undocking station." ;; :type 'boolean ;; :group 'elite-for-emacs-online) ;; ;; (defcustom elite-for-emacs-online-proxy-host nil ;; "*HTTP proxy host." ;; :type 'string ;; :group 'elite-for-emacs-online) ;; ;; (defcustom elite-for-emacs-online-proxy-port nil ;; "*HTTP proxy port." ;; :type 'string ;; :group 'elite-for-emacs-online) ;; (defcustom elite-for-emacs-buffer-name "*Elite for EMACS*" ;; "*Simple Shell buffer name." ;; :type 'string ;; :group 'elite-for-emacs) ;; ;; ;; (defcustom elite-for-emacs-prompt-function 'elite-for-emacs-default-prompt ;; "*Simple Shell prompt function name. Function must return a string that will be used ;; as shell prompt. Prompt function is called after calling function 'newline (normally after pressing ;; ENTER). Use 'ignore'-function to disable feature." ;; :type 'function ;; :group 'elite-for-emacs) ;; ;; (defcustom elite-for-emacs-mode-line-function 'elite-for-emacs-default-mode-line ;; "*Simple Shell mode line function name. Function must return a list of mode line options, see ;; GNU Emacs (21.2) Lisp Reference Manual section 23.3 Mode Line Format. ;; Mode line function is called after calling function 'newline (normally after pressing ;; ENTER). Use 'ignore'-function to disable feature." ;; :type 'function ;; :group 'elite-for-emacs) ;; ;; (defcustom elite-for-emacs-frame-title-function 'elite-for-emacs-default-frame-title ;; "*Simple Shell frame title function name. Function must return a string that will be used as ;; a new frame title. ;; Frame title function is called after calling function 'newline (normally after pressing ;; ENTER). Use 'ignore'-function to disable feature." ;; :type 'function ;; :group 'elite-for-emacs) ;; ;; (defcustom elite-for-emacs-custom-post-command-function 'ignore ;; "*Function is added to post-command-hook and is executed after executing simple shell command. Use 'ignore'-function to disable feature." ;; :type 'function ;; :group 'elite-for-emacs) ;; ;; (defcustom elite-for-emacs-custom-pre-command-function 'ignore ;; "*Function is added to pre-command-hook and is executed before executing simple shell command. Use 'ignore'-function to disable feature." ;; :type 'function ;; :group 'elite-for-emacs) ;; ;; ;; (defcustom elite-for-emacs-command-list '(("version" emacs-version)) ;; "*Simple Shell command list. Key is shell command and value is function. If function displays something ;; in the mini buffer it is inserted in the mini buffer and message is not show in the mini buffer if ;; elite-for-emacs-suppress-message is t. Functions should use insert-function to insert messages in the shell ;; buffer. " ;; ;; :type 'alist;(alist :key-type string :value-type symbol) ;; :group 'elite-for-emacs) ;; ;; (defcustom elite-for-emacs-suppress-message t ;; "*Suppress message in mini buffer." ;; :type 'boolean ;; :group 'elite-for-emacs) (provide 'elite-for-emacs)