Created
January 16, 2017 06:22
-
-
Save hawkins/5c05d077a5d15d95404c3bb56b2a81d7 to your computer and use it in GitHub Desktop.
Node.js blessed screen - keep your output separate from your input!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* I've used blessed to create a textbox at the bottom line in the screen. | |
* The rest of the screen is the 'body' where your code output will be added. | |
* This way, when you type input, your program won't muddle it with output. | |
* | |
* To try this code: | |
* - $ npm install blessed --save | |
* - $ node screen.js | |
* | |
* Key points here are: | |
* - Your code should show output using the log function. | |
* Think of this as a console.log drop-in-replacement. | |
* Don't use console.* functions anymore, they'll mess up blessed's screen. | |
* - You have to 'focus' the inputBar element for it to receive input. | |
* You can have it always focused, however, but my demonstration shows listening for an enter key press or click on the blue bar to focus it. | |
* - If you write code that manipulates the screen, remember to run screen.render() to render your changes. | |
*/ | |
const blessed = require('blessed'); | |
var screen = blessed.screen(); | |
var body = blessed.box({ | |
top: 0, | |
left: 0, | |
height: '100%-1', | |
width: '100%', | |
keys: true, | |
mouse: true, | |
alwaysScroll: true, | |
scrollable: true, | |
scrollbar: { | |
ch: ' ', | |
bg: 'red' | |
} | |
}); | |
var inputBar = blessed.textbox({ | |
bottom: 0, | |
left: 0, | |
height: 1, | |
width: '100%', | |
keys: true, | |
mouse: true, | |
inputOnFocus: true, | |
style: { | |
fg: 'white', | |
bg: 'blue' // Blue background so you see this is different from body | |
} | |
}); | |
// Add body to blessed screen | |
screen.append(body); | |
screen.append(inputBar); | |
// Close the example on Escape, Q, or Ctrl+C | |
screen.key(['escape', 'q', 'C-c'], (ch, key) => (process.exit(0))); | |
// Handle submitting data | |
inputBar.on('submit', (text) => { | |
log(text); | |
inputBar.clearValue(); | |
}); | |
// Add text to body (replacement for console.log) | |
const log = (text) => { | |
body.pushLine(text); | |
screen.render(); | |
} | |
/* | |
* Demonstration purposes | |
*/ | |
// Listen for enter key and focus input then | |
screen.key('enter', (ch, key) => { | |
inputBar.focus(); | |
}); | |
// Log example output | |
setInterval(() => { | |
log("Just log some example output"); | |
}, 1000); |
Check out the comments, they explain everything already. Input bar has to be focused to receive input. I chose to set that on enter for demonstration purposes. As for inputBar submit event, I suggest you check out blessed’s documentation. That should just be an enter key press while focused.
This works great, but I had an issue with the auto-scrolling. It just wasn't doing it. I was able to update it by adding some basic logic to the log function.
const log = (text) => {
body.pushLine(text);
// Was using the below for debugging:
// body.pushLine(`childOffset:${body.childOffset};\tchildBase:${body.childBase};\tbaseLimit:${body.baseLimit};\theight:${body.height}\tgetScrollHeight:${body.getScrollHeight()};\tgetScroll:${body.getScroll()}`)
screen.render();
// The scroll seems to be broken, but this helps. It will only auto-scroll if
// the scrollbar is at or near the very bottom (thus maintaining the position).
// If the box is scrolled to anywhere else, it will not auto scroll
if ( body.getScrollHeight() <= body.getScroll()+3)
body.scrollTo(body.getScrollHeight())
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't get why you're focusing on input when user presses enter. And how does the submit event get triggered?