feat: add syntax highlighting
This commit is contained in:
0
src/lib/UI/GUI/SyntaxHightlightedTextarea.svelte
Normal file
0
src/lib/UI/GUI/SyntaxHightlightedTextarea.svelte
Normal file
@@ -1,16 +1,10 @@
|
||||
<textarea
|
||||
class={"border border-darkborderc n-scroll focus:border-borderc resize-none rounded-md shadow-sm text-textcolor bg-transparent focus:ring-borderc focus:ring-2 focus:outline-none transition-colors duration-200" + ((className) ? (' ' + className) : '')}
|
||||
<div
|
||||
class={"border border-darkborderc relative z-20 n-scroll focus-within:border-borderc rounded-md shadow-sm text-textcolor bg-transparent focus-within:ring-borderc focus-within:ring-2 focus-within:outline-none transition-colors duration-200" + ((className) ? (' ' + className) : '')}
|
||||
class:text-sm={size === 'sm' || (size === 'default' && $textAreaTextSize === 1)}
|
||||
class:text-md={size === 'md' || (size === 'default' && $textAreaTextSize === 2)}
|
||||
class:text-lg={size === 'lg' || (size === 'default' && $textAreaTextSize === 3)}
|
||||
class:text-xl={size === 'xl'}
|
||||
class:text-xs={size === 'xs' || (size === 'default' && $textAreaTextSize === 0)}
|
||||
class:px-4={padding}
|
||||
class:py-2={padding}
|
||||
class:mb-4={margin === 'bottom'}
|
||||
class:mb-2={margin === 'both'}
|
||||
class:mt-4={margin === 'top'}
|
||||
class:mt-2={margin === 'both'}
|
||||
class:w-full={fullwidth}
|
||||
class:h-20={height === '20' || (height === 'default' && $textAreaSize === -5)}
|
||||
class:h-24={height === '24' || (height === 'default' && $textAreaSize === -4)}
|
||||
@@ -35,33 +29,58 @@
|
||||
class:min-h-64={height === 'default' && $textAreaSize === 3}
|
||||
class:min-h-72={height === 'default' && $textAreaSize === 4}
|
||||
class:min-h-80={height === 'default' && $textAreaSize === 5}
|
||||
{autocomplete}
|
||||
{placeholder}
|
||||
id={id}
|
||||
bind:value={value}
|
||||
on:input={(e) => {
|
||||
if(optimaizedInput){
|
||||
if(inpa++ > 10){
|
||||
value = e.currentTarget.value
|
||||
inpa = 0
|
||||
class:mb-4={margin === 'bottom'}
|
||||
class:mb-2={margin === 'both'}
|
||||
class:mt-4={margin === 'top'}
|
||||
class:mt-2={margin === 'both'}
|
||||
bind:this={highlightDom}
|
||||
>
|
||||
{#if !highlight || !CSS.highlights}
|
||||
<textarea
|
||||
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto"
|
||||
class:text-transparent={highlight}
|
||||
class:px-4={padding}
|
||||
class:py-2={padding}
|
||||
{autocomplete}
|
||||
{placeholder}
|
||||
id={id}
|
||||
bind:value={value}
|
||||
on:input={(e) => {
|
||||
if(optimaizedInput){
|
||||
if(inpa++ > 10){
|
||||
value = e.currentTarget.value
|
||||
inpa = 0
|
||||
onInput()
|
||||
}
|
||||
}
|
||||
else{
|
||||
value = e.currentTarget.value
|
||||
onInput()
|
||||
}
|
||||
}}
|
||||
on:change={(e) => {
|
||||
if(optimaizedInput){
|
||||
value = e.currentTarget.value
|
||||
onInput()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<div
|
||||
class="w-full h-full bg-transparent focus-within:outline-none resize-none absolute top-0 left-0 z-10 overflow-y-auto px-4 py-2 break-words whitespace-pre-wrap"
|
||||
contenteditable="plaintext-only"
|
||||
bind:innerText={value}
|
||||
on:keydown={(e) => {
|
||||
onInput()
|
||||
}
|
||||
}
|
||||
else{
|
||||
value = e.currentTarget.value
|
||||
onInput()
|
||||
}
|
||||
}}
|
||||
on:change={(e) => {
|
||||
if(optimaizedInput){
|
||||
value = e.currentTarget.value
|
||||
onInput()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
}}
|
||||
>{value ?? ''}</div>
|
||||
{/if}
|
||||
</div>
|
||||
<script lang="ts">
|
||||
import { textAreaSize, textAreaTextSize } from 'src/ts/gui/guisize'
|
||||
import { highlighter, getNewHighlightId, removeHighlight } from 'src/ts/gui/highlight'
|
||||
import { sleep } from 'src/ts/util';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
export let size: 'xs'|'sm'|'md'|'lg'|'xl'|'default' = 'default'
|
||||
export let autocomplete: 'on'|'off' = 'off'
|
||||
export let placeholder: string = ''
|
||||
@@ -74,10 +93,26 @@
|
||||
export let height:'20'|'24'|'28'|'32'|'36'|'full'|'default' = 'default'
|
||||
export let className = ''
|
||||
export let optimaizedInput = true
|
||||
export let highlight = false
|
||||
let highlightId = highlight ? getNewHighlightId() : 0
|
||||
let inpa = 0
|
||||
|
||||
let highlightDom: HTMLDivElement
|
||||
let optiValue = value
|
||||
|
||||
onMount(() => {
|
||||
highlighter(highlightDom, highlightId)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
removeHighlight(highlightId)
|
||||
})
|
||||
|
||||
const highlightChange = async (value:string, highlightId:number) => {
|
||||
await sleep(1)
|
||||
highlighter(highlightDom, highlightId)
|
||||
}
|
||||
|
||||
$: optiValue = value
|
||||
$: highlightChange(value, highlightId)
|
||||
|
||||
</script>
|
||||
@@ -68,7 +68,7 @@
|
||||
<OptionInput value="globalNote">{language.globalNote}</OptionInput>
|
||||
</SelectInput>
|
||||
<span>{language.prompt}</span>
|
||||
<TextAreaInput bind:value={promptItem.text} />
|
||||
<TextAreaInput highlight bind:value={promptItem.text} />
|
||||
<span>{language.role}</span>
|
||||
<SelectInput bind:value={promptItem.role}>
|
||||
<OptionInput value="user">{language.user}</OptionInput>
|
||||
@@ -115,7 +115,7 @@
|
||||
}} />
|
||||
{:else}
|
||||
<span>{language.innerFormat}</span>
|
||||
<TextAreaInput bind:value={promptItem.innerFormat}/>
|
||||
<TextAreaInput highlight bind:value={promptItem.innerFormat}/>
|
||||
<CheckInput name={language.customInnerFormat} check={true} className="mt-2" onChange={() => {
|
||||
if(promptItem.type === 'persona' || promptItem.type === 'description' || promptItem.type === 'authornote' || promptItem.type === 'memory'){
|
||||
promptItem.innerFormat = null
|
||||
|
||||
Reference in New Issue
Block a user