1 ;;; snmp-mode.el --- SNMP & SNMPv2 MIB major mode
3 ;; Copyright (C) 1995, 1998, 2001-2018 Free Software Foundation, Inc.
5 ;; Author: Paul D. Smith <psmith@BayNetworks.com>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
27 ;; This package provides a major mode for editing SNMP MIBs. It
28 ;; provides all the modern Emacs 19 bells and whistles: default
29 ;; fontification via font-lock, imenu search functions, etc.
31 ;; SNMP mode also uses tempo, a textual boilerplate insertion package
32 ;; distributed with Emacs, to add in boilerplate SNMP MIB structures.
33 ;; See tempo.el for more details about tempo.
35 ;; If you want to change or add new tempo templates, use the tempo tag
36 ;; list `snmp-tempo-tags' (or `snmpv2-tempo-tags'): this list is
37 ;; automatically installed when snmp-mode (or snmpv2-mode) is entered.
39 ;; The SNMPv2 mode in this version has been enhanced thanks to popular
42 ;; I'm very interested in new tempo macros for both v1 and v2, and any
43 ;; other suggestions for enhancements (different syntax table items, new
49 ;; Mostly, use it as you would any other mode. There's a very
50 ;; simplistic auto-indent feature; hopefully it'll help more than get in
51 ;; your way. For the most part it tries to indent to the same level as
52 ;; the previous line. It will try to recognize some very simple tokens
53 ;; on the previous line that tell it to use extra indent or outdent.
57 ;; To use the Tempo templates, type the Tempo tag (or a unique prefix)
58 ;; and use C-c C-i (C-c TAB) to complete it; if you don't have
59 ;; tempo-interactive set to nil it will ask you to fill in values.
60 ;; Fields with predefined values (SYNTAX, STATUS, etc.) will do
61 ;; completing-reads on a list of valid values; use the normal SPC or TAB
64 ;; Currently the following templates are available:
66 ;; objectType -- Defines an OBJECT-TYPE macro.
68 ;; tableType -- Defines both a Table and Entry OBJECT-TYPE, and a
69 ;; SEQUENCE for the ASN.1 Entry definition.
71 ;; Once the template is done, you can use C-cC-f and C-cC-b to move back
72 ;; and forth between the Tempo sequence points to fill in the rest of
78 ;; If you want font-lock in your MIB buffers, add this:
80 ;; (add-hook 'snmp-common-mode-hook 'turn-on-font-lock)
82 ;; Enabling global-font-lock-mode is also sufficient.
88 (require 'imenu
)) ; Need this stuff when compiling for imenu macros, etc.
92 ;;;----------------------------------------------------------------------------
96 ;;;----------------------------------------------------------------------------
99 "Mode for editing SNMP MIB files."
103 (defcustom snmp-special-indent t
104 "If non-nil, use a simple heuristic to try to guess the right indentation.
105 If nil, then no special indentation is attempted."
109 (defcustom snmp-indent-level
4
110 "Indentation level for SNMP MIBs."
114 (defcustom snmp-tab-always-indent nil
115 "Non-nil means TAB should always reindent the current line.
116 A value of nil means reindent if point is within the initial line indentation;
117 otherwise insert a TAB."
121 (defcustom snmp-completion-ignore-case t
122 "Non-nil means that case differences are ignored during completion.
123 A value of nil means that case is significant.
124 This is used during Tempo template completion."
128 (defcustom snmp-common-mode-hook nil
129 "Hook(s) evaluated when a buffer enters either SNMP or SNMPv2 mode."
133 (defcustom snmp-mode-hook nil
134 "Hook(s) evaluated when a buffer enters SNMP mode."
138 (defcustom snmpv2-mode-hook nil
139 "Hook(s) evaluated when a buffer enters SNMPv2 mode."
143 (defvar snmp-tempo-tags nil
144 "Tempo tags for SNMP mode.")
146 (defvar snmpv2-tempo-tags nil
147 "Tempo tags for SNMPv2 mode.")
150 ;; Enable fontification for SNMP MIBs
153 ;; These are pretty basic fontifications. Note we assume these macros
154 ;; are first on a line (except whitespace), to speed up fontification.
156 (defvar snmp-font-lock-keywords-1
158 ;; OBJECT-TYPE, TRAP-TYPE, and OBJECT-IDENTIFIER macros
159 '("^[ \t]*\\([a-z][-a-zA-Z0-9]+\\)[ \t]+\\(\\(MODULE-\\(COMPLIANCE\\|IDENTITY\\)\\|OBJECT-\\(COMPLIANCE\\|GROUP\\|IDENTITY\\|TYPE\\)\\|TRAP-\\(GROUP\\|TYPE\\)\\)\\|\\(OBJECT\\)[ \t]+\\(IDENTIFIER\\)[ \t]*::=\\)"
160 (1 font-lock-variable-name-face
) (3 font-lock-keyword-face nil t
)
161 (7 font-lock-keyword-face nil t
) (8 font-lock-keyword-face nil t
))
163 ;; DEFINITIONS clause
164 '("^[ \t]*\\([A-Z][-a-zA-Z0-9]+\\)[ \t]+\\(DEFINITIONS\\)[ \t]*::="
165 (1 font-lock-function-name-face
) (2 font-lock-keyword-face
))
167 "Basic SNMP MIB mode expression highlighting.")
169 (defvar snmp-font-lock-keywords-2
171 '(("ACCESS\\|BEGIN\\|DE\\(FVAL\\|SCRIPTION\\)\\|END\\|FROM\\|I\\(MPORTS\\|NDEX\\)\\|S\\(TATUS\\|YNTAX\\)"
172 (0 font-lock-keyword-face
)))
173 snmp-font-lock-keywords-1
)
174 "Medium SNMP MIB mode expression highlighting.")
176 (defvar snmp-font-lock-keywords-3
178 '(("\\([^\n]+\\)[ \t]+::=[ \t]+\\(SEQUENCE\\)[ \t]+{"
179 (1 font-lock-constant-face
) (2 font-lock-keyword-face
))
180 ("::=[ \t]*{[ \t]*\\([a-z0-9].*[ \t]+\\)?\\([0-9]+\\)[ \t]*}"
181 (1 font-lock-constant-face nil t
) (2 font-lock-variable-name-face
)))
182 snmp-font-lock-keywords-2
)
183 "Gaudy SNMP MIB mode expression highlighting.")
185 (defvar snmp-font-lock-keywords snmp-font-lock-keywords-1
186 "Default SNMP MIB mode expression highlighting.")
189 ;; These lists are used for the completion capabilities in the tempo
193 (defvar snmp-mode-syntax-list nil
194 "Predefined types for SYNTAX clauses.")
196 (defvar snmp-rfc1155-types
197 '("INTEGER" "OCTET STRING" "OBJECT IDENTIFIER" "NULL" "IpAddress"
198 "NetworkAddress" "Counter" "Gauge" "TimeTicks" "Opaque")
199 "Types from RFC 1155 v1 SMI.")
201 (defvar snmp-rfc1213-types
203 "Types from RFC 1213 MIB-II.")
205 (defvar snmp-rfc1902-types
206 '("INTEGER" "OCTET STRING" "OBJECT IDENTIFIER" "Integer32"
207 "IpAddress" "Counter32" "Gauge32" "Unsigned32" "TimeTicks"
208 "Opaque" "Counter64")
209 "Types from RFC 1902 v2 SMI.")
211 (defvar snmp-rfc1903-types
212 '("DisplayString" "PhysAddress" "MacAddress" "TruthValue"
213 "TestAndIncr" "AutonomousType" "InstancePointer"
214 "VariablePointer" "RowPointer" "RowStatus" "TimeStamp"
215 "TimeInterval" "DateAndTime" "StorageType" "TDomain"
217 "Types from RFC 1903 Textual Conventions.")
220 (defvar snmp-mode-access-list nil
221 "Predefined values for ACCESS clauses.")
223 (defvar snmp-rfc1155-access
224 '("read-only" "read-write" "write-only" "not-accessible")
225 "ACCESS values from RFC 1155 v1 SMI.")
227 (defvar snmp-rfc1902-access
228 '("read-only" "read-write" "read-create" "not-accessible"
229 "accessible-for-notify")
230 "ACCESS values from RFC 1155 v1 SMI.")
233 (defvar snmp-mode-status-list nil
234 "Predefined values for STATUS clauses.")
236 (defvar snmp-rfc1212-status
237 '("mandatory" "obsolete" "deprecated")
238 "STATUS values from RFC 1212 v1 SMI.")
240 (defvar snmp-rfc1902-status
241 '("current" "obsolete" "deprecated")
242 "STATUS values from RFC 1902 v2 SMI.")
245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
246 ;;;----------------------------------------------------------------------------
248 ;; Nothing to customize below here.
250 ;;;----------------------------------------------------------------------------
251 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
254 ;; Create abbrev table for SNMP MIB mode
256 (defvar snmp-mode-abbrev-table nil
257 "Abbrev table in use in SNMP mode.")
258 (define-abbrev-table 'snmp-mode-abbrev-table
())
261 ;; Create abbrev table for SNMPv2 mode
263 (defvar snmpv2-mode-abbrev-table nil
264 "Abbrev table in use in SNMPv2 mode.")
265 (define-abbrev-table 'snmpv2-mode-abbrev-table
())
270 (defvar snmp-mode-map
271 (let ((map (make-sparse-keymap)))
272 (define-key map
"\177" 'backward-delete-char-untabify
)
273 (define-key map
"\C-c\C-i" 'tempo-complete-tag
)
274 (define-key map
"\C-c\C-f" 'tempo-forward-mark
)
275 (define-key map
"\C-c\C-b" 'tempo-backward-mark
)
277 "Keymap used in SNMP mode.")
280 ;; Set up our syntax table
282 (defvar snmp-mode-syntax-table
283 (let ((st (make-syntax-table)))
284 (modify-syntax-entry ?
\\ "\\" st
)
285 (modify-syntax-entry ?-
"_ 1234" st
)
286 (modify-syntax-entry ?
\n ">" st
)
287 (modify-syntax-entry ?\^m
">" st
)
288 (modify-syntax-entry ?_
"." st
)
289 (modify-syntax-entry ?
: "." st
)
290 (modify-syntax-entry ?
= "." st
)
292 "Syntax table used for buffers in SNMP mode.")
294 ;; Set up the stuff that's common between snmp-mode and snmpv2-mode
296 (defun snmp-common-mode (name mode abbrev font-keywords imenu-index tempo-tags
)
297 (kill-all-local-variables)
299 ;; Become the current major mode
300 (setq mode-name name
)
301 (setq major-mode mode
)
303 ;; Activate keymap, syntax table, and abbrev table
304 (use-local-map snmp-mode-map
)
305 (set-syntax-table snmp-mode-syntax-table
)
306 (setq local-abbrev-table abbrev
)
308 ;; Set up paragraphs (?)
309 (make-local-variable 'paragraph-start
)
310 (setq paragraph-start
(concat "$\\|" page-delimiter
))
311 (make-local-variable 'paragraph-separate
)
312 (setq paragraph-separate paragraph-start
)
313 (make-local-variable 'paragraph-ignore-fill-prefix
)
314 (setq paragraph-ignore-fill-prefix t
)
317 (make-local-variable 'comment-start
)
318 (setq comment-start
"-- ")
319 (make-local-variable 'comment-start-skip
)
320 (setq comment-start-skip
"--+[ \t]*")
321 (make-local-variable 'comment-column
)
322 (setq comment-column
40)
323 (make-local-variable 'parse-sexp-ignore-comments
)
324 (setq parse-sexp-ignore-comments t
)
326 ;; Set up indentation
327 (if snmp-special-indent
328 (set (make-local-variable 'indent-line-function
) 'snmp-indent-line
))
329 (set (make-local-variable 'tab-always-indent
) snmp-tab-always-indent
)
332 (make-local-variable 'font-lock-defaults
)
333 (setq font-lock-defaults
(cons font-keywords
'(nil nil
((?- .
"w 1234")))))
336 (make-local-variable 'imenu-create-index-function
)
337 (setq imenu-create-index-function imenu-index
)
340 (tempo-use-tag-list tempo-tags
)
341 (make-local-variable 'tempo-match-finder
)
342 (setq tempo-match-finder
"\\b\\(.+\\)\\=")
343 (make-local-variable 'tempo-interactive
)
344 (setq tempo-interactive t
)
346 ;; Miscellaneous customization
347 (make-local-variable 'require-final-newline
)
348 (setq require-final-newline mode-require-final-newline
))
351 ;; SNMPv1 MIB Editing Mode.
355 "Major mode for editing SNMP MIBs.
356 Expression and list commands understand all C brackets.
357 Tab indents for C code.
358 Comments start with -- and end with newline or another --.
359 Delete converts tabs to spaces as it moves back.
361 Turning on snmp-mode runs the hooks in `snmp-common-mode-hook', then
365 (snmp-common-mode "SNMP" 'snmp-mode
366 snmp-mode-abbrev-table
367 '(snmp-font-lock-keywords
368 snmp-font-lock-keywords-1
369 snmp-font-lock-keywords-2
370 snmp-font-lock-keywords-3
)
371 'snmp-mode-imenu-create-index
375 (make-local-variable 'snmp-mode-syntax-list
)
376 (setq snmp-mode-syntax-list
(append snmp-rfc1155-types
378 snmp-mode-syntax-list
))
379 (make-local-variable 'snmp-mode-access-list
)
380 (setq snmp-mode-access-list snmp-rfc1155-access
)
381 (make-local-variable 'snmp-mode-status-list
)
382 (setq snmp-mode-status-list snmp-rfc1212-status
)
385 (run-mode-hooks 'snmp-common-mode-hook
'snmp-mode-hook
))
389 (defun snmpv2-mode ()
390 "Major mode for editing SNMPv2 MIBs.
391 Expression and list commands understand all C brackets.
392 Tab indents for C code.
393 Comments start with -- and end with newline or another --.
394 Delete converts tabs to spaces as it moves back.
396 Turning on snmp-mode runs the hooks in `snmp-common-mode-hook',
397 then `snmpv2-mode-hook'."
400 (snmp-common-mode "SNMPv2" 'snmpv2-mode
401 snmpv2-mode-abbrev-table
402 '(snmp-font-lock-keywords
403 snmp-font-lock-keywords-1
404 snmp-font-lock-keywords-2
405 snmp-font-lock-keywords-3
)
406 'snmp-mode-imenu-create-index
410 (make-local-variable 'snmp-mode-syntax-list
)
411 (setq snmp-mode-syntax-list
(append snmp-rfc1902-types
413 snmp-mode-syntax-list
))
414 (make-local-variable 'snmp-mode-access-list
)
415 (setq snmp-mode-access-list snmp-rfc1902-access
)
416 (make-local-variable 'snmp-mode-status-list
)
417 (setq snmp-mode-status-list snmp-rfc1902-status
)
420 (run-mode-hooks 'snmp-common-mode-hook
'snmpv2-mode-hook
))
423 ;;;----------------------------------------------------------------------------
427 ;;;----------------------------------------------------------------------------
429 (defvar snmp-macro-open
430 "[a-zA-Z][-a-zA-Z0-9]*[ \t]*\\(OBJECT\\|TRAP\\)-\\(TYPE\\|GROUP\\)\
431 \\|DESCRIPTION\\|IMPORTS\\|MODULE\\(-IDENTITY\\|-COMPLIANCE\\)\
432 \\|.*::=[ \t]*\\(BEGIN\\|TEXTUAL-CONVENTION\\)[ \t]*$")
434 (defvar snmp-macro-close
435 "::=[ \t]*{\\|\\(END\\|.*[;\"]\\)[ \t]*$")
437 (defun snmp-calculate-indent ()
438 "Calculate the current line indentation in SNMP MIB code.
440 We use a very simple scheme: if the previous non-empty line was a \"macro
441 open\" string, add `snmp-indent-level' to it. If it was a \"macro close\"
442 string, subtract `snmp-indent-level'. Otherwise, use the same indentation
443 as the previous non-empty line. Note comments are considered empty
444 lines for the purposes of this function."
445 (let ((empty (concat "\\([ \t]*\\)\\(" comment-start-skip
"\\|$\\)"))
446 (case-fold-search nil
)) ; keywords must be in uppercase
448 (while (and (>= (forward-line -
1) 0)
450 (skip-chars-forward " \t")
452 ;; Are we looking at a macro open string? If so, add more.
453 (cond ((looking-at snmp-macro-open
)
455 ;; macro close string? If so, remove some.
456 ((looking-at snmp-macro-close
)
457 (- snmp-indent-level
))
458 ;; Neither; just stay here.
461 (defun snmp-indent-line ()
462 "Indent current line as SNMP MIB code."
463 (let ((indent (snmp-calculate-indent))
464 (pos (- (point-max) (point)))
468 (skip-chars-forward " \t")
469 (setq shift-amt
(- indent
(current-column)))
470 (if (zerop shift-amt
)
472 (delete-region beg
(point))
474 ;; If initial point was within line's indentation,
475 ;; position after the indentation. Else stay at same point in text.
476 (if (> (- (point-max) pos
) (point))
477 (goto-char (- (point-max) pos
)))))
480 ;;;----------------------------------------------------------------------------
484 ;;;----------------------------------------------------------------------------
486 (defvar snmp-clause-regexp
487 "^[ \t]*\\([a-zA-Z][-a-zA-Z0-9]*\\)[ \t\n]*\
488 \\(TRAP-TYPE\\|::=\\|OBJECT\\(-TYPE[ \t\n]+SYNTAX\\|[ \t\n]+IDENTIFIER[ \t\n]*::=\\)\\)")
490 (defun snmp-mode-imenu-create-index ()
491 (let ((index-alist '())
492 (index-oid-alist '())
494 (index-table-alist '())
495 (index-trap-alist '())
496 (case-fold-search nil
) ; keywords must be uppercase
498 (goto-char (point-min))
499 (imenu-progress-message prev-pos
0)
500 ;; Search for a useful MIB item (that's not in a comment)
502 (while (re-search-forward snmp-clause-regexp nil t
)
503 (imenu-progress-message prev-pos
)
506 token
(cons (match-string 1)
507 (set-marker (make-marker) (match-beginning 1))))
508 (goto-char (match-beginning 2))
509 (cond ((looking-at "OBJECT-TYPE[ \t\n]+SYNTAX")
510 (push token index-alist
))
511 ((looking-at "OBJECT[ \t\n]+IDENTIFIER[ \t\n]*::=")
512 (push token index-oid-alist
))
513 ((looking-at "::=[ \t\n]*SEQUENCE[ \t\n]*{")
514 (push token index-table-alist
))
515 ((looking-at "TRAP-TYPE")
516 (push token index-trap-alist
))
518 (push token index-tc-alist
)))
521 (imenu-progress-message prev-pos
100)
522 (setq index-alist
(nreverse index-alist
))
524 (push (cons "Textual Conventions" (nreverse index-tc-alist
))
526 (and index-trap-alist
527 (push (cons "Traps" (nreverse index-trap-alist
))
529 (and index-table-alist
530 (push (cons "Tables" (nreverse index-table-alist
))
533 (push (cons "Object IDs" (nreverse index-oid-alist
))
538 ;;;----------------------------------------------------------------------------
542 ;;;----------------------------------------------------------------------------
544 ;; Perform a completing-read with info given
546 (defun snmp-completing-read (prompt table
&optional pred require init hist
)
547 "Read from the minibuffer, with completion.
548 Like `completing-read', but the variable `snmp-completion-ignore-case'
549 controls whether case is significant."
550 (let ((completion-ignore-case snmp-completion-ignore-case
))
551 (completing-read prompt table pred require init hist
)))
553 ;; OBJECT-TYPE macro template
555 (tempo-define-template "snmp-object-type"
556 '(> (P "Object Label: ") " OBJECT-TYPE" n
>
558 (if tempo-interactive
559 (snmp-completing-read "Syntax: " snmp-mode-syntax-list nil nil
)
562 (if tempo-interactive
563 (snmp-completing-read "Access: " snmp-mode-access-list nil t
)
566 (if tempo-interactive
567 (snmp-completing-read "Status: " snmp-mode-status-list nil t
)
569 "DESCRIPTION" n
> "\"" p
"\"" n
>
570 (P "Default Value: " defval t
)
571 (if (string= "" (tempo-lookup-named 'defval
))
573 '(l "DEFVAL { " (s defval
) " }" n
>))
574 "::= { " (p "OID: ") " }" n
)
576 "Insert an OBJECT-TYPE macro."
579 ;; Table macro template
581 (tempo-define-template "snmp-table-type"
582 ;; First the table OBJECT-TYPE
583 '(> (P "Table Name: " table
)
584 (P "Entry Name: " entry t
)
585 (let* ((entry (tempo-lookup-named 'entry
))
586 (seq (copy-sequence entry
)))
587 (aset entry
0 (downcase (aref entry
0)))
588 (aset seq
0 (upcase (aref seq
0)))
589 (tempo-save-named 'obj-entry entry
)
590 (tempo-save-named 'seq-entry seq
)
593 "SYNTAX SEQUENCE OF "
595 "ACCESS not-accessible" n
>
596 "STATUS mandatory" n
>
597 "DESCRIPTION" n
> "\"" p
"\"" n
>
598 "::= { " (p "OID: ") " }" n n
>
599 ;; Next the row OBJECT-TYPE
600 (s obj-entry
) " OBJECT-TYPE" n
>
601 "SYNTAX " (s seq-entry
) n
>
602 "ACCESS not-accessible" n
>
603 "STATUS mandatory" n
>
604 "DESCRIPTION" n
> "\"" p
"\"" n
>
605 "INDEX { " (p "Index List: ") " }" n
>
606 "::= {" (s table
) " 1 }" n n
>
607 ;; Finally the SEQUENCE type
608 (s seq-entry
) " ::= SEQUENCE {" n
> p n
> "}" n
)
610 "Insert an SNMP table."
614 ;; v2 SMI OBJECT-TYPE macro template
616 (tempo-define-template "snmpv2-object-type"
617 '(> (P "Object Label: ") " OBJECT-TYPE" n
>
619 (if tempo-interactive
620 (snmp-completing-read "Syntax: " snmp-mode-syntax-list nil nil
)
623 (if tempo-interactive
624 (snmp-completing-read "Max Access: " snmp-mode-access-list nil t
)
627 (if tempo-interactive
628 (snmp-completing-read "Status: " snmp-mode-status-list nil t
)
630 "DESCRIPTION" n
> "\"" p
"\"" n
>
631 (P "Default Value: " defval t
)
632 (if (string= "" (tempo-lookup-named 'defval
))
634 '(l "DEFVAL { " (s defval
) " }" n
>))
635 "::= { " (p "OID: ") " }" n
)
637 "Insert an v2 SMI OBJECT-TYPE macro."
640 ;; v2 SMI Table macro template
642 (tempo-define-template "snmpv2-table-type"
643 ;; First the table OBJECT-TYPE
644 '(> (P "Table Name: " table
)
645 (P "Entry Name: " entry t
)
646 (let* ((entry (tempo-lookup-named 'entry
))
647 (seq (copy-sequence entry
)))
648 (aset entry
0 (downcase (aref entry
0)))
649 (aset seq
0 (upcase (aref seq
0)))
650 (tempo-save-named 'obj-entry entry
)
651 (tempo-save-named 'seq-entry seq
)
654 "SYNTAX SEQUENCE OF "
656 "MAX-ACCESS not-accessible" n
>
658 "DESCRIPTION" n
> "\"" p
"\"" n
>
659 "::= { " (p "OID: ") " }" n n
>
660 ;; Next the row OBJECT-TYPE
661 (s obj-entry
) " OBJECT-TYPE" n
>
662 "SYNTAX " (s seq-entry
) n
>
663 "MAX-ACCESS not-accessible" n
>
665 "DESCRIPTION" n
> "\"" p
"\"" n
>
666 "INDEX { " (p "Index List: ") " }" n
>
667 "::= { " (s table
) " 1 }" n n
>
668 ;; Finally the SEQUENCE type
669 (s seq-entry
) " ::= SEQUENCE {" n
> p n
> "}" n
)
671 "Insert an v2 SMI SNMP table."
674 ;; v2 SMI TEXTUAL-CONVENTION macro template
676 (tempo-define-template "snmpv2-textual-convention"
677 '(> (P "Textual Convention Type: ") " ::= TEXTUAL-CONVENTION" n
>
679 (if tempo-interactive
680 (snmp-completing-read "Status: " snmp-mode-status-list nil t
)
682 "DESCRIPTION" n
> "\"" p
"\"" n
>
684 (if tempo-interactive
685 (snmp-completing-read "Syntax: " snmp-mode-syntax-list nil nil
)
688 "Insert an v2 SMI TEXTUAL-CONVENTION macro."
694 ;;; snmp-mode.el ends here