⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buffer.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
字号:
// Copyright (c) 2002, 2005  Per M.A. Bothner.// This is free software;  for terms and warranty disclaimer see ./COPYING.package gnu.jemacs.buffer;import java.io.*;import gnu.mapping.*;import gnu.lists.*;import gnu.text.*;import gnu.commonlisp.lang.Symbols; // FIXMEpublic abstract class Buffer extends AbstractSequence implements CharSeq{  String name;  Path path;  String encoding;  //boolean modified;  static Buffer current;  public Marker pointMarker;  public Marker markMarker;  /** Buffer-local variable bindings.   * Represented as pairs of (<code>Symbol</code>, value)-pairs:   * For an even integer <code>i</code>, if <code>localBindings[i]</code>   * is a <code>Symbol</code>, there is a buffer-local binding   * whose value is <code>localBindings{i+1]</code>. */  Object[] localBindings;  /** List of modes active for this buffer, major mode first. */  Mode modes;  /** Map buffer names to buffers. */  public static java.util.Hashtable buffers  = new java.util.Hashtable(100);  /** Map file names to buffer.s */  public static java.util.Hashtable fileBuffers  = new java.util.Hashtable(100);  EKeymap localKeymap;  public EKeymap[] activeKeymaps;  int activeLength;  // private EKeymap actual;  /* Count of initial Keymaps in activeKeymaps that have been eliminated,   * because of previous prefix keys. */  int eliminated = 0;  public String getName() { return name; }  public Path getPath () { return path; }  public void setPath (Path path) { this.path = path; }  public String getFileName() { return path.toString(); }  public void setFileName(String fname)  {    String filename = getFileName();    if (filename != null && fileBuffers.get(filename) == this)      fileBuffers.remove(filename);    if (name != null && buffers.get(name) == this)      buffers.remove(name);    File file = new File(fname);    setPath(FilePath.valueOf(file));    name = generateNewBufferName(file.getName());    buffers.put(name, this);    fileBuffers.put(filename, this);    redrawModeline();  }  public abstract CharSeq getStringContent ();  /**   * @see gnu.lists.CharSeq#charAt(int)   */  public char charAt(int index)  {    return getStringContent().charAt(index);  }  /**   * @see gnu.lists.CharSeq#setCharAt(int, char)   */  public void setCharAt(int index, char ch)  {    getStringContent().setCharAt(index, ch);  }  /**   * @see gnu.lists.CharSeq#fill(char)   */  public void fill(char value)  {    getStringContent().fill(value);  }  /**   * @see gnu.lists.CharSeq#fill(int, int, char)   */  public void fill(int fromIndex, int toIndex, char value)  {    getStringContent().fill(fromIndex, toIndex, value);  }  /**   * @see gnu.lists.CharSeq#getChars(int, int, char[], int)   */  public void getChars (int srcBegin, int srcEnd, char[] dst, int dstBegin)  {    getStringContent().getChars(srcBegin, srcEnd, dst, dstBegin);  }  /* #ifdef use:java.lang.CharSequence */  public CharSequence subSequence(int start, int end)  {    return getStringContent().subSequence(start, end);  }  /* #endif */  /* #ifdef JAVA5 */  // /**  //  * @see gnu.lists.CharSeq#writeTo(int, int, Appendable)  //  */  // public void writeTo(int start, int count, Appendable dest)  //   throws java.io.IOException  // {  //   getStringContent().writeTo(start, count, dest);  // }  // public void writeTo(Appendable dest)  //   throws java.io.IOException  // {  //   writeTo(0, length(), dest);  // }  /* #else */  /**   * @see gnu.lists.CharSeq#writeTo(int, int, java.io.Writer)   */  public void writeTo(int start, int count, java.io.Writer dest)    throws java.io.IOException  {    getStringContent().writeTo(start, count, dest);  }  public void writeTo(java.io.Writer str) throws java.io.IOException  {    writeTo(0, length(), str);  }  /* #endif */  /**   * @see gnu.lists.CharSeq#consume(int, int, gnu.lists.Consumer)   */  public void consume(int start, int count, gnu.lists.Consumer out)  {    getStringContent().consume(start, count, out);  }  public static Buffer findFile(String fname)  {    Buffer buffer = (Buffer) fileBuffers.get(fname);    if (buffer == null)      {        buffer = EToolkit.getInstance().newBuffer(null);        buffer.setFileName(fname);	buffer.encoding = System.getProperty("file.encoding", "UTF8");        try          {	    Reader in = new InputStreamReader(new FileInputStream(fname),					      buffer.encoding);            buffer.insertFile(in);            in.close();          }        catch (java.io.FileNotFoundException ex)          {            Signal.message("New file");          }        catch (Exception ex)          {            throw new RuntimeException("error reading file \"" + fname                                       + "\": " + ex);          }      }    return buffer;  }  public static Buffer getBuffer(String name)  {    return (Buffer) buffers.get(name);  }  public static Buffer coerceBuffer(Object buf)  {    if (buf instanceof Buffer)      return (Buffer) buf;    return getBuffer(buf.toString());  }  public static String generateNewBufferName(String start)  {    Buffer buf = getBuffer(start);    if (buf == null)      return start;    int len = start.length();    StringBuffer sbuf = new StringBuffer(len + 5);    sbuf.append(start);    sbuf.append('<');    for (int i = 2;  ;  i++)      {	sbuf.append(i);	sbuf.append('>');	String name = sbuf.toString();	buf = getBuffer(name);	if (buf == null)	  return name;	sbuf.setLength(len+1);      }  }  public abstract void redrawModeline ();  public Buffer (String name)  {    this.name = name;    activeKeymaps = new EKeymap[6];    activeLength = 1;    activeKeymaps[0] = EKeymap.globalKeymap;  }  public int checkMark()  {    return markMarker.getOffset();  }  public static Buffer getCurrent()  {    return current;  }  public static void setCurrent(Buffer buffer)  {    current = buffer;  }  public int getDot()  {    return pointMarker.getOffset();  }  public int getPoint()  {    return 1 + getDot();  }  public void setDot(int i)  {    if (i > maxDot())      throw new Error("set dot to "+i+ " max:"+maxDot());    pointMarker.set(this, i);  }  public final void setPoint(int i)  {    setDot(i - 1);  }  public int minDot()  {    return 0;  }  public abstract int getLength();  public final int length() { return getLength(); }  public abstract int maxDot();  public void forwardChar(int i)  {    pointMarker.forwardChar(i);  }  public void backwardChar(int i)  {    pointMarker.backwardChar(i);  }  public String toString()  {    return "#<buffer \"" + name + "\">";  }  /** Insert count copies of ch at Pos ipos. */  /*  public void insert (char ch, int count, Object style, int ipos)  {  }  */  /** Insert string with given style at position pair. */  public abstract void insert (String string, Object style, int ipos);  /** Insert character with given style at position pair. */  public void insert (char[] chars, int offset, int count, Object style,		      int ipos)  {    insert(new String(chars, offset, count), style, ipos);  }  public void insertAll (Object[] values, Object style)  {    int len = values.length;    for (int i = 0;  i < len;  i++)      {	Object value = values[i];	if (value instanceof Char)	  insert(((Char) value).charValue(), 1, style);	else	  pointMarker.insert(value.toString(), style);      }  }  public void insert (String string, Object style)  {    pointMarker.insert(string, style);  }  public void insert (Object value, Object style)  {    if (value instanceof Char)      insert(((Char) value).charValue(), 1, style);    else      pointMarker.insert(value.toString(), style);  }  /** Insert count copies of ch at point. */  public void insert (char ch, int count)  {    pointMarker.insert(ch, count, null);  }  /** Insert count copies of ch at point. */  public void insert (char ch, int count, Object style)  {    pointMarker.insert(ch, count, style);  }  public void removeChar (int count)  {    pointMarker.removeChar(count);  }  public abstract void removeAll ();  public Marker getPointMarker (boolean share)  {    return share ? pointMarker : new Marker(pointMarker);  }  public Marker getMarkMarker (boolean force)  {    return markMarker;  }  /** Convert an Emacs position (Marker, or 1-origin integer)   * to a (0-origin) buffer offset. */  public int positionToOffset (Object position)  {    if (position instanceof Number)      {	int min = minDot();	int max = maxDot();	int goal = ((Number) position).intValue() - 1;	return goal < min ? min : goal > max ? max : goal;      }    return ((Marker) position).getOffset();  }  public abstract void insertFile(Reader in) throws Exception;  public abstract void save(Writer out) throws Exception;  public void save()  {    try      {	if (encoding == null)	  encoding = System.getProperty("file.encoding", "UTF8");	Writer out = new OutputStreamWriter(path.openOutputStream(),					    encoding);        save(out);        out.close();      }    catch (Exception ex)      {        throw new RuntimeException("error save-buffer: "+ex);      }  }  public void insertFile(String filename)  {    try      {	if (encoding == null)	  encoding = System.getProperty("file.encoding", "UTF8");        Reader in = new InputStreamReader(new FileInputStream(filename),					  encoding);        insertFile(in);        in.close();      }    catch (Exception ex)      {        throw new RuntimeException("error reading file \""+filename+"\": "+ex);      }  }  int tabWidth = 8;  public int charWidth (char ch, int column)  {    if (ch < 0x3000)      {	// Combining forma should probably be 0.	if (ch < ' ')	  {	    if (ch == '\t')	      return (((column + tabWidth) / tabWidth) * tabWidth) - column;	    return 0;	  }      }    else      {	if (ch < 0xD800 // CJK Ideographs	    || (ch >= 0xFF01 && ch <= 0xFF5E)  // Fullwidth ASCII.	    || (ch >= 0xFFe0 && ch <= 0xFFE6)) // Fullwidth punctuation.	  return 2;	if (ch < 0xE000)	  return 0;  // Surrogates.      }    return 1;  }  public int countColumns(char[] chars, int start, int count, int initial)  {    while (--count >= 0)      initial += charWidth (chars[start++], initial);    return initial;  }  public int currentColumn()  {    return currentColumn(getDot());  }  /** Return the column number at a specified offset. */  public int currentColumn(int offset)  {    try      {	int lineStart = lineStartOffset(offset);	InPort port = openReader(lineStart, offset - lineStart);	int column = 0;	while (port.read() >= 0)	  {	    // Subtract one from pos, to undo the read we just did.	    int start = port.pos - 1;	    column = countColumns(port.buffer, start, port.limit - start, column);	    port.pos = port.limit;	  }	return column;      }    catch (java.io.IOException ex)      {	throw new WrappedException(ex);      }  }  public int moveToColumn(int column, boolean force)  {     return pointMarker.moveToColumn(column, force);  }  public abstract int lineStartOffset(int offset);  public int lineStartOffset()  {    return lineStartOffset(getDot());  }  /** Search in BUF for COUNT instances of the character TARGET between START and END.   * If COUNT is positive, search forwards; END must be >= START.   * If COUNT is negative, search backwards for the -COUNTth instance;   *   END must be <= START.   * If COUNT is zero, do anything you please; run rogue, for all I care.   * If END is zero, use beginning or end of (FIXME: accessible part of)   * the buffer, as appropriate for the direction indicated by COUNT.   *   * If we find COUNT instances, SHORTAGE is zero, and return the   * position after the COUNTth match.  Note that for reverse motion   * this is not the same as the usual convention for Emacs motion commands.   * If we don't find COUNT instances before reaching END, set SHORTAGE   * to the number of TARGETs left unfound, and return (shortage<<32|END).   * @return (SHORTAGE<<32|POS)  */  public abstract long scan(char target, int start, int end,			    int count, boolean allowQuit);    /** Find the position a give number of lines forward or backward.   * A side-effect-free version of Emacs's forward-line function.   * @param lines number of lines forward (or backward if negative)   * @param start initial position (buffer offset)   * @return (SHORTAGE<<32|POS)   */  public final long forwardLine(int lines, int start)  {    boolean neg = lines <= 0;    long scanned = scan('\n', start, 0, lines - (neg ? 1 : 0), true);    int shortage = (int) (scanned >> 32);    int pos = (int) scanned;    if (shortage > 0	&& (neg	    || (maxDot() > minDot() && pos != start		&& charAt(pos - 1) != '\n')))      shortage--;    return ((long) (neg ? -shortage : shortage) << 32) | (long) pos;  }  public int forwardLine(int lines)  {    long value = forwardLine(lines, getDot());    setDot((int) value);    return (int) (value >> 32);  }  public EWindow display(boolean notThisWindow, EFrame frame)  {    if (frame == null)      frame = EFrame.getSelectedFrame();    EWindow selected = frame.getSelectedWindow();    EWindow window = frame.otherWindow(1);    if (selected == window && notThisWindow)      window = selected.split(-1, false);    window.setBuffer(this);    return window;  }  /*  public Element createLeafElement(Element parent, AttributeSet attributes,                                   int p0, int p1)  {    p0 = content.createPosition(p0, p0!=0);    p1 = content.createPosition(p1, true);    return new Leaf(this, parent, attributes, p0, p1);  }  */  /**   * @param all true if make-variable-buffer-local,   *  false if make-local-variable FIXME   */  public static void makeBufferLocal(Object symbol, boolean all)  {    BufferLocal.make(Symbols.getSymbol(symbol), all);  }  public EKeymap getLocalKeymap() { return localKeymap; }  public void setLocalKeymap(EKeymap map)  {    // First remove the old local map.    if (localKeymap != null)      {        activeKeymaps[activeLength-2] = activeKeymaps[activeLength-1];        activeLength--;        localKeymap = null;      }    if (map != null)      {        activeKeymaps[activeLength] = activeKeymaps[activeLength-1];        activeKeymaps[activeLength-1]= map;        activeLength++;        localKeymap = map;      }  }  public abstract InPort openReader (int start, int count);  public abstract long savePointMark ();    public abstract void restorePointMark (long pointMark);  /**   * This is intended for Runnable's that may affect the state of the buffer.    * The implementation should make shure that the GUI is properly updated before   * control returns   *    *  @param doRun   */  public abstract void invoke(Runnable doRun);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -