diff options
| author | rocky <rocky@gnu.org> | 2020-05-09 22:48:03 -0400 |
|---|---|---|
| committer | rocky <rocky@gnu.org> | 2020-05-09 22:48:03 -0400 |
| commit | 7b3e08006f6232e021a4894e13aada64c3715d78 (patch) | |
| tree | 8763258a774987cd16e647ea98b0692e82695d99 | |
realgud interface to trepan-xpy
| -rw-r--r-- | .gitignore | 25 | ||||
| -rw-r--r-- | Makefile.am | 49 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rwxr-xr-x | autogen.sh | 12 | ||||
| -rw-r--r-- | common.mk.in | 24 | ||||
| -rwxr-xr-x | compute-lispdir.sh | 46 | ||||
| -rw-r--r-- | configure.ac | 55 | ||||
| -rw-r--r-- | realgud-trepan-xpy.el | 48 | ||||
| -rw-r--r-- | test/Makefile.am | 73 | ||||
| -rwxr-xr-x | test/gcd.py | 41 | ||||
| -rw-r--r-- | test/make-check-filter.rb | 24 | ||||
| -rw-r--r-- | test/regexp-helper.el | 61 | ||||
| -rw-r--r-- | trepan-xpy/Makefile.am | 8 | ||||
| -rw-r--r-- | trepan-xpy/core.el | 186 | ||||
| -rw-r--r-- | trepan-xpy/init.el | 141 | ||||
| -rw-r--r-- | trepan-xpy/track-mode.el | 70 | ||||
| -rw-r--r-- | trepan-xpy/trepan-xpy.el | 100 |
17 files changed, 964 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98b94eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +*.elc +*~ +/*-pkg.el +/*.tar.gz +/.byebug_history +/.python-version +/.ruby-version +/README +/aclocal.m4 +/autom4te.cache +/common.mk +/config.log +/config.status +/configure +/configure.lineno +/elpa +/install-sh +/missing +/test/npm-debug.log +/tmp +Makefile +Makefile.in +elc-stamp +elc-temp +script diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..fda03c1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,49 @@ +# Note: This makefile include remake-style target comments. +# These comments before the targets start with #: +# remake --tasks to shows the targets and the comments + +SUBDIRS = trepan-xpy test + +GIT2CL ?= git2cl +RUBY ?= ruby + +lispdir = @lispdir@ + +lisp_files = $(wildcard *.el) +lisp_LISP = $(lisp_files) +include common.mk + +PHONY=check clean dist distclean test check-short check-terse install-short + +EXTRA_DIST = common.mk.in INSTALL.md README.md THANKS $(lisp_files) + +if MAINTAINER_MODE + +#: Remove change log: ChangeLog +rmChangeLog: + rm ChangeLog || true + +#: Create a ChangeLog file from git logs +ChangeLog: rmChangeLog + git log --pretty --numstat --summary | $(GIT2CL) > $@ + +ACLOCAL_AMFLAGS=-I . + +endif + +#: Run all tests +test: check + +#: Run all tests without bloated output +check-short: + $(MAKE) check 2>&1 | $(RUBY) test/make-check-filter.rb + +#: Run all tests without and show just the failure lines +check-terse: + $(MAKE) check 2>&1 | $(RUBY) tes/make-check-filter.rb | grep failure + +#: Run "make install" non-verbosely +install-short: + $(MAKE) install 2>&1 | $(RUBY) test/make-check-filter.rb + +.PHONY: test check check-short rmChangeLog diff --git a/README.md b/README.md new file mode 100644 index 0000000..576a8f3 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Emacs Lisp Module to add [ipdb](https://pypi.org/project/ipdb/) support to [realgud](http://github.com/rocky/emacs-dbgr). diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..7beb4b9c --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# An autoconf setup script. +# From inside emacs, make sure test-simple is installed and then +# Press C-x C-e at the end of the next line run this script +# (test-simple-run "EMACSLOADPATH=%s ./autogen.sh" (mapconcat 'identity load-path ":")) +ln -fs README.md README +touch common.mk +autoreconf -vfi && \ +autoconf && { + echo "Running configure with --enable-maintainer-mode $@" + ./configure --enable-maintainer-mode $@ +} diff --git a/common.mk.in b/common.mk.in new file mode 100644 index 0000000..88f3a9d --- /dev/null +++ b/common.mk.in @@ -0,0 +1,24 @@ +MOSTLYCLEANFILES = *.elc +EMACSLOADPATH=@EMACSLOADPATH@ + +short: + $(MAKE) 2>&1 >/dev/null | ruby $(top_srcdir)/make-check-filter.rb + +%.short: + $(MAKE) $(@:.short=) 2>&1 >/dev/null + +# This is the default target but We need to include an EMACSLOADPATH +.el.elc: + if test "$(EMACS)" != "no"; then \ + am__dir=. am__subdir_includes=''; \ + case $@ in */*) \ + am__dir=`echo '$@' | sed 's,/[^/]*$$,,'`; \ + am__subdir_includes="-L $$am__dir -L $(srcdir)/$$am__dir"; \ + esac; \ + test -d "$$am__dir" || $(MKDIR_P) "$$am__dir" || exit 1; \ + EMACSLOADPATH=$(EMACSLOADPATH) $(EMACS) --batch \ + $(AM_ELCFLAGS) --eval "(progn(package-initialize))" \ + $$am__subdir_includes -L $(builddir) -L $(srcdir) \ + --eval "(defun byte-compile-dest-file (f) \"$@\")" \ + --eval "(unless (byte-compile-file \"$<\") (kill-emacs 1))"; \ + else :; fi diff --git a/compute-lispdir.sh b/compute-lispdir.sh new file mode 100755 index 0000000..553b579 --- /dev/null +++ b/compute-lispdir.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Figures out a reasonable --prefix +typeset -i rc=0 +typeset -i DEBUG=${DEBUG:-0} +EMACS_PROG=${EMACS_PROG:-emacs} +list=$($EMACS_PROG --batch --no-splash --no-site-file --eval '(message (substring (format "%s" load-path) 1 -1))' 2>&1) +rc=$? +if (( rc != 0 )) ; then + echo >&2 "Something went wrong running $EMACS_PROG" + exit $rc +$cmd +fi +for dir in $list ; do + if [[ -d $dir ]] ; then + case $dir in + */emacs/site-lisp) + ((DEBUG)) && echo "site lisp: $dir" + echo "$dir" + exit 0 + ;; + esac + fi +done +for dir in $list ; do + if [[ -d $dir ]] ; then + case $dir in + */emacs/2[5-8]\.[0-9]/site-lisp) + ((DEBUG)) && echo "versioned site lisp: $dir" + echo "$dir" + exit 0 + ;; + esac + fi +done +for dir in $list ; do + if [[ -d $dir ]] ; then + case $dir in + */emacs/2[5-8]\.[0-9]/site-lisp) + ((DEBUG)) && echo "versioned site lisp: $dir" + echo "$dir" + exit 0 + ;; + esac + fi +done +exit 0 diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..b9d28a6 --- /dev/null +++ b/configure.ac @@ -0,0 +1,55 @@ +dnl FIXME: pick up from realgud.el +AC_INIT(realgud-trepan-xpy, 1.0.0,) +AC_CONFIG_SRCDIR(trepan-xpy/trepan-xpy.el) +AM_INIT_AUTOMAKE([foreign]) +AM_MAINTAINER_MODE + +AC_PATH_PROG([EMACS], [emacs], [emacs]) +AC_ARG_WITH(emacs, AC_HELP_STRING([--with-emacs], + [location of emacs program]), EMACS=$withval) + +AC_MSG_NOTICE("Checking emacs version") +$EMACS -batch -q --no-site-file -eval \ + '(if (<= emacs-major-version 24) + (progn + (error "You need GNU Emacs 25 or later.") + (kill-emacs 1) + ) + )' +if test $? -ne 0 ; then + AC_MSG_ERROR([Can't continue until above error is corrected.]) +fi + +################################################################## +# See if --with-lispdir was set. If not, set it to a reasonable default +# based on where bash thinks bashdb is supposed to be installed. +################################################################## + +AM_MISSING_PROG(GIT2CL, git2cl, $missing_dir) + +# Check whether --with-lispdir was given. +if test "${with_lispdir+set}" = set; then : +else + my_lispdir=$(EMACS_PROG=$EMACS $SH_PROG $(dirname $0)/compute-lispdir.sh) + if test "${my_lispdir+set}" = set; then : + with_lispdir=$my_lispdir + echo "'compute-lispdir.sh' lispdir install directory override: '$with_lispdir'" + fi +fi + +## +## Find out where to install the debugger emacs lisp files +## +AM_PATH_LISPDIR +lispdir_realgud=$lispdir/realgud +AC_SUBST([lispdir]) +AC_SUBST([lispdir_realgud]) + +AM_CONDITIONAL(INSTALL_EMACS_LISP, test "x$lispdir_realgud" != "x") + +AC_CONFIG_FILES([Makefile \ + common.mk \ + trepan-xpy/Makefile \ + test/Makefile \ + ]) +AC_OUTPUT diff --git a/realgud-trepan-xpy.el b/realgud-trepan-xpy.el new file mode 100644 index 0000000..4e309f9 --- /dev/null +++ b/realgud-trepan-xpy.el @@ -0,0 +1,48 @@ +;;; realgud-trepan-xpy.el --- Realgud front-end to trepan-xpy -*- lexical-binding: t -*- + +;; Author: Rocky Bernstein <rocky@gnu.org> +;; Version: 1.0.0 +;; Package-Type: multi +;; Package-Requires: ((realgud "1.5.0") (load-relative "1.3.1") (emacs "25")) +;; URL: http://github.com/rocky/realgud-trepan-xpy +;; Compatibility: GNU Emacs 25.x + +;; Copyright (C) 2019 Free Software Foundation, Inc + +;; Author: Rocky Bernstein <rocky@gnu.org> + +;; 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/>. + +;;; Commentary: + +;; realgud support for the Python trepan-xpy +;; See https://pypi.org/project/trepan-xpy/ + +;;; Code: + +;; Press C-x C-e at the end of the next line configure the program in +;; for building via "make" to get set up. +;; (compile (format "EMACSLOADPATH=:%s:%s:%s:%s ./autogen.sh" (file-name-directory (locate-library "loc-changes.elc")) (file-name-directory (locate-library "test-simple.elc")) (file-name-directory (locate-library "load-relative.elc")) (file-name-directory (locate-library "realgud.elc")))) + +(require 'load-relative) + +(defgroup realgud-trepan-xpy nil + "Realgud interface to trepan-xpy" + :group 'realgud + :version "25.1") + +(require-relative-list '( "./trepan-xpy/trepan-xpy" ) "realgud-") + +(provide-me) +;;; realgud-trepan-xpy.el ends here diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..972821b --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,73 @@ +lisp_files = $(wildcard *.el) +EXTRA_DIST = $(lisp_files) +lisp_LISP = $(lisp_files) +include $(top_srcdir)/common.mk + +PHONY=check test all check-elget test-elget help + +#: overall help on running the make targets +help: + @echo "The main function of this Makefile is to facilitate running tests." + @echo + @echo "To run all of the tests, use targets \"test\", \"check\" or \"check-short\"." + @echo "For example:" + @echo + @echo " make check" + @echo "or:" + @echo " make check-short" + @echo + @echo "The -short target uses a filter written in Ruby to remove extreanous output." + @echo + @echo "To run a specific test like test-srcbuf.el, change \".el\" to" + @echo "\".run\". For example:" + @echo + @echo " make test-srcbuf.run" + @echo + @echo "Tests can also be run via the Emacs el-get package and this loads dependent emacs " + @echo "package, like load-relative. To do this, use targets, \"check-elget\"," + @echo "\"test-elget\", or \"check-short-elget\"." + @echo + @echo "To run a specific test like test-srcbuf.el via el-get change \".el\"" + @echo "to \".elrun\" For example:" + @echo + @echo " make test-srcbuf.elrun" + + +#: same thing as "check" +test: check + +#: same thing as "check-elget" +test-elget: check-elget + +test_files := $(wildcard test-*.el) + +CHECK_FILES = $(notdir $(test_files:.el=.run)) +EL_GET_CHECK_FILES = $(notdir $(test_files:.el=.elrun)) + +#: Run all tests +check: $(CHECK_FILES) + +#: Run all tests via el-get +check-elget: $(EL_GET_CHECK_FILES) + +#: Run all tests with minimum verbosity +check-short: + $(MAKE) check 2>&1 | ruby ../make-check-filter.rb + +#: Run all tests with minimum verbosity via el-get +check-short-elget: + $(MAKE) check-elget 2>&1 | ruby ../make-check-filter.rb + +test-%.run: + (cd $(top_srcdir)/test && EMACSLOADPATH=$(EMACSLOADPATH) $(EMACS) --batch --no-site-file --no-splash --load $(@:.run=.el)) + +#: Run tests using el-get to specify external Lisp dependencies +test-%.elrun: + (cd $(top_srcdir)/test && EMACSLOADPATH=$(EMACSLOADPATH) $(EMACS) --batch --no-site-file --no-splash --load ../el-get-install.el --load $(@:.elrun=.el)) + +install-lispLISP: $(lisp_LISP) $(ELCFILES) + +# Whatever it is you want to do, it should be forwarded to the +# to top-level directories +# %: +# $(MAKE) -C .. $@ diff --git a/test/gcd.py b/test/gcd.py new file mode 100755 index 0000000..e64f284 --- /dev/null +++ b/test/gcd.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +"""Greatest Common Divisor + +Some characterstics of this program used for testing check_args() does +not have a 'return' statement. + +check_args() raises an uncaught exception when given the wrong number +of parameters. + +""" +import sys + +def check_args(): + if len(sys.argv) != 3: + # Rather than use sys.exit let's just raise an error + raise Exception("Need to give two numbers") + for i in range(2): + try: + sys.argv[i+1] = int(sys.argv[i+1]) + except ValueError: + print("** Expecting an integer, got: %s" % repr(sys.argv[i])) + sys.exit(2) + +def gcd(a,b): + """ GCD. We assume positive numbers""" + + # Make: a <= b + if a > b: + (a, b) = (b, a) + + if a <= 0: + return None + if a == 1 or b-a == 0: + return a + return gcd(b-a, a) + +if __name__=='__main__': + check_args() + + (a, b) = sys.argv[1:3] + print("The GCD of %d and %d is %d" % (a, b, gcd(a, b))) diff --git a/test/make-check-filter.rb b/test/make-check-filter.rb new file mode 100644 index 0000000..508c8f6 --- /dev/null +++ b/test/make-check-filter.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +# Use this to cut out the crud from make check. +# Use like this: +# make check 2>&1 | ruby ../make-check-filter.rb +# See Makefile.am +pats = ["^(?:Loading", + '(re)?make\[', + "Making check in", + '\(cd \.\.', + "make -C", + "Test-Unit", + "Fontifying", + "`flet'", + '\s*$', + '##[<>]+$' + ].join('|') + ')' +# puts pats +skip_re = /#{pats}/ + +while gets() + next if $_.encode!('UTF-8', 'binary', + invalid: :replace, undef: :replace, replace: '') =~ skip_re + puts $_ +end diff --git a/test/regexp-helper.el b/test/regexp-helper.el new file mode 100644 index 0000000..cdcecae --- /dev/null +++ b/test/regexp-helper.el @@ -0,0 +1,61 @@ +(require 'test-simple) +(require 'realgud) + +(eval-when-compile + (defvar helper-bps) + (defvar helper-info-brkpt) + (defvar helper-loc) + (defvar helper-tb) + (defvar prompt-pat) +) + +(declare-function realgud-loc-pat-regexp 'realgud-backtrace-mode) +(declare-function realgud-cmdbuf-info-loc-regexp 'realgud-buffer-command) +(declare-function test-simple-start 'test-simple) + + +(defun setup-regexp-vars(pat-hash) + (setq helper-bps (gethash "brkpt-set" pat-hash)) + (setq helper-info-brkpt (gethash "debugger-breakpoint" pat-hash)) + (setq helper-loc (gethash "loc" pat-hash)) + (setq helper-tb (gethash "lang-backtrace" pat-hash)) +) + +(defun loc-match(text regexp-list) + "Match TEXT against regexp field REGEXP" + (let ((regexp) + (ret-val nil)) + (unless (listp regexp-list) + (setq regexp-list (list regexp-list))) + (while regexp-list + (setq regexp (car regexp-list)) + (setq regexp-list (cdr regexp-list)) + (when (setq ret-val (string-match (realgud-loc-pat-regexp regexp) text)) + (setq regexp-list nil))) + ret-val + )) + +(defun bp-loc-match(text) + (string-match (realgud-loc-pat-regexp helper-bps) text) +) + +(defun tb-loc-match(text) + (string-match (realgud-loc-pat-regexp helper-tb) text) +) + +(defun cmdbuf-loc-match(text dbgr) + "Match TEXT against cmdbuf-info-loc field VAR" + (string-match (realgud-cmdbuf-info-loc-regexp dbgr) text) + ) + +(defun prompt-match(prompt-str &optional num-str fmt-str) + (unless fmt-str (setq fmt-str "debugger prompt %s")) + (assert-equal 0 (string-match (realgud-loc-pat-regexp prompt-pat) + prompt-str) + (format fmt-str prompt-str)) + (cond (num-str + (assert-equal num-str (substring prompt-str + (match-beginning 1) (match-end 1)))) + ('t 't)) + ) +(provide 'realgud-regexp-helper) diff --git a/trepan-xpy/Makefile.am b/trepan-xpy/Makefile.am new file mode 100644 index 0000000..b15e3bf --- /dev/null +++ b/trepan-xpy/Makefile.am @@ -0,0 +1,8 @@ +lisp_files = $(wildcard *.el) +EXTRA_DIST=$(lisp_files) +lisp_LISP = $(lisp_files) +include ../common.mk +lispdir = @lispdir@/ipdb + +ipdb.elc: core.elc track-mode.elc +track-mode.elc: core.elc init.elc diff --git a/trepan-xpy/core.el b/trepan-xpy/core.el new file mode 100644 index 0000000..3ebcdaa --- /dev/null +++ b/trepan-xpy/core.el @@ -0,0 +1,186 @@ +;; Copyright (C) 2010, 2012-2017, 2020 Free Software Foundation, Inc + +;; Author: Rocky Bernstein <rocky@gnu.org> + +;; 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/>. +;; + +(require 'comint) +(require 'realgud) +(require 'load-relative) +(require-relative-list '("init") "realgud--trepan-xpy-") + +(declare-function realgud:expand-file-name-if-exists 'realgud-core) +(declare-function realgud-parse-command-arg 'realgud-core) +(declare-function realgud-query-cmdline 'realgud-core) +(declare-function realgud-suggest-invocation 'realgud-core) + +;; FIXME: I think the following could be generalized and moved to +;; realgud-... probably via a macro. +(defvar realgud:trepan-xpy-minibuffer-history nil + "minibuffer history list for the command `realgud:trepan-xpy'.") + +(easy-mmode-defmap trepan-xpy-minibuffer-local-map + '(("\C-i" . comint-dynamic-complete-filename)) + "Keymap for minibuffer prompting of gud startup command." + :inherit minibuffer-local-map) + +;; FIXME: I think this code and the keymaps and history +;; variable chould be generalized, perhaps via a macro. +(defun trepan-xpy-query-cmdline (&optional opt-debugger) + (realgud-query-cmdline + 'trepan-xpy-suggest-invocation + trepan-xpy-minibuffer-local-map + 'realgud-trepan-xpy-minibuffer-history + opt-debugger)) + +(defun trepan-xpy-parse-cmd-args (orig-args) + "Parse command line ARGS for the annotate level and name of script to debug. + +ARGS should contain a tokenized list of the command line to run. + +We return the a list containing +- the command processor (e.g. python) and it's arguments if any - a list of strings +- the name of the debugger given (e.g. trepan-xpy) and its arguments - a list of strings +- the script name and its arguments - list of strings +- whether the annotate or emacs option was given ('-A', '--annotate' or '--emacs) - a boolean + +For example for the following input + (map 'list 'symbol-name + '(python2.6 -O -Qold --emacs ./gcd.py a b)) + +we might return: + ((python2.6 -O -Qold) (trepan-xpy --emacs) (./gcd.py a b) 't) + +NOTE: the above should have each item listed in quotes. +" + + ;; Parse the following kind of pattern: + ;; [python python-options] trepan-xpy trepan-xpy-options script-name script-options + (let ( + (args orig-args) + (pair) ;; temp return from + (python-opt-two-args '("c" "m" "Q" "W")) + ;; Python doesn't have mandatory 2-arg options in our sense, + ;; since the two args can be run together, e.g. "-C/tmp" or "-C /tmp" + ;; + (python-two-args '()) + ;; One dash is added automatically to the below, so + ;; h is really -h and -host is really --host. + (trepan-xpy-two-args '("x" "-command" "e" "-execute" + "o" "-output" "t" "-target" + "a" "-annotate")) + (trepan-xpy-opt-two-args '()) + (interp-regexp + (if (member system-type (list 'windows-nt 'cygwin 'msdos)) + "^python[-0-9.]*\\(.exe\\)?$" + "^python[-0-9.]*$")) + + ;; Things returned + (annotate-p nil) + (debugger-args '()) + (debugger-name nil) + (interpreter-args '()) + (script-args '()) + (script-name nil) + ) + + (if (not (and args)) + ;; Got nothing: return '(nil, nil) + (list interpreter-args debugger-args script-args annotate-p) + ;; else + ;; Strip off optional "python" or "python182" etc. + (when (string-match interp-regexp + (file-name-sans-extension + (file-name-nondirectory (car args)))) + (setq interpreter-args (list (pop args))) + + ;; Strip off Python-specific options + (while (and args + (string-match "^-" (car args))) + (setq pair (realgud-parse-command-arg + args python-two-args python-opt-two-args)) + (nconc interpreter-args (car pair)) + (setq args (cadr pair)))) + + ;; Remove "trepan-xpy" from "trepan-xpy --trepan-xpy-options script + ;; --script-options" + (setq debugger-name (file-name-sans-extension + (file-name-nondirectory (car args)))) + (unless (string-match "^\\(trepan-xpy\\|cli.py\\)$" debugger-name) + (message + "Expecting debugger name `%s' to be `trepan-xpy' or `cli.py'" + debugger-name)) + (setq debugger-args (list (pop args))) + + ;; Skip to the first non-option argument. + (while (and args (not script-name)) + (let ((arg (car args))) + (cond + ;; Annotation or emacs option with level number. + ((or (member arg '("--annotate" "-A")) + (equal arg "--emacs")) + (setq annotate-p t) + (nconc debugger-args (list (pop args)))) + ;; Combined annotation and level option. + ((string-match "^--annotate=[0-9]" arg) + (nconc debugger-args (list (pop args)) ) + (setq annotate-p t)) + ;; Options with arguments. + ((string-match "^-" arg) + (setq pair (realgud-parse-command-arg + args trepan-xpy-two-args trepan-xpy-opt-two-args)) + (nconc debugger-args (car pair)) + (setq args (cadr pair))) + ;; Anything else must be the script to debug. + (t (setq script-name (realgud:expand-file-name-if-exists arg)) + (setq script-args (cons script-name (cdr args)))) + ))) + (list interpreter-args debugger-args script-args annotate-p)))) + +;; To silence Warning: reference to free variable +(defvar realgud:trepan-xpy-command-name) + +(defun trepan-xpy-suggest-invocation (debugger-name) + "Suggest a trepan-xpy command invocation via `realgud-suggest-invocaton'" + (realgud-suggest-invocation (or debugger-name realgud:trepan-xpy-command-name) + realgud:trepan-xpy-minibuffer-history + "python" "\\.py" + realgud:trepan-xpy-command-name)) + +(defun trepan-xpy-reset () + "trepan-xpy cleanup - remove debugger's internal buffers (frame, +breakpoints, etc.)." + (interactive) + ;; (trepan-xpy-breakpoint-remove-all-icons) + (dolist (buffer (buffer-list)) + (when (string-match "\\*trepan-xpy-[a-z]+\\*" (buffer-name buffer)) + (let ((w (get-buffer-window buffer))) + (when w + (delete-window w))) + (kill-buffer buffer)))) + +;; (defun trepan-xpy-reset-keymaps() +;; "This unbinds the special debugger keys of the source buffers." +;; (interactive) +;; (setcdr (assq 'trepan-xpy-debugger-support-minor-mode minor-mode-map-alist) +;; trepan-xpy-debugger-support-minor-mode-map-when-deactive)) + + +(defun realgud:trepan-xpy-customize () + "Use `customize' to edit the settings of the `trepan-xpy' debugger." + (interactive) + (customize-group 'realgud:trepan-xpy)) + +(provide-me "realgud--trepan-xpy-") diff --git a/trepan-xpy/init.el b/trepan-xpy/init.el new file mode 100644 index 0000000..4505fce --- /dev/null +++ b/trepan-xpy/init.el @@ -0,0 +1,141 @@ +;; Copyright (C) 2010-2019 Free Software Foundation, Inc + +;; Author: Rocky Bernstein <rocky@gnu.org> + +;; 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/>. + +;; trepan-xpy: Python 3.2 and beyond + +(eval-when-compile (require 'cl-lib)) ;For setf. + +(require 'load-relative) +(require 'realgud) + +(defvar realgud-pat-hash) +(declare-function make-realgud-loc-pat 'realgud-regexp) + +(defvar realgud:trepan-xpy-pat-hash (make-hash-table :test 'equal) + "Hash key is the what kind of pattern we want to match: +backtrace, prompt, etc. The values of a hash entry is a +realgud-loc-pat struct") + +(declare-function make-realgud-loc 'realgud-loc) + +;; realgud-loc-pat that describes a trepan-xpy location generally shown +;; before a command prompt. +;; +;; For example: +;; (/usr/bin/zonetab2pot.py:15 @3): <module> +;; (/usr/bin/zonetab2pot.py:15 remapped <string>): <module> +;; or MS Windows: +;; (c:\\mydirectory\\gcd.py:10): <module> +(setf (gethash "loc" realgud:trepan-xpy-pat-hash) + realgud:python-trepan-loc-pat) + +;; An initial list of regexps that don't generally have files +;; associated with them and therefore we should not try to find file +;; associations for them. This list is used to seed a field of the +;; same name in the cmd-info structure inside a command buffer. A user +;; may add additional files to the command-buffer's re-ignore-list. +(setf (gethash "ignore-re-file-list" realgud:trepan-xpy-pat-hash) + (list realgud-python-ignore-file-re)) + +;; realgud-loc-pat that describes a trepan-xpy prompt. +;; Note: the prompt in nested debugging +;; For example: +;; (trepan3) +;; ((trepan-xpy)) +(setf (gethash "prompt" realgud:trepan-xpy-pat-hash) + (make-realgud-loc-pat + :regexp "^(+trepan-xpy+) " + )) + +;; realgud-loc-pat that describes a trepan-xpy backtrace line. +;; For example: +;; ->0 get_distribution(dist='trepan==0.3.9') +;; called from file '/python2.7/dist-packages/pkg_res.py' at line 341 +;; ##1 load_entry_point(dist='tr=0.3.9', group='console_scripts', name='tr') +;; called from file '/python2.7/dist-packages/pkg_res.py' at line 351 +;; ##2 <module> exec() + +(setf (gethash "debugger-backtrace" realgud:trepan-xpy-pat-hash) + realgud:python-trepan-backtrace-pat) + +;; realgud-loc-pat that describes a line a Python "info break" line. +;; For example: +;; 1 breakpoint keep y at /usr/local/bin/trepan-xpy:7 +(setf (gethash "debugger-breakpoint" realgud:trepan-xpy-pat-hash) + realgud-python-breakpoint-pat) + +;; realgud-loc-pat that describes a Python backtrace line. +(setf (gethash "lang-backtrace" realgud:trepan-xpy-pat-hash) + realgud-python-backtrace-loc-pat) + +;; realgud-loc-pat that describes location in a pytest error +(setf (gethash "pytest-error" realgud:trepan-xpy-pat-hash) + realgud-pytest-error-loc-pat) + +;; realgud-loc-pat that describes location in a flake8 message +(setf (gethash "flake8-msg" realgud:trepan-xpy-pat-hash) + realgud-flake8-msg-loc-pat) + +;; realgud-loc-pat that describes a "breakpoint set" line +(setf (gethash "brkpt-set" realgud:trepan-xpy-pat-hash) + realgud:python-trepan-brkpt-set-pat) + +;; realgud-loc-pat that describes a "delete breakpoint" line +(setf (gethash "brkpt-del" realgud:trepan-xpy-pat-hash) + realgud:python-trepan-brkpt-del-pat) + +;; realgud-loc-pat that describes a debugger "disable" (breakpoint) response. +;; For example: +;; Breakpoint 4 disabled. +(setf (gethash "brkpt-disable" realgud:trepan-xpy-pat-hash) + realgud:python-trepan-brkpt-disable-pat) + +;; realgud-loc-pat that describes a debugger "enable" (breakpoint) response. +;; For example: +;; Breakpoint 4 enabled. +(setf (gethash "brkpt-enable" realgud:trepan-xpy-pat-hash) + realgud:python-trepan-brkpt-enable-pat) + +;; realgud-loc-pat for a termination message. +(setf (gethash "termination" realgud:trepan-xpy-pat-hash) + "^trepan-xpy: That's all, folks...\n") + +(setf (gethash "font-lock-keywords" realgud:trepan-xpy-pat-hash) + realgud:python-debugger-font-lock-keywords) + +(setf (gethash "font-lock-breakpoint-keywords" realgud:trepan-xpy-pat-hash) + realgud:python-debugger-font-lock-breakpoint-keywords) + +(setf (gethash "trepan-xpy" realgud-pat-hash) realgud:trepan-xpy-pat-hash) + +(defvar realgud:trepan-xpy-command-hash (make-hash-table :test 'equal) + "Hash key is command name like 'shell' and the value is + the trepan-xpy command to use, like 'python'") + +(setf (gethash "eval" realgud:trepan-xpy-command-hash) "eval %s") +(setf (gethash "info-breakpoints" realgud:trepan-xpy-command-hash) "info break") +(setf (gethash "pprint" realgud:trepan-xpy-command-hash) "pp %s") +(setf (gethash "shell" realgud:trepan-xpy-command-hash) "python") +(setf (gethash "until" realgud:trepan-xpy-command-hash) "continue %l") + +;; If your version of trepan-xpy doesn't support "quit!", +;; get a more recent version of trepan-xpy +(setf (gethash "quit" realgud:trepan-xpy-command-hash) "quit!") + +(setf (gethash "trepan-xpy" realgud-command-hash) realgud:trepan-xpy-command-hash) + +(provide-me "realgud--trepan-xpy-") diff --git a/trepan-xpy/track-mode.el b/trepan-xpy/track-mode.el new file mode 100644 index 0000000..2b6b445 --- /dev/null +++ b/trepan-xpy/track-mode.el @@ -0,0 +1,70 @@ +;; Copyright (C) 2015-2016, 2020 Free Software Foundation, Inc + +;; Author: Rocky Bernstein <rocky@gnu.org> + +;; 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/>. +;; Python "trepan-xpy" Debugger tracking a comint buffer. + +(require 'realgud) +(require 'load-relative) +(require-relative-list '("core" "init") "realgud--trepan-xpy-") + +(declare-function realgud-track-mode 'realgud-track-mode) +(declare-function realgud-track-mode-hook 'realgud-track-mode) +(declare-function realgud-track-mode-setup 'realgud-track-mode) +(declare-function realgud:track-set-debugger 'realgud-track-mode) +(declare-function realgud-python-populate-command-keys 'realgud-lang-python) + +(realgud-track-mode-vars "trepan-xpy") + +(declare-function realgud-track-mode(bool)) + +(realgud-python-populate-command-keys trepan-xpy-track-mode-map) + +(defun trepan-xpy-track-mode-hook() + (if trepan-xpy-track-mode + (progn + (use-local-map trepan-xpy-track-mode-map) + (message "using trepan-xpy mode map") + ) + (message "trepan-xpy track-mode-hook disable called") + ) +) + +(define-minor-mode trepan-xpy-track-mode + "Minor mode for tracking trepan-xpy source locations inside a process shell via realgud. trepan-xpy is a Python debugger. See URL `http://code.google.com/p/python3-trepan/'. + +If called interactively with no prefix argument, the mode is toggled. A prefix argument, captured as ARG, enables the mode if the argument is positive, and disables it otherwise. + +\\{trepan-xpy-track-mode-map} +" + :init-value nil + ;; :lighter " trepan-xpy" ;; mode-line indicator from realgud-track is sufficient. + ;; The minor mode bindings. + :global nil + :group 'realgud:trepan-xpy + :keymap trepan-xpy-track-mode-map + (realgud:track-set-debugger "trepan-xpy") + (if trepan-xpy-track-mode + (progn + (realgud-track-mode-setup 't) + (trepan-xpy-track-mode-hook)) + (progn + (setq realgud-track-mode nil) + )) +) + +(define-key trepan-xpy-short-key-mode-map "T" 'realgud:cmd-backtrace) + +(provide-me "realgud--trepan-xpy-") diff --git a/trepan-xpy/trepan-xpy.el b/trepan-xpy/trepan-xpy.el new file mode 100644 index 0000000..287ddf3 --- /dev/null +++ b/trepan-xpy/trepan-xpy.el @@ -0,0 +1,100 @@ +;; Copyright (C) 2010-2014, 2016-2017 Free Software Foundation, Inc + +;; Author: Rocky Bernstein <rocky@gnu.org> + +;; 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. + +(require 'load-relative) + +(require 'realgud) +(require-relative-list '("core" "track-mode") "realgud--trepan-xpy-") + + +;; This is needed, or at least the docstring part of it is needed to +;; get the customization menu to work in Emacs 25. +(defgroup realgud--trepan-xpy nil + "The realgud interface to the Python debugger, trepan-trepan-xpy" + :group 'realgud + :group 'python + :version "25.1") + +(declare-function trepan-xpy-query-cmdline 'realgud--trepan-xpy-core) +(declare-function trepan-xpy-parse-cmd-args 'realgud--trepan-xpy-core) +(declare-function realgud:run-debugger 'realgud:run) +(declare-function realgud:run-process 'realgud:core) +(declare-function realgud:flatten 'realgud-utils) + +;; ------------------------------------------------------------------- +;; User-definable variables +;; + +(defcustom realgud:trepan-xpy-command-name + ;;"trepan-xpy --emacs 3" + "trepan-xpy" + "File name for executing the Python debugger and command options. +This should be an executable on your path, or an absolute file name." + :type 'string + :group 'realgud-trepan-xpy) + +(declare-function trepan-xpy-track-mode (bool)) + +;; ------------------------------------------------------------------- +;; The end. +;; + +;;;###autoload +(defun realgud:trepan-xpy (&optional opt-cmd-line no-reset) + "Invoke the trepan-xpy Python debugger and start the Emacs user interface. + +String OPT-CMD-LINE is treated like a shell string; arguments are +tokenized by `split-string-and-unquote'. The tokenized string is +parsed by `trepan-xpy-parse-cmd-args' and path elements found by that +are expanded using `realgud:expand-file-name-if-exists'. + +Normally, command buffers are reused when the same debugger is +reinvoked inside a command buffer with a similar command. If we +discover that the buffer has prior command-buffer information and +NO-RESET is nil, then that information which may point into other +buffers and source buffers which may contain marks and fringe or +marginal icons is reset. See `loc-changes-clear-buffer' to clear +fringe and marginal icons. +" + (interactive) + (realgud:run-debugger "trepan-xpy" + 'trepan-xpy-query-cmdline + 'trepan-xpy-parse-cmd-args + 'realgud:trepan-xpy-minibuffer-history + opt-cmd-line no-reset) + ) + +;;;###autoload +(defalias 'trepan-xpy 'realgud:trepan-xpy) + +;;;###autoload +(defun realgud:trepan-xpy-delayed () + "This is like `trepan-xpy', but assumes inside the program to be debugged, you +have a call to the debugger somewhere, e.g. 'from trepan.api import debug; debug()'. +Therefore we invoke python rather than the debugger initially. +" + (interactive) + (let* ((initial-debugger python-shell-interpreter) + (actual-debugger "trepan-xpy") + (cmd-str (trepan-xpy-query-cmdline initial-debugger)) + (cmd-args (split-string-and-unquote cmd-str)) + ;; XXX: python gets registered as the interpreter rather than + ;; a debugger, and the debugger position (nth 1) is missing: + ;; the script-args takes its place. + (parsed-args (trepan-xpy-parse-cmd-args cmd-args)) + (script-args (nth 1 parsed-args)) + (script-name (car script-args)) + (parsed-cmd-args + (cl-remove-if 'nil (realgud:flatten parsed-args)))) + (realgud:run-process actual-debugger script-name parsed-cmd-args + 'realgud:trepan-xpy-deferred-minibuffer-history))) + +(realgud-deferred-invoke-setup "trepan-xpy") + +(provide-me "realgud-") |
