Closure, anonymous functions or binds on delayed functions
Actually, what you are looking for is already done in Lodash via debounce or throttle. And yes, a closure is probably the best way to do this. So let's take your closure example and improve it.

Instead of returning a function, why not just define the function normally. That way, there's no developer overhead. Devs shouldn't know about your limiter function just to make their APIs.

// We'll be fine with this
function get(input, html_output) {
  if (!input) return;    

  $.ajax('/_api/pp_search/' + input).done(function (data) {
    html_output[0].innerHTML = data;
  });

}


delay is a bit deceiving as the word "delay" can mean a lot of things. It can mean "pause", which then equates to sleep which does an entirely different thing. "debounce" and "throttle" are actually better names. Verbose names aren't that bad as well (except for the extra keystrokes). Something like holdExecutionUntilAfter.

Now for the implementation, let's accept a delay and the function we want to delay. Our return will be our "proxy" function that controls the real function from executing.

function holdExecutionUntilAfter(fn, delay){
  var timer = null;

  return function(){
    if(timer) clearTimeout(timer);

    setTimeout(function(){
      fn.apply(null, arguments);
      clearTimeout(timer);
    }, delay);
  }
}


As simple as that! What it does is get a reference of the real function into a closure. Then we return a "proxy" function which well be using to call the real function. When it gets called, it resets the timer and kicks off another. We use apply to pass in the arguments like you normally would in the regular call. Usage will be as simple as:

var get = delay(function(input, html_output){
  if (!input) return;    
  $.ajax('/_api/pp_search/' + input).done(function (data) {
    html_output[0].innerHTML = data;
  });
}, 500);

get(event.currentTarget.value, $results);

// or verbosely

function get(input, html_output){
  if (!input) return;    

  $.ajax('/_api/pp_search/' + input).done(function (data) {
    html_output[0].innerHTML = data;
  });
}
var proxiedGet = delay(get, 500);

proxiedGet(event.currentTarget.value, $results);