浏览代码

Fix closing parens completion for prometheus queries in Explore (#12810)

- position was determined by SPACE, but Prometheus selectors can
  contain spaces
- added negative lookahead to check if space is outside a selector
- moved braces plugin into PromQueryField since braces are prom specific
David 7 年之前
父节点
当前提交
0f94d2f5f1

+ 2 - 0
public/app/containers/Explore/PromQueryField.tsx

@@ -7,6 +7,7 @@ import { Value } from 'slate';
 import { getNextCharacter, getPreviousCousin } from './utils/dom';
 import PluginPrism, { setPrismTokens } from './slate-plugins/prism/index';
 import PrismPromql, { FUNCTIONS } from './slate-plugins/prism/promql';
+import BracesPlugin from './slate-plugins/braces';
 import RunnerPlugin from './slate-plugins/runner';
 import { processLabels, RATE_RANGES, cleanText, getCleanSelector } from './utils/prometheus';
 
@@ -110,6 +111,7 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
     super(props, context);
 
     this.plugins = [
+      BracesPlugin(),
       RunnerPlugin({ handler: props.onPressEnter }),
       PluginPrism({ definition: PrismPromql, language: PRISM_LANGUAGE }),
     ];

+ 1 - 2
public/app/containers/Explore/QueryField.tsx

@@ -5,7 +5,6 @@ import { Block, Change, Document, Text, Value } from 'slate';
 import { Editor } from 'slate-react';
 import Plain from 'slate-plain-serializer';
 
-import BracesPlugin from './slate-plugins/braces';
 import ClearPlugin from './slate-plugins/clear';
 import NewlinePlugin from './slate-plugins/newline';
 
@@ -149,7 +148,7 @@ class QueryField extends React.Component<TypeaheadFieldProps, TypeaheadFieldStat
     super(props, context);
 
     // Base plugins
-    this.plugins = [BracesPlugin(), ClearPlugin(), NewlinePlugin(), ...props.additionalPlugins];
+    this.plugins = [ClearPlugin(), NewlinePlugin(), ...props.additionalPlugins];
 
     this.state = {
       suggestions: [],

+ 9 - 0
public/app/containers/Explore/slate-plugins/braces.jest.ts

@@ -44,4 +44,13 @@ describe('braces', () => {
     handler(event, change);
     expect(Plain.serialize(change.value)).toEqual('(foo) (bar)() ugh');
   });
+
+  it('adds closing braces outside a selector', () => {
+    const change = Plain.deserialize('sumrate(metric{namespace="dev", cluster="c1"}[2m])').change();
+    let event;
+    change.move(3);
+    event = new window.KeyboardEvent('keydown', { key: '(' });
+    handler(event, change);
+    expect(Plain.serialize(change.value)).toEqual('sum(rate(metric{namespace="dev", cluster="c1"}[2m]))');
+  });
 });

+ 4 - 2
public/app/containers/Explore/slate-plugins/braces.ts

@@ -4,6 +4,8 @@ const BRACES = {
   '(': ')',
 };
 
+const NON_SELECTOR_SPACE_REGEXP = / (?![^}]+})/;
+
 export default function BracesPlugin() {
   return {
     onKeyDown(event, change) {
@@ -28,8 +30,8 @@ export default function BracesPlugin() {
           event.preventDefault();
           const text = value.anchorText.text;
           const offset = value.anchorOffset;
-          const space = text.indexOf(' ', offset);
-          const length = space > 0 ? space : text.length;
+          const delimiterIndex = text.slice(offset).search(NON_SELECTOR_SPACE_REGEXP);
+          const length = delimiterIndex > -1 ? delimiterIndex + offset : text.length;
           const forward = length - offset;
           // Insert matching braces
           change