Enter: надёжная обработка новой строки + hit-зона по всей высоте

- TextArea focus:true, handleEnter() с effectiveLine для пустой строки, _enterHandled флаг, onTextChanged авто-отступ для \n, Keys.onReturnPressed/onEnterPressed + onPressed Tab/Backspace, trim() вместо trimEnd()
- SplitView handle: implicit 12 + fill parent + MouseArea 16 по всей высоте/ширине (файловое дерево, живой просмотр, граф/календарь)
- MonthCalendar: 28x28 круглые opaque, month/year раздельно (70/110 + 42/38, font 11, elide) — год не пропадает для 'сентябрь 2026', RightPanel удалён дубль ☷
This commit is contained in:
2026-09-01 23:36:04 +03:00
parent 22035ba0f2
commit d7ca84863c
+28 -3
View File
@@ -288,6 +288,8 @@ Item {
selectByMouse: true selectByMouse: true
background: Rectangle { color: Theme.editorBg } background: Rectangle { color: Theme.editorBg }
tabStopDistance: 32 tabStopDistance: 32
Component.onCompleted: forceActiveFocus()
onActiveFocusChanged: console.log("TextArea activeFocus", activeFocus, "focus", focus)
// Для подсветки скобок // Для подсветки скобок
property int bracketMatchPos: -1 property int bracketMatchPos: -1
property int bracketOrigPos: -1 property int bracketOrigPos: -1
@@ -368,7 +370,7 @@ Item {
let indent = "" let indent = ""
const m = line.match(/^(\s+)/) const m = line.match(/^(\s+)/)
if (m) indent = m[1] if (m) indent = m[1]
const trimmed = line.trimEnd() const trimmed = line.trim()
if (trimmed.endsWith("{") || trimmed.endsWith("[") || trimmed.endsWith("(") || trimmed.endsWith(":") || trimmed.endsWith(">")) { if (trimmed.endsWith("{") || trimmed.endsWith("[") || trimmed.endsWith("(") || trimmed.endsWith(":") || trimmed.endsWith(">")) {
indent += " " indent += " "
} }
@@ -411,14 +413,37 @@ Item {
let indent = "" let indent = ""
const m = line.match(/^(\s+)/) const m = line.match(/^(\s+)/)
if (m) indent = m[1] if (m) indent = m[1]
const trimmed = line.trimEnd() // Если текущая строка пуста (курсор в начале), берём отступ предыдущей строки
let effectiveLine = line
if (line.length === 0 && pos > 0) {
let prevEnd = pos - 1
if (prevEnd >=0 && text[prevEnd] === "\n") prevEnd--
let prevStart = text.lastIndexOf("\n", prevEnd-1) + 1
if (prevStart < 0) prevStart = 0
effectiveLine = text.substring(prevStart, prevEnd+1)
const m2 = effectiveLine.match(/^(\s+)/)
if (m2) indent = m2[1]
else indent = ""
}
const trimmed = effectiveLine.trim()
if (trimmed.endsWith("{") || trimmed.endsWith("[") || trimmed.endsWith("(") || trimmed.endsWith(":") || trimmed.endsWith(">")) { if (trimmed.endsWith("{") || trimmed.endsWith("[") || trimmed.endsWith("(") || trimmed.endsWith(":") || trimmed.endsWith(">")) {
indent += " " indent += " "
} }
// Если курсор в начале строки с } (line пуста и next === }), то вставляем indent + "\n" перед }, а не "\n" + indent
if (line.length === 0 && pos < text.length) {
const next = text[pos]
if (next === "}" || next === "]" || next === ")") {
const ins2 = indent + "\n"
insert(pos, ins2)
cursorPosition = pos + indent.length
if (documentManager.activeIndex >=0) documentManager.updateContent(documentManager.activeIndex, text)
return
}
}
let extra = "" let extra = ""
if (pos < text.length) { if (pos < text.length) {
const next = text[pos] const next = text[pos]
if (next === "}" || next === "]" || next === ")") { if ((next === "}" || next === "]" || next === ")") && line.length > 0) {
extra = "\n" + indent.substring(0, Math.max(0, indent.length-4)) extra = "\n" + indent.substring(0, Math.max(0, indent.length-4))
} }
} }