title: Differentiate between Esc and other special keys on ANSI terminal
body: <p>Terminal programs (notably vi and vim) can differentiate between the Esc (escape) key and other special keys like the arrow keys, having different commands for all of them.</p>
  
  <p>In terminal emulators, Esc seems to be encoded using only  a single hex byte:</p>
  
  <pre><code>{ 1b }
  </code></pre>
  
  <p>However, some special keys (arrow keys, page up/down, home/end, insert/delete) are multi-byte sequences starting with that same byte:</p>
  
  <pre><code>{ 1b 5b 41 } up
  { 1b 5b 42 } down
  { 1b 5b 43 } right
  { 1b 5b 44 } left
  </code></pre>
  
  <p>Given the dual role of this byte, how do I detect when the user just pressed escape, as opposed to pressing one of the other keys?</p>
  
  <ul>
  <li><p>I cannot wait for the next byte after a <code>0x1b</code>, since there may not be one. The user can press escape and then wait indefinitely for my program to respond to that key.</p></li>
  <li><p>I could call <code>read()</code> once to read all available data on the terminal and check whether that's only one byte or several bytes long. This works, provided that we trust the terminal is fast enough to send all the relevant bytes in time for the <code>read()</code> and only sends one keystroke at a time (so the <code>read()</code> doesn't return extra data or partial keystrokes). Is this a reasonable assumption nowadays that people practically always use terminal emulators? What about network links (e.g. SSH) causing delays?</p></li>
  <li><p>I could call <code>read()</code> repeatedly, reading only one byte with each <code>read()</code> call until there are no more bytes available. The <a href="https://github.com/antirez/linenoise/blob/master/linenoise.c" rel="nofollow noreferrer">linenoise</a> library does this, citing compatibility with slow terminals as the reason (but doesn't say which particular terminals those are).</p></li>
  </ul>
  
  <p>A couple of general considerations:</p>
  
  <ul>
  <li><p>Should I be doing blocking or non-blocking reads? Does it matter?</p></li>
  <li><p>Should I be using a read timeout, and if so, is there some empirically determined value that is often used?</p></li>
  </ul>
  
  <p>I used the following test program to show the bytes for the keystrokes:</p>
  
  <pre><code>#include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  
  #include &lt;stdio.h&gt;
  #include &lt;termios.h&gt;
  
  static void dump(void) {
      unsigned char bytes[8];
      ssize_t i, n;
      while ((n = read(0, bytes, sizeof(bytes))) &gt; 0) {
          printf("{ ");
          for (i = 0; i &lt; n; i++) {
              printf("%02x ", bytes[i]);
          }
          printf("}\r\n");
          if (bytes[0] == 'q') {
              break;
          }
      }
  }
  
  int main(void) {
      struct termios origMode;
      struct termios rawMode;
      cfmakeraw(&amp;rawMode);
      tcgetattr(0, &amp;origMode);
      tcsetattr(0, TCSAFLUSH, &amp;rawMode);
      dump();
      tcsetattr(0, TCSAFLUSH, &amp;origMode);
      return 0;
  }
  </code></pre>