Ticket #3646: 3646-paren-matching-all.patch

File 3646-paren-matching-all.patch, 6.7 kB (added by boothby, 4 months ago)
  • 3646/sage/server/notebook/js.py

    old new  
    11131113 
    11141114///////////////////////////////////////////////////////////////////  
    11151115//  
     1116// Paren Matching 
     1117//  
     1118/////////////////////////////////////////////////////////////////// 
     1119 
     1120function paren_jump(cell,i,c,eat) { 
     1121    /* 
     1122    INPUT: 
     1123        cell: a textarea object 
     1124        i:    the index of where to insert/replace a paren 
     1125        c:    the character to insert (may be empty) 
     1126        eat:  whether or not to eat the character at i 
     1127 
     1128    OUTPUT: 
     1129        Replaces / inserts the desired paren, and moves the 
     1130        cursor to immediately after the paren. 
     1131    */ 
     1132    var j = i; 
     1133    if(eat) 
     1134        j++; 
     1135    cell.value = cell.value.substring(0,i) + c + cell.value.substring(j); 
     1136    set_cursor_position(cell, i+c.length); 
     1137} 
     1138 
     1139function paren_match(cell) { 
     1140    /* 
     1141    Fix parentheses / braces / brackets.  If mis-matched parentheses 
     1142    are found, fix them.  If an unmatched paren is found, insert it  
     1143    at the cursor.  This is implemented via a character-by-character 
     1144    lexer, so quotes and comments are handled appropriately.  Perhaps 
     1145    in the future this lexer will be generalized so it can be used 
     1146    for other stuff. 
     1147 
     1148    EXAMPLES:  (the pipe character indicates cursor position) 
     1149        IN: 
     1150            this = some(sample.code( 
     1151                        "foo))", 
     1152            #           bar)), 
     1153                        baz| 
     1154        OUT: 
     1155            this = some.code( 
     1156                        "foo)", 
     1157            #           bar), 
     1158                        baz)| 
     1159 
     1160        IN: 
     1161            foo = bar(baz(],a,b,c)| 
     1162        OUT: 
     1163            foo = bar(baz()|,a,b,c) 
     1164 
     1165        IN: 
     1166            foo = bar()| 
     1167        OUT: 
     1168            foo = bar()| 
     1169 
     1170        IN: 
     1171            foo = bar]bar()| 
     1172        OUT: 
     1173            foo = bar|bar() 
     1174 
     1175    INPUT: 
     1176        a cell object (textarea) 
     1177 
     1178    OUTPUT: 
     1179        the text in the cell is possibly changed, and the cursor may move. 
     1180    */ 
     1181    var quote = ''; 
     1182    var comment = false; 
     1183    var escape = false; 
     1184    var txt = cell.value.substring(0,get_cursor_position(cell)) 
     1185    var n = txt.length; 
     1186    var pstack = []; 
     1187    var squo = "'", dquo = '"', hash = "#", cr   = '\n', esc  = '\\', empty = '', 
     1188        lpar = '(', rpar = ')', lbrk = '[', rbrk = ']', lbrc = '{', rbrc = '}'; 
     1189    var deparen = Array(); 
     1190    deparen[lpar] = rpar; 
     1191    deparen[lbrc] = rbrc; 
     1192    deparen[lbrk] = rbrk; 
     1193 
     1194    for(i=0;i<n;i++) { 
     1195        c = txt[i]; 
     1196        if(quote != empty) { 
     1197            if(escape) 
     1198                escape = false; 
     1199            else if(c == quote) 
     1200                quote=empty; 
     1201            else if(c == esc) 
     1202                escape=true; 
     1203        } else if(comment) { 
     1204            if(c == cr) 
     1205                comment = false; 
     1206        } else switch(c) { 
     1207          case lpar: 
     1208          case lbrc: 
     1209          case lbrk: 
     1210            pstack.push(c); 
     1211            break; 
     1212          case rpar: 
     1213          case rbrc: 
     1214          case rbrk: 
     1215            if(pstack.length < 0) { 
     1216                paren_jump(cell,i,'',true); 
     1217                return; 
     1218            } 
     1219            p = pstack.pop(); 
     1220            if(deparen[p] != c) { 
     1221                paren_jump(cell,i,deparen[p],true); 
     1222                return; 
     1223            } 
     1224            break; 
     1225          case squo: 
     1226            quote = squo; 
     1227            break; 
     1228          case dquo: 
     1229            quote = dquo; 
     1230            break; 
     1231          case hash: 
     1232            comment=true 
     1233            break; 
     1234        } 
     1235    } 
     1236    p = pstack.pop(); 
     1237    i = txt.length; 
     1238    if(quote == empty && !comment && p != undefined) 
     1239        paren_jump(cell,i,deparen[p],false); 
     1240} 
     1241 
     1242 
     1243 
     1244///////////////////////////////////////////////////////////////////  
     1245//  
    11161246// WORKSHEET functions -- for switching between and managing worksheets  
    11171247//  
    11181248/////////////////////////////////////////////////////////////////// 
     
    20532183       history_window(); 
    20542184    } else if (key_request_log(e)) { 
    20552185       text_log_window(worksheet_filename); 
     2186    } else if (key_fix_paren(e)) { 
     2187       paren_match(cell_input); 
    20562188    } 
    20572189     
    20582190    // An actual non-controlling character was sent, which means this cell has changed. 
  • 3646/sage/server/notebook/config.py

    old new  
    4141js.keyhandler.add('uncomment',              key = "KEY_COMMA", ctrl=True) 
    4242js.keyhandler.add('comment',                key = "KEY_3",     ctrl=True) 
    4343js.keyhandler.add('uncomment',              key = "KEY_4",     ctrl=True) 
     44js.keyhandler.add('fix_paren',              key = "KEY_0",     ctrl=True) 
     45js.keyhandler.add('fix_paren',              key = "KEY_RBRACK",     ctrl=True) 
    4446 
    4547js.keyhandler.add('control',                key = "KEY_CTRL") 
    4648js.keyhandler.add('backspace',              key = "KEY_BKSPC") 
  • 3646/sage/server/notebook/tutorial.py

    old new  
    384384#                ('Emacs Keybindings', 'If you are using GNU/Linux, you can change (or create) a <tt>.gtkrc-2.0</tt> file.  Add the line <tt>gtk-key-theme-name = "Emacs"</tt> to it.  See <a target="_blank" href="http://kb.mozillazine.org/Emacs_Keybindings_(Firefox)">this page</a> [mozillazine.org] for more details.'), 
    385385 #               ('More Help', 'Type "help(sage.server.notebook.notebook)" for a detailed discussion of the architecture of the SAGE notebook and a tutorial (or see the SAGE reference manual).'), 
    386386#                ('Javascript Debugger', 'Type ?debug at the end of a worksheet url to enable the javascript debugger.  A pair of textareas will appear at the top of the worksheet -- the upper of which is for output, the lower is a direct interface to the page\'s javascript environment.  Type any eval()-able javascript into the input box and press shift+enter to execute it.  Type debug_append(str) to print to, and debug_clear() to clear the debug output window.'), 
     387            ('Paren matching', 'To fix unmatched or mis-matched parentheses, braces or brackets, press ctrl-0 or ctrl-].  Parentheses / brackets / braces to the left of / above the cursor will be matched, minding strings and comments.  Note, only python comments are recogized, so this won\'t work for c-style multiline comments, etc.') 
    387388                ] 
    388389 
    389390notebook_help.sort()