Skip to main content

PartialParse

Struct PartialParse 

Source
pub struct PartialParse<'a> {
    pub completed: Vec<&'a str>,
    pub partial: &'a str,
    pub tree_path: Vec<&'a str>,
    pub raw_line: &'a str,
    pub cursor_offset: usize,
    pub tap_count: u32,
}
Expand description

Structured snapshot of the partial command-line state at the cursor position. Passed to subtree providers so they can offer context-aware completions without re-tokenising COMP_LINE.

Carries both the whitespace-tokenised view (completed, partial, tree_path — the same shape every veks-completion flow uses) AND the raw line + cursor offset that grammar-aware providers (e.g. for embedded query DSLs like MetricsQL or PromQL) need to resolve quote / bracket / operator state. Callers that don’t have raw context populate raw_line with an empty string and cursor_offset with 0 — grammar helpers fall back to the tokenised view in that case.

Fields§

§completed: Vec<&'a str>

Words the user has already completed (whitespace-separated, program name excluded).

§partial: &'a str

The partial word currently under the cursor (may be empty).

§tree_path: Vec<&'a str>

Path through the command tree that resolved against completed. Same shape as completed but only the prefix that maps to actual nodes.

§raw_line: &'a str

Raw COMP_LINE (or equivalent) — the full command line as the user typed it, before any tokenisation. Empty when the caller didn’t have it.

§cursor_offset: usize

Byte offset of the cursor within raw_line. 0 when raw_line is empty.

§tap_count: u32

Tap count for this completion invocation. The engine sets this from the rotating-tier counter (1 on the first tap, 2 on a rapid follow-up, etc.). Providers may use it to layer their output — e.g., tap 1 = primary candidates (metric names inside a function-arg position), tap 2 = + secondary candidates (inner functions to stack). Defaults to 1 for callers that don’t drive rotation.

Implementations§

Source§

impl<'a> PartialParse<'a>

Source

pub const DEFAULT_BASH_WORDBREAKS: &'static str = " \t\n<>;|&"

COMP_WORDBREAKS value that the engine’s bash hook installs locally — a deliberately minimal set that keeps shell metacharacters as word separators (< > ; | &) but drops everything bash would otherwise use to “helpfully” split inside a grammar token: ' " (shell wrapper quotes), = (key=value), ( (function-call open), : (label values, subquery step). With these out of the way:

  • 'metricsql expr is one word → readline doesn’t auto-close the wrapper quote when our candidate ends mid-context (e.g. delta().
  • up{job= is one word → label-value candidates splice cleanly without prefix gymnastics.
  • delta(rate( is one word → nested function-call completions work without the shell mid-quoting.

This is the bash-side “raw mode” the engine relies on so shell-quoting heuristics don’t fight grammar-aware splicing. The hook sets it locally per call so the user’s interactive COMP_WORDBREAKS is untouched outside completion.

{, [, ], }, , were already not in bash’s default set — they don’t split the word in bash, which is what makes PartialParse::splice_candidate necessary in the first place. We additionally strip ' " = ( : to extend the same “splicer owns this” treatment to those grammar contexts.

Source

pub fn before_cursor(&self) -> &'a str

Slice of raw_line strictly before the cursor. Empty when raw_line is empty.

Source

pub fn after_cursor(&self) -> &'a str

Slice of raw_line from the cursor to the end.

Source

pub fn bracket_state(&self) -> BracketState

Compute the bracket / quote state at the cursor by linearly scanning before_cursor. Honors quotes (everything inside "…" or '…' is counted as string content, brackets within don’t shift the depth) and supports backslash-escapes inside quotes.

When raw_line is empty (caller didn’t supply it), returns the default zero-depth state.

Source

pub fn trigger_char(&self) -> Option<char>

Last non-whitespace, non-identifier character before the cursor, scanning back over identifier characters first. Useful for “what symbol triggered this completion?” — e.g., = after label means we’re in a label-value position. Returns None if the only thing before the cursor is identifier characters or whitespace.

Source

pub fn shell_word_start(&self) -> usize

Byte offset in Self::raw_line where the shell will consider the “current word” to begin — the byte after the last word-separator character before the cursor, or 0 if none. Falls back to 0 when raw_line is empty.

Today this assumes bash semantics (Self::DEFAULT_BASH_WORDBREAKS). When other shells gain first-class support, this method may take a per-shell wordbreak set.

Source

pub fn shell_current_word(&self) -> &'a str

What the shell sees as the “current word” — the slice between Self::shell_word_start and the cursor. This is the segment the shell will replace when the user accepts a candidate the engine returns.

Source

pub fn splice_candidate(&self, target_start: usize, suggestion: &str) -> String

Splice a logical suggestion into the shell-correct form for a COMPREPLY candidate. Providers compute suggestions in their own grammar terms (e.g. “the label key is job”); this helper produces the substitution string the shell needs so that whatever the user already typed in the shell-perceived current word, before the suggestion’s insertion point, is preserved.

target_start is the byte offset in Self::raw_line where the suggestion logically begins. For an inside-{ label-key suggestion in up{job, target_start is the position right after the {. The helper returns raw_line[shell_word_start..target_start] + suggestion — i.e., the part of the shell’s current word that’s BEFORE the completion target, plus the new content.

When target_start <= shell_word_start, the suggestion replaces the entire shell word (or starts before it), so the helper returns the suggestion unchanged.

§Example
use veks_completion::PartialParse;

let pp = PartialParse {
    completed: vec![],
    partial: "",
    tree_path: vec![],
    raw_line: "myapp query up{",
    cursor_offset: 15,
    tap_count: 1,
};
assert_eq!(pp.shell_word_start(), 12);          // after the last space
assert_eq!(pp.shell_current_word(), "up{");     // shell will replace this

// Suggestion: the label key `job`. Logically it starts
// right after the `{` (byte 15).
let candidate = pp.splice_candidate(15, "job");
assert_eq!(candidate, "up{job");
// → shell replaces "up{" with "up{job" ⇒ final word "up{job"
Source

pub fn ident_before_cursor(&self) -> &'a str

Identifier (or partial identifier) immediately to the left of the cursor. For input up{job=, returns "" (cursor is right after =, so the partial-ident before the cursor is empty). For input up{jo, returns "jo".

Trait Implementations§

Source§

impl<'a> Clone for PartialParse<'a>

Source§

fn clone(&self) -> PartialParse<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for PartialParse<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for PartialParse<'a>

§

impl<'a> RefUnwindSafe for PartialParse<'a>

§

impl<'a> Send for PartialParse<'a>

§

impl<'a> Sync for PartialParse<'a>

§

impl<'a> Unpin for PartialParse<'a>

§

impl<'a> UnsafeUnpin for PartialParse<'a>

§

impl<'a> UnwindSafe for PartialParse<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.