xyzzy関連

テキストエディタxyzzy用の簡易VHDLモード

・色付け、括弧対応の確認ができる。
・xyzzyに付属のpascal.lを下記のように小改造してvhdl-mode.lを作成。
  * 全ての"pascal"を"vhdl"に置換。
  * "'", "\", "{", "}", "(*", "*)"が扱われないように削除。
  * "--"から行末までがコメントとして扱われるように追加(C++の//を流用)。
  * 他はそのまま。
・vhdl-mode.elを参考にしてキーワードファイル"VHDL"を作成。
・siteinit.lまたは.xyzzyにこのモードを追加。

;----------------------------------------
;    ..../xyzzy/lisp/vhdl-mode.l
;----------------------------------------

(provide "vhdl")

(in-package "editor")

(export '(*vhdl-mode-hook* vhdl-mode *vhdl-keyword-file*
          vhdl-electric-rbrace vhdl-goto-matched-parenthesis
          *vhdl-indent-tabs-mode*))

(defvar *vhdl-mode-hook* nil)

(defvar *vhdl-indent-tabs-mode* nil)

(defvar *vhdl-keyword-hash-table* nil)
(defvar *vhdl-keyword-file* "VHDL")

(defvar *vhdl-mode-syntax-table* nil)
(unless *vhdl-mode-syntax-table*
  (setq *vhdl-mode-syntax-table* (make-syntax-table))
  (do ((x #x21 (1+ x)))((>= x #x7f))
    (let ((c (code-char x)))
      (unless (alphanumericp c)
        (set-syntax-punctuation *vhdl-mode-syntax-table* c))))
  (set-syntax-string *vhdl-mode-syntax-table* #\")
; (set-syntax-string *vhdl-mode-syntax-table* #\')               ;delete
; (set-syntax-escape *vhdl-mode-syntax-table* #\\)               ;delete
  (set-syntax-symbol *vhdl-mode-syntax-table* #\_)
  (set-syntax-match *vhdl-mode-syntax-table* #\( #\))
  (set-syntax-match *vhdl-mode-syntax-table* #\[ #\])
; (set-syntax-start-comment *vhdl-mode-syntax-table* #\{)        ;delete
; (set-syntax-end-comment *vhdl-mode-syntax-table* #\})          ;delete
; (set-syntax-start-multi-comment *vhdl-mode-syntax-table* "(*") ;delete
; (set-syntax-end-multi-comment *vhdl-mode-syntax-table* "*)"))  ;delete
  (set-syntax-start-c++-comment *vhdl-mode-syntax-table* #\-)    ;add
  (set-syntax-end-c++-comment *vhdl-mode-syntax-table* #\LFD))   ;add

(defvar *vhdl-mode-map* nil)
(unless *vhdl-mode-map*
  (setq *vhdl-mode-map* (make-sparse-keymap))
  (define-key *vhdl-mode-map* #\} 'vhdl-electric-rbrace)
  (define-key *vhdl-mode-map* '(#\ESC #\]) 'vhdl-goto-matched-parenthesis))

(defvar *vhdl-mode-abbrev-table* nil)
(unless *vhdl-mode-abbrev-table*
  (define-abbrev-table '*vhdl-mode-abbrev-table*))

(defun vhdl-electric-rbrace (&optional (arg 1))
  (interactive "*p")
  (self-insert-command arg)
  (and (interactive-p)
       (not *executing-macro*)
       (save-excursion
         (and (scan-buffer "{" :reverse t)
              (show-matched-parenthesis))))
  t)

(defun vhdl-goto-matched-parenthesis ()
  (interactive)
  (cond ((looking-at "[][()]")
         (goto-matched-parenthesis))
        ((looking-for "}")
         (unless (scan-buffer "{" :reverse t)
           (message "一致する括弧が見つかりません")))
        ((looking-for "{")
         (unless (scan-buffer "}")
           (message "一致する括弧が見つかりません")))
        (t
         (let ((pos (save-excursion
                      (let ((tail (progn
                                    (skip-syntax-spec-forward "w_")
                                    (point))))
                        (skip-syntax-spec-backward "w_")
                        (cond ((and (looking-for "begin" t)
                                    (= (- tail (point)) 5))
                               (goto-char tail)
                               (if (forward-identifier "end" "begin" t)
                                   (point)
                                 (progn
                                   (message "一致するendが見つかりません")
                                   nil)))
                              ((and (looking-for "end" t)
                                    (= (- tail (point)) 3))
                               (forward-char -1)
                               (if (backward-identifier "begin" "end" t)
                                   (point)
                                 (progn
                                   (message "一致するbeginが見つかりません")
                                   nil))))))))
           (when pos
             (goto-char pos))))))

(defun vhdl-mode ()
  (interactive)
  (kill-all-local-variables)
  (setq mode-name "VHDL")
  (setq buffer-mode 'vhdl-mode)
  (use-syntax-table *vhdl-mode-syntax-table*)
  (use-keymap *vhdl-mode-map*)
  (make-local-variable 'paragraph-start)
  (setq paragraph-start "^$\\|\f")
  (make-local-variable 'paragraph-separate)
  (setq paragraph-separate paragraph-start)
  (make-local-variable 'indent-tabs-mode)
  (setq indent-tabs-mode *vhdl-indent-tabs-mode*)
  (and *vhdl-keyword-file*
       (null *vhdl-keyword-hash-table*)
       (setq *vhdl-keyword-hash-table*
             (load-keyword-file *vhdl-keyword-file* t)))
  (when *vhdl-keyword-hash-table*
    (make-local-variable 'keyword-hash-table)
    (setq keyword-hash-table *vhdl-keyword-hash-table*))
  (setq *local-abbrev-table* *vhdl-mode-abbrev-table*)
  (run-hooks '*vhdl-mode-hook*))

;----------------------------------------
;    ..../xyzzy/etc/VHDL
;----------------------------------------

abs
access
after
alias
all
and
arch
architecture
array
assert
attr
attribute
begin
block
body
buffer
bus
case
comp
component
cond
conditional
conf
configuration
cons
constant
disconnect
downto
else
elseif
elsif
end
entity
exit
file
for
func
function
generic
group
guarded
if
impure
in
inertial
inout
inst
instance
is
label
library
linkage
literal
loop
map
mod
nand
new
next
nor
not
null
of
on
open
or
others
out
pack
package
port
postponed
procedure
process
pure
range
record
register
reject
rem
report
return
rol
ror
select
severity
shared
sig
signal
sla
sll
sra
srl
subtype
then
to
transport
type
unaffected
units
until
use
var
variable
wait
when
while
with
xnor
xor

;----------------------------------------
;    ..../xyzzy/site-lisp/siteinit.l
;    (or ..../xyzzy/.xyzzy)
;----------------------------------------

(require "vhdl-mode")
(push '("\\.vhd$" . vhdl-mode) *auto-mode-alist*)