Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
b9a5ed5a
Commit
b9a5ed5a
authored
Feb 05, 2008
by
Skip Montanaro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sync with most recent version from python-mode sf project
parent
10e9b726
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
353 additions
and
215 deletions
+353
-215
Misc/python-mode.el
Misc/python-mode.el
+353
-215
No files found.
Misc/python-mode.el
View file @
b9a5ed5a
...
...
@@ -2,7 +2,8 @@
;; Copyright (C) 1992,1993,1994 Tim Peters
;; Author: 1995-2002 Barry A. Warsaw
;; Author: 2003-2007 http://sf.net/projects/python-mode
;; 1995-2002 Barry A. Warsaw
;; 1992-1994 Tim Peters
;; Maintainer: python-mode@python.org
;; Created: Feb 1992
...
...
@@ -19,19 +20,38 @@
;;; Commentary:
;; This is a major mode for editing Python programs. It was developed
;; by Tim Peters after an original idea by Michael A. Guravage. Tim
;; subsequently left the net; in 1995, Barry Warsaw inherited the mode
;; and is the current maintainer. Tim's now back but disavows all
;; responsibility for the mode. Smart Tim :-)
;; This is a major mode for editing Python programs. It was developed by Tim
;; Peters after an original idea by Michael A. Guravage. Tim subsequently
;; left the net and in 1995, Barry Warsaw inherited the mode. Tim's now back
;; but disavows all responsibility for the mode. In fact, we suspect he
;; doesn't even use Emacs any more. In 2003, python-mode.el was moved to its
;; own SourceForge project apart from the Python project, and now is
;; maintained by the volunteers at the python-mode@python.org mailing list.
;; pdbtrack support contributed by Ken Manheimer, April 2001.
;; pdbtrack support contributed by Ken Manheimer, April 2001. Skip Montanaro
;; has also contributed significantly to python-mode's development.
;; Please use the SourceForge Python project to submit bugs or
;; patches:
;;
;; http://sourceforge.net/projects/python
;; INSTALLATION:
;; To install, just drop this file into a directory on your load-path and
;; byte-compile it. To set up Emacs to automatically edit files ending in
;; ".py" using python-mode add the following to your ~/.emacs file (GNU
;; Emacs) or ~/.xemacs/init.el file (XEmacs):
;; (setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
;; (setq interpreter-mode-alist (cons '("python" . python-mode)
;; interpreter-mode-alist))
;; (autoload 'python-mode "python-mode" "Python editing mode." t)
;;
;; In XEmacs syntax highlighting should be enabled automatically. In GNU
;; Emacs you may have to add these lines to your ~/.emacs file:
;; (global-font-lock-mode t)
;; (setq font-lock-maximum-decoration t)
;; FOR MORE INFORMATION:
;; There is some information on python-mode.el at
...
...
@@ -60,6 +80,7 @@
(
require
'custom
)
(
require
'cl
)
(
require
'compile
)
(
require
'ansi-color
)
;; user definable variables
...
...
@@ -70,34 +91,41 @@
:group
'languages
:prefix
"py-"
)
(
defcustom
py-tab-always-indent
t
"*Non-nil means TAB in Python mode should always reindent the current line,
regardless of where in the line point is when the TAB command is used."
:type
'boolean
:group
'python
)
(
defcustom
py-python-command
"python"
"*Shell command used to start Python interpreter."
:type
'string
:group
'python
)
(
defcustom
py-jpython-command
"jpython"
"*Shell command used to start the JPython interpreter."
(
make-obsolete-variable
'py-jpython-command
'py-jython-command
)
(
defcustom
py-jython-command
"jython"
"*Shell command used to start the Jython interpreter."
:type
'string
:group
'python
:tag
"J
P
ython Command"
)
:tag
"Jython Command"
)
(
defcustom
py-default-interpreter
'cpython
"*Which Python interpreter is used by default.
The value for this variable can be either `cpython' or `j
p
ython'.
The value for this variable can be either `cpython' or `jython'.
When the value is `cpython', the variables `py-python-command' and
`py-python-command-args' are consulted to determine the interpreter
and arguments to use.
When the value is `j
python', the variables `py-jp
ython-command' and
`py-j
p
ython-command-args' are consulted to determine the interpreter
When the value is `j
ython', the variables `py-j
ython-command' and
`py-jython-command-args' are consulted to determine the interpreter
and arguments to use.
Note that this variable is consulted only the first time that a Python
mode buffer is visited during an Emacs session. After that, use
\\[py-toggle-shells] to change the interpreter shell."
:type
'
(
choice
(
const
:tag
"Python (a.k.a. CPython)"
cpython
)
(
const
:tag
"J
Python"
jp
ython
))
(
const
:tag
"J
ython"
j
ython
))
:group
'python
)
(
defcustom
py-python-command-args
'
(
"-i"
)
...
...
@@ -105,11 +133,12 @@ mode buffer is visited during an Emacs session. After that, use
:type
'
(
repeat
string
)
:group
'python
)
(
defcustom
py-jpython-command-args
'
(
"-i"
)
"*List of string arguments to be used when starting a JPython shell."
(
make-obsolete-variable
'py-jpython-command-args
'py-jython-command-args
)
(
defcustom
py-jython-command-args
'
(
"-i"
)
"*List of string arguments to be used when starting a Jython shell."
:type
'
(
repeat
string
)
:group
'python
:tag
"J
P
ython Command Args"
)
:tag
"Jython Command Args"
)
(
defcustom
py-indent-offset
4
"*Amount of offset per level of indentation.
...
...
@@ -248,7 +277,7 @@ Otherwise, all modified buffers are saved without asking."
:type
'function
:group
'python
)
(
defcustom
py-imenu-show-method-args-p
nil
(
defcustom
py-imenu-show-method-args-p
nil
"*Controls echoing of arguments of functions & methods in the Imenu buffer.
When non-nil, arguments are printed."
:type
'boolean
...
...
@@ -275,19 +304,20 @@ as gud-mode does for debugging C programs with gdb."
20000
"Maximum number of characters to search for a Java-ish import statement.
When `python-mode' tries to calculate the shell to use (either a
CPython or a J
P
ython shell), it looks at the so-called `shebang' line
CPython or a Jython shell), it looks at the so-called `shebang' line
-- i.e. #! line. If that's not available, it looks at some of the
file heading imports to see if they look Java-like."
:type
'integer
:group
'python
)
(
defcustom
py-jpython-packages
(
make-obsolete-variable
'py-jpython-packages
'py-jython-packages
)
(
defcustom
py-jython-packages
'
(
"java"
"javax"
"org"
"com"
)
"Imported packages that imply `j
p
ython-mode'."
"Imported packages that imply `jython-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.
...
...
@@ -317,16 +347,39 @@ buffer is prepended to come up with a file name.")
:tag
"Pychecker Command Args"
)
(
defvar
py-shell-alist
'
((
"jpython"
.
'jpython
)
(
"jython"
.
'jpython
)
'
((
"jython"
.
'jython
)
(
"python"
.
'cpython
))
"*Alist of interpreters and python shells. Used by `py-choose-shell'
to select the appropriate python interpreter mode for a file."
)
(
defcustom
py-shell-input-prompt-1-regexp
"^>>> "
"*A regular expression to match the input prompt of the shell."
:type
'string
:group
'python
)
(
defcustom
py-shell-input-prompt-2-regexp
"^[.][.][.] "
"*A regular expression to match the input prompt of the shell after the
first line of input."
:type
'string
:group
'python
)
(
defcustom
py-shell-switch-buffers-on-execute
t
"*Controls switching to the Python buffer where commands are
executed. When non-nil the buffer switches to the Python buffer, if
not no switching occurs."
:type
'boolean
:group
'python
)
;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
(
defvar
py-line-number-offset
0
"When an exception occurs as a result of py-execute-region, a
subsequent py-up-exception needs the line number where the region
started, in order to jump to the correct file line. This variable is
set in py-execute-region and used in py-jump-to-exception."
)
(
defconst
py-emacs-features
(
let
(
features
)
features
)
...
...
@@ -339,9 +392,31 @@ support for features needed by `python-mode'.")
"Face for pseudo keywords in Python mode, like self, True, False, Ellipsis."
)
(
make-face
'py-pseudo-keyword-face
)
;; PEP 318 decorators
(
defvar
py-decorators-face
'py-decorators-face
"Face method decorators."
)
(
make-face
'py-decorators-face
)
;; Face for builtins
(
defvar
py-builtins-face
'py-builtins-face
"Face for builtins like TypeError, object, open, and exec."
)
(
make-face
'py-builtins-face
)
;; XXX, TODO, and FIXME comments and such
(
defvar
py-XXX-tag-face
'py-XXX-tag-face
"Face for XXX, TODO, and FIXME tags"
)
(
make-face
'py-XXX-tag-face
)
(
defun
py-font-lock-mode-hook
()
(
or
(
face-differs-from-default-p
'py-pseudo-keyword-face
)
(
copy-face
'font-lock-keyword-face
'py-pseudo-keyword-face
)))
(
copy-face
'font-lock-keyword-face
'py-pseudo-keyword-face
))
(
or
(
face-differs-from-default-p
'py-builtins-face
)
(
copy-face
'font-lock-keyword-face
'py-builtins-face
))
(
or
(
face-differs-from-default-p
'py-decorators-face
)
(
copy-face
'py-pseudo-keyword-face
'py-decorators-face
))
(
or
(
face-differs-from-default-p
'py-XXX-tag-face
)
(
copy-face
'font-lock-comment-face
'py-XXX-tag-face
))
)
(
add-hook
'font-lock-mode-hook
'py-font-lock-mode-hook
)
(
defvar
python-font-lock-keywords
...
...
@@ -352,30 +427,17 @@ support for features needed by `python-mode'.")
"from"
"global"
"if"
"import"
"in"
"is"
"lambda"
"not"
"or"
"pass"
"print"
"raise"
"return"
"while"
"yield"
"return"
"while"
"
with"
"
yield"
)
"\\|"
))
(
kw2
(
mapconcat
'identity
'
(
"else:"
"except:"
"finally:"
"try:"
)
"\\|"
))
(
kw3
(
mapconcat
'identity
'
(
"ArithmeticError"
"AssertionError"
"AttributeError"
"DeprecationWarning"
"EOFError"
"Ellipsis"
"EnvironmentError"
"Exception"
"False"
"FloatingPointError"
"FutureWarning"
"IOError"
"ImportError"
"IndentationError"
"IndexError"
"KeyError"
"KeyboardInterrupt"
"LookupError"
"MemoryError"
"NameError"
"None"
"NotImplemented"
"NotImplementedError"
"OSError"
"OverflowError"
"OverflowWarning"
"PendingDeprecationWarning"
"ReferenceError"
"RuntimeError"
"RuntimeWarning"
"StandardError"
"StopIteration"
"SyntaxError"
"SyntaxWarning"
"SystemError"
"SystemExit"
"TabError"
"True"
"TypeError"
"UnboundLocalError"
"UnicodeDecodeError"
"UnicodeEncodeError"
"UnicodeError"
"UnicodeTranslateError"
"UserWarning"
"ValueError"
"Warning"
"ZeroDivisionError"
"__debug__"
;; Don't include True, False, None, or
;; Ellipsis in this list, since they are
;; already defined as pseudo keywords.
'
(
"__debug__"
"__import__"
"__name__"
"abs"
"apply"
"basestring"
"bool"
"buffer"
"callable"
"chr"
"classmethod"
"cmp"
"coerce"
"compile"
"complex"
"copyright"
...
...
@@ -391,26 +453,52 @@ support for features needed by `python-mode'.")
"super"
"tuple"
"type"
"unichr"
"unicode"
"vars"
"xrange"
"zip"
)
"\\|"
))
(
kw4
(
mapconcat
'identity
;; Exceptions and warnings
'
(
"ArithmeticError"
"AssertionError"
"AttributeError"
"DeprecationWarning"
"EOFError"
"EnvironmentError"
"Exception"
"FloatingPointError"
"FutureWarning"
"IOError"
"ImportError"
"IndentationError"
"IndexError"
"KeyError"
"KeyboardInterrupt"
"LookupError"
"MemoryError"
"NameError"
"NotImplemented"
"NotImplementedError"
"OSError"
"OverflowError"
"OverflowWarning"
"PendingDeprecationWarning"
"ReferenceError"
"RuntimeError"
"RuntimeWarning"
"StandardError"
"StopIteration"
"SyntaxError"
"SyntaxWarning"
"SystemError"
"SystemExit"
"TabError"
"TypeError"
"UnboundLocalError"
"UnicodeDecodeError"
"UnicodeEncodeError"
"UnicodeError"
"UnicodeTranslateError"
"UserWarning"
"ValueError"
"Warning"
"ZeroDivisionError"
)
"\\|"
))
)
(
list
'
(
"^[ \t]*\\(@.+\\)"
1
'py-decorators-face
)
;; keywords
(
cons
(
concat
"\\
b\\("
kw1
"\\)\\b
[ \n\t(]"
)
1
)
(
cons
(
concat
"\\
<\\("
kw1
"\\)\\>
[ \n\t(]"
)
1
)
;; builtins when they don't appear as object attributes
(
cons
(
concat
"\\(\\b\\|[.]\\)\\("
kw3
"\\)\\b[ \n\t(]"
)
2
)
(
list
(
concat
"\\([^. \t]\\|^\\)[ \t]*\\<\\("
kw3
"\\)\\>[ \n\t(]"
)
2
'py-builtins-face
)
;; block introducing keywords with immediately following colons.
;; Yes "except" is in both lists.
(
cons
(
concat
"\\b\\("
kw2
"\\)[ \n\t(]"
)
1
)
;; `as' but only in "import foo as bar"
'
(
"[ \t]*\\(\\bfrom\\b.*\\)?\\bimport\\b.*\\b\\(as\\)\\b"
.
2
)
(
cons
(
concat
"\\<\\("
kw2
"\\)[ \n\t(]"
)
1
)
;; Exceptions
(
list
(
concat
"\\<\\("
kw4
"\\)[ \n\t:,(]"
)
1
'py-builtins-face
)
;; `as' but only in "import foo as bar" or "with foo as bar"
'
(
"[ \t]*\\(\\<from\\>.*\\)?\\<import\\>.*\\<\\(as\\)\\>"
.
2
)
'
(
"[ \t]*\\<with\\>.*\\<\\(as\\)\\>"
.
1
)
;; classes
'
(
"\\bclass[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
1
font-lock-type-face
)
'
(
"\\<class[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
1
font-lock-type-face
)
;; functions
'
(
"\\
b
def[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
'
(
"\\
<
def[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
1
font-lock-function-name-face
)
;; pseudo-keywords
'
(
"\\
b\\(self\\|None\\|True\\|False\\|Ellipsis\\)\\b
"
'
(
"\\
<\\(self\\|None\\|True\\|False\\|Ellipsis\\)\\>
"
1
py-pseudo-keyword-face
)
;; XXX, TODO, and FIXME tags
'
(
"XXX\\|TODO\\|FIXME"
0
py-XXX-tag-face
t
)
))
"Additional expressions to highlight in Python mode."
)
(
put
'python-mode
'font-lock-defaults
'
(
python-font-lock-keywords
))
...
...
@@ -421,13 +509,7 @@ support for features needed by `python-mode'.")
Currently-active file is at the head of the list."
)
(
defvar
py-pdbtrack-is-tracking-p
nil
)
(
defvar
py-pdbtrack-last-grubbed-buffer
nil
"Record of the last buffer used when the source path was invalid.
This buffer is consulted before the buffer-list history for satisfying
`py-pdbtrack-grub-for-buffer', since it's the most often the likely
prospect as debugging continues."
)
(
make-variable-buffer-local
'py-pdbtrack-last-grubbed-buffer
)
(
defvar
py-pychecker-history
nil
)
...
...
@@ -461,7 +543,7 @@ prospect as debugging continues.")
"\\("
"[^#'\"\n\\]"
"\\|"
py-stringlit-re
"\\)*"
"\\\\$"
)
"Regular expression matching Python backslash continuation lines."
)
(
defconst
py-blank-or-comment-re
"[ \t]*\\($\\|#\\)"
"Regular expression matching a blank or comment line."
)
...
...
@@ -474,7 +556,7 @@ prospect as debugging continues.")
"\\|"
)
"\\)"
)
"Regular expression matching statements to be dedented one level."
)
(
defconst
py-block-closing-keywords-re
"\\(return\\|raise\\|break\\|continue\\|pass\\)"
"Regular expression matching keywords which typically close a block."
)
...
...
@@ -495,30 +577,17 @@ prospect as debugging continues.")
"\\)"
)
"Regular expression matching lines not to dedent after."
)
(
defconst
py-defun-start-re
"^\\([ \t]*\\)def[ \t]+\\([a-zA-Z_0-9]+\\)\\|\\(^[a-zA-Z_0-9]+\\)[ \t]*="
;; If you change this, you probably have to change py-current-defun
;; as well. This is only used by py-current-defun to find the name
;; for add-log.el.
"Regular expression matching a function, method, or variable assignment."
)
(
defconst
py-class-start-re
"^class[ \t]*\\([a-zA-Z_0-9]+\\)"
;; If you change this, you probably have to change py-current-defun
;; as well. This is only used by py-current-defun to find the name
;; for add-log.el.
"Regular expression for finding a class name."
)
(
defconst
py-traceback-line-re
(
defvar
py-traceback-line-re
"[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"
"Regular expression that describes tracebacks."
)
;; pdbtrack contants
;; pdbtrack con
s
tants
(
defconst
py-pdbtrack-stack-entry-regexp
; "^> \\([^(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
"^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
"Regular expression pdbtrack uses to find a stack trace entry."
)
(
defconst
py-pdbtrack-input-prompt
"\n[(<]*
p
db[>)]+ "
(
defconst
py-pdbtrack-input-prompt
"\n[(<]*
[Pp]
db[>)]+ "
"Regular expression pdbtrack uses to recognize a pdb prompt."
)
(
defconst
py-pdbtrack-track-range
10000
...
...
@@ -536,8 +605,9 @@ prospect as debugging continues.")
(
defvar
python-mode-hook
nil
"*Hook called by `python-mode'."
)
(
defvar
jpython-mode-hook
nil
"*Hook called by `jpython-mode'. `jpython-mode' also calls
(
make-obsolete-variable
'jpython-mode-hook
'jython-mode-hook
)
(
defvar
jython-mode-hook
nil
"*Hook called by `jython-mode'. `jython-mode' also calls
`python-mode-hook'."
)
(
defvar
py-shell-hook
nil
...
...
@@ -560,8 +630,6 @@ prospect as debugging continues.")
(
define-key
py-mode-map
"\C-c\C-r"
'py-shift-region-right
)
(
define-key
py-mode-map
"\C-c<"
'py-shift-region-left
)
(
define-key
py-mode-map
"\C-c>"
'py-shift-region-right
)
;; paragraph and string filling
(
define-key
py-mode-map
"\eq"
'py-fill-paragraph
)
;; subprocess commands
(
define-key
py-mode-map
"\C-c\C-c"
'py-execute-buffer
)
(
define-key
py-mode-map
"\C-c\C-m"
'py-execute-import-or-reload
)
...
...
@@ -624,7 +692,7 @@ prospect as debugging continues.")
;; expect RET to do a `py-newline-and-indent' and any Emacsers who
;; dislike this are probably knowledgeable enough to do a rebind.
;; However, we do *not* change C-j since many Emacsers have already
;; swapped RET and C-j and they don't want C-j bound to `newline' to
;; swapped RET and C-j and they don't want C-j bound to `newline' to
;; change.
(
define-key
py-mode-map
"\C-m"
'py-newline-and-indent
)
)
...
...
@@ -742,8 +810,8 @@ This function does not modify point or mark."
(
cond
((
eq
position
'bol
)
(
beginning-of-line
))
((
eq
position
'eol
)
(
end-of-line
))
((
eq
position
'bod
)
(
py-beginning-of-def-or-class
))
((
eq
position
'eod
)
(
py-end-of-def-or-class
))
((
eq
position
'bod
)
(
py-beginning-of-def-or-class
'either
))
((
eq
position
'eod
)
(
py-end-of-def-or-class
'either
))
;; Kind of funny, I know, but useful for py-up-exception.
((
eq
position
'bob
)
(
beginning-of-buffer
))
((
eq
position
'eob
)
(
end-of-buffer
))
...
...
@@ -851,7 +919,7 @@ package. Note that the latest X/Emacs releases contain this package.")
(
defvar
py-imenu-method-regexp
(
concat
; <<methods and functions>>
"\\("
;
"\\("
;
"^[ \t]*"
; new line and maybe whitespace
"\\(def[ \t]+"
; function definitions start with def
"\\([a-zA-Z0-9_]+\\)"
; name is here
...
...
@@ -887,7 +955,7 @@ information.")
;; it.
(
defvar
py-imenu-generic-expression
(
cons
(
concat
(
concat
py-imenu-class-regexp
"\\|"
; or...
py-imenu-method-regexp
...
...
@@ -956,7 +1024,7 @@ of the first definition found."
looking-p
def-name
prev-name
cur-indent
def-pos
(
class-paren
(
first
py-imenu-generic-parens
))
(
class-paren
(
first
py-imenu-generic-parens
))
(
def-paren
(
second
py-imenu-generic-parens
)))
(
setq
looking-p
(
re-search-forward
py-imenu-generic-regexp
(
point-max
)
t
))
...
...
@@ -1011,7 +1079,7 @@ of the first definition found."
(
cons
save-elmt
sub-method-alist
))
index-alist
))))
;; found less indented expression, we're done.
(
t
(
t
(
setq
looking-p
nil
)
(
re-search-backward
py-imenu-generic-regexp
(
point-min
)
t
)))
;; end-cond
...
...
@@ -1025,7 +1093,7 @@ of the first definition found."
(
defun
py-choose-shell-by-shebang
()
"Choose CPython or J
P
ython mode by looking at #! on the first line.
"Choose CPython or Jython 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' (if available)."
...
...
@@ -1049,10 +1117,10 @@ Used by `py-choose-shell', and similar to but distinct from
(
defun
py-choose-shell-by-import
()
"Choose CPython or J
P
ython mode based imports.
If a file imports any packages in `py-j
p
ython-packages', within
"Choose CPython or Jython mode based imports.
If a file imports any packages in `py-jython-packages', within
`py-import-check-point-max' characters from the start of the file,
return `j
p
ython', otherwise return nil."
return `jython', otherwise return nil."
(
let
(
mode
)
(
save-excursion
(
goto-char
(
point-min
))
...
...
@@ -1060,14 +1128,14 @@ return `jpython', otherwise return nil."
(
search-forward-regexp
"^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)"
py-import-check-point-max
t
))
(
setq
mode
(
and
(
member
(
match-string
4
)
py-j
p
ython-packages
)
'j
p
ython
(
setq
mode
(
and
(
member
(
match-string
4
)
py-jython-packages
)
'jython
))))
mode
))
(
defun
py-choose-shell
()
"Choose CPython or J
P
ython mode. Returns the appropriate mode function.
"Choose CPython or Jython 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'
...
...
@@ -1116,6 +1184,7 @@ py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
(
make-local-variable
'indent-region-function
)
(
make-local-variable
'indent-line-function
)
(
make-local-variable
'add-log-current-defun-function
)
(
make-local-variable
'fill-paragraph-function
)
;;
(
set-syntax-table
py-mode-syntax-table
)
(
setq
major-mode
'python-mode
...
...
@@ -1134,6 +1203,8 @@ py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
indent-line-function
'py-indent-line
;; tell add-log.el how to find the current function/method/variable
add-log-current-defun-function
'py-current-defun
fill-paragraph-function
'py-fill-paragraph
)
(
use-local-map
py-mode-map
)
;; add the menu
...
...
@@ -1173,17 +1244,18 @@ py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
(
py-toggle-shells
(
py-choose-shell
))))
(
defun
jpython-mode
()
"Major mode for editing JPython/Jython files.
(
make-obsolete
'jpython-mode
'jython-mode
)
(
defun
jython-mode
()
"Major mode for editing Jython/Jython files.
This is a simple wrapper around `python-mode'.
It runs `j
p
ython-mode-hook' then calls `python-mode.'
It runs `jython-mode-hook' then calls `python-mode.'
It is added to `interpreter-mode-alist' and `py-choose-shell'.
"
(
interactive
)
(
python-mode
)
(
py-toggle-shells
'j
p
ython
)
(
when
j
p
ython-mode-hook
(
run-hooks
'j
p
ython-mode-hook
)))
(
py-toggle-shells
'jython
)
(
when
jython-mode-hook
(
run-hooks
'jython-mode-hook
)))
;; It's handy to add recognition of Python files to the
...
...
@@ -1191,16 +1263,16 @@ It is added to `interpreter-mode-alist' and `py-choose-shell'.
;; can specify different `derived-modes' based on the #! line, but
;; with the latter, we can't. So we just won't add them if they're
;; already added.
(
let
((
modes
'
((
"jpython"
.
jpython-mode
)
(
"jython"
.
jp
ython-mode
)
;;;###autoload
(
let
((
modes
'
((
"jython"
.
j
ython-mode
)
(
"python"
.
python-mode
))))
(
while
modes
(
when
(
not
(
assoc
(
car
modes
)
interpreter-mode-alist
))
(
push
(
car
modes
)
interpreter-mode-alist
))
(
setq
modes
(
cdr
modes
))))
;;;###autoload
(
when
(
not
(
or
(
rassq
'python-mode
auto-mode-alist
)
(
rassq
'j
p
ython-mode
auto-mode-alist
)))
(
rassq
'jython-mode
auto-mode-alist
)))
(
push
'
(
"\\.py$"
.
python-mode
)
auto-mode-alist
))
...
...
@@ -1272,7 +1344,8 @@ comint believe the user typed this string so that
(
procbuf
(
process-buffer
proc
))
; (comint-scroll-to-bottom-on-output t)
(
msg
(
format
"## working on region in file %s...\n"
filename
))
(
cmd
(
format
"execfile(r'%s')\n"
filename
)))
;; add some comment, so that we can filter it out of history
(
cmd
(
format
"execfile(r'%s') # PYTHON-MODE\n"
filename
)))
(
unwind-protect
(
save-excursion
(
set-buffer
procbuf
)
...
...
@@ -1285,12 +1358,13 @@ comint believe the user typed this string so that
(
defun
py-comint-output-filter-function
(
string
)
"Watch output for Python prompt and exec next file waiting in queue.
This function is appropriate for `comint-output-filter-functions'."
;; TBD: this should probably use split-string
(
when
(
and
(
or
(
string-equal
string
">>> "
)
(
and
(
>=
(
length
string
)
5
)
(
string-equal
(
substring
string
-5
)
"\n>>> "
)))
py-file-queue
)
(
pop-to-buffer
(
current-buffer
))
;;remove ansi terminal escape sequences from string, not sure why they are
;;still around...
(
setq
string
(
ansi-color-filter-apply
string
))
(
when
(
and
(
string-match
py-shell-input-prompt-1-regexp
string
)
py-file-queue
)
(
if
py-shell-switch-buffers-on-execute
(
pop-to-buffer
(
current-buffer
)))
(
py-safe
(
delete-file
(
car
py-file-queue
)))
(
setq
py-file-queue
(
cdr
py-file-queue
))
(
if
py-file-queue
...
...
@@ -1346,7 +1420,7 @@ script, and set to python-mode, and pdbtrack will find it.)"
(
-
procmark
py-pdbtrack-track-range
))
procmark
))
target
target_fname
target_lineno
)
target
target_fname
target_lineno
target_buffer
)
(
if
(
not
(
string-match
(
concat
py-pdbtrack-input-prompt
"$"
)
block
))
(
py-pdbtrack-overlay-arrow
nil
)
...
...
@@ -1374,8 +1448,7 @@ script, and set to python-mode, and pdbtrack will find it.)"
We look first to visit the file indicated in the trace.
Failing that, we look for the most recently visited python-mode buffer
with the same name or having
having the named function.
with the same name or having the named function.
If we're unable find the source code we return a string describing the
problem as best as we can determine."
...
...
@@ -1419,11 +1492,10 @@ problem as best as we can determine."
(
defun
py-pdbtrack-grub-for-buffer
(
funcname
lineno
)
"Find most recent buffer itself named or having function funcname.
We first check the last buffer this function found, if any, then walk
throught the buffer-list history for python-mode buffers that are
We walk the buffer-list history for python-mode buffers that are
named for funcname or define a function funcname."
(
let
((
buffers
(
buffer-list
))
cur
buf
buf
got
)
(
while
(
and
buffers
(
not
got
))
(
setq
buf
(
car
buffers
)
...
...
@@ -1438,7 +1510,7 @@ named for funcname or define a function funcname."
(
buffer-substring
(
point-min
)
(
point-max
))))))
(
setq
got
buf
)))
(
setq
py-pdbtrack-last-grubbed-buffer
got
)
))
got
))
(
defun
py-postprocess-output-buffer
(
buf
)
"Highlight exceptions found in BUF.
...
...
@@ -1468,7 +1540,7 @@ If an exception occurred return t, otherwise return nil. BUF must exist."
(
defconst
py-output-buffer
"*Python Output*"
)
(
make-variable-buffer-local
'py-output-buffer
)
;; for toggling between CPython and J
P
ython
;; for toggling between CPython and Jython
(
defvar
py-which-shell
nil
)
(
defvar
py-which-args
py-python-command-args
)
(
defvar
py-which-bufname
"Python"
)
...
...
@@ -1477,14 +1549,14 @@ If an exception occurred return t, otherwise return nil. BUF must exist."
(
make-variable-buffer-local
'py-which-bufname
)
(
defun
py-toggle-shells
(
arg
)
"Toggles between the CPython and J
P
ython shells.
"Toggles between the CPython and Jython shells.
With positive argument ARG (interactively \\[universal-argument]),
uses the CPython shell, with negative ARG uses the J
P
ython shell, and
uses the CPython shell, with negative ARG uses the Jython shell, and
with a zero argument, toggles the shell.
Programmatically, ARG can also be one of the symbols `cpython' or
`j
p
ython', equivalent to positive arg and negative arg respectively."
`jython', equivalent to positive arg and negative arg respectively."
(
interactive
"P"
)
;; default is to toggle
(
if
(
null
arg
)
...
...
@@ -1497,7 +1569,7 @@ Programmatically, ARG can also be one of the symbols `cpython' or
(
setq
arg
-1
)
(
setq
arg
1
)))
((
equal
arg
'cpython
)
(
setq
arg
1
))
((
equal
arg
'j
p
ython
)
(
setq
arg
-1
)))
((
equal
arg
'jython
)
(
setq
arg
-1
)))
(
let
(
msg
)
(
cond
((
<
0
arg
)
...
...
@@ -1505,14 +1577,16 @@ Programmatically, ARG can also be one of the symbols `cpython' or
(
setq
py-which-shell
py-python-command
py-which-args
py-python-command-args
py-which-bufname
"Python"
msg
"CPython"
mode-name
"Python"
))
msg
"CPython"
)
(
if
(
string-equal
py-which-bufname
"Jython"
)
(
setq
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"
))
(
setq
py-which-shell
py-jython-command
py-which-args
py-jython-command-args
py-which-bufname
"Jython"
msg
"Jython"
)
(
if
(
string-equal
py-which-bufname
"Python"
)
(
setq
mode-name
"Jython"
)))
)
(
message
"Using the %s shell"
msg
)
(
setq
py-output-buffer
(
format
"*%s Output*"
py-which-bufname
))))
...
...
@@ -1534,9 +1608,9 @@ prompt). This argument is ignored when this function is called
programmatically, or when running in Emacs 19.34 or older.
Note: You can toggle between using the CPython interpreter and the
J
P
ython interpreter by hitting \\[py-toggle-shells]. This toggles
Jython interpreter by hitting \\[py-toggle-shells]. This toggles
buffer local variables which control whether all your subshell
interactions happen to the `*J
P
ython*' or `*Python*' buffers (the
interactions happen to the `*Jython*' or `*Python*' buffers (the
latter is the name used for the CPython buffer).
Warning: Don't use an interactive Python if you change sys.ps1 or
...
...
@@ -1570,10 +1644,14 @@ filter."
(
concat
(
mapconcat
'identity
py-which-args
" "
)
" "
)
))))
(
switch-to-buffer-other-window
(
apply
'make-comint
py-which-bufname
py-which-shell
nil
args
))
(
if
(
not
(
equal
(
buffer-name
)
"*Python*"
))
(
switch-to-buffer-other-window
(
apply
'make-comint
py-which-bufname
py-which-shell
nil
args
))
(
apply
'make-comint
py-which-bufname
py-which-shell
nil
args
))
(
make-local-variable
'comint-prompt-regexp
)
(
setq
comint-prompt-regexp
"^>>> \\|^[.][.][.] \\|^(pdb) "
)
(
setq
comint-prompt-regexp
(
concat
py-shell-input-prompt-1-regexp
"\\|"
py-shell-input-prompt-2-regexp
"\\|"
"^([Pp]db) "
))
(
add-hook
'comint-output-filter-functions
'py-comint-output-filter-function
)
;; pdbtrack
...
...
@@ -1644,11 +1722,13 @@ is inserted at the end. See also the command `py-clear-queue'."
(
setq
start
(
point
))
(
or
(
<
start
end
)
(
error
"Region is empty"
))
(
setq
py-line-number-offset
(
count-lines
1
start
))
(
let
((
needs-if
(
/=
(
py-point
'bol
)
(
py-point
'boi
))))
(
set-buffer
buf
)
(
python-mode
)
(
when
needs-if
(
insert
"if 1:\n"
))
(
insert
"if 1:\n"
)
(
setq
py-line-number-offset
(
-
py-line-number-offset
1
)))
(
insert-buffer-substring
cur
start
end
)
;; Set the shell either to the #! line command, or to the
;; py-which-shell buffer local variable.
...
...
@@ -1685,8 +1765,9 @@ is inserted at the end. See also the command `py-clear-queue'."
(
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"
)
" -"
""
))))
(
let
((
cmd
(
concat
py-which-shell
(
if
(
string-equal
py-which-bufname
"Jython"
)
" -"
""
))))
;; otherwise either run it synchronously in a subprocess
(
save-excursion
(
set-buffer
buf
)
...
...
@@ -1720,12 +1801,14 @@ sent. A trailing newline will be supplied if needed.
See the `\\[py-execute-region]' docs for an account of some
subtleties, 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
))
(
let
((
old-buffer
(
current-buffer
)))
(
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
)
(
pop-to-buffer
old-buffer
)))
(
defun
py-execute-import-or-reload
(
&optional
async
)
"Import the current buffer's file in a Python interpreter.
...
...
@@ -1821,6 +1904,9 @@ subtleties, including the use of the optional ASYNC argument."
(
t
(
find-file
(
read-file-name
"Exception file: "
nil
file
t
))))))
;; Fiddle about with line number
(
setq
line
(
+
py-line-number-offset
line
))
(
pop-to-buffer
buffer
)
;; Force Python mode
(
if
(
not
(
eq
major-mode
'python-mode
))
...
...
@@ -2001,16 +2087,29 @@ This function is normally bound to `indent-line-function' so
(
interactive
"P"
)
(
let*
((
ci
(
current-indentation
))
(
move-to-indentation-p
(
<=
(
current-column
)
ci
))
(
need
(
py-compute-indentation
(
not
arg
))))
;; see if we need to dedent
(
if
(
py-outdent-p
)
(
setq
need
(
-
need
py-indent-offset
)))
(
if
(
/=
ci
need
)
(
save-excursion
(
beginning-of-line
)
(
delete-horizontal-space
)
(
indent-to
need
)))
(
if
move-to-indentation-p
(
back-to-indentation
))))
(
need
(
py-compute-indentation
(
not
arg
)))
(
cc
(
current-column
)))
;; dedent out a level if previous command was the same unless we're in
;; column 1
(
if
(
and
(
equal
last-command
this-command
)
(
/=
cc
0
))
(
progn
(
beginning-of-line
)
(
delete-horizontal-space
)
(
indent-to
(
*
(
/
(
-
cc
1
)
py-indent-offset
)
py-indent-offset
)))
(
progn
;; see if we need to dedent
(
if
(
py-outdent-p
)
(
setq
need
(
-
need
py-indent-offset
)))
(
if
(
or
py-tab-always-indent
move-to-indentation-p
)
(
progn
(
if
(
/=
ci
need
)
(
save-excursion
(
beginning-of-line
)
(
delete-horizontal-space
)
(
indent-to
need
)))
(
if
move-to-indentation-p
(
back-to-indentation
)))
(
insert-tab
))))))
(
defun
py-newline-and-indent
()
"Strives to act like the Emacs `newline-and-indent'.
...
...
@@ -2054,39 +2153,23 @@ dedenting."
((
py-continuation-line-p
)
(
let
((
startpos
(
point
))
(
open-bracket-pos
(
py-nesting-level
))
endpos
searching
found
state
)
endpos
searching
found
state
cind
cline
)
(
if
open-bracket-pos
(
progn
;; align with first item in list; else a normal
;; indent beyond the line with the open bracket
(
goto-char
(
1+
open-bracket-pos
))
; just beyond bracket
;; is the first list item on the same line?
(
skip-chars-forward
" \t"
)
(
if
(
null
(
memq
(
following-char
)
'
(
?\n
?#
?\\
)))
; yes, so line up with it
(
current-column
)
;; first list item on another line, or doesn't exist yet
(
forward-line
1
)
(
while
(
and
(
<
(
point
)
startpos
)
(
looking-at
"[ \t]*[#\n\\\\]"
))
; skip noise
(
forward-line
1
))
(
if
(
and
(
<
(
point
)
startpos
)
(
/=
startpos
(
save-excursion
(
goto-char
(
1+
open-bracket-pos
))
(
forward-comment
(
point-max
))
(
point
))))
;; again mimic the first list item
(
current-indentation
)
;; else they're about to enter the first item
(
goto-char
open-bracket-pos
)
(
setq
placeholder
(
point
))
(
py-goto-initial-line
)
(
py-goto-beginning-of-tqs
(
save-excursion
(
nth
3
(
parse-partial-sexp
placeholder
(
point
)))))
(
+
(
current-indentation
)
py-indent-offset
))))
(
setq
endpos
(
py-point
'bol
))
(
py-goto-initial-line
)
(
setq
cind
(
current-indentation
))
(
setq
cline
cind
)
(
dolist
(
bp
(
nth
9
(
save-excursion
(
parse-partial-sexp
(
point
)
endpos
)))
cind
)
(
if
(
search-forward
"\n"
bp
t
)
(
setq
cline
cind
))
(
goto-char
(
1+
bp
))
(
skip-chars-forward
" \t"
)
(
setq
cind
(
if
(
memq
(
following-char
)
'
(
?\n
?#
?\\
))
(
+
cline
py-indent-offset
)
(
current-column
)))))
;; else on backslash continuation line
(
forward-line
-1
)
(
if
(
py-continuation-line-p
)
; on at least 3rd line in block
...
...
@@ -2834,7 +2917,7 @@ pleasant."
;; ripped from cc-mode
(
defun
py-forward-into-nomenclature
(
&optional
arg
)
"Move forward to end of a nomenclature section or word.
With \\[universal-argument] (programmatically, optional argument ARG),
With \\[universal-argument] (programmatically, optional argument ARG),
do it that many times.
A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
...
...
@@ -2888,6 +2971,11 @@ A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
;; Pychecker
;; hack for FSF Emacs
(
unless
(
fboundp
'read-shell-command
)
(
defalias
'read-shell-command
'read-string
))
(
defun
py-pychecker-run
(
command
)
"*Run pychecker (default on the file currently visited)."
(
interactive
...
...
@@ -3412,7 +3500,7 @@ multi-line statement we need to skip over the continuation lines."
(
defun
py-statement-opens-block-p
()
"Return t iff the current statement opens a block.
I.e., iff it ends with a colon that is not in a comment. Point should
I.e., iff it ends with a colon that is not in a comment. Point should
be at the start of a statement."
(
save-excursion
(
let
((
start
(
point
))
...
...
@@ -3496,8 +3584,8 @@ does not include blank lines, comments, or continuation lines."
KEY is a regular expression describing a Python keyword. Skip blank
lines and non-indenting comments. If the statement found starts with
KEY, then stop, otherwise go back to first enclosing block starting
with KEY. If successful, leave point at the start of the KEY line and
return t. Otherwise, leav point at an undefined place and return nil."
with KEY. If successful, leave point at the start of the KEY line and
return t. Otherwise, leav
e
point at an undefined place and return nil."
;; skip blanks and non-indenting #
(
py-goto-initial-line
)
(
while
(
and
...
...
@@ -3505,7 +3593,7 @@ return t. Otherwise, leav point at an undefined place and return nil."
(
zerop
(
forward-line
-1
)))
; go back
nil
)
(
py-goto-initial-line
)
(
let*
((
re
(
concat
"[ \t]*"
key
"\\
b
"
))
(
let*
((
re
(
concat
"[ \t]*"
key
"\\
>
"
))
(
case-fold-search
nil
)
; let* so looking-at sees this
(
found
(
looking-at
re
))
(
dead
nil
))
...
...
@@ -3531,7 +3619,7 @@ Prefix with \"...\" if leading whitespace was skipped."
`Keyword' is defined (essentially) as the regular expression
([a-z]+). Returns nil if none was found."
(
let
((
case-fold-search
nil
))
(
if
(
looking-at
"[ \t]*\\([a-z]+\\)\\
b
"
)
(
if
(
looking-at
"[ \t]*\\([a-z]+\\)\\
>
"
)
(
intern
(
buffer-substring
(
match-beginning
1
)
(
match-end
1
)))
nil
)))
...
...
@@ -3539,14 +3627,49 @@ Prefix with \"...\" if leading whitespace was skipped."
"Python value for `add-log-current-defun-function'.
This tells add-log.el how to find the current function/method/variable."
(
save-excursion
(
if
(
re-search-backward
py-defun-start-re
nil
t
)
(
or
(
match-string
3
)
(
let
((
method
(
match-string
2
)))
(
if
(
and
(
not
(
zerop
(
length
(
match-string
1
))))
(
re-search-backward
py-class-start-re
nil
t
))
(
concat
(
match-string
1
)
"."
method
)
method
)))
nil
)))
;; Move back to start of the current statement.
(
py-goto-initial-line
)
(
back-to-indentation
)
(
while
(
and
(
or
(
looking-at
py-blank-or-comment-re
)
(
py-in-literal
))
(
not
(
bobp
)))
(
backward-to-indentation
1
))
(
py-goto-initial-line
)
(
let
((
scopes
""
)
(
sep
""
)
dead
assignment
)
;; Check for an assignment. If this assignment exists inside a
;; def, it will be overwritten inside the while loop. If it
;; exists at top lever or inside a class, it will be preserved.
(
when
(
looking-at
"[ \t]*\\([a-zA-Z0-9_]+\\)[ \t]*="
)
(
setq
scopes
(
buffer-substring
(
match-beginning
1
)
(
match-end
1
)))
(
setq
assignment
t
)
(
setq
sep
"."
))
;; Prepend the name of each outer socpe (def or class).
(
while
(
not
dead
)
(
if
(
and
(
py-go-up-tree-to-keyword
"\\(class\\|def\\)"
)
(
looking-at
"[ \t]*\\(class\\|def\\)[ \t]*\\([a-zA-Z0-9_]+\\)[ \t]*"
))
(
let
((
name
(
buffer-substring
(
match-beginning
2
)
(
match-end
2
))))
(
if
(
and
assignment
(
looking-at
"[ \t]*def"
))
(
setq
scopes
name
)
(
setq
scopes
(
concat
name
sep
scopes
))
(
setq
sep
"."
))))
(
setq
assignment
nil
)
(
condition-case
nil
; Terminate nicely at top level.
(
py-goto-block-up
'no-mark
)
(
error
(
setq
dead
t
))))
(
if
(
string=
scopes
""
)
nil
scopes
))))
(
defconst
py-help-address
"python-mode@python.org"
...
...
@@ -3588,7 +3711,7 @@ non-nil) just submit an enhancement request."
"Dear Barry,"
)
;salutation
(
if
enhancement-p
nil
(
set-mark
(
point
))
(
insert
(
insert
"
Please
replace
this
text
with
a
sufficiently
large
code
sample\n
\
and
an
exact
recipe
so
that
I
can
reproduce
your
problem.
Failure\n
\
to
do
so
may
mean
a
greater
delay
in
fixing
your
bug.\n\n
")
...
...
@@ -3608,7 +3731,7 @@ These are Python temporary files awaiting execution."
(add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
;; Add a designator to the minor mode strings
(or (assq 'py-pdbtrack-
minor-mode-string
minor-mode-alist)
(or (assq 'py-pdbtrack-
is-tracking-p
minor-mode-alist)
(push '(py-pdbtrack-is-tracking-p py-pdbtrack-minor-mode-string)
minor-mode-alist))
...
...
@@ -3747,20 +3870,35 @@ and initial `#'s.
If
point
is
inside
a
string,
narrow
to
that
string
and
fill.
"
(interactive "
P
")
(let* ((bod (py-point 'bod))
(pps (parse-partial-sexp bod (point))))
(cond
;; are we inside a comment or on a line with only whitespace before
;; the comment start?
((or (nth 4 pps)
(save-excursion (beginning-of-line) (looking-at "
[
\t]*#
"
)))
(
py-fill-comment
justify
))
;; are we inside a string?
((
nth
3
pps
)
(
py-fill-string
(
nth
8
pps
)))
;; otherwise use the default
(
t
(
fill-paragraph
justify
))
)))
;; fill-paragraph will narrow incorrectly
(save-restriction
(widen)
(let* ((bod (py-point 'bod))
(pps (parse-partial-sexp bod (point))))
(cond
;; are we inside a comment or on a line with only whitespace before
;; the comment start?
((or (nth 4 pps)
(save-excursion (beginning-of-line) (looking-at "
[
\t]*#
"
)))
(
py-fill-comment
justify
))
;; are we inside a string?
((
nth
3
pps
)
(
py-fill-string
(
nth
8
pps
)))
;; are we at the opening quote of a string, or in the indentation?
((
save-excursion
(
forward-word
1
)
(
eq
(
py-in-literal
)
'string
))
(
save-excursion
(
py-fill-string
(
py-point
'boi
))))
;; are we at or after the closing quote of a string?
((
save-excursion
(
backward-word
1
)
(
eq
(
py-in-literal
)
'string
))
(
save-excursion
(
py-fill-string
(
py-point
'boi
))))
;; otherwise use the default
(
t
(
fill-paragraph
justify
))
))))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment