Required files added

This commit is contained in:
Sameer Rahmani 2011-12-03 15:00:16 +03:30
parent 2b36631ba2
commit e284af314f
75 changed files with 6697 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
conf/emacs.d/session*
*~

1652
conf/emacs.d/ac-comphist.dat Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,151 @@
(eval-when-compile (require 'cl))
(defvar clang-executable "clang")
(defvar clang-completion-doc-table (make-hash-table :test 'equal))
;; faces
(defface clang-completion-plain-face
'((t (:inherit default :family "Verdana")))
"clang completion hint base font" :group 'clang-completion-faces)
(defface clang-completion-type-face
'((t (:inherit 'clang-completion-plain-face :foreground "#729FCF" :weight bold :family "Verdana")))
"clang completion hint font for types" :group 'clang-completion-faces)
(defface clang-completion-variable-face
'((t (:inherit 'clang-completion-plain-face :foreground "#73D216" :family "Verdana")))
"clang completion hint font for variables" :group 'clang-completion-faces)
;; extra flags
(defvar clang-completion-pch nil)
(defvar clang-completion-flags nil)
(defvar clang-completion-suppress-error nil)
(defun clang-process-exec (command)
(with-output-to-string
(with-current-buffer standard-output
(unless (or (eq (apply 'call-process (car command) nil '(t ".clang-completion-error") nil (cdr command)) 0) clang-completion-suppress-error)
(let ((last-command compile-command))
(compile "cat .clang-completion-error")
(setq compile-command last-command))))))
(defun clang-parse-completion-line (line)
(cond ((string-match "^COMPLETION: Pattern" line) nil) ;; exclude patterns
((string-match "^COMPLETION: \\([^ ]*\\)\\(?: : \\([^\"]*\\)\\)$" line)
(list (match-string 1 line) (match-string 2 line)))
((string-match "^OVERRIDE: \\([^ ]*\\)\\(?: : \\([^\"]*\\)\\)$" line)
(list (match-string 1 line) (match-string 2 line)))
(t nil))
)
(defun clang-process (buffer point)
(unless (buffer-file-name buffer)
(return ""))
(let* ((filename (buffer-file-name buffer))
(col (1+ (- point (point-at-bol))))
(row (count-lines point (point-min)))
(cmd (list clang-executable "-cc1"
filename "-fsyntax-only" "-code-completion-at"
(format "%s:%s:%s" filename row col))))
;; eval the config file under buffer locations
(let* ((filedir (file-name-directory filename))
(config-filename (concat filedir ".clang-completion-config.el")))
(when (file-readable-p config-filename)
(with-temp-buffer
(insert-file-contents config-filename)
(eval-buffer))))
(when (listp clang-completion-flags)
(setq cmd (append cmd clang-completion-flags)))
(when (stringp clang-completion-pch)
(setq cmd (append cmd (list "-include-pch" clang-completion-pch))))
(message (format "complete at %s:%s:%s" filename row col))
(clang-process-exec cmd)))
(defun clang-get-process-result (string)
(let* ((completion-lines (split-string string "\n")))
(delq nil (mapcar 'clang-parse-completion-line completion-lines))))
(defun clang-get-process-completion-result (string)
(mapcar 'car (clang-get-process-result string)))
(defun clang-get-process-prototype-table (string)
(let* ((lines (clang-get-process-result string))
(result-table (make-hash-table :test 'equal)))
(dolist (line lines)
(let* ((key (first line))
(value (gethash key result-table)))
(setq value (append value (list (second line))))
(puthash key value result-table))
)
(setq clang-completion-doc-table result-table)))
(defun clang-get-completions (&optional buffer point)
;; save all modified buffers
(or buffer (setq buffer (current-buffer)))
(or point (setq point (point)))
(save-some-buffers t)
(let* ((output (clang-process buffer point)))
(clang-get-process-prototype-table output)
(clang-get-process-completion-result output)))
(defun filter-doc-buffer ()
(while (re-search-backward "\\[#.*?::#\\]" nil t)
(replace-match ""))
(goto-char (point-max))
(while (re-search-backward "\\[#\\|#\\]" nil t)
(replace-match " "))
(goto-char (point-max))
(while (re-search-backward "{#\\|#}\\|<#\\|#>" nil t)
(replace-match ""))
)
(defun clang-get-doc (symbol)
;;(setq symbol (symbol-name (intern-soft symbol)))
(let ((reslist (gethash symbol clang-completion-doc-table)))
(with-temp-buffer
(font-lock-add-keywords nil '(("\\[#\\(.*?\\)#\\]" 1
'clang-completion-type-face t)))
(font-lock-add-keywords nil '(("<#\\(.*?\\)#>" 1
'clang-completion-variable-face t)))
(font-lock-add-keywords nil '(("\\(.*\\)" 1
'clang-completion-plain-face t)))
(font-lock-mode t)
(insert (reduce '(lambda (x y) (concat x "\n" y)) reslist))
(font-lock-fontify-buffer)
(filter-doc-buffer)
(message (buffer-string))))
;;(with-temp-buffer
;; (dolist (proto reslist)
;; (insert proto)
;; (insert "\n\n"))
;; (filter-doc-buffer)
;; (buffer-string))
;; display nothing
(return nil))
(defvar ac-source-clang-complete
'((candidates . (clang-get-completions nil ac-point))
(prefix "[^a-zA-Z0-9_]\\(\\(?:[a-zA-Z_][a-zA-Z0-9_]*\\)?\\)" nil 1)
(document . clang-get-doc)
(requires . 0)
(symbol . "C")
(cache)))
;;(defvar ac-source-clang-static-complete
;; '((candidates . (clang-get-completions nil ac-point))
;; (prefix "::\\(\\(?:[a-zA-Z_][a-zA-Z0-9_]*\\)?\\)" nil 1)
;; ;;(document . 'clang-get-doc)
;; (requires . 0)
;; (symbol . "M")
;; (cache)))
(defun ac-complete-clang ()
(interactive)
(auto-complete '(ac-source-clang-complete)))
(provide 'auto-complete-clang)

2061
conf/emacs.d/doctest-mode.el Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
(autoload 'python-mode "python-mode" "Python Mode." t)
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-to-list 'interpreter-mode-alist '("python" . python-mode))
(require 'python-mode)
(add-hook 'python-mode-hook
(lambda ()
(set-variable 'py-indent-offset 4)
;(set-variable 'py-smart-indentation nil)
(set-variable 'indent-tabs-mode nil)
(define-key py-mode-map (kbd "RET") 'newline-and-indent)
;(define-key py-mode-map [tab] 'yas/expand)
;(setq yas/after-exit-snippet-hook 'indent-according-to-mode)
(smart-operator-mode-on)
))
;; pymacs
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-exec "pymacs" nil t)
(autoload 'pymacs-load "pymacs" nil t)
;;(eval-after-load "pymacs"
;; '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
(pymacs-load "ropemacs" "rope-")
(setq ropemacs-enable-autoimport t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Auto-completion
;;; Integrates:
;;; 1) Rope
;;; 2) Yasnippet
;;; all with AutoComplete.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun prefix-list-elements (list prefix)
(let (value)
(nreverse
(dolist (element list value)
(setq value (cons (format "%s%s" prefix element) value))))))
(defvar ac-source-rope
'((candidates
. (lambda ()
(prefix-list-elements (rope-completions) ac-target))))
"Source for Rope")
(defun ac-python-find ()
"Python `ac-find-function'."
(require 'thingatpt)
(let ((symbol (car-safe (bounds-of-thing-at-point 'symbol))))
(if (null symbol)
(if (string= "." (buffer-substring (- (point) 1) (point)))
(point)
nil)
symbol)))
(defun ac-python-candidate ()
"Python `ac-candidates-function'"
(let (candidates)
(dolist (source ac-sources)
(if (symbolp source)
(setq source (symbol-value source)))
(let* ((ac-limit (or (cdr-safe (assq 'limit source)) ac-limit))
(requires (cdr-safe (assq 'requires source)))
cand)
(if (or (null requires)
(>= (length ac-target) requires))
(setq cand
(delq nil
(mapcar (lambda (candidate)
(propertize candidate 'source source))
(funcall (cdr (assq 'candidates source)))))))
(if (and (> ac-limit 1)
(> (length cand) ac-limit))
(setcdr (nthcdr (1- ac-limit) cand) nil))
(setq candidates (append candidates cand))))
(delete-dups candidates)))
(add-hook 'python-mode-hook
(lambda ()
(auto-complete-mode 1)
(set (make-local-variable 'ac-sources)
(append ac-sources '(ac-source-rope) '(ac-source-yasnippet)))
(set (make-local-variable 'ac-find-function) 'ac-python-find)
(set (make-local-variable 'ac-candidate-function) 'ac-python-candidate)
(set (make-local-variable 'ac-auto-start) 3)))
;;sameer's python specific tab completion
(defun sameer-python-tab ()
; Try the following:
; 1) Do a yasnippet expansion
; 2) Do a Rope code completion
; 3) Do an indent
(interactive)
(if (eql (ac-start) 0)
(indent-for-tab-command)))
(defadvice ac-start (before advice-turn-on-auto-start activate)
(set (make-local-variable 'ac-auto-start) t))
(defadvice ac-cleanup (after advice-turn-off-auto-start activate)
(set (make-local-variable 'ac-auto-start) nil))
(define-key py-mode-map (kbd "M-p") 'sameer-python-tab)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; End Auto Completion
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auto Syntax Error Hightlight
(add-hook 'find-file-hook 'flymake-find-file-hook)
(provide 'init_python)

491
conf/emacs.d/ipython.el Normal file
View File

@ -0,0 +1,491 @@
;;; ipython.el --- Adds support for IPython to python-mode.el
;; Copyright (C) 2002, 2003, 2004, 2005 Alexander Schmolck
;; Author: Alexander Schmolck
;; Keywords: ipython python languages oop
;; URL: http://ipython.scipy.org
;; Compatibility: Emacs21, XEmacs21
;; FIXME: #$@! INPUT RING
(defconst ipython-version "$Revision: 2927 $"
"VC version number.")
;;; Commentary
;; This library makes all the functionality python-mode has when running with
;; the normal python-interpreter available for ipython, too. It also enables a
;; persistent py-shell command history across sessions (if you exit python
;; with C-d in py-shell) and defines the command `ipython-to-doctest', which
;; can be used to convert bits of a ipython session into something that can be
;; used for doctests. To install, put this file somewhere in your emacs
;; `load-path' [1] and add the following line to your ~/.emacs file (the first
;; line only needed if the default (``"ipython"``) is wrong)::
;;
;; (setq ipython-command "/SOME-PATH/ipython")
;; (require 'ipython)
;;
;; Ipython will be set as the default python shell, but only if the ipython
;; executable is in the path. For ipython sessions autocompletion with <tab>
;; is also enabled (experimental feature!). Please also note that all the
;; terminal functions in py-shell are handled by emacs's comint, **not** by
;; (i)python, so importing readline etc. will have 0 effect.
;;
;; To start an interactive ipython session run `py-shell' with ``M-x py-shell``
;; (or the default keybinding ``C-c C-!``).
;;
;; You can customize the arguments passed to the IPython instance at startup by
;; setting the ``py-python-command-args`` variable. For example, to start
;; always in ``pylab`` mode with hardcoded light-background colors, you can
;; use::
;;
;; (setq py-python-command-args '("-pylab" "-colors" "LightBG"))
;;
;;
;; NOTE: This mode is currently somewhat alpha and although I hope that it
;; will work fine for most cases, doing certain things (like the
;; autocompletion and a decent scheme to switch between python interpreters)
;; properly will also require changes to ipython that will likely have to wait
;; for a larger rewrite scheduled some time in the future.
;;
;;
;; Further note that I don't know whether this runs under windows or not and
;; that if it doesn't I can't really help much, not being afflicted myself.
;;
;;
;; Hints for effective usage
;; -------------------------
;;
;; - IMO the best feature by far of the ipython/emacs combo is how much easier
;; it makes it to find and fix bugs thanks to the ``%pdb on or %debug``/
;; pdbtrack combo. Try it: first in the ipython to shell do ``%pdb on`` then
;; do something that will raise an exception (FIXME nice example), or type
;; ``%debug`` after the exception has been raised. YOu'll be amazed at how
;; easy it is to inspect the live objects in each stack frames and to jump to
;; the corresponding sourcecode locations as you walk up and down the stack
;; trace (even without ``%pdb on`` you can always use ``C-c -``
;; (`py-up-exception') to jump to the corresponding source code locations).
;;
;; - emacs gives you much more powerful commandline editing and output searching
;; capabilities than ipython-standalone -- isearch is your friend if you
;; quickly want to print 'DEBUG ...' to stdout out etc.
;;
;; - This is not really specific to ipython, but for more convenient history
;; access you might want to add something like the following to *the beggining*
;; of your ``.emacs`` (if you want behavior that's more similar to stand-alone
;; ipython, you can change ``meta p`` etc. for ``control p``)::
;;
;; (require 'comint)
;; (define-key comint-mode-map [(meta p)]
;; 'comint-previous-matching-input-from-input)
;; (define-key comint-mode-map [(meta n)]
;; 'comint-next-matching-input-from-input)
;; (define-key comint-mode-map [(control meta n)]
;; 'comint-next-input)
;; (define-key comint-mode-map [(control meta p)]
;; 'comint-previous-input)
;;
;; - Be aware that if you customize py-python-command previously, this value
;; will override what ipython.el does (because loading the customization
;; variables comes later).
;;
;; Please send comments and feedback to the ipython-list
;; (<ipython-user@scipy.org>) where I (a.s.) or someone else will try to
;; answer them (it helps if you specify your emacs version, OS etc;
;; familiarity with <http://www.catb.org/~esr/faqs/smart-questions.html> might
;; speed up things further).
;;
;; Footnotes:
;;
;; [1] If you don't know what `load-path' is, C-h v load-path will tell
;; you; if required you can also add a new directory. So assuming that
;; ipython.el resides in ~/el/, put this in your emacs:
;;
;;
;; (add-to-list 'load-path "~/el")
;; (setq ipython-command "/some-path/ipython")
;; (require 'ipython)
;;
;;
;;
;;
;; TODO:
;; - do autocompletion properly
;; - implement a proper switching between python interpreters
;;
;; BUGS:
;; - neither::
;;
;; (py-shell "-c print 'FOOBAR'")
;;
;; nor::
;;
;; (let ((py-python-command-args (append py-python-command-args
;; '("-c" "print 'FOOBAR'"))))
;; (py-shell))
;;
;; seem to print anything as they should
;;
;; - look into init priority issues with `py-python-command' (if it's set
;; via custom)
;;; Code
(require 'cl)
(require 'shell)
(require 'executable)
(require 'ansi-color)
(defcustom ipython-command "ipython"
"*Shell command used to start ipython."
:type 'string
:group 'python)
;; Users can set this to nil
(defvar py-shell-initial-switch-buffers t
"If nil, don't switch to the *Python* buffer on the first call to
`py-shell'.")
(defvar ipython-backup-of-py-python-command nil
"HACK")
(defvar ipython-de-input-prompt-regexp "\\(?:
In \\[[0-9]+\\]: *.*
----+> \\(.*
\\)[\n]?\\)\\|\\(?:
In \\[[0-9]+\\]: *\\(.*
\\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: *\\(.*
\\)"
"A regular expression to match the IPython input prompt and the python
command after it. The first match group is for a command that is rewritten,
the second for a 'normal' command, and the third for a multiline command.")
(defvar ipython-de-output-prompt-regexp "^Out\\[[0-9]+\\]: "
"A regular expression to match the output prompt of IPython.")
(if (not (executable-find ipython-command))
(message (format "Can't find executable %s - ipython.el *NOT* activated!!!"
ipython-command))
;; XXX load python-mode, so that we can screw around with its variables
;; this has the disadvantage that python-mode is loaded even if no
;; python-file is ever edited etc. but it means that `py-shell' works
;; without loading a python-file first. Obviously screwing around with
;; python-mode's variables like this is a mess, but well.
(require 'python-mode)
;; turn on ansi colors for ipython and activate completion
(defun ipython-shell-hook ()
;; the following is to synchronize dir-changes
(make-local-variable 'shell-dirstack)
(setq shell-dirstack nil)
(make-local-variable 'shell-last-dir)
(setq shell-last-dir nil)
(make-local-variable 'shell-dirtrackp)
(setq shell-dirtrackp t)
(add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
(ansi-color-for-comint-mode-on)
(define-key py-shell-map [tab] 'ipython-complete)
;; Add this so that tab-completion works both in X11 frames and inside
;; terminals (such as when emacs is called with -nw).
(define-key py-shell-map "\t" 'ipython-complete)
;;XXX this is really just a cheap hack, it only completes symbols in the
;;interactive session -- useful nonetheless.
(define-key py-mode-map [(meta tab)] 'ipython-complete)
)
(add-hook 'py-shell-hook 'ipython-shell-hook)
;; Regular expression that describes tracebacks for IPython in context and
;; verbose mode.
;;Adapt python-mode settings for ipython.
;; (this works for %xmode 'verbose' or 'context')
;; XXX putative regexps for syntax errors; unfortunately the
;; current python-mode traceback-line-re scheme is too primitive,
;; so it's either matching syntax errors, *or* everything else
;; (XXX: should ask Fernando for a change)
;;"^ File \"\\(.*?\\)\", line \\([0-9]+\\).*\n.*\n.*\nSyntaxError:"
;;^ File \"\\(.*?\\)\", line \\([0-9]+\\)"
(setq py-traceback-line-re
"\\(^[^\t >].+?\\.py\\).*\n +[0-9]+[^\00]*?\n-+> \\([0-9]+\\)+")
;; Recognize the ipython pdb, whose prompt is 'ipdb>' or 'ipydb>'
;;instead of '(Pdb)'
(setq py-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]y?db[>)]+ ")
(setq pydb-pydbtrack-input-prompt "\n[(]*ipydb[>)]+ ")
(setq py-shell-input-prompt-1-regexp "^In \\[[0-9]+\\]: *"
py-shell-input-prompt-2-regexp "^ [.][.][.]+: *" )
;; select a suitable color-scheme
(unless (member "-colors" py-python-command-args)
(setq py-python-command-args
(nconc py-python-command-args
(list "-colors"
(cond
((eq frame-background-mode 'dark)
"Linux")
((eq frame-background-mode 'light)
"LightBG")
(t ; default (backg-mode isn't always set by XEmacs)
"LightBG"))))))
(unless (equal ipython-backup-of-py-python-command py-python-command)
(setq ipython-backup-of-py-python-command py-python-command))
(setq py-python-command ipython-command))
;; MODIFY py-shell so that it loads the editing history
(defadvice py-shell (around py-shell-with-history)
"Add persistent command-history support (in
$PYTHONHISTORY (or \"~/.ipython/history\", if we use IPython)). Also, if
`py-shell-initial-switch-buffers' is nil, it only switches to *Python* if that
buffer already exists."
(if (comint-check-proc "*Python*")
ad-do-it
(setq comint-input-ring-file-name
(if (string-equal py-python-command ipython-command)
(concat (or (getenv "IPYTHONDIR") "~/.ipython") "/history")
(or (getenv "PYTHONHISTORY") "~/.python-history.py")))
(comint-read-input-ring t)
(let ((buf (current-buffer)))
ad-do-it
(unless py-shell-initial-switch-buffers
(switch-to-buffer-other-window buf)))))
(ad-activate 'py-shell)
;; (defadvice py-execute-region (before py-execute-buffer-ensure-process)
;; "HACK: test that ipython is already running before executing something.
;; Doing this properly seems not worth the bother (unless people actually
;; request it)."
;; (unless (comint-check-proc "*Python*")
;; (error "Sorry you have to first do M-x py-shell to send something to ipython.")))
;; (ad-activate 'py-execute-region)
(defadvice py-execute-region (around py-execute-buffer-ensure-process)
"HACK: if `py-shell' is not active or ASYNC is explicitly desired, fall back
to python instead of ipython."
(let ((py-which-shell (if (and (comint-check-proc "*Python*") (not async))
py-python-command
ipython-backup-of-py-python-command)))
ad-do-it))
(ad-activate 'py-execute-region)
(defun ipython-to-doctest (start end)
"Transform a cut-and-pasted bit from an IPython session into something that
looks like it came from a normal interactive python session, so that it can
be used in doctests. Example:
In [1]: import sys
In [2]: sys.stdout.write 'Hi!\n'
------> sys.stdout.write ('Hi!\n')
Hi!
In [3]: 3 + 4
Out[3]: 7
gets converted to:
>>> import sys
>>> sys.stdout.write ('Hi!\n')
Hi!
>>> 3 + 4
7
"
(interactive "*r\n")
;(message (format "###DEBUG s:%de:%d" start end))
(save-excursion
(save-match-data
;; replace ``In [3]: bla`` with ``>>> bla`` and
;; ``... : bla`` with ``... bla``
(goto-char start)
(while (re-search-forward ipython-de-input-prompt-regexp end t)
;(message "finding 1")
(cond ((match-string 3) ;continued
(replace-match "... \\3" t nil))
(t
(replace-match ">>> \\1\\2" t nil))))
;; replace ``
(goto-char start)
(while (re-search-forward ipython-de-output-prompt-regexp end t)
(replace-match "" t nil)))))
(defvar ipython-completion-command-string
"print ';'.join(__IP.Completer.all_completions('%s')) #PYTHON-MODE SILENT\n"
"The string send to ipython to query for all possible completions")
;; xemacs doesn't have `comint-preoutput-filter-functions' so we'll try the
;; following wonderful hack to work around this case
(if (featurep 'xemacs)
;;xemacs
(defun ipython-complete ()
"Try to complete the python symbol before point. Only knows about the stuff
in the current *Python* session."
(interactive)
(let* ((ugly-return nil)
(sep ";")
(python-process (or (get-buffer-process (current-buffer))
;XXX hack for .py buffers
(get-process py-which-bufname)))
;; XXX currently we go backwards to find the beginning of an
;; expression part; a more powerful approach in the future might be
;; to let ipython have the complete line, so that context can be used
;; to do things like filename completion etc.
(beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
(point)))
(end (point))
(pattern (buffer-substring-no-properties beg end))
(completions nil)
(completion-table nil)
completion
(comint-output-filter-functions
(append comint-output-filter-functions
'(ansi-color-filter-apply
(lambda (string)
;(message (format "DEBUG filtering: %s" string))
(setq ugly-return (concat ugly-return string))
(delete-region comint-last-output-start
(process-mark (get-buffer-process (current-buffer)))))))))
;(message (format "#DEBUG pattern: '%s'" pattern))
(process-send-string python-process
(format ipython-completion-command-string pattern))
(accept-process-output python-process)
;(message (format "DEBUG return: %s" ugly-return))
(setq completions
(split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
(setq completion-table (loop for str in completions
collect (list str nil)))
(setq completion (try-completion pattern completion-table))
(cond ((eq completion t))
((null completion)
(message "Can't find completion for \"%s\"" pattern)
(ding))
((not (string= pattern completion))
(delete-region beg end)
(insert completion))
(t
(message "Making completion list...")
(with-output-to-temp-buffer "*Python Completions*"
(display-completion-list (all-completions pattern completion-table)))
(message "Making completion list...%s" "done")))))
;; emacs
(defun ipython-complete ()
"Try to complete the python symbol before point. Only knows about the stuff
in the current *Python* session."
(interactive)
(let* ((ugly-return nil)
(sep ";")
(python-process (or (get-buffer-process (current-buffer))
;XXX hack for .py buffers
(get-process py-which-bufname)))
;; XXX currently we go backwards to find the beginning of an
;; expression part; a more powerful approach in the future might be
;; to let ipython have the complete line, so that context can be used
;; to do things like filename completion etc.
(beg (save-excursion (skip-chars-backward "a-z0-9A-Z_./" (point-at-bol))
(point)))
(end (point))
(pattern (buffer-substring-no-properties beg end))
(completions nil)
(completion-table nil)
completion
(comint-preoutput-filter-functions
(append comint-preoutput-filter-functions
'(ansi-color-filter-apply
(lambda (string)
(setq ugly-return (concat ugly-return string))
"")))))
(process-send-string python-process
(format ipython-completion-command-string pattern))
(accept-process-output python-process)
(setq completions
(split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
;(message (format "DEBUG completions: %S" completions))
(setq completion-table (loop for str in completions
collect (list str nil)))
(setq completion (try-completion pattern completion-table))
(cond ((eq completion t))
((null completion)
(message "Can't find completion for \"%s\"" pattern)
(ding))
((not (string= pattern completion))
(delete-region beg end)
(insert completion))
(t
(message "Making completion list...")
(with-output-to-temp-buffer "*IPython Completions*"
(display-completion-list (all-completions pattern completion-table)))
(message "Making completion list...%s" "done")))))
)
;;; autoindent support: patch sent in by Jin Liu <m.liu.jin@gmail.com>,
;;; originally written by doxgen@newsmth.net
;;; Minor modifications by fperez for xemacs compatibility.
(defvar ipython-autoindent t
"If non-nil, enable autoindent for IPython shell through python-mode.")
(defvar ipython-indenting-buffer-name "*IPython Indentation Calculation*"
"Temporary buffer for indenting multiline statement.")
(defun ipython-get-indenting-buffer ()
"Return a temporary buffer set in python-mode. Create one if necessary."
(let ((buf (get-buffer-create ipython-indenting-buffer-name)))
(set-buffer buf)
(unless (eq major-mode 'python-mode)
(python-mode))
buf))
(defvar ipython-indentation-string nil
"Indentation for the next line in a multiline statement.")
(defun ipython-send-and-indent ()
"Send the current line to IPython, and calculate the indentation for
the next line."
(interactive)
(if ipython-autoindent
(let ((line (buffer-substring (point-at-bol) (point)))
(after-prompt1)
(after-prompt2))
(save-excursion
(comint-bol t)
(if (looking-at py-shell-input-prompt-1-regexp)
(setq after-prompt1 t)
(setq after-prompt2 (looking-at py-shell-input-prompt-2-regexp)))
(with-current-buffer (ipython-get-indenting-buffer)
(when after-prompt1
(erase-buffer))
(when (or after-prompt1 after-prompt2)
(delete-region (point-at-bol) (point))
(insert line)
(newline-and-indent))))))
;; send input line to ipython interpreter
(comint-send-input))
(defun ipython-indentation-hook (string)
"Insert indentation string if py-shell-input-prompt-2-regexp
matches last process output."
(let* ((start-marker (or comint-last-output-start
(point-min-marker)))
(end-marker (process-mark (get-buffer-process (current-buffer))))
(text (ansi-color-filter-apply (buffer-substring start-marker end-marker))))
;; XXX if `text' matches both pattern, it MUST be the last prompt-2
(when (and (string-match py-shell-input-prompt-2-regexp text)
(not (string-match "\n$" text)))
(with-current-buffer (ipython-get-indenting-buffer)
(setq ipython-indentation-string
(buffer-substring (point-at-bol) (point))))
(goto-char end-marker)
(insert ipython-indentation-string)
(setq ipython-indentation-string nil))))
(add-hook 'py-shell-hook
(lambda ()
(add-hook 'comint-output-filter-functions
'ipython-indentation-hook)))
(define-key py-shell-map (kbd "RET") 'ipython-send-and-indent)
;;; / end autoindent support
(provide 'ipython)

325
conf/emacs.d/php-mode.el Normal file
View File

@ -0,0 +1,325 @@
;;; php-mode.el -- major mode for editing PHP source files
;; Author: Fred Yankowski <fcy@acm.org>
;; Keywords: PHP, PHP3, languages
;; $Id: php-mode.el,v 1.31 2002/04/12 19:34:11 fred Exp $
;; php-mode.el is Copyright (c) 1999,2000 by Fred Yankowski <fcy@acm.org>
;;
;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2,
;; or (at your option) any later version.
;;
;; This is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public
;; License as the file COPYING. If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary;
;;
;; PHP mode is a major mode for editing the PHP programming language
;; <www.php.net>. It is mostly concerned with setting up syntax
;; coloring via the font-lock library. The most recent version can be
;; found at <http://www.ontosys.com/src/php-mode.el>.
;;
;; To use PHP mode, add this to your ~/.emacs file:
;;
;; (autoload 'php-mode "php-mode" "PHP editing mode" t)
;; (add-to-list 'auto-mode-alist '("\\.php3\\'" . php-mode))
;;
;; Repeat the second line for any other filename suffixes that you
;; want to associate with PHP mode. Then, install this file in some
;; directory in your Emacs load-path and run byte-compile-file on it.
;; Voila'.
;;
;; If php-mode does not colorize the text of your PHP code, you may need
;; to tweak the supporting font-lock mode a bit. Here is more code for
;; .emacs that demonstrates one approach:
;;
;; (cond (window-system
;; (require 'font-lock)
;; (setq font-lock-support-mode 'lazy-lock-mode)
;; (setq font-lock-maximum-decoration t)
;; (global-font-lock-mode t)
;; ))
;;
;; The above configuration treats the entire file as being PHP code,
;; causing interspersed HTML code to be handled very poorly. An
;; option that provides very satisfying results is to use php-mode in
;; conjuction with the Multiple Major Modes package. Get that package
;; from mmm-mode.sourceforge.net, install it, and use something like
;; the following in your .emacs file to configure it:
;;
;; (require 'mmm-mode)
;; (setq mmm-global-mode 'maybe)
;; (mmm-add-mode-ext-class nil "\\.php3?\\'" 'html-php)
;; (mmm-add-classes
;; '((html-php
;; :submode php-mode
;; :front "<\\?\\(php\\)?"
;; :back "\\?>"
;; )))
;; (autoload 'php-mode "php-mode" "PHP editing mode" t)
;; (add-to-list 'auto-mode-alist '("\\.php3?\\'" . sgml-html-mode))
;;
;; Note that .php files now have the PSGML/HTML mode as their major
;; mode and PHP mode as a submode applied by the MMM minor mode. You
;; can force a file to get PHP mode as a submode by starting the file
;; with a line like this:
;;
;; <?php // -*- mmm-classes: html-php -*-
;;
;; For files with HTML and PHP code that generates some of the
;; top-level elements of the HTML document, the following convinces
;; PSGML to treat the HTML content as if it were in the context of the
;; BODY element of an HTML document:
;;
;; <?php // -*- sgml-parent-document: ("dummy.html" "html" "body" ()) -*-
;;
;; This depends on having a dummy.html file that contains just the
;; DOCTYPE element for the desired HTML document type. See the PSGML
;; info file for more help.
;;
;; The font-coloring applied by the PSGML/HTML mode may collide with
;; the coloring applied by PHP mode. I got around this by removing
;; the list element for 'pi' in the sgml-markup-faces value.
;;
;; On a completely different subject... Xemacs users may want to
;; install the xemacs-devel package, which is reported to provide a
;; faster regexp-opt function than the one defined below.
;;
;; * A note about indenting problems
;; Code outside of any function will be indented strangely because
;; php-mode is using the indenting logic from c-mode, which expects
;; only declarations at the top level. I haven't figured out how to
;; fix that problem. One workaround (if you're desperate) is to put
;; your top-level PHP code inside a block; inside a pair of curly
;; brackets, that is.
;;
;; I also encounter strange indenting problems when php-mode is used
;; along with sgml-html mode, in that the quantum of indenting seems
;; to follow that of sgml-html mode even when inside a PHP code
;; segment. Puzzling.
;; Xemacs users report that regexp-opt is not defined.
(eval-when-compile
(unless (fboundp 'regexp-opt)
(defun regexp-opt (strings paren)
(let ((open-paren (if paren "\\(" ""))
(close-paren (if paren "\\)" "")))
(concat open-paren
(mapconcat 'regexp-quote strings "\\|")
close-paren)))))
(defconst xemacsp (string-match "Lucid\\|XEmacs" emacs-version) "\
Non nil if using XEmacs.")
(let* ((php-keywords
(eval-when-compile
(regexp-opt
'("and" "as" "break" "case" "continue" "default" "do" "echo"
"else" "elseif" "endfor" "endforeach" "endif" "endswitch" "endwhile" "exit"
"extends" "for" "foreach" "global" "if" "include"
"or" "require" "return" "static" "switch" "then"
"var" "while" "xor") t)))
;; "class", "new" and "extends" get special treatment below
(php-constants
(eval-when-compile
(regexp-opt
'("false" "true"
"E_ERROR" "E_WARNING" "E_PARSE" "E_NOTICE"
"E_CORE_ERROR" "E_CORE_WARNING"
"E_COMPILE_ERROR" "E_COMPILE_WARNING"
"E_USER_ERROR" "E_USER_WARNING" "E_USER_NOTICE"
"E_ALL"
"NULL"
"PHP_OS" "PHP_VERSION"
"__LINE__" "__FILE__") t)))
(php-types
(eval-when-compile
(regexp-opt '("array" "bool" "char" "double" "float" "int"
"integer" "long" "mixed" "object" "real"
"string" "void") t)))
)
(defconst php-font-lock-keywords-1
(list
'("^[ \t]*\\(class\\)[ \t]*\\(\\sw+\\)?"
(1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
'("^[ \t]*\\(function\\)[ \t]*\\(\\sw+\\)?"
(1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
))
(defconst php-font-lock-keywords-2
(append php-font-lock-keywords-1
(list
(concat "\\<\\(" php-keywords "\\)\\>")
`(,(concat "\\<\\(" php-constants "\\)\\>")
1 font-lock-constant-face)
;; handle several words specially, to include following word,
;; thereby excluding it from unknown-symbol checks later
'("\\<\\(new\\|extends\\)\\s-+\\$?\\(\\sw+\\)"
(1 font-lock-keyword-face) (2 default))
;; treat 'print' as keyword only when not used like a function name
'("\\<print\\s-*(" . default)
'("\\<print\\>" . font-lock-keyword-face)
'("<\\?\\(php\\)?" . font-lock-constant-face)
'("\\?>" . font-lock-constant-face)
)))
(defconst php-font-lock-keywords-3
(append
(list
;; warn about 'new FooBar()' -- empty parens are tempting but wrong
'("\\<\\(new\\)\\s-+\\(\\sw+\\)\\((\\s-*)\\)"
(1 font-lock-keyword-face) (2 default) (3 font-lock-warning-face))
)
php-font-lock-keywords-2
(list
;'("</?\\sw+[^>]*>" . font-lock-constant-face) ; <word> or </word>
;; warn about '$' immediately after ->
'("\\$\\sw+->\\s-*\\(\\$\\)\\(\\sw+\\)"
(1 font-lock-warning-face) (2 default))
;; warn about $word.word -- it could be a valid concatenation,
;; but without any spaces we'll assume $word->word was meant.
'("\\$\\sw+\\(\\.\\)\\sw"
1 font-lock-warning-face)
;; exclude casts from bare-word treatment
`(,(concat "(\\(" php-types "\\))")
1 default)
;; highlight variables, as suggested by Trond Aasan
'("[$*]{?\\(\\sw+\\)" 1 font-lock-variable-name-face)
;; Warn about bare symbols, those that don't follow '$' or precede
;; '('. But first explicitly mark some words that are OK.
'("->\\s-*\\sw+" . default) ; -->word
'("\\$\\sw+" . default) ; $word
'("\\<\\sw+\\s-*[[(]" . default) ; word( or word[
'("\\<[0-9]+" . default) ; number (also matches word)
'("\\<\\sw+\\>" . font-lock-warning-face)
;; Warn about ==> instead of => (why do I *do* that?)
'("==+>" . font-lock-warning-face)
))))
(defconst php-font-lock-syntactic-keywords
(if xemacsp nil
;; Mark shell-style comments. font-lock handles this in a
;; separate pass from normal syntactic scanning (somehow), so we
;; get a chance to mark these in addition to C and C++ style
;; comments. This only works in GNU Emacs, not Xemacs 21 which
;; seems to ignore this same code if we try to use it.
(list
;; Mark _all_ # chars as being comment-start. That will be
;; ignored when inside a quoted string.
'("\\(\#\\)"
(1 (11 . nil)))
;; Mark all newlines ending a line with # as being comment-end.
;; This causes a problem, premature end-of-comment, when '#'
;; appears inside a multiline C-style comment. Oh well.
'("#.*\\([\n]\\)"
(1 (12 . nil)))
)))
;; Define the imenu-generic-expression for PHP mode.
;; To use, execute M-x imenu, then click on Functions or Classes,
;; then select given function/class name to go to its definition.
;; [Contributed by Gerrit Riessen]
(defvar php-imenu-generic-expression
'(
("Functions"
"\\(^\\|\\s-\\)function\\s-+\\(\\sw+\\)\\s-*(" 2)
("Classes"
"\\(^\\|\\s-\\)class\\s-+\\(\\sw+\\)\\s-*" 2)
)
"Imenu generic expression for PHP Mode. See `imenu-generic-expression'."
)
(define-derived-mode php-mode c-mode "PHP"
"A major mode for editing PHP source code.
Key bindings:
\\{php-mode-map}"
(setq comment-start "// "
comment-end ""
comment-start-skip "// *")
(defvar php-mode-syntax-table php-mode-syntax-table)
(modify-syntax-entry ?_ "w" php-mode-syntax-table)
;; underscore considered part of word
(modify-syntax-entry ?$ "." php-mode-syntax-table)
;; dollar-sign considered punctuation, not part of word
(if xemacsp (progn
(modify-syntax-entry ?# "< b" php-mode-syntax-table)
(modify-syntax-entry ?\n "> b" php-mode-syntax-table)))
;; The above causes Xemacs to handle shell-style comments correctly,
;; but fails to work in GNU Emacs which fails to interpret \n as the
;; end of the comment.
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults
'((php-font-lock-keywords-1
php-font-lock-keywords-2
;; Comment-out the next line if the font-coloring is too
;; extreme/ugly for you.
php-font-lock-keywords-3
)
nil ; KEYWORDS-ONLY
T ; CASE-FOLD
nil ; SYNTAX-ALIST
nil ; SYNTAX-BEGIN
(font-lock-syntactic-keywords . php-font-lock-syntactic-keywords)))
(make-local-variable 'require-final-newline)
(setq require-final-newline nil)
(make-local-variable 'next-line-add-newlines)
(setq next-line-add-newlines nil)
;; Will not force newline at end of file. Such newlines can cause
;; trouble if the PHP file is included in another file before calls
;; to header() or cookie().
(make-local-variable 'imenu-generic-expression)
(make-local-variable 'imenu-case-fold-search)
(setq
imenu-generic-expression php-imenu-generic-expression
imenu-case-fold-search nil)
)
(unless (boundp 'default)
(defvar default 'default))
;; Created "default" symbol for GNU Emacs so that both Xemacs and GNU
;; emacs can refer to the default face by a variable named "default".
(unless (boundp 'font-lock-keyword-face)
(copy-face 'bold 'font-lock-keyword-face))
;; font-lock-keyword-face is sure to be valid now, assuming that the
;; bold face exists
(unless (boundp 'font-lock-constant-face)
(copy-face 'font-lock-keyword-face 'font-lock-constant-face))
;; font-lock-constant-face now exists, which Xemacs doesn't seem to have
;; by default
(provide 'php-mode)

View File

@ -0,0 +1,50 @@
;;; Complete symbols at point using Pymacs.
;; Copyright (C) 2007 Skip Montanaro
;; Author: Skip Montanaro
;; Maintainer: skip@pobox.com
;; Created: Oct 2004
;; Keywords: python pymacs emacs
;; This software is provided as-is, without express or implied warranty.
;; Permission to use, copy, modify, distribute or sell this software,
;; without fee, for any purpose and by any individual or organization, is
;; hereby granted, provided that the above copyright notice and this
;; paragraph appear in all copies.
;; Along with pycomplete.py this file allows programmers to complete Python
;; symbols within the current buffer. See pycomplete.py for the Python side
;; of things and a short description of what to expect.
(require 'pymacs)
(require 'python-mode)
(pymacs-load "pycomplete")
(defun py-complete ()
(interactive)
(let ((pymacs-forget-mutability t))
(insert (pycomplete-pycomplete (py-symbol-near-point)
(py-find-global-imports)))))
(defun py-find-global-imports ()
(save-excursion
(let (first-class-or-def imports)
(goto-char (point-min))
(setq first-class-or-def
(re-search-forward "^ *\\(def\\|class\\) " nil t))
(goto-char (point-min))
(setq imports nil)
(while (re-search-forward
"^\\(import \\|from \\([A-Za-z_][A-Za-z_0-9]*\\) import \\).*"
nil t)
(setq imports (append imports
(list (buffer-substring
(match-beginning 0)
(match-end 0))))))
imports)))
(define-key py-mode-map "\M-\C-i" 'py-complete)
(provide 'pycomplete)

110
conf/emacs.d/pycomplete.py Normal file
View File

@ -0,0 +1,110 @@
"""
Python dot expression completion using Pymacs.
This almost certainly needs work, but if you add
(require 'pycomplete)
to your .xemacs/init.el file (untried w/ GNU Emacs so far) and have Pymacs
installed, when you hit M-TAB it will try to complete the dot expression
before point. For example, given this import at the top of the file:
import time
typing "time.cl" then hitting M-TAB should complete "time.clock".
This is unlikely to be done the way Emacs completion ought to be done, but
it's a start. Perhaps someone with more Emacs mojo can take this stuff and
do it right.
See pycomplete.el for the Emacs Lisp side of things.
"""
# Author: Skip Montanaro
# Maintainer: skip@pobox.com
# Created: Oct 2004
# Keywords: python pymacs emacs
# This software is provided as-is, without express or implied warranty.
# Permission to use, copy, modify, distribute or sell this software, without
# fee, for any purpose and by any individual or organization, is hereby
# granted, provided that the above copyright notice and this paragraph
# appear in all copies.
# Along with pycomplete.el this file allows programmers to complete Python
# symbols within the current buffer.
import sys
import os.path
try:
x = set
except NameError:
from sets import Set as set
else:
del x
def get_all_completions(s, imports=None):
"""Return contextual completion of s (string of >= zero chars).
If given, imports is a list of import statements to be executed first.
"""
locald = {}
if imports is not None:
for stmt in imports:
try:
exec stmt in globals(), locald
except TypeError:
raise TypeError, "invalid type: %s" % stmt
dots = s.split(".")
if not s or len(dots) == 1:
keys = set()
keys.update(locald.keys())
keys.update(globals().keys())
import __builtin__
keys.update(dir(__builtin__))
keys = list(keys)
keys.sort()
if s:
return [k for k in keys if k.startswith(s)]
else:
return keys
sym = None
for i in range(1, len(dots)):
s = ".".join(dots[:i])
try:
sym = eval(s, globals(), locald)
except NameError:
try:
sym = __import__(s, globals(), locald, [])
except ImportError:
return []
if sym is not None:
s = dots[-1]
return [k for k in dir(sym) if k.startswith(s)]
def pycomplete(s, imports=None):
completions = get_all_completions(s, imports)
dots = s.split(".")
return os.path.commonprefix([k[len(dots[-1]):] for k in completions])
if __name__ == "__main__":
print "<empty> ->", pycomplete("")
print "sys.get ->", pycomplete("sys.get")
print "sy ->", pycomplete("sy")
print "sy (sys in context) ->", pycomplete("sy", imports=["import sys"])
print "foo. ->", pycomplete("foo.")
print "Enc (email * imported) ->",
print pycomplete("Enc", imports=["from email import *"])
print "E (email * imported) ->",
print pycomplete("E", imports=["from email import *"])
print "Enc ->", pycomplete("Enc")
print "E ->", pycomplete("E")
# Local Variables :
# pymacs-auto-reload : t
# End :

757
conf/emacs.d/pymacs.el Normal file
View File

@ -0,0 +1,757 @@
;;; Interface between Emacs Lisp and Python - Lisp part. -*- emacs-lisp -*-
;;; Copyright © 2001, 2002, 2003 Progiciels Bourbeau-Pinard inc.
;;; François Pinard <pinard@iro.umontreal.ca>, 2001.
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2, or (at your option)
;;; any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, write to the Free Software Foundation,
;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
;;; Portability stunts.
(defvar pymacs-use-hash-tables
(and (fboundp 'make-hash-table) (fboundp 'gethash) (fboundp 'puthash))
"Set to t if hash tables are available.")
(eval-and-compile
;; pymacs-cancel-timer
(defalias 'pymacs-cancel-timer
(cond ((fboundp 'cancel-timer) 'cancel-timer)
;; XEmacs case - yet having post-gc-hook, this is unused.
((fboundp 'delete-itimer) 'delete-itimer)
(t 'ignore)))
;; pymacs-kill-without-query
(if (fboundp 'set-process-query-on-exit-flag)
(defun pymacs-kill-without-query (process)
"Tell recent Emacs how to quickly destroy PROCESS while exiting."
(set-process-query-on-exit-flag process nil))
(defalias 'pymacs-kill-without-query
(if (fboundp 'process-kill-without-query-process)
'process-kill-without-query-process
'ignore)))
;; pymacs-multibyte-string-p
(cond ((fboundp 'multibyte-string-p)
(defalias 'pymacs-multibyte-string-p 'multibyte-string-p))
((fboundp 'find-charset-string)
(defun pymacs-multibyte-string-p (string)
"Tell XEmacs if STRING should be handled as multibyte."
(not (member (find-charset-string string) '(nil (ascii))))))
(t
; Tell XEmacs that STRING is unibyte, when Mule is not around!
(defalias 'pymacs-multibyte-string-p 'ignore)))
;; pymacs-report-error
(defalias 'pymacs-report-error (symbol-function 'error))
;; pymacs-set-buffer-multibyte
(if (fboundp 'set-buffer-multibyte)
(defalias 'pymacs-set-buffer-multibyte 'set-buffer-multibyte)
(defun pymacs-set-buffer-multibyte (flag)
"For use in Emacs 20.2 or earlier. Under XEmacs: no operation."
(setq enable-multibyte-characters flag)))
;; pymacs-timerp
(defalias 'pymacs-timerp
(cond ((fboundp 'timerp) 'timerp)
; XEmacs case - yet having post-gc-hook, this is unused.
((fboundp 'itimerp) 'itimerp)
(t 'ignore)))
)
;;; Published variables and functions.
(defvar pymacs-load-path nil
"List of additional directories to search for Python modules.
The directories listed will be searched first, in the order given.")
(defvar pymacs-trace-transit '(5000 . 30000)
"Keep the communication buffer growing, for debugging.
When this variable is nil, the `*Pymacs*' communication buffer gets erased
before each communication round-trip. Setting it to `t' guarantees that
the full communication is saved, which is useful for debugging.
It could also be given as (KEEP . LIMIT): whenever the buffer exceeds LIMIT
bytes, it is reduced to approximately KEEP bytes.")
(defvar pymacs-forget-mutability nil
"Transmit copies to Python instead of Lisp handles, as much as possible.
When this variable is nil, most mutable objects are transmitted as handles.
This variable is meant to be temporarily rebound to force copies.")
(defvar pymacs-mutable-strings nil
"Prefer transmitting Lisp strings to Python as handles.
When this variable is nil, strings are transmitted as copies, and the
Python side thus has no way for modifying the original Lisp strings.
This variable is ignored whenever `forget-mutability' is set.")
(defvar pymacs-timeout-at-start 30
"Maximum reasonable time, in seconds, for starting the Pymacs helper.
A machine should be pretty loaded before one needs to increment this.")
(defvar pymacs-timeout-at-reply 5
"Expected maximum time, in seconds, to get the first line of a reply.
The status of the Pymacs helper is checked at every such timeout.")
(defvar pymacs-timeout-at-line 2
"Expected maximum time, in seconds, to get another line of a reply.
The status of the Pymacs helper is checked at every such timeout.")
(defvar pymacs-auto-restart 'ask
"Should the Pymacs helper be restarted whenever it dies?
Possible values are nil, t or ask.")
(defvar pymacs-dreadful-zombies nil
"If zombies should trigger hard errors, whenever they get called.
If `nil', calling a zombie will merely produce a diagnostic message.")
(defun pymacs-load (module &optional prefix noerror)
"Import the Python module named MODULE into Emacs.
Each function in the Python module is made available as an Emacs function.
The Lisp name of each function is the concatenation of PREFIX with
the Python name, in which underlines are replaced by dashes. If PREFIX is
not given, it defaults to MODULE followed by a dash.
If NOERROR is not nil, do not raise error when the module is not found."
(interactive
(let* ((module (read-string "Python module? "))
(default (concat (car (last (split-string module "\\."))) "-"))
(prefix (read-string (format "Prefix? [%s] " default)
nil nil default)))
(list module prefix)))
(message "Pymacs loading %s..." module)
(let ((lisp-code (pymacs-call "pymacs_load_helper" module prefix)))
(cond (lisp-code (let ((result (eval lisp-code)))
(message "Pymacs loading %s...done" module)
result))
(noerror (message "Pymacs loading %s...failed" module) nil)
(t (pymacs-report-error "Pymacs loading %s...failed" module)))))
(defun pymacs-eval (text)
"Compile TEXT as a Python expression, and return its value."
(interactive "sPython expression? ")
(let ((value (pymacs-serve-until-reply "eval" `(princ ,text))))
(when (interactive-p)
(message "%S" value))
value))
(defun pymacs-exec (text)
"Compile and execute TEXT as a sequence of Python statements.
This functionality is experimental, and does not appear to be useful."
(interactive "sPython statements? ")
(let ((value (pymacs-serve-until-reply "exec" `(princ ,text))))
(when (interactive-p)
(message "%S" value))
value))
(defun pymacs-call (function &rest arguments)
"Return the result of calling a Python function FUNCTION over ARGUMENTS.
FUNCTION is a string denoting the Python function, ARGUMENTS are separate
Lisp expressions, one per argument. Immutable Lisp constants are converted
to Python equivalents, other structures are converted into Lisp handles."
(pymacs-serve-until-reply
"eval" `(pymacs-print-for-apply ',function ',arguments)))
(defun pymacs-apply (function arguments)
"Return the result of calling a Python function FUNCTION over ARGUMENTS.
FUNCTION is a string denoting the Python function, ARGUMENTS is a list of
Lisp expressions. Immutable Lisp constants are converted to Python
equivalents, other structures are converted into Lisp handles."
(pymacs-serve-until-reply
"eval" `(pymacs-print-for-apply ',function ',arguments)))
;;; Integration details.
;; This page tries to increase the integration seamlessness of Pymacs
;; with the reminder of Emacs.
;; Module "desktop" savagely kills `*Pymacs*' in some circumstances.
;; Let's avoid such damage.
(eval-after-load 'desktop
'(push "\\*Pymacs\\*" desktop-clear-preserve-buffers))
;; Python functions and modules should ideally look like Lisp
;; functions and modules.
(when t
(defadvice documentation (around pymacs-ad-documentation activate)
;; Integration of doc-strings.
(let* ((reference (pymacs-python-reference function))
(python-doc (when reference
(pymacs-eval (format "doc_string(%s)" reference)))))
(if (or reference python-doc)
(setq ad-return-value
(concat
"It interfaces to a Python function.\n\n"
(when python-doc
(if raw python-doc (substitute-command-keys python-doc)))))
ad-do-it)))
(defun pymacs-python-reference (object)
;; Return the text reference of a Python object if possible, else nil.
(when (functionp object)
(let* ((definition (indirect-function object))
(body (and (pymacs-proper-list-p definition)
(> (length definition) 2)
(eq (car definition) 'lambda)
(cddr definition))))
(when (and body (listp (car body)) (eq (caar body) 'interactive))
;; Skip the interactive specification of a function.
(setq body (cdr body)))
(when (and body
;; Advised functions start with a string.
(not (stringp (car body)))
;; Python trampolines hold exactly one expression.
(= (length body) 1))
(let ((expression (car body)))
;; EXPRESSION might now hold something like:
;; (pymacs-apply (quote (pymacs-python . N)) ARGUMENT-LIST)
(when (and (pymacs-proper-list-p expression)
(= (length expression) 3)
(eq (car expression) 'pymacs-apply)
(eq (car (cadr expression)) 'quote))
(setq object (cadr (cadr expression))))))))
(when (eq (car-safe object) 'pymacs-python)
(format "python[%d]" (cdr object)))))
;; The following functions are experimental -- they are not satisfactory yet.
(defun pymacs-file-handler (operation &rest arguments)
;; Integration of load-file, autoload, etc.
;; Emacs might want the contents of some `MODULE.el' which does not exist,
;; while there is a `MODULE.py' or `MODULE.pyc' file in the same directory.
;; The goal is to generate a virtual contents for this `MODULE.el' file, as
;; a set of Lisp trampoline functions to the Python module functions.
;; Python modules can then be loaded or autoloaded as if they were Lisp.
(cond ((and (eq operation 'file-readable-p)
(let ((module (substring (car arguments) 0 -3)))
(or (pymacs-file-force operation arguments)
(file-readable-p (concat module ".py"))
(file-readable-p (concat module ".pyc"))))))
((and (eq operation 'load)
(not (pymacs-file-force
'file-readable-p (list (car arguments))))
(file-readable-p (car arguments)))
(let ((lisp-code (pymacs-call "pymacs_load_helper"
(substring (car arguments) 0 -3)
nil)))
(unless lisp-code
(pymacs-report-error "Python import error"))
(eval lisp-code)))
((and (eq operation 'insert-file-contents)
(not (pymacs-file-force
'file-readable-p (list (car arguments))))
(file-readable-p (car arguments)))
(let ((lisp-code (pymacs-call "pymacs_load_helper"
(substring (car arguments) 0 -3)
nil)))
(unless lisp-code
(pymacs-report-error "Python import error"))
(insert (prin1-to-string lisp-code))))
(t (pymacs-file-force operation arguments))))
(defun pymacs-file-force (operation arguments)
;; Bypass the file handler.
(let ((inhibit-file-name-handlers
(cons 'pymacs-file-handler
(and (eq inhibit-file-name-operation operation)
inhibit-file-name-handlers)))
(inhibit-file-name-operation operation))
(apply operation arguments)))
;(add-to-list 'file-name-handler-alist '("\\.el\\'" . pymacs-file-handler))
;;; Gargabe collection of Python IDs.
;; Python objects which have no Lisp representation are allocated on the
;; Python side as `python[INDEX]', and INDEX is transmitted to Emacs, with
;; the value to use on the Lisp side for it. Whenever Lisp does not need a
;; Python object anymore, it should be freed on the Python side. The
;; following variables and functions are meant to fill this duty.
(defvar pymacs-used-ids nil
"List of received IDs, currently allocated on the Python side.")
;; This is set whenever the Pymacs helper successfully starts, and is
;; also used to later detect the death of a previous helper. If
;; pymacs-use-hash-tables is unset, this variable receives `t' when
;; the helper starts, so the detection works nevertheless.
(defvar pymacs-weak-hash nil
"Weak hash table, meant to find out which IDs are still needed.")
(defvar pymacs-gc-wanted nil
"Flag that it is desirable to clean up unused IDs on the Python side.")
(defvar pymacs-gc-inhibit nil
"Flag that a new Pymacs garbage collection should just not run now.")
(defvar pymacs-gc-timer nil
"Timer to trigger Pymacs garbage collection at regular time intervals.
The timer is used only if `post-gc-hook' is not available.")
(defun pymacs-schedule-gc (&optional xemacs-list)
(unless pymacs-gc-inhibit
(setq pymacs-gc-wanted t)))
(defun pymacs-garbage-collect ()
;; Clean up unused IDs on the Python side.
(when (and pymacs-use-hash-tables (not pymacs-gc-inhibit))
(let ((pymacs-gc-inhibit t)
(pymacs-forget-mutability t)
(ids pymacs-used-ids)
used-ids unused-ids)
(while ids
(let ((id (car ids)))
(setq ids (cdr ids))
(if (gethash id pymacs-weak-hash)
(setq used-ids (cons id used-ids))
(setq unused-ids (cons id unused-ids)))))
(setq pymacs-used-ids used-ids
pymacs-gc-wanted nil)
(when unused-ids
(pymacs-apply "free_python" unused-ids)))))
(defun pymacs-defuns (arguments)
;; Take one argument, a list holding a number of items divisible by 3. The
;; first argument is an INDEX, the second is a NAME, the third is the
;; INTERACTION specification, and so forth. Register Python INDEX with a
;; function with that NAME and INTERACTION on the Lisp side. The strange
;; calling convention is to minimise quoting at call time.
(while (>= (length arguments) 3)
(let ((index (nth 0 arguments))
(name (nth 1 arguments))
(interaction (nth 2 arguments)))
(fset name (pymacs-defun index interaction))
(setq arguments (nthcdr 3 arguments)))))
(defun pymacs-defun (index interaction)
;; Register INDEX on the Lisp side with a Python object that is a function,
;; and return a lambda form calling that function. If the INTERACTION
;; specification is nil, the function is not interactive. Otherwise, the
;; function is interactive, INTERACTION is then either a string, or the
;; index of an argument-less Python function returning the argument list.
(let ((object (pymacs-python index)))
(cond ((null interaction)
`(lambda (&rest arguments)
(pymacs-apply ',object arguments)))
((stringp interaction)
`(lambda (&rest arguments)
(interactive ,interaction)
(pymacs-apply ',object arguments)))
(t `(lambda (&rest arguments)
(interactive (pymacs-call ',(pymacs-python interaction)))
(pymacs-apply ',object arguments))))))
(defun pymacs-python (index)
;; Register on the Lisp side a Python object having INDEX, and return it.
;; The result is meant to be recognised specially by `print-for-eval', and
;; in the function position by `print-for-apply'.
(let ((object (cons 'pymacs-python index)))
(when pymacs-use-hash-tables
(puthash index object pymacs-weak-hash)
(setq pymacs-used-ids (cons index pymacs-used-ids)))
object))
;;; Generating Python code.
;; Many Lisp expressions cannot fully be represented in Python, at least
;; because the object is mutable on the Lisp side. Such objects are allocated
;; somewhere into a vector of handles, and the handle index is used for
;; communication instead of the expression itself.
(defvar pymacs-lisp nil
"Vector of handles to hold transmitted expressions.")
(defvar pymacs-freed-list nil
"List of unallocated indices in Lisp.")
;; When the Python GC is done with a Lisp object, a communication occurs so to
;; free the object on the Lisp side as well.
(defun pymacs-allocate-lisp (expression)
;; This function allocates some handle for an EXPRESSION, and return its
;; index.
(unless pymacs-freed-list
(let* ((previous pymacs-lisp)
(old-size (length previous))
(new-size (if (zerop old-size) 100 (+ old-size (/ old-size 2))))
(counter new-size))
(setq pymacs-lisp (make-vector new-size nil))
(while (> counter 0)
(setq counter (1- counter))
(if (< counter old-size)
(aset pymacs-lisp counter (aref previous counter))
(setq pymacs-freed-list (cons counter pymacs-freed-list))))))
(let ((index (car pymacs-freed-list)))
(setq pymacs-freed-list (cdr pymacs-freed-list))
(aset pymacs-lisp index expression)
index))
(defun pymacs-free-lisp (indices)
;; This function is triggered from Python side for Lisp handles which lost
;; their last reference. These references should be cut on the Lisp side as
;; well, or else, the objects will never be garbage-collected.
(while indices
(let ((index (car indices)))
(aset pymacs-lisp index nil)
(setq pymacs-freed-list (cons index pymacs-freed-list)
indices (cdr indices)))))
(defun pymacs-print-for-apply (function arguments)
;; This function prints a Python expression calling FUNCTION, which is a
;; string naming a Python function, or a Python reference, over all its
;; ARGUMENTS, which are Lisp expressions.
(let ((separator "")
argument)
(if (eq (car-safe function) 'pymacs-python)
(princ (format "python[%d]" (cdr function)))
(princ function))
(princ "(")
(while arguments
(setq argument (car arguments)
arguments (cdr arguments))
(princ separator)
(setq separator ", ")
(pymacs-print-for-eval argument))
(princ ")")))
(defun pymacs-print-for-eval (expression)
;; This function prints a Python expression out of a Lisp EXPRESSION.
(let (done)
(cond ((not expression)
(princ "None")
(setq done t))
((eq expression t)
(princ "True")
(setq done t))
((numberp expression)
(princ expression)
(setq done t))
((stringp expression)
(when (or pymacs-forget-mutability
(not pymacs-mutable-strings))
(let* ((multibyte (pymacs-multibyte-string-p expression))
(text (if multibyte
(encode-coding-string expression 'utf-8)
(copy-sequence expression))))
(set-text-properties 0 (length text) nil text)
(princ (mapconcat 'identity
(split-string (prin1-to-string text) "\n")
"\\n"))
(when multibyte
(princ ".encode('ISO-8859-1').decode('UTF-8')")))
(setq done t)))
((symbolp expression)
(let ((name (symbol-name expression)))
;; The symbol can only be transmitted when in the main oblist.
(when (eq expression (intern-soft name))
(princ "lisp[")
(prin1 name)
(princ "]")
(setq done t))))
((vectorp expression)
(when pymacs-forget-mutability
(let ((limit (length expression))
(counter 0))
(princ "(")
(while (< counter limit)
(unless (zerop counter)
(princ ", "))
(pymacs-print-for-eval (aref expression counter))
(setq counter (1+ counter)))
(when (= limit 1)
(princ ","))
(princ ")")
(setq done t))))
((eq (car-safe expression) 'pymacs-python)
(princ "python[")
(princ (cdr expression))
(princ "]")
(setq done t))
((pymacs-proper-list-p expression)
(when pymacs-forget-mutability
(princ "[")
(pymacs-print-for-eval (car expression))
(while (setq expression (cdr expression))
(princ ", ")
(pymacs-print-for-eval (car expression)))
(princ "]")
(setq done t))))
(unless done
(let ((class (cond ((vectorp expression) "Vector")
((and pymacs-use-hash-tables
(hash-table-p expression))
"Table")
((bufferp expression) "Buffer")
((pymacs-proper-list-p expression) "List")
(t "Lisp"))))
(princ class)
(princ "(")
(princ (pymacs-allocate-lisp expression))
(princ ")")))))
;;; Communication protocol.
(defvar pymacs-transit-buffer nil
"Communication buffer between Emacs and Python.")
;; The principle behind the communication protocol is that it is easier to
;; generate than parse, and that each language already has its own parser.
;; So, the Emacs side generates Python text for the Python side to interpret,
;; while the Python side generates Lisp text for the Lisp side to interpret.
;; About nothing but expressions are transmitted, which are evaluated on
;; arrival. The pseudo `reply' function is meant to signal the final result
;; of a series of exchanges following a request, while the pseudo `error'
;; function is meant to explain why an exchange could not have been completed.
;; The protocol itself is rather simple, and contains human readable text
;; only. A message starts at the beginning of a line in the communication
;; buffer, either with `>' for the Lisp to Python direction, or `<' for the
;; Python to Lisp direction. This is followed by a decimal number giving the
;; length of the message text, a TAB character, and the message text itself.
;; Message direction alternates systematically between messages, it never
;; occurs that two successive messages are sent in the same direction. The
;; first message is received from the Python side, it is `(version VERSION)'.
(defun pymacs-start-services ()
;; This function gets called automatically, as needed.
(let ((buffer (get-buffer-create "*Pymacs*")))
(with-current-buffer buffer
;; Erase the buffer in case some previous incarnation of the
;; Pymacs helper died. Otherwise, the "(goto-char (point-min))"
;; below might not find the proper synchronising reply and later
;; trigger a spurious "Protocol error" diagnostic.
(erase-buffer)
(buffer-disable-undo)
(pymacs-set-buffer-multibyte nil)
(set-buffer-file-coding-system 'raw-text)
(save-match-data
;; Launch the Pymacs helper.
(let ((process
(apply 'start-process "pymacs" buffer
(let ((python (getenv "PYMACS_PYTHON")))
(if (or (null python) (equal python ""))
"python"
python))
"-c" (concat "import sys;"
" from Pymacs.pymacs import main;"
" main(*sys.argv[1:])")
(append
(and (>= emacs-major-version 24) '("-f"))
(mapcar 'expand-file-name pymacs-load-path)))))
(pymacs-kill-without-query process)
;; Receive the synchronising reply.
(while (progn
(goto-char (point-min))
(not (re-search-forward "<\\([0-9]+\\)\t" nil t)))
(unless (accept-process-output process pymacs-timeout-at-start)
(pymacs-report-error
"Pymacs helper did not start within %d seconds"
pymacs-timeout-at-start)))
(let ((marker (process-mark process))
(limit-position (+ (match-end 0)
(string-to-number (match-string 1)))))
(while (< (marker-position marker) limit-position)
(unless (accept-process-output process pymacs-timeout-at-start)
(pymacs-report-error
"Pymacs helper probably was interrupted at start")))))
;; Check that synchronisation occurred.
(goto-char (match-end 0))
(let ((reply (read (current-buffer))))
(if (and (pymacs-proper-list-p reply)
(= (length reply) 2)
(eq (car reply) 'version))
(unless (string-equal (cadr reply) "0.24-beta2")
(pymacs-report-error
"Pymacs Lisp version is 0.24-beta2, Python is %s"
(cadr reply)))
(pymacs-report-error "Pymacs got an invalid initial reply")))))
(if (not pymacs-use-hash-tables)
(setq pymacs-weak-hash t)
(when pymacs-used-ids
;; A previous Pymacs session occurred in this Emacs session,
;; some IDs hang around which do not correspond to anything on
;; the Python side. Python should not recycle such IDs for
;; new objects.
(let ((pymacs-transit-buffer buffer)
(pymacs-forget-mutability t)
(pymacs-gc-inhibit t))
(pymacs-apply "zombie_python" pymacs-used-ids))
(setq pymacs-used-ids nil))
(setq pymacs-weak-hash (make-hash-table :weakness 'value))
(if (boundp 'post-gc-hook)
(add-hook 'post-gc-hook 'pymacs-schedule-gc)
(setq pymacs-gc-timer (run-at-time 20 20 'pymacs-schedule-gc))))
;; If nothing failed, only then declare that Pymacs has started!
(setq pymacs-transit-buffer buffer)))
(defun pymacs-terminate-services ()
;; This function is mainly provided for documentation purposes.
(interactive)
(garbage-collect)
(pymacs-garbage-collect)
(when (or (not pymacs-used-ids)
(yes-or-no-p "\
Killing the Pymacs helper might create zombie objects. Kill? "))
(cond ((boundp 'post-gc-hook)
(remove-hook 'post-gc-hook 'pymacs-schedule-gc))
((pymacs-timerp pymacs-gc-timer)
(pymacs-cancel-timer pymacs-gc-timer)))
(when pymacs-transit-buffer
(kill-buffer pymacs-transit-buffer))
(setq pymacs-gc-inhibit nil
pymacs-gc-timer nil
pymacs-transit-buffer nil
pymacs-lisp nil
pymacs-freed-list nil)))
(defun pymacs-serve-until-reply (action inserter)
;; This function builds a Python request by printing ACTION and
;; evaluating INSERTER, which itself prints an argument. It then
;; sends the request to the Pymacs helper, and serves all
;; sub-requests coming from the Python side, until either a reply or
;; an error is finally received.
(unless (and pymacs-transit-buffer
(buffer-name pymacs-transit-buffer)
(get-buffer-process pymacs-transit-buffer))
(when pymacs-weak-hash
(unless (or (eq pymacs-auto-restart t)
(and (eq pymacs-auto-restart 'ask)
(yes-or-no-p "The Pymacs helper died. Restart it? ")))
(pymacs-report-error "There is no Pymacs helper!")))
(pymacs-start-services))
(when pymacs-gc-wanted
(pymacs-garbage-collect))
(let ((inhibit-quit t)
done value)
(while (not done)
(let ((form (pymacs-round-trip action inserter)))
(setq action (car form))
(when (eq action 'free)
(pymacs-free-lisp (cadr form))
(setq form (cddr form)
action (car form)))
(let* ((pair (pymacs-interruptible-eval (cadr form)))
(success (cdr pair)))
(setq value (car pair))
(cond ((eq action 'eval)
(if success
(setq action "return"
inserter `(pymacs-print-for-eval ',value))
(setq action "raise"
inserter `(let ((pymacs-forget-mutability t))
(pymacs-print-for-eval ,value)))))
((eq action 'expand)
(if success
(setq action "return"
inserter `(let ((pymacs-forget-mutability t))
(pymacs-print-for-eval ,value)))
(setq action "raise"
inserter `(let ((pymacs-forget-mutability t))
(pymacs-print-for-eval ,value)))))
((eq action 'return)
(if success
(setq done t)
(pymacs-report-error "%s" value)))
((eq action 'raise)
(if success
(pymacs-report-error "Python: %s" value)
(pymacs-report-error "%s" value)))
(t (pymacs-report-error "Protocol error: %s" form))))))
value))
(defun pymacs-round-trip (action inserter)
;; This function produces a Python request by printing and
;; evaluating INSERTER, which itself prints an argument. It sends
;; the request to the Pymacs helper, awaits for any kind of reply,
;; and returns it.
(with-current-buffer pymacs-transit-buffer
;; Possibly trim the beginning of the transit buffer.
(cond ((not pymacs-trace-transit)
(erase-buffer))
((consp pymacs-trace-transit)
(when (> (buffer-size) (cdr pymacs-trace-transit))
(let ((cut (- (buffer-size) (car pymacs-trace-transit))))
(when (> cut 0)
(save-excursion
(goto-char cut)
(unless (memq (preceding-char) '(0 ?\n))
(forward-line 1))
(delete-region (point-min) (point))))))))
;; Send the request, wait for a reply, and process it.
(let* ((process (get-buffer-process pymacs-transit-buffer))
(status (process-status process))
(marker (process-mark process))
(moving (= (point) marker))
send-position reply-position reply)
(save-excursion
(save-match-data
;; Encode request.
(setq send-position (marker-position marker))
(let ((standard-output marker))
(princ action)
(princ " ")
(eval inserter))
(goto-char marker)
(unless (= (preceding-char) ?\n)
(princ "\n" marker))
;; Send request text.
(goto-char send-position)
(insert (format ">%d\t" (- marker send-position)))
(setq reply-position (marker-position marker))
(process-send-region process send-position marker)
;; Receive reply text.
(while (and (eq status 'run)
(progn
(goto-char reply-position)
(not (re-search-forward "<\\([0-9]+\\)\t" nil t))))
(unless (accept-process-output process pymacs-timeout-at-reply)
(setq status (process-status process))))
(when (eq status 'run)
(let ((limit-position (+ (match-end 0)
(string-to-number (match-string 1)))))
(while (and (eq status 'run)
(< (marker-position marker) limit-position))
(unless (accept-process-output process pymacs-timeout-at-line)
(setq status (process-status process))))))
;; Decode reply.
(if (not (eq status 'run))
(pymacs-report-error "Pymacs helper status is `%S'" status)
(goto-char (match-end 0))
(setq reply (read (current-buffer))))))
(when (and moving (not pymacs-trace-transit))
(goto-char marker))
reply)))
(defun pymacs-interruptible-eval (expression)
;; This function produces a pair (VALUE . SUCCESS) for EXPRESSION.
;; A cautious evaluation of EXPRESSION is attempted, and any
;; error while evaluating is caught, including Emacs quit (C-g).
;; Any Emacs quit also gets forward as a SIGINT to the Pymacs handler.
;; With SUCCESS being true, VALUE is the expression value.
;; With SUCCESS being false, VALUE is an interruption diagnostic.
(condition-case info
(cons (let ((inhibit-quit nil)) (eval expression)) t)
(quit (setq quit-flag t)
(interrupt-process pymacs-transit-buffer)
(cons "*Interrupted!*" nil))
(error (cons (prin1-to-string info) nil))))
(defun pymacs-proper-list-p (expression)
;; Tell if a list is proper, id est, that it is `nil' or ends with `nil'.
(cond ((not expression))
((consp expression) (not (cdr (last expression))))))
(provide 'pymacs)

View File

@ -0,0 +1,115 @@
;;; python-pylint.el --- minor mode for running `pylint'
;; Copyright (c) 2009, 2010 Ian Eure <ian.eure@gmail.com>
;; Author: Ian Eure <ian.eure@gmail.com>
;; Keywords: languages python
;; Last edit: 2010-02-12
;; Version: 1.01
;; python-pylint.el is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by the Free
;; Software Foundation; either version 2, or (at your option) any later
;; version.
;;
;; It is distributed in the hope that it will be useful, but WITHOUT ANY
;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;; details.
;;
;; You should have received a copy of the GNU General Public License along
;; with your copy of Emacs; see the file COPYING. If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;; 02111-1307, USA.
;;; Commentary:
;;
;; (autoload 'python-pylint "python-pylint")
;; (autoload 'pylint "python-pylint")
;;
;;; Code:
(defgroup python-pylint nil
"Minor mode for running pylint"
:prefix "python-pylint-"
:group 'tools)
(defvar python-pylint-last-buffer nil
"The most recent PYLINT buffer.
A PYLINT buffer becomes most recent when you select PYLINT mode in it.
Notice that using \\[next-error] or \\[compile-goto-error] modifies
`complation-last-buffer' rather than `python-pylint-last-buffer'.")
(defconst python-pylint-regexp-alist
(let ((base "^\\(.*\\):\\([0-9]+\\):\s+\\(\\[%s.*\\)$"))
(list
(list (format base "[FE]") 1 2)
(list (format base "[RWC]") 1 2 nil 1)))
"Regexp used to match PYLINT hits. See `compilation-error-regexp-alist'.")
(defcustom python-pylint-options '("-rn" "-f parseable")
"Options to pass to pylint.py"
:type '(repeat string)
:group 'python-pylint)
(defcustom python-pylint-command "pylint"
"PYLINT command."
:type '(file)
:group 'python-pylint)
(defcustom python-pylint-ask-about-save nil
"Non-nil means \\[python-pylint] asks which buffers to save before compiling.
Otherwise, it saves all modified buffers without asking."
:type 'boolean
:group 'python-pylint)
(define-compilation-mode python-pylint-mode "PYLINT"
(setq python-pylint-last-buffer (current-buffer))
(set (make-local-variable 'compilation-error-regexp-alist)
python-pylint-regexp-alist)
(set (make-local-variable 'compilation-disable-input) t))
(defvar python-pylint-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map compilation-minor-mode-map)
(define-key map " " 'scroll-up)
(define-key map "\^?" 'scroll-down)
(define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
(define-key map "\r" 'compile-goto-error) ;; ?
(define-key map "n" 'next-error-no-select)
(define-key map "p" 'previous-error-no-select)
(define-key map "{" 'compilation-previous-file)
(define-key map "}" 'compilation-next-file)
(define-key map "\t" 'compilation-next-error)
(define-key map [backtab] 'compilation-previous-error)
map)
"Keymap for PYLINT buffers.
`compilation-minor-mode-map' is a cdr of this.")
;;;###autoload
(defun python-pylint ()
"Run PYLINT, and collect output in a buffer.
While pylint runs asynchronously, you can use \\[next-error] (M-x next-error),
or \\<python-pylint-mode-map>\\[compile-goto-error] in the grep \
output buffer, to go to the lines where pylint found matches."
(interactive)
(save-some-buffers (not python-pylint-ask-about-save) nil)
(let* ((tramp (tramp-tramp-file-p (buffer-file-name)))
(file (or (and tramp
(aref (tramp-dissect-file-name (buffer-file-name)) 3))
(buffer-file-name)))
(command (mapconcat
'identity
(list python-pylint-command
(mapconcat 'identity python-pylint-options " ")
(comint-quote-filename file)) " ")))
(compilation-start command 'python-pylint-mode)))
;;;###autoload
(defalias 'pylint 'python-pylint)
(provide 'python-pylint)

View File

@ -0,0 +1,18 @@
;; Object sss/
;; SEMANTICDB Tags save file
(semanticdb-project-database-file "sss/"
:tables (list
(semanticdb-table "sss.c"
:major-mode 'c-mode
:tags nil
:file "sss.c"
:pointmax 850
:fsize 169
:lastmodtime '(19739 31366)
:unmatched-syntax 'nil
)
)
:file "!home!lxsameer!src!sss!semantic.cache"
:semantic-tag-version "2.0pre7"
:semanticdb-version "2.0pre7"
)

View File

@ -0,0 +1,18 @@
;; Object bits/
;; SEMANTICDB Tags save file
(semanticdb-project-database-file "bits/"
:tables (list
(semanticdb-table "c++config.h"
:major-mode 'c++-mode
:tags nil
:file "c++config.h"
:pointmax 41901
:fsize 41900
:lastmodtime '(19701 32168)
:unmatched-syntax 'nil
)
)
:file "!usr!include!c++!4.4!x86_64-linux-gnu!bits!semantic.cache"
:semantic-tag-version "2.0pre7"
:semanticdb-version "2.0pre7"
)

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -0,0 +1,23 @@
================
yasnippet-django
================
yasnippet-django is a set of `yasnippet`_-compatible snippets for Django 1.0
The current set of snippets build on the updated TextMate bundle, created by `Brian Kerr`_. They have been converted for use with yasnippet. If you have ideas for other additions please let me know.
Usage
=====
#. Checkout the repository, or untar the release:
git://github.com/jonatkinson/yasnippet-django.git
-or-
tar xzf yasnippet-django-X.X.tar.gz
#. Copy these files into your yasnippets/django-mode/ folder (this could be located anywhere, if you need a point in the right direction, try ~/.emacs.d/)
.. _yasnippet: http://code.google.com/p/yasnippet/
.. _Brian Kerr: http://bitbucket.org/bkerr/django-textmate-bundles/wiki/Home

View File

@ -0,0 +1,3 @@
{% autoescape ${1:off} %}
$2
{% endautoescape %}

View File

@ -0,0 +1,3 @@
{% block $1 %}
$2
{% endblock $1 %}

View File

@ -0,0 +1,3 @@
{% blocktrans ${1:with ${2:var1} as ${3:var2}} %}
$4{{ $3 }}
{% endblocktrans %}

View File

@ -0,0 +1,3 @@
{% comment %}
$1
{% endcomment %}

View File

@ -0,0 +1 @@
{% cycle $1 as $2 %}

View File

@ -0,0 +1,3 @@
<pre>
{% debug %}
</pre>

View File

@ -0,0 +1 @@
{% extends '${1:base.html}' %}

View File

@ -0,0 +1,3 @@
{% filter $1 %}
$2
{% endfilter %}

View File

@ -0,0 +1 @@
{% firstof $1 %}

View File

@ -0,0 +1,3 @@
{% for $1 in $2 %}
$3
{% endfor %}

View File

@ -0,0 +1,5 @@
{% if $1 %}
$0${2:
{% else %}
}
{% endif %}

View File

@ -0,0 +1 @@
{% ifchanged $1%}$2{% endifchanged %}

View File

@ -0,0 +1,3 @@
{% ifequal $1 $2 %}
$3
{% endifequal %}

View File

@ -0,0 +1,3 @@
{% ifnotequal $1 $2 %}
$3
{% endifnotequal %}

View File

@ -0,0 +1 @@
{% include ${1:"$2"} %}

View File

@ -0,0 +1 @@
{% load $1 %}

View File

@ -0,0 +1 @@
{% now "$1" %}

View File

@ -0,0 +1 @@
{% regroup $1 by $2 as $3 %}

View File

@ -0,0 +1,3 @@
{% spaceless %}
$1
{% endspaceless %}

View File

@ -0,0 +1 @@
{% ssi $1 ${2:parsed} %}

View File

@ -0,0 +1 @@
{{ block.super }}

View File

@ -0,0 +1 @@
{% trans "${1:string to translate}" %}

View File

@ -0,0 +1 @@
{% url $1 as $2 %}

View File

@ -0,0 +1 @@
{% widthratio ${1:this_value} ${2:max_value} ${3:100} %}

View File

@ -0,0 +1,3 @@
{% with $1 as $2 %}
$3
{% endwith %}

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.AutoField()

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.BooleanField(${2:default=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.CharField(${2:blank=True, }max_length=${3:255})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.CommaSeparatedIntegerField(max_length=$2)

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.DateField(2:blank=True, null=True, }${3:auto_now_add=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.DateTimeField(${2:blank=True, null=True, }${3:auto_now_add=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.DecimalField(max_digits=$2, decimal_places=$3)

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.EmailField()

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.FileField(upload_to=${1:/path/for/upload})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.FilePathField(path="${1:/location/of/choices}"${2:, match="${3:regex}"}${4:, recursive=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.ForeignKey(${2:RELATED_MODEL})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.FloatField()

View File

@ -0,0 +1,15 @@
class ${1:Formname}(forms.Form):
"""${2:($1 description)}"""
${3:def __init__(self, *args, **kwargs):
${4:}
super($1, self).__init__(*args, **kwargs)}
$0
${5:def clean_${6:fieldname}(self):
$7
return self.cleaned_data['$6']}
${8:def clean(self):
$9
return self.cleaned_data}

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.ImageField(upload_to="${2:/dir/path}"${3:, height_field=$4}${5:, width_field=$6})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.IntegerField(${2:blank=True, null=True})

View File

@ -0,0 +1,5 @@
class ${1:Modelname}(models.Model):
"""${2:($1 description)}"""
${3:target_field_name} = models.ForeignKey(${4:TargetModel})
${5:source_field_name} = models.ForeignKey(${6:SourceModel})
$0

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.IPAddressField(${2:blank=True})

View File

@ -0,0 +1,14 @@
class ${1:Modelname}(models.Model):
"""${2:($1 description)}"""
$0
${3:class Meta:
ordering = [${4:}]
verbose_name, verbose_name_plural = "${5:}", "${6:$5s}"}
def __unicode__(self):
return ${7:u"$1"}
${8:@models.permalink
def get_absolute_url(self):
return ('${9:$1}', [${10:self.id}])}

View File

@ -0,0 +1,13 @@
class ${1:ModelName}Admin(admin.ModelAdmin):
${2:date_hierarchy = '${3:}'}
${4:list_display = (${5:})}
${6:list_filter = (${7:})}
${8:search_fields = [${9:}]}
${10:fieldsets = (${11:})}
${12:save_as = True}
${13:save_on_top = True}
${14:inlines = [${15:}]}
admin.site.register($1, $1Admin)

View File

@ -0,0 +1,14 @@
class ${1:ModelnameForm}(forms.ModelForm):
$0
${3:def clean_${4:fieldname}(self):
$5
return self.cleaned_data['$4']}
${6:def clean(self):
${7:}
return self.cleaned_data}
${8:def save(self):
super($1, self).save()
${9:}}

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.ManyToManyField(${2:RELATED_MODEL})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.NullBooleanField(${2:default=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.PositiveIntegerField(${2:blank=True, null=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.PositiveSmallIntegerField(${2:blank=True, null=True})

View File

@ -0,0 +1 @@
mail.send_mail("${1:Subject}", "${2:Message}", "${3:from@example.com}", ${4:["to@example.com"]}${5:, fail_silently=True})

View File

@ -0,0 +1 @@
${1:slug} = models.SlugField()

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.SmallIntegerField(${2:blank=True, null=True})

View File

@ -0,0 +1,5 @@
class ${1:ModelName}Inline(admin.StackedInline):
model = ${2:$1}
${3:extra = ${4:}}
${5:max_num = ${6:}}
$0

View File

@ -0,0 +1,5 @@
class ${1:ModelName}Inline(admin.TabularInline):
model = ${2:$1}
${3:extra = ${4:}}
${5:max_num = ${6:}}
$0

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.TextField(${2:blank=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.TimeField(${2:blank=True})

View File

@ -0,0 +1 @@
${1:FIELDNAME} = models.XMLField(schema_path=${2:/path/to/RelaxNG}${3:, blank=True})

View File

@ -0,0 +1,4 @@
#name : # =>
#group : general
# --
# =>