feat: add syntax highlighting

This commit is contained in:
kwaroran
2024-05-26 08:15:45 +09:00
parent 9e9f23b209
commit 93cba968b5
12 changed files with 402 additions and 58 deletions

View File

@@ -178,10 +178,10 @@
{#if currentChar.type !== 'group' && licensed !== 'private'}
<TextInput size="xl" marginBottom placeholder="Character Name" bind:value={currentChar.data.name} />
<span class="text-textcolor">{language.description} <Help key="charDesc"/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.desc}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.desc}></TextAreaInput>
<span class="text-textcolor2 mb-6 text-sm">{tokens.desc} {language.tokens}</span>
<span class="text-textcolor">{language.firstMessage} <Help key="charFirstMessage"/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.firstMessage}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.firstMessage}></TextAreaInput>
<span class="text-textcolor2 mb-6 text-sm">{tokens.firstMsg} {language.tokens}</span>
{:else if licensed !== 'private' && currentChar.type === 'group'}
@@ -239,6 +239,7 @@
margin="both"
autocomplete="off"
bind:value={currentChar.data.chats[currentChar.data.chatPage].note}
highlight
placeholder={getAuthorNoteDefaultText()}
/>
<span class="text-textcolor2 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
@@ -468,7 +469,7 @@
{#if currentChar.data.inlayViewScreen}
<span class="text-textcolor mt-2">{language.imgGenInstructions}</span>
<TextAreaInput bind:value={currentChar.data.newGenData.emotionInstructions} />
<TextAreaInput highlight bind:value={currentChar.data.newGenData.emotionInstructions} />
{/if}
<CheckInput bind:check={currentChar.data.inlayViewScreen} name={language.inlayViewScreen} onChange={() => {
@@ -488,11 +489,11 @@
<span class="text-textcolor2 text-xs">{language.emotionWarn}</span>
<span class="text-textcolor mt-2">{language.imgGenPrompt}</span>
<TextAreaInput bind:value={currentChar.data.newGenData.prompt} />
<TextAreaInput highlight bind:value={currentChar.data.newGenData.prompt} />
<span class="text-textcolor mt-2">{language.imgGenNegatives}</span>
<TextAreaInput bind:value={currentChar.data.newGenData.negative} />
<TextAreaInput highlight bind:value={currentChar.data.newGenData.negative} />
<span class="text-textcolor mt-2">{language.imgGenInstructions}</span>
<TextAreaInput bind:value={currentChar.data.newGenData.instructions} />
<TextAreaInput highlight bind:value={currentChar.data.newGenData.instructions} />
<CheckInput bind:check={currentChar.data.inlayViewScreen} name={language.inlayViewScreen} onChange={() => {
if(currentChar.type === 'character'){
@@ -727,7 +728,7 @@
<h2 class="mb-2 text-2xl font-bold mt-2">{language.advancedSettings}</h2>
{#if currentChar.type !== 'group'}
<span class="text-textcolor">{language.exampleMessage} <Help key="exampleMessage"/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.exampleMessage}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.exampleMessage}></TextAreaInput>
<span class="text-textcolor">{language.creatorNotes} <Help key="creatorQuotes"/></span>
<MultiLangInput bind:value={currentChar.data.creatorNotes} className="my-2" onInput={() => {
@@ -735,25 +736,25 @@
}}></MultiLangInput>
<span class="text-textcolor">{language.systemPrompt} <Help key="systemPrompt"/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.systemPrompt}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.systemPrompt}></TextAreaInput>
<span class="text-textcolor">{language.replaceGlobalNote} <Help key="replaceGlobalNote"/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.replaceGlobalNote}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.replaceGlobalNote}></TextAreaInput>
<span class="text-textcolor mt-2">{language.additionalText} <Help key="additionalText" /></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.additionalText}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.additionalText}></TextAreaInput>
{#if $DataBase.showUnrecommended || currentChar.data.personality.length > 3}
<span class="text-textcolor">{language.personality} <Help key="personality" unrecommended/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.personality}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.personality}></TextAreaInput>
{/if}
{#if $DataBase.showUnrecommended || currentChar.data.scenario.length > 3}
<span class="text-textcolor">{language.scenario} <Help key="scenario" unrecommended/></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.scenario}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.scenario}></TextAreaInput>
{/if}
<span class="text-textcolor mt-2">{language.backgroundHTML} <Help key="backgroundHTML" /></span>
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.backgroundHTML}></TextAreaInput>
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.backgroundHTML}></TextAreaInput>
<span class="text-textcolor">{language.creator}</span>
<TextInput size="sm" autocomplete="off" bind:value={currentChar.data.additionalData.creator} />
@@ -795,7 +796,7 @@
{#each currentChar.data.alternateGreetings as bias, i}
<tr>
<td class="font-medium truncate">
<TextAreaInput bind:value={currentChar.data.alternateGreetings[i]} placeholder="..." fullwidth />
<TextAreaInput highlight bind:value={currentChar.data.alternateGreetings[i]} placeholder="..." fullwidth />
</td>
<th class="font-medium cursor-pointer w-10">
<button class="hover:text-green-500" on:click={() => {

View File

@@ -86,7 +86,7 @@
<NumberInput size="sm" bind:value={value.insertorder} min={0} max={1000}/>
{/if}
<span class="text-textcolor mt-4 mb-2">{language.prompt}</span>
<TextAreaInput autocomplete="off" bind:value={value.content} />
<TextAreaInput highlight autocomplete="off" bind:value={value.content} />
{#await getTokens(value.content)}
<span class="text-textcolor2 mt-2 mb-2 text-sm">{tokens} {language.tokens}</span>
{:then e}

View File

@@ -5,6 +5,7 @@
import type { customscript } from "src/ts/storage/database";
import Check from "../../UI/GUI/CheckInput.svelte";
import TextInput from "../../UI/GUI/TextInput.svelte";
import TextAreaInput from "../../UI/GUI/TextAreaInput.svelte";
import SelectInput from "../../UI/GUI/SelectInput.svelte";
import OptionInput from "../../UI/GUI/OptionInput.svelte";
@@ -57,7 +58,7 @@
<span class="text-textcolor mt-6">IN:</span>
<TextInput size="sm" bind:value={value.in} />
<span class="text-textcolor mt-6">OUT:</span>
<TextInput size="sm" bind:value={value.out} />
<TextAreaInput highlight autocomplete="off" size="sm" bind:value={value.out} />
{#if value.ableFlag}
<span class="text-textcolor mt-6">FLAG:</span>
<TextInput size="sm" bind:value={value.flag} />

View File

@@ -122,7 +122,7 @@
<OptionInput value="regex">{language.triggerMatchRegex}</OptionInput>
</SelectInput>
<span class="text-textcolor2 text-sm">{language.value}</span>
<TextInput size="sm" bind:value={cond.value} />
<TextAreaInput highlight bind:value={cond.value} />
<span class="text-textcolor2 text-sm">{language.searchDepth}</span>
<NumberInput size="sm" bind:value={cond.depth} />
@@ -133,7 +133,7 @@
<TextInput size="sm" bind:value={cond.var} />
{/if}
{#if cond.type === 'value'}
<TextInput size="sm" bind:value={cond.var} />
<TextAreaInput highlight size="sm" bind:value={cond.var} />
{/if}
<span class="text-textcolor2 text-sm">{language.value}</span>
<SelectInput bind:value={cond.operator} size="sm">
@@ -147,7 +147,7 @@
</SelectInput>
{#if cond.operator !== 'null'}
<TextInput size="sm" bind:value={cond.value} />
<TextAreaInput highlight size="sm" bind:value={cond.value} />
{/if}
{/if}
{/each}
@@ -255,7 +255,7 @@
<OptionInput value="promptend">{language.promptend}</OptionInput>
</SelectInput>
<span class="text-textcolor2 text-sm">{language.value}</span>
<TextAreaInput bind:value={effect.value} />
<TextAreaInput highlight bind:value={effect.value} />
{/if}
{#if effect.type === 'setvar'}
<span class="text-textcolor2 text-sm">{language.varableName}</span>
@@ -269,7 +269,7 @@
<OptionInput value="/=">{language.TriggerDivToVar}</OptionInput>
</SelectInput>
<span class="text-textcolor2 text-sm">{language.value}</span>
<TextInput bind:value={effect.value} />
<TextAreaInput highlight bind:value={effect.value} />
{/if}
{#if effect.type === 'runtrigger'}
@@ -278,7 +278,7 @@
{/if}
{#if effect.type === 'command'}
<span class="text-textcolor2 text-sm">{language.value}</span>
<TextAreaInput bind:value={effect.value} />
<TextAreaInput highlight bind:value={effect.value} />
{/if}
{#if effect.type === 'impersonate'}
<span class="text-textcolor2 text-sm">{language.role}</span>
@@ -287,7 +287,7 @@
<OptionInput value="char">{language.character}</OptionInput>
</SelectInput>
<span class="text-textcolor2 text-sm">{language.value}</span>
<TextAreaInput bind:value={effect.value} />
<TextAreaInput highlight bind:value={effect.value} />
{/if}
{/each}
</div>

View 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>

View File

@@ -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