jed-users mailing list

[2002 Date Index] [2002 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

Re: Re: pymode patch (1.3.1 + 1.4 -> 1.4.1)


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]