Changes http://wiki.axiom-developer.org/AxiomEmacsMode/diff
--

??changed:
 \begin{document}
-\title{\$SPAD/src/emacs/axiommode.el\\Version 19-06-2007} 
+\title{\$SPAD/src/emacs/axiommode.el\\Version 30-09-2007} 
 \author{Jay Belanger, Fran\c{c}ois Maltey, Martin Rubey and Cliff Yapp}

 \item[M-return] evaluates input and appends output at the end of the buffer.
++added:
+\item[C-return] writes the front item of the kill ring into a temporary file,
+  and then [[)re]]ads that file.
 \end{description}

??changed:
 (defvar axiom-after-output-wait 100) ;; time to wait for axiom to repond prompt
-
+(defvar axiom-mode-map (copy-keymap comint-mode-map) 
+  "local key map for Axiom terminal mode")
 @

 
++added:
+; from emacs 22
+(defun make-temp-file (prefix &optional dir-flag suffix)
+  "Create a temporary file.
+The returned file name (created by appending some random characters at the end
+of PREFIX, and expanding against `temporary-file-directory' if necessary),
+is guaranteed to point to a newly created empty file.
+You can then use `write-region' to write new data into the file.
+
+If DIR-FLAG is non-nil, create a new empty directory instead of a file.
+
+If SUFFIX is non-nil, add that at the end of the file name."
+  (let ((umask (default-file-modes))
+        file)
+    (unwind-protect
+        (progn
+          ;; Create temp files with strict access rights.  It's easy to
+          ;; loosen them later, whereas it's impossible to close the
+          ;; time-window of loose permissions otherwise.
+          (set-default-file-modes ?\700)
+          (while (condition-case ()
+                     (progn
+                       (setq file
+                             (make-temp-name
+                              (expand-file-name prefix 
temporary-file-directory)))
+                       (if suffix
+                           (setq file (concat file suffix)))
+                       (if dir-flag
+                           (make-directory file)
+                         (write-region "" nil file nil 'silent nil 'excl))
+                       nil)
+                   (file-already-exists t))
+            ;; the file was somehow created by someone else between
+            ;; `make-temp-name' and `write-region', let's try again.
+            nil)
+          file)
+      ;; Reset the umask.
+      (set-default-file-modes umask))))
+
+(defun axiom-yank ()
+  "puts the front item of the kill ring into a temporary file and makes axiom 
)read it"
+  (interactive)
+  (let* ((tmp-file (make-temp-file "axiom" nil ".input"))
+        (end (progn (goto-char (point-max))
+                    (point))))  
+    (write-region (car kill-ring-yank-pointer) nil tmp-file)
+    (delete-region (axiom-previous-prompt) end)
+    (comint-set-process-mark)
+    (insert (concat ")re " tmp-file))
+    (axiom-eval)
+    (delete-file tmp-file)))
+
+(define-key axiom-mode-map [(ctrl return)] 'axiom-yank)
+
 (defun axiom-output? (position)

--removed:
 <<axiom-mode-map>>=
-(defvar axiom-mode-map (copy-keymap comint-mode-map) 
-  "local key map for Axiom terminal mode")
-
 (define-key axiom-mode-map [(meta up)] 'axiom-previous-input)

 <<axiom-reset>>=
++added:
+(defun axiom-resync-directory ()
+  "Send )sys pwd to the axiom process, parse the result, cd to it and clean up
+    output.  Assumes that we are just after a prompt."
+  (let ((inhibit-read-only t)
+        (begin (progn (forward-line 0) (point)))
+        (end (progn (end-of-line) (point)))
+        (dir))
+    (delete-region begin end)
+    (process-send-string (get-buffer-process (current-buffer)) ")sys pwd\n")
+    (axiom-wait-for-output)
+    (forward-line -1)
+    (end-of-line)
+    (sit-for 0)
+    (setq end (point))
+    (cd (buffer-substring-no-properties begin end))
+    (delete-region (1- begin) end)
+    (forward-line 1)
+    (end-of-line)))
+
+;  (let ((inhibit-read-only t)
+;        (inhibit-field-text-motion t)
+;        dir begin end)
+;    (delete-region (progn (forward-line 0) (point))
+;                   (progn (end-of-line) (point)))
+;    (process-send-string (get-buffer-process (current-buffer)) ")sys pwd\n")
+;    (axiom-wait-for-output)
+;    (forward-line -1)
+;    (setq begin (point))
+;    (end-of-line)
+;    (sit-for 0)
+;    (setq end (point))
+;    (cd (buffer-substring-no-properties begin end))
+;    (delete-region (1- begin) end)
+;    (forward-line 1)
+;    (end-of-line)))
+
+
 (defun axiom-reset ()

??changed:
    "Remove read-only properties from everything after the last prompt. Set
-process-mark so we can continue."
+process-mark so we can continue.  Resync directory."
    (interactive)

??changed:
      (axiom-make-prompt (re-search-backward axiom-prompt nil t) (point))
-     (comint-goto-process-mark)))
+     (comint-goto-process-mark)
+     (axiom-resync-directory)))
 

??changed:
   (interactive)
-  (if axiom-system-command 
-      ;; we are responding to a system command.
-      (progn 
-       (setq axiom-system-command nil
-              axiom-end-of-input (copy-marker (axiom-end-of-input)))
-       (comint-send-input)
-       (axiom-wait-for-output)
-        
-        ;; If there is a prompt further down, we are overwriting old stuff.
-       (when (re-search-forward axiom-prompt nil t)
-          (re-search-backward axiom-prompt)
-          (axiom-repair-prompts)
-          (re-search-forward axiom-prompt nil t)
-          (comint-set-process-mark)))
-
-    ;; otherwise, we first check whether process-mark is at a prompt
-    (when (axiom-prompt? (1- (process-mark axiom-process)))
-
-      ;; do we have multiline input?
-[25 more lines...]
+  (let ((axiom-cd nil))
+    (if axiom-system-command 
+        ;; we are responding to a system command.
+        (progn 
+          (setq axiom-system-command nil
+                axiom-end-of-input (copy-marker (axiom-end-of-input)))
+          (comint-send-input)
+          (axiom-wait-for-output)
+          ;; If there is a prompt further down, we are overwriting old stuff.
+          (when (re-search-forward axiom-prompt nil t)
+            (re-search-backward axiom-prompt)
+            (axiom-repair-prompts)
+            (re-search-forward axiom-prompt nil t)
+            (comint-set-process-mark)))
+
+      ;; otherwise, we first check whether process-mark is at a prompt
+      (when (axiom-prompt? (1- (process-mark axiom-process)))
+
+        ;; do we have multiline input?
+        (beginning-of-line)
+        (if (looking-at ".*_ *$")
+            (progn (end-of-line)
+                   (newline))
+          
+          ;; move to the the end of the preceding prompt
+          (axiom-previous-prompt)
+          (comint-set-process-mark)
+          ;; is it a system command?
+          (setq axiom-system-command (looking-at " *)"))
+          (when axiom-system-command
+            (setq axiom-cd (looking-at " *)cd *")))
+          
+          ;; If there is a prompt further down, we are overwriting old stuff.
+          (if (axiom-next-prompt)
+              (progn (axiom-overwrite-output-eval)
+                     ;; if we are now looking at a prompt, we are certainly not
+                     ;; answering a question posed by axiom.
+                     (when (looking-backward-at axiom-prompt)
+                       (when axiom-cd (axiom-resync-directory))
+                       (setq axiom-system-command nil)
+                       (axiom-repair-prompts)
+                       (end-of-line) ;; this moves point to the end of the 
prompt!
+                       ;; it seems to work even if we type text
+                       ;; during a computation.
+                       (comint-set-process-mark)))
+            (axiom-normal-eval)
+            (when (looking-backward-at axiom-prompt)
+              (when axiom-cd (axiom-resync-directory))
+              (setq axiom-system-command nil))))))))
 

 
++added:
+\subsection{Command completion}
+
+It is not clear to what extend command completion would be useful in Axiom.
+For the moment, I just enable filename completion.  I'd like to restrict to
+[[.input]], [[.spad]] and [[.as]] filenames, but I do not know how.
+
+<<axiom-command-completion>>=
+(define-key axiom-mode-map "\t" 'axiom-dynamic-complete)
+@
+
+I had [[(define-key axiom-mode-map [tab] 'axiom-dynamic-complete)]]
+here before, but that did not work entirely: hitting tab twice inserted a tab!
+
+<<axiom-command-completion>>=
+(defun axiom-file-name-all-completions (pathnondir directory)
+  "Returns all filenames relevant to axiom"
+  (save-match-data
+    (remove-if-not 
+     (function (lambda (f) 
+                 (or (and (string-match "\\.[^.]*\\'" f)
+                          (member (match-string 0 f)
+                                  (list ".input" ".spad" ".as")))
+                     (string= (file-name-directory f) f))))
+     (file-name-all-completions pathnondir directory))))
+@
+
+We are not using [[file-name-extension]], since that would strip off trailing
+tildes.
+
+
+The following probably could be simplified a lot.  In principle, I need to find
+the position of the first mismatch.
+
+<<axiom-command-completion>>=
+(defun axiom-file-name-completion (file directory)
+  "Returns the longest string common to all file names relevant to axiom in
+DIRECTORY that start with FILE.  If there is only one and FILE matches it
+exactly, returns t.  Returns nil if DIR contains no name starting with FILE."
+  (let* ((completions (axiom-file-name-all-completions file directory))
+        (frst (first completions))
+        (len  (length frst))
+        (start      0)
+        (not-done   t))
+    (cond ((consp (rest completions))
+          (while (and not-done
+                      (> len start))
+            (let ((char (substring frst start (1+ start)))
+                  (rst  (rest completions)))
+              (while (and not-done 
+                          (consp rst))
+                (if (and (> (length (first rst)) start)
+                         (string= (substring (first rst) 
+                                             start (1+ start))
+                                  char))
+                    (setq rst (rest rst))
+                  (setq not-done nil))))
+            (when not-done 
+              (setq start (1+ start))))
+          (substring frst 0 start))
+         ((string= frst file)
+          t)
+         (t
+          frst))))
+@
+
+This is stolen from [[comint.el]], I only changed [[file-name-all-completions]]
+to [[axiom-file-name-all-completions]].
+
+<<axiom-command-completion>>=
+(defun axiom-dynamic-list-filename-completions ()
+  "List in help buffer possible completions of the filename at point."
+  (interactive)
+  (let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt)))
+        ;; If we bind this, it breaks remote directory tracking in rlogin.el.
+        ;; I think it was originally bound to solve file completion problems,
+        ;; but subsequent changes may have made this unnecessary.  sm.
+        ;;(file-name-handler-alist nil)
+        (filename (or (comint-match-partial-filename) ""))
+        (pathdir (file-name-directory filename))
+        (pathnondir (file-name-nondirectory filename))
+        (directory (if pathdir (comint-directory pathdir) default-directory))
+        (completions (axiom-file-name-all-completions pathnondir directory)))
+    (if (not completions)
+       (message "No completions of %s" filename)
+      (comint-dynamic-list-completions
+       (mapcar 'comint-quote-filename completions)))))
+@
+
+Again, this is stolen from [[comint.el]].  I should specialise here, I think.
+Furthermore, directory tracking does not work yet.
+
+<<axiom-command-completion>>=
+(defun axiom-dynamic-complete ()
+  "Dynamically perform completion at point."
+  (interactive)
+  (when (save-excursion
+         (axiom-previous-prompt)
+         (looking-at " *)"))
+    (axiom-dynamic-complete-filename)))
+@
+
+Maybe the bit to detect whether we have a system command should go into a new
+function, since it's used in eval, too.
+
+<<axiom-command-completion>>=
+(defun axiom-dynamic-complete-filename ()
+  "Dynamically complete at point as a filename.
+See `comint-dynamic-complete-filename'.  Returns t if successful."
+  (interactive)
+  (let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt)))
+        (completion-ignored-extensions comint-completion-fignore)
+        ;; If we bind this, it breaks remote directory tracking in rlogin.el.
+        ;; I think it was originally bound to solve file completion problems,
+        ;; but subsequent changes may have made this unnecessary.  sm.
+        ;;(file-name-handler-alist nil)
+        (minibuffer-p (window-minibuffer-p (selected-window)))
+        (success t)
+        (dirsuffix (cond ((not comint-completion-addsuffix)
+                          "")
+                         ((not (consp comint-completion-addsuffix))
+                          (char-to-string directory-sep-char))
+                         (t
+                          (car comint-completion-addsuffix))))
+        (filesuffix (cond ((not comint-completion-addsuffix)
+                           "")
+                          ((not (consp comint-completion-addsuffix))
+                           " ")
+                          (t
+                           (cdr comint-completion-addsuffix))))
+        (filename (or (comint-match-partial-filename) ""))
+        (pathdir (file-name-directory filename))
+        (pathnondir (file-name-nondirectory filename))
+        (directory (if pathdir (comint-directory pathdir) default-directory))
+        (completion (axiom-file-name-completion pathnondir directory)))
+    (cond ((null completion)
+          (message "No completions of %s" filename)
+          (setq success nil))
+         ((eq completion t)            ; Means already completed "file".
+          (insert filesuffix)
+          (unless minibuffer-p
+            (message "Sole completion")))
+         ((string-equal completion "") ; Means completion on "directory/".
+          (axiom-dynamic-list-filename-completions))
+         (t                            ; Completion string returned.
+          (let ((file (concat (file-name-as-directory directory) completion)))
+            (insert (comint-quote-filename
+                     (substring (directory-file-name completion)
+                                (length pathnondir))))
+            (cond ((symbolp (axiom-file-name-completion completion directory))
+                   ;; We inserted a unique completion.
+                   (insert (if (file-directory-p file) dirsuffix filesuffix))
+                   (unless minibuffer-p
+                     (message "Completed")))
+                  ((and comint-completion-recexact comint-completion-addsuffix
+                        (string-equal pathnondir completion)
+                        (file-exists-p file))
+                   ;; It's not unique, but user wants shortest match.
+                   (insert (if (file-directory-p file) dirsuffix filesuffix))
+                   (unless minibuffer-p
+                     (message "Completed shortest")))
+                  ((or comint-completion-autolist
+                       (string-equal pathnondir completion))
+                   ;; It's not unique, list possible completions.
+                   (axiom-dynamic-list-filename-completions))
+                  (t
+                   (unless minibuffer-p
+                     (message "Partially completed")))))))
+    success))
+@
 

 ;;################### Terminal Mode ########################
++added:
+<<axiom-command-completion>>
 <<axiommodekeyboardmap-axiom-previous-input>>

--
forwarded from http://wiki.axiom-developer.org/[EMAIL PROTECTED]

Reply via email to