slow.el 5.21 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
68
69
70
71
72
73
74
75
76
77
  (if (= (point) (point-max))
      nil
    (buffer-substring (point) (point-max))))

(defun kom-expand-slow-command ()
  "Tries to complete the command at point.
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)
78
	 (alternatives (mapcar (function (lambda (pair)
79
					   (cons (cdr pair) (car pair))))
80
81
			       (lyskom-get-strings
				lyskom-commands 'lyskom-command)))
David Kågedal's avatar
David Kågedal committed
82
83
84
85
86
87
88
89
90
	 (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))
     ((= (length completes) 1)
91
      (setq command (cons (cdr (assq (car completes) alternatives))
David Kågedal's avatar
David Kågedal committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
			  (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))


(defun kom-expand-slow-or-next-command ()
  "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)
      (kom-expand-slow-command)
David Byers's avatar
David Byers committed
118
    (buffer-disable-undo)
David Kågedal's avatar
David Kågedal committed
119
120
121
122
123
124
125
126
    (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))
	 (command (and text (kom-expand-slow-command))))
David Byers's avatar
David Byers committed
127
    (buffer-disable-undo)
David Kågedal's avatar
David Kågedal committed
128
129
130
131
132
133
134
135
136
137
138
139
    (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
140
141
142
143
144
  (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
145
146
147
148
149
150
  (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
151
152
153
154
  (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
155
156
157
  (lyskom-end-of-command))