onUrlChange(newValue)}
+ collection={collection}
/>
diff --git a/packages/bruno-app/src/components/SingleLineEditor/StyledWrapper.js b/packages/bruno-app/src/components/SingleLineEditor/StyledWrapper.js
new file mode 100644
index 000000000..fc84d7f51
--- /dev/null
+++ b/packages/bruno-app/src/components/SingleLineEditor/StyledWrapper.js
@@ -0,0 +1,33 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ width: 100%;
+ height: 30px;
+ overflow-y: hidden;
+
+ .CodeMirror {
+ background: transparent;
+ height: 30px;
+ font-size: 14px;
+ line-height: 30px;
+
+ .CodeMirror-lines {
+ padding: 0;
+ }
+
+ .CodeMirror-cursor {
+ height: 20px !important;
+ margin-top: 5px !important;
+ }
+
+ pre {
+ font-family: Inter, sans-serif !important;
+ }
+ }
+
+ .cm-variable-valid{color: green}
+ .cm-variable-invalid{color: red}
+ .cm-matchhighlight {background-color: yellow}
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/SingleLineEditor/index.js b/packages/bruno-app/src/components/SingleLineEditor/index.js
new file mode 100644
index 000000000..495519cd3
--- /dev/null
+++ b/packages/bruno-app/src/components/SingleLineEditor/index.js
@@ -0,0 +1,103 @@
+import React, { Component } from 'react';
+import CodeMirror from 'codemirror';
+import each from 'lodash/each';
+import isEqual from 'lodash/isEqual';
+import { findEnvironmentInCollection } from 'utils/collections';
+import StyledWrapper from './StyledWrapper';
+
+class SingleLineEditor extends Component {
+ constructor(props) {
+ super(props);
+ this.editorRef = React.createRef();
+ this.variables = {};
+ }
+ componentDidMount() {
+ // Initialize CodeMirror as a single line editor
+ this.editor = CodeMirror(this.editorRef.current, {
+ lineWrapping: false,
+ lineNumbers: false,
+ autofocus: true,
+ mode: "brunovariables",
+ extraKeys: {
+ "Enter": () => {},
+ "Ctrl-Enter": () => {},
+ "Cmd-Enter": () => {},
+ "Alt-Enter": () => {},
+ "Shift-Enter": () => {}
+ },
+ });
+ this.editor.setValue(this.props.value)
+
+ this.editor.on('change', (cm) => {
+ this.props.onChange(cm.getValue());
+ });
+ this.addOverlay();
+ }
+
+ componentDidUpdate(prevProps) {
+ let variables = this.getEnvironmentVariables();
+ if (!isEqual(variables, this.variables)) {
+ this.addOverlay();
+ }
+ }
+
+ componentWillUnmount() {
+ this.editor.getWrapperElement().remove();
+ }
+
+ getEnvironmentVariables = () => {
+ let variables = {};
+ const collection = this.props.collection;
+ if (collection) {
+ const environment = findEnvironmentInCollection(collection, collection.activeEnvironmentUid);
+ if (environment) {
+ each(environment.variables, (variable) => {
+ if(variable.name && variable.value && variable.enabled) {
+ variables[variable.name] = variable.value;
+ }
+ });
+ }
+ }
+
+ return variables;
+ }
+
+ addOverlay = () => {
+ let variables = this.getEnvironmentVariables();
+ this.variables = variables;
+
+ CodeMirror.defineMode("brunovariables", function(config, parserConfig) {
+ let variablesOverlay = {
+ token: function(stream, state) {
+ if (stream.match("{{", true)) {
+ let ch;
+ let word = "";
+ while ((ch = stream.next()) != null) {
+ if (ch == "}" && stream.next() == "}") {
+ stream.eat("}");
+ if (word in variables) {
+ return "variable-valid";
+ } else {
+ return "variable-invalid";
+ }
+ }
+ word += ch;
+ }
+ }
+ while (stream.next() != null && !stream.match("{{", false)) {}
+ return null;
+ }
+ };
+ return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/plain"), variablesOverlay);
+ });
+
+ this.editor.setOption('mode', 'brunovariables');
+ }
+
+ render() {
+ return (
+
+ );
+ }
+}
+export default SingleLineEditor;
diff --git a/packages/bruno-app/src/pageComponents/Index/index.js b/packages/bruno-app/src/pageComponents/Index/index.js
index b96341f4f..015cfadc8 100644
--- a/packages/bruno-app/src/pageComponents/Index/index.js
+++ b/packages/bruno-app/src/pageComponents/Index/index.js
@@ -6,7 +6,6 @@ import RequestTabPanel from 'components/RequestTabPanel';
import Sidebar from 'components/Sidebar';
import { useSelector } from 'react-redux';
import StyledWrapper from './StyledWrapper';
-import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/material.css';
import 'codemirror/theme/monokai.css';