fix: compiling issues for codemirror-lang-graphql
This commit is contained in:
@@ -307,9 +307,7 @@ import { makeGQLHistoryEntry, addGraphqlHistoryEntry } from "~/newstore/history"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { getCurrentStrategyID } from "~/helpers/network"
|
||||
import { makeGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { useNewCodemirror as useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import "codemirror/mode/javascript/javascript"
|
||||
import "~/helpers/editor/modes/graphql"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import jsonLinter from "~/helpers/editor/linting/json"
|
||||
import { createGQLQueryLinter } from "~/helpers/editor/linting/gqlQuery"
|
||||
import queryCompleter from "~/helpers/editor/completion/gqlQuery"
|
||||
|
||||
@@ -252,7 +252,6 @@ import {
|
||||
setGQLURL,
|
||||
setGQLVariables,
|
||||
} from "~/newstore/GQLSession"
|
||||
import "~/helpers/editor/modes/graphql"
|
||||
|
||||
function isTextFoundInGraphqlFieldObject(
|
||||
text: string,
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
makeRESTRequest,
|
||||
} from "~/helpers/types/HoppRESTRequest"
|
||||
import { setRESTRequest } from "~/newstore/RESTSession"
|
||||
import "codemirror/mode/shell/shell"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
|
||||
@@ -175,7 +175,6 @@ import {
|
||||
deleteAllRESTParams,
|
||||
setRESTParams,
|
||||
} from "~/newstore/RESTSession"
|
||||
import "codemirror/mode/yaml/yaml"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
|
||||
@@ -85,8 +85,7 @@
|
||||
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { usePreRequestScript } from "~/newstore/RESTSession"
|
||||
import snippets from "~/helpers/preRequestScriptSnippets"
|
||||
import "codemirror/mode/javascript/javascript"
|
||||
import { useNewCodemirror as useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import linter from "~/helpers/editor/linting/preRequest"
|
||||
import completer from "~/helpers/editor/completion/preRequest"
|
||||
|
||||
|
||||
@@ -72,11 +72,6 @@ import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { getEditorLangForMimeType } from "~/helpers/editorutils"
|
||||
import { pluckRef } from "~/helpers/utils/composables"
|
||||
import { useRESTRequestBody } from "~/newstore/RESTSession"
|
||||
import "codemirror/mode/yaml/yaml"
|
||||
import "codemirror/mode/xml/xml"
|
||||
import "codemirror/mode/css/css"
|
||||
import "codemirror/mode/htmlmixed/htmlmixed"
|
||||
import "codemirror/mode/javascript/javascript"
|
||||
|
||||
const props = defineProps<{
|
||||
contentType: string
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { useTestScript } from "~/newstore/RESTSession"
|
||||
import testSnippets from "~/helpers/testSnippets"
|
||||
import "codemirror/mode/javascript/javascript"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import linter from "~/helpers/editor/linting/testScript"
|
||||
import completer from "~/helpers/editor/completion/testScript"
|
||||
|
||||
@@ -66,10 +66,6 @@
|
||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import "codemirror/mode/xml/xml"
|
||||
import "codemirror/mode/javascript/javascript"
|
||||
import "codemirror/mode/css/css"
|
||||
import "codemirror/mode/htmlmixed/htmlmixed"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -145,9 +145,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||
import { useNewCodemirror as useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import "codemirror/mode/javascript/javascript"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
import jsonParse, { JSONObjectMember, JSONValue } from "~/helpers/jsonParse"
|
||||
import { getJSONOutlineAtPos } from "~/helpers/newOutline"
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import "codemirror/mode/xml/xml"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -1,30 +1,3 @@
|
||||
import CodeMirror from "codemirror"
|
||||
|
||||
import "codemirror-theme-github/theme/github.css"
|
||||
import "codemirror/theme/base16-dark.css"
|
||||
import "codemirror/theme/tomorrow-night-bright.css"
|
||||
|
||||
import "codemirror/lib/codemirror.css"
|
||||
import "codemirror/addon/lint/lint.css"
|
||||
import "codemirror/addon/dialog/dialog.css"
|
||||
import "codemirror/addon/hint/show-hint.css"
|
||||
|
||||
import "codemirror/addon/fold/foldgutter.css"
|
||||
import "codemirror/addon/fold/foldgutter"
|
||||
import "codemirror/addon/fold/brace-fold"
|
||||
import "codemirror/addon/fold/comment-fold"
|
||||
import "codemirror/addon/fold/indent-fold"
|
||||
import "codemirror/addon/display/autorefresh"
|
||||
import "codemirror/addon/lint/lint"
|
||||
import "codemirror/addon/hint/show-hint"
|
||||
import "codemirror/addon/display/placeholder"
|
||||
import "codemirror/addon/edit/closebrackets"
|
||||
import "codemirror/addon/search/search"
|
||||
import "codemirror/addon/search/searchcursor"
|
||||
import "codemirror/addon/search/jump-to-line"
|
||||
import "codemirror/addon/dialog/dialog"
|
||||
import "codemirror/addon/selection/active-line"
|
||||
|
||||
import { keymap, EditorView, ViewPlugin, ViewUpdate } from "@codemirror/view"
|
||||
import {
|
||||
Extension,
|
||||
@@ -39,7 +12,7 @@ import { basicSetup } from "@codemirror/basic-setup"
|
||||
import { Completion, autocompletion } from "@codemirror/autocomplete"
|
||||
import { linter } from "@codemirror/lint"
|
||||
|
||||
import { watch, onMounted, ref, Ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { watch, onMounted, ref, Ref } from "@nuxtjs/composition-api"
|
||||
|
||||
import { javascriptLanguage } from "@codemirror/lang-javascript"
|
||||
import { jsonLanguage } from "@codemirror/lang-json"
|
||||
@@ -52,191 +25,19 @@ import { Completer } from "./completion"
|
||||
import { LinterDefinition } from "./linting/linter"
|
||||
import { baseTheme, baseHighlightStyle } from "./themes/baseTheme"
|
||||
|
||||
type ExtendedEditorConfig = {
|
||||
mode: string
|
||||
placeholder: string
|
||||
readOnly: boolean
|
||||
lineWrapping: boolean
|
||||
}
|
||||
|
||||
type CodeMirrorOptions = {
|
||||
extendedEditorConfig: Omit<CodeMirror.EditorConfiguration, "value">
|
||||
extendedEditorConfig: Partial<ExtendedEditorConfig>
|
||||
linter: LinterDefinition | null
|
||||
completer: Completer | null
|
||||
}
|
||||
|
||||
const DEFAULT_EDITOR_CONFIG: CodeMirror.EditorConfiguration = {
|
||||
autoRefresh: true,
|
||||
lineNumbers: true,
|
||||
foldGutter: true,
|
||||
autoCloseBrackets: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
extraKeys: {
|
||||
"Ctrl-Space": "autocomplete",
|
||||
},
|
||||
viewportMargin: Infinity,
|
||||
styleActiveLine: true,
|
||||
}
|
||||
|
||||
/**
|
||||
* A Vue composable to mount and use Codemirror
|
||||
*
|
||||
* NOTE: Make sure to import all the necessary Codemirror modules,
|
||||
* as this function doesn't import any other than the core
|
||||
* @param el Reference to the dom node to attach to
|
||||
* @param value Reference to value to read/write to
|
||||
* @param options CodeMirror options to pass
|
||||
*/
|
||||
export function useCodemirror(
|
||||
el: Ref<any | null>,
|
||||
value: Ref<string>,
|
||||
options: CodeMirrorOptions
|
||||
): { cm: Ref<CodeMirror.Position | null>; cursor: Ref<CodeMirror.Position> } {
|
||||
const { $colorMode } = useContext() as any
|
||||
|
||||
const cm = ref<CodeMirror.Editor | null>(null)
|
||||
const cursor = ref<CodeMirror.Position>({ line: 0, ch: 0 })
|
||||
|
||||
const updateEditorConfig = () => {
|
||||
Object.keys(options.extendedEditorConfig).forEach((key) => {
|
||||
// Only update options which need updating
|
||||
if (
|
||||
cm.value &&
|
||||
cm.value?.getOption(key as any) !==
|
||||
(options.extendedEditorConfig as any)[key]
|
||||
) {
|
||||
cm.value?.setOption(
|
||||
key as any,
|
||||
(options.extendedEditorConfig as any)[key]
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const updateLinterConfig = () => {
|
||||
if (options.linter) {
|
||||
cm.value?.setOption("lint", options.linter)
|
||||
}
|
||||
}
|
||||
|
||||
const updateCompleterConfig = () => {
|
||||
if (options.completer) {
|
||||
cm.value?.setOption("hintOptions", {
|
||||
completeSingle: false,
|
||||
hint: async (editor: CodeMirror.Editor) => {
|
||||
const pos = editor.getCursor()
|
||||
const text = editor.getValue()
|
||||
|
||||
const token = editor.getTokenAt(pos)
|
||||
// It's not a word token, so, just increment to skip to next
|
||||
if (token.string.toUpperCase() === token.string.toLowerCase())
|
||||
token.start += 1
|
||||
|
||||
const result = await options.completer!(text, pos)
|
||||
|
||||
if (!result) return null
|
||||
|
||||
return <CodeMirror.Hints>{
|
||||
from: { line: pos.line, ch: token.start },
|
||||
to: { line: pos.line, ch: token.end },
|
||||
list: result.completions
|
||||
.sort((a, b) => a.score - b.score)
|
||||
.map((x) => x.text),
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const initialize = () => {
|
||||
if (!el.value) return
|
||||
|
||||
cm.value = CodeMirror(el.value!, DEFAULT_EDITOR_CONFIG)
|
||||
|
||||
cm.value.setValue(value.value)
|
||||
|
||||
setTheme()
|
||||
updateEditorConfig()
|
||||
updateLinterConfig()
|
||||
updateCompleterConfig()
|
||||
|
||||
cm.value.on("change", (instance) => {
|
||||
// External update propagation (via watchers) should be ignored
|
||||
if (instance.getValue() !== value.value) {
|
||||
value.value = instance.getValue()
|
||||
}
|
||||
})
|
||||
|
||||
cm.value.on("cursorActivity", (instance) => {
|
||||
cursor.value = instance.getCursor()
|
||||
})
|
||||
}
|
||||
|
||||
// Boot-up CodeMirror, set the value and listeners
|
||||
onMounted(() => {
|
||||
initialize()
|
||||
})
|
||||
|
||||
// Reinitialize if the target ref updates
|
||||
watch(el, () => {
|
||||
if (cm.value) {
|
||||
const parent = cm.value.getWrapperElement()
|
||||
parent.remove()
|
||||
cm.value = null
|
||||
}
|
||||
initialize()
|
||||
})
|
||||
|
||||
const setTheme = () => {
|
||||
if (cm.value) {
|
||||
cm.value?.setOption("theme", getThemeName($colorMode.value))
|
||||
}
|
||||
}
|
||||
|
||||
const getThemeName = (mode: string) => {
|
||||
switch (mode) {
|
||||
case "system":
|
||||
return "default"
|
||||
case "light":
|
||||
return "github"
|
||||
case "dark":
|
||||
return "base16-dark"
|
||||
case "black":
|
||||
return "tomorrow-night-bright"
|
||||
default:
|
||||
return "default"
|
||||
}
|
||||
}
|
||||
|
||||
// If the editor properties are reactive, watch for updates
|
||||
watch(() => options.extendedEditorConfig, updateEditorConfig, {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
})
|
||||
watch(() => options.linter, updateLinterConfig, { immediate: true })
|
||||
watch(() => options.completer, updateCompleterConfig, { immediate: true })
|
||||
|
||||
// Watch value updates
|
||||
watch(value, (newVal) => {
|
||||
// Check if we are mounted
|
||||
if (cm.value) {
|
||||
// Don't do anything on internal updates
|
||||
if (cm.value.getValue() !== newVal) {
|
||||
cm.value.setValue(newVal)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Push cursor updates
|
||||
watch(cursor, (value) => {
|
||||
if (value !== cm.value?.getCursor()) {
|
||||
cm.value?.focus()
|
||||
cm.value?.setCursor(value)
|
||||
}
|
||||
})
|
||||
|
||||
// Watch color mode updates and update theme
|
||||
watch(() => $colorMode.value, setTheme)
|
||||
|
||||
return {
|
||||
cm,
|
||||
cursor,
|
||||
}
|
||||
}
|
||||
|
||||
const hoppCompleterExt = (completer: Completer): Extension => {
|
||||
return autocompletion({
|
||||
override: [
|
||||
@@ -324,7 +125,7 @@ const getEditorLanguage = (
|
||||
O.getOrElseW(() => [])
|
||||
)
|
||||
|
||||
export function useNewCodemirror(
|
||||
export function useCodemirror(
|
||||
el: Ref<any | null>,
|
||||
value: Ref<string>,
|
||||
options: CodeMirrorOptions
|
||||
@@ -380,7 +181,7 @@ export function useNewCodemirror(
|
||||
EditorState.changeFilter.of(() => !options.extendedEditorConfig.readOnly),
|
||||
language.of(
|
||||
getEditorLanguage(
|
||||
(options.extendedEditorConfig.mode as any) ?? "",
|
||||
options.extendedEditorConfig.mode ?? "",
|
||||
options.linter ?? undefined,
|
||||
options.completer ?? undefined
|
||||
)
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 GraphQL Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
import CodeMirror from "codemirror"
|
||||
import {
|
||||
LexRules,
|
||||
ParseRules,
|
||||
isIgnored,
|
||||
onlineParser,
|
||||
State,
|
||||
} from "graphql-language-service-parser"
|
||||
|
||||
/**
|
||||
* The GraphQL mode is defined as a tokenizer along with a list of rules, each
|
||||
* of which is either a function or an array.
|
||||
*
|
||||
* * Function: Provided a token and the stream, returns an expected next step.
|
||||
* * Array: A list of steps to take in order.
|
||||
*
|
||||
* A step is either another rule, or a terminal description of a token. If it
|
||||
* is a rule, that rule is pushed onto the stack and the parsing continues from
|
||||
* that point.
|
||||
*
|
||||
* If it is a terminal description, the token is checked against it using a
|
||||
* `match` function. If the match is successful, the token is colored and the
|
||||
* rule is stepped forward. If the match is unsuccessful, the remainder of the
|
||||
* rule is skipped and the previous rule is advanced.
|
||||
*
|
||||
* This parsing algorithm allows for incremental online parsing within various
|
||||
* levels of the syntax tree and results in a structured `state` linked-list
|
||||
* which contains the relevant information to produce valuable typeaheads.
|
||||
*/
|
||||
CodeMirror.defineMode("graphql", (config) => {
|
||||
const parser = onlineParser({
|
||||
eatWhitespace: (stream) => stream.eatWhile(isIgnored),
|
||||
lexRules: LexRules,
|
||||
parseRules: ParseRules,
|
||||
editorConfig: { tabSize: 2 },
|
||||
})
|
||||
|
||||
return {
|
||||
config,
|
||||
startState: parser.startState,
|
||||
token: parser.token as unknown as CodeMirror.Mode<any>["token"], // TODO: Check if the types are indeed compatible
|
||||
indent,
|
||||
electricInput: /^\s*[})\]]/,
|
||||
fold: "brace",
|
||||
lineComment: "#",
|
||||
closeBrackets: {
|
||||
pairs: '()[]{}""',
|
||||
explode: "()[]{}",
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// Seems the electricInput type in @types/codemirror is wrong (i.e it is written as electricinput instead of electricInput)
|
||||
function indent(
|
||||
this: CodeMirror.Mode<any> & {
|
||||
electricInput?: RegExp
|
||||
config?: CodeMirror.EditorConfiguration
|
||||
},
|
||||
state: State,
|
||||
textAfter: string
|
||||
) {
|
||||
const levels = state.levels
|
||||
// If there is no stack of levels, use the current level.
|
||||
// Otherwise, use the top level, pre-emptively dedenting for close braces.
|
||||
const level =
|
||||
!levels || levels.length === 0
|
||||
? state.indentLevel
|
||||
: levels[levels.length - 1] -
|
||||
(this.electricInput?.test(textAfter) ? 1 : 0)
|
||||
return (level || 0) * (this.config?.indentUnit || 0)
|
||||
}
|
||||
@@ -60,8 +60,6 @@
|
||||
"acorn": "^8.5.0",
|
||||
"acorn-walk": "^8.2.0",
|
||||
"axios": "^0.24.0",
|
||||
"codemirror": "^5.63.3",
|
||||
"codemirror-theme-github": "^1.0.0",
|
||||
"core-js": "^3.19.1",
|
||||
"esprima": "^4.0.1",
|
||||
"firebase": "^9.2.0",
|
||||
|
||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -99,8 +99,6 @@ importers:
|
||||
axios: ^0.24.0
|
||||
babel-core: ^7.0.0-bridge.0
|
||||
babel-jest: ^27.3.1
|
||||
codemirror: ^5.63.3
|
||||
codemirror-theme-github: ^1.0.0
|
||||
core-js: ^3.19.1
|
||||
eslint: ^8.1.0
|
||||
eslint-config-prettier: ^8.3.0
|
||||
@@ -186,8 +184,6 @@ importers:
|
||||
acorn: 8.5.0
|
||||
acorn-walk: 8.2.0
|
||||
axios: 0.24.0
|
||||
codemirror: 5.63.3
|
||||
codemirror-theme-github: 1.0.0
|
||||
core-js: 3.19.1
|
||||
esprima: 4.0.1
|
||||
firebase: 9.2.0
|
||||
@@ -7915,14 +7911,6 @@ packages:
|
||||
resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/codemirror-theme-github/1.0.0:
|
||||
resolution: {integrity: sha512-suheFec2wlI4klyqn61MOFXjjrKPZiNY7d2py0OvTd5Z+7AsNxoGKDaS/HI59y7EAG1SkkXW/JQ1Rt2gDMxHfA==}
|
||||
dev: false
|
||||
|
||||
/codemirror/5.63.3:
|
||||
resolution: {integrity: sha512-1C+LELr+5grgJYqwZKqxrcbPsHFHapVaVAloBsFBASbpLnQqLw1U8yXJ3gT5D+rhxIiSpo+kTqN+hQ+9ialIXw==}
|
||||
dev: false
|
||||
|
||||
/collect-v8-coverage/1.0.1:
|
||||
resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==}
|
||||
dev: true
|
||||
|
||||
Reference in New Issue
Block a user