1 ;;; cmd-mode.el --- Edit of MS Windows cmd and bat files ;; -*- coding: sjis-dos -*-
3 ;; Copyright (C) 2001-2005 by Tadamegu Furukawa. <tfuruka1 at nifty dot com>
5 ;; Author: Tadamegu Furukawa <tfuruka1 at nifty dot com>
6 ;; Maintainer: Lennart Borgman <lennart dot borgman dot 073 at student dot lu dot se>
12 ;; Kindly translated to English 2005 by Kenichi Handa after an inquiry
13 ;; by Lennart Borgman.
15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17 ;; This file is not part of GNU Emacs.
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24 ;; MS-DOS??????????Windows NT???????????????
25 ;; ?????????????%????????????????????
26 ;; ??????????????????????????font-lock???
27 ;; ??????????????emacs 20.7 "Meadow-1.14 (AWSAKA:62)" ?
28 ;; ?????????(????????????????????)?
30 ;; Tiny mode for editing batch files of MS-DOS and command scripts of
31 ;; Windows NT. The purpose is to improve the readablity of those
32 ;; files that contains many `%' and are difficult to read. So,
33 ;; basically this provides only a proper font-lock setting. This
34 ;; program has been tested for Emacs 20.7 "Meadow-1.14 (AWSAKA:62)
35 ;; (the other versions of Emacsen are out of my focus).
37 ;; It has now been tested also on Emacs 21.3 and 22.0.50 on W2k.
41 ;; .emacs?????????????????????cmd??bat????
42 ;; ????????cmd-mode??????
45 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 ;; Please input the following code somewhere in your .emacs. Then,
50 ;; cmd-mode is automatically activated when you open a file whose
51 ;; extention is "cmd" or "bat".
53 ;; (autoload 'cmd-mode "cmd-mode" "CMD mode." t)
54 ;; (setq auto-mode-alist (append '(("\\.\\(cmd\\|bat\\)$" . cmd-mode))
58 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;;;;;;;;;;;;;;;;; What is this:
63 ;; $Id: cmd-mode.el,v 1.1 2005/07/18 14:38:50 Administrator Exp $
64 ;; $Log: cmd-mode.el,v $
65 ;; Revision 1.1 2005/07/18 14:38:50 Administrator
66 ;; *** empty log message ***
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69 ;; Revision 1.4 2005/10/18
71 ;; o Translation to English. (Kenichi Handa)
72 ;; o Changed set-mark to push-mark. (Lennart Borgman)
75 ;; Revision 1.3 2001/09/11 12:39:03 tfuruka1
80 ;; ????????????????????
81 ;; o Add a facility to jump to any label.
84 ;; Revision 1.2 2001/08/31 13:25:50 tfuruka1
86 ;; ?SET?????????????????????????????????
88 ;; o Fix the problme of incorrect coloring in the case that an
89 ;; environment varialbe of SET contains a keyword string.
91 ;; ?SET /A ??????????????????????????????
93 ;; o FIx the problem of incorrectly coloring a part of operand in SET
94 ;; /A as an environment variable in
96 ;; Revision 1.1 2001/08/28 13:14:43 tfuruka1
102 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106 ;; Added by L Borgman:
109 ;; (replace-regexp "[\t ]+$" "")
111 (defconst cmd-mode-revision-number
"1.4" "cmd-mode.el version number.")
115 (defvar cmd-menu-bar
(make-sparse-keymap "cmd-mode-menu")
118 (defvar cmd-submenu-jump
(make-sparse-keymap "cmd-mode-submenu-jump")
119 ;; "??????????(????)"
120 "Popup menu for jump.")
123 (defvar cmd-mode-hook nil
124 ;; "cmd-mode??????????????? hook ???"
125 "Hook called when `cmd-mode' is entered.")
126 (defvar cmd-help-mode-hook nil
127 ;; "cmd-help-mode??????????????? hook ???"
128 "Hook called when `cmd-help-mode' is entered.")
131 ;;; *** External command
132 (defvar cmd-help-command
"help"
133 ;; "help???????????Windows NT????????????"
134 "Name of `help' command. It exists only on Windows NT.")
137 ;;; *** Buffer related things.
138 (defvar cmd-temp-buf
" *cmd-temp-buf*"
140 "Hidden buffer for work.")
141 (defvar cmd-help-buf-base-name
"*cmd-help "
143 "Base name of help buffer.")
146 (defvar cmd-full-size-space-etc-pattern
"\\(+\\)"
148 "Regular expression for fullwidth space sequence.")
149 (defvar cmd-tab-pattern
"\\(\t+\\)"
151 "Regular expression for TAB character sequence.")
152 (defvar cmd-comment-pattern
"^[ \t]*\\(@*\\)\\(rem\\)\\([\t ].*$\\|$\\)"
154 "Regular expression for a comment line.")
155 (defvar cmd-variable-pattern
157 "%\\(" ;??????% the first char is `%'
158 "\\*" ;%* ??? in case of "%*"
160 "~[^0-9 \n]+[0-9a-z]" ;~f1 ? e.g. ~f1
162 "[0-9a-z]\\b" ;%1 ? e.g. %1
164 "[^%\n -?]+%" ;??????? normal env. var.
166 "%[0-9a-z]" ;%% ? e.g. %$
171 ;; ???????????????????
174 ;; ----------- -----------------------
176 ;; %~fi, %~dp1 ????????(%n)??FOR???????
178 ;; %1, %i ????????(%n)??FOR????
179 ;; %%, %%1, %%i %?????????????(%n)??FOR????(???
181 "Regular expression for expanding an environment variable.
183 The following patterns are concerned.
187 %* refer to all of the arguments
188 %~f1, %~dp1 replacement for batch parameter (%n) and FOR variable reference
189 %STRING% normal reference of an environment variable
190 %1, %i batch parameter (%n) and FOR variable reference
191 %%, %%1, %%i % itself, batch parameter (%n) and FOR variable reference
192 (when used in a batch file)"
194 (defvar cmd-const-pattern
195 "\\(^[ \t]*@\\|nul\\|:eof\\|&&\\||\\|\\^\\|&[12]?\\|[,;]\\)"
197 "Regular expression for conditional symbols.")
198 (defvar cmd-set-pattern
200 "\\(set\\b\\)\\([ \t]+/a\\)*"
201 "\\(\\([ \t]+[_A-Za-z-][_A-Za-z0-9-]*\\)*\\)"
202 "\\([-+/\\*]\\|\\W\\)*")
204 "Regular expression for SET command.")
205 (defvar cmd-label-pattern
"^[ \t]*\\(:[:A-Za-z0-9_-]+\\)"
207 "Regular expression for a label.")
208 (defvar cmd-redirect-pattern
210 "[12]?>>?" ;1> 2> 1>> 2>> > >>
219 "Regular expression for redirection.")
220 (defvar cmd-option-pattern
225 "not" "exist" "defined" "errorlevel" "cmdextversion"
226 "equ" "neq" "lss" "leq" "gtr" "geq"
228 "eol" "skip" "delims" "tokens" "in" "do") t
) "\\b")
230 "Regular expression for options to a statement like IF.")
231 (defvar cmd-command-pattern
233 (regexp-opt '("assoc" "break" "call" "cd" "chdir" "cls"
234 "color" "copy" "date" "del" "dir" "echo"
235 "echo." "endlocal" "erase" "exit" "for"
236 "ftype" "goto" "if" "md" "mkdir" "move" "path"
237 "pause" "popd" "prompt" "pushd" "rd" "ren"
238 "rename" "rmdir" "setlocal" "shift" "start"
239 "time" "title" "type" "ver" "verify" "vol" )
243 ;; ????????????????Windows NT?HELP???????????
244 ;; ??????????????(*.exe, *.com)????????????SET
245 ;; ? REM ???????????????????????????ECHO ?
248 "Regular expression for internal commands.
250 Only internal commands. Actually they are commands listed by
251 HELP command of Windows NT (such external commands as *.ext and
252 *.com are excluded). SET and REM are also excluded because they
253 are defined in the other place. As for ECHO, ECHO. is included
257 ;; Setting for font-lock.
258 (defvar cmd-font-lock-keywords
262 (list cmd-comment-pattern
263 '(1 font-lock-constant-face
) ;???@ @ at bol
264 '(2 font-lock-keyword-face
) ;rem
265 '(3 font-lock-comment-face
) ;?????? command character
268 (list cmd-set-pattern
269 '(1 font-lock-keyword-face
) ;SET
270 '(3 font-lock-type-face
) ;????? name of env. var.
274 (list cmd-label-pattern
275 '(1 (cons font-lock-function-name-face
'(underline))))
278 (list cmd-redirect-pattern
1 font-lock-warning-face
)
280 ;; reference of environment variable
281 (list cmd-variable-pattern
1 font-lock-variable-name-face
)
284 (list cmd-command-pattern
1 font-lock-keyword-face
)
286 ;; e.g. conditional symbols
287 (list cmd-const-pattern
1 font-lock-constant-face
)
289 ;; e.g. options of IF and FOR
290 (list cmd-option-pattern
1 font-lock-builtin-face
)
293 (list cmd-full-size-space-etc-pattern
'(1 '(underline)))
296 (list cmd-tab-pattern
'(1 '(highlight)))
298 ;; "cmd-mode, cmd-help-mode?????font-lock??????
299 ;; ???font-lock-defaults??????????"
300 "Setting for font-lock used in `cmd-mode' and `cmd-help-mode'.
301 See `font-lock-defaults' for detail.")
303 (defun cmd-mode-version ()
304 ;; "cmd-mode?Version??"
305 "Show the version of `cmd-mode'."
308 (concat "cmd-mode version " cmd-mode-revision-number
)))
310 (defun cmd-help (arg)
311 ;; "help???????????????????
312 ;; ??????Windows NT?????????????
314 ;; ?Windows \\(9[58]\\|Me\\)???????????????????????
316 "Execute help command and show the result.
317 This functinos works only on Windows NT.
319 Implementers note: I intended that this work also on Windows
320 \\(9[58]\\|Me\\), but actually failed.
321 Argument ARG is the command to describe."
323 (list (let* ((command (current-word))
325 (format "Help for command%s: " ;; "????%s: "
326 (if (string-equal command
"")
328 (format " (%s)" command
))))))
329 (if (string-equal input
"")
330 (if (string-equal command
"")
335 (let* ((case-fold-search t
)
336 (cmd-help-buffer (format "%s%s*"
337 cmd-help-buf-base-name
(downcase arg
)))
338 (comspec (getenv "ComSpec"))
341 ((string-match "cmd\\.exe$" comspec
)
342 (list "\\/c" cmd-help-command
343 (if (string-equal arg
"help") "" arg
)))
344 ((string-match "command\\.com$" comspec
)
345 (if (string-equal arg
"help")
346 (error "Insert command" ;; "?????????????"
348 (list "\\/c" arg
"\\/?")))
350 (error (concat "Work only on WindowsXX ComSpec="
351 ;;"WindowsXX?????????? ComSpec="
354 (set-buffer (get-buffer-create cmd-help-buffer
))
355 (setq buffer-read-only nil
)
357 (apply (function call-process
) comspec nil t nil cmd-help-arg
)
358 (goto-char (point-min))
359 (display-buffer cmd-help-buffer
)
363 (defun cmd-help-mode-exit ()
364 ;; "cmd-help-mode???????"
365 "Terminate `cmd-help-mode'."
367 (if (eq major-mode
'cmd-help-mode
)
368 (kill-buffer (current-buffer)))
371 (defun cmd-help-mode ()
372 ;; "cmd-help??????????
374 ;; ??????????????????????
377 ;; ?cmd-help-mode???????
378 ;; \\[cmd-help-mode-exit]"
380 "Mode for `cmd-help'.
382 o Execute help command and show the result.
385 o Terminate `cmd-help-mode'.
386 \\[cmd-help-mode-exit]"
388 (kill-all-local-variables)
389 ;;????????????????????????????
390 ;; Setting the mode name and the mode-name field of the mode-line.
391 (setq major-mode
'cmd-help-mode
393 buffer-auto-save-file-name nil
;??????? suppresss auto saving
394 buffer-read-only t
;?????? for read only
398 (setq cmd-help-local-map
(make-keymap))
401 (define-key cmd-help-local-map
"\C-ch" 'cmd-help
)
402 (define-key cmd-help-local-map
"\C-m" 'cmd-help
)
403 (define-key cmd-help-local-map
" " 'cmd-help
)
404 (define-key cmd-help-local-map
"q" 'cmd-help-mode-exit
)
405 (define-key cmd-help-local-map
"Q" 'cmd-help-mode-exit
)
406 (define-key cmd-help-local-map
"n" 'next-line
)
407 (define-key cmd-help-local-map
"p" 'previous-line
)
410 ;; Declare to use of the local map
411 (use-local-map cmd-help-local-map
)
414 ;; Setting for font-lock
415 (make-local-variable 'font-lock-defaults
)
416 (setq font-lock-defaults
417 '((cmd-font-lock-keywords) t t
))
420 (run-hooks 'cmd-help-mode-hook
)
423 (defun cmd-right-trim-region (start end
)
424 ;; "????????????????????????????"
425 "Delete space characters at the end of line of the specified region.
426 Region is between START and END."
430 (while (re-search-forward "[\t ]+$" end t
)
431 (replace-match ""))))
434 ;; "????????(??????)?????????????????
435 ;; ???????????????????"
437 "Save the buffer (if necessary) and execute it.
438 corner-cutting work."
441 (shell-command (buffer-file-name))
444 (defun cmd-recenter ()
445 ;; "???????????????????????????????"
446 "Set the point to the center, and delete extra spaces at the end of line."
449 (cmd-right-trim-region (point-min) (point-max)))
451 (defun cmd-next-label ()
453 "Jump to the next label."
455 (if (re-search-forward cmd-label-pattern nil t
)
456 (goto-char (match-end 0))))
457 (defun cmd-prev-label ()
459 "Jump to the previous label."
461 (if (re-search-backward cmd-label-pattern nil t
)
462 (goto-char (match-beginning 0))))
464 (defun cmd-fill-paragraph ()
465 ;; "????????????????????????????(?????
469 Fairly corner-cutting (is it allowed to do this kind of thing?)."
472 (let (;;?????????????
476 "\\([\t ]*@?\\(rem\\|echo\\)\\)\\([ \t].*$\\|$\\)")
481 (cmd-fill-column fill-column
)
482 (current-buffer (buffer-name))
485 (if (looking-at cmd-rem-regexp
)
487 (setq match-str
(buffer-substring
488 (match-beginning 1) (match-end 1))
490 (message ;; "cmd-fill-paragraph?%s?"
491 "cmd-fill-paragraph [%s]" match-str
)
494 (if (looking-at (concat match-str
"\\([\t ]\\|$\\)"))
495 (setq rem-begin
(point))
496 (goto-char (point-min))))
498 (goto-char rem-begin
)
501 "\\(^" match-str
"[^\n]*\n\\)+"
502 "\\(^" match-str
"[^\n]*\\)?\\|"
503 "^" match-str
".*$\\)"))
504 (if (looking-at cmd-rem-regexp
)
506 (setq rem-end
(match-end 0)
507 rem-paragraph
(buffer-substring rem-begin rem-end
))
508 (set-buffer (get-buffer-create cmd-temp-buf
))
510 (insert rem-paragraph
)
513 (goto-char (point-min))
514 (while (re-search-forward
515 (concat "^" match-str
" ?") nil t
)
518 (setq fill-column
(- cmd-fill-column
(length match-str
)))
519 (goto-char (point-min))
524 (goto-char (point-min))
527 (insert (concat match-str
528 (if (looking-at "$") "" " ")))
530 (if (looking-at "[ \t]*@?echo$")
536 (goto-char (point-max))
538 (if (looking-at (concat match-str
"$"))
541 (cmd-right-trim-region (point-min) (point-max))
544 (buffer-substring (point-min) (point-max)))
545 (kill-buffer cmd-temp-buf
)
546 (set-buffer current-buffer
)
547 (delete-region rem-begin rem-end
)
548 (insert rem-paragraph
)
553 (error ;; "cmd-fill-paragraph????????"
554 "cmd-fill-paragraph [seems like a bug]")))
557 ;;"cmd-fill-paragraph: ??? REM ?? ECHO ???????"
558 "cmd-fill-paragraph: The line doesn't start with REM nor ECHO.")
564 (defun cmd-goto-label ()
567 ;; ???????????????????????????????????
568 ;; ?????????????????????(?????????????
571 "Jump to the specified label.
573 Label can be completed at the mini-buffer. A word at the cursor
574 position is shown as default (if it matches one of existing
577 (let ((label-alist '())
580 (goto-char (point-min))
581 (while (re-search-forward
582 "^[ \t]*:\\([:A-Za-z0-9_-]+\\)\\([\t ]\\|$\\)" nil t
)
583 (setq label-alist
(cons (list (buffer-substring (match-beginning 1)
586 (if (not label-alist
)
587 (error ;; "???????????"
589 (setq label
(completing-read "Label:" label-alist nil t
590 (if (assoc (current-word) label-alist
)
592 (when (and label
(not (string= label
"")))
593 (push-mark (point)) ;??????? Set mark
594 (goto-char (point-min))
595 (re-search-forward (concat "^[\t ]*:" label
"\\([ \t]\\|$\\)"))
601 ;; "MS-DOS?????????Windows NT ????????????????
604 ;; ???????????????????????
611 ;; \\[cmd-goto-label]
613 ;; ??????????????????????????????????
617 ;; ???????(REM or ECHO)?????????
618 ;; \\[cmd-fill-paragraph]
621 ;; \\[cmd-prev-label]
624 ;; \\[cmd-next-label]"
626 "Tiny mode for editing batch files (MS-DOS) and command scripts (Windows NT).
628 * Save buffer and execute it.
632 * Show help of a command.
635 * Jump to the specified label.
638 * Set the point to the center, and delete extra spaces at the end
642 * Fill comment lines (e.g REM, ECHO).
643 \\[cmd-fill-paragraph]
645 * Jump to the previous label.
648 * Jump to the next label.
651 (kill-all-local-variables)
652 ;;????????????????????????????
653 ;; Setting the mode name and the mode-name field of the mode-line.
654 (setq major-mode
'cmd-mode
655 ;;mode-name "CMD?BAT")
659 (setq cmd-local-map
(make-keymap))
662 (define-key cmd-local-map
"\C-c\C-c" 'cmd-exec
)
663 (define-key cmd-local-map
"\C-cg" 'cmd-goto-label
)
664 (define-key cmd-local-map
"\C-ch" 'cmd-help
)
665 (define-key cmd-local-map
"\C-l" 'cmd-recenter
)
666 ;;(define-key cmd-local-map "\eq" 'cmd-fill-paragraph)
667 (define-key cmd-local-map
"\M-q" 'cmd-fill-paragraph
)
668 ;;(define-key cmd-local-map "\e\C-a" 'cmd-prev-label)
669 (define-key cmd-local-map
"\M-\C-a" 'cmd-prev-label
)
670 ;;(define-key cmd-local-map "\e\C-e" 'cmd-next-label)
671 (define-key cmd-local-map
"\M-\C-e" 'cmd-next-label
)
674 ;; Create the menu bar.
675 (define-key cmd-submenu-jump
[sub-goto-label
]
677 "Specified label" . cmd-goto-label
))
678 (define-key cmd-submenu-jump
[sub-next-label
]
680 "Next label" . cmd-next-label
))
681 (define-key cmd-submenu-jump
[sub-prev-label
]
683 "Previous label" . cmd-prev-label
))
685 (define-key cmd-local-map
[menu-bar cmd
] (cons mode-name cmd-menu-bar
))
686 (define-key cmd-menu-bar
[submenu-jump
] (cons "Jump" ;; "????"
688 (define-key cmd-menu-bar
[sep-1
] '("--"))
689 (define-key cmd-menu-bar
[help] '("Help" ;; "???..."
691 (define-key cmd-menu-bar [sep-2] '("--"))
692 (define-key cmd-menu-bar [recenter] '("Delete trailing spaces"
695 (define-key cmd-menu-bar [fill] '("Fill comments" ;; "????????"
696 . cmd-fill-paragraph))
697 (define-key cmd-menu-bar [exec] '("??" . cmd-exec))
700 ;; Declare to use of the local map
701 (use-local-map cmd-local-map)
704 ;; Setting for font-lock.
705 (make-local-variable 'font-lock-defaults)
706 (setq font-lock-defaults
707 '((cmd-font-lock-keywords) t t))
710 (run-hooks 'cmd-mode-hook)
713 ;; Added by L Borgman
716 ;;; cmd-mode.el ends here