From: Kevin B. <kb...@ca...> - 2002-01-24 15:26:04
|
OK, this got me thinking _way_ too much about this. Here is a modification to python-mode.el (v. 4.6) that auto-detects the interpreter based on: - #! line (a la 'get-auto-mode') - import of java/javax/org/com packages (these imply jpython) - default to cpython (not py-default-interpreter, because the imports test can only detect jpython) It works really well for me. Anyway, here's the patch. Anyone willing to try this and give feedback? After hearing from you I'll submit it to the sourceforge project... I also put the modified python-mode.el file up on: http://www.xmission.com/~butler/python-mode.el kb diff -c python-mode.el python-mode.el.4.6 *** python-mode.el Wed Jan 23 17:31:31 2002 --- python-mode.el.4.6 Wed Jan 23 17:31:28 2002 *************** *** 275,293 **** :type 'string :group 'python) - (defcustom py-choose-bound - 20000 - "Max characters to search in trying to choode `python-mode'." - :type 'integer - :group 'python - ) - - (defcustom py-jpython-packages - '("java" "javax" "org" "com") - "Imported packages that imply `jpython-mode'." - :type '(repeat string) - :group 'python) - ;; Not customizable (defvar py-master-file nil "If non-nil, execute the named file instead of the buffer's file. --- 275,280 ---- *************** *** 304,315 **** buffer is prepended to come up with a file name.") (make-variable-buffer-local 'py-master-file) - (defvar py-shell-alist - '(("jpython" . 'jpython) - ("jython" . 'jpython) - ("python" . 'cpython)) - "*Alist of interpreters and python shells. Used by `py-choose-shell' - to select the appropriate python interpreter mode for a file.") ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- 291,296 ---- *************** *** 466,480 **** (defvar python-mode-hook nil "*Hook called by `python-mode'.") ;; In previous version of python-mode.el, the hook was incorrectly ;; called py-mode-hook, and was not defvar'd. Deprecate its use. (and (fboundp 'make-obsolete-variable) (make-obsolete-variable 'py-mode-hook 'python-mode-hook)) - (defvar jpython-mode-hook nil - "*Hook called by `jpython-mode'. `jpython-mode' also calls - `python-mode-hook'.") - (defvar py-mode-map () "Keymap used in `python-mode' buffers.") (if py-mode-map --- 447,458 ---- (defvar python-mode-hook nil "*Hook called by `python-mode'.") + ;; In previous version of python-mode.el, the hook was incorrectly ;; called py-mode-hook, and was not defvar'd. Deprecate its use. (and (fboundp 'make-obsolete-variable) (make-obsolete-variable 'py-mode-hook 'python-mode-hook)) (defvar py-mode-map () "Keymap used in `python-mode' buffers.") (if py-mode-map *************** *** 936,1012 **** (point-max) 'move)))) (nreverse index-alist))) - ;; let emacs auto-detect the j/python interpreter based on the #!... line - (setq interpreter-mode-alist - (append interpreter-mode-alist '(("jpython" . jpython-mode) - ("jython" . jpython-mode) - ("python" . python-mode)))) - - - - (defun jpython-mode () - "Major mode for editing JPython/Jython files. - This is a simple wrapper around `python-mode'. - It runs `jpython-mode-hook' then calls `python-mode.' - It is added to `interpreter-mode-alist' and `py-choose-shell'. - " - (interactive) - (py-toggle-shells 'jpython) - (when jpython-mode-hook - (run-hooks 'jpython-mode-hook)) - (python-mode) - ) - - - (defun py-choose-shell-by-shebang () - "Choose CPython or JPython mode by looking at #! on the first line. - Returns the appropriate mode function. - Used by `py-choose-shell', and similar to but distinct from - `set-auto-mode', though it uses `auto-mode-interpreter-regexp'." - ;; look for an interpreter specified in the first line - ;; similar to set-auto-mode (files.el) - (let ((interpreter - (save-excursion - (goto-char (point-min)) - (if (looking-at auto-mode-interpreter-regexp) - (match-string 2) - "")))) - ;; Map interpreter name to a mode. - (setq elt (assoc (file-name-nondirectory interpreter) - py-shell-alist)) - (if elt (caddr elt)))) - - - (defun py-choose-shell-by-import () - "Choose CPython or JPython mode based imports. - If a file imports any packages in `py-jpython-packages', return - 'jpython, otherwise return nil." - (let ((mode nil)) - (save-excursion - (goto-char (point-min)) - (while (and (not mode) - (search-forward-regexp - "^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)" - py-choose-bound t)) - (setq mode (and (member (match-string 4) py-jpython-packages) - 'jpython - )))) - mode)) - - - (defun py-choose-shell () - "Choose CPython or JPython mode. Returns the appropriate mode function. - This does the following: - - look for an interpreter with `py-choose-shell-by-shebang' - - examine imports using `py-choose-shell-by-import' - - default to py-default-interpreter" - (interactive) - (or (py-choose-shell-by-shebang) - (py-choose-shell-by-import) - 'cpython ;; don't use to py-default-interpreter, because default - ;; is only way to choose CPython - )) - ;;;###autoload (defun python-mode () --- 914,919 ---- *************** *** 1097,1103 **** )) ;; Set the default shell if not already set (when (null py-which-shell) ! (py-toggle-shells (py-choose-shell))) ) --- 1004,1010 ---- )) ;; Set the default shell if not already set (when (null py-which-shell) ! (py-toggle-shells py-default-interpreter)) ) Jon K Hellan wrote: > > Syver Enstad <syv...@on...> writes: > > > For another solution, (what I do): > > put the following in the first line of a jython script: > > ## -*- mode: python; eval: (py-toggle-shells 'jpython); -*-1 > > > > Since I run Cpython mostly but do a fair bit of hacking with jython > > at the time being. > > Here's what I do: > > (add-hook > 'python-mode-hook > (lambda () > (let ((using-jython > (save-excursion > (goto-char (point-min)) > (looking-at "#!.*\\(java\\|jp?ython\\)")))) > (py-toggle-shells (if using-jython 'jpython 'cpython))))) > > This looks at the #! line at the top of the script and selects the > appropriate interpreter. I like that. I'd probably extend it so it recognizes imports of java-specific packages, too: (add-hook 'python-mode-hook (lambda () (let ((using-jython (save-excursion (goto-char (point-min)) (or (looking-at "#!.*\\(java\\|jp?ython\\)") (looking-at "import java"))))) (py-toggle-shells (if using-jython 'jpython 'cpython))))) |