Index: editor/parrot.el =================================================================== --- editor/parrot.el (revision 16136) +++ editor/parrot.el (working copy) @@ -22,3 +22,56 @@ (statement-case-intro . *) (inextern-lang . 0) )))) + +;; All *.pmc and *.ops files are really C (or close enough). +(let ((tail '("\\.pmc$" "\\.ops$"))) + (while tail + (or (assoc (car tail) auto-mode-alist) + (setq auto-mode-alist + (cons (cons (car tail) 'c-mode) auto-mode-alist))) + (setq tail (cdr tail)))) + +(defun parrot-hack-perl-local-variables () + "Redo hack-local-variables if it was fooled by __END__ or __DATA__. +The coda containing 'Local Variables:' should appear just before the first +of these, but Emacs won't see it if there are more than 3000 characters +after the __END__ or __DATA__. This is designed to be installed as a +mode hook; when the hook runs, we know we're in a Perl buffer and can +repeat the search for the coda in the Perl-appropriate place. + +Important: Do not call this from another mode hook function. If it is +not directly on the perl-mode-hook or cperl-mode-hook list, it won't be +able to disable itself, and you'll get an unbounded recursion. + +We try hard not to call hack-local-variables if it's not needed. But if +it is, and 'Local Variables:' contains a 'Mode:' line, then the mode +function will be called again, and mode hooks will be rerun." + (interactive) + (save-excursion + ;; The hack-local-variables code makes a point of only looking backwards + ;; from point-max in case the buffer is huge. We need to search from the + ;; start, to find the first of __END__ or __DATA__, and can assume that the + ;; buffer is of reasonable size. + (goto-char (point-min)) + (if (re-search-forward "^__\\(END\\|DATA\\)__$" nil t) + (let* ((end (point)) + ;; this is based on the hack-local-variables logic. + (start (max (- end 3000) (point-min)))) + (search-backward "\n\^L" start 'move) + (if (let ((case-fold-search t)) + (search-forward "Local Variables:" end t)) + (let ((cperl-mode-hook + (remove 'parrot-hack-perl-local-variables cperl-mode-hook)) + (perl-mode-hook + (remove 'parrot-hack-perl-local-variables perl-mode-hook))) + ;; Important: We can't rerun hack-local-variables without + ;; rebinding mode hooks, since hack-local-variables may + ;; re-establish the mode, which will run the hooks again. + (save-restriction + (narrow-to-region start end) + (hack-local-variables)))))))) + +(add-hook 'cperl-mode-hook 'parrot-hack-perl-local-variables) +;; We also need one on perl mode, because the coda contains the Mode: spec, so +;; we'll be in perl-mode to start off. +(add-hook 'perl-mode-hook 'parrot-hack-perl-local-variables)