Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
b360c71b
Commit
b360c71b
authored
Jul 08, 2013
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #242 from gvol/master
Improvements to cython-mode.el
parents
807d143a
0e5d211f
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
210 additions
and
7 deletions
+210
-7
Tools/cython-mode.el
Tools/cython-mode.el
+210
-7
No files found.
Tools/cython-mode.el
View file @
b360c71b
;; Cython mode
;;; cython-mode.el -- Major mode for editing Cython files
;;; Commentary:
;; This should work with python-mode.el as well as either the new
;; python.el or the old.
;;; Code:
;; Load python-mode if available, otherwise use builtin emacs python package
(
when
(
not
(
require
'python-mode
nil
t
))
(
when
(
not
(
require
'python-mode
nil
t
))
(
require
'python
))
(
eval-when-compile
(
require
'rx
))
;;;###autoload
(
add-to-list
'auto-mode-alist
'
(
"\\.pyx\\'"
.
cython-mode
))
;;;###autoload
(
add-to-list
'auto-mode-alist
'
(
"\\.pxd\\'"
.
cython-mode
))
;;;###autoload
(
add-to-list
'auto-mode-alist
'
(
"\\.pxi\\'"
.
cython-mode
))
(
defvar
cython-buffer
nil
"Variable pointing to the cython buffer which was compiled."
)
(
defun
cython-compile
()
"Compile the file via Cython."
(
interactive
)
...
...
@@ -17,8 +31,7 @@
(
compile
compile-command
)
(
set
(
make-local-variable
'cython-buffer
)
cy-buffer
)
(
add-to-list
(
make-local-variable
'compilation-finish-functions
)
'cython-compilation-finish
)))
)
'cython-compilation-finish
))))
(
defun
cython-compilation-finish
(
buffer
how
)
"Called when Cython compilation finishes."
...
...
@@ -50,16 +63,206 @@
1
font-lock-function-name-face
))
"Additional font lock keywords for Cython mode."
)
;;;###autoload
(
defgroup
cython
nil
"Major mode for editing and compiling Cython files"
:group
'languages
:prefix
"cython-"
:link
'
(
url-link
:tag
"Homepage"
"http://cython.org"
))
;;;###autoload
(
defcustom
cython-default-compile-format
"cython -a %s"
"Format for the default command to compile a Cython file.
It will be passed to `format' with `buffer-file-name' as the only other argument."
:group
'cython
:type
'string
)
;; Some functions defined differently in the different python modes
(
defun
cython-comment-line-p
()
"Return non-nil if current line is a comment."
(
save-excursion
(
back-to-indentation
)
(
eq
?#
(
char-after
(
point
)))))
(
defun
cython-in-string/comment
()
"Return non-nil if point is in a comment or string."
(
nth
8
(
syntax-ppss
)))
(
defalias
'cython-beginning-of-statement
(
cond
;; python-mode.el
((
fboundp
'py-beginning-of-statement
)
'py-beginning-of-statement
)
;; old python.el
((
fboundp
'python-beginning-of-statement
)
'python-beginning-of-statement
)
;; new python.el
((
fboundp
'python-nav-beginning-of-statement
)
'python-nav-beginning-of-statement
)
(
t
(
error
"Couldn't find implementation for `cython-beginning-of-statement'"
))))
(
defalias
'cython-beginning-of-block
(
cond
;; python-mode.el
((
fboundp
'py-beginning-of-block
)
'py-beginning-of-block
)
;; old python.el
((
fboundp
'python-beginning-of-block
)
'python-beginning-of-block
)
;; new python.el
((
fboundp
'python-nav-beginning-of-block
)
'python-nav-beginning-of-block
)
(
t
(
error
"Couldn't find implementation for `cython-beginning-of-block'"
))))
(
defalias
'cython-end-of-statement
(
cond
;; python-mode.el
((
fboundp
'py-end-of-statement
)
'py-end-of-statement
)
;; old python.el
((
fboundp
'python-end-of-statement
)
'python-end-of-statement
)
;; new python.el
((
fboundp
'python-nav-end-of-statement
)
'python-nav-end-of-statement
)
(
t
(
error
"Couldn't find implementation for `cython-end-of-statement'"
))))
(
defun
cython-open-block-statement-p
(
&optional
bos
)
"Return non-nil if statement at point opens a Cython block.
BOS non-nil means point is known to be at beginning of statement."
(
save-excursion
(
unless
bos
(
cython-beginning-of-statement
))
(
looking-at
(
rx
(
and
(
or
"if"
"else"
"elif"
"while"
"for"
"def"
"cdef"
"cpdef"
"class"
"try"
"except"
"finally"
"with"
"EXAMPLES:"
"TESTS:"
"INPUT:"
"OUTPUT:"
)
symbol-end
)))))
(
defun
cython-beginning-of-defun
()
"`beginning-of-defun-function' for Cython.
Finds beginning of innermost nested class or method definition.
Returns the name of the definition found at the end, or nil if
reached start of buffer."
(
let
((
ci
(
current-indentation
))
(
def-re
(
rx
line-start
(
0+
space
)
(
or
"def"
"cdef"
"cpdef"
"class"
)
(
1+
space
)
(
group
(
1+
(
or
word
(
syntax
symbol
))))))
found
lep
)
;; def-line
(
if
(
cython-comment-line-p
)
(
setq
ci
most-positive-fixnum
))
(
while
(
and
(
not
(
bobp
))
(
not
found
))
;; Treat bol at beginning of function as outside function so
;; that successive C-M-a makes progress backwards.
;;(setq def-line (looking-at def-re))
(
unless
(
bolp
)
(
end-of-line
))
(
setq
lep
(
line-end-position
))
(
if
(
and
(
re-search-backward
def-re
nil
'move
)
;; Must be less indented or matching top level, or
;; equally indented if we started on a definition line.
(
let
((
in
(
current-indentation
)))
(
or
(
and
(
zerop
ci
)
(
zerop
in
))
(
=
lep
(
line-end-position
))
; on initial line
;; Not sure why it was like this -- fails in case of
;; last internal function followed by first
;; non-def statement of the main body.
;;(and def-line (= in ci))
(
=
in
ci
)
(
<
in
ci
)))
(
not
(
cython-in-string/comment
)))
(
setq
found
t
)))))
(
defun
cython-end-of-defun
()
"`end-of-defun-function' for Cython.
Finds end of innermost nested class or method definition."
(
let
((
orig
(
point
))
(
pattern
(
rx
line-start
(
0+
space
)
(
or
"def"
"cdef"
"cpdef"
"class"
)
space
)))
;; Go to start of current block and check whether it's at top
;; level. If it is, and not a block start, look forward for
;; definition statement.
(
when
(
cython-comment-line-p
)
(
end-of-line
)
(
forward-comment
most-positive-fixnum
))
(
when
(
not
(
cython-open-block-statement-p
))
(
cython-beginning-of-block
))
(
if
(
zerop
(
current-indentation
))
(
unless
(
cython-open-block-statement-p
)
(
while
(
and
(
re-search-forward
pattern
nil
'move
)
(
cython-in-string/comment
)))
; just loop
(
unless
(
eobp
)
(
beginning-of-line
)))
;; Don't move before top-level statement that would end defun.
(
end-of-line
)
(
beginning-of-defun
))
;; If we got to the start of buffer, look forward for
;; definition statement.
(
when
(
and
(
bobp
)
(
not
(
looking-at
(
rx
(
or
"def"
"cdef"
"cpdef"
"class"
)))))
(
while
(
and
(
not
(
eobp
))
(
re-search-forward
pattern
nil
'move
)
(
cython-in-string/comment
))))
; just loop
;; We're at a definition statement (or end-of-buffer).
;; This is where we should have started when called from end-of-defun
(
unless
(
eobp
)
(
let
((
block-indentation
(
current-indentation
)))
(
python-nav-end-of-statement
)
(
while
(
and
(
forward-line
1
)
(
not
(
eobp
))
(
or
(
and
(
>
(
current-indentation
)
block-indentation
)
(
or
(
cython-end-of-statement
)
t
))
;; comment or empty line
(
looking-at
(
rx
(
0+
space
)
(
or
eol
"#"
))))))
(
forward-comment
-1
))
;; Count trailing space in defun (but not trailing comments).
(
skip-syntax-forward
" >"
)
(
unless
(
eobp
)
; e.g. missing final newline
(
beginning-of-line
)))
;; Catch pathological cases like this, where the beginning-of-defun
;; skips to a definition we're not in:
;; if ...:
;; ...
;; else:
;; ... # point here
;; ...
;; def ...
(
if
(
<
(
point
)
orig
)
(
goto-char
(
point-max
)))))
(
defun
cython-current-defun
()
"`add-log-current-defun-function' for Cython."
(
save-excursion
;; Move up the tree of nested `class' and `def' blocks until we
;; get to zero indentation, accumulating the defined names.
(
let
((
start
t
)
accum
)
(
while
(
or
start
(
>
(
current-indentation
)
0
))
(
setq
start
nil
)
(
cython-beginning-of-block
)
(
end-of-line
)
(
beginning-of-defun
)
(
if
(
looking-at
(
rx
(
0+
space
)
(
or
"def"
"cdef"
"cpdef"
"class"
)
(
1+
space
)
(
group
(
1+
(
or
word
(
syntax
symbol
))))))
(
push
(
match-string
1
)
accum
)))
(
if
accum
(
mapconcat
'identity
accum
"."
)))))
;;;###autoload
(
define-derived-mode
cython-mode
python-mode
"Cython"
"Major mode for Cython development, derived from Python mode.
\\{cython-mode-map}"
(
setcar
font-lock-defaults
(
append
python-font-lock-keywords
cython-font-lock-keywords
))
(
set
(
make-local-variable
'outline-regexp
)
(
rx
(
*
space
)
(
or
"class"
"def"
"cdef"
"cpdef"
"elif"
"else"
"except"
"finally"
"for"
"if"
"try"
"while"
"with"
)
symbol-end
))
(
set
(
make-local-variable
'beginning-of-defun-function
)
#'
cython-beginning-of-defun
)
(
set
(
make-local-variable
'end-of-defun-function
)
#'
cython-end-of-defun
)
(
set
(
make-local-variable
'compile-command
)
(
concat
"cython -a "
buffer-file-name
))
(
format
cython-default-compile-format
(
shell-quote-argument
buffer-file-name
)))
(
set
(
make-local-variable
'add-log-current-defun-function
)
#'
cython-current-defun
)
(
add-hook
'which-func-functions
#'
cython-current-defun
nil
t
)
(
add-to-list
(
make-local-variable
'compilation-finish-functions
)
'cython-compilation-finish
)
)
'cython-compilation-finish
))
(
provide
'cython-mode
)
;;; cython-mode.el ends here
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