1 36 package jline; 37 38 import java.util.*; 39 40 41 85 public class ArgumentCompletor 86 implements Completor 87 { 88 final Completor [] completors; 89 final ArgumentDelimiter delim; 90 boolean strict = true; 91 92 93 99 public ArgumentCompletor (final Completor completor) 100 { 101 this (new Completor [] { completor }); 102 } 103 104 105 111 public ArgumentCompletor (final List completors) 112 { 113 this ((Completor [])completors.toArray ( 114 new Completor [completors.size ()])); 115 } 116 117 118 124 public ArgumentCompletor (final Completor [] completors) 125 { 126 this (completors, new WhitespaceArgumentDelimiter ()); 127 } 128 129 130 137 public ArgumentCompletor (final Completor completor, 138 final ArgumentDelimiter delim) 139 { 140 this (new Completor [] { completor }, delim); 141 } 142 143 144 151 public ArgumentCompletor (final Completor [] completors, 152 final ArgumentDelimiter delim) 153 { 154 this.completors = completors; 155 this.delim = delim; 156 } 157 158 159 163 public void setStrict (final boolean strict) 164 { 165 this.strict = strict; 166 } 167 168 169 173 public boolean getStrict () 174 { 175 return this.strict; 176 } 177 178 179 public int complete (final String buffer, final int cursor, 180 final List candidates) 181 { 182 ArgumentList list = delim.delimit (buffer, cursor); 183 int argpos = list.getArgumentPosition (); 184 int argIndex = list.getCursorArgumentIndex (); 185 186 if (argIndex < 0) 187 return -1; 188 189 final Completor comp; 190 191 if (argIndex >= completors.length) 193 comp = completors [completors.length - 1]; 194 else 195 comp = completors [argIndex]; 196 197 for (int i = 0; getStrict () && i < argIndex; i++) 200 { 201 Completor sub = completors [i >= completors.length 202 ? completors.length - 1 : i]; 203 String [] args = list.getArguments (); 204 String arg = args == null || i >= args.length ? "" : args [i]; 205 206 List subCandidates = new LinkedList (); 207 if (sub.complete (arg, arg.length (), subCandidates) == -1) 208 return -1; 209 210 if (subCandidates.size () == 0) 211 return -1; 212 } 213 214 int ret = comp.complete (list.getCursorArgument (), argpos, candidates); 215 if (ret == -1) 216 return -1; 217 218 int pos = ret + (list.getBufferPosition () - argpos) + 1; 219 220 230 if (cursor != buffer.length () && delim.isDelimiter (buffer, cursor)) 231 { 232 for (int i = 0; i < candidates.size (); i++) 233 { 234 String val = candidates.get (i).toString (); 235 while (val.length () > 0 && 236 delim.isDelimiter (val, val.length () - 1)) 237 val = val.substring (0, val.length () - 1); 238 239 candidates.set (i, val); 240 } 241 } 242 243 ConsoleReader.debug ("Completing " + buffer + "(pos=" + cursor + ") " 244 + "with: " + candidates + ": offset=" + pos); 245 246 return pos; 247 } 248 249 250 257 public static interface ArgumentDelimiter 258 { 259 268 ArgumentList delimit (String buffer, int argumentPosition); 269 270 271 279 boolean isDelimiter (String buffer, int pos); 280 } 281 282 283 290 public static abstract class AbstractArgumentDelimiter 291 implements ArgumentDelimiter 292 { 293 private char [] quoteChars = new char [] { '\'', '"' }; 294 private char [] escapeChars = new char [] { '\\' }; 295 296 297 public void setQuoteChars (final char [] quoteChars) 298 { 299 this.quoteChars = quoteChars; 300 } 301 302 303 public char [] getQuoteChars () 304 { 305 return this.quoteChars; 306 } 307 308 309 public void setEscapeChars (final char [] escapeChars) 310 { 311 this.escapeChars = escapeChars; 312 } 313 314 315 public char [] getEscapeChars () 316 { 317 return this.escapeChars; 318 } 319 320 321 322 public ArgumentList delimit (final String buffer, final int cursor) 323 { 324 List args = new LinkedList (); 325 StringBuffer arg = new StringBuffer (); 326 int argpos = -1; 327 int bindex = -1; 328 329 for (int i = 0; buffer != null && i <= buffer.length (); i++) 330 { 331 if (i == cursor) 334 { 335 bindex = args.size (); 336 argpos = arg.length (); 339 } 340 341 if (i == buffer.length () || isDelimiter (buffer, i)) 342 { 343 if (arg.length () > 0) 344 { 345 args.add (arg.toString ()); 346 arg.setLength (0); } 348 } 349 else 350 { 351 arg.append (buffer.charAt (i)); 352 } 353 } 354 355 return new ArgumentList ( 356 (String [])args.toArray (new String [args.size ()]), 357 bindex, argpos, cursor); 358 } 359 360 361 373 public boolean isDelimiter (final String buffer, final int pos) 374 { 375 if (isQuoted (buffer, pos)) 376 return false; 377 if (isEscaped (buffer, pos)) 378 return false; 379 380 return isDelimiterChar (buffer, pos); 381 } 382 383 384 public boolean isQuoted (final String buffer, final int pos) 385 { 386 return false; 387 } 388 389 390 public boolean isEscaped (final String buffer, final int pos) 391 { 392 if (pos <= 0) 393 return false; 394 395 for (int i = 0; escapeChars != null && i < escapeChars.length; i++) 396 { 397 if (buffer.charAt (pos) == escapeChars [i]) 398 return !isEscaped (buffer, pos - 1); } 400 401 return false; 402 } 403 404 405 413 public abstract boolean isDelimiterChar (String buffer, int pos); 414 } 415 416 417 425 public static class WhitespaceArgumentDelimiter 426 extends AbstractArgumentDelimiter 427 { 428 432 public boolean isDelimiterChar (String buffer, int pos) 433 { 434 return Character.isWhitespace (buffer.charAt (pos)); 435 } 436 } 437 438 439 444 public static class ArgumentList 445 { 446 private String [] arguments; 447 private int cursorArgumentIndex; 448 private int argumentPosition; 449 private int bufferPosition; 450 451 459 public ArgumentList (String [] arguments, int cursorArgumentIndex, 460 int argumentPosition, int bufferPosition) 461 { 462 this.arguments = arguments; 463 this.cursorArgumentIndex = cursorArgumentIndex; 464 this.argumentPosition = argumentPosition; 465 this.bufferPosition = bufferPosition; 466 } 467 468 469 public void setCursorArgumentIndex (int cursorArgumentIndex) 470 { 471 this.cursorArgumentIndex = cursorArgumentIndex; 472 } 473 474 475 public int getCursorArgumentIndex () 476 { 477 return this.cursorArgumentIndex; 478 } 479 480 481 public String getCursorArgument () 482 { 483 if (cursorArgumentIndex < 0 484 || cursorArgumentIndex >= arguments.length) 485 return null; 486 487 return arguments [cursorArgumentIndex]; 488 } 489 490 491 public void setArgumentPosition (int argumentPosition) 492 { 493 this.argumentPosition = argumentPosition; 494 } 495 496 497 public int getArgumentPosition () 498 { 499 return this.argumentPosition; 500 } 501 502 503 public void setArguments (String [] arguments) 504 { 505 this.arguments = arguments; 506 } 507 508 509 public String [] getArguments () 510 { 511 return this.arguments; 512 } 513 514 515 public void setBufferPosition (int bufferPosition) 516 { 517 this.bufferPosition = bufferPosition; 518 } 519 520 521 public int getBufferPosition () 522 { 523 return this.bufferPosition; 524 } 525 } 526 } 527 528 | Popular Tags |