3
0

Add autocompletion to ace-editor

This commit is contained in:
Kelani Tolulope 2024-04-12 14:54:59 +01:00 committed by Jože Fortun
parent ad64c547a2
commit 104a33ee0e
12 changed files with 240 additions and 2 deletions

View File

@ -57,6 +57,8 @@
font-size="14px"
show-line-numbers
class="flex-fill w-100"
auto-complete
:auto-complete-suggestions="customCssAutocompleteVal"
/>
</b-form-group>
</b-col>
@ -77,6 +79,7 @@
<script>
import { components } from '@cortezaproject/corteza-vue'
import { CUSTOM_CSS_AUTO_COMPLETE_VALUES } from 'corteza-webapp-admin/src/lib/cssAutoComplete'
import CUploaderWithPreview from 'corteza-webapp-admin/src/components/CUploaderWithPreview'
const { CAceEditor } = components
@ -116,6 +119,12 @@ export default {
},
},
data () {
return {
customCssAutocompleteVal: CUSTOM_CSS_AUTO_COMPLETE_VALUES,
}
},
methods: {
uploadedFile (name) {
const localAttachment = /^attachment:(\d+)/

View File

@ -131,11 +131,13 @@
>
<c-ace-editor
v-model="theme.customCSS"
lang="css"
auto-complete
lang="scss"
height="400px"
font-size="14px"
show-line-numbers
:show-popout="true"
:auto-complete-suggestions="customCssAutocompleteVal"
@open="openCustomCSSModal(theme.id)"
/>
</b-form-group>
@ -158,12 +160,14 @@
>
<c-ace-editor
v-model="customCSSModal.value"
auto-complete
lang="scss"
height="500px"
font-size="14px"
show-line-numbers
:border="false"
:show-popout="false"
:auto-complete-suggestions="customCssAutocompleteVal"
/>
</b-modal>
@ -183,6 +187,7 @@
<script>
import CUploaderWithPreview from 'corteza-webapp-admin/src/components//CUploaderWithPreview'
import { components } from '@cortezaproject/corteza-vue'
import { CUSTOM_CSS_AUTO_COMPLETE_VALUES } from 'corteza-webapp-admin/src/lib/cssAutoComplete'
const { CInputColorPicker, CAceEditor } = components
export default {
@ -279,6 +284,8 @@ export default {
id: '',
value: '',
},
customCssAutocompleteVal: CUSTOM_CSS_AUTO_COMPLETE_VALUES,
}
},

View File

@ -0,0 +1,47 @@
export const CUSTOM_CSS_AUTO_COMPLETE_VALUES = [
{ value: 'var(--blue)', caption: 'var(--blue)' },
{ value: 'var(--indigo)', caption: 'var(--indigo)' },
{ value: 'var(--purple)', caption: 'var(--purple)' },
{ value: 'var(--pink)', caption: 'var(--pink)' },
{ value: 'var(--red)', caption: 'var(--red)' },
{ value: 'var(--orange)', caption: 'var(--orange)' },
{ value: 'var(--yellow)', caption: 'var(--yellow)' },
{ value: 'var(--green)', caption: 'var(--green)' },
{ value: 'var(--teal)', caption: 'var(--teal)' },
{ value: 'var(--cyan)', caption: 'var(--cyan)' },
{ value: 'var(--white)', caption: 'var(--white)' },
{ value: 'var(--gray)', caption: 'var(--gray)' },
{ value: 'var(--gray-dark)', caption: 'var(--gray-dark)' },
{ value: 'var(--gray-900)', caption: 'var(--gray-900)' },
{ value: 'var(--primary)', caption: 'var(--primary)' },
{ value: 'var(--secondary)', caption: 'var(--secondary)' },
{ value: 'var(--success)', caption: 'var(--success)' },
{ value: 'var(--info)', caption: 'var(--info)' },
{ value: 'var(--warning)', caption: 'var(--warning)' },
{ value: 'var(--danger)', caption: 'var(--danger)' },
{ value: 'var(--light)', caption: 'var(--light)' },
{ value: 'var(--dark)', caption: 'var(--dark)' },
{ value: 'var(--white)', caption: 'var(--white)' },
{ value: 'var(--black)', caption: 'var(--black)' },
{ value: 'var(--extra-light)', caption: 'var(--extra-light)' },
{ value: 'var(--breakpoint-xs)', caption: 'var(--breakpoint-xs)' },
{ value: 'var(--breakpoint-sm)', caption: 'var(--breakpoint-sm)' },
{ value: 'var(--breakpoint-md)', caption: 'var(--breakpoint-md)' },
{ value: 'var(--breakpoint-lg)', caption: 'var(--breakpoint-lg)' },
{ value: 'var(--breakpoint-xl)', caption: 'var(--breakpoint-xl)' },
{ value: 'var(--breakpoint-xxl)', caption: 'var(--breakpoint-xxl)' },
{ value: 'var(--body-bg)', caption: 'var(--body-bg)' },
{ value: 'var(--topbar-height)', caption: 'var(--topbar-height)' },
{ value: 'var(--topbar-bg)', caption: 'var(--topbar-bg)' },
{ value: 'var(--sidebar-width)', caption: 'var(--sidebar-width)' },
{ value: 'var(--sidebar-bg)', caption: 'var(--sidebar-bg)' },
{ value: 'var(--font-regular)', caption: 'var(--font-regular)' },
{ value: 'var(--font-semibold)', caption: 'var(--font-semibold)' },
{ value: 'var(--font-family-base)', caption: 'var(--font-family-base)' },
{ value: 'var(--font-medium)', caption: 'var(--font-medium)' },
{ value: 'var(--btn-font-family)', caption: 'var(--btn-font-family)' },
{ value: 'var(--btn-padding-x)', caption: 'var(--btn-padding-x)' },
{ value: 'var(--btn-padding-y)', caption: 'var(--btn-padding-y)' },
{ value: 'var(--font-family-sans-serif)', caption: 'var(--font-family-sans-serif)' },
{ value: 'var(--font-family-monospace)', caption: 'var(--font-family-monospace)' },
]

View File

@ -26,7 +26,9 @@
lang="javascript"
font-size="18px"
show-line-numbers
auto-complete
:show-popout="false"
:auto-complete-suggestions="expressionAutoCompleteValues"
@input="valueChanged"
/>
</b-form-group>
@ -38,6 +40,7 @@
<script>
import base from './base'
import { components } from '@cortezaproject/corteza-vue'
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../../lib/editor-auto-complete.js'
const { CAceEditor } = components
@ -48,6 +51,12 @@ export default {
extends: base,
data () {
return {
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},
watch: {
'item.config.stepID': {
immediate: true,

View File

@ -25,7 +25,9 @@
lang="javascript"
font-size="18px"
show-line-numbers
auto-complete
:show-popout="false"
:auto-complete-suggestions="expressionAutoCompleteValues"
@open="openInEditor"
@input="valueChanged"
/>
@ -49,9 +51,11 @@
lang="javascript"
height="500"
font-size="18px"
auto-complete
show-line-numbers
:border="false"
:show-popout="false"
:auto-complete-suggestions="expressionAutoCompleteValues"
/>
</b-modal>
</b-card>
@ -60,6 +64,7 @@
<script>
import base from './base'
import { components } from '@cortezaproject/corteza-vue'
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../../lib/editor-auto-complete.js'
const { CAceEditor } = components
@ -75,6 +80,7 @@ export default {
expressionEditor: {
currentExpression: undefined,
},
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},

View File

@ -67,8 +67,10 @@
lang="javascript"
font-size="18px"
show-line-numbers
auto-complete
:border="false"
:show-popout="false"
:auto-complete-suggestions="expressionAutoCompleteValues"
/>
</b-modal>
</div>
@ -78,6 +80,7 @@
import base from './base'
import ExpressionTable from '../ExpressionTable.vue'
import { components } from '@cortezaproject/corteza-vue'
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../../lib/editor-auto-complete.js'
const { CAceEditor } = components
@ -97,6 +100,8 @@ export default {
currentIndex: undefined,
currentExpression: undefined,
},
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},

View File

@ -160,6 +160,8 @@
<c-ace-editor
v-else
v-model="a.value"
auto-complete
:auto-complete-suggestions="expressionAutoCompleteValues"
@open="openInEditor(index)"
@input="$root.$emit('change-detected')"
/>
@ -170,6 +172,8 @@
v-model="a.expr"
lang="javascript"
show-line-numbers
auto-complete
:auto-complete-suggestions="expressionAutoCompleteValues"
@open="openInEditor(index)"
@input="$root.$emit('change-detected')"
/>
@ -310,8 +314,10 @@
height="500"
font-size="18px"
show-line-numbers
auto-complete
:border="false"
:show-popout="false"
:auto-complete-suggestions="expressionAutoCompleteValues"
/>
</b-modal>
</div>
@ -322,6 +328,7 @@ import base from './base'
import ExpressionTable from '../ExpressionTable.vue'
import { objectSearchMaker, stringSearchMaker } from '../../lib/filter'
import { components } from '@cortezaproject/corteza-vue'
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../../lib/editor-auto-complete.js'
const { CAceEditor } = components
@ -355,6 +362,8 @@ export default {
currentExpression: undefined,
lang: 'javascript',
},
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},

View File

@ -38,7 +38,9 @@
lang="javascript"
height="100"
show-line-numbers
auto-complete
:show-popout="false"
:auto-complete-suggestions="expressionAutoCompleteValues"
@input="updateEdge(edge.id, $event)"
/>
</b-form-group>
@ -51,6 +53,7 @@
<script>
import base from './base'
import { components } from '@cortezaproject/corteza-vue'
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../../lib/editor-auto-complete.js'
const { CAceEditor } = components
@ -61,6 +64,12 @@ export default {
extends: base,
data () {
return {
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},
computed: {
gatewayKind () {
return this.item.config.ref

View File

@ -9,6 +9,9 @@
:show-line-numbers="showLineNumbers"
:font-size="fontSize"
:show-popout="showPopout"
auto-complete
:border="border"
:auto-complete-suggestions="expressionAutoCompleteValues"
v-on="$listeners"
/>
</div>
@ -16,6 +19,7 @@
<script>
import { components } from '@cortezaproject/corteza-vue'
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../lib/editor-auto-complete.js'
const { CAceEditor } = components
@ -61,6 +65,12 @@ export default {
},
},
data () {
return {
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},
computed: {
expressionValue: {
get () {

View File

@ -101,6 +101,8 @@
v-model="item[valueField]"
lang="javascript"
show-line-numbers
auto-complete
:auto-complete-suggestions="expressionAutoCompleteValues"
@open="$emit('open-editor', index)"
@input="$root.$emit('change-detected')"
/>
@ -114,6 +116,7 @@
</template>
<script>
import { EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES } from '../lib/editor-auto-complete.js'
import { components } from '@cortezaproject/corteza-vue'
import { objectSearchMaker } from '../lib/filter'
import draggable from 'vuedraggable'
@ -148,6 +151,12 @@ export default {
},
},
data () {
return {
expressionAutoCompleteValues: EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES,
}
},
methods: {
varFilter: objectSearchMaker('text'),

View File

@ -0,0 +1,70 @@
export const EXPRESSION_EDITOR_AUTO_COMPLETE_VALUES = [
{ value: 'push(', caption: 'push(array, ...elements)' },
{ value: 'pop(', caption: 'pop(array)' },
{ value: 'shift(', caption: 'shift(array)' },
{ value: 'count(', caption: 'count(array, ...elements)' },
{ value: 'has(', caption: 'has(arr, ...elements)' },
{ value: 'hasAll(', caption: 'hasAll(arr, ...elements)' },
{ value: 'find(', caption: 'find(arr, elements)' },
{ value: 'sort(', caption: 'sort(array, descending)' },
{ value: 'splice(', caption: 'splice' },
{ value: 'min(', caption: 'min(...number)' },
{ value: 'max(', caption: 'max(...number)' },
{ value: 'round(', caption: 'round(number, places)' },
{ value: 'floor(', caption: 'floor(number)' },
{ value: 'ceil(', caption: 'ceil(number)' },
{ value: 'abs(', caption: 'abs(number)' },
{ value: 'log(', caption: 'log(number)' },
{ value: 'pow(', caption: 'pow(number, exp)' },
{ value: 'sqrt(', caption: 'sqrt(number)' },
{ value: 'sum(', caption: 'sum(...number)' },
{ value: 'average(', caption: 'average(...number)' },
{ value: 'random(', caption: 'random(a, b?)' },
{ value: 'int(', caption: 'int' },
{ value: 'float(', caption: 'float' },
{ value: 'toJSON(', caption: 'toJSON' },
{ value: 'trim(', caption: 'trim(string)' },
{ value: 'trimLeft(', caption: 'trimLeft(string, remove)' },
{ value: 'trimRight(', caption: 'trimRight(string, remove)' },
{ value: 'toLower(', caption: 'toLower(string)' },
{ value: 'toUpper(', caption: 'toUpper(string)' },
{ value: 'shortest(', caption: 'shortest(string1, ...strings)' },
{ value: 'longest(', caption: 'longest(arg1, arg2, ...arguments)' },
{ value: 'format(', caption: 'format(format, ...arguments)' },
{ value: 'title(', caption: 'title(string)' },
{ value: 'untitle(', caption: 'untitle(string)' },
{ value: 'isUrl(', caption: 'isUrl(string)' },
{ value: 'isEmail(', caption: 'isEmail(string)' },
{ value: 'split(', caption: 'split(string, separator)' },
{ value: 'join(', caption: 'join(strings, separator)' },
{ value: 'hasSubstring(', caption: 'hasSubstring(string, substring, case)' },
{ value: 'hasPrefix(', caption: 'hasPrefix(string, prefix)' },
{ value: 'hasSuffix(', caption: 'hasSuffix(string, prefix)' },
{ value: 'camelize(', caption: 'camelize(string)' },
{ value: 'snakify(', caption: 'snakify(string)' },
{ value: 'match(', caption: 'match(string, regex)' },
{ value: 'base64encode(', caption: 'base64encode(string)' },
{ value: 'unction(', caption: 'unction' },
{ value: 'set(', caption: 'set(kv, k, v)' },
{ value: 'merge(', caption: 'merge(kv, ...kv)' },
{ value: 'filter(', caption: 'filter(kv, ...include)' },
{ value: 'omit(', caption: 'omit(kv, ...exclude)' },
{ value: 'coalesce(', caption: 'coalesce(...Any)' },
{ value: 'isEmpty(', caption: 'isEmpty(Any)' },
{ value: 'isNil(', caption: 'isNil(Any)' },
{ value: 'length(', caption: 'length(array)' },
{ value: 'earliest(', caption: 'earliest(DateTime, ...DateTime)' },
{ value: 'latest(', caption: 'latest()' },
{ value: 'parseISOTime(', caption: 'parseISOTime()' },
{ value: 'modTime(', caption: 'modTime()' },
{ value: 'modDate(', caption: 'modDate(datetime, days)' },
{ value: 'modWeek(', caption: 'modWeek(datetime, weeks)' },
{ value: 'modMonth(', caption: 'modMonth(datetime, months)' },
{ value: 'modYear(', caption: 'modYear(datetime, years)' },
{ value: 'parseDuration(', caption: 'parseDuration()' },
{ value: 'strftime(', caption: 'strftime(datetime, pattern)' },
{ value: 'isLeapYear(', caption: 'isLeapYear(datetime)' },
{ value: 'now(', caption: 'now()' },
{ value: 'isWeekDay(', caption: 'isWeekDay()' },
{ value: 'sub(', caption: 'sub(from, to)' },
]

View File

@ -79,6 +79,11 @@ export default {
type: Boolean,
default: false,
},
autoComplete: {
type: Boolean,
default: false,
},
highlightActiveLine: {
type: Boolean,
@ -89,6 +94,11 @@ export default {
type: Boolean,
default: false,
},
autoCompleteSuggestions: {
type: Array,
default: () => ([])
}
},
computed: {
@ -111,7 +121,19 @@ export default {
require('brace/mode/scss')
require('brace/mode/json')
require('brace/mode/javascript')
require('brace/mode/json')
require('brace/snippets/text')
require('brace/snippets/html')
require('brace/snippets/css')
require('brace/snippets/scss')
require('brace/snippets/json')
require('brace/snippets/javascript')
require('brace/snippets/json')
require('brace/theme/chrome')
require('brace/ext/language_tools')
require('brace/ext/emmet')
editor.setOptions({
tabSize: 2,
@ -124,8 +146,34 @@ export default {
displayIndentGuides: this.lang !== 'text',
useWorker: false,
readOnly: this.readOnly,
highlightActiveLine: this.highlightActiveLine
highlightActiveLine: this.highlightActiveLine,
...(this.autoComplete && {
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
enableEmmet: true
}),
})
const self = this;
const staticWordCompleter = {
getCompletions: function (editor, session, pos, prefix, callback) {
var autoCompleteSuggestions = self.autoCompleteSuggestions;
callback(
null,
autoCompleteSuggestions.map(function ({ caption, value, meta }) {
return {
caption,
value,
meta,
};
})
);
},
};
editor.completers.push(staticWordCompleter);
},
},
}