001: // Copyright (c) 2002 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.jemacs.buffer;
005:
006: import gnu.mapping.*;
007: import java.io.*;
008:
009: public class ProcessMode extends Mode {
010: protected Writer toInferior;
011:
012: protected Marker processMark;
013:
014: protected boolean lineMode = false;
015:
016: static Procedure enterAction = new gnu.expr.PrimProcedure(
017: gnu.bytecode.ClassType
018: .make("gnu.jemacs.buffer.ProcessMode")
019: .getDeclaredMethod("enterAction", 0));
020:
021: public static EKeymap modeMap = new EKeymap("process");
022: static {
023: modeMap.defineKey("\n", enterAction);
024: modeMap.defineKey("\r", enterAction);
025: modeMap.defineKey("enter", enterAction);
026: modeMap.defineKey("return", enterAction);
027: Object insert = new ProcessInsertCommand();
028: // modeMap.setDefaultBinding(insert);
029: modeMap.set(' ', 126, insert);
030: modeMap.set(128, 255, insert);
031: }
032:
033: public Marker getProcessMark() {
034: return processMark;
035: }
036:
037: public static void enterAction() {
038: Buffer buffer = Buffer.getCurrent();
039: ProcessMode pmode = getProcessMode(buffer);
040: pmode.enter();
041: }
042:
043: public void enter() {
044: try {
045: if (lineMode) {
046: buffer.insert('\n', 1, null);
047: int pos = buffer.getDot();
048: int markPos = processMark.getOffset();
049:
050: buffer.writeTo(markPos, pos - markPos, toInferior);
051: processMark.setDot(pos);
052: } else
053: toInferior.write('\r');
054: toInferior.flush();
055: } catch (Exception ex) {
056: throw new WrappedException(ex);
057: }
058: }
059:
060: public static ProcessMode getProcessMode(Buffer buffer) {
061: for (Mode mode = buffer.modes;; mode = mode.next) {
062: if (mode == null)
063: Signal.error("not in process mode");
064: if (mode instanceof ProcessMode)
065: return (ProcessMode) mode;
066: }
067: }
068:
069: public void writeToInferior(gnu.lists.CharSeq str)
070: throws java.io.IOException {
071: str.writeTo(toInferior);
072: toInferior.flush();
073: }
074:
075: public void selfInsert() {
076: EWindow window = EWindow.getSelected();
077: insert((char) window.pendingKeys[window.pendingLength], 1);
078: }
079:
080: public void insert(char ch, int count) {
081: if (!lineMode) {
082: try {
083: while (--count >= 0)
084: toInferior.write(ch);
085: toInferior.flush();
086: } catch (Exception ex) {
087: throw new WrappedException(ex);
088: }
089: } else
090: buffer.insert(ch, count);
091: }
092:
093: /**
094: *
095: * @param doRun
096: */
097: public void invoke(Runnable doRun) {
098: buffer.invoke(doRun);
099: }
100: }
101:
102: class ProcessInsertCommand extends Procedure0 {
103: public Object getProperty(Object key, Object defaultValue) {
104: if (key == "emacs-interactive")
105: return "*";
106: return super .getProperty(key, defaultValue);
107: }
108:
109: public Object apply0() {
110: EWindow window = EWindow.getSelected();
111: Buffer buffer = window.buffer;
112: ProcessMode pmode = ProcessMode.getProcessMode(buffer);
113: pmode
114: .insert(
115: (char) window.pendingKeys[window.pendingLength],
116: 1);
117: return Values.empty;
118: }
119: }
|