promql/ui: highlight start()/end()/range()/step() as functions; start()/end() as modifiers only after @

Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
This commit is contained in:
Julien Pivotto 2026-04-17 15:49:45 +02:00
parent 5d0bc055ef
commit 504c5e67ea
6 changed files with 139 additions and 13 deletions

View File

@ -275,6 +275,12 @@ export const functionIdentifierTerms = [
info: 'Calculate smoothed value of input series',
type: 'function',
},
{
label: 'end',
detail: 'function',
info: 'Return the query end timestamp in seconds',
type: 'function',
},
{
label: 'hour',
detail: 'function',
@ -433,6 +439,12 @@ export const functionIdentifierTerms = [
// Avoid ranking higher than `rate`.
boost: -1,
},
{
label: 'range',
detail: 'function',
info: 'Return the query range in seconds',
type: 'function',
},
{
label: 'rate',
detail: 'function',
@ -505,6 +517,18 @@ export const functionIdentifierTerms = [
info: 'Return the square root for input series',
type: 'function',
},
{
label: 'start',
detail: 'function',
info: 'Return the query start timestamp in seconds',
type: 'function',
},
{
label: 'step',
detail: 'function',
info: 'Return the query step in seconds',
type: 'function',
},
{
label: 'stddev_over_time',
detail: 'function',

View File

@ -37,6 +37,7 @@ import {
Deg,
Delta,
Deriv,
EndFn,
Exp,
FirstOverTime,
Floor,
@ -74,6 +75,7 @@ import {
PresentOverTime,
QuantileOverTime,
Rad,
Range,
Rate,
Resets,
Round,
@ -86,6 +88,8 @@ import {
SortByLabel,
SortByLabelDesc,
Sqrt,
StartFn,
Step,
StddevOverTime,
StdvarOverTime,
SumOverTime,
@ -265,6 +269,12 @@ const promqlFunctions: { [key: number]: PromQLFunction } = {
variadic: 0,
returnType: ValueType.vector,
},
[EndFn]: {
name: 'end',
argTypes: [],
variadic: 0,
returnType: ValueType.scalar,
},
[Exp]: {
name: 'exp',
argTypes: [ValueType.vector],
@ -487,6 +497,12 @@ const promqlFunctions: { [key: number]: PromQLFunction } = {
variadic: 0,
returnType: ValueType.vector,
},
[Range]: {
name: 'range',
argTypes: [],
variadic: 0,
returnType: ValueType.scalar,
},
[Rate]: {
name: 'rate',
argTypes: [ValueType.matrix],
@ -559,6 +575,18 @@ const promqlFunctions: { [key: number]: PromQLFunction } = {
variadic: 0,
returnType: ValueType.vector,
},
[StartFn]: {
name: 'start',
argTypes: [],
variadic: 0,
returnType: ValueType.scalar,
},
[Step]: {
name: 'step',
argTypes: [],
variadic: 0,
returnType: ValueType.scalar,
},
[StddevOverTime]: {
name: 'stddev_over_time',
argTypes: [ValueType.matrix],

View File

@ -20,10 +20,10 @@ export const promQLHighLight = styleTags({
NumberDurationLiteral: tags.number,
NumberDurationLiteralInDurationContext: tags.number,
Identifier: tags.variableName,
'Abs Absent AbsentOverTime Acos Acosh Asin Asinh Atan Atanh AvgOverTime Ceil Changes Clamp ClampMax ClampMin Cos Cosh CountOverTime DaysInMonth DayOfMonth DayOfWeek DayOfYear Deg Delta Deriv Exp Floor HistogramAvg HistogramCount HistogramFraction HistogramQuantile HistogramSum DoubleExponentialSmoothing Hour Idelta Increase Irate LabelReplace LabelJoin LastOverTime Ln Log10 Log2 MaxOverTime MinOverTime Minute Month Pi PredictLinear PresentOverTime QuantileOverTime Rad Rate Resets Round Scalar Sgn Sin Sinh Sort SortDesc SortByLabel SortByLabelDesc Sqrt StddevOverTime StdvarOverTime SumOverTime Tan Tanh Time Timestamp Vector Year':
'Abs Absent AbsentOverTime Acos Acosh Asin Asinh Atan Atanh AvgOverTime Ceil Changes Clamp ClampMax ClampMin Cos Cosh CountOverTime DaysInMonth DayOfMonth DayOfWeek DayOfYear Deg Delta Deriv EndFn Exp Floor HistogramAvg HistogramCount HistogramFraction HistogramQuantile HistogramSum DoubleExponentialSmoothing Hour Idelta Increase Irate LabelReplace LabelJoin LastOverTime Ln Log10 Log2 MaxOverTime MinOverTime Minute Month Pi PredictLinear PresentOverTime QuantileOverTime Rad Range Rate Resets Round Scalar Sgn Sin Sinh Sort SortDesc SortByLabel SortByLabelDesc Sqrt StartFn Step StddevOverTime StdvarOverTime SumOverTime Tan Tanh Time Timestamp Vector Year':
tags.function(tags.variableName),
'Avg Bottomk Count Count_values Group LimitK LimitRatio Max Min Quantile Stddev Stdvar Sum Topk': tags.operatorKeyword,
'By Without Bool On Ignoring GroupLeft GroupRight Offset Start End Smoothed Anchored': tags.modifier,
'AtModifierPreprocessors By Without Bool On Ignoring GroupLeft GroupRight Offset Smoothed Anchored': tags.modifier,
'And Unless Or': tags.logicOperator,
'Sub Add Mul Mod Div Atan2 Eql Neq Lte Lss Gte Gtr EqlRegex EqlSingle NeqRegex Pow At': tags.operator,
UnaryOp: tags.arithmeticOperator,

View File

@ -211,6 +211,10 @@ FunctionIdentifier {
SortDesc |
SortByLabel |
SortByLabelDesc |
StartFn |
EndFn |
Range |
Step |
Sqrt |
StddevOverTime |
StdvarOverTime |
@ -287,7 +291,7 @@ StepInvariantExpr {
}
AtModifierPreprocessors {
Start | End
AtStart | AtEnd
}
NumberDurationLiteral {
@ -387,8 +391,10 @@ NumberDurationLiteralInDurationContext {
And,
Or,
Unless,
Start,
End,
StartFn,
EndFn,
AtStart,
AtEnd,
Smoothed,
Anchored,
Fill,
@ -473,6 +479,8 @@ NumberDurationLiteralInDurationContext {
SortDesc { condFn<"sort_desc"> }
SortByLabel { condFn<"sort_by_label"> }
SortByLabelDesc { condFn<"sort_by_label_desc"> }
Range { condFn<"range"> }
Step { condFn<"step"> }
Sqrt { condFn<"sqrt"> }
StddevOverTime { condFn<"stddev_over_time"> }
StdvarOverTime { condFn<"stdvar_over_time"> }

View File

@ -20,7 +20,6 @@ import {
By,
Count,
CountValues,
End,
Group,
GroupLeft,
GroupRight,
@ -35,13 +34,16 @@ import {
Quantile,
LimitK,
LimitRatio,
Start,
StartFn,
EndFn,
Stddev,
Stdvar,
Sum,
Topk,
Unless,
Without,
AtEnd,
AtStart,
Smoothed,
Anchored,
Fill,
@ -85,8 +87,6 @@ const contextualKeywordTokens = {
and: And,
or: Or,
unless: Unless,
start: Start,
end: End,
smoothed: Smoothed,
anchored: Anchored,
fill: Fill,
@ -95,5 +95,23 @@ const contextualKeywordTokens = {
};
export const extendIdentifier = (value, stack) => {
return contextualKeywordTokens[value.toLowerCase()] || -1;
if (value === "start" && stack.canShift(StartFn)) {
return StartFn;
}
if (value === "end" && stack.canShift(EndFn)) {
return EndFn;
}
if (value.toLowerCase() === "start" && stack.canShift(AtStart)) {
return AtStart;
}
if (value.toLowerCase() === "end" && stack.canShift(AtEnd)) {
return AtEnd;
}
const token = contextualKeywordTokens[value.toLowerCase()];
if (token !== undefined && stack.canShift(token)) {
return token;
}
return -1;
};

View File

@ -428,6 +428,54 @@ end
==>
PromQL(VectorSelector(Identifier))
# Lowercase start function.
start()
==>
PromQL(
FunctionCall(
FunctionIdentifier(StartFn),
FunctionCallBody
)
)
# Lowercase end function.
end()
==>
PromQL(
FunctionCall(
FunctionIdentifier(EndFn),
FunctionCallBody
)
)
# Lowercase range function.
range()
==>
PromQL(
FunctionCall(
FunctionIdentifier(Range),
FunctionCallBody
)
)
# Lowercase step function.
step()
==>
PromQL(
FunctionCall(
FunctionIdentifier(Step),
FunctionCallBody
)
)
# Simple At start
foo @ start()
@ -439,7 +487,7 @@ PromQL(
Identifier
),
At,
AtModifierPreprocessors(Start),
AtModifierPreprocessors(AtStart),
)
)
@ -454,7 +502,7 @@ PromQL(
Identifier
),
At,
AtModifierPreprocessors(End),
AtModifierPreprocessors(AtEnd),
)
)
@ -484,7 +532,7 @@ PromQL(
Identifier
),
At,
AtModifierPreprocessors(Start),
AtModifierPreprocessors(AtStart),
)
)