From 3de27dac4fefebda1b7bb9ea4f42830fc47939ed Mon Sep 17 00:00:00 2001 From: svk Date: Thu, 29 Jan 2026 14:22:55 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83=20=D1=81=D0=BE=20?= =?UTF-8?q?=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=BE=D0=BC=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B8=D0=B7=20?= =?UTF-8?q?=D0=B2=D1=81=D0=BF=D0=BB=D1=8B=D0=B2=D0=B0=D1=8E=D1=89=D0=B5?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=BE=D0=BA=D0=BD=D0=B0.=20=D0=A2=D0=B5=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D1=8C=20=D1=82=D0=B0=D0=BC=20=D0=BC=D0=BE=D0=B6?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=B2=D1=8B=D0=B1=D1=80=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?=D0=B8=D0=B7=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=B5=D0=BB=D0=BA=D0=B0=D0=BC=D0=B8=20=D0=B8=20?= =?UTF-8?q?=D0=B2=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D0=BF=D0=BE?= =?UTF-8?q?=20Enter.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/editor.tcl | 76 ++++++++++++++++++++++++++++++++++++++++++++++---- lib/helper.tcl | 46 +++++++++++++++--------------- 2 files changed, 94 insertions(+), 28 deletions(-) diff --git a/lib/editor.tcl b/lib/editor.tcl index 9326f6d..ff85af6 100644 --- a/lib/editor.tcl +++ b/lib/editor.tcl @@ -16,7 +16,7 @@ namespace eval Editor { $node.frmText.t configure -$optionName $value } } - + # Comment one string or selected string proc Comment {txt fileType} { global lexers cfgVariables @@ -404,7 +404,14 @@ namespace eval Editor { } proc ReleaseKey {k txt fileType} { - global cfgVariables lexers + global cfgVariables lexers returnProcessed + # Если Return уже обработан в SelectFromList, пропускаем + # puts "$returnProcessed $k" + if {$k eq "Return" && [info exists returnProcessed]} { + unset returnProcessed + return + } + # set pos [$txt index insert] set lineNum [lindex [split $pos "."] 0] set posNum [lindex [split $pos "."] 1] @@ -508,10 +515,68 @@ namespace eval Editor { if {$cfgVariables(variableHelper) eq "true"} { if {[dict exists $lexers $fileType variableSymbol] != 0} { set varSymbol [dict get $lexers $fileType variableSymbol] - set lastSymbol [string last $varSymbol [$txt get $lineNum.0 $pos]] + set lineText [$txt get $lineNum.0 $pos] + # # Ищем переменную с помощью регулярного выражения + # # Паттерн ищет $ за которым идет имя переменной И курсор сразу после имени + # if {[regexp "(\\$)(\[a-zA-Z_:\]\[a-zA-Z0-9_:\]*)\$" $lineText -> symbol varName]} { + # # Проверяем, что найденный $ - это действительно начало переменной + # # (а не часть строки или другого символа) + # DebugPuts "Found variable: $symbol$varName" + # + # # Дополнительная проверка: перед $ не должно быть обратного слэша (экранирование) + # set posOfVarSymbol [string last $varSymbol $lineText] + # if {$posOfVarSymbol > 0} { + # set charBefore [string index $lineText [expr {$posOfVarSymbol - 1}]] + # if {$charBefore eq "\\"} { + # DebugPuts "Dollar sign is escaped, skipping" + # return + # } + # } + # Helper::VarHelper $box_x $box_y $txt $varName vars + # } + DebugPuts "Line text: '$lineText'" + + # Проверяем, есть ли $ в строке + set lastSymbol [string last $varSymbol $lineText] if {$lastSymbol ne "-1"} { - set word [string trim [$txt get $lineNum.[expr $lastSymbol + 1] $pos]] - Helper::VarHelper $box_x $box_y $txt $word vars + # Проверяем экранирование + if {$lastSymbol > 0} { + set charBefore [string index $lineText [expr {$lastSymbol - 1}]] + if {$charBefore eq "\\"} { + DebugPuts "Dollar sign is escaped, skipping" + return + } + } + # Берем текст после $ + set afterDollar [string range $lineText [expr {$lastSymbol + 1}] end] + DebugPuts "Text after $varSymbol: '$afterDollar'" + # Если после $ ничего нет (только что ввели $) - показываем все переменные + if {$afterDollar eq ""} { + DebugPuts "Just typed $varSymbol, showing all variables" + Helper::VarHelper $box_x $box_y $txt "" vars + return + } + # Проверяем, что введено после $ + if {[regexp {^([a-zA-Z_:][a-zA-Z0-9_:]*)?$} $afterDollar -> varName]} { + # Вариант 1: regexp с концом строки - курсор сразу после (возможного) имени + DebugPuts "Cursor after variable name (or $varSymbol only): '$varName'" + Helper::VarHelper $box_x $box_y $txt $varName vars + } elseif {[regexp {^([a-zA-Z_:][a-zA-Z0-9_:]*)} $afterDollar -> varName]} { + # Вариант 2: есть имя переменной, но курсор не обязательно сразу после + DebugPuts "Found variable name: '$varName'" + # Проверяем позицию курсора + set varEndPos [expr {[string length $varName] + 1}] ; # +1 для $ + + if {$varEndPos == [string length $lineText]} { + # Курсор сразу после имени + Helper::VarHelper $box_x $box_y $txt $varName vars + } else { + DebugPuts "Cursor not immediately after variable name, skipping" + } + } else { + # После $ что-то недопустимое (например, цифра, скобка и т.д.) + DebugPuts "Invalid characters after $varSymbol" + } } } else { set ind [$txt search -backwards -regexp {\W} $pos {insert linestart}] @@ -523,6 +588,7 @@ namespace eval Editor { # set ind [$txt search -backwards -regexp {^} $pos {insert linestart}] set word [$txt get {insert linestart} $pos] } + DebugPuts "> Extracted word: '$word'" if {$word ne ""} { Helper::VarHelper $box_x $box_y $txt $word {} } diff --git a/lib/helper.tcl b/lib/helper.tcl index 8dd03e1..b78e084 100644 --- a/lib/helper.tcl +++ b/lib/helper.tcl @@ -4,7 +4,7 @@ namespace eval Helper { variable ::listActive 0 # Переменная для отслеживания предыдущего ввода (чтобы не обновлять список без необходимости) variable ::previousInput "" - + proc VarHelperKey { widget K A } { set win .varhelper DebugPuts "Helper::VarHelperKey: K=$K, A='$A'" @@ -16,7 +16,7 @@ namespace eval Helper { set ::listActive 0 return } - + switch -- $K { { DebugPuts "Processing Up arrow" @@ -275,7 +275,7 @@ namespace eval Helper { } return } - + # Восстанавливаем оригинальные привязки foreach binding $::originalBindings { set event [lindex $binding 0] @@ -288,49 +288,49 @@ namespace eval Helper { bind $txt $event $command } } - + # Очищаем сохраненные привязки set ::originalBindings {} } proc SelectFromList {txt} { + global returnProcessed editors lexers set win .varhelper - - DebugPuts "SelectFromList called" + puts "[dict get $editors $txt fileType]" + puts "[dict get $lexers [dict get $editors $txt fileType] variableSymbol]" if {![winfo exists $win]} { - DebugPuts "Window doesn't exist" return } - - # Получаем выбранный элемент set selected [$win.lBox curselection] - DebugPuts "Selected index: $selected" - if {$selected ne ""} { - set text [$win.lBox get $selected] - DebugPuts "Selected text: $text" - - # Вставляем выбранный текст в текстовое поле - $txt delete "insert - 1 chars wordstart" "insert wordend - 1 chars" - $txt insert "insert" $text - - # Закрываем окно списка + set text [string trim [$win.lBox get $selected]] + set varSymbol [dict get $lexers [dict get $editors $txt fileType] variableSymbol] + # Опеределяем что символ перед позицией вставки равен символу переменной из настроек lexers + # если равен то вставляем выбранное из списка сразу за ним + # если нет то удаляем введенный текст до этого символа и вставляем выбранное из списка + if {[$txt get "insert - 1 char" "insert"] eq $varSymbol} { + $txt insert "insert" $text + } else { + $txt delete "insert - 1 chars wordstart" "insert wordend - 1 chars" + $txt insert "insert" $text + } + # Закрываем окно destroy $win set ::listActive 0 Helper::VarHelperBindingsRestore $txt set ::previousInput "" + + # Устанавливаем флаг, что Return уже обработан + set returnProcessed 1 + # after 10 {catch {unset returnProcessed}} - # Возвращаем фокус focus $txt.t } } - proc DebugPuts {msg} { puts "DEBUG: $msg" } } - -