Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to CodeMirror 6 #2058

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Upgrade to CodeMirror 6 #2058

wants to merge 13 commits into from

Conversation

grolu
Copy link
Contributor

@grolu grolu commented Aug 30, 2024

What this PR does / why we need it:
Upgrade CodeMirror 5 to CodeMirror 6

Which issue(s) this PR fixes:
Fixes #1892

Special notes for your reviewer:

Release note:

Upgraded the code editor from CodeMirror 5 to CodeMirror 6 to enhance performance, modernize the interface, and improve extensibility

 - upgrade to CM6
 - migrated editor line highlighter composable
TODO
 - code completion
 - test migration
@gardener-robot gardener-robot added needs/review Needs review size/xl Size of pull request is huge (see gardener-robot robot/bots/size.py) needs/second-opinion Needs second review by someone else labels Aug 30, 2024
@gardener-robot-ci-3 gardener-robot-ci-3 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Aug 30, 2024
@gardener-robot-ci-2 gardener-robot-ci-2 added needs/ok-to-test Needs approval for testing (check PR in detail before setting this label because PR is run on CI/CD) and removed reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) labels Aug 30, 2024
@gardener-robot gardener-robot added the needs/rebase Needs git rebase label Sep 6, 2024
@gardener-robot
Copy link

@grolu You need rebase this pull request with latest master branch. Please check.

@gardener-robot-ci-1 gardener-robot-ci-1 added reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) and removed reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) labels Sep 6, 2024
@gardener-robot-ci-2 gardener-robot-ci-2 added reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) and removed reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) labels Sep 9, 2024
@gardener-robot-ci-3 gardener-robot-ci-3 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 10, 2024
@gardener-robot-ci-3 gardener-robot-ci-3 removed the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 10, 2024
- Restructured main scss theme dependant classes
@gardener-robot-ci-1 gardener-robot-ci-1 added reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) and removed reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) labels Sep 16, 2024
Make editor always consume 100% height
Cleaned-up some comments
@gardener-robot-ci-1 gardener-robot-ci-1 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 16, 2024
@grolu grolu marked this pull request as ready for review September 16, 2024 16:26
@grolu grolu changed the title [DRAFT] Enh/upgrade cm 6 Upgrade to CodeMirror 6 Sep 16, 2024
@gardener-robot-ci-3 gardener-robot-ci-3 removed the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 16, 2024
@gardener-robot-ci-1 gardener-robot-ci-1 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 16, 2024
@gardener-robot-ci-3 gardener-robot-ci-3 removed the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 16, 2024
let [startLine, endLine = startLine] = values
const [startLineCurrent, endLineCurrent] = valuesCurrent

if (endLine === startLine && startLine === startLineCurrent && !endLineCurrent) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had similar code in my PR where I introduce the feature to clear the selected line if the current selected line is clicked again, however holger propsed to use ESC-key instead to clear the selection. Clearing with ESC-key currently does not work anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know. The problem here is that I did not find a way to add a key listener to the gutter. It is possible to add a key listener to the editor itself and clear the highlight on escape. However, the editor needs to be focused, so you would need to click inside the editor to make this work.
So I checked how Github does the highlighting and it does not clear the selection on escape, it works exactly like I implemented it now.

frontend/src/composables/useShootEditor/helper.js Outdated Show resolved Hide resolved
label: string,
displayLabel: text,
detail: typeText,
type: 'keyword', // TODO check weather we want to show diffrent icons
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a list of icons / types to choose from?

Copy link
Contributor Author

@grolu grolu Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://codemirror.net/docs/ref/#autocomplete.Completion.type
It is also possible to omit the type property so that no icon is rendered. AFAIK it is not possible to provide a custom render function for the completion box (like we did for CM5), only for the content that is shown next to it, the info (details) it is possible to provide a render function

Copy link
Member

@petersutter petersutter Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's leave it like it is for now (and remove the TODO), I do not have a better suggestion


return { lineTokens, lineString }
return token
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not part of this PR, but the hasOnlyTypeOrTypeAndFormatProperties function needs an overhaul

    const hasOnlyTypeOrTypeAndFormatProperties = value => {
      if (value.every(item => {
        return (Object.keys(item).length === 1 && item.type) ||
        (Object.keys(item).length === 2 && item.type && item.format)
      })) {
        return true
      }
      return false
    }

How about refactoring it to either

const hasValidKeys = value => {
  return value.every(item => {
    const keys = Object.keys(item)
    const hasType = 'type' in item
    const hasFormat = 'format' in item

    return (keys.length === 1 && hasType) || (keys.length === 2 && hasType && hasFormat)
  })
}

or

const hasValidKeys = value => {
  const validKeyCombinations = [
    ['type'],
    ['type', 'format']
  ]

  return value.every(item => {
    const keys = Object.keys(item)
    return validKeyCombinations.some(combination =>
      combination.length === keys.length && combination.every(key => keys.includes(key))
    )
  })
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you want to change it in this PR anyway?

frontend/src/composables/useShootEditor/index.js Outdated Show resolved Hide resolved
frontend/src/composables/useShootEditor/index.js Outdated Show resolved Hide resolved
# Conflicts:
#	.pnp.cjs
#	.yarn/cache/codemirror-npm-5.65.18-debbbac10b-806e00c708.zip
#	frontend/src/composables/useShootEditor/helper.js
#	frontend/src/composables/useShootEditor/index.js
#	yarn.lock
@gardener-robot-ci-1 gardener-robot-ci-1 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 24, 2024
@gardener-robot-ci-2 gardener-robot-ci-2 removed the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 24, 2024
@gardener-robot-ci-1 gardener-robot-ci-1 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 24, 2024
@gardener-robot-ci-2 gardener-robot-ci-2 removed the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Sep 24, 2024
@grolu grolu added the area/ipcei IPCEI (Important Project of Common European Interest) label Oct 14, 2024
@grolu grolu mentioned this pull request Oct 14, 2024
48 tasks
Copy link
Member

@petersutter petersutter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor things, otherwise /lgtm

@@ -83,9 +90,9 @@ export class EditorCompletions {
end,
string,
}
if (token.start <= pos.ch && pos.ch <= token.end) {
if (token.start <= lineChar && lineChar <= token.end) {
// Ensure that mouse pointer is on propety and not somewhere else on this line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Ensure that mouse pointer is on propety and not somewhere else on this line
// Ensure that mouse pointer is on property and not somewhere else on this line

// Ensure that mouse pointer is on propety and not somewhere else on this line
const completions = this._getYamlCompletions(token, pos, cm, true)
const completions = this._getYamlCompletions(token, { ch: lineChar, line }, cmView, true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract to variable for better readability

Suggested change
const completions = this._getYamlCompletions(token, { ch: lineChar, line }, cmView, true)
const cur = { ch: lineChar, line }
const completions = this._getYamlCompletions(token, cur, cmView, true)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is cur? Is it current? Or is it cursor? Use easy understable names.


return { lineTokens, lineString }
return token
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you want to change it in this PR anyway?

<div v-bind="slotProps.props">
<g-action-button
size="x-small"
:icon="renderWhitespaces ? 'mdi-grid' : 'mdi-grid-off'"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These icons are not intuitive to me. I would use these ones. We should use Hide and Show (not Render). And I think we can delete the tab icon in assets?

Screenshot 2024-10-15 at 17 22 40
Screenshot 2024-10-15 at 17 22 19

whitespace-eye
whitespace-eye-off

          <v-tooltip location="top">
            <template #activator="slotProps">
              <div v-bind="slotProps.props">
                <v-btn
                  variant="text"
                  size="x-small"
                  flat
                  icon
                  color="black"
                  @click="renderWhitespaces = !renderWhitespaces"
                >
                  <span v-html="renderWhitespaces ? whitespaceEye : whitespaceEyeOff" style="width: 18px; height: 18px"/>
                </v-btn>
              </div>
            </template>
            <span>{{ renderWhitespaces ? 'Hide' : 'Render' }} whitespaces</span>
          </v-tooltip>

}
return highlights
},
provide: f => EditorView.decorations.from(f),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
provide: f => EditorView.decorations.from(f),
provide (f) {
return EditorView.decorations.from(f)
},

export function useEditorWhitespace () {
const matchDecorator = new MatchDecorator({
regexp: /[ \t]/g,
decoration: match => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
decoration: match => {
decoration (match) {

return Decoration.mark({
attributes: { class: 'g-cm-highlightedTab' },
})
} else if (match[0] === ' ') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if (match[0] === ' ') {
}
if (match[0] === ' ') {

// Ensure that mouse pointer is on propety and not somewhere else on this line
const completions = this._getYamlCompletions(token, pos, cm, true)
const completions = this._getYamlCompletions(token, { ch: lineChar, line }, cmView, true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is cur? Is it current? Or is it cursor? Use easy understable names.

return completionArray
}

// get token at cursor position in editor with yaml content
_getYamlToken (cm, cur) {
_getYamlToken (cmView, cur) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods starting with underscore should be private and the underscore removed.

Comment on lines +132 to +190
.v-theme-- {
@mixin alternate-row-background($background-color) {
.alternate-row-background > div:nth-of-type(even) {
background-color: $background-color;
}
}

@mixin g-highlighted($background-color, $border-color) {
.g-highlighted {
position: relative;
background-color: $background-color;
/* Left border */
box-shadow: inset 1px 0 0 0 $border-color;

/* Top border */
&.g-highlighted--top::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px; /* Adjust border thickness as needed */
background-color: $border-color;
}

/* Bottom border */
&.g-highlighted--bottom::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px; /* Adjust border thickness as needed */
background-color: $border-color;
}
}
}

@mixin g-cm-highlighted-whitespace($whitespace-color) {
$whitespace-color-encoded: #{'%23' + str-slice(inspect($whitespace-color), 2)};

.g-cm-highlightedSpace {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="6"><circle cx="3" cy="3" r="1" fill="#{$whitespace-color-encoded}" /></svg>');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}

.g-cm-highlightedTab {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M0 3 L10 3" stroke="#{$whitespace-color-encoded}" stroke-width="1" /></svg>');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}

.g-cm-newline-marker {
color: $whitespace-color;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.v-theme-- {
@mixin alternate-row-background($background-color) {
.alternate-row-background > div:nth-of-type(even) {
background-color: $background-color;
}
}
@mixin g-highlighted($background-color, $border-color) {
.g-highlighted {
position: relative;
background-color: $background-color;
/* Left border */
box-shadow: inset 1px 0 0 0 $border-color;
/* Top border */
&.g-highlighted--top::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px; /* Adjust border thickness as needed */
background-color: $border-color;
}
/* Bottom border */
&.g-highlighted--bottom::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px; /* Adjust border thickness as needed */
background-color: $border-color;
}
}
}
@mixin g-cm-highlighted-whitespace($whitespace-color) {
$whitespace-color-encoded: #{'%23' + str-slice(inspect($whitespace-color), 2)};
.g-cm-highlightedSpace {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="6"><circle cx="3" cy="3" r="1" fill="#{$whitespace-color-encoded}" /></svg>');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.g-cm-highlightedTab {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M0 3 L10 3" stroke="#{$whitespace-color-encoded}" stroke-width="1" /></svg>');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.g-cm-newline-marker {
color: $whitespace-color;
}
}
@mixin alternate-row-background($background-color) {
.alternate-row-background>div:nth-of-type(even) {
background-color: $background-color;
}
}
@mixin g-highlighted($background-color, $border-color) {
.g-highlighted {
position: relative;
background-color: $background-color;
/* Left border */
box-shadow: inset 1px 0 0 0 $border-color;
/* Top border */
&.g-highlighted--top::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
/* Adjust border thickness as needed */
background-color: $border-color;
}
/* Bottom border */
&.g-highlighted--bottom::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
/* Adjust border thickness as needed */
background-color: $border-color;
}
}
}
@mixin g-cm-highlighted-whitespace($whitespace-color) {
$whitespace-color-encoded: #{'%23' + str-slice(inspect($whitespace-color), 2)};
.g-cm-highlightedSpace {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="6"><circle cx="3" cy="3" r="1" fill="#{$whitespace-color-encoded}" /></svg>');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.g-cm-highlightedTab {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M0 3 L10 3" stroke="#{$whitespace-color-encoded}" stroke-width="1" /></svg>');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.g-cm-newline-marker {
color: $whitespace-color;
}
}
.v-theme-- {

}
return next()
})
onBeforeRouteUpdate(async (to, from, next) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this change. I think this has nothing to do with cm6. Isnt't this part of an ohter PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ipcei IPCEI (Important Project of Common European Interest) needs/ok-to-test Needs approval for testing (check PR in detail before setting this label because PR is run on CI/CD) needs/rebase Needs git rebase needs/review Needs review needs/second-opinion Needs second review by someone else size/xl Size of pull request is huge (see gardener-robot robot/bots/size.py)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Upgrade to Codemirror v6
7 participants