Have a button input interrupt code

I've written some basic code for a light I'm making. I've started introducing modes, so having the lights flash on different intervals, with the mode being cycled through a button press. The major flaw in my code is that you can't interrupt the patterns, the button has to be pushed at the end of the mode's cycle. This is a problem for ideas like running morse code, as it makes it hard to switch past that mode. So I'm wondering if there's a way to interrupt the code while its running, instead of having to wait for the end of the cycle.

Effectively, when switchVal goes HIGH, I want it to bring the code back to the beginning of loop(), even if it's partway through one of the if loops.

#include <Morse.h>
int buttonPin = 13;
int pin = 11;
int counter = 0;
int switchVal = digitalRead(buttonPin);
Morse Morse(11);

void setup(){
  pinMode(buttonPin, INPUT);
  pinMode(pin, OUTPUT);
}
void loop()
{
    int switchVal = digitalRead(buttonPin);
    if(switchVal == HIGH)
    {
      counter ++;
      delay(500);
    }
    if(counter == 0){
      digitalWrite(pin, HIGH);
      delay(8);
      digitalWrite(pin, LOW);
      delay(87);
  }
    else if(counter == 1){
      digitalWrite(pin, HIGH);
  }
    else if(counter == 2){
      digitalWrite(pin, HIGH);
      delay(200);
      digitalWrite(pin, LOW);
      delay(100);
      digitalWrite(pin, HIGH);
      delay(100);
      digitalWrite(pin, LOW);
      delay(50);
  }
    else if(counter >= 3){
      counter = 0;
  }
}

The major flaw in my code is that you can't interrupt the patterns, the button has to be pushed at the end of the mode's cycle.

Only because you are using delay() which stops everything except interrupts.

The Blink Without Delay example shows how to blink an LED without using the dreaded delay() function.

The modes you are introducing are states. You could do a bit of research on state machines, if you are interested.

But, basically, extending the Blink Without Delay example means reading the button state at the top of loop(), and then having a function for each state. Call the appropriate function based on the current state, possibly as modified as a result of the button having changed to the pressed state.

Within each function, see if it is time to do something different. If so record the new time, and do something. Otherwise, just return.