1 11 package org.eclipse.jdt.internal.core.dom.rewrite; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Map ; 16 17 import org.eclipse.jface.text.Assert; 18 import org.eclipse.jface.text.BadLocationException; 19 import org.eclipse.jface.text.DefaultLineTracker; 20 import org.eclipse.jface.text.ILineTracker; 21 import org.eclipse.jface.text.IRegion; 22 23 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; 24 25 import org.eclipse.text.edits.ReplaceEdit; 26 27 30 public class Indents { 31 32 private Indents() { 33 } 35 36 42 public static boolean isIndentChar(char ch) { 43 return Character.isWhitespace(ch) && !isLineDelimiterChar(ch); 44 } 45 46 51 public static boolean isLineDelimiterChar(char ch) { 52 return ch == '\n' || ch == '\r'; 53 } 54 55 64 public static int computeIndentUnits(String line, int tabWidth, int indentWidth) { 65 if (indentWidth == 0) 66 return -1; 67 int visualLength= measureIndentLength(line, tabWidth); 68 return visualLength / indentWidth; 69 } 70 71 81 public static int measureIndentLength(CharSequence line, int tabSize) { 82 int length= 0; 83 int max= line.length(); 84 for (int i= 0; i < max; i++) { 85 char ch= line.charAt(i); 86 if (ch == '\t') { 87 int reminder= length % tabSize; 88 length += tabSize - reminder; 89 } else if (isIndentChar(ch)) { 90 length++; 91 } else { 92 return length; 93 } 94 } 95 return length; 96 } 97 98 105 public static String trimIndent(String line, int indentsToRemove, int tabWidth, int indentWidth) { 106 if (line == null || indentsToRemove <= 0) 107 return line; 108 109 final int spaceEquivalentsToRemove= indentsToRemove * indentWidth; 110 111 int start= 0; 112 int spaceEquivalents= 0; 113 int size= line.length(); 114 String prefix= null; 115 for (int i= 0; i < size; i++) { 116 char c= line.charAt(i); 117 if (c == '\t') { 118 int remainder= spaceEquivalents % tabWidth; 119 spaceEquivalents += tabWidth - remainder; 120 } else if (isIndentChar(c)) { 121 spaceEquivalents++; 122 } else { 123 start= i; 125 break; 126 } 127 if (spaceEquivalents == spaceEquivalentsToRemove) { 128 start= i + 1; 129 break; 130 } 131 if (spaceEquivalents > spaceEquivalentsToRemove) { 132 start= i + 1; char[] missing= new char[spaceEquivalents - spaceEquivalentsToRemove]; 137 Arrays.fill(missing, ' '); 138 prefix= new String (missing); 139 break; 140 } 141 } 142 String trimmed; 143 if (start == size) 144 trimmed= ""; else 146 trimmed= line.substring(start); 147 148 if (prefix == null) 149 return trimmed; 150 return prefix + trimmed; 151 } 152 153 154 155 164 public static String getIndentString(String line, int tabWidth, int indentWidth) { 165 int size= line.length(); 166 int end= 0; 167 168 int spaceEquivs= 0; 169 int characters= 0; 170 for (int i= 0; i < size; i++) { 171 char c= line.charAt(i); 172 if (c == '\t') { 173 int remainder= spaceEquivs % tabWidth; 174 spaceEquivs += tabWidth - remainder; 175 characters++; 176 } else if (isIndentChar(c)) { 177 spaceEquivs++; 178 characters++; 179 } else { 180 break; 181 } 182 if (spaceEquivs >= indentWidth) { 183 end += characters; 184 characters= 0; 185 spaceEquivs= spaceEquivs % indentWidth; 186 } 187 } 188 if (end == 0) 189 return ""; else if (end == size) 191 return line; 192 else 193 return line.substring(0, end); 194 } 195 196 203 public static int computeIndentLength(String line, int numberOfIndents, int tabWidth, int indentWidth) { 204 Assert.isTrue(numberOfIndents >= 0); 205 Assert.isTrue(tabWidth >= 0); 206 Assert.isTrue(indentWidth >= 0); 207 208 int spaceEquivalents= numberOfIndents * indentWidth; 209 210 int size= line.length(); 211 int result= -1; 212 int blanks= 0; 213 for (int i= 0; i < size && blanks < spaceEquivalents; i++) { 214 char c= line.charAt(i); 215 if (c == '\t') { 216 int remainder= blanks % tabWidth; 217 blanks += tabWidth - remainder; 218 } else if (isIndentChar(c)) { 219 blanks++; 220 } else { 221 break; 222 } 223 result= i; 224 } 225 if (blanks < spaceEquivalents) 226 return -1; 227 return result + 1; 228 } 229 230 236 public static String changeIndent(String code, int codeIndentLevel, int tabWidth, int indentWidth, String newIndent, String lineDelim) { 237 try { 238 ILineTracker tracker= new DefaultLineTracker(); 239 tracker.set(code); 240 int nLines= tracker.getNumberOfLines(); 241 if (nLines == 1) { 242 return code; 243 } 244 245 StringBuffer buf= new StringBuffer (); 246 247 for (int i= 0; i < nLines; i++) { 248 IRegion region= tracker.getLineInformation(i); 249 int start= region.getOffset(); 250 int end= start + region.getLength(); 251 String line= code.substring(start, end); 252 253 if (i == 0) { buf.append(line); 255 } else { buf.append(lineDelim); 257 buf.append(newIndent); 258 buf.append(trimIndent(line, codeIndentLevel, tabWidth, indentWidth)); 259 } 260 } 261 return buf.toString(); 262 } catch (BadLocationException e) { 263 return code; 265 } 266 } 267 268 278 public static ReplaceEdit[] getChangeIndentEdits(String source, int sourceIndentLevel, int tabWidth, int indentWidth, String newIndent) { 279 ArrayList result= new ArrayList (); 280 try { 281 ILineTracker tracker= new DefaultLineTracker(); 282 tracker.set(source); 283 int nLines= tracker.getNumberOfLines(); 284 if (nLines == 1) 285 return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]); 286 for (int i= 1; i < nLines; i++) { 287 IRegion region= tracker.getLineInformation(i); 288 int offset= region.getOffset(); 289 String line= source.substring(offset, offset + region.getLength()); 290 int length= Indents.computeIndentLength(line, sourceIndentLevel, tabWidth, indentWidth); 291 if (length >= 0) { 292 result.add(new ReplaceEdit(offset, length, newIndent)); 293 } else { 294 length= Indents.computeIndentUnits(line, tabWidth, indentWidth); 295 result.add(new ReplaceEdit(offset, length, "")); } 297 } 298 } catch (BadLocationException cannotHappen) { 299 } 301 return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]); 302 } 303 304 309 public static int getTabWidth(Map options) { 310 return parseIntValue(options, DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, 4); 311 } 312 313 319 public static int getIndentWidth(Map options, int tabWidth) { 320 boolean isMixedMode= DefaultCodeFormatterConstants.MIXED.equals(options.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR)); 321 if (isMixedMode) { 322 return parseIntValue(options, DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, tabWidth); 323 } 324 return tabWidth; 325 } 326 327 private static int parseIntValue(Map options, String key, int def) { 328 try { 329 return Integer.parseInt((String ) options.get(key)); 330 } catch (NumberFormatException e) { 331 return def; 332 } 333 } 334 335 336 342 public static String changeIndent(String code, int codeIndentLevel, int tabWidth, String newIndent, String lineDelim) { 343 return changeIndent(code, codeIndentLevel, tabWidth, tabWidth, newIndent, lineDelim); 344 } 345 346 353 public static int computeIndent(String line, int tabWidth) { 354 return computeIndentUnits(line, tabWidth, tabWidth); 355 } 356 357 } 358 359 | Popular Tags |