little problem with while, Serial.read, Serial.peek

Lines 4 to 15 are to loop or break depending on if ESC has been pressed.
If by mistake the key buffer was not empty before ESC, ESC was not recognized.
So I added a routine to empty the buffer. This mostly works but if the buffer was not empty before ESC then a 'dit' or 'dah' has to be sent before the function exits. I have tried moving the code between lines 6 to 11 and some other things but have not solved this minor problem.

void paddle() // send code w/option to change wpm without monitor
  unsigned int dit = 0; unsigned int dah = 0; unsigned long lastChar = 0;
  refresh_Screen(); Serial.println(F("Press Esc to quit paddle mode"));
  while (Serial.read() != 27)
  {
    while (Serial.available() > 0) { // clear the buffer till ESC. this is close but not perfect. grr---
      if (Serial.peek() != 27) {       // char has to be sent before the function quits
        Serial.read();
      }
      else if (Serial.peek() == 27) {
        code_string = ""; menu(); return;
      }
    } //------------------------------------------------------------------------------------------------------------
    while (digitalRead(P_dit) && digitalRead(P_dah) && Serial.peek() != 27) // wait for input
    {
      if (battery == false)
      {
        lastChar = millis() - lastTone;
        if (lastChar > elementWait * 3 + 1 && code_string != "") match_code_str();
        //if (lastChar > elementWait * space + 1 && code_string != "") match_code_str();
      }
    }
    if (!digitalRead(P_dit)) // If the dit pin is LOW...
    {
      dit_dah(".");         // send a dot and update lastTone
      if (battery == false) // in battery mode there is no screen or keyboard attached
      {
        ifWord(lastChar); // add space between words
        code_string.concat(".");
      }
      if (battery == true) // if 15 dits with no dah, wpm = wpm + 2 for example
      {
        dit++; dah = 0; // if 15 dits with no dah, we have a change wpm request
        if (dit > 14)
        {
          dit = 0; wpm = wpm + 2; eWait(); wpm2code(); // update data & send the new wpm to user
        }
      }
    }
    if (!digitalRead(P_dah)) // If the dah pin is LOW...
    {
      dit_dah("-");         // send a dash
      if (battery == false) // in battery mode there is no screen or keyboard attached
      {
        ifWord(lastChar); code_string.concat("-");
      }
      if (battery == true)
      {
        dah++; dit = 0;     // if 15 dahs with no dits, we have a change wpm request
        if (dah > 14)
        {
          dah = 0; wpm = wpm - 2; eWait(); wpm2code(); // update data & send the new wpm to user
        }
      }
    }
  }
  code_string = ""; menu(); return;
}

You have yet to describe the actual problem.

More importantly, you have yet to describe how the working code should behave (what is the goal).

"You have yet to describe the actual problem."

I'm trying to clear the key buffer so that ESC is not on the stack behind other key presses.
Problem:
Leaving this function and going back to the main menu is not always IMMEDIATE after pressing ESC .
Works fine if no key is pressed except ESC.
If the user presses a key before ESC, a Morse character has to be sent before the function exits.

void paddle()
{
Serial.println(F("Press Esc to quit paddle mode"));
  while (Serial.read() != 27)
  {
    while (Serial.available() > 0) { // clear the buffer till ESC. this is close but not perfect. grr
      if (Serial.peek() != 27) {
        Serial.read();
      }
      else if (Serial.peek() == 27) {
        code_string = ""; menu(); return;
      }
    }
    while (digitalRead(P_dit) && digitalRead(P_dah) && Serial.peek() != 27) // wait for input
    {
     // not part of the problem. However, already posted.
    } 
  }
  code_string = ""; menu(); return;
}

When paddle is running and the human presses ESC what is supposed to happen?

The function should exit.
return to menu();
quit.
go do something else.

flat5:
The function should exit.

Then why is IMMEDIATE in this sentence…

Leaving this function and going back to the main menu is not always IMMEDIATE after pressing ESC .

Solved. Changed Serial.peek() to !Serial.available()

while (digitalRead(P_dit) && digitalRead(P_dah) && !Serial.available()) // peek() != 27) // wait for input