;; stk-mode.el - A major-mode for editing stk scripts ;; ;; Author of tcl-mode.el: ;; Author: Gregor Schmid ;; Keywords: languages, processes, tools ;; ;; Maintainer of lisp-mode.el ;; Maintainer: FSF ;; Keywords: lisp, languages ;; This file is not part of GNU Emacs. ;; Merged from tcl-mode.el and lisp-mode.el from ;; Erwin Burgstaller ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. ;; Stk-mode supports c-mode style formatting and sending of ;; lines/regions/files to a stk interpreter. An interpreter (see ;; variable `stk-default-application') will be started if you try to ;; send some code and none is running. You can use the process-buffer ;; (named after the application you chose) as if it were an ;; interactive shell. See the documentation for `comint.el' for ;; details. ;; Another version of this package which has support for other Emacs ;; versions is in the LCD archive. ;;}}} ;;{{{ Key-bindings ;; To see all the keybindings for folding mode, look at `stk-setup-keymap' ;; or start `stk-mode' and type `\C-h m'. ;; The keybindings may seem strange, since I prefer to use them with ;; stk-prefix-key set to nil, but since those keybindings are already used ;; the default for `stk-prefix-key' is `\C-c', which is the conventional ;; prefix for major-mode commands. ;; You can customise the keybindings either by setting `stk-prefix-key' ;; or by putting the following in your .emacs ;; (setq stk-mode-map (make-sparse-keymap)) ;; and ;; (define-key stk-mode-map ) ;; for all the functions you need. ;;}}} ;;{{{ Variables ;; You may want to customize the following variables: ;; stk-always-show ;; stk-mode-map ;; stk-prefix-key ;; stk-mode-hook ;; stk-default-application ;; stk-default-command-switches ;;}}} ;;; Code: ;; We need that ! (require 'comint) ;;{{{ variables (defvar stk-default-application "stk" "Default stk/tk application to run in stk subprocess.") (defvar stk-default-command-switches nil "Command switches for `stk-default-application'. Should be a list of strings.") (defvar stk-process nil "The active stk subprocess corresponding to current buffer.") (defvar stk-process-buffer nil "Buffer used for communication with stk subprocess for current buffer.") (defvar stk-always-show t "*Non-nil means display stk-process-buffer after sending a command.") (defvar stk-mode-map nil "Keymap used with stk mode.") (defvar stk-prefix-key "\C-c" "Prefix for all stk-mode commands.") (defvar stk-mode-hook nil "Hooks called when stk mode fires up.") (defvar stk-region-start (make-marker) "Start of special region for stk communication.") (defvar stk-region-end (make-marker) "End of special region for stk communication.") (defvar stk-indent-level 4 "Amount by which stk subexpressions are indented.") (defvar stk-default-eval "eval" "Default command used when sending regions.") (defvar stk-mode-menu (make-sparse-keymap "Stk-Mode") "Keymap for stk-mode's menu.") ;;}}} ;;{{{ stk-mode ;;;###autoload (defun stk-mode () "Major mode for editing stk scripts. The following keys are bound: \\{stk-mode-map} " (interactive) (let ((switches nil) s) (kill-all-local-variables) (setq major-mode 'stk-mode) (setq mode-name "STK") (set (make-local-variable 'stk-process) nil) (set (make-local-variable 'stk-process-buffer) nil) (make-local-variable 'stk-default-command-switches) (set (make-local-variable 'indent-line-function) 'stk-indent-line) (set (make-local-variable 'comment-start) "#") (set (make-local-variable 'comment-start-skip) "\\(\\(^\\|;\\)[ \t]*\\)#") (make-local-variable 'stk-default-eval) (or stk-mode-map (stk-setup-keymap)) (use-local-map stk-mode-map) (set-syntax-table (copy-syntax-table)) (modify-syntax-entry ?# "<") (modify-syntax-entry ?\n ">") ;; look for a #!.../wish -f line at bob (save-excursion (goto-char (point-min)) (if (looking-at "#![ \t]*\\([^ \t]*\\)[ \t]\\(.*[ \t]\\)*-f") (progn (set (make-local-variable 'stk-default-application) (buffer-substring (match-beginning 1) (match-end 1))) (if (match-beginning 2) (progn (goto-char (match-beginning 2)) (set (make-local-variable 'stk-default-command-switches) nil) (while (< (point) (match-end 2)) (setq s (read (current-buffer))) (if (<= (point) (match-end 2)) (setq stk-default-command-switches (append stk-default-command-switches (list (prin1-to-string s))))))))) ;; if this fails, look for the #!/bin/csh ... exec hack (while (eq (following-char) ?#) (forward-line 1)) (or (bobp) (forward-char -1)) (if (eq (preceding-char) ?\\) (progn (forward-char 1) (if (looking-at "exec[ \t]+\\([^ \t]*\\)[ \t]\\(.*[ \t]\\)*-f") (progn (set (make-local-variable 'stk-default-application) (buffer-substring (match-beginning 1) (match-end 1))) (if (match-beginning 2) (progn (goto-char (match-beginning 2)) (set (make-local-variable 'stk-default-command-switches) nil) (while (< (point) (match-end 2)) (setq s (read (current-buffer))) (if (<= (point) (match-end 2)) (setq stk-default-command-switches (append stk-default-command-switches (list (prin1-to-string s))))))))) ))))) (run-hooks 'stk-mode-hook))) ;;}}} ;;{{{ stk-setup-keymap (defun stk-setup-keymap () "Set up keymap for stk mode. If the variable `stk-prefix-key' is nil, the bindings go directly to `stk-mode-map', otherwise they are prefixed with `stk-prefix-key'." (setq stk-mode-map (make-sparse-keymap)) (define-key stk-mode-map [menu-bar stk-mode] (cons "Stk-Mode" stk-mode-menu)) (let ((map (if stk-prefix-key (make-sparse-keymap) stk-mode-map))) ;; indentation (define-key stk-mode-map [?)] 'stk-electric-brace) ;; communication (define-key map "\M-e" 'stk-send-current-line) (define-key map "\M-r" 'stk-send-region) (define-key map "\M-w" 'stk-send-proc) (define-key map "\M-a" 'stk-send-buffer) (define-key map "\M-q" 'stk-kill-process) (define-key map "\M-u" 'stk-restart-with-whole-file) (define-key map "\M-s" 'stk-show-process-buffer) (define-key map "\M-h" 'stk-hide-process-buffer) (define-key map "\M-i" 'stk-get-error-info) (define-key map "\C-\M-s" 'stk-set-stk-region-start) (define-key map "\C-\M-e" 'stk-set-stk-region-end) (define-key map "\C-\M-r" 'stk-send-stk-region) (if stk-prefix-key (define-key stk-mode-map stk-prefix-key map)) )) ;;}}} ;;{{{ indentation ;;}}} ;;{{{ stk-electric-brace (defun stk-electric-brace (arg) "Insert `}' and indent line for stk." (interactive "P") (insert-char ?) (prefix-numeric-value arg)) (lisp-indent-line) (blink-matching-open)) ;;}}} (defun lisp-comment-indent () (if (looking-at "\\s<\\s<\\s<") (current-column) (if (looking-at "\\s<\\s<") (let ((tem (calculate-lisp-indent))) (if (listp tem) (car tem) tem)) (skip-chars-backward " \t") (max (if (bolp) 0 (1+ (current-column))) comment-column)))) (defconst lisp-indent-offset nil "") (defconst lisp-indent-function 'lisp-indent-function "") (defun lisp-indent-line (&optional whole-exp) "Indent current line as Lisp code. With argument, indent any additional lines of the same expression rigidly along with this one." (interactive "P") (let ((indent (calculate-lisp-indent)) shift-amt beg end (pos (- (point-max) (point)))) (beginning-of-line) (setq beg (point)) (skip-chars-forward " \t") (if (looking-at "\\s<\\s<\\s<") ;; Don't alter indentation of a ;;; comment line. (goto-char (- (point-max) pos)) (if (and (looking-at "\\s<") (not (looking-at "\\s<\\s<"))) ;; Single-semicolon comment lines should be indented ;; as comment lines, not as code. (progn (indent-for-comment) (forward-char -1)) (if (listp indent) (setq indent (car indent))) (setq shift-amt (- indent (current-column))) (if (zerop shift-amt) nil (delete-region beg (point)) (indent-to indent))) ;; If initial point was within line's indentation, ;; position after the indentation. Else stay at same point in text. (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos))) ;; If desired, shift remaining lines of expression the same amount. (and whole-exp (not (zerop shift-amt)) (save-excursion (goto-char beg) (forward-sexp 1) (setq end (point)) (goto-char beg) (forward-line 1) (setq beg (point)) (> end beg)) (indent-code-rigidly beg end shift-amt))))) (defun calculate-lisp-indent (&optional parse-start) "Return appropriate indentation for current line as Lisp code. In usual case returns an integer: the column to indent to. Can instead return a list, whose car is the column to indent to. This means that following lines at the same level of indentation should not necessarily be indented the same way. The second element of the list is the buffer position of the start of the containing expression." (save-excursion (beginning-of-line) (let ((indent-point (point)) state paren-depth ;; setting this to a number inhibits calling hook (desired-indent nil) (retry t) last-sexp containing-sexp) (if parse-start (goto-char parse-start) (beginning-of-defun)) ;; Find outermost containing sexp (while (< (point) indent-point) (setq state (parse-partial-sexp (point) indent-point 0))) ;; Find innermost containing sexp (while (and retry state (> (setq paren-depth (elt state 0)) 0)) (setq retry nil) (setq last-sexp (elt state 2)) (setq containing-sexp (elt state 1)) ;; Position following last unclosed open. (goto-char (1+ containing-sexp)) ;; Is there a complete sexp since then? (if (and last-sexp (> last-sexp (point))) ;; Yes, but is there a containing sexp after that? (let ((peek (parse-partial-sexp last-sexp indent-point 0))) (if (setq retry (car (cdr peek))) (setq state peek))))) (if retry nil ;; Innermost containing sexp found (goto-char (1+ containing-sexp)) (if (not last-sexp) ;; indent-point immediately follows open paren. ;; Don't call hook. (setq desired-indent (current-column)) ;; Find the start of first element of containing sexp. (parse-partial-sexp (point) last-sexp 0 t) (cond ((looking-at "\\s(") ;; First element of containing sexp is a list. ;; Indent under that list. ) ((> (save-excursion (forward-line 1) (point)) last-sexp) ;; This is the first line to start within the containing sexp. ;; It's almost certainly a function call. (if (= (point) last-sexp) ;; Containing sexp has nothing before this line ;; except the first element. Indent under that element. nil ;; Skip the first element, find start of second (the first ;; argument of the function call) and indent under. (progn (forward-sexp 1) (parse-partial-sexp (point) last-sexp 0 t))) (backward-prefix-chars)) (t ;; Indent beneath first sexp on same line as last-sexp. ;; Again, it's almost certainly a function call. (goto-char last-sexp) (beginning-of-line) (parse-partial-sexp (point) last-sexp 0 t) (backward-prefix-chars))))) ;; Point is at the point to indent under unless we are inside a string. ;; Call indentation hook except when overridden by lisp-indent-offset ;; or if the desired indentation has already been computed. (let ((normal-indent (current-column))) (cond ((elt state 3) ;; Inside a string, don't change indentation. (goto-char indent-point) (skip-chars-forward " \t") (current-column)) ((and (integerp lisp-indent-offset) containing-sexp) ;; Indent by constant offset (goto-char containing-sexp) (+ (current-column) lisp-indent-offset)) (desired-indent) ((and (boundp 'lisp-indent-function) lisp-indent-function (not retry)) (or (funcall lisp-indent-function indent-point state) normal-indent)) (t normal-indent)))))) (defun lisp-indent-function (indent-point state) (let ((normal-indent (current-column))) (goto-char (1+ (elt state 1))) (parse-partial-sexp (point) last-sexp 0 t) (if (and (elt state 2) (not (looking-at "\\sw\\|\\s_"))) ;; car of form doesn't seem to be a a symbol (progn (if (not (> (save-excursion (forward-line 1) (point)) last-sexp)) (progn (goto-char last-sexp) (beginning-of-line) (parse-partial-sexp (point) last-sexp 0 t))) ;; Indent under the list or under the first sexp on the ;; same line as last-sexp. Note that first thing on that ;; line has to be complete sexp since we are inside the ;; innermost containing sexp. (backward-prefix-chars) (current-column)) (let ((function (buffer-substring (point) (progn (forward-sexp 1) (point)))) method) (setq method (or (get (intern-soft function) 'lisp-indent-function) (get (intern-soft function) 'lisp-indent-hook))) (cond ((or (eq method 'defun) (and (null method) (> (length function) 3) (string-match "\\`def" function))) (lisp-indent-defform state indent-point)) ((integerp method) (lisp-indent-specform method state indent-point normal-indent)) (method (funcall method state indent-point))))))) (defconst lisp-body-indent 2 "Number of columns to indent the second line of a `(def...)' form.") (defun lisp-indent-specform (count state indent-point normal-indent) (let ((containing-form-start (elt state 1)) (i count) body-indent containing-form-column) ;; Move to the start of containing form, calculate indentation ;; to use for non-distinguished forms (> count), and move past the ;; function symbol. lisp-indent-function guarantees that there is at ;; least one word or symbol character following open paren of containing ;; form. (goto-char containing-form-start) (setq containing-form-column (current-column)) (setq body-indent (+ lisp-body-indent containing-form-column)) (forward-char 1) (forward-sexp 1) ;; Now find the start of the last form. (parse-partial-sexp (point) indent-point 1 t) (while (and (< (point) indent-point) (condition-case () (progn (setq count (1- count)) (forward-sexp 1) (parse-partial-sexp (point) indent-point 1 t)) (error nil)))) ;; Point is sitting on first character of last (or count) sexp. (if (> count 0) ;; A distinguished form. If it is the first or second form use double ;; lisp-body-indent, else normal indent. With lisp-body-indent bound ;; to 2 (the default), this just happens to work the same with if as ;; the older code, but it makes unwind-protect, condition-case, ;; with-output-to-temp-buffer, et. al. much more tasteful. The older, ;; less hacked, behavior can be obtained by replacing below with ;; (list normal-indent containing-form-start). (if (<= (- i count) 1) (list (+ containing-form-column (* 2 lisp-body-indent)) containing-form-start) (list normal-indent containing-form-start)) ;; A non-distinguished form. Use body-indent if there are no ;; distinguished forms and this is the first undistinguished form, ;; or if this is the first undistinguished form and the preceding ;; distinguished form has indentation at least as great as body-indent. (if (or (and (= i 0) (= count 0)) (and (= count 0) (<= body-indent normal-indent))) body-indent normal-indent)))) (defun lisp-indent-defform (state indent-point) (goto-char (car (cdr state))) (forward-line 1) (if (> (point) (car (cdr (cdr state)))) (progn (goto-char (car (cdr state))) (+ lisp-body-indent (current-column))))) ;; (put 'progn 'lisp-indent-function 0), say, causes progn to be indented ;; like defun if the first form is placed on the next line, otherwise ;; it is indented like any other form (i.e. forms line up under first). (put 'lambda 'lisp-indent-function 'defun) (put 'autoload 'lisp-indent-function 'defun) (put 'progn 'lisp-indent-function 0) (put 'prog1 'lisp-indent-function 1) (put 'prog2 'lisp-indent-function 2) (put 'save-excursion 'lisp-indent-function 0) (put 'save-window-excursion 'lisp-indent-function 0) (put 'save-restriction 'lisp-indent-function 0) (put 'save-match-data 'lisp-indent-function 0) (put 'let 'lisp-indent-function 1) (put 'let* 'lisp-indent-function 1) (put 'while 'lisp-indent-function 1) (put 'if 'lisp-indent-function 2) (put 'catch 'lisp-indent-function 1) (put 'condition-case 'lisp-indent-function 2) (put 'unwind-protect 'lisp-indent-function 1) (put 'with-output-to-temp-buffer 'lisp-indent-function 1) (defun indent-sexp (&optional endpos) "Indent each line of the list starting just after point. If optional arg ENDPOS is given, indent each line, stopping when ENDPOS is encountered." (interactive) (let ((indent-stack (list nil)) (next-depth 0) (starting-point (point)) (last-point (point)) last-depth bol outer-loop-done inner-loop-done state this-indent) ;; Get error now if we don't have a complete sexp after point. (save-excursion (forward-sexp 1)) (save-excursion (setq outer-loop-done nil) (while (if endpos (< (point) endpos) (not outer-loop-done)) (setq last-depth next-depth inner-loop-done nil) ;; Parse this line so we can learn the state ;; to indent the next line. ;; This inner loop goes through only once ;; unless a line ends inside a string. (while (and (not inner-loop-done) (not (setq outer-loop-done (eobp)))) (setq state (parse-partial-sexp (point) (progn (end-of-line) (point)) nil nil state)) (setq next-depth (car state)) ;; If the line contains a comment other than the sort ;; that is indented like code, ;; indent it now with indent-for-comment. ;; Comments indented like code are right already. ;; In any case clear the in-comment flag in the state ;; because parse-partial-sexp never sees the newlines. (if (car (nthcdr 4 state)) (progn (indent-for-comment) (end-of-line) (setcar (nthcdr 4 state) nil))) ;; If this line ends inside a string, ;; go straight to next line, remaining within the inner loop, ;; and turn off the \-flag. (if (car (nthcdr 3 state)) (progn (forward-line 1) (setcar (nthcdr 5 state) nil)) (setq inner-loop-done t))) (and endpos (<= next-depth 0) (progn (setq indent-stack (append indent-stack (make-list (- next-depth) nil)) last-depth (- last-depth next-depth) next-depth 0))) (or outer-loop-done (setq outer-loop-done (<= next-depth 0))) (if outer-loop-done (forward-line 1) (while (> last-depth next-depth) (setq indent-stack (cdr indent-stack) last-depth (1- last-depth))) (while (< last-depth next-depth) (setq indent-stack (cons nil indent-stack) last-depth (1+ last-depth))) ;; Now go to the next line and indent it according ;; to what we learned from parsing the previous one. (forward-line 1) (setq bol (point)) (skip-chars-forward " \t") ;; But not if the line is blank, or just a comment ;; (except for double-semi comments; indent them as usual). (if (or (eobp) (looking-at "\\s<\\|\n")) nil (if (and (car indent-stack) (>= (car indent-stack) 0)) (setq this-indent (car indent-stack)) (let ((val (calculate-lisp-indent (if (car indent-stack) (- (car indent-stack)) starting-point)))) (if (integerp val) (setcar indent-stack (setq this-indent val)) (setcar indent-stack (- (car (cdr val)))) (setq this-indent (car val))))) (if (/= (current-column) this-indent) (progn (delete-region bol (point)) (indent-to this-indent))))) (or outer-loop-done (setq outer-loop-done (= (point) last-point)) (setq last-point (point))))))) ;; Indent every line whose first char is between START and END inclusive. (defun lisp-indent-region (start end) (save-excursion (goto-char start) (and (bolp) (not (eolp)) (lisp-indent-line)) (let ((endmark (copy-marker end))) (indent-sexp endmark) (set-marker endmark nil)))) ;;}}} ;;{{{ communication with a inferior process via comint ;;{{{ stk-start-process (defun stk-start-process (name program &optional startfile &rest switches) "Start a stk process named NAME, running PROGRAM." (or switches (setq switches stk-default-command-switches)) (setq stk-process-buffer (apply 'make-comint name program startfile switches)) (setq stk-process (get-buffer-process stk-process-buffer)) (save-excursion (set-buffer stk-process-buffer) (setq comint-prompt-regexp "^[^% ]*%\\( %\\)* *")) ) ;;}}} ;;{{{ stk-kill-process (defun stk-kill-process () "Kill stk subprocess and its buffer." (interactive) (if stk-process-buffer (kill-buffer stk-process-buffer))) ;;}}} ;;{{{ stk-set-stk-region-start (defun stk-set-stk-region-start (&optional arg) "Set start of region for use with `stk-send-stk-region'." (interactive) (set-marker stk-region-start (or arg (point)))) ;;}}} ;;{{{ stk-set-stk-region-end (defun stk-set-stk-region-end (&optional arg) "Set end of region for use with `stk-send-stk-region'." (interactive) (set-marker stk-region-end (or arg (point)))) ;;}}} ;;{{{ send line/region/buffer to stk-process ;;{{{ stk-send-current-line (defun stk-send-current-line () "Send current line to stk subprocess, found in `stk-process'. If `stk-process' is nil or dead, start a new process first." (interactive) (let ((start (save-excursion (beginning-of-line) (point))) (end (save-excursion (end-of-line) (point)))) (or (and stk-process (eq (process-status stk-process) 'run)) (stk-start-process stk-default-application stk-default-application)) (comint-simple-send stk-process (buffer-substring start end)) (forward-line 1) (if stk-always-show (display-buffer stk-process-buffer)))) ;;}}} ;;{{{ stk-send-region (defun stk-send-region (start end) "Send region to stk subprocess, wrapped in `eval { ... }'." (interactive "r") (or (and stk-process (comint-check-proc stk-process-buffer)) (stk-start-process stk-default-application stk-default-application)) (comint-simple-send stk-process (concat stk-default-eval " {\n"(buffer-substring start end) "\n}")) (if stk-always-show (display-buffer stk-process-buffer))) ;;}}} ;;{{{ stk-send-stk-region (defun stk-send-stk-region () "Send preset stk region to stk subprocess, wrapped in `eval { ... }'." (interactive) (or (and stk-region-start stk-region-end) (error "stk-region not set")) (or (and stk-process (comint-check-proc stk-process-buffer)) (stk-start-process stk-default-application stk-default-application)) (comint-simple-send stk-process (concat "(" stk-default-eval (buffer-substring stk-region-start stk-region-end) ")\n")) (if stk-always-show (display-buffer stk-process-buffer))) ;;}}} ;;{{{ stk-send-proc (defun stk-send-proc () "Send proc around point to stk subprocess, wrapped in `eval { ... }'." (interactive) (let (beg end) (save-excursion (stk-beginning-of-proc) (setq beg (point)) (stk-end-of-proc) (setq end (point))) (or (and stk-process (comint-check-proc stk-process-buffer)) (stk-start-process stk-default-application stk-default-application)) (comint-simple-send stk-process (concat "(" stk-default-eval (buffer-substring beg end) ")\n")) (if stk-always-show (display-buffer stk-process-buffer)))) ;;}}} ;;{{{ stk-send-buffer (defun stk-send-buffer () "Send whole buffer to stk subprocess, wrapped in `eval { ... }'." (interactive) (or (and stk-process (comint-check-proc stk-process-buffer)) (stk-start-process stk-default-application stk-default-application)) (if (buffer-modified-p) (comint-simple-send stk-process (concat "(" stk-default-eval (buffer-substring (point-min) (point-max)) ")\n")) (comint-simple-send stk-process (concat "load " (buffer-file-name) "\n"))) (if stk-always-show (display-buffer stk-process-buffer))) ;;}}} ;;}}} ;;{{{ stk-get-error-info (defun stk-get-error-info () "Send string `set errorInfo' to stk subprocess and display the stk buffer." (interactive) (or (and stk-process (comint-check-proc stk-process-buffer)) (stk-start-process stk-default-application stk-default-application)) (comint-simple-send stk-process "set errorInfo\n") (display-buffer stk-process-buffer)) ;;}}} ;;{{{ stk-restart-with-whole-file (defun stk-restart-with-whole-file () "Restart stk subprocess and send whole file as input." (interactive) (stk-kill-process) (stk-start-process stk-default-application stk-default-application) (stk-send-buffer)) ;;}}} ;;{{{ stk-show-process-buffer (defun stk-show-process-buffer () "Make sure `stk-process-buffer' is being displayed." (interactive) (display-buffer stk-process-buffer)) ;;}}} ;;{{{ stk-hide-process-buffer (defun stk-hide-process-buffer () "Delete all windows that display `stk-process-buffer'." (interactive) (delete-windows-on stk-process-buffer)) ;;}}} ;;}}} ;;{{{ menu bar (define-key stk-mode-menu [restart-with-whole-file] '("Restart With Whole File" . stk-restart-with-whole-file)) (define-key stk-mode-menu [kill-process] '("Kill Process" . stk-kill-process)) (define-key stk-mode-menu [hide-process-buffer] '("Hide Process Buffer" . stk-hide-process-buffer)) (define-key stk-mode-menu [get-error-info] '("Get Error Info" . stk-get-error-info)) (define-key stk-mode-menu [show-process-buffer] '("Show Process Buffer" . stk-show-process-buffer)) (define-key stk-mode-menu [send-stk-region] '("Send Stk-Region" . stk-send-stk-region)) (define-key stk-mode-menu [set-stk-regio-end] '("Set Stk-Region End" . stk-set-stk-region-end)) (define-key stk-mode-menu [set-stk-region-start] '("Set Stk-Region Start" . stk-set-stk-region-start)) (define-key stk-mode-menu [send-current-line] '("Send Current Line" . stk-send-current-line)) (define-key stk-mode-menu [send-region] '("Send Region" . stk-send-region)) (define-key stk-mode-menu [send-proc] '("Send Proc" . stk-send-proc)) (define-key stk-mode-menu [send-buffer] '("Send Buffer" . stk-send-buffer)) ;;}}} ;;{{{ Emacs local variables ;; Local Variables: ;; folded-file: t ;; End: ;;}}} ;;; stk-mode.el ends here