Hacker News new | past | comments | ask | show | jobs | submit login
St – simple terminal (suckless.org)
92 points by cleverjake on Nov 26, 2014 | hide | past | favorite | 83 comments



I like the idea of cleaning up legacy cruft. I'm not crazy about the way this project is going about it. My main issues:

* ignoring C best practices:

    /* prefix macros, please */
    #define MIN(a, b)  ((a) < (b) ? (a) : (b))
* barely any comments

    /* ME: ...so it parses a string? Doesn't pretty
     * much every parser? Also, no prefix again. */
    void
    strparse(void) {
* Lack of overall project structure. Maybe some comments here would clear things up, but even some groupings like this would be nice:

    /*************************
     * X11 CALLBACKS GO HERE
     *************************/
* No tests. I think reasonable people can disagree about how testing should happen, but I'm a hard sell if you tell me your code needs absolutely no automated testing. If a new dev wants to commit a patch, how does she know her code works?

* Here's a scenario broached by the README:

    One  goal  of  st is to only support what is really
    needed. When you encounter a sequence which you
    really need, implement it.
...my problem is that there are no instructions here nor comments in the code about how start doing that ('see commit X in the repo' would even work). Again, I would hope that a dev-oriented tool like this (editing config.mk is in the installation instructions) would be a bit more friendly to developers who are stepping into the project for the first time.

My concern is that the code might suck less than xterm (I'm not familiar with that code-base), but I'm not sure "less cruft" is a good enough reason for me to want to get involved with (or even use) a project. Of course, I'm willing for the people of suckless.org to prove me wrong in my assessment.


strparse makes sense if you read the code linearly, since they also have csiparse, and deal with STREscape and CSIEscape, respectively. If you did need to add an escape sequence, it would take less than a minute to find where to add it.

While I wouldn't call it a paragon of clarity, it basically follows the same style and organization as older Unix tools. In such cases, I find starting from main() and jumping around with ctags a useful strategy (after reading the globals and type definitions).

Oh, and I strongly agree about tests. Especially escape sequence parsing could benefit from fuzzing or other property-based testing approaches.


  ...it basically follows the same style and organization
  as older Unix tools. In such cases, I find starting from
  main() and jumping around with ctags a useful strategy
 (after reading the globals and type definitions).
Oh, I know it's the same style and organization as older Unix tools. And it's the same style and organization as large one-off perl scripts. It would be a shame to replace old cruft with new stuff that doesn't the leverage lessons learned in software engineering over the last 40 years or so.


Yeah, agreed, the code is somewhat gross (also, everything is global!) and the people working on it have poor taste in coding style.

I forked it awhile back, this is the terminal I use now:

http://evilpiepirate.org/git/st.git/


> xterm is bloated and unmaintainable (...) It has over 65K lines of code and emulates obscure and obsolete terminals you will never need.

The way these things are usually implemented is that there is an interface of a "terminal" and implementations. As long as implementations do not break the abstraction and do not require modifications in the interface and other parts of code these implementations do not decrease internal software quality. They only cause bloatedness in terms of size of source code files which doesn't matter much.

I read something similar on Neovim's site, that they removed support of obsoleted architectures. And as an opposing example it seems that Linux kernel ships with drivers for very old devices and doesn't have plans for removing them.

Note that I don't know if in xterm's or vim's case implementations for obsolete subsystems cause real damage or only increase code size.

And when I was choosing a terminal implementation, I mostly benchmarked scrolling performance and looked at font rendering quality and xterm won. It is also actively maintained outside of Xorg [0].

[0] http://invisible-island.net/xterm/xterm.log.html


> Linux kernel ships with drivers for very old devices and doesn't have plans for removing them.

I think as long as there is someone to maintain that driver, it doesn't get removed.


But if removing them would simplify other parts of code, I think they would do it, like they did for i386 recently.


Indeed, they do remove truly unused architectures and drivers from the kernel -- support for IBM MicroChannel is gone, as well as support for "it was uncommon back then" hardware. I have a bunch of Allied Telesis ISA 10baseFL Ethernet cards that were recently removed.


I like suckless. I use some of their tools within my Awesome(WM) sessions.

However, I don't see the point of St. There are dozens of other graphical terminal emulators that were created with the exact same goal: "Xterm's codebase sucks, we can do better".

FWIW, I've (currently[1]) settled on ROXTerm, which (on Debian and Ubuntu) comes in GTK2 and GTK3 variants. I use Tmux within it. It does FreeType and FontConfig fonts well, which I care strongly about. Its colour scheme is configurable and it's not tied to a desktop environment. It does use libvte from Gnome to implement the terminal emulator widget, and I'm OK with that. Less NIH please!

[1] After using Gnome-Terminal, Konsole, and RXVT-Unicode for a while. I doubt my quest has yet ended.


I've been using a few - in the end I landed on sakura: http://www.pleyades.net/david/projects/sakura

I don't quite remember why I ended up moving from urxvt to sakura (and not eg: roxterm) -- but I think it was a combination of it being light (enough), easy to set up without any kind of window decorations, as well as a sane way to pick and choose fonts. With the current gtk ~/.conf-scheme it has a nice ini-like config file, and I can easily have different font preferences on my laptop, my netbook and my desktop (all different screen sizes and different PPI).

FFW I use a spartan xmonad setup, and typically run one, or a handful of terminal windows, each with their own gnu screen instance (typically one local, and a few remote screen instances over ssh. Sometimes I'll have more than one view/windows to one screen session -- and sometimes I might have a screen for a chroot or local vm/container of some sort).


Thanks for letting me know about sakura, I think it's the first one to actually match the rendering speed of xterm.

I do have one question though, why are the colors more pale in sakura than in xterm?

And is there any way to change it?


I have no idea about sakura, but being a libvte-based terminal, I highly doubt it's comparable (or even approaches) xterm in term of rendering speed.

I'm wondering how people can compare these terminals mentioning speed, considering the actual performance is bound by libvte, and thus will be equally the same between roxterm, sakura, tilda, etc. What are they measuring?

xterm is quite fast (in the order of 3-5x faster) than any libvte-based terminal. Try doing something like "time [term] -c 'cat <bigfile>'", and try varying the scrollback size to have a real measure.

[u]rxvt in turn is even faster, especially with large scrollback buffers, which is the main (I could say only, really) reason I use it. As in, 10x faster than any libvte based terminal.

I also use suckless tools (with spectrwm), though I never had a reason to investigate st. urxvt supports fallback fonts, which for UTF-8 text is essential.


> I'm wondering how people can compare these terminals mentioning speed, considering the actual performance is bound by libvte, and thus will be equally the same between roxterm, sakura, tilda, etc. What are they measuring?

Not sure about others, but the first thing I test: dmesg; ps auxww; ls /dev

I only really care about apparent speed and, like I said, sakura was the only one that was comparable to xterm.

None of the other terminals I have tried (and only now I realize that they have libvte in common, thanks for that) have managed to perform acceptably (for me, at least).


On my windoze box now, so can't check - but I think there should be something about colors in the right-click context menu? But I'm not entirely sure when (as in which version) palette/colorset support[1] was added -- it might not yet be in Debian stable?

https://code.launchpad.net/~kraiskil/sakura/colorsets/+merge...


Awesome, thank you!

If others have the same issue, it's: right click -> Options -> More -> Set Palette -> Xterm


I've used gnome-terminal, sakura and now I'm using terminator: http://gnometerminator.blogspot.co.uk/p/introduction.html

The main difference with the other terminal emulators is that I can easily do horizontal and vertical window splits.

Many use screen or tmux for that but I find them too limiting, especially in their scrollback implementation.


i always found screen splitting in the terminal when you have a graphical window manager kinda of silly.


This is especially true when using a tiling window manager such as wmii.

In that case you don't even have to rearrange windows - each new window automatically takes part in the split. And you can combine terminal sessions, browser, etc. as you wish. I find this a lot easier to use than screen/tmux.


I'd love it if there would be graphical frontend to tmux or screen. Something that would look very much like a terminal emulator, with tabs and splits, but backed by screen or tmux, whereby each tab or split window would be a tmux or screen window. And the awesome part is that when you're elsewhere, you could ssh in and attach to that tmux or screen session.


You can send commands to a running tmux session, eg. http://superuser.com/questions/492266/run-or-send-a-command-...

How far you take it depends on what you'd want out of such a tool. Simple "New Shell", "Close Shell" buttons would be easy; overlaying draggable partitions would be more effort, and less elegant, but still do-able.


You can do that on OS X with iTerm2 e.g.: http://www.railsonmaui.com/blog/2014/03/11/rocking-with-tmux...


It means you can do screen splitting on a remote machine and still have the same workflow as your local sessions, which is pretty nice.


After using emacs a lot I've ended up preferring screen splitting.

I used to be happy just running multiple xterms, but I've been using Linux again recently and found myself a bit unhappy with that. I think due to advancing age I'm just finding it hard to cope with lots of windows. Keeping on top of them is a pain.


I tend to have terminator fullscreened (no decorations) on one desktop, and switch desktops far more often than I switch windows.


Gnome-terminal, rox-term, sakura and terminator are actually all based on the same terminal emulation backend: libvte


st is not about rewriting xterm.

it's about removing features, and then rewriting.

for example, it doesn't even have scroll back! ... which is the reason i don't care much for it.


I like roxterm, but I recently switched to xfce's terminal, which lets me load it without a menu bar, (I like having more vertical space).

More options are good.


hide_menubar=1 in roxterm config :)


Sorry that was unclear, I meant no menu bar and no drag bar with minimize and close buttons; my terminal window goes from the top of my screen to the bottom. I realize I can use a DE that lets me do that, but my preferred DE on linux atm is xfce itself. If there is a way to configure roxterm to not have a drag bar from inside the program, I have not found it.


I use the Xfce 4 Terminal on a i3 with no DE. Works wonderfully and has all the features I care for and need.


Same here. Very few dependencies.


> xterm is bloated and unmaintainable. [...] It has over 65K lines of code and emulates obscure and obsolete terminals you will never need. The popular alternative, rxvt has only 32K lines of code. This is just too much for something as simple as a terminal emulator; it’s yet another example of code complexity.

Ok, I am interested.

> How do I scroll back up?

> - Using a terminal multiplexer [shows tmux example]

Emm... tmux is a 32K lines of code. That kind of defeats the purpose of the opening paragraph.


I think the point is: do one thing and do it well.

In this view, I guess it's not the terminal's duty to do multiplexing, scrolling etc. Tmux is meant to do the job, so its codebase size should not be added together with st's. They're separate software, each doing its thing and doing it well, an approach completely opposite to that of other software (e.g. emacs) that do lots of things.


I'm not sure in what meaningful sense of the word tmux isn't also a terminal emulator, thus doing more than it should, if I follow your reasoning all right.


Terminal emulators accept drawing commands (literal and control characters) and render them to some kind of device (eg. a framebuffer, an X window, a Wayland surface, etc.).

Multiplexers accept drawing commands from multiple applications and combine them into one "root window".

By analogy, Linux launches a single process (init) which then handles all the others. The init system is not a kernel.

On the other hand, X11 doesn't just render a single root window (eg. controlled by the window manager). Instead it allows multiple clients to each draw to multiple windows, and the window manager performs a lot of back-and-forth communication with X to keep track of them.

In that sense X is certainly doing more than it should. Is tmux? Probably. Hell, it contains a mode-line with a clock! Why not use the existing multiplexing to offer a "sticky" single-line window, in which we can run some arbitrary status-displaying program?


> Terminal emulators accept drawing commands (literal and control characters) and render them to some kind of device (eg. a framebuffer, an X window, a Wayland surface, etc.).

Multiplexers accept drawing commands from multiple applications and combine them into one "root window".

If we accept for the sake of discussion that rendering to a "device" is the distinguishing characteristic of terminal emulators here, rather than, say, emulating terminals (which tmux certainly does), can't you think of another terminal emulator as such a device?

I can't really tell how the Linux init analogy is valid and what your point of making it is. Is the init system a "kernel emulator" or a "kernel multiplexer"?


> If we accept for the sake of discussion that rendering to a "device" is the distinguishing characteristic of terminal emulators here, rather than, say, emulating terminals (which tmux certainly does), can't you think of another terminal emulator as such a device?

It depends whether you think "Save to PDF" printer drivers really are printing. Does tmux "certainly" emulate a terminal, given that I can't observe any of the output or send it any input without assistance from another terminal emulator, like st?

> I can't really tell how the Linux init analogy is valid and what your point of making it is. Is the init system a "kernel emulator" or a "kernel multiplexer"?

The init system is like a "process multiplexer". The kernel only starts one process; if we tell it to start bash, we have a shell but not much else (until we fork stuff off manually). If we tell it to start an init system/daemon then we get a whole bunch of processes started for us during boot.

Likewise, when we start a terminal emulator we can run bash to get a single shell session, or we can run a multiplexer to get many.


> It depends whether you think "Save to PDF" printer drivers really are printing.

How does it depend on that? When you express an argument as an analogy without further explanation you lose a lot of information.

> Does tmux "certainly" emulate a terminal, given that I can't observe any of the output or send it any input without assistance from another terminal emulator, like st?

It "certainly" emulates terminals in that it behaves like one to the user and to programs that use it as a terminal, just like xterm or st. Whether the platform it uses for presenting this to the user is X11 or a terminal/another terminal emulator seems irrelevant to me.

> The init system is like a "process multiplexer".

It isn't a process multiplexer. How is it "like" a process multiplexer? init maybe starts a bunch of processes, but it doesn't do any multiplexing or even manage their communication at all.

> Likewise, when we start a terminal emulator we can run bash to get a single shell session, or we can run a multiplexer to get many.

You don't need to use a terminal multiplexer to have multiple shell sessions.


Fair enough, in a way, but I'd say you can't launch it stand-alone inside an X session without using another terminal emulator (st, xtrem, whatever).


That is true. It seems somewhat beside your original point, though, unless you are arguing that that difference cuts it clear which terminal emulator should handle scrollback


No, my point wasn't strictly about scrolling. My line of reasoning is:

1 tmux is needed to handle multiplexing

2 tmux also handles scrolling

3 if you need tmux for other things already, you don't need scrolling in the terminal emulator

I wouldn't say that, by this reasoning, it is the right place to implement scrolling, just that, since it's a solved problem, re-implementing it would be a useless duplication of effort.

But in this specific case I'd concede that the way tmux scrolls is not at all comparable with how a X terminal emulator would be expected to scroll.


Not quite, the opening paragraph says rxvt is "only 32K", but of course st (which is the program being talked about) is around 4K.

It's easy to count, since it's mostly a single file: http://git.suckless.org/st/tree/st.c. :)


I heard dtach + dvtm were smaller, but I'm not sure.


Nice, not seen dvtm before. Since I've not seen it mentioned in other multiplexer comparisons I was assuming it's not in major repos yet, but an optimistic "nix-env -i dvtm" has installed it!


nix really does make people optimistic


I personally love Terminology: https://www.enlightenment.org/p.php?p=about/terminology

It's modern, incredibly fast (could even be GPU-accelerated), fancy (if you want it to) and stable.

See previous discussion: https://news.ycombinator.com/item?id=5438089


My friend tried committing code and getting involved, but they seem to be a tight-knit group of friends. It's hard for outsiders to do anything.


This may be true but it's also one of their goals not to really add new features. st and dwm both have some "3rd party" patches for some features that some people might want.

I'm not sure whether that's the right thing to do but it's the way they work.


I've used St and have written some patches myself to add minor features I wanted. I get the impression that they intend it to be a small core for people to add features themselves if they want. They implemented the core features that people can all agree on, then leave it as an exercise to the reader to add other stuff. Dwb follows a similar approach, I think.

That said, I moved on to ROXterm because I was having encoding issues with a couple of programs I use. St is worth consideration as an uber-minimalist terminal though... it's very fast. Even on ancient hardware it launches essentially instantly because it's not loading any large libraries like GTK. St is pretty fun to hack on, too.


Every software is a product, even if it is OSS and no money exchange is involved at all. There is a designer, and a final user. The idea of this product is that terminals don't need to scroll up into the past history, actually doing this well is one of the most critical aspects of a terminal as a good product for end users: retain history, do it reasonably when programs controlling the cursors are executed, don't get super slow if there is a lot of history already in memory, and so forth.


> actually [scrolling up] well is one of the most critical aspects of a terminal as a good product for end users

You've clearly misunderstood the point st is trying to make. Not only is it not critical, it's a bad idea for a terminal to store and scroll history! Yes it's nice to have a history to scroll through, but other programs (screen, tmux, Emacs, etc.) are much better at doing that than terminal emulators are!

For many people, like sysadmins, it's crucial that shells can be accessed over a network. Does that mean terminal emulators should build networking into their code? No, since SSH already does an excellent job.

For many disabled people, it's crucial that shells can be speech-driven. Does that mean terminal emulators should build speech recognition into their code? No, since external systems (Sphinx, etc.) are already tackling this problem.

Of course, from an "end user" perspective it would be nice to have "one application" which does all this. The beauty of the UNIX philosphy is that we can write such an application easily (untested, but you get the idea):

    #!/bin/sh
    if zenity --entry \
    --title="New Terminal" \
    --text="Enter the shell URL (blank for local shell)" \
      then st -e "tmux -c ssh '$?'"
      else st -e "tmux"
    fi


That's why I addressed it in the POV of a product. It's basically subjective. IMHO the "terminal product" should have history handling included.


If you're thinking about a "terminal product" then why single out st's lack of history at all? That would be like claiming Excel lacks presentation capabilities. Whilst it's a true statement, presentation facilities are irrelevant to a spreadsheet; they're available in the PowerPoint component of the Microsoft Office suite, and they're designed to work together, so it's a complete non-issue.


You're entirely missing the point. Scrolling is already broken if you use any terminal multiplexer (such as `screen` or `tmux`).

As such, having an additional, useless layer of scrollback on the client is both confusing and pointless, so they removed it.


The best terminal emulator I've used is termite[1]. It has vim-like keybindings and normal/insert mode, plus a bunch of other features worth looking at. If you are using xterm, urxvt, or something similar, I would highly suggest giving it a try.

[1] https://github.com/thestinger/termite


Since everyone is sharing their terminal emulator, I decided to hijack your comment and post mine :) .

I use Sakura. https://launchpad.net/sakura


Termite is lovely. If you like it, you might also want to look at ROXTerm.


I'm a tmux user, so the menus and tabs are not really useful for me :). And the command mode in termite is vim oriented, so it's quite nice. I'm not sure how ROXTerm does it. To be honest, as long as a terminal supports vte (for fontconfig), it's already a huge improvement over xterm and urxvt.


I'm a tmux user as well. I actually turn off all of the menus and make it pretty slimmed down. I stopped using Termite originally because colors were acting funky.


Interesting. Have you tried it lately? I've never had any problems in the past few months. If you are happy with whatever you are using now, then there is no need to change :).


I feel stupid. I opened up the comments and then thought to myself "Hey, I remember reading a confession from the xterm developers themselves about how terribly bloated xterm is, I should go and find it again". After 5 minutes of searching I finally found it... Only it was on the suckless page for st.


suckless sounds quite like a good name. I'm currently also working on some terminal style I/O and I can totally understand why there are programs with >30k lines of code just for being a terminal emulator. terminal communication is not really standardized. It has grown since a time where "computer" meant a person who calculates things. So I'm not sure it St could arrive at a stable state without also having a few thousands lines more than it would like to have.

But what is wrong with Gnome-Terminal? For me it works well enough out of the box. I literally didn't do anything beside increasing the scroll buffer and haven't run into enough troubles yet to switch.


> But what is wrong with Gnome-Terminal?

The dependencies: https://github.com/NixOS/nixpkgs/blob/master/pkgs/desktops/g...

If you're using Gnome, you probably have those already so it's no big deal. The same goes for Konsole in KDE: https://github.com/NixOS/nixpkgs/blob/master/pkgs/desktops/k...

If not, pulling in a few hundred MB of dependencies for a terminal emulator seems distasteful. st is much more self-contained: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applicatio...

That's why st is usually compared to xterm; they're small, basic and desktop-agnostic.


That's good to know. Without Gnome(3) Gnome-Terminal might not be the right choice.


The source directory of libtsm, which only does the state handling for an abstract screen, is already ~11k without tests, so 30k doesn't surprise me.

http://www.freedesktop.org/wiki/Software/kmscon/libtsm/


I actually use xterm's tek4014 emulation for plots, I can keep them going off to the side at 15Hz just drawing over the top of each other until I change something in the main text window, then I erase and repeat. I tried to do similar with gnuplot but I could never figure-out how to keep updating continuously like that, so that's why.


I use Konsole and yaquake always. Tabs, colors, profiles (I just have one for neovim), nice font rendering, split windows, copy&paste from clipboard...

Apart, Windows needs a good terminal. Console2 and ConEmu, not end to work fine... I get strange issues with colors every time that I connect to ssh against a GNU/Linux machine and open vim.


If I'm stuck on Windows, I just use a Cygwin console and ssh to the world.


ConEmu works fine with colors. Your ssh client does not...


Yeah, I just learned that I should use ConEmu + Putty. At least now, I don't get weird colors and a grey background filling all when I open vim. But I keep missing having something like Yakuake or Konsole.


I use Mintty, the terminal which comes with Cygwin, and it works great both on Windows and while ssh'ed into Unix boxes.

Windows + Vim: https://i.imgur.com/soTIhNy.png

SSH + Vim: https://i.imgur.com/aLs9ACy.png


Konsole is great.


> Some random program complains that st is unknown/not recognised/unsupported/whatever!

I really wish there was a better way to deal with this (I have the same problem with rxvt-unicode-256color). I'm obviously not going to make install a graphical terminal emulator on some random server I'm logging into.


I'd argue that they should go the route that most terminal programs do and just announce they're xterm, or at least have a config file option for doing so.


Put the following in your shell configuration.

  alias ssh='env TERM=xterm-256color ssh'


    tic -s st.info
or setting your TERM variable should help.


I meant the distribution problem of getting the file to the server. I grant that it's a petty annoyance, but it is still an annoying thing. And logging into a new server always carries with it the question of whether it's worth fixing it permanently when you barely use it.

For the machines I regularly use I have terminfo files in my dotfiles git repo.


How does copy and paste work with tmux in st? I guess it can't be marking with the mouse, for I can't imagine that tmux scrolls when I move the mouse downwards out of the window.


My benchmark test for a terminal:

If it takes more time for the graphical terminal to give me a usable prompt than alt+Fx then that particular terminal failed.


To save others some time, they use X descriptors for font specifiers, like the following.

  st -f DejaVuSansMono-12


Seems nice, however I do like the idea of a GTK2 based and tabbed terminal. Sadly, a lot of them feel very bloated.


st uses the Xembed protocol so you can use tabs with it using the "tabbed" utility from the same site (ie. you can embed many st instances into tabbed).

Or just use tmux for "tabs", you'll need something like that anyway for scrollback, etc.


evilvte




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

Search: