I use the AMPL emacs mode from here. It is quite good, but I did make a few customizations. Specifically, I wanted the standard Emacs comment binding M-; to work for AMPL comments, so I added the following lines to my ampl-mode.el file:
(defun ampl-comment-dwim () "Comment or uncomment the current line or text selection." (interactive) ;; If there's no text selection, comment or uncomment the line ;; depending whether the WHOLE line is a comment. If there is a text ;; selection, using the first line to determine whether to ;; comment/uncomment. (let (p1 p2) (if (region-active-p) (save-excursion (setq p1 (region-beginning) p2 (region-end)) (goto-char p1) (if (wholeLineIsCmt-p) (ampl-uncomment-region p1 p2) (ampl-comment-region p1 p2) )) (progn (if (wholeLineIsCmt-p) (ampl-uncomment-current-line) (ampl-comment-current-line) )) ))) (defun wholeLineIsCmt-p () (save-excursion (beginning-of-line 1) (looking-at "[ t]*#") )) (defun ampl-comment-current-line () (interactive) (beginning-of-line 1) (insert "# ") ) (defun ampl-uncomment-current-line () "Remove “#” (if any) in the beginning of current line." (interactive) (when (wholeLineIsCmt-p) (beginning-of-line 1) (search-forward "# ") (delete-backward-char 2) )) (defun ampl-comment-region (p1 p2) "Add “# ” to the beginning of each line of selected text." (interactive "r") (let ((deactivate-mark nil)) (save-excursion (goto-char p2) (while (>= (point) p1) (ampl-comment-current-line) (previous-line) )))) (defun ampl-uncomment-region (p1 p2) "Remove “# ” (if any) in the beginning of each line of selected text." (interactive "r") (let ((deactivate-mark nil)) (save-excursion (goto-char p2) (while (>= (point) p1) (ampl-uncomment-current-line) (previous-line) )) )) ;; USE FOLLOWING IF YOU WANT REGULAR COMMENT-DWIM BEHAVIOR INSTEAD ;; ;; the command to comment/uncomment text ;; (defun ampl-comment-dwim (arg) ;; "Comment or uncomment current line or region in a smart way. ;; For detail, see `comment-dwim'." ;; (interactive "*P") ;; (require 'newcomment) ;; (let ((deactivate-mark nil) (comment-start "#") (comment-end "")) ;; (comment-dwim arg))) ;; modify the keymap (define-key ampl-mode-map [remap comment-dwim] 'ampl-comment-dwim) I found the template for this code here. Additionally, in my.emacsinit file, I added the following lines:(setq auto-mode-alist (cons '("\.mod$" . ampl-mode) auto-mode-alist)) (setq auto-mode-alist (cons '("\.dat$" . ampl-mode) auto-mode-alist)) (setq auto-mode-alist (cons '("\.run$" . ampl-mode) auto-mode-alist)) (setq auto-mode-alist (cons '("\.ampl$" . ampl-mode) auto-mode-alist)) (setq interpreter-mode-alist (cons '("ampl" . ampl-mode) interpreter-mode-alist)) (load "ampl-mode") ;; Enable syntax coloring (add-hook 'ampl-mode-hook 'turn-on-font-lock) ;; If you find parenthesis matching a nuisance, turn it off by ;; removing the leading semi-colons on the following lines: (setq ampl-auto-close-parenthesis nil) (setq ampl-auto-close-brackets nil) (setq ampl-auto-close-curlies nil) (setq ampl-auto-close-double-quote nil) (setq ampl-auto-close-single-quote nil)These lines are provided by the AMPL mode file itself, but I made a few changes, uncommenting the last block of lines (as I find autocomplete parentheses, etc. annoying) and adding the lines
(setq auto-mode-alist (cons '("\.run$" . ampl-mode) auto-mode-alist))so that emacs would recognize
.runfiles as AMPL scripts.