slow.el 5.45 KB
Newer Older
1
;;;;; -*-coding: raw-text;-*-
David Kågedal's avatar
David Kågedal committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
;;;;;
;;;;; $Id$
;;;;; Copyright (C) 1996  Lysator Academic Computer Association.
;;;;;
;;;;; This file is part of the LysKOM server.
;;;;; 
;;;;; LysKOM 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.
;;;;; 
;;;;; LysKOM 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 LysKOM; see the file COPYING.  If not, write to
;;;;; Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
;;;;; or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
;;;;; MA 02139, USA.
;;;;;
;;;;; Please mail bug reports to bug-lyskom@lysator.liu.se. 
;;;;;
;;;; ================================================================
;;;; ================================================================
;;;;
;;;; File: slow.el
;;;;
;;;; This file contains the code that makes it possible to run a 
;;;; long-commands mode in the lyskom-buffer.
;;;;
;;;; ================================================================
;;;;

;;; Author: Linus Tolke
;;; Modified by: David Kågedal

(defvar lyskom-slow-mode-map
  (make-sparse-keymap)
  "Mode map for the `slow' lyskom command mode.")

(define-key lyskom-slow-mode-map "\r" 'kom-parse-command-and-execute)
(define-key lyskom-slow-mode-map "\t" 'kom-expand-slow-command)
(define-key lyskom-slow-mode-map " " 'kom-expand-slow-or-next-command)

(defun lyskom-get-entered-slow-command ()
  "Get the text that the user has entered after the last prompt.
Note that this function leaves point at the end of the prompt.

If no text is entered, nil is returned."
  (goto-char (point-max))
  (save-restriction
David Byers's avatar
David Byers committed
55
56
    (when (> lyskom-last-viewed (point-max))
      (setq lyskom-last-viewed (point-max)))
David Kågedal's avatar
David Kågedal committed
57
    (narrow-to-region lyskom-last-viewed (point-max))
David Byers's avatar
David Byers committed
58
59
60
61
62
63
    (if (search-backward lyskom-current-prompt-text nil t)
        (forward-char (length lyskom-current-prompt-text))
      (goto-char (point-max))
      (beginning-of-line))
    (when (looking-at "\\(\\s-+\\)")
      (goto-char (match-end 0))))
David Kågedal's avatar
David Kågedal committed
64
65
66
67
  (if (= (point) (point-max))
      nil
    (buffer-substring (point) (point-max))))

David Byers's avatar
David Byers committed
68
(defun kom-expand-slow-command (&optional try-exact)
David Kågedal's avatar
David Kågedal committed
69
  "Tries to complete the command at point.
David Byers's avatar
David Byers committed
70
71
If optional TRY-EXACT is non-nil, look for an exact match.

David Kågedal's avatar
David Kågedal committed
72
73
74
75
76
77
78
79
If the completion was exact return a pair `(COMMAND . POINT)' where
COMMAND is the command and POINT is the point where the command text
starts.

If the completion was not exact it returns nil."
  (interactive)
  (let* ((text (lyskom-get-entered-slow-command))
	 (completion-ignore-case t)
80
	 (alternatives (mapcar (function (lambda (pair)
81
					   (cons (cdr pair) (car pair))))
82
83
			       (lyskom-get-strings
				lyskom-commands 'lyskom-command)))
David Byers's avatar
David Byers committed
84
         (exact (and try-exact text (lyskom-string-assoc text alternatives)))
David Kågedal's avatar
David Kågedal committed
85
86
87
88
89
90
91
92
	 (completes (and text (all-completions text alternatives)))
	 (command nil))
    (cond
     ((null text)
      (lyskom-beep t))
     ((null completes)
      (lyskom-insert-before-prompt (lyskom-get-string 'no-such-command))
      (lyskom-beep t))
David Byers's avatar
David Byers committed
93
94
     (exact
      (setq command (cons (cdr exact) (point))))
David Kågedal's avatar
David Kågedal committed
95
     ((= (length completes) 1)
96
      (setq command (cons (cdr (assq (car completes) alternatives))
David Kågedal's avatar
David Kågedal committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
			  (point)))
      (delete-region (point) (point-max))
      (insert (car completes)))
     ((> (length completes) 1)
      (let ((longest (try-completion text alternatives)))
	(cond
	 ((eq longest 't)
	  (delete-region (point) (point-max))
	  (insert (car completes)))
	 ((stringp longest)
	  (if (string= (upcase longest) (upcase text))
	      (lyskom-format-insert-before-prompt
	       'command-completions
	       (mapconcat 'identity completes "\n ")))
	  (delete-region (point) (point-max))
	  (insert longest))
	 (t (signal 'lyskom-internal-error '()))))))
    command))


David Byers's avatar
David Byers committed
117
(defun kom-expand-slow-or-next-command (&optional try-exact)
David Kågedal's avatar
David Kågedal committed
118
119
120
121
  "If any part of a slow command has been entered, call
`kom-expand-slow-command'. Otherwise, do `kom-next-command'."
  (interactive)
  (if (lyskom-get-entered-slow-command)
David Byers's avatar
David Byers committed
122
      (kom-expand-slow-command try-exact)
David Byers's avatar
David Byers committed
123
    (buffer-disable-undo)
David Kågedal's avatar
David Kågedal committed
124
125
126
127
128
129
130
    (kom-next-command)))


(defun kom-parse-command-and-execute ()
  "Reads a command from the last line in the buffer and executes it."
  (interactive)
  (let* ((text (lyskom-get-entered-slow-command))
David Byers's avatar
David Byers committed
131
	 (command (and text (kom-expand-slow-command t))))
David Byers's avatar
David Byers committed
132
    (buffer-disable-undo)
David Kågedal's avatar
David Kågedal committed
133
134
135
136
137
138
139
140
141
142
143
144
    (cond
     ((null text)
      (call-interactively 'kom-next-command))
     (command
      (delete-region (cdr command) (point-max))
      (call-interactively (car command))))))


(defun kom-slow-mode ()
  "Starts the slow-command-mode."
  (interactive)
  (lyskom-start-of-command 'kom-slow-mode)
David Byers's avatar
David Byers committed
145
146
147
148
149
  (unless lyskom-slow-mode
    (setq lyskom-saved-read-only buffer-read-only)
    (setq lyskom-slow-mode t)
    (setq buffer-read-only nil)
    (use-local-map lyskom-slow-mode-map))
David Kågedal's avatar
David Kågedal committed
150
151
152
153
154
155
  (lyskom-end-of-command))

(defun kom-quick-mode ()
  "Starts the quick-command-mode."
  (interactive)
  (lyskom-start-of-command 'kom-quick-mode)
David Byers's avatar
David Byers committed
156
157
158
159
  (when lyskom-slow-mode
    (setq buffer-read-only lyskom-saved-read-only)
    (setq lyskom-slow-mode nil)
    (use-local-map lyskom-mode-map))
David Kågedal's avatar
David Kågedal committed
160
161
162
  (lyskom-end-of-command))