diff --git a/data/schema/language.xsd b/data/schema/language.xsd
--- a/data/schema/language.xsd
+++ b/data/schema/language.xsd
@@ -279,17 +279,23 @@
-->
-
-
-
+
+
+
+
+
+
diff --git a/data/syntax/scss.xml b/data/syntax/scss.xml
--- a/data/syntax/scss.xml
+++ b/data/syntax/scss.xml
@@ -38,616 +38,7 @@
-
- - align-content
- - align-items
- - alignment-baseline
- - align-self
- - all
- - animation
- - animation-delay
- - animation-direction
- - animation-duration
- - animation-fill-mode
- - animation-iteration-count
- - animation-name
- - animation-play-state
- - animation-timing-function
- - appearance
- - azimuth
- - backface-visibility
- - background
- - background-attachment
- - background-blend-mode
- - background-clip
- - background-color
- - background-image
- - background-image-transform
- - background-origin
- - background-position
- - background-repeat
- - background-size
- - baseline-shift
- - block-size
- - block-step
- - block-step-align
- - block-step-insert
- - block-step-round
- - block-step-size
- - bookmark-label
- - bookmark-level
- - bookmark-state
- - border
- - border-block
- - border-block-color
- - border-block-end
- - border-block-end-color
- - border-block-end-style
- - border-block-end-width
- - border-block-start
- - border-block-start-color
- - border-block-start-style
- - border-block-start-width
- - border-block-style
- - border-block-width
- - border-bottom
- - border-bottom-color
- - border-bottom-left-radius
- - border-bottom-right-radius
- - border-bottom-style
- - border-bottom-width
- - border-boundary
- - border-collapse
- - border-color
- - border-image
- - border-image-outset
- - border-image-repeat
- - border-image-slice
- - border-image-source
- - border-image-transform
- - border-image-width
- - border-inline
- - border-inline-color
- - border-inline-end
- - border-inline-end-color
- - border-inline-end-style
- - border-inline-end-width
- - border-inline-start
- - border-inline-start-color
- - border-inline-start-style
- - border-inline-start-width
- - border-inline-style
- - border-inline-width
- - border-left
- - border-left-color
- - border-left-style
- - border-left-width
- - border-radius
- - border-right
- - border-right-color
- - border-right-style
- - border-right-width
- - border-spacing
- - border-style
- - border-top
- - border-top-color
- - border-top-left-radius
- - border-top-right-radius
- - border-top-style
- - border-top-width
- - border-width
- - bottom
- - box-decoration-break
- - box-shadow
- - box-sizing
- - box-snap
- - break-after
- - break-before
- - break-inside
- - caption-side
- - caret
- - caret-color
- - caret-shape
- - clear
- - clip
- - clip-path
- - clip-rule
- - color
- - color-adjust
- - color-interpolation-filters
- - columns
- - column-count
- - column-fill
- - column-gap
- - column-rule
- - column-rule-color
- - column-rule-style
- - column-rule-width
- - column-span
- - column-width
- - contain
- - content
- - continue
- - counter-increment
- - counter-reset
- - counter-set
- - cue
- - cue-after
- - cue-before
- - cursor
- - direction
- - display
- - dominant-baseline
- - elevation
- - empty-cells
- - fill
- - fill-break
- - fill-color
- - fill-image
- - fill-opacity
- - fill-origin
- - fill-position
- - fill-repeat
- - fill-rule
- - fill-size
- - filter
- - flex
- - flex-basis
- - flex-direction
- - flex-flow
- - flex-grow
- - flex-shrink
- - flex-wrap
- - float
- - float-defer
- - float-offset
- - float-reference
- - flood-color
- - flood-opacity
- - flow-from
- - flow-into
- - font
- - font-family
- - font-feature-settings
- - font-kerning
- - font-language-override
- - font-max-size
- - font-min-size
- - font-optical-sizing
- - font-palette
- - font-size
- - font-size-adjust
- - font-stretch
- - font-style
- - font-synthesis
- - font-variant
- - font-variant-alternates
- - font-variant-caps
- - font-variant-east-asian
- - font-variant-emoji
- - font-variant-ligatures
- - font-variant-numeric
- - font-variant-position
- - font-variation-settings
- - font-weight
- - footnote-display
- - footnote-policy
- - gap
- - glyph-orientation-vertical
- - grid
- - grid-area
- - grid-auto-columns
- - grid-auto-flow
- - grid-auto-rows
- - grid-column
- - grid-column-end
- - grid-column-gap
- - grid-column-start
- - grid-gap
- - grid-row
- - grid-row-end
- - grid-row-gap
- - grid-row-start
- - grid-template
- - grid-template-areas
- - grid-template-columns
- - grid-template-rows
- - hanging-punctuation
- - height
- - hyphenate-character
- - hyphenate-limit-chars
- - hyphenate-limit-last
- - hyphenate-limit-lines
- - hyphenate-limit-zone
- - hyphens
- - image-orientation
- - image-rendering
- - image-resolution
- - initial-letter
- - initial-letter-align
- - initial-letter-wrap
- - inline-size
- - inset
- - inset-block
- - inset-block-end
- - inset-block-start
- - inset-inline
- - inset-inline-end
- - inset-inline-start
- - isolation
- - justify-content
- - justify-items
- - justify-self
- - left
- - letter-spacing
- - lighting-color
- - line-break
- - line-grid
- - line-height
- - line-height-step
- - line-snap
- - list-style
- - list-style-image
- - list-style-position
- - list-style-type
- - margin
- - margin-block
- - margin-block-end
- - margin-block-start
- - margin-bottom
- - margin-inline
- - margin-inline-end
- - margin-inline-start
- - margin-left
- - margin-right
- - margin-top
- - marker
- - marker-end
- - marker-knockout-left
- - marker-knockout-right
- - marker-mid
- - marker-pattern
- - marker-segment
- - marker-side
- - marker-start
- - marquee-direction
- - marquee-loop
- - marquee-speed
- - marquee-style
- - mask
- - mask-border
- - mask-border-mode
- - mask-border-outset
- - mask-border-repeat
- - mask-border-slice
- - mask-border-source
- - mask-border-width
- - mask-clip
- - mask-composite
- - mask-image
- - mask-mode
- - mask-origin
- - mask-position
- - mask-repeat
- - mask-size
- - mask-type
- - max-block-size
- - max-height
- - max-inline-size
- - max-lines
- - max-width
- - min-block-size
- - min-height
- - min-inline-size
- - min-width
- - mix-blend-mode
- - nav-up
- - nav-down
- - nav-left
- - nav-right
- - object-fit
- - object-position
- - offset
- - offset-after
- - offset-anchor
- - offset-before
- - offset-distance
- - offset-end
- - offset-path
- - offset-position
- - offset-rotate
- - offset-start
- - opacity
- - order
- - orphans
- - outline
- - outline-color
- - outline-offset
- - outline-style
- - outline-width
- - overflow
- - overflow-style
- - overflow-wrap
- - overflow-x
- - overflow-y
- - padding
- - padding-block
- - padding-block-end
- - padding-block-start
- - padding-bottom
- - padding-inline
- - padding-inline-end
- - padding-inline-start
- - padding-left
- - padding-right
- - padding-top
- - page
- - page-break-after
- - page-break-before
- - page-break-inside
- - pause
- - pause-after
- - pause-before
- - perspective
- - perspective-origin
- - pitch
- - pitch-range
- - place-content
- - place-items
- - place-self
- - play-during
- - pointer-events
- - position
- - quotes
- - region-fragment
- - resize
- - richness
- - right
- - rotation
- - rotation-point
- - row-gap
- - ruby-align
- - ruby-merge
- - ruby-position
- - running
- - scrollbar-gutter
- - shape-image-threshold
- - shape-inside
- - shape-margin
- - shape-outside
- - size
- - speak
- - speak-header
- - speak-numeral
- - speak-punctuation
- - speech-rate
- - stress
- - string-set
- - table-layout
- - tab-size
- - text-align-all
- - text-align
- - text-align-last
- - text-combine-upright
- - text-decoration-color
- - text-decoration
- - text-decoration-line
- - text-decoration-skip
- - text-decoration-skip-ink
- - text-decoration-style
- - text-decoration-width
- - text-emphasis
- - text-emphasis-color
- - text-emphasis-position
- - text-emphasis-skip
- - text-emphasis-style
- - text-indent
- - text-justify
- - text-orientation
- - text-overflow
- - text-shadow
- - text-space-collapse
- - text-space-trim
- - text-spacing
- - text-transform
- - text-underline-offset
- - text-underline-position
- - text-wrap
- - top
- - transform
- - transform-box
- - transform-origin
- - transform-style
- - transition
- - transition-delay
- - transition-duration
- - transition-property
- - transition-timing-function
- - unicode-bidi
- - user-select
- - vertical-align
- - visibility
- - voice-family
- - volume
- - white-space
- - widows
- - width
- - will-change
- - word-break
- - word-spacing
- - word-wrap
- - wrap-after
- - wrap-before
- - wrap-flow
- - wrap-inside
- - wrap-through
- - writing-mode
- - z-index
-
-
- - -moz-animation
- - -moz-animation-delay
- - -moz-animation-direction
- - -moz-animation-duration
- - -moz-animation-fill-mode
- - -moz-animation-iteration-count
- - -moz-animation-name
- - -moz-animation-play-state
- - -moz-animation-timing-function
- - -moz-appearance
- - -moz-background-clip
- - -moz-background-origin
- - -moz-background-size
- - -moz-border-image
- - -moz-border-radius
- - -moz-border-radius-bottomleft
- - -moz-border-radius-bottomright
- - -moz-border-radius-topleft
- - -moz-border-radius-topright
- - -moz-box-align
- - -moz-box-direction
- - -moz-box-flex
- - -moz-box-flex-group
- - -moz-box-ordinal-group
- - -moz-box-orient
- - -moz-box-pack
- - -moz-box-shadow
- - -moz-box-sizing
- - -moz-box
- - -moz-column-count
- - -moz-column-fill
- - -moz-column-gap
- - -moz-column-rule
- - -moz-column-rule-color
- - -moz-column-rule-style
- - -moz-column-rule-width
- - -moz-columns
- - -moz-column-width
- - -moz-hyphens
- - -moz-opacity
- - -moz-outline-style
- - -moz-perspective
- - -moz-resize
- - -moz-text-align-last
- - -moz-text-decoration-color
- - -moz-text-decoration-line
- - -moz-text-decoration-style
- - -moz-transform
- - -moz-transform-origin
- - -moz-transform-style
- - -moz-transition
- - -moz-transition-delay
- - -moz-transition-duration
- - -moz-transition-property
- - -moz-transition-timing-function
- - -moz-user-select
-
-
- - -o-background-size
- - -o-linear-gradient
- - -o-text-overflow
- - -o-transition
- - -o-transform-origin
-
-
- - konq_bgpos_x
- - konq_bgpos_y
- - -khtml-background-size
- - -khtml-border-top-left-radius
- - -khtml-border-top-right-radius
- - -khtml-border-bottom-left-radius
- - -khtml-border-bottom-right-radius
- - -khtml-border-radius
- - -khtml-box-shadow
- - -khtml-opacity
-
-
- - -webkit-appearance
- - -webkit-animation
- - -webkit-animation-name
- - -webkit-animation-duration
- - -webkit-animation-iteration
- - -webkit-animation-direction
- - -webkit-animation-delay
- - -webkit-animation-play-state
- - -webkit-animation-fill-mode
- - -webkit-background-size
- - -webkit-backface-visibility
- - -webkit-border-image
- - -webkit-border-bottom-colors
- - -webkit-border-left-colors
- - -webkit-border-radius
- - -webkit-border-right-colors
- - -webkit-border-top-colors
- - -webkit-border-top-left-radius
- - -webkit-border-top-right-radius
- - -webkit-border-bottom-left-radius
- - -webkit-border-bottom-right-radius
- - -webkit-border-radius-bottomleft
- - -webkit-border-radius-bottomright
- - -webkit-box-align
- - -webkit-box-direction
- - -webkit-box-flex
- - -webkit-box-ordinal-group
- - -webkit-box-orient
- - -webkit-box-pack
- - -webkit-box-reflect
- - -webkit-box-shadow
- - -webkit-box-sizing
- - -webkit-column-count
- - -webkit-column-gap
- - -webkit-hyphens
- - -webkit-linear-gradient
- - -webkit-gradient
- - -webkit-overflow-scrolling
- - -webkit-perspective
- - -webkit-text-decoration
- - -webkit-text-decoration-skip
- - -webkit-text-fill-color
- - -webkit-text-stroke-color
- - -webkit-text-stroke-width
- - -webkit-text-size-adjust
- - -webkit-tap-highlight-color
- - -webkit-transform
- - -webkit-transform-origin
- - -webkit-transform-style
- - -webkit-transition
- - -webkit-transition-property
- - -webkit-transition-delay
- - -webkit-transition-duration
- - -webkit-user-select
-
-
- - zoom
- - -ms-animation-name
- - -ms-animation-duration
- - -ms-animation-iteration
- - -ms-animation-direction
- - -ms-animation-delay
- - -ms-animation-play-state
- - -ms-animation-fill-mode
- - -ms-box-sizing
- - -ms-filter
- - -ms-flex
- - -ms-flex-align
- - -ms-flex-direction
- - -ms-flex-flow
- - -ms-flex-item-align
- - -ms-flex-line-pack
- - -ms-flex-negative
- - -ms-flex-order
- - -ms-flex-pack
- - -ms-flex-positive
- - -ms-flex-position
- - -ms-flex-preferred-size
- - -ms-flex-wrap
- - -ms-interpolation-mode
- - -ms-linear-gradient
- - -ms-overflow-style
- - -ms-text-size-adjust
- - -ms-transform
- - -ms-transition
- - -ms-user-select
+ properties##CSS
@@ -923,396 +314,20 @@
- - inherit
- - unset
- - auto
-
+ value keywords##CSS
- - none
- - hidden
- - dotted
- - dashed
- - solid
- - double
- - groove
- - ridge
- - inset
- - outset
- - xx-small
- - x-small
- - small
- - medium
- - large
- - x-large
- - xx-large
- - smaller
- - larger
- - italic
- - oblique
- - small-caps
- - normal
- - bold
- - bolder
- - lighter
- - light
- - transparent
- - repeat
- - repeat-x
- - repeat-y
- - no-repeat
- - baseline
- - sub
- - super
- - top
- - text-top
- - middle
- - bottom
- - text-bottom
- - left
- - right
- - center
- - justify
- - konq-center
- - disc
- - circle
- - square
- - box
- - decimal
- - decimal-leading-zero
- - lower-roman
- - upper-roman
- - lower-greek
- - lower-alpha
- - lower-latin
- - upper-alpha
- - upper-latin
- - hebrew
- - armenian
- - georgian
- - cjk-ideographic
- - hiragana
- - katakana
- - hiragana-iroha
- - katakana-iroha
- - inline
- - inline-block
- - block
- - list-item
- - run-in
- - compact
- - marker
- - table
- - inline-table
- - table-row-group
- - table-header-group
- - table-footer-group
- - table-row
- - table-column-group
- - table-column
- - table-cell
- - table-caption
- - crosshair
- - default
- - pointer
- - move
- - e-resize
- - ne-resize
- - nw-resize
- - n-resize
- - se-resize
- - sw-resize
- - s-resize
- - w-resize
- - text
- - wait
- - help
- - above
- - absolute
- - always
- - avoid
- - below
- - bidi-override
- - blink
- - both
- - capitalize
- - caption
- - clip
- - close-quote
- - collapse
- - condensed
- - crop
- - cross
- - ellipsis
- - ellipsis-word
- - embed
- - expanded
- - extra-condensed
- - extra-expanded
- - fixed
- - hand
- - hide
- - higher
- - icon
- - inside
- - invert
- - landscape
- - level
- - line-through
- - loud
- - lower
- - lowercase
- - ltr
- - menu
- - message-box
- - mix
- - narrower
- - no-close-quote
- - no-open-quote
- - nowrap
- - open-quote
- - outside
- - overline
- - portrait
- - pre
- - pre-line
- - pre-wrap
- - relative
- - rtl
- - scroll
- - semi-condensed
- - semi-expanded
- - separate
- - show
- - small-caption
- - static
- - static-position
- - status-bar
- - thick
- - thin
- - ultra-condensed
- - ultra-expanded
- - underline
- - uppercase
- - visible
- - wider
- - break
- - serif
- - sans-serif
- - cursive
- - fantasy
- - monospace
- - border-box
- - content-box
- - -epub-hyphens
- - contain
- - cover
-
-
- - all
- - ease
- - ease-in
- - ease-out
- - ease-in-out
- - step-start
- - step-end
- - linear
-
-
- - infinite
- - reverse
- - alternate
- - alternate-reverse
- - forwards
- - backwards
- - running
- - paused
+ values##CSS
- - black
- - silver
- - gray
- - white
- - maroon
- - red
- - purple
- - fuchsia
- - green
- - lime
- - olive
- - yellow
- - navy
- - blue
- - teal
- - aqua
- - orange
- - aliceblue
- - antiquewhite
- - aquamarine
- - azure
- - beige
- - bisque
- - blanchedalmond
- - blueviolet
- - brown
- - burlywood
- - cadetblue
- - chartreuse
- - chocolate
- - coral
- - cornflowerblue
- - cornsilk
- - crimson
- - cyan
- - aqua
- - darkblue
- - darkcyan
- - darkgoldenrod
- - darkgray
- - darkgreen
- - darkgrey
- - darkkhaki
- - darkmagenta
- - darkolivegreen
- - darkorange
- - darkorchid
- - darkred
- - darksalmon
- - darkseagreen
- - darkslateblue
- - darkslategray
- - darkslategrey
- - darkturquoise
- - darkviolet
- - deeppink
- - deepskyblue
- - dimgray
- - dimgrey
- - dodgerblue
- - firebrick
- - floralwhite
- - forestgreen
- - gainsboro
- - ghostwhite
- - gold
- - goldenrod
- - greenyellow
- - grey
- - honeydew
- - hotpink
- - indianred
- - indigo
- - ivory
- - khaki
- - lavender
- - lavenderblush
- - lawngreen
- - lemonchiffon
- - lightblue
- - lightcoral
- - lightcyan
- - lightgoldenrodyellow
- - lightgray
- - lightgreen
- - lightgrey
- - lightpink
- - lightsalmon
- - lightseagreen
- - lightskyblue
- - lightslategray
- - lightslategrey
- - lightsteelblue
- - lightyellow
- - limegreen
- - linen
- - magenta
- - fuchsia
- - mediumaquamarine
- - mediumblue
- - mediumorchid
- - mediumpurple
- - mediumseagreen
- - mediumslateblue
- - mediumspringgreen
- - mediumturquoise
- - mediumvioletred
- - midnightblue
- - mintcream
- - mistyrose
- - moccasin
- - navajowhite
- - oldlace
- - olivedrab
- - orangered
- - orchid
- - palegoldenrod
- - palegreen
- - paleturquoise
- - palevioletred
- - papayawhip
- - peachpuff
- - peru
- - pink
- - plum
- - powderblue
- - rosybrown
- - royalblue
- - saddlebrown
- - salmon
- - sandybrown
- - seagreen
- - seashell
- - sienna
- - skyblue
- - slateblue
- - slategray
- - slategrey
- - snow
- - springgreen
- - steelblue
- - tan
- - thistle
- - tomato
- - turquoise
- - violet
- - wheat
- - whitesmoke
- - yellowgreen
- - rebeccapurple
-
- - ActiveBorder
- - ActiveCaption
- - AppWorkspace
- - Background
- - ButtonFace
- - ButtonHighlight
- - ButtonShadow
- - ButtonText
- - CaptionText
- - GrayText
- - Highlight
- - HighlightText
- - InactiveBorder
- - InactiveCaption
- - InactiveCaptionText
- - InfoBackground
- - InfoText
- - Menu
- - MenuText
- - Scrollbar
- - ThreeDDarkShadow
- - ThreeDFace
- - ThreeDHighlight
- - ThreeDLightShadow
- - ThreeDShadow
- - Window
- - WindowFrame
- - WindowText
+ colors##CSS
+ functions##CSS
+
- red
- green
@@ -1391,239 +406,32 @@
- get-function
- if
- unique-id
-
-
- - attr
- - calc
- - hsl
- - hsla
- - linear-gradient
- - radial-gradient
- - repeating-linear-gradient
- - repeating-radial-gradient
- - rgb
- - rgba
- - var
- - url
-
-
- - rect
-
-
- - inset
- - circle
- - ellipse
- - polygon
-
-
- - blur
- - brightness
- - contrast
- - drop-shadow
- - grayscale
- - hue-rotate
- - invert
- - opacity
- - saturate
- - sepia
-
-
- - max-content
- - min-content
- - minmax
- - fix-content
- - repeat
-
-
- - cubic-bezier
- - frames
- - steps
-
-
- - matrix
- - matrix3d
- - perspective
- - rotate
- - rotate3d
- - rotateX
- - rotateY
- - rotateZ
- - scale
- - scale3d
- - scaleX
- - scaleY
- - scaleZ
- - skew
- - skewX
- - skewY
- - translate
- - translate3d
- - translateX
- - translateY
- - translateZ
-
-
- - local
- - format
-
- - all
- - print
- - screen
- - speech
-
-
- - any-pointer
- - any-hover
- - aspect-ratio
- - color
- - color-gamut
- - color-index
- - display-mode
- - grid
- - height
- - hover
- - max-aspect-ratio
- - max-color
- - max-color-index
- - max-device-aspect-ratio
- - max-device-height
- - max-device-width
- - max-height
- - max-monochrome
- - max-resolution
- - max-width
- - min-aspect-ratio
- - min-color
- - min-color-index
- - min-device-aspect-ratio
- - min-device-height
- - min-device-width
- - min-height
- - min-monochrome
- - min-resolution
- - min-width
- - monochrome
- - orientation
- - pointer
- - resolution
- - scan
- - update
- - width
+ medias##CSS
- - after
- - before
- - cue
- - first-letter
- - first-line
- - selection
-
-
- - backdrop
- - placeholder
-
- - slotted
-
-
-
-
- - value
- - choices
- - repeat-item
- - repeat-index
-
- - -moz-progress-bar
- - -moz-range-progress
- - -moz-range-thumb
- - -moz-range-track
- - -moz-selection
- - -ms-fill
- - -ms-fill-lower
- - -ms-fill-upper
- - -ms-thumb
- - -ms-track
- - -webkit-progress-bar
- - -webkit-progress-value
- - -webkit-slider-runnable-track
- - -webkit-slider-thumb
+ pseudoelements##CSS
- - active
- - any-link
- - checked
- - default
- - defined
-
- - disabled
- - empty
- - enabled
- - first-child
- - first-of-type
- - fullscreen
- - focus
- - focus-within
- - host
- - hover
- - in-range
- - indeterminate
- - invalid
- - lang
- - last-child
- - last-of-type
- - link
- - not
- - nth-child
- - nth-last-child
- - nth-last-of-type
- - nth-of-type
- - only-child
- - only-of-type
- - optional
- - out-of-range
- - placeholder-shown
- - read-only
- - read-write
- - required
- - root
- - scope
- - target
- - valid
- - visited
-
-
- - after
- - before
- - cue
- - first-letter
- - first-line
- - selection
+ pseudoclasses##CSS
- - not
+ pseudoclass-not##CSS
- - blank
- - first
- - left
- - recto
- - right
- - verso
+ pseudoclasses-@page##CSS
- - @character
- - @charset
- - @import
- - @namespace
+ at-rules##CSS
- @debug
@@ -1634,9 +442,7 @@
- - @document
- - @media
- - @supports
+ nested at-rules##CSS
- @at-rule
@@ -1673,60 +479,35 @@
- - min-width
- - max-width
- - width
- - min-height
- - max-height
- - height
- - zoom
- - min-zoom
- - max-zoom
- - user-zoom
- - orientation
- - viewport-fit
+ within-@viewport##CSS
- @page
- - size
- - marks
- - bleed
+ within-@page##CSS
- @font-face
- - font-display
- - font-family
- - font-stretch
- - font-style
- - font-weight
- - font-variant
- - font-feature-settings
- - font-variation-settings
- - src
- - unicode-range
+ within-@font-face##CSS
- @keyframes
- - from
- - to
+ within-@keyframes##CSS
- - and
- - only
- - not
+ media operators##CSS
diff --git a/src/indexer/katehighlightingindexer.cpp b/src/indexer/katehighlightingindexer.cpp
--- a/src/indexer/katehighlightingindexer.cpp
+++ b/src/indexer/katehighlightingindexer.cpp
@@ -193,6 +193,82 @@
return true;
}
+/**
+ * Helper class to search for non-existing keyword include.
+ */
+class KeywordIncludeChecker
+{
+public:
+ void processElement(const QString &hlFilename, const QString &hlName, QXmlStreamReader &xml)
+ {
+ if (xml.name() == QLatin1String("list")) {
+ auto &keywords = m_keywordMap[hlName];
+ keywords.filename = hlFilename;
+ auto name = xml.attributes().value(QLatin1String("name")).toString();
+ m_currentIncludes = &keywords.includes[name];
+ }
+ else if (xml.name() == QLatin1String("include")) {
+ if (!m_currentIncludes) {
+ qWarning() << hlFilename << "line" << xml.lineNumber() << " tag ouside ";
+ m_success = false;
+ } else {
+ m_currentIncludes->push_back({xml.lineNumber(), xml.readElementText()});
+ }
+ }
+ }
+
+ bool check() const
+ {
+ bool success = m_success;
+ for (auto &keywords : m_keywordMap) {
+ QMapIterator> includes(keywords.includes);
+ while (includes.hasNext()) {
+ includes.next();
+ for (auto &include : includes.value()) {
+ bool containsKeywordName = true;
+ int const idx = include.name.indexOf(QStringLiteral("##"));
+ if (idx == -1) {
+ auto &keywordName = includes.key();
+ containsKeywordName = keywords.includes.contains(keywordName);
+ }
+ else {
+ auto defName = include.name.mid(idx + 2);
+ auto listName = include.name.left(idx);
+ auto it = m_keywordMap.find(defName);
+ if (it == m_keywordMap.end()) {
+ qWarning() << keywords.filename << "line" << include.line << "unknown definition in" << include.name;
+ success = false;
+ } else {
+ containsKeywordName = it->includes.contains(listName);
+ }
+ }
+
+ if (!containsKeywordName) {
+ qWarning() << keywords.filename << "line" << include.line << "unknown keyword name in" << include.name;
+ success = false;
+ }
+ }
+ }
+ }
+ return success;
+ }
+
+private:
+ struct Keywords
+ {
+ QString filename;
+ struct Include
+ {
+ qint64 line;
+ QString name;
+ };
+ QMap> includes;
+ };
+ QHash m_keywordMap;
+ QVector *m_currentIncludes = nullptr;
+ bool m_success = true;
+};
+
/**
* Helper class to search for non-existing or unreferenced keyword lists.
*/
@@ -457,6 +533,7 @@
// index all given highlightings
ContextChecker contextChecker;
+ KeywordIncludeChecker keywordIncludeChecker;
QVariantMap hls;
int anyError = 0;
foreach (const QString &hlFilename, hlFilenames) {
@@ -528,6 +605,9 @@
// search for used/existing contexts if applicable
contextChecker.processElement(hlFilename, hlName, xml);
+ // search for existing keyword includes
+ keywordIncludeChecker.processElement(hlFilename, hlName, xml);
+
// search for used/existing attributes if applicable
attributeChecker.processElement(xml);
@@ -571,6 +651,9 @@
if (!contextChecker.check())
anyError = 7;
+ if (!keywordIncludeChecker.check())
+ anyError = 7;
+
// bail out if any problem was seen
if (anyError)
diff --git a/src/lib/definition.cpp b/src/lib/definition.cpp
--- a/src/lib/definition.cpp
+++ b/src/lib/definition.cpp
@@ -31,6 +31,7 @@
#include "context_p.h"
#include "format.h"
#include "format_p.h"
+#include "repository.h"
#include "repository_p.h"
#include "rule_p.h"
#include "ksyntaxhighlighting_logging.h"
@@ -221,13 +222,13 @@
QStringList Definition::keywordLists() const
{
- d->load();
+ d->load(DefinitionData::OnlyKeywords(true));
return d->keywordLists.keys();
}
QStringList Definition::keywordList(const QString& name) const
{
- d->load();
+ d->load(DefinitionData::OnlyKeywords(true));
const auto list = d->keywordList(name);
return list ? list->keywords() : QStringList();
}
@@ -356,14 +357,17 @@
return !contexts.isEmpty();
}
-bool DefinitionData::load()
+bool DefinitionData::load(OnlyKeywords onlyKeywords)
{
if (fileName.isEmpty())
return false;
if (isLoaded())
return true;
+ if (bool(onlyKeywords) && keywordIsLoaded)
+ return true;
+
QFile file(fileName);
if (!file.open(QFile::ReadOnly))
return false;
@@ -374,15 +378,20 @@
if (token != QXmlStreamReader::StartElement)
continue;
- if (reader.name() == QLatin1String("highlighting"))
- loadHighlighting(reader);
+ if (reader.name() == QLatin1String("highlighting")) {
+ loadHighlighting(reader, onlyKeywords);
+ if (bool(onlyKeywords)) {
+ return true;
+ }
+ }
else if (reader.name() == QLatin1String("general"))
loadGeneral(reader);
}
- for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it)
- (*it).setCaseSensitivity(caseSensitive);
+ for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
+ it->setCaseSensitivity(caseSensitive);
+ }
foreach (auto context, contexts) {
context->resolveContexts();
@@ -491,19 +500,25 @@
return true;
}
-void DefinitionData::loadHighlighting(QXmlStreamReader& reader)
+void DefinitionData::loadHighlighting(QXmlStreamReader& reader, OnlyKeywords onlyKeywords)
{
Q_ASSERT(reader.name() == QLatin1String("highlighting"));
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
while (!reader.atEnd()) {
switch (reader.tokenType()) {
case QXmlStreamReader::StartElement:
if (reader.name() == QLatin1String("list")) {
- KeywordList keywords;
- keywords.load(reader);
- keywordLists.insert(keywords.name(), keywords);
+ if (!keywordIsLoaded) {
+ KeywordList keywords;
+ keywords.load(reader);
+ keywordLists.insert(keywords.name(), keywords);
+ }
+ } else if (bool(onlyKeywords)) {
+ resolveIncludeKeywords();
+ return;
} else if (reader.name() == QLatin1String("contexts")) {
+ resolveIncludeKeywords();
loadContexts(reader);
reader.readNext();
} else if (reader.name() == QLatin1String("itemDatas")) {
@@ -521,6 +536,19 @@
}
}
+void DefinitionData::resolveIncludeKeywords()
+{
+ if (keywordIsLoaded) {
+ return;
+ }
+
+ keywordIsLoaded = true;
+
+ for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
+ it->resolveIncludeKeywords(*this);
+ }
+}
+
void DefinitionData::loadContexts(QXmlStreamReader& reader)
{
Q_ASSERT(reader.name() == QLatin1String("contexts"));
diff --git a/src/lib/definition_p.h b/src/lib/definition_p.h
--- a/src/lib/definition_p.h
+++ b/src/lib/definition_p.h
@@ -54,17 +54,21 @@
void clear();
- bool load();
+ enum class OnlyKeywords : bool;
+
+ bool load(OnlyKeywords onlyKeywords = OnlyKeywords(false));
bool loadLanguage(QXmlStreamReader &reader);
- void loadHighlighting(QXmlStreamReader &reader);
+ void loadHighlighting(QXmlStreamReader &reader, OnlyKeywords onlyKeywords);
void loadContexts(QXmlStreamReader &reader);
void loadItemData(QXmlStreamReader &reader);
void loadGeneral(QXmlStreamReader &reader);
void loadComments(QXmlStreamReader &reader);
void loadFoldingIgnoreList(QXmlStreamReader &reader);
void loadSpellchecking(QXmlStreamReader &reader);
bool checkKateVersion(const QStringRef &verStr);
+ void resolveIncludeKeywords();
+
KeywordList *keywordList(const QString &name);
bool isWordDelimiter(QChar c) const;
@@ -83,6 +87,7 @@
QHash formats;
QString wordDelimiters;
QString wordWrapDelimiters;
+ bool keywordIsLoaded = false;
bool hasFoldingRegions = false;
bool indentationBasedFolding = false;
QStringList foldingIgnoreList;
diff --git a/src/lib/keywordlist.cpp b/src/lib/keywordlist.cpp
--- a/src/lib/keywordlist.cpp
+++ b/src/lib/keywordlist.cpp
@@ -22,6 +22,9 @@
*/
#include "keywordlist_p.h"
+#include "repository.h"
+#include "definition_p.h"
+#include "ksyntaxhighlighting_logging.h"
#include
#include
@@ -58,6 +61,11 @@
reader.readNextStartElement();
break;
}
+ else if (reader.name() == QLatin1String("include")) {
+ m_includes.append(reader.readElementText().trimmed());
+ reader.readNextStartElement();
+ break;
+ }
reader.readNext();
break;
case QXmlStreamReader::EndElement:
@@ -102,3 +110,33 @@
*/
std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive] (const QStringRef &a, const QStringRef &b) { return a.compare(b, caseSensitive) < 0; });
}
+
+void KeywordList::resolveIncludeKeywords(DefinitionData &def)
+{
+ for (auto &kw_include : m_includes) {
+ const auto idx = kw_include.indexOf(QLatin1String("##"));
+ KeywordList *keywords = nullptr;
+ if (idx >= 0) {
+ auto listName = kw_include.left(idx);
+ auto defName = kw_include.mid(idx + 2);
+ auto includeDef = def.repo->definitionForName(defName);
+ if (!includeDef.isValid()) {
+ qCWarning(Log) << "Unable to resolve external include keyword for definition" << defName << "in" << def.name;
+ continue;
+ }
+ auto defData = DefinitionData::get(includeDef);
+ defData->load(DefinitionData::OnlyKeywords(true));
+ keywords = defData->keywordList(listName);
+ } else {
+ keywords = def.keywordList(kw_include);
+ }
+
+ if (keywords) {
+ m_keywords += keywords->m_keywords;
+ } else {
+ qCWarning(Log) << "Unresolved include keyword for" << kw_include;
+ }
+ }
+
+ m_includes.clear();
+}
diff --git a/src/lib/keywordlist_p.h b/src/lib/keywordlist_p.h
--- a/src/lib/keywordlist_p.h
+++ b/src/lib/keywordlist_p.h
@@ -34,15 +34,18 @@
namespace KSyntaxHighlighting {
+class Repository;
+class DefinitionData;
+
class KeywordList
{
public:
KeywordList() = default;
~KeywordList() = default;
bool isEmpty() const
{
- return m_keywords.isEmpty();
+ return m_keywords.isEmpty() && m_includes.isEmpty();
}
const QString &name() const
@@ -67,6 +70,7 @@
void load(QXmlStreamReader &reader);
void setCaseSensitivity(Qt::CaseSensitivity caseSensitive);
void initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive);
+ void resolveIncludeKeywords(DefinitionData &def);
private:
/**
@@ -79,6 +83,11 @@
*/
QStringList m_keywords;
+ /**
+ * raw list of include keywords, as seen in XML (but trimmed)
+ */
+ QStringList m_includes;
+
/**
* default case-sensitivity setting
*/