| | 1116 | // Paren Matching |
|---|
| | 1117 | // |
|---|
| | 1118 | /////////////////////////////////////////////////////////////////// |
|---|
| | 1119 | |
|---|
| | 1120 | function 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 | |
|---|
| | 1139 | function 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 | // |
|---|