Timer0 Interruption xc8
Personally I prefer never to use the "simplified" macros provided by Microchip. They hide just what is going on from you and you never learn what you're really doing with the hardware.

I notice you aren't actually turning on interrupts in your code.  You have to do that manually yourself.

This is a snippet of code I use, directly manipulating the registers instead of using the macros, which enables timer 0 for 1ms ticks on a PIC18:

// Set up TIMER0 to tick at 1ms intervals.
// The oscillator ticks at Fosc/4, so 4MHz. That is 1/16000000 s per tick.
// or 0.000000063s, or 0.000063ms, so 1 ms is 16000 ticks.
T0CONbits.T08BIT = 0; // 16-bit
T0CONbits.T0CS = 0; // Internal clock
T0CONbits.PSA = 1; // No prescaler
uint16_t tpr = (F_CPU/4)/1000;
tpr = 0xFFFF - tpr;
TMR0H = tpr &gt;&gt; 8;
TMR0L = tpr &amp; 0xFF;
INTCONbits.T0IF = 0; // Clear the flag
INTCONbits.T0IE = 1; // Enable the interrupt
INTCONbits.PEIE = 1; // Turn on peripheral interrupts  &lt;-- This is needed by you
INTCONbits.GIE = 1; // ... and global interrupts  &lt;-- As is this
T0CONbits.TMR0ON = 1; // and finally set the period.


And then my ISR looks like:

void interrupt low_priority __isr_handler(void) {
    if (INTCONbits.TMR0IE &amp;&amp; INTCONbits.T0IF) {
        INTCONbits.T0IF = 0;
        uint16_t tpr = (F_CPU/4)/1000;
        tpr = 0xFFFF - tpr;
        TMR0H = tpr &gt;&gt; 8;
        TMR0L = tpr &amp; 0xFF;
        __millis++;
    }
}


One reason I prefer to do manual register manipulation is that you get to decide exactly what order things are done in.  You notice I do all the setting up first - configuring the timer, the interrupts, everything - and only once all that is done do I actually turn on the timer.