1 4 package gnu.jemacs.buffer; 5 import java.io.*; 6 import gnu.mapping.*; 7 import gnu.lists.*; 8 import gnu.text.Char; 9 import gnu.commonlisp.lang.Symbols; 11 public abstract class Buffer extends AbstractSequence implements CharSeq 12 { 13 String name; 14 String filename; 15 String encoding; 16 18 static Buffer current; 19 20 public Marker pointMarker; 21 public Marker markMarker; 22 23 28 Object [] localBindings; 29 30 31 Mode modes; 32 33 34 public static java.util.Hashtable buffers 35 = new java.util.Hashtable (100); 36 37 38 public static java.util.Hashtable fileBuffers 39 = new java.util.Hashtable (100); 40 41 EKeymap localKeymap; 42 public EKeymap[] activeKeymaps; 43 int activeLength; 44 47 int eliminated = 0; 48 49 public String getName() { return name; } 50 51 public String getFileName() { return filename; } 52 53 public void setFileName(String fname) 54 { 55 if (filename != null && fileBuffers.get(filename) == this) 56 fileBuffers.remove(filename); 57 if (name != null && buffers.get(name) == this) 58 buffers.remove(name); 59 filename = fname; 60 name = generateNewBufferName(new java.io.File (fname).getName()); 61 buffers.put(name, this); 62 fileBuffers.put(filename, this); 63 redrawModeline(); 64 } 65 66 public abstract CharSeq getStringContent (); 67 68 71 public char charAt(int index) 72 { 73 return getStringContent().charAt(index); 74 } 75 76 79 public void setCharAt(int index, char ch) 80 { 81 getStringContent().setCharAt(index, ch); 82 } 83 84 87 public void fill(char value) 88 { 89 getStringContent().fill(value); 90 } 91 92 95 public void fill(int fromIndex, int toIndex, char value) 96 { 97 getStringContent().fill(fromIndex, toIndex, value); 98 } 99 100 103 public void getChars (int srcBegin, int srcEnd, char[] dst, int dstBegin) 104 { 105 getStringContent().getChars(srcBegin, srcEnd, dst, dstBegin); 106 } 107 108 109 public CharSequence subSequence(int start, int end) 110 { 111 return getStringContent().subSequence(start, end); 112 } 113 114 115 124 130 133 public void writeTo(int start, int count, java.io.Writer dest) 134 throws java.io.IOException 135 { 136 getStringContent().writeTo(start, count, dest); 137 } 138 139 public void writeTo(java.io.Writer str) throws java.io.IOException 140 { 141 writeTo(0, length(), str); 142 } 143 144 145 148 public void consume(int start, int count, gnu.lists.Consumer out) 149 { 150 getStringContent().consume(start, count, out); 151 } 152 153 public static Buffer findFile(String fname) 154 { 155 Buffer buffer = (Buffer) fileBuffers.get(fname); 156 if (buffer == null) 157 { 158 buffer = EToolkit.getInstance().newBuffer(null); 159 buffer.setFileName(fname); 160 buffer.encoding = System.getProperty("file.encoding", "UTF8"); 161 try 162 { 163 Reader in = new InputStreamReader(new FileInputStream(fname), 164 buffer.encoding); 165 buffer.insertFile(in); 166 in.close(); 167 } 168 catch (java.io.FileNotFoundException ex) 169 { 170 Signal.message("New file"); 171 } 172 catch (Exception ex) 173 { 174 throw new RuntimeException ("error reading file \"" + fname 175 + "\": " + ex); 176 } 177 } 178 return buffer; 179 } 180 181 public static Buffer getBuffer(String name) 182 { 183 return (Buffer) buffers.get(name); 184 } 185 186 public static Buffer coerceBuffer(Object buf) 187 { 188 if (buf instanceof Buffer) 189 return (Buffer) buf; 190 return getBuffer(buf.toString()); 191 } 192 193 public static String generateNewBufferName(String start) 194 { 195 Buffer buf = getBuffer(start); 196 if (buf == null) 197 return start; 198 int len = start.length(); 199 StringBuffer sbuf = new StringBuffer (len + 5); 200 sbuf.append(start); 201 sbuf.append('<'); 202 for (int i = 2; ; i++) 203 { 204 sbuf.append(i); 205 sbuf.append('>'); 206 String name = sbuf.toString(); 207 buf = getBuffer(name); 208 if (buf == null) 209 return name; 210 sbuf.setLength(len+1); 211 } 212 } 213 214 215 public abstract void redrawModeline (); 216 217 public Buffer (String name) 218 { 219 this.name = name; 220 221 activeKeymaps = new EKeymap[6]; 222 activeLength = 1; 223 activeKeymaps[0] = EKeymap.globalKeymap; 224 } 225 226 public int checkMark() 227 { 228 return markMarker.getOffset(); 229 } 230 231 public static Buffer getCurrent() 232 { 233 return current; 234 } 235 236 public static void setCurrent(Buffer buffer) 237 { 238 current = buffer; 239 } 240 241 public int getDot() 242 { 243 return pointMarker.getOffset(); 244 } 245 246 public int getPoint() 247 { 248 return 1 + getDot(); 249 } 250 251 public void setDot(int i) 252 { 253 if (i > maxDot()) 254 throw new Error ("set dot to "+i+ " max:"+maxDot()); 255 pointMarker.set(this, i); 256 } 257 258 public final void setPoint(int i) 259 { 260 setDot(i - 1); 261 } 262 263 public int minDot() 264 { 265 return 0; 266 } 267 268 public abstract int getLength(); 269 270 public final int length() { return getLength(); } 271 272 public abstract int maxDot(); 273 274 public void forwardChar(int i) 275 { 276 pointMarker.forwardChar(i); 277 } 278 279 public void backwardChar(int i) 280 { 281 pointMarker.backwardChar(i); 282 } 283 284 public String toString() 285 { 286 return "#<buffer \"" + name + "\">"; 287 } 288 289 290 295 296 297 public abstract void insert (String string, Object style, int ipos); 298 299 300 public void insert (char[] chars, int offset, int count, Object style, 301 int ipos) 302 { 303 insert(new String (chars, offset, count), style, ipos); 304 } 305 306 public void insertAll (Object [] values, Object style) 307 { 308 int len = values.length; 309 for (int i = 0; i < len; i++) 310 { 311 Object value = values[i]; 312 if (value instanceof Char) 313 insert(((Char) value).charValue(), 1, style); 314 else 315 pointMarker.insert(value.toString(), style); 316 } 317 } 318 319 public void insert (String string, Object style) 320 { 321 pointMarker.insert(string, style); 322 } 323 324 public void insert (Object value, Object style) 325 { 326 if (value instanceof Char) 327 insert(((Char) value).charValue(), 1, style); 328 else 329 pointMarker.insert(value.toString(), style); 330 } 331 332 333 public void insert (char ch, int count) 334 { 335 pointMarker.insert(ch, count, null); 336 } 337 338 339 public void insert (char ch, int count, Object style) 340 { 341 pointMarker.insert(ch, count, style); 342 } 343 344 public void removeChar (int count) 345 { 346 pointMarker.removeChar(count); 347 } 348 349 public abstract void removeAll (); 350 351 public Marker getPointMarker (boolean share) 352 { 353 return share ? pointMarker : new Marker(pointMarker); 354 } 355 356 public Marker getMarkMarker (boolean force) 357 { 358 return markMarker; 359 } 360 361 363 public int positionToOffset (Object position) 364 { 365 if (position instanceof Number ) 366 { 367 int min = minDot(); 368 int max = maxDot(); 369 int goal = ((Number ) position).intValue() - 1; 370 return goal < min ? min : goal > max ? max : goal; 371 } 372 return ((Marker) position).getOffset(); 373 } 374 375 public abstract void insertFile(Reader in) throws Exception ; 376 377 public abstract void save(Writer out) throws Exception ; 378 379 public void save() 380 { 381 try 382 { 383 if (encoding == null) 384 encoding = System.getProperty("file.encoding", "UTF8"); 385 Writer out = new OutputStreamWriter(new FileOutputStream(filename), 386 encoding); 387 save(out); 388 out.close(); 389 } 390 catch (Exception ex) 391 { 392 throw new RuntimeException ("error save-buffer: "+ex); 393 } 394 } 395 396 public void insertFile(String filename) 397 { 398 try 399 { 400 if (encoding == null) 401 encoding = System.getProperty("file.encoding", "UTF8"); 402 Reader in = new InputStreamReader(new FileInputStream(filename), 403 encoding); 404 insertFile(in); 405 in.close(); 406 } 407 catch (Exception ex) 408 { 409 throw new RuntimeException ("error reading file \""+filename+"\": "+ex); 410 } 411 } 412 413 int tabWidth = 8; 414 415 public int charWidth (char ch, int column) 416 { 417 if (ch < 0x3000) 418 { 419 if (ch < ' ') 421 { 422 if (ch == '\t') 423 return (((column + tabWidth) / tabWidth) * tabWidth) - column; 424 return 0; 425 } 426 } 427 else 428 { 429 if (ch < 0xD800 || (ch >= 0xFF01 && ch <= 0xFF5E) || (ch >= 0xFFe0 && ch <= 0xFFE6)) return 2; 433 if (ch < 0xE000) 434 return 0; } 436 return 1; 437 } 438 439 public int countColumns(char[] chars, int start, int count, int initial) 440 { 441 while (--count >= 0) 442 initial += charWidth (chars[start++], initial); 443 return initial; 444 } 445 446 public int currentColumn() 447 { 448 return currentColumn(getDot()); 449 } 450 451 452 public int currentColumn(int offset) 453 { 454 try 455 { 456 int lineStart = lineStartOffset(offset); 457 InPort port = openReader(lineStart, offset - lineStart); 458 int column = 0; 459 while (port.read() >= 0) 460 { 461 int start = port.pos - 1; 463 column = countColumns(port.buffer, start, port.limit - start, column); 464 port.pos = port.limit; 465 } 466 return column; 467 } 468 catch (java.io.IOException ex) 469 { 470 throw new WrappedException(ex); 471 } 472 } 473 474 public int moveToColumn(int column, boolean force) 475 { 476 return pointMarker.moveToColumn(column, force); 477 } 478 479 public abstract int lineStartOffset(int offset); 480 481 public int lineStartOffset() 482 { 483 return lineStartOffset(getDot()); 484 } 485 486 502 public abstract long scan(char target, int start, int end, 503 int count, boolean allowQuit); 504 505 511 public final long forwardLine(int lines, int start) 512 { 513 boolean neg = lines <= 0; 514 long scanned = scan('\n', start, 0, lines - (neg ? 1 : 0), true); 515 int shortage = (int) (scanned >> 32); 516 int pos = (int) scanned; 517 if (shortage > 0 518 && (neg 519 || (maxDot() > minDot() && pos != start 520 && charAt(pos - 1) != '\n'))) 521 shortage--; 522 return ((long) (neg ? -shortage : shortage) << 32) | (long) pos; 523 } 524 525 public int forwardLine(int lines) 526 { 527 long value = forwardLine(lines, getDot()); 528 setDot((int) value); 529 return (int) (value >> 32); 530 } 531 532 public EWindow display(boolean notThisWindow, EFrame frame) 533 { 534 if (frame == null) 535 frame = EFrame.getSelectedFrame(); 536 EWindow selected = frame.getSelectedWindow(); 537 EWindow window = frame.otherWindow(1); 538 if (selected == window && notThisWindow) 539 window = selected.split(-1, false); 540 window.setBuffer(this); 541 return window; 542 } 543 544 553 554 558 public static void makeBufferLocal(Object symbol, boolean all) 559 { 560 BufferLocal.make(Symbols.getSymbol(symbol), all); 561 } 562 563 public EKeymap getLocalKeymap() { return localKeymap; } 564 565 public void setLocalKeymap(EKeymap map) 566 { 567 if (localKeymap != null) 569 { 570 activeKeymaps[activeLength-2] = activeKeymaps[activeLength-1]; 571 activeLength--; 572 localKeymap = null; 573 } 574 if (map != null) 575 { 576 activeKeymaps[activeLength] = activeKeymaps[activeLength-1]; 577 activeKeymaps[activeLength-1]= map; 578 activeLength++; 579 localKeymap = map; 580 } 581 } 582 583 public abstract InPort openReader (int start, int count); 584 585 public abstract long savePointMark (); 586 587 public abstract void restorePointMark (long pointMark); 588 589 596 public abstract void invoke(Runnable doRun); 597 598 } 599 | Popular Tags |