Search code examples
c++shellcommand-line-interfacereadlinegetchar

How to detect the Enter key when pasting multi-line text (containing `\r`)?


While developing a line editor in C++, I'm using getch() to capture each key input, and see \r(13 in ASCII) as the Enter key. However, when pasting text that contains multiple lines, the program mistakenly interprets \r within the text as an Enter key press.

I've noticed that in some shells, when pasting multiple lines, they automatically handle the input as new lines, without executing each line individually. I'm curious about how they achieve this. Do they detect key presses without relying on getch()?

Is there a cross-platform way in C or C++ to handle this issue effectively?


Solution

  • Seems to me you are mixing the concepts of Shell and console here.

    Firstly, no matter whether you are typing or pasting something, you effectively trigger an interrupt. How is the interrupt handled depends on what process you are currently running.

    For your situation, certainly the terminal/console is the one currently running, the interrupt is handled by the console, hence you instantly get the character you just typed shows on the display.

    Up to now, whatever you typed/pasted is not executed, they are simply buffered until a "enter/return" is pressed, which could be a single '\n' or "\r\n", in Linux and Windows, respectively, then Shell takes over and execute your instructions.

    So for your statement:

    they automatically handle the input as new lines, without executing each line individually.

    The reason is obvious for now, hopefully:

    • They are displayed as multiple lines because they are themselves really multiple lines, the console process simply shows whatever it is.
    • The first line is not executed immediately because you haven't pushed the return on your keyboard, only when the interrupt of return/enter signals and get processed by your console, will the Shell take over and execute. That said, when you pressed return, they'll still be executed as separate commands, unless '\' is appended at end of each line.