性能优化和样式更新
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, nextTick } from 'vue';
|
||||
import { splitTokens, parseDetailedToken, constructToken } from '../../stores/promptStore';
|
||||
import { splitTokens, parseDetailedToken, constructToken, normalizeSymbols } from '../../stores/promptStore';
|
||||
import PromptQuickAdd from '../PromptQuickAdd.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -26,6 +26,7 @@ const emit = defineEmits<{
|
||||
'add-tag': [tag: string];
|
||||
'drag-tag-start': [tag: string];
|
||||
'drag-tag-end': [];
|
||||
'locate-token': [index: number];
|
||||
}>();
|
||||
|
||||
const inputEl = ref<HTMLTextAreaElement | null>(null);
|
||||
@@ -154,9 +155,41 @@ async function applySuggestion(s: string) {
|
||||
emit('update-suggestions');
|
||||
}
|
||||
|
||||
function updateSuggestions() {
|
||||
// 通知父组件更新建议
|
||||
// 计算与 splitTokens 对齐的非空 token 区间(用于光标定位)
|
||||
function computeTokenRanges(txt: string): { start: number; end: number }[] {
|
||||
const ranges: { start: number; end: number }[] = [];
|
||||
let depth = 0;
|
||||
let segStart = 0;
|
||||
for (let i = 0; i < txt.length; i++) {
|
||||
const c = txt[i]!;
|
||||
if (c === '(' || c === '[' || c === '{' || c === '<') depth++;
|
||||
else if (c === ')' || c === ']' || c === '}' || c === '>') depth = Math.max(0, depth - 1);
|
||||
if ((c === ',' || c === '\n') && depth === 0) {
|
||||
ranges.push({ start: segStart, end: i });
|
||||
segStart = i + 1;
|
||||
}
|
||||
}
|
||||
ranges.push({ start: segStart, end: txt.length });
|
||||
return ranges.filter(r => txt.slice(r.start, r.end).trim().length > 0);
|
||||
}
|
||||
|
||||
// 根据光标位置定位对应的 token 序号,通知父组件高亮右侧映射
|
||||
function emitLocate() {
|
||||
const el = inputEl.value;
|
||||
if (!el) return;
|
||||
const norm = normalizeSymbols(props.text);
|
||||
const pos = el.selectionStart ?? norm.length;
|
||||
const ranges = computeTokenRanges(norm);
|
||||
if (!ranges.length) { emit('locate-token', -1); return; }
|
||||
let idx = ranges.findIndex(r => pos >= r.start && pos <= r.end);
|
||||
if (idx === -1) idx = ranges.findIndex(r => pos <= r.end);
|
||||
if (idx === -1) idx = ranges.length - 1;
|
||||
emit('locate-token', idx);
|
||||
}
|
||||
|
||||
function onCursorActivity() {
|
||||
emit('update-suggestions');
|
||||
emitLocate();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@@ -172,8 +205,8 @@ defineExpose({
|
||||
class="pe-input"
|
||||
v-model="localText"
|
||||
@keydown="onKeyDown"
|
||||
@click="updateSuggestions"
|
||||
@keyup="updateSuggestions"
|
||||
@click="onCursorActivity"
|
||||
@keyup="onCursorActivity"
|
||||
placeholder="例如:1girl, aaa, bbb, ccc"
|
||||
></textarea>
|
||||
<div class="pe-input-actions">
|
||||
|
||||
Reference in New Issue
Block a user