cinap_lenrekadd hg and python4bb9e2215 years agoHistory
3768 lines · 138.6 KB · Emacs Lisp
RawDownload
  (let (msg)    (cond     ((< 0 arg)      ;; set to CPython      (setq py-which-shell py-python-command	    py-which-args py-python-command-args	    py-which-bufname "Python"	    msg "CPython"	    mode-name "Python"))     ((> 0 arg)      (setq py-which-shell py-jpython-command	    py-which-args py-jpython-command-args	    py-which-bufname "JPython"	    msg "JPython"	    mode-name "JPython"))     )    (message "Using the %s shell" msg)    (setq py-output-buffer (format "*%s Output*" py-which-bufname)))) ;;;###autoload(defun py-shell (&optional argprompt)  "Start an interactive Python interpreter in another window.This is like Shell mode, except that Python is running in the windowinstead of a shell.  See the `Interactive Shell' and `Shell Mode'sections of the Emacs manual for details, especially for the keybindings active in the `*Python*' buffer. With optional \\[universal-argument], the user is prompted for theflags to pass to the Python interpreter.  This has no effect when thiscommand is used to switch to an existing process, only when a newprocess is started.  If you use this, you will probably want to ensurethat the current arguments are retained (they will be included in theprompt).  This argument is ignored when this function is calledprogrammatically, or when running in Emacs 19.34 or older. Note: You can toggle between using the CPython interpreter and theJPython interpreter by hitting \\[py-toggle-shells].  This togglesbuffer local variables which control whether all your subshellinteractions happen to the `*JPython*' or `*Python*' buffers (thelatter is the name used for the CPython buffer). Warning: Don't use an interactive Python if you change sys.ps1 orsys.ps2 from their default values, or if you're running code thatprints `>>> ' or `... ' at the start of a line.  `python-mode' can'tdistinguish your output from Python's output, and assumes that `>>> 'at the start of a line is a prompt from Python.  Similarly, the EmacsShell mode code assumes that both `>>> ' and `... ' at the start of aline are Python prompts.  Bad things can happen if you fool eithermode. Warning:  If you do any editing *in* the process buffer *while* thebuffer is accepting output from Python, do NOT attempt to `undo' thechanges.  Some of the output (nowhere near the parts you changed!) maybe lost if you do.  This appears to be an Emacs bug, an unfortunateinteraction between undo and process filters; the same problem exists innon-Python process buffers using the default (Emacs-supplied) processfilter."  (interactive "P")  ;; Set the default shell if not already set  (when (null py-which-shell)    (py-toggle-shells py-default-interpreter))  (let ((args py-which-args))    (when (and argprompt	       (interactive-p)	       (fboundp 'split-string))      ;; TBD: Perhaps force "-i" in the final list?      (setq args (split-string		  (read-string (concat py-which-bufname				       " arguments: ")			       (concat				(mapconcat 'identity py-which-args " ") " ")			       ))))    (switch-to-buffer-other-window     (apply 'make-comint py-which-bufname py-which-shell nil args))    (make-local-variable 'comint-prompt-regexp)    (setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ")    (add-hook 'comint-output-filter-functions	      'py-comint-output-filter-function)    ;; pdbtrack    (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)    (setq py-pdbtrack-do-tracking-p t)    (set-syntax-table py-mode-syntax-table)    (use-local-map py-shell-map)    (run-hooks 'py-shell-hook)    )) (defun py-clear-queue ()  "Clear the queue of temporary files waiting to execute."  (interactive)  (let ((n (length py-file-queue)))    (mapcar 'delete-file py-file-queue)    (setq py-file-queue nil)    (message "%d pending files de-queued." n))) (defun py-execute-region (start end &optional async)  "Execute the region in a Python interpreter. The region is first copied into a temporary file (in the directory`py-temp-directory').  If there is no Python interpreter shellrunning, this file is executed synchronously using`shell-command-on-region'.  If the program is long running, use\\[universal-argument] to run the command asynchronously in its ownbuffer. When this function is used programmatically, arguments START and ENDspecify the region to execute, and optional third argument ASYNC, ifnon-nil, specifies to run the command asynchronously in its ownbuffer. If the Python interpreter shell is running, the region is execfile()'din that shell.  If you try to execute regions too quickly,`python-mode' will queue them up and execute them one at a time whenit sees a `>>> ' prompt from Python.  Each time this happens, theprocess buffer is popped into a window (if it's not already in somewindow) so you can see it, and a comment of the form     \t## working on region in file <name>... is inserted at the end.  See also the command `py-clear-queue'."  (interactive "r\nP")  ;; Skip ahead to the first non-blank line  (let* ((proc (get-process py-which-bufname))	 (temp (if (memq 'broken-temp-names py-emacs-features)		   (let		       ((sn py-serial-number)			(pid (and (fboundp 'emacs-pid) (emacs-pid))))		     (setq py-serial-number (1+ py-serial-number))		     (if pid			 (format "python-%d-%d" sn pid)		       (format "python-%d" sn)))		 (make-temp-name "python-")))	 (file (concat (expand-file-name temp py-temp-directory) ".py"))	 (cur (current-buffer))	 (buf (get-buffer-create file))	 shell)    ;; Write the contents of the buffer, watching out for indented regions.    (save-excursion      (goto-char start)      (beginning-of-line)      (while (and (looking-at "\\s *$")		  (< (point) end))	(forward-line 1))      (setq start (point))      (or (< start end)	  (error "Region is empty"))      (let ((needs-if (/= (py-point 'bol) (py-point 'boi))))	(set-buffer buf)	(python-mode)	(when needs-if	  (insert "if 1:\n"))	(insert-buffer-substring cur start end)	;; Set the shell either to the #! line command, or to the	;; py-which-shell buffer local variable.	(setq shell (or (py-choose-shell-by-shebang)			(py-choose-shell-by-import)			py-which-shell))))    (cond     ;; always run the code in its own asynchronous subprocess     (async      ;; User explicitly wants this to run in its own async subprocess      (save-excursion	(set-buffer buf)	(write-region (point-min) (point-max) file nil 'nomsg))      (let* ((buf (generate-new-buffer-name py-output-buffer))	     ;; TBD: a horrible hack, but why create new Custom variables?	     (arg (if (string-equal py-which-bufname "Python")		      "-u" "")))	(start-process py-which-bufname buf shell arg file)	(pop-to-buffer buf)	(py-postprocess-output-buffer buf)	;; TBD: clean up the temporary file!	))     ;; if the Python interpreter shell is running, queue it up for     ;; execution there.     (proc      ;; use the existing python shell      (save-excursion	(set-buffer buf)	(write-region (point-min) (point-max) file nil 'nomsg))      (if (not py-file-queue)	  (py-execute-file proc file)	(message "File %s queued for execution" file))      (setq py-file-queue (append py-file-queue (list file)))      (setq py-exception-buffer (cons file (current-buffer))))     (t      ;; TBD: a horrible hack, but why create new Custom variables?      (let ((cmd (concat shell (if (string-equal py-which-bufname "JPython")				   " -" ""))))	;; otherwise either run it synchronously in a subprocess	(save-excursion	  (set-buffer buf)	  (shell-command-on-region (point-min) (point-max)				   cmd py-output-buffer))	;; shell-command-on-region kills the output buffer if it never	;; existed and there's no output from the command	(if (not (get-buffer py-output-buffer))	    (message "No output.")	  (setq py-exception-buffer (current-buffer))	  (let ((err-p (py-postprocess-output-buffer py-output-buffer)))	    (pop-to-buffer py-output-buffer)	    (if err-p		(pop-to-buffer py-exception-buffer)))	  ))      ))    ;; Clean up after ourselves.    (kill-buffer buf))) ;; Code execution commands(defun py-execute-buffer (&optional async)  "Send the contents of the buffer to a Python interpreter.If the file local variable `py-master-file' is non-nil, execute thenamed file instead of the buffer's file. If there is a *Python* process buffer it is used.  If a clippingrestriction is in effect, only the accessible portion of the buffer issent.  A trailing newline will be supplied if needed. See the `\\[py-execute-region]' docs for an account of somesubtleties, including the use of the optional ASYNC argument."  (interactive "P")  (if py-master-file      (let* ((filename (expand-file-name py-master-file))	     (buffer (or (get-file-buffer filename)			 (find-file-noselect filename))))	(set-buffer buffer)))  (py-execute-region (point-min) (point-max) async)) (defun py-execute-import-or-reload (&optional async)  "Import the current buffer's file in a Python interpreter. If the file has already been imported, then do reload instead to getthe latest version. If the file's name does not end in \".py\", then do execfile instead. If the current buffer is not visiting a file, do `py-execute-buffer'instead. If the file local variable `py-master-file' is non-nil, import orreload the named file instead of the buffer's file.  The file may besaved based on the value of `py-execute-import-or-reload-save-p'. See the `\\[py-execute-region]' docs for an account of somesubtleties, including the use of the optional ASYNC argument. This may be preferable to `\\[py-execute-buffer]' because:  - Definitions stay in their module rather than appearing at top   level, where they would clutter the global namespace and not affect   uses of qualified names (MODULE.NAME).  - The Python debugger gets line number information about the functions."  (interactive "P")  ;; Check file local variable py-master-file  (if py-master-file      (let* ((filename (expand-file-name py-master-file))             (buffer (or (get-file-buffer filename)                         (find-file-noselect filename))))        (set-buffer buffer)))  (let ((file (buffer-file-name (current-buffer))))    (if file        (progn	  ;; Maybe save some buffers	  (save-some-buffers (not py-ask-about-save) nil)          (py-execute-string           (if (string-match "\\.py$" file)               (let ((f (file-name-sans-extension			 (file-name-nondirectory file))))                 (format "if globals().has_key('%s'):\n    reload(%s)\nelse:\n    import %s\n"                         f f f))             (format "execfile(r'%s')\n" file))           async))      ;; else      (py-execute-buffer async))))  (defun py-execute-def-or-class (&optional async)  "Send the current function or class definition to a Python interpreter. If there is a *Python* process buffer it is used. See the `\\[py-execute-region]' docs for an account of somesubtleties, including the use of the optional ASYNC argument."  (interactive "P")  (save-excursion    (py-mark-def-or-class)    ;; mark is before point    (py-execute-region (mark) (point) async)))  (defun py-execute-string (string &optional async)  "Send the argument STRING to a Python interpreter. If there is a *Python* process buffer it is used. See the `\\[py-execute-region]' docs for an account of somesubtleties, including the use of the optional ASYNC argument."  (interactive "sExecute Python command: ")  (save-excursion    (set-buffer (get-buffer-create                 (generate-new-buffer-name " *Python Command*")))    (insert string)    (py-execute-region (point-min) (point-max) async)))  (defun py-jump-to-exception (file line)  "Jump to the Python code in FILE at LINE."  (let ((buffer (cond ((string-equal file "<stdin>")		       (if (consp py-exception-buffer)			   (cdr py-exception-buffer)			 py-exception-buffer))		      ((and (consp py-exception-buffer)			    (string-equal file (car py-exception-buffer)))		       (cdr py-exception-buffer))		      ((py-safe (find-file-noselect file)))		      ;; could not figure out what file the exception		      ;; is pointing to, so prompt for it		      (t (find-file (read-file-name "Exception file: "						    nil						    file t))))))    (pop-to-buffer buffer)    ;; Force Python mode    (if (not (eq major-mode 'python-mode))	(python-mode))    (goto-line line)    (message "Jumping to exception in file %s on line %d" file line))) (defun py-mouseto-exception (event)  "Jump to the code which caused the Python exception at EVENT.EVENT is usually a mouse click."  (interactive "e")  (cond   ((fboundp 'event-point)    ;; XEmacs    (let* ((point (event-point event))	   (buffer (event-buffer event))	   (e (and point buffer (extent-at point buffer 'py-exc-info)))	   (info (and e (extent-property e 'py-exc-info))))      (message "Event point: %d, info: %s" point info)      (and info	   (py-jump-to-exception (car info) (cdr info)))      ))   ;; Emacs -- Please port this!   )) (defun py-goto-exception ()  "Go to the line indicated by the traceback."  (interactive)  (let (file line)    (save-excursion      (beginning-of-line)      (if (looking-at py-traceback-line-re)	  (setq file (match-string 1)		line (string-to-int (match-string 2)))))    (if (not file)	(error "Not on a traceback line"))    (py-jump-to-exception file line))) (defun py-find-next-exception (start buffer searchdir errwhere)  "Find the next Python exception and jump to the code that caused it.START is the buffer position in BUFFER from which to begin searchingfor an exception.  SEARCHDIR is a function, either`re-search-backward' or `re-search-forward' indicating the directionto search.  ERRWHERE is used in an error message if the limit (top orbottom) of the trackback stack is encountered."  (let (file line)    (save-excursion      (set-buffer buffer)      (goto-char (py-point start))      (if (funcall searchdir py-traceback-line-re nil t)	  (setq file (match-string 1)		line (string-to-int (match-string 2)))))    (if (and file line)	(py-jump-to-exception file line)      (error "%s of traceback" errwhere)))) (defun py-down-exception (&optional bottom)  "Go to the next line down in the traceback.With \\[univeral-argument] (programmatically, optional argumentBOTTOM), jump to the bottom (innermost) exception in the exceptionstack."  (interactive "P")  (let* ((proc (get-process "Python"))	 (buffer (if proc "*Python*" py-output-buffer)))    (if bottom	(py-find-next-exception 'eob buffer 're-search-backward "Bottom")      (py-find-next-exception 'eol buffer 're-search-forward "Bottom")))) (defun py-up-exception (&optional top)  "Go to the previous line up in the traceback.With \\[universal-argument] (programmatically, optional argument TOP)jump to the top (outermost) exception in the exception stack."  (interactive "P")  (let* ((proc (get-process "Python"))	 (buffer (if proc "*Python*" py-output-buffer)))    (if top	(py-find-next-exception 'bob buffer 're-search-forward "Top")      (py-find-next-exception 'bol buffer 're-search-backward "Top")))) ;; Electric deletion(defun py-electric-backspace (arg)  "Delete preceding character or levels of indentation.Deletion is performed by calling the function in `py-backspace-function'with a single argument (the number of characters to delete). If point is at the leftmost column, delete the preceding newline. Otherwise, if point is at the leftmost non-whitespace character of aline that is neither a continuation line nor a non-indenting commentline, or if point is at the end of a blank line, this command reducesthe indentation to match that of the line that opened the currentblock of code.  The line that opened the block is displayed in theecho area to help you keep track of where you are.  With\\[universal-argument] dedents that many blocks (but not past columnzero). Otherwise the preceding character is deleted, converting a tab tospaces if needed so that only a single column position is deleted.\\[universal-argument] specifies how many characters to delete;default is 1. When used programmatically, argument ARG specifies the number ofblocks to dedent, or the number of characters to delete, as indicatedabove."  (interactive "*p")  (if (or (/= (current-indentation) (current-column))	  (bolp)	  (py-continuation-line-p);	  (not py-honor-comment-indentation);	  (looking-at "#[^ \t\n]")	; non-indenting #	  )      (funcall py-backspace-function arg)    ;; else indent the same as the colon line that opened the block    ;; force non-blank so py-goto-block-up doesn't ignore it    (insert-char ?* 1)    (backward-char)    (let ((base-indent 0)		; indentation of base line	  (base-text "")		; and text of base line	  (base-found-p nil))      (save-excursion	(while (< 0 arg)	  (condition-case nil		; in case no enclosing block	      (progn		(py-goto-block-up 'no-mark)		(setq base-indent (current-indentation)		      base-text   (py-suck-up-leading-text)		      base-found-p t))	    (error nil))	  (setq arg (1- arg))))      (delete-char 1)			; toss the dummy character      (delete-horizontal-space)      (indent-to base-indent)      (if base-found-p	  (message "Closes block: %s" base-text)))))  (defun py-electric-delete (arg)  "Delete preceding or following character or levels of whitespace. The behavior of this function depends on the variable`delete-key-deletes-forward'.  If this variable is nil (or does notexist, as in older Emacsen and non-XEmacs versions), then thisfunction behaves identically to \\[c-electric-backspace]. If `delete-key-deletes-forward' is non-nil and is supported in yourEmacs, then deletion occurs in the forward direction, by calling thefunction in `py-delete-function'. \\[universal-argument] (programmatically, argument ARG) specifies thenumber of characters to delete (default is 1)."  (interactive "*p")  (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21	       (delete-forward-p))	  (and (boundp 'delete-key-deletes-forward) ;XEmacs 20	       delete-key-deletes-forward))      (funcall py-delete-function arg)    (py-electric-backspace arg))) ;; required for pending-del and delsel modes(put 'py-electric-colon 'delete-selection t) ;delsel(put 'py-electric-colon 'pending-delete   t) ;pending-del(put 'py-electric-backspace 'delete-selection 'supersede) ;delsel(put 'py-electric-backspace 'pending-delete   'supersede) ;pending-del(put 'py-electric-delete    'delete-selection 'supersede) ;delsel(put 'py-electric-delete    'pending-delete   'supersede) ;pending-del  (defun py-indent-line (&optional arg)  "Fix the indentation of the current line according to Python rules.With \\[universal-argument] (programmatically, the optional argumentARG non-nil), ignore dedenting rules for block closing statements(e.g. return, raise, break, continue, pass) This function is normally bound to `indent-line-function' so\\[indent-for-tab-command] will call it."

Lines 1501–2000 of 3768. Previous lines