use comemo::Tracked;

use crate::diag::HintedStrResult;
use crate::foundations::{Context, func};
use crate::introspection::Location;

/// Provides the current location in the document.
///
/// You can think of `here` as a low-level building block that directly extracts
/// the current location from the active @reference:context[context]. Some other
/// functions use it internally: For instance, `{counter.get()}` is equivalent
/// to `{counter.at(here())}`.
///
/// Within show rules on @location:locatable[locatable] elements, `{here()}`
/// will match the location of the shown element.
///
/// If you want to display the current page number, refer to the documentation
/// of the @counter type. While `here` can be used to determine the physical
/// page number, typically you want the logical page number that may, for
/// instance, have been reset after a preface.
///
/// = Examples <examples>
/// Determining the current position in the document in combination with the
/// @location.position[`position`] method:
///
/// ```example
/// #context [
///   I am located at
///   #here().position()
/// ]
/// ```
///
/// Running a @query[query] for elements before the current position:
///
/// ```example
/// = Introduction
/// = Background
///
/// There are
/// #context query(
///   selector(heading).before(here())
/// ).len()
/// headings before me.
///
/// = Conclusion
/// ```
///
/// Refer to the @selector type for more details on before/after selectors.
#[func(contextual)]
pub fn here(context: Tracked<Context>) -> HintedStrResult<Location> {
    context.location()
}
