/* * Close_Last_Open_Tag.py - Inserts a closing tag for the * last un-closed element. This macro assumes it's bound * to "/", so will always insert a "/". It's intentionally * naive -- it simply scans backwards in the buffer, ignoring * self-closing elements and closes the last open one. This * makes it useful for HTML/XML in Javadocs, strings, comments, * etc... where the XML plugin's tag insertion won't work. * * Copyright (C) 2004 Ollie Rutherfurd * * $Id$ */ void closeLastOpenTag(View view){ JEditTextArea textArea = view.getTextArea(); int caret = textArea.getCaretPosition(); char[] chars = textArea.getText(0,caret).toCharArray(); int pos = caret-1; int stack = 0; boolean skip = false; // at start of buffer or "/" not following "<". if((pos == 0) || ((pos > 1) && (chars[pos] != '<'))) { textArea.setSelectedText("/"); return; } char c, n; pos--; // always need two chars while(pos >= 0) { c = chars[pos]; n = chars[pos+1]; if(c == '<') { if(n == '/') stack--; else if('A' <= n && n <= 'z') { if(!skip) { stack++; if(stack > 0) { int i = pos + 1; StringBuffer tag = new StringBuffer("/"); while(i < chars.length) { char x = chars[i]; if((x >= 'A' && x <= 'z') || (x >= '0' && x <= '9') || (x == '_') || (x == ':') || (x == '-')) tag.append(x); else break; i++; } tag.append(">"); textArea.setSelectedText(tag.toString()); return; } } } } else if(c == '/' && n == '>') skip = true; pos--; } textArea.setSelectedText("/"); } if(!buffer.isReadOnly() && textArea.hasFocus()) closeLastOpenTag(view);