Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Black Screen: A modern terminal emulator based on Electron (github.com/shockone)
215 points by SalGnt on Sept 5, 2015 | hide | past | favorite | 95 comments


Hello. I'm the author of Black Screen, and I'm upset this post has appeared on Hacker News. The terminal is at a very early stage; I don't even use it by myself. Although, it's nice to see that people show some interest.


You should probably put a note saying as much at the top of the README.

Pretty cool looking project though, I have been thinking about something like this for a while now. The two biggest problems seem to be performance(I spawn throwaway shells all the time, so my terminal emulator need to open pretty much instantly), and fully compatibility(I use vim in the terminal as my main editor).

I'll be watching to see how it turns out.


Thank you for your kind words. Spawning a shell shouldn't be a performance bottleneck as long as you create a new tab or pane, and not a new application instance. By the way there is a (very) experimental support of panes, press cmd + _ to split horizontally.

By biggest concern is how to cat a 50MB file. If you try it now, everything gets stuck.


I feel really sorry for the inconvenience, I just wanted to share your awesome project.


I should thank you for the post. It reassured me I'm doing something people are interested in.


No problem! You had a great idea and I'll look forward to see it completed, I'll help as much as I can.


Hi shockone,

A new terminal/shell is a very hard sell, as I know from my own experience. Six years ago I wrote my own terminal/shell combination ( http://wiki.tcl.tk/23446 ). It works well enough that I've been using it myself full-time at work ever since, but although a few other people have tried it, no-one else ever adopted it. My own attempt is implemented in Tcl/Tk, an older but much lighter-weight framework (it has no problem with cat-ing a 50MB file).

I combined the functions of shell and terminal because I found the shell/terminal split made some of the functionality I wanted difficult or impossible. One example is that I colour text written to stderr in red - standard shells mix stderr and stdout together before the terminal even sees them.

I decided early on that I would not support terminal escape sequences. I set the TERM environment variable to "dumb" which tells well-behaved programs not to use escape sequences. So you can't run vi/vim in one of my windows, but I always use gvim so I don't find this a problem.

Similarly after some experimentation I decided not to use ptys as they created as many problems as they solved. So programs which change behaviour based on whether they are connected to a terminal behave as if running from a script. Eg. running "man command" lists the whole man page rather than trying to page it - but this is what I want since one can page up/down in the shell anyway.

However it seems that people who use a terminal get very attached to its idiosyncracies and will reject anything even slightly different. Since it's very difficult to make any real improvements without introducing incompatibilies, attempts at improving the terminal/shell user experience rarely catch on. In contrast, a few other tools I have implemented using the same technology have been adopted by a worthwhile user community at work. I think the difference is that they are used for more specialised tasks and don't require the user to change their everyday workflow.

Anyway, good luck with your endeavour!


Can you use another npm namespace?

. npm install black-screen

is far better t'han "install-all" for many reasons: better npm search, no namespace pollution, more semantic than such a generic name.

Please consider to change it.


I'm afraid you misunderstood the command. The package is named correctly - black-screen. Install-all is a local npm script, that's why you run it with `npm run`.


it hasn't been published to npm yet. the instructions are for cloning the repo and installing it locally to test. that's an install script


One of these seems to pop up every few months, which is great, terminals are old crusty awful things, but it seems like they always die out in development before they can run existing things like Vim which makes them fun POC's and not much else :/


The problem seems to be that they come at things from the wrong direction - you can't run vim without being backwards compatible with at minimum terminfo pages, very likely vim also makes an assumption also that the terminal communicates over a tty, and possibly you may just need to support actual ANSI Escape Codes. You can't run anything else without that either. Running vim should be the first thing this terminal can do.

Just like the web itself, any new teminal client needs to be backwards compatible with the capabilities of prior terminal clients, because programs that run in the terminal expect it. And if your terminal can't run the programs everyone runs in their terminals, no one will adopt your terminal. But many of these projects seem to have no intention of maintaining that backward compatibility. Some, like TermKit, fully conflate the terminal and the shell and even many UNIX utilities.

You can't hope to supplant ANSI compatible terminals when you let them have the enormous advantage of running all the software anyone wants to run in a terminal that already exists. It would be like saying you have a new, better web browser that can't open any existing web pages.

No idea if this particular project has learned from past examples and is backwards compatible or not. (EDIT: It doesn't have a terminfo page, so probably not.)


It does indeed support ANSI codes. Not fully compatible with VT100 yet, but that's where I'm moving. Vim is functioning, but there are a lot of bugs. https://dl.dropboxusercontent.com/spa/dlqheu39w0arg9q/xxy316...

The problem with terminfo is that not every tool relies on it. I've seen many examples (hello, exa), when the codes are hard-coded to operate with xterm-256. So, I decided to pretend to be an xterm.


Hey thanks for replying & I hope my comments didn't seem snooty. I've thought a lot about how to solve this problem and was disappointed by the way some past attempts have just ignored the infrastructure that ensconses current terminals. And its a real shame that so many tools just hard-emit ANSI escape codes - there are even some TUI frameworks that do it.

The problem I see is that you seem to have the terminal doing things like fuzzy matching input against PATH executables. But that's the shell's domain. The terminal should just expose commands for adding text items to a drop down under the cursor, and the shell should send the matches to the terminal. And capabilities like this should be clearly defined in a terminfo page (which you should definitely have, even if for non-custom capabilities it uses the same definitions as xterm), so that well-written apps can send this information if and only if those capabilities are defined.

Of course this is a huge challenge, because if you do it this way your terminal doesn't do anything new until someone writes a program to run in it using its extended capabilities. So this creates a chicken and egg problem. But you can't come up with nearly as many interesting things for your terminal to do with cursor dropdowns as everyone in the world can if you're just exposing that in the same way the character grid is exposed.


Hey. Not snooty at all. I understand your pain: once I tried to open Vim in this Kickstarter terminal project - Xiki - and was disappointed in the same way.

Perhaps unexpectedly, Black Screen is both a terminal emulator and a shell. I tried hard to avoid going with writing a shell, but the existing ones simply don't fit. It's even hard to know when a child execution has finished. And I want smart autocompletion, so I have to at least extend a shell.

Traditionally these two are separated, and it must be a good design, but my current goal is to prove the concept. Perhaps, later I'll extract the shell.


I think for this to work you just have to create a shell and a terminal, to have a killer app that your terminal is the paltform for (realizing this is what kept me from ever moving on the idea). But my point is that I think the shell component absolutely must communicate with the terminal component over the tty subsystem using an extension of ANSI Escape Codes, defined in a terminfo page, so that the terminal component is only concerned with how the information is displayed, and not what the information is.


What problems will I face if they don't communicate over a TTY?


The thing is, the web stack is not how to do it (for a prototype, maybe).

As they say above, this thing would halt when you cat a 50MB file.

It takes someone who's familiar with terminals, and can use a language fit for the task (and without too many depenedencies -- so if you built it in Haskell and I need the Platform and half of Cabal to build it, it will never fly -- and it being in Haskell it will not attrack many UNIX hands, who are the people familiar with Terminals most).

So something like C, C++, Rust or Go.


No, I think integrating the web stack in a terminal is one of the better options. You'll get a lot of nice things that already work, e.g. serialization (HTML/CSS/JS/JSON), debugging (webkit dev tools, if you use webkit to render you terminal), libraries that are useful for terminal based apps (d3.js) and nice font rendering to only name a few.

`cat 50mbfile` will not halt a web based terminal if you don't keep it all in the scrollback buffer.


I would really love it if one of these web-based terminals managed to stick around. Just being able to view images in a terminal would be amazing. The trouble with building on web technologies seems to be that the overhead is just too high (eg. Atom) considering how many terminals the average developer has open at a time.

I guess at least since it's based on Electron, it might have more longevity than something built from a cobbled together base. Here's hoping!


But still, even with electron, it’s performance will be horrible.

Several hundred MB RAM usage for a single Terminal window are just not acceptable.

Somehow many devs today write their software under the assumption that a user with 2GB RAM or 4GB RAM will at all times only run one single piece of software.


I liked the JavaScript IRC client which uses like 400MB of memory.


Exactly. And this is somehow acceptable, or even "industry standard" today.


iTerm 2 actually supports images! http://www.iterm2.com/images.html It works pretty well. I wrote a little blog post awhile ago about using it for integration testing: http://kevinmarsh.com/2014/05/07/in-terminal-screenshots-wit...


That blog post, very creative. Such a good idea. All I've done with the image integration is show a 128px frown emoji when a script exits wrong.


Feh is usually good enough for me. There's always catimg too if you really really want it in the terminal and don't care that it'll look terrible.


+1 on feh, although it doesn't work with gifs, and the author isn't planning to implement that support.


SVG is also not supported.


urxvt also supports viewing images (or at least I know that because that's the emulator I use, maybe other emulators also support it)

Like I know ranger has an option for it, but iirc there's also a way to just run a command ala `cat`ing a text file. If you'd like, I can look into it more if you can't already find out how to do it by searching.

Also, people are mentioning feh, I'd like to plug in sxiv (not my program though).


xterm supports tektronix vector graphics... And sixel (and regis). You can cat the graphics, and it will display (may have to build xterm from source -- Fedora enables tek, but not sixel, for example). GNU plot supports sixel.


Wow, how? I use urxvt and dindn't know that.


Sorry for the late reply. I found it, I got the method from this blog post [1] initally. Also see [2].

However, I'm sad to say that when I tried this again rn, it didn't work anymore. (I know for a fact it used to work great because I used to use it.)

The funny thing is, ranger's image preview still works for me (same terminal and everything), so I guess one could start going through the ranger source code to see how they wrap w3mimagedisplay if they really wanted to.

I don't really have the motivation for that though because, although I'm a heavy terminal user (and it would be nice), recently switching to emacs means a lot of my file management can be done with dired (an emacs package). And dired can do image previews quite nicely already [3] (I'm assuming provided you're using GUI emacs^). ^^

^Emacs can fire up terminals inside it anyway, so using GUI emacs is not a problem for me, even though I'm heavily terminal orientated.

^^Although I think I prefer sxiv's thumbnail mode for browsing directories full of images (as opposed to a few here and there).

[1]: http://blog.z3bra.org/2014/01/images-in-terminal.html

[2]: https://github.com/hut/ranger/wiki/Image-Previews

[3]: https://github.com/ralesi/ranger#screencast


The ranger file manager, which I use can do image previews in urxvt and claims to also work with iTerm, st and xterm.


You can view images on iTerm 2:

https://db.tt/nO3P7yO6

And yes, iTerm2 also displays animated gifs.


What is displaying your "tabs" at the bottom of your terminal?


Yep as steckerbrett mentioned, it's the new Dark style tabs introduced in iTerm nightlies, which you can put it in the bottom. It might be included now in the betas or the stable version, not sure.


That's part of iTerm. In appearance, set tab style "bottom" and "dark" to emulate that screenshot.


Just being able to view images in a terminal would be amazing

What are the advantages of that over using a dedicated image viewer program?


A different programmer is always more creative than yourself. It's an axiom to remember, because when the people with the power to change the tools at our disposal give us better tools, suddenly we can use them to do things they didn't even realize they wanted.

Even giving the ability to set a specific pixel to a specific rgb value would get far. Yes, some programs would get it wrong or would be annoying to use. But think what it would enable. Even at 3 fps, you could still show the user a performance graph of your program, or a flame chart. In the terminal. No extra windows required, no fiddling with GUI frameworks, just "set some pixels to some values."

In the short term, being able to set text to a specific foreground and background rgb would be nice. I'm talking 24-bit color. It turns out that this is not possible across all Unix variants: OS X default Terminal doesn't support 24-bit color for text. And there's no reason why it should be like that. The standards are in place, and they are a straightfoward extension to exiting behavior. The toolmakers just haven't enabled the other makers to use it. Of course, it's because it makes no sense for Apple to waste engineering cycles on that. But that doesn't change that it would be true that if they gave us better tools, we would do more.

The issue is that it has to be a minimum spec that's supported by all platforms. (All Unix platforms would be fine.) Simply writing a program that supports a nonstandard way of setting pixels to values wouldn't cut it. At least at first. That's probably how it has to start, though, in order for others to follow.


Focus and context. You don't have to switch to another application and, presumably, displayed image will stay in terminal output. It would be great for printing out inline performance graphs, or even sparklines.


sxiv .

Combine it with dwm :)


When you check in something that breaks the build, the tests can drop an image of battered, bloody Doomguy directly into your terminal instead of having to go through something like http://squarism.com/2010/05/23/watchr-unit-tests-growl-doomg....


cat tmp.png

"Yep that looks like it's right"

git add tmp.png


Whoopee, you saved one keystroke (`eom tmp.png` "Yep, looks good. Presses Escape") and if you become interested in any data from previous commands' output you'll have to scroll up more / live with a larger window than otherwise because now you've got an image sucking up n rows in your terminal.


Look at IPython and DrRacket to see why inline images can be useful in REPLs. With DrRacket you can not only view, but also create and combine images one step at the time, always seeing the latest form of it. And then you naturally end up with a script for doing the transformations needed to get your desired result.

In short: the time savings introduced by shortening the feedback loop tend to add up. There is a reason why Web developers now use auto-reloading solutions, despite the fact that it saves "just one keystroke" (F5 in this case).


Oh, I'm all for interactive development, one of the reasons I prefer dynamic languages is precisely that, I just don't think the utility of having a static (or animated, or auto-reloading ((!) changing output in a non-ncurses shell?!) image in the shell is that useful compared to the engineering effort and what feels to me the loss of the shell's essential character. ncurses is about the limit of having enough control to make a game vs. having something that isn't a shell interface anymore. The shell isn't a monolithic IDE which you only run one instance of, the closest analogy I use is "vim+Linux are my IDE" and terminal windows are just windows to interface with my "IDE" that I can run any time. eom theoretically supports auto image reloading, though other viewers definitely do. When I edit LaTeX files, I do so in vim, and have the PDF open in evince/atril to the side which auto-refreshes when I save the file (if I set up vim to run latexmk on save, otherwise it's just an extra command I do). This is just the same when doing ClojureScript development -- your IDE doesn't necessarily reload and try to support all the features of a browser, the programmer just uses an actual browser to the side and you use whatever IDE or text editor you like and a file monitor manages the auto-reloading stuff.


For easier use, you could even alias `cat` to run `file` first, then pass to your image viewer or whatever if it's not a text file.


You may be diappointed to know that Windows' cmd.exe will automatically open the default associated program, so all you need to do is enter the filename if you've associated image files with a default viewer:

http://superuser.com/questions/246825/open-file-from-the-com...

(I suppose a similar thing could be done on *nix with a suitably modified execlp()/execvp().)


Freedesktop systems get you an 'xdg-open' command (there's also 'gnome-open' for GNOME, and 'open' for Mac OS X).

On Linux you should be able to wire up binfmt_misc, the plugin system for execve, to xdg-open.


kde-open exists, too ;)


If I understand you correctly you can also do this in zsh: https://grml.org/zsh/zsh-lovers.html although not automatically.


This use-case is reasonable, but it still requires a dedicated interface for diffing.


You could just make your own external difftool that displays the two images side by side, and add that in to ~/.gitconfig.

Then you could just call that external difftool when comparing images:

    git difftool --tool img-diff 
Just an example.


Lighter faster version of Ipython/Jupyter.


You can view images in an xterm, though it relies on X11's lack of partitioning. Xterm sets an environment variable containing its window handle, so child processes can use that to draw in xterm's window. w3m-img (an in-terminal graphical web browser and file viewer) uses this trick.


> One of these seems to pop up every few months

Do you --or anyone reading this-- have a list of these? I would love to check them all out actually (not that I don't get your point).



Well, there's Finalterm that doesn't exactly seem to like vim.


> terminals are old crusty awful things

Not really, they're just poorly documented. They're based on ad-hoc standards that are scattered across many outdated documents.

It'd be nice if somebody could actually pull all that together and publish one comprehensible document that is readable and up-to-date.


Screenshot looks awesome!

I get this error on mac os Yosemite, I made a github issue here: https://github.com/shockone/black-screen/issues/21

    black-screen$ gulp
    [17:35:09] Using gulpfile ~/black-screen/gulpfile.js
    [17:35:09] Starting 'default'...
    [17:35:09] Starting 'watch'...
    [17:35:09] Starting 'clean'...
    [17:35:09] Finished 'default' after 359 ms
    [17:35:09] Finished 'clean' after 58 ms
    [17:35:09] Starting 'typescript'...
    [17:35:09] Starting 'sass'...
    [17:35:10] Starting 'react'...
    [17:35:11] gulp-notify: [Black Screen Watcher] React has been compiled.
    [17:35:11] Finished 'react' after 1.83 s
    ~/black-screen/node_modules/typescript/lib/typescript.js:35171
                if (host.fileExists(fileName)) {
                         ^
    TypeError: undefined is not a function
        ...


Appears to be gulp-typescript problem. Upgrading gulp-typescript to "^2.8.1" solves.


If anyone's curious to try this, here's how to get it working: https://github.com/shockone/black-screen/issues/21#issuecomm...

Overall, actually really like the interface and the potential behind it. Super laggy and could use some work.


Getting the same error on Arch Linux.


Getting the same error on OS X 10.10.5


That should be fixed now.


Bringing up a whole web browser engine for the terminal is a deal breaker for me. I want it to start instantly. 1 second is too long.


That's understandable. It's like with editors. There is vim and there is Intellij IDEA (sorry, JetBrains, for calling your child an editor). I want it to be smart.


I see it is buzzword-compliant, but what is it good for?


Ha-ha, I get that a lot after telling about React and Electron. Initially I was thinking about Swift + Cocoa, but I figured CSS would give me more flexibility in designing the UI, and it would allow more people to write plugins. Everybody knows JavaScript, right?

So, I use a terminal emulators pretty extensively, and I'm tired of their dumbness. Compare any operating system from 1980 and 2015 - there is a huge difference. The same with web-sites, text editors, and pretty much any other category of software. Except terminals. The biggest achievement they made is 256 colours support. Good job!

It doesn't take a genius to understand that the limitations are caused by the text user interface. Of course, text is a great and universal tool. It's easily parsable (or not so easily, but still parsable). It can be piped, after all.

But who said we can't take the good old text and present it beautifully? Imagine you fired an sql client, wrote a select statement and received an ASCII table as an output. Wouldn't it be useful if the terminal understood that it looks like a table and converted it into an HTML table, with sorting by any column, resizing, filtering, and everything else. The same with XML, JSON and every other format: why should I type `jq` after a command that outputs JSON? Is that so hard to just detect and parse it for me?

Output formatters was the idea that made me start the development. I also plan to let users write custom formatting plugins.

But even besides that point there is a lot of room for improvement in current terminal emulators. For example, I have a git branch displayed in RPROMPT of my ZSH. It works well, but if I checkout another branch from a different place, my shell will still show the old branch, which can have certain consequences, if you rely on it.

The current feature I work on is autocompletion. I plan to parse man files and provide only what can be displayed in that place. By the way, folks from the Fish team do the same.

Unfortunately, right now Black Screen can not be used as a replacement for your favourite terminal, it has a long path to the first release.


I kind of don't want to have my terminal emulator run a complete webbrowser because that's how all the cool kids now pull off the Delphi window skinning look of 2000.


If we can have a teletype metaphor today in 2015, 40-odd (or thereabouts) years later, with the awfulness of this whole idea being a minority viewpoint, perhaps we need to just go with the web browser metaphor today, and see what comes of it by 2055.

Thanks to people insisting for years that the TTY is just fine, we don't appear have any other options. Ideally, we'd have progress - but as it is, we have nothing, or a shit sandwich. Forgive me for not going for nothing.


I think that what these JS-based UI toolkits are doing is really great, but I really dislike the idea of bundling basically a browser with the application.


There is a positive side: a built-in HTML and CSS engine allows to write very customizable interfaces.


I have a feeling that when enough things want to run "a complete web browser", what we'll get instead is a single web-browser window server process for these applications to talk to.


Wayland and its associated protocol stack is old, crufty, and written for a use case that doesn't exist anymore. We're planning to get all the major toolkits migrated to DisplayWebKit sometime within the next two years.


That's a confusing assertion. Wayland is only a few years old, and has only very recently seen anything approaching widespread usage. What do you mean by "Wayland is old"?

And, who's "we" when you say "We're planning to get all the major toolkits migrated to DisplayWebKit"?

I'm not trying to be argumentative, I just don't get where you're coming from.


I think GP's post was tongue-in-cheek; I read it that way, anyway.


Ah, too subtle for me. There are enough people looking at the world through the lens of "everything should be on the web" that it doesn't seem entirely crazy to have the browser as the display target.


I read the comment as being satirical but I find the best satire is that which could be mistaken for the genuine article.

https://en.wikipedia.org/wiki/Poe's_law


It's supposed to be in the spirit of "what we'll hear a few years from now about Wayland" just like we're hearing it now about X11.


It's still nice sometimes to have a terminal among available Web controls. Not as a main tool, I suspect.


reminds me a lot of TermKit

http://acko.net/blog/on-termkit/

looking cool!


When I saw this post I thought it was going to be an xterm with an oldschool CRT look. I got someone to build me one of those for playing rougelikes a few years ago - see here if anyone is interested: http://ubuntuforums.org/showthread.php?t=1884955


Something like this, but with performant native controls?

I will love to build a interactive REPL "terminal" for some data tool I'm building, but with a modern native GUI.


iPython Notebook makes for a nice terminal emulator: http://jeroenjanssens.com/2015/02/19/ibash-notebook.html (inline images!).

It lacks readline support, though, and does not implement all VT100 control characters.


Nice, another application that eats away tons of RAM because it comes with it's own WebKit engine.


I don't disagree, but as someone who has written a bunch of personal tools (including a Tinder assistant lol) with electron and nwjs, think about why people are using these runtimes before you rip on it. Since so many people are doing it, there must be some good reasons.


Yes, they are using it because they are familiar with the web platform and want to go a step further. But that doesn't mean that all other ways to build programs for desktop use suck and we can only use a webkit engine. With stuff like electron, the result is bloated as hell and looks totally foreign.

EDIT: Just think of the major performance problems these electron based editors had and still have. Our compurters have become faster, so we just write more bloated and slower software?



Bummer. Doesn't compile with iojs.


It looks like it uses "child_pty" to spawn pty's. child_pty hasn't been updated to support the latest nan/v8 api (in fact, it looks like it's been unmaintained since March). It also improperly uses fs streams to read and write to the pty fd which will exhaust the thread pool very quickly. So, even if you can compile it, it will still break.

It also looks like it doesn't handle sigchld with a waitpid anywhere, so be prepared to have a zombie apocalypse on your machine.

I'd recommend the author switch to pty.js[1] which now compiles on io.js >=3.0.0 and reads pty fd's properly, but I'm biased.

[1] https://github.com/chjj/pty.js


Thank you for the advice. Pty.js was my initial choice, but it didn't support return codes at the moment. I'll take a look at it again.


Add an issue for it.


Try the 'n' module/cli.


This looks really awesome - can't wait to try it out!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: