- Subject: Re: Re: pymode patch (1.3.1 + 1.4 -> 1.4.1)
- From: Guenter Milde <milde@xxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 3 Dec 2002 12:16:50 +0100 (CET)
On Mon, 02 Dec 2002 20:20:43 +0100 wrote Joachim Schmitz <js@xxxxxxxxxxxxx>:
> >
> > Unfortunately, the new jed 0.99.16 includes an update of pymode from
> > 1.3 to 1.3.1 while the last version is 1.4.
> > I incorporated the changes from 1.3.1 into 1.4, as well as some
> > privat (and hopefully helpfull) additions.
> >
> > Highlight: a help function that uses help from the pydoc module and also
> > scans for included modules to get help for imported functions...
> I tried to apply the patch and it failed partiall
Sorry, only after the posting I realized that it might have been wiser to post
the diff to the distributed 1.3.1 from jed 99.16. (However it is
considerabely longer.)
> where can I download the version 1.4.1 of pymode.sl
Unfortunately, I do not remember (it was posted to the list, either as
attachment or as a pointer). Nor did I find it in the archive (ok, not
trying very hard)).
Therefore here comes the diff 1.3.1 vs. 1.4.1
BTW: Is the mode still actively maintained? (As I have some more ideas for
improvement.)
--- pymode.sl Fri Nov 8 10:42:14 2002
+++ pymode-1.4.1.sl Mon Dec 2 16:23:27 2002
@@ -1,5 +1,5 @@
-% Python mode
-% File: pymode.sl v1.3.1
+% Python mode
+% File: pymode.sl v1.4.1
%
% For editing source code written in the Python programming language.
% Provides basic compatibility with Python mode under real Emacs
@@ -7,22 +7,22 @@
% Authors: Harri Pasanen <hpa@xxxxxx>
% Brien Barton <brien_barton@xxxxxxxxxxx>
%
-% following keys have python specific bindings:
+% The following keys have python specific bindings:
%
-% DELETE deletes to previous indent level
-% TAB indents line
-% ^C# comments region or current line
-% ^C> shifts line or region right
-% ^C< shifts line or region left
-% ^C^C executes the region, or the buffer if region not marked.
-% ^C| executes the region
-% ^C\t reindents the region
-% : colon dedents appropriately
+% Backspace deletes to previous indent level
+% : (colon) dedents appropriately
+% (the next assume _Reserved_Key_Prefix == "^C")
+% ^C# comments region or current line
+% ^C> shifts line or region right
+% ^C< shifts line or region left
+% ^C^C executes the region, or the buffer if region not marked.
+% ^C| executes the region
+% ^C\t reindents the region
%
% See python_mode function for available hooks
%
-% Shortcomings: does not really support triple-quoted strings in any way.
-%
+% Shortcomings: does not support triple-quoted strings well. It works
+% OK with """ but NOT with '''.
% Changes from v1.0:
%
@@ -31,7 +31,6 @@
% - execution of python code from JED
% - DFA syntax support
% - improved indent - dedent.
-%
% Changes from v1.1:
%
@@ -41,13 +40,26 @@
% - fixed non-DFA syntax hilighting tables to work better
% - added the new assert keyword
-% Changes from v1.2
+% Changes from v1.2:
+%
% - autoindent correction
-% Changes from v1.3
+% Changes from v1.3:
+%
+% - Better indenting of function arguments and tuples
+% - New keywords and builtins added (TJC)
+% - An attempt to do pretty indenting of data structures and parameter lists
+% - Try to keep the lines under 80 columns and make formatting consistent
+
+% Changes from v1.4:
+% (JED)
% - discard return value from run_shell_cmd
% - avoid use of create_array and explicit loop for initializing it.
-
+% (Günter Milde <milde@xxxxxx>)
+% - declared python_mode explicitely a public function
+% - new function python_help (needs the pydoc module)
+% - various small twiddles
+%
$1 = "python";
!if (keymap_p ($1)) make_keymap ($1);
@@ -60,15 +72,19 @@
definekey_reserved ("py_exec_region", "|", $1);
definekey_reserved ("py_reindent_region", "\t", $1);
-definekey ("py_backspace_key", "^?", $1);
-definekey ("indent_line", "\t", $1);
+definekey ("py_backspace_key", Key_BS, $1);
+% definekey ("indent_line", "\t", $1); % not needed: see indent_hook
definekey ("py_electric_colon", ":", $1);
+% These work, but act a bit odd when rebalancing delimiters from the inside.
+% Clues?
+%definekey ("py_electric_paren", ")", $1);
+%definekey ("py_electric_square", "]", $1);
+%definekey ("py_electric_curly", "}", $1);
#ifdef MSWINDOWS
definekey ("py_help_on_word", "^@;", $1);
#endif
-
% Set the following to your favourite indentation level
!if (is_defined ("Py_Indent_Level")) { % users can set this in .jedrc
variable Py_Indent_Level = 4;
@@ -119,28 +135,64 @@
return 0;
}
+static define py_find_matching_delimiter_col()
+{
+ variable col = -1;
+ variable line = -1;
+ variable delim, closest_delim, fnd_col, fnd_line;
+
+ push_spot ();
+ foreach (")]}") {
+ delim = ();
+ bol ();
+ if (1 == find_matching_delimiter (delim)) {
+ fnd_col = what_column ();
+ fnd_line = what_line ();
+ if (fnd_line > line or (fnd_line == line and fnd_col > col)) {
+ line = fnd_line;
+ col = fnd_col;
+ closest_delim = delim;
+ }
+ }
+ goto_spot ();
+ }
+ goto_spot ();
+ bol_skip_white ();
+ if (0 <= col)
+ if (looking_at_char(closest_delim))
+ col -= 1;
+ pop_spot ();
+ return col;
+}
+
static define py_indent_calculate()
{ % return the indentation of the previous python line
variable col = 0;
variable subblock = 0;
-
+
EXIT_BLOCK
{
pop_spot ();
return col;
}
-
+
+ col = py_find_matching_delimiter_col();
+ if (-1 == col)
+ col = 0;
+ else
+ return col;
+
% check if current line starts a sub-block
subblock = py_line_starts_subblock();
-
+
% go to previous non blank line
push_spot_bol ();
!if (re_bsearch ("[^ \t\n]"))
return;
bol_skip_white();
-
+
col = what_column() - 1;
-
+
if (py_line_ends_with_colon())
col += Py_Indent_Level;
if (py_endblock_cmd() or (subblock and not py_line_starts_block()))
@@ -150,42 +202,60 @@
define py_indent_line()
{
variable col;
-
+
col = py_indent_calculate();
bol_trim ();
whitespace( col );
}
-define py_comment_line()
+define py_comment_line()
{
bol();
insert("##");
}
-define py_electric_colon()
+define py_electric_colon()
{
- variable i;
insert(":");
push_spot();
- if (py_line_starts_subblock()) % Only dedents on colon
- {
- pop_spot();
- i = what_column();
+ if (py_line_starts_subblock()) % else:, elif:, except:, finally:
+ {
bol_skip_white();
- i = i - what_column();
if (py_indent_calculate() < what_column()) % Ensure dedent only
py_indent_line();
- bol_skip_white();
- goto_column( i + what_column() );
}
- else
- pop_spot();
+ pop_spot();
+}
+
+% These next four complain about about spurious mismatches when fixing them.
+static define py_electric_delim(delim)
+{
+ insert(delim);
+ push_spot();
+ py_indent_line();
+ pop_spot();
+ blink_match();
+}
+
+define py_electric_paren()
+{
+ py_electric_delim(")");
+}
+
+define py_electric_square()
+{
+ py_electric_delim("]");
+}
+
+define py_electric_curly()
+{
+ py_electric_delim("}");
}
define py_comment_region()
{
variable n;
-
+
check_region (1);
n = what_line ();
pop_mark_1 ();
@@ -197,7 +267,7 @@
pop_spot();
}
-define py_comment()
+define py_comment()
{
push_spot();
if (markp()) {
@@ -208,7 +278,7 @@
pop_spot();
}
-define py_uncomment_line()
+define py_uncomment_line()
{
bol_skip_white();
while (looking_at("#")) del();
@@ -217,7 +287,7 @@
define py_uncomment_region()
{
variable n;
-
+
check_region (1);
n = what_line ();
pop_mark_1 ();
@@ -239,26 +309,26 @@
pop_spot();
}
-define py_backspace_key()
-{
- variable col;
-
- col = what_column();
- push_spot();
- bskip_white();
- if (bolp() and (col > 1)) {
- pop_spot();
- bol_trim ();
- col--;
- if (col mod Py_Indent_Level == 0)
- col--;
- whitespace ( (col / Py_Indent_Level) * Py_Indent_Level );
- }
- else {
- pop_spot();
- call("backward_delete_char_untabify");
- }
-}
+define py_backspace_key()
+{
+ variable col;
+
+ col = what_column();
+ push_spot();
+ bskip_white();
+ if (bolp() and (col > 1)) {
+ pop_spot();
+ bol_trim ();
+ col--;
+ if (col mod Py_Indent_Level == 0)
+ col--;
+ whitespace ( (col / Py_Indent_Level) * Py_Indent_Level );
+ }
+ else {
+ pop_spot();
+ call("backward_delete_char_untabify");
+ }
+}
define py_shift_line_right()
{
@@ -280,7 +350,7 @@
pop_spot();
}
-define py_shift_right()
+define py_shift_right()
{
push_spot();
if (markp()) {
@@ -304,7 +374,7 @@
define py_shift_region_left()
{
variable n;
-
+
check_region (1);
n = what_line ();
pop_mark_1 ();
@@ -339,67 +409,69 @@
substr(fullname, 1, strlen(fullname)-strlen(filename));
}
-define py_exec_region()
-{
- % Run python interpreter on current region.
- % Display output in *shell-output* buffer window.
- variable oldbuf, thisbuf, file, line, start_line;
- variable tmpfile = "_python.tmp";
- variable error_regexp = "^ File \"\\([^\"]+\\)\", line \\(\\d+\\).*";
- variable py_source = buffer_filename();
- change_default_dir(file_path(py_source));
- thisbuf = whatbuf();
- % Check if 1st line starts in column 1
- exchange_point_and_mark();
- bol_skip_white();
- start_line = what_line();
- if (what_column() > 1) {
- % Workaround in case block is indented
- write_string_to_file("if 1:\n", tmpfile); bol();
- start_line--; % offset for this extra line
- }
- exchange_point_and_mark();
- append_region_to_file(tmpfile);
- oldbuf = pop2buf_whatbuf("*shell-output*"); erase_buffer ();
-#ifdef UNIX
- ()=run_shell_cmd(sprintf("python %s 2>&1", tmpfile));
-#else
- ()=run_shell_cmd(sprintf("python %s", tmpfile));
-#endif
- () = delete_file(tmpfile);
-
- % try to restore any window that got replaced by the shell-output
- if (strlen(oldbuf) and (strcmp(oldbuf, "*shell-output*") != 0)
- and (strcmp(thisbuf, oldbuf) != 0)) {
- splitwindow(); sw2buf(oldbuf); pop2buf("*shell-output*");
- }
- eob();
- % Check for error message
- while (re_bsearch(error_regexp) != 0) {
- % Make sure error occurred in the file we were executing
- file = regexp_nth_match(1);
- line = integer(regexp_nth_match(2));
- if (strcmp(file, tmpfile) == 0) {
- % Move to line in source that generated the error
- pop2buf(thisbuf);
- goto_line(line + start_line - 1);
- break;
- } else {
- % Error is in another file, try previous error message
- continue;
- }
- }
+define py_exec_region()
+{
+ % Run python interpreter on current region.
+ % Display output in *shell-output* buffer window.
+ variable oldbuf, file, line, start_line;
+ variable thisbuf = whatbuf();
+ variable tmpfile = "_python.tmp";
+ variable error_regexp = "^ File \"\\([^\"]+\\)\", line \\(\\d+\\).*";
+ variable py_source = buffer_filename();
+
+ () = change_default_dir(file_path(py_source));
+ % Check if 1st line starts in column 1
+ check_region(0); exchange_point_and_mark();
+ bol_skip_white();
+ start_line = what_line();
+ if (what_column() > 1) {
+ % Workaround in case block is indented
+ write_string_to_file("if 1:\n", tmpfile); bol();
+ start_line--; % offset for this extra line
+ }
+ exchange_point_and_mark();
+ append_region_to_file(tmpfile);
+ oldbuf = pop2buf_whatbuf("*shell-output*"); erase_buffer ();
+#ifdef UNIX
+ () = run_shell_cmd(sprintf("python %s 2>&1", tmpfile));
+#else
+ () = run_shell_cmd(sprintf("python %s", tmpfile));
+#endif
+ () = delete_file(tmpfile);
+
+ % try to restore any window that got replaced by the shell-output
+ if (strlen(oldbuf) and (strcmp(oldbuf, "*shell-output*") != 0)
+ and (strcmp(thisbuf, oldbuf) != 0)) {
+ splitwindow(); sw2buf(oldbuf); pop2buf("*shell-output*");
+ }
% if there is no output, then close the shell-window and
% put a message up. This is how emacs works. <jimbag>
if( bobp() and eobp() ) {
- pop2buf( thisbuf );
- onewindow();
message( "No output." );
+ call("delete_window");
+ } else {
+ % Check for error message
+ eob();
+ while (re_bsearch(error_regexp) != 0) {
+ % Make sure error occurred in the file we were executing
+ file = regexp_nth_match(1);
+ line = integer(regexp_nth_match(2));
+ if (strcmp(file, tmpfile) == 0) {
+ % Move to line in source that generated the error
+ pop2buf(thisbuf);
+ goto_line(line + start_line - 1);
+ break;
+ } else {
+ % Error is in another file, try previous error message
+ continue;
+ }
+ }
}
-}
+ pop2buf( thisbuf );
+}
-define py_exec()
+define py_exec()
{
% Run python interpreter on current region if one is defined, otherwise
% on the whole buffer.
@@ -409,6 +481,8 @@
push_mark_eob ();
}
py_exec_region();
+ if (eob) % don't go away from error spots
+ pop_spot();
}
define py_reindent() {
@@ -417,11 +491,10 @@
% Warning: Current version can be fooled by implicit or explicit
% continuation lines.
variable indent_level = Int_Type[64];
- %variable indent_level = create_array('i', 64, 1);
variable level = -1;
variable current_indent = -1;
variable errmsg, i, col, ignore, oldlevel;
-
+
indent_level[*] = -1;
bob();
do {
@@ -437,7 +510,7 @@
indent_level[level] = -1; % clear current level setting
level--;
}
- }
+ }
if ((indent_level[level] != -1) and (indent_level[level] != col)) {
% Indent is wrong. Hopefully it's a continuation line.
level = oldlevel; % reset level
@@ -482,8 +555,7 @@
define_syntax ("#", "", '%', $1); % comments
define_syntax ("([{", ")]}", '(', $1); % delimiters
define_syntax ('"', '"', $1); % quoted strings
-define_syntax ('\'', '"', $1); % quoted strings
-%define_syntax ('\'', '\'', $1); % quoted characters
+define_syntax ('\'', '\'', $1); % quoted characters
define_syntax ('\\', '\\', $1); % continuations
define_syntax ("0-9a-zA-Z_", 'w', $1); % words
define_syntax ("-+0-9a-fA-FjJlLxX.", '0', $1); % Numbers
@@ -491,29 +563,48 @@
define_syntax ("%-+/&*=<>|!~^`", '+', $1); % operators
set_syntax_flags ($1, 0); % keywords ARE case-sensitive
-() = define_keywords ($1, "ifinisor", 2); % all keywords of length 2
+() = define_keywords ($1, "asifinisor", 2); % all keywords of length 2
() = define_keywords ($1, "anddefdelfornottry", 3); % of length 3 ....
() = define_keywords ($1, "elifelseexecfrompass", 4);
-() = define_keywords ($1, "breakclassprintraisewhile", 5);
+() = define_keywords ($1, "breakclassprintraisewhileyield", 5);
() = define_keywords ($1, "assertexceptglobalimportlambdareturn", 6);
() = define_keywords ($1, "finally", 7);
() = define_keywords ($1, "continue", 8);
-% Type 1 keywords (actually these are what's in __builtins__)
+% Type 1 keywords (actually these are most of what is in __builtins__)
() = define_keywords_n ($1, "id", 2, 1);
-() = define_keywords_n ($1, "abschrcmpdirhexintlenmapmaxminoctordpowstr", 3, 1);
-() = define_keywords_n ($1, "Noneevalhashlongopenreprtypevars", 4, 1);
-() = define_keywords_n ($1, "applyfloatinputrangeroundtuple", 5, 1);
-() = define_keywords_n ($1, "coercedivmodfilterlocalsreducereloadxrange", 6, 1);
-() = define_keywords_n ($1, "IOError__doc__compiledelattrgetattrglobalshasattrsetattr", 7, 1);
-() = define_keywords_n ($1, "EOFErrorKeyError__name__callableexecfile", 8, 1);
-() = define_keywords_n ($1, "NameErrorTypeErrorraw_input", 9, 1);
-() = define_keywords_n ($1, "IndexErrorSystemExitValueError__import__", 10, 1);
-() = define_keywords_n ($1, "AccessErrorImportErrorMemoryErrorSyntaxErrorSystemError", 11, 1);
-() = define_keywords_n ($1, "RuntimeError", 12, 1);
-() = define_keywords_n ($1, "ConflictErrorOverflowError", 13, 1);
-() = define_keywords_n ($1, "AttributeError", 14, 1);
-() = define_keywords_n ($1, "KeyboardInterruptZeroDivisionError", 17, 1);
+() = define_keywords_n ($1, "abschrcmpdirhexintlenmapmaxminoctordpowstrzip",
+ 3, 1);
+() = define_keywords_n ($1, "Nonedictevalfilehashiterlistlongopenreprtypevars",
+ 4, 1);
+() = define_keywords_n ($1, "applyfloatinputrangeroundslicetuple", 5, 1);
+() = define_keywords_n ($1, "buffercoercedivmodfilterinternlocalsreducereload"
+ + "unichrxrange",
+ 6, 1);
+() = define_keywords_n ($1, "IOErrorOSError__doc__compilecomplexdelattr"
+ + "getattrglobalshasattrsetattrunicode",
+ 7, 1);
+() = define_keywords_n ($1, "EOFErrorKeyErrorTabError__name__callable"
+ + "execfile",
+ 8, 1);
+() = define_keywords_n ($1, "ExceptionNameErrorTypeErrorraw_input", 9, 1);
+() = define_keywords_n ($1, "IndexErrorSystemExitValueError__import__"
+ + "isinstanceissubclass",
+ 10, 1);
+() = define_keywords_n ($1, "ImportErrorLookupErrorMemoryErrorSyntaxError"
+ + "SystemError",
+ 11, 1);
+() = define_keywords_n ($1, "RuntimeErrorUnicodeError", 12, 1);
+() = define_keywords_n ($1, "ConflictErrorOverflowErrorStandardError", 13, 1);
+() = define_keywords_n ($1, "AssertionErrorAttributeErrorReferenceError",
+ 14, 1);
+() = define_keywords_n ($1, "ArithmeticError", 15, 1);
+() = define_keywords_n ($1, "EnvironmentError", 16, 1);
+() = define_keywords_n ($1, "KeyboardInterruptUnboundLocalError"
+ + "ZeroDivisionError",
+ 17, 1);
+() = define_keywords_n ($1, "FloatingPointError", 18, 1);
+() = define_keywords_n ($1, "NotImplementedError", 19, 1);
#ifdef HAS_DFA_SYNTAX
%%% DFA_CACHE_BEGIN %%%
@@ -537,7 +628,7 @@
dfa_define_highlight_rule("[\\(\\[{}\\]\\),:\\.\"`'=;]", "delimiter", name);
dfa_define_highlight_rule("[\\+\\-\\*/%<>&\\|\\^~]", "operator", name); % 1 char
dfa_define_highlight_rule("<<|>>|==|<=|>=|<>|!=", "operator", name); % 2 char
-
+
% Flag badly formed numeric literals or identifiers. This is more effective
% if you change the error colors so they stand out.
dfa_define_highlight_rule("[1-9][0-9]*[lL]?[0-9A-Za-z\\.]+", "error", name); % bad decimal
@@ -576,10 +667,10 @@
%\seealso{Py_Indent_Level}
%\seealso{set_mode, c_mode}
%!%-
-define python_mode ()
+public define python_mode ()
{
variable python = "python";
-
+
TAB = 8;
set_mode (python, 0x4); % flag value of 4 is generic language mode
use_keymap(python);
@@ -588,3 +679,56 @@
use_syntax_table (python);
run_mode_hooks ("python_mode_hook");
}
+
+% GM addition
+%!%+
+%\function{py_help}
+%\synopsis{Run python's help feature on topic}
+%\usage{ Void py_help([String topic])}
+%\description
+% Call python help on topic and display the help text in a window.
+% If the topic is not given, ask in the minibuffer.
+%\notes
+% Only tested on UNIX
+%\seealso{py_mode}
+%!%-
+define py_help() %([topic])
+{
+ % get optional argument or ask
+ variable topic;
+ if (_NARGS)
+ topic = ();
+ else
+ topic = read_mini("Python Help for: ", "", "");
+
+
+ variable help_cmd = "python -c \"from pydoc import help; ";
+
+ push_spot_bob;
+ do
+ {
+ bol();
+ if (looking_at("from") or looking_at("import"))
+ help_cmd += line_as_string() + "; ";
+ }
+ while(down(1));
+ pop_spot();
+
+ help_cmd += "help(" + topic + ")\"";
+ sw2buf("*Python help*");
+ set_readonly(0);
+ erase_buffer();
+
+ set_prefix_argument (1); % insert output at point
+ flush("Calling: " + help_cmd);
+ do_shell_cmd(help_cmd);
+
+ popup_buffer("*Python help*");
+ set_readonly(1);
+ set_buffer_modified_flag(0);
+ set_mode ("python help", 0x4); % flag value of 4 is generic language mode
+ if (is_defined("help_2click_hook"))
+ set_buffer_hook ( "mouse_2click", "help_2click_hook");
+}
+
+
best regards
Günter Milde
--
Milde at ife.et.tu-dresden.de
--------------------------
To unsubscribe send email to <jed-users-request@xxxxxxxxxxx> with
the word "unsubscribe" in the message body.
Need help? Email <jed-users-owner@xxxxxxxxxxx>.
[2002 date index]
[2002 thread index]
[Thread Prev] [Thread Next]
[Date Prev] [Date Next]