|  | @@ -11,6 +11,8 @@ import (
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  var FindANSIColor *regexp.Regexp
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +const WRITE_DEBUG bool = false
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func init() {
 | 
	
		
			
				|  |  |  	FindANSIColor = regexp.MustCompile("\x1b\\[([0-9;]*)m")
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -140,13 +142,17 @@ Have the Write manage itself.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // For now, update is SavePos + output + RestorePos.
 | 
	
		
			
				|  |  |  // FUTURE: Access the screen struct to "save" Color+Attr+Pos.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func (d *Door) Update(output []byte) {
 | 
	
		
			
				|  |  |  	// sync.Pool ?
 | 
	
		
			
				|  |  | -	var buffer bytes.Buffer
 | 
	
		
			
				|  |  | -	buffer.WriteString(SAVE_POS)
 | 
	
		
			
				|  |  | -	buffer.Write(output)
 | 
	
		
			
				|  |  | -	buffer.WriteString(RESTORE_POS)
 | 
	
		
			
				|  |  | -	d.Writer.Write(buffer.Bytes())
 | 
	
		
			
				|  |  | +	d.WriteA(SAVE_POS, output, RESTORE_POS)
 | 
	
		
			
				|  |  | +	/*
 | 
	
		
			
				|  |  | +		var buffer bytes.Buffer
 | 
	
		
			
				|  |  | +		buffer.WriteString(SAVE_POS)
 | 
	
		
			
				|  |  | +		buffer.Write(output)
 | 
	
		
			
				|  |  | +		buffer.WriteString(RESTORE_POS)
 | 
	
		
			
				|  |  | +		d.Writer.Write(buffer.Bytes())
 | 
	
		
			
				|  |  | +	*/
 | 
	
		
			
				|  |  |  	// d.Write(SAVE_POS + output + RESTORE_POS)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -172,6 +178,7 @@ func (d *Door) WriteA(a ...interface{}) {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +// Is this byte the end of the ANSI CSI?
 | 
	
		
			
				|  |  |  func EndCSI(c byte) bool {
 | 
	
		
			
				|  |  |  	return (c >= 0x40) && (c <= 0x7f)
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -189,7 +196,10 @@ func (d *Door) ANSIProcess() {
 | 
	
		
			
				|  |  |  			d.Writer.LastSavedColor = d.Writer.LastSavedColor[0:slen]
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		copy(d.Writer.LastSavedColor, d.LastColor)
 | 
	
		
			
				|  |  | -		log.Printf("ColorSave: %d\n", d.Writer.LastSavedColor)
 | 
	
		
			
				|  |  | +		if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +			log.Printf("ColorSave: %d\n", d.Writer.LastSavedColor)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	case 'u':
 | 
	
		
			
				|  |  |  		// Restore Color
 | 
	
		
			
				|  |  |  		var slen int = len(d.Writer.LastSavedColor)
 | 
	
	
		
			
				|  | @@ -199,7 +209,9 @@ func (d *Door) ANSIProcess() {
 | 
	
		
			
				|  |  |  			d.LastColor = d.LastColor[0:slen]
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		copy(d.LastColor, d.Writer.LastSavedColor)
 | 
	
		
			
				|  |  | -		log.Printf("ColorRestore: %d\n", d.LastColor)
 | 
	
		
			
				|  |  | +		if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +			log.Printf("ColorRestore: %d\n", d.LastColor)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	case 'm':
 | 
	
		
			
				|  |  |  		// Process color code
 | 
	
		
			
				|  |  |  		var color [5]int
 | 
	
	
		
			
				|  | @@ -231,7 +243,9 @@ func (d *Door) ANSIProcess() {
 | 
	
		
			
				|  |  |  			cpos++
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		log.Printf("color: [%d]", color[0:cpos])
 | 
	
		
			
				|  |  | +		if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +			log.Printf("color: [%d]", color[0:cpos])
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  		var newColor = ParseColorArray(d.LastColor)
 | 
	
		
			
				|  |  |  		for _, c := range color[0:cpos] {
 | 
	
		
			
				|  |  |  			switch c {
 | 
	
	
		
			
				|  | @@ -266,14 +280,20 @@ func (d *Door) ANSIProcess() {
 | 
	
		
			
				|  |  |  		if newColor.BG != -1 {
 | 
	
		
			
				|  |  |  			d.LastColor = append(d.LastColor, newColor.BG+40)
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		log.Printf("LastColor: [%d]", d.LastColor)
 | 
	
		
			
				|  |  | +		if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +			log.Printf("LastColor: [%d]", d.LastColor)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	var outputByte [20]byte
 | 
	
		
			
				|  |  | -	var output []byte = outputByte[0:0]
 | 
	
		
			
				|  |  | +	if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +		var outputByte [20]byte
 | 
	
		
			
				|  |  | +		var output []byte = outputByte[0:0]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		output = fmt.Appendf(output, "ANSI: [%q]\n", d.ansiCode)
 | 
	
		
			
				|  |  | +		log.Printf("%s", output)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	output = fmt.Appendf(output, "ANSI: [%q]\n", d.ansiCode)
 | 
	
		
			
				|  |  | -	log.Printf("%s", output)
 | 
	
		
			
				|  |  | +	// Reset
 | 
	
		
			
				|  |  |  	d.ansiCode = d.ansiCode[0:0]
 | 
	
		
			
				|  |  |  	d.ansiCSI = false
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -326,17 +346,36 @@ func (d *Door) ANSIScan(output []byte) {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +func (d *Door) NewLinesTranslate(output []byte) []byte {
 | 
	
		
			
				|  |  | +	var pos, nextpos int
 | 
	
		
			
				|  |  | +	if d.nlBuffer == nil {
 | 
	
		
			
				|  |  | +		d.nlBuffer = &bytes.Buffer{}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	d.nlBuffer.Reset()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for pos != -1 {
 | 
	
		
			
				|  |  | +		nextpos = bytes.Index(output[pos:], []byte{'\n'})
 | 
	
		
			
				|  |  | +		if nextpos != -1 {
 | 
	
		
			
				|  |  | +			nextpos += pos
 | 
	
		
			
				|  |  | +			// Something to do
 | 
	
		
			
				|  |  | +			d.nlBuffer.Write(output[pos:nextpos])
 | 
	
		
			
				|  |  | +			nextpos++
 | 
	
		
			
				|  |  | +			pos = nextpos
 | 
	
		
			
				|  |  | +			d.nlBuffer.Write([]byte("\r\n"))
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			d.nlBuffer.Write(output[pos:])
 | 
	
		
			
				|  |  | +			pos = nextpos // -1
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	// log.Printf(">> %q\n", ow.nlBuffer.Bytes())
 | 
	
		
			
				|  |  | +	return d.nlBuffer.Bytes()
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func (d *Door) LockedWrite(output []byte) {
 | 
	
		
			
				|  |  |  	if d.writeMutex.TryLock() {
 | 
	
		
			
				|  |  |  		log.Panic("LockedWrite: mutex was NOT locked.")
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	// var lastColorBytes [32]byte
 | 
	
		
			
				|  |  | -	var lastColor string // []byte = lastColorBytes[0:0]
 | 
	
		
			
				|  |  | -	/*
 | 
	
		
			
				|  |  | -		if (bytes.HasPrefix(output, []byte(SavePos))) &&
 | 
	
		
			
				|  |  | -			(bytes.HasSuffix(output, []byte(RestorePos))) {
 | 
	
		
			
				|  |  | -	*/
 | 
	
		
			
				|  |  |  	/*
 | 
	
		
			
				|  |  |  		if bytes.HasSuffix(output, []byte(RestorePos)) {
 | 
	
		
			
				|  |  |  			// Write the current color
 | 
	
	
		
			
				|  | @@ -346,16 +385,24 @@ func (d *Door) LockedWrite(output []byte) {
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	*/
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	log.Printf(">> %q\n", output)
 | 
	
		
			
				|  |  | +	if true {
 | 
	
		
			
				|  |  | +		output = d.NewLinesTranslate(output)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +		log.Printf(">> %q\n", output)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  	d.Writer.Write(output)
 | 
	
		
			
				|  |  |  	d.ANSIScan(output)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if bytes.HasSuffix(output, []byte(RestorePos)) {
 | 
	
		
			
				|  |  | -		lastColor = Color(d.LastColor)
 | 
	
		
			
				|  |  | +		lastColor := Color(d.LastColor)
 | 
	
		
			
				|  |  |  		//fmt.Append(lastColor, []byte(Color(d.LastColor)))
 | 
	
		
			
				|  |  | -		log.Printf("Restore LastColor: %d => %q", d.LastColor, lastColor)
 | 
	
		
			
				|  |  | +		if WRITE_DEBUG {
 | 
	
		
			
				|  |  | +			log.Printf("Restore LastColor: %d => %q", d.LastColor, lastColor)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  		d.Writer.Write([]byte(lastColor))
 | 
	
		
			
				|  |  | -		d.ANSIScan([]byte(lastColor))
 | 
	
		
			
				|  |  | +		//d.ANSIScan([]byte(lastColor))
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	/*
 | 
	
		
			
				|  |  |  		if len(lastColor) != 0 {
 |