Download
1.4" "cmd-mode.el version number.")
(defvar cmd-menu-bar (make-sparse-keymap "cmd-mode-menu")
メニュー"
"Menu bar entry.")
(defvar cmd-submenu-jump (make-sparse-keymap "cmd-mode-submenu-jump")
ポップアップメニュー(ジャンプ)"
"Popup menu for jump.")
(defvar cmd-mode-hook nil
cmd-modeを作成するタイミングで呼ばれる hook です。"
"Hook called when `cmd-mode' is entered.")
(defvar cmd-help-mode-hook nil
cmd-help-modeを作成するタイミングで呼ばれる hook です。"
"Hook called when `cmd-help-mode' is entered.")
(defvar cmd-help-command "help"
helpコマンドのコマンド名。Windows NT系以外には存在しません。"
"Name of `help' command. It exists only on Windows NT.")
(defvar cmd-temp-buf " *cmd-temp-buf*"
作業用の隠しバッファ"
"Hidden buffer for work.")
(defvar cmd-help-buf-base-name "*cmd-help "
ヘルプバッファのベース名"
"Base name of help buffer.")
(defvar cmd-full-size-space-etc-pattern "\\( +\\)"
所謂「全角の空白」の正規表現"
"Regular expression for fullwidth space sequence.")
(defvar cmd-tab-pattern "\\(\t+\\)"
TAB文字の正規表現"
"Regular expression for TAB character sequence.")
(defvar cmd-comment-pattern "^[ \t]*\\(@*\\)\\(rem\\)\\([\t ].*$\\|$\\)"
コメント行の正規表現"
"Regular expression for a comment line.")
(defvar cmd-variable-pattern
(concat "\\("
"%\\("
"\\*" %*"
"\\|"
"~[^0-9 \n]+[0-9a-z]"
"\\|"
"[0-9a-z]\\b"
"\\|"
"[^%\n -龠]+%"
"\\|"
"%[0-9a-z]"
"\\)"
"\\)")
環境変数の展開の正規表現
Regular expression for expanding an environment variable.
The following patterns are concerned.
example meaning
------- -------
%* refer to all of the arguments
%~f1, %~dp1 replacement for batch parameter (%n) and FOR variable reference
%STRING% normal reference of an environment variable
%1, %i batch parameter (%n) and FOR variable reference
%%, %%1, %%i % itself, batch parameter (%n) and FOR variable reference
(when used in a batch file)"
)
(defvar cmd-const-pattern
"\\(^[ \t]*@\\|nul\\|:eof\\|&&\\||\\|\\^\\|&[12]?\\|[,Regular expression for conditional symbols.")
(defvar cmd-set-pattern
(concat "\\b"
"\\(set\\b\\)\\([ \t]+/a\\)*"
"\\(\\([ \t]+[_A-Za-z-][_A-Za-z0-9-]*\\)*\\)"
"\\([-+/\\*]\\|\\W\\)*")
SETコマンドの正規表現"
"Regular expression for SET command.")
(defvar cmd-label-pattern "^[ \t]*\\(:[:A-Za-z0-9_-]+\\)"
ラベルの正規表現"
"Regular expression for a label.")
(defvar cmd-redirect-pattern
(concat "\\("
"[12]?>>?"
"\\|"
"<[12]?"
"\\|"
"2>&1"
"\\|"
"1>&2"
"\\)")
リダイレクトの正規表現"
"Regular expression for redirection.")
(defvar cmd-option-pattern
(concat "\\b"
(regexp-opt
'(
"not" "exist" "defined" "errorlevel" "cmdextversion"
"equ" "neq" "lss" "leq" "gtr" "geq"
"eol" "skip" "delims" "tokens" "in" "do") t) "\\b")
IF文等のオプションの正規表現"
"Regular expression for options to a statement like IF.")
(defvar cmd-command-pattern
(concat "\\b"
(regexp-opt '("assoc" "break" "call" "cd" "chdir" "cls"
"color" "copy" "date" "del" "dir" "echo"
"echo." "endlocal" "erase" "exit" "for"
"ftype" "goto" "if" "md" "mkdir" "move" "path"
"pause" "popd" "prompt" "pushd" "rd" "ren"
"rename" "rmdir" "setlocal" "shift" "start"
"time" "title" "type" "ver" "verify" "vol" )
t) "\\b")
コマンドの正規表現
Regular expression for internal commands.
Only internal commands. Actually they are commands listed by
HELP command of Windows NT (such external commands as *.ext and
*.com are excluded). SET and REM are also excluded because they
are defined in the other place. As for ECHO, ECHO. is included
too.")
(defvar cmd-font-lock-keywords
(list
(list cmd-comment-pattern
'(1 font-lock-constant-face)
'(2 font-lock-keyword-face)
'(3 font-lock-comment-face)
)
(list cmd-set-pattern
'(1 font-lock-keyword-face)
'(3 font-lock-type-face)
)
(list cmd-label-pattern
'(1 (cons font-lock-function-name-face '(underline))))
(list cmd-redirect-pattern 1 font-lock-warning-face)
(list cmd-variable-pattern 1 font-lock-variable-name-face)
(list cmd-command-pattern 1 font-lock-keyword-face)
(list cmd-const-pattern 1 font-lock-constant-face)
(list cmd-option-pattern 1 font-lock-builtin-face)
(list cmd-full-size-space-etc-pattern '(1 '(underline)))
(list cmd-tab-pattern '(1 '(highlight)))
)
cmd-mode, cmd-help-modeで使用するfont-lockの設定です。
Setting for font-lock used in `cmd-mode' and `cmd-help-mode'.
See `font-lock-defaults' for detail.")
(defun cmd-mode-version ()
cmd-modeのVersion表示"
"Show the version of `cmd-mode'."
(interactive)
(message
(concat "cmd-mode version " cmd-mode-revision-number)))
(defun cmd-help (arg)
helpコマンドを実行して、結果を表示します。
Execute help command and show the result.
This functinos works only on Windows NT.
Implementers note: I intended that this work also on Windows
\\(9[58]\\|Me\\), but actually failed.
Argument ARG is the command to describe."
(interactive
(list (let* ((command (current-word))
(input (read-string
(format "Help for command%s: " コマンド%s: "
(if (string-equal command "")
""
(format " (%s)" command))))))
(if (string-equal input "")
(if (string-equal command "")
"help"
command)
input))))
(let* ((case-fold-search t)
(cmd-help-buffer (format "%s%s*"
cmd-help-buf-base-name (downcase arg)))
(comspec (getenv "ComSpec"))
(cmd-help-arg
(cond
((string-match "cmd\\.exe$" comspec)
(list "\\/c" cmd-help-command
(if (string-equal arg "help") "" arg)))
((string-match "command\\.com$" comspec)
(if (string-equal arg "help")
(error "Insert command" コマンドを入力してください"
)
(list "\\/c" arg "\\/?")))
(t
(error (concat "Work only on WindowsXX ComSpec="
WindowsXX以外では動作しません ComSpec="
comspec)))))
)
(set-buffer (get-buffer-create cmd-help-buffer))
(setq buffer-read-only nil)
(erase-buffer)
(apply (function call-process) comspec nil t nil cmd-help-arg)
(goto-char (point-min))
(display-buffer cmd-help-buffer)
(cmd-help-mode)
))
(defun cmd-help-mode-exit ()
cmd-help-modeを終了します。"
"Terminate `cmd-help-mode'."
(interactive)
(if (eq major-mode 'cmd-help-mode)
(kill-buffer (current-buffer)))
)
(defun cmd-help-mode ()
cmd-helpから呼び出されます。
Mode for `cmd-help'.
o Execute help command and show the result.
\\[cmd-help]
o Terminate `cmd-help-mode'.
\\[cmd-help-mode-exit]"
(interactive)
(kill-all-local-variables)
(setq major-mode 'cmd-help-mode
mode-name "cmd-help"
buffer-auto-save-file-name nil
buffer-read-only t
)
(setq cmd-help-local-map (make-keymap))
(define-key cmd-help-local-map "\C-ch" 'cmd-help)
(define-key cmd-help-local-map "\C-m" 'cmd-help)
(define-key cmd-help-local-map " " 'cmd-help)
(define-key cmd-help-local-map "q" 'cmd-help-mode-exit)
(define-key cmd-help-local-map "Q" 'cmd-help-mode-exit)
(define-key cmd-help-local-map "n" 'next-line)
(define-key cmd-help-local-map "p" 'previous-line)
(use-local-map cmd-help-local-map)
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults
'((cmd-font-lock-keywords) t t))
(font-lock-mode t)
(run-hooks 'cmd-help-mode-hook)
)
(defun cmd-right-trim-region (start end)
リージョンで指定された範囲の行末の空白文字を削除します。"
"Delete space characters at the end of line of the specified region.
Region is between START and END."
(interactive "r")
(save-excursion
(goto-char start)
(while (re-search-forward "[\t ]+$" end t)
(replace-match ""))))
(defun cmd-exec ()
バッファの内容を(必要であれば)ファイルに保存し、保存したファイル
Save the buffer (if necessary) and execute it.
corner-cutting work."
(interactive)
(save-buffer)
(shell-command (buffer-file-name))
)
(defun cmd-recenter ()
カレント位置を中央に配置した後、余分な行末のスペースを削除する"
"Set the point to the center, and delete extra spaces at the end of line."
(interactive)
(recenter)
(cmd-right-trim-region (point-min) (point-max)))
(defun cmd-next-label ()
次のラベルへ跳ぶ"
"Jump to the next label."
(interactive)
(if (re-search-forward cmd-label-pattern nil t)
(goto-char (match-end 0))))
(defun cmd-prev-label ()
前のラベルへ跳ぶ"
"Jump to the previous label."
(interactive)
(if (re-search-backward cmd-label-pattern nil t)
(goto-char (match-beginning 0))))
(defun cmd-fill-paragraph ()
コメント行等の行詰めを行います。かなり手抜きをしています(こんな事を
Fill comment lines.
Fairly corner-cutting (is it allowed to do this kind of thing?)."
(interactive)
(save-excursion
(let (
(case-fold-search t)
(cmd-rem-regexp
"\\([\t ]*@?\\(rem\\|echo\\)\\)\\([ \t].*$\\|$\\)")
rem-begin
rem-end
rem-paragraph
match-str
(cmd-fill-column fill-column)
(current-buffer (buffer-name))
)
(beginning-of-line)
(if (looking-at cmd-rem-regexp)
(progn
(setq match-str (buffer-substring
(match-beginning 1) (match-end 1))
rem-begin (point))
(message cmd-fill-paragraph【%s】"
"cmd-fill-paragraph [%s]" match-str)
(while (not (bobp))
(forward-line -1)
(if (looking-at (concat match-str "\\([\t ]\\|$\\)"))
(setq rem-begin (point))
(goto-char (point-min))))
(goto-char rem-begin)
(setq cmd-rem-regexp
(concat "\\("
"\\(^" match-str "[^\n]*\n\\)+"
"\\(^" match-str "[^\n]*\\)?\\|"
"^" match-str ".*$\\)"))
(if (looking-at cmd-rem-regexp)
(progn
(setq rem-end (match-end 0)
rem-paragraph (buffer-substring rem-begin rem-end))
(set-buffer (get-buffer-create cmd-temp-buf))
(erase-buffer)
(insert rem-paragraph)
(indented-text-mode)
(goto-char (point-min))
(while (re-search-forward
(concat "^" match-str " ?") nil t)
(replace-match ""))
(setq fill-column (- cmd-fill-column (length match-str)))
(goto-char (point-min))
(while (not (eobp))
(fill-paragraph nil)
(forward-paragraph))
(goto-char (point-min))
(while (not (eobp))
(beginning-of-line)
(insert (concat match-str
(if (looking-at "$") "" " ")))
(beginning-of-line)
(if (looking-at "[ \t]*@?echo$")
(progn
(end-of-line)
(insert ".")))
(forward-line 1))
(goto-char (point-max))
(beginning-of-line)
(if (looking-at (concat match-str "$"))
(replace-match ""))
(cmd-right-trim-region (point-min) (point-max))
(setq rem-paragraph
(buffer-substring (point-min) (point-max)))
(kill-buffer cmd-temp-buf)
(set-buffer current-buffer)
(delete-region rem-begin rem-end)
(insert rem-paragraph)
(message "done.")
)
(progn
(ding)
(error cmd-fill-paragraph【バグでしょう】"
"cmd-fill-paragraph [seems like a bug]")))
)
(message
cmd-fill-paragraph: 行頭が REM 又は ECHO ではありません"
"cmd-fill-paragraph: The line doesn't start with REM nor ECHO.")
)
)
)
)
(defun cmd-goto-label ()
指定したラベルへジャンプします。
Jump to the specified label.
Label can be completed at the mini-buffer. A word at the cursor
position is shown as default (if it matches one of existing
labels)."
(interactive)
(let ((label-alist '())
(label nil))
(save-excursion
(goto-char (point-min))
(while (re-search-forward
"^[ \t]*:\\([:A-Za-z0-9_-]+\\)\\([\t ]\\|$\\)" nil t)
(setq label-alist (cons (list (buffer-substring (match-beginning 1)
(match-end 1)))
label-alist))))
(if (not label-alist)
(error ラベルが見つかりません"
"No label found"))
(setq label (completing-read "Label: class="string">" label-alist nil t
(if (assoc (current-word) label-alist)
(current-word) "")))
(when (and label (not (string= label "")))
(push-mark (point))
(goto-char (point-min))
(re-search-forward (concat "^[\t ]*: class="string">" label "\\([ \t]\\|$\\)"))
)
)
)
(defun cmd-mode ()
MS-DOSのバッチファイルやWindows NT のコマンドスクリプトファイルを編
Tiny mode for editing batch files (MS-DOS) and command scripts (Windows NT).
* Save buffer and execute it.
\\[cmd-exec]
* Show help of a command.
\\[cmd-help]
* Jump to the specified label.
\\[cmd-goto-label]
* Set the point to the center, and delete extra spaces at the end
of line.
\\[cmd-recenter]
* Fill comment lines (e.g REM, ECHO).
\\[cmd-fill-paragraph]
* Jump to the previous label.
\\[cmd-prev-label]
* Jump to the next label.
\\[cmd-next-label]"
(interactive)
(kill-all-local-variables)
(setq major-mode 'cmd-mode
CMDとBAT")
mode-name "CMD")
(setq cmd-local-map (make-keymap))
(define-key cmd-local-map "\C-c\C-c" 'cmd-exec)
(define-key cmd-local-map "\C-cg" 'cmd-goto-label)
(define-key cmd-local-map "\C-ch" 'cmd-help)
(define-key cmd-local-map "\C-l" 'cmd-recenter)
\eq" 'cmd-fill-paragraph)
(define-key cmd-local-map "\M-q" 'cmd-fill-paragraph)
\e\C-a" 'cmd-prev-label)
(define-key cmd-local-map "\M-\C-a" 'cmd-prev-label)
\e\C-e" 'cmd-next-label)
(define-key cmd-local-map "\M-\C-e" 'cmd-next-label)
(define-key cmd-submenu-jump [sub-goto-label]
'(任意のラベル..."
"Specified label" . cmd-goto-label))
(define-key cmd-submenu-jump [sub-next-label]
'(次のラベル"
"Next label" . cmd-next-label))
(define-key cmd-submenu-jump [sub-prev-label]
'(前のラベル"
"Previous label" . cmd-prev-label))
(define-key cmd-local-map [menu-bar cmd] (cons mode-name cmd-menu-bar))
(define-key cmd-menu-bar [submenu-jump] (cons "Jump" ジャンプ"
cmd-submenu-jump))
(define-key cmd-menu-bar [sep-1] '("--"))
(define-key cmd-menu-bar [help] '("Help" ヘルプ..."
. cmd-help))
(define-key cmd-menu-bar [sep-2] '("--"))
(define-key cmd-menu-bar [recenter] '("Delete trailing spaces"
行末の空白文字削除"
. cmd-recenter))
(define-key cmd-menu-bar [fill] '("Fill comments" コメントの行詰め"
. cmd-fill-paragraph))
(define-key cmd-menu-bar [exec] '("実行" . cmd-exec))
(use-local-map cmd-local-map)
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults
'((cmd-font-lock-keywords) t t))
(font-lock-mode t)
(run-hooks 'cmd-mode-hook)
)
(provide 'cmd-mode)