2016-12-24 2 views
9

Ich habe das folgende Problem, wo ich ein ASCII-Zeichen im Terminalfenster zeichnen, und den Cursor an eine andere Position bewegen und den Vorgang mit dem folgenden Code wiederholen.Readline in NodeJS zeichnet unerwünschte Linien

const readline = require('readline'); 

// 
// Set the direction of the cursor 
// 
let dirrection_y = true; 
let dirrection_x = true; 

// 
// Set the initial position of the cursor 
// 
let position_x = 0; 
let position_y = 0; 

// 
// Get the terminal window size 
// 
let window_x = process.stdout.columns; 
let window_y = process.stdout.rows; 

// 
// Set the cursor to the top left corner of the terminal window so we can clear 
// the terminal screen 
// 
readline.cursorTo(process.stdout, position_x, position_y) 

// 
// Clear everything on the screen so we have a clean template to draw on. 
// 
readline.clearScreenDown(process.stdout) 

// 
// Create the interface so we can use it to for example write on the console. 
// 
let rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout, 
}); 

// 
// React to CTR+C so we can close the app, and potentially do something before 
// closing the app. 
// 
rl.on('close', function() { 

    process.exit(0); 

}); 

// 
// Start the main loop 
// 
draw(); 

// 
// The main loop that moves the cursor around the screen. 
// 
function draw() 
{ 
    setTimeout(function() { 

     // 
     // 1. Move the cursor up or down 
     // 
     dirrection_y ? position_y++ : position_y-- 

     // 
     // 2. When we reach the bottom of the terminal window, we switch 
     //  direction from down, to up. 
     // 
     if(position_y == window_y) 
     { 
      // 
      // 1. Switch the direction to go up 
      // 
      dirrection_y = false 

      // 
      // 2. Move the next column or previous one depending on the 
      //  direction. 
      // 
      dirrection_x ? position_x++ : position_x-- 
     } 

     // 
     // 3. When we reach the top of the terminal screen, switch direction 
     //  again 
     // 
     if(position_y < 0) 
     { 
      // 
      // 1. Switch the direction to go down 
      // 
      dirrection_y = true 

      // 
      // 2. Move the next column or previous one depending on the 
      //  direction. 
      // 
      dirrection_x ? position_x++ : position_x-- 
     } 

     // 
     // 4. When we reach the far right of the terminal screen we switch 
     //  direction from 'to right', to 'to left' 
     // 
     if(position_x == window_x) { dirrection_x = false } 

     // 
     // 5. When we reach the far left (beginning) of the terminal window 
     //  we switch direction again. 
     // 
     if(position_x == 0) { dirrection_x = true } 

     // 
     // 6. Write on char on the terminal screen. 
     // 
     rl.write('█'); 

     // 
     // 7. Move the cursor to the next position 
     // 
     readline.cursorTo(process.stdout, position_x, position_y) 

     // 
     // 8. Restart the loop. 
     // 
     draw(); 

    }, 100) 
} 

Alles geht gut, bis ich zu einem Punkt erreichen, an dem es eine volle Linie auf dem Bildschirm zeigt, dass ich nicht wie das Bild unten habe zeichnen zeigt

enter image description here

Wenn Ich halte die App am Laufen, schließlich füllt sich der ganze Bildschirm mit Zeilen, die zeigen, was ich zeichne.

Fragen

Ich glaube nicht, daß ich diese Zeilen zeichnen, wenn das wahr ist, was mit dem Terminal-Fenster geschieht?

Tech Sec

  • macOS
  • Terminal- und iTerm haben das gleiche Problem
  • NodeJS v6.40

Antwort

1

am Sourcecode für Readline- In suchen, glaube ich, an old hack sie hinzugefügt Korrigieren einige Registerkarte Verhalten verursacht weiterhin Probleme für this current line. Immer wenn die Cursorpositions-Spalten bei 0 erkannt werden (wahrscheinlich ein anderer Fehler in der Quelle), wird eine refreshLine --- ausgegeben, die eine Eingabeaufforderung auslöst. Die docs sagen, dass "Die rl.write() - Methode schreibt die Daten auf die Eingabe der readline-Schnittstelle, als ob sie vom Benutzer bereitgestellt wurden.", So die Eingabeaufforderung gibt alle Ihre Eingaben zurück zu Ihnen.

Ich konnte eine Problemumgehung in Quelle nicht finden, aber Sie können den Quellcode der Schnittstelle ändern. Fügen Sie dieses Snippet nach Ihrer const readline = require('readline'); hinzu, um das Problem zu beheben.

readline.Interface.prototype._insertString = function(c) { 
    if (this.cursor < this.line.length) { 
    var beg = this.line.slice(0, this.cursor); 
    var end = this.line.slice(this.cursor, this.line.length); 
    this.line = beg + c + end; 
    this.cursor += c.length; 
    this._refreshLine(); 
    } else { 
    this.line += c; 
    this.cursor += c.length; 
    this.output.write(c); 
    this._moveCursor(0); 
    } 
}; 
+0

Fantastisch, Ihre Erklärung ist auf Punkt und der Code hat gerade gearbeitet! Vielen Dank :) –

+0

Aus Neugier, warum reparierst du dieses Problem nicht mit einer Pull-Anfrage und ersetzen '_insertString' mit dem, was du gerade hier geschrieben hast? –

+1

@DavidGatti yeah gute Idee - Ich arbeite daran - ich muss es nur für den Tab-Fix-Fall und Ihren Fall machen. –