Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.765
diff -u -F^function -r1.765 common.inc
--- includes/common.inc	6 May 2008 12:18:45 -0000	1.765
+++ includes/common.inc	11 May 2008 16:27:18 -0000
@@ -2915,6 +2915,9 @@ function drupal_common_theme() {
     'pager' => array(
       'arguments' => array('tags' => array(), 'limit' => 10, 'element' => 0, 'parameters' => array()),
     ),
+    'pager_range' => array(
+      'arguments' => array('limit' => 10, 'element' => 0),
+    ),
     'pager_first' => array(
       'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'parameters' => array()),
     ),
Index: includes/pager.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/pager.inc,v
retrieving revision 1.63
diff -u -F^function -r1.63 pager.inc
--- includes/pager.inc	6 Dec 2007 09:58:30 -0000	1.63
+++ includes/pager.inc	11 May 2008 16:27:21 -0000
@@ -91,6 +91,41 @@ function pager_get_querystring() {
 }
 
 /**
+ * Get a description of the range of items presented by the pager (e.g. Items x
+ * of y of z).
+ *
+ * @param $limit
+ *   The number of query results displayed per page.
+ * @param $element
+ *   An optional integer to distinguish between multiple pagers on one page.
+ * @return
+ *   A string containing the description, or an empty string if there are no
+ *   items.
+ */
+function pager_describe_range($limit = 10, $element = 0) {
+  global $pager_page_array, $pager_total, $pager_total_items;
+
+  // Prepare additional information about the current paging status.
+  $from = $pager_page_array[$element] * $limit + 1;
+  $to = min(($pager_page_array[$element] + 1) * $limit, $pager_total_items[$element]);
+  if ($pager_total_items[$element] == 1) {
+    return t('1 item');
+  }
+  elseif ($pager_total_items[$element] > 1) {
+    if ($from == $to) {
+      return t('Item @to of @total', array('@to' => $to, '@total' => $pager_total_items[$element]));
+    }
+    elseif ($pager_total_items[$element] <= $limit) {
+      return t('@total items', array('@total' => $pager_total_items[$element]));
+    }
+    else {
+      return t('Items @from - @to of @total', array('@from' => $from, '@to' => $to, '@total' => $pager_total_items[$element]));
+    }    
+  }
+  return '';
+}
+
+/**
  * Format a query pager.
  *
  * Menu callbacks that display paged query results should call theme('pager') to
@@ -214,6 +249,17 @@ function theme_pager($tags = array(), $l
   }
 }
 
+/**
+ * Format pager ranges on the total number of items.
+ *
+ * @param $limit
+ *   The number of query results displayed per page.
+ * @param $element
+ *   An optional integer to distinguish between multiple pagers on one page.
+ */
+function theme_pager_range($limit = 10, $element = 0) {
+  return '<div class="pager-range">' . pager_describe_range($limit, $element) . '</div>';
+}
 
 /**
  * @name Pager pieces
Index: modules/search/search-results.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search-results.tpl.php,v
retrieving revision 1.1
diff -u -F^function -r1.1 search-results.tpl.php
--- modules/search/search-results.tpl.php	31 Oct 2007 18:06:38 -0000	1.1
+++ modules/search/search-results.tpl.php	11 May 2008 16:27:26 -0000
@@ -21,6 +21,7 @@
  * @see template_preprocess_search_results()
  */
 ?>
+<?php print $pager_range; ?>
 <dl class="search-results <?php print $type; ?>-results">
   <?php print $search_results; ?>
 </dl>
Index: modules/search/search.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.pages.inc,v
retrieving revision 1.5
diff -u -F^function -r1.5 search.pages.inc
--- modules/search/search.pages.inc	14 Apr 2008 17:48:41 -0000	1.5
+++ modules/search/search.pages.inc	11 May 2008 16:27:30 -0000
@@ -63,7 +63,8 @@ function template_preprocess_search_resu
   foreach ($variables['results'] as $result) {
     $variables['search_results'] .= theme('search_result', $result, $variables['type']);
   }
-  $variables['pager'] = theme('pager', NULL, 10, 0);
+  $variables['pager'] = theme('pager');
+  $variables['pager_range'] = theme('pager_range');
   // Provide alternate search results template.
   $variables['template_files'][] = 'search-results-' . $variables['type'];
 }
Index: includes/pager.test
===================================================================
--- /dev/null	2008-05-17 18:17:13.640625000 -0400
+++ includes/pager.test	2008-05-17 18:01:57.953125000 -0400
@@ -0,0 +1,109 @@
+<?php
+// $Id$
+
+/**
+ * Tests the pager range description function. Since pager_describe_range()
+ * relies on global pager variables, this test sets those variables and checks
+ * whether the right description is returned.
+ */
+class DescribePagerRangeTestCase extends DrupalWebTestCase {
+  /**
+   * Implementation of getInfo().
+   */
+  function getInfo() {
+    return array(
+      'name' => t('Pager range description'),
+      'description' => t('Tests the pager range description function.'),
+      'group' => t('Pager'),
+    );
+  }
+
+  /**
+   * Test pager description with no items.
+   */
+  function testNoItems() {
+    $this->_testNoItems(0);
+    $this->_testNoItems(1);
+  }
+
+  /**
+   * Test pager description with a total of one item.
+   */
+  function testSingleItem() {
+    $this->_testSingleItem(0);
+    $this->_testSingleItem(1);
+  }
+
+  /**
+   * Test pager description for a page showing only the last item.
+   */
+  function testLastItem() {
+    $this->_testLastItem(0);
+    $this->_testLastItem(1);
+  }
+
+  /**
+   * Test pager description for multiple items fitting a single page.
+   */
+  function testSinglePage() {
+    $this->_testSinglePage(0);
+    $this->_testSinglePage(1);
+  }
+
+  /**
+   * Test pager description with multiple pages.
+   */
+  function testMultiplePages() {
+    $this->_testMultiplePages(0);
+    $this->_testMultiplePages(1);
+  }
+  
+  function _testNoItems($element) {
+    global $pager_page_array, $pager_total, $pager_total_items;
+    $pager_page_array[$element] = 0; // Current page.
+    $pager_total[$element] = 0; // Number of pages.
+    $pager_total_items[$element] = 0; // Number items.
+    $description = pager_describe_range(10, $element);
+    $this->assertEqual($description, '', t('Got description "@description" for pager @element', array('@element' => $element, '@description' => $description)));
+  }
+
+  function _testSingleItem($element) {
+    global $pager_page_array, $pager_total, $pager_total_items;
+    $pager_page_array[$element] = 0; // Current page.
+    $pager_total[$element] = 1; // Number of pages.
+    $pager_total_items[$element] = 1; // Number items.
+    $description = pager_describe_range(10, $element);
+    $this->assertEqual($description, t('1 item'), t('Got description "@description" for pager @element', array('@element' => $element, '@description' => $description)));
+  }
+
+  function _testLastItem($element) {
+    global $pager_page_array, $pager_total, $pager_total_items;
+    $pager_page_array[$element] = 1; // Current page.
+    $pager_total[$element] = 2; // Number of pages.
+    $pager_total_items[$element] = 11; // Number items.
+    $description = pager_describe_range(10, $element);
+    $this->assertEqual($description, t('Item 11 of 11'), t('Got description "@description" for pager @element', array('@element' => $element, '@description' => $description)));
+  }
+  
+  function _testSinglePage($element) {
+    global $pager_page_array, $pager_total, $pager_total_items;
+    $pager_page_array[$element] = 0; // Current page.
+    $pager_total[$element] = 1; // Number of pages.
+    $pager_total_items[$element] = 10; // Number items.
+    $description = pager_describe_range(10, $element);
+    $this->assertEqual($description, t('10 items'), t('Got description "@description" for pager @element', array('@element' => $element, '@description' => $description)));
+  }
+
+  function _testMultiplePages($element) {
+    global $pager_page_array, $pager_total, $pager_total_items;
+    $pager_page_array[$element] = 0; // Current page.
+    $pager_total[$element] = 2; // Number of pages.
+    $pager_total_items[$element] = 25; // Number items.
+    $description = pager_describe_range(10, $element);
+    $this->assertEqual($description, t('Items 1 - 10 of 25'), t('Got description "@description" for pager @element', array('@element' => $element, '@description' => $description)));
+    
+    $pager_page_array[$element] = 2; // Current page.
+    $description = pager_describe_range(10, $element);
+    $this->assertEqual($description, t('Items 21 - 25 of 25'), t('Got description "@description" for pager @element', array('@element' => $element, '@description' => $description)));
+  }
+}
