summaryrefslogtreecommitdiff
path: root/lib/editor
diff options
context:
space:
mode:
Diffstat (limited to 'lib/editor')
-rw-r--r--[-rwxr-xr-x]lib/editor/ASMsyntaxhighlight.tcl302
-rw-r--r--[-rwxr-xr-x]lib/editor/Csyntaxhighlight.tcl145
-rw-r--r--[-rwxr-xr-x]lib/editor/LSTsyntaxhighlight.tcl87
-rw-r--r--[-rwxr-xr-x]lib/editor/R_ASMsyntaxhighlight.tcl157
-rw-r--r--[-rwxr-xr-x]lib/editor/autocompletion.tcl135
-rw-r--r--[-rwxr-xr-x]lib/editor/commandline.tcl119
-rw-r--r--[-rwxr-xr-x]lib/editor/editor.tcl652
-rw-r--r--[-rwxr-xr-x]lib/editor/eventhandlers.tcl166
-rw-r--r--[-rwxr-xr-x]lib/editor/exports.tcl159
-rw-r--r--[-rwxr-xr-x]lib/editor/generalproc.tcl539
-rw-r--r--lib/editor/spell_check.tcl1325
11 files changed, 2896 insertions, 890 deletions
diff --git a/lib/editor/ASMsyntaxhighlight.tcl b/lib/editor/ASMsyntaxhighlight.tcl
index fe364d5..1486201 100755..100644
--- a/lib/editor/ASMsyntaxhighlight.tcl
+++ b/lib/editor/ASMsyntaxhighlight.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _ASMSYNTAXHIGHLIGHT_TCL ] } {
+set _ASMSYNTAXHIGHLIGHT_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements syntax highlighting interface for assembly language
@@ -31,7 +36,7 @@ namespace eval ASMsyntaxHighlight {
# {
# {tag_name ?foreground? ?overstrike? ?italic? ?bold?}
# }
- variable hightlight_tags {
+ variable highlight_tags {
{tag_char #880066 0 0 0}
{tag_hex #8800BB 0 0 0}
{tag_oct #880000 0 0 0}
@@ -94,9 +99,9 @@ namespace eval ASMsyntaxHighlight {
# directives with argument(s) but without any label
variable directive_type1 {
- DSEG ISEG BSEG XSEG CSEG SKIP NAME
+ DSEG ISEG BSEG XSEG CSEG SKIP NAME LOCAL
}
- # directives for constants definitions
+ # directives for symbol definitions
variable directive_type2 {
EQU BIT SET CODE DATA IDATA XDATA MACRO FLAG
}
@@ -115,7 +120,7 @@ namespace eval ASMsyntaxHighlight {
variable expr_symbols {
= + - * / > < %
}
-
+
# control sequencies without any argument
variable controls_type0 {
NOLIST NOMOD NOOBJECT NOPAGING NOPRINT
@@ -185,26 +190,22 @@ namespace eval ASMsyntaxHighlight {
variable validation_L1 1 ;# Bool: Advancet validation enabled
## Define highlighting text tags in the given text widget
- # @parm Widget - ID of the target text widget
- # @parm Int - font size
- # @parm String - font family
- # @parm List = default - Highlighting tags definition
+ # @parm Widget text_widget - ID of the target text widget
+ # @parm Int fontSize - font size
+ # @parm String fontFamily - font family
+ # @parm List highlight=default - Highlighting tags definition
+ # @parm Bool nobold=0 - Ignore bold flag
# @return void
- proc create_tags args {
- variable hightlight_tags ;# Highlight tags definition
+ proc create_tags {text_widget fontSize fontFamily {highlight {}} {nobold 0}} {
+ variable highlight_tags ;# Highlight tags definition
# Handle arguments
- set text_widget [lindex $args 0] ;# text widget
- set fontSize [lindex $args 1] ;# font size
- set fontFamily [lindex $args 2] ;# font family
- if {[llength $args] > 3} { ;# highlighting definition
- set hightlight [lindex $args 3]
- } {
- set hightlight $hightlight_tags
+ if {$highlight == {}} { ;# highlighting definition
+ set highlight $highlight_tags
}
# Iterate over highlighting tags definition
- foreach item $hightlight {
+ foreach item $highlight {
# Create array of tag attributes
for {set i 0} {$i < 5} {incr i} {
set tag($i) [lindex $item $i]
@@ -217,13 +218,13 @@ namespace eval ASMsyntaxHighlight {
# Fonr slant
if {$tag(3) == 1} {
set tag(3) italic
- } {
+ } else {
set tag(3) roman
}
# Font weight
- if {$tag(4) == 1} {
+ if {$tag(4) == 1 && !$nobold} {
set tag(4) bold
- } {
+ } else {
set tag(4) normal
}
@@ -253,13 +254,13 @@ namespace eval ASMsyntaxHighlight {
}
## Perform syntax highlight on the given line in the given widget
- # @parm Widget Editor - Text widget
- # @parm Int LineNumber - Number of line to highlight
- # @parm Bool inline_asm - Inline assembler
- # @parm Int boundary_0 = 0 - Start index
- # @parm Int boundary_1 = end - End index
+ # @parm Widget p_editor - Text widget
+ # @parm Int linenumber - Number of line to highlight
+ # @parm Bool inlineasm - Inline assembler
+ # @parm Int linestart=0 - Start index
+ # @parm Int lineend=end - End index
# @return Bool - result
- proc highlight args {
+ proc highlight {p_editor linenumber {inlineasm 0} {linestart {}} {lineend {}}} {
variable editor ;# ID of the text widget
variable lineNumber ;# Number of current line
variable lineStart ;# Index of line start
@@ -282,27 +283,22 @@ namespace eval ASMsyntaxHighlight {
variable validation_L0 ;# Bool: Basic validation enabled
# Parse input arguments
- set editor [lindex $args 0]
- set lineNumber [lindex $args 1]
- set inline_asm [lindex $args 2]
- set lineStart [lindex $args 3]
- set lineEnd [lindex $args 4]
- if {$inline_asm == {}} {
- set inline_asm 0
- }
- if {$lineStart == {}} {
+ set editor $p_editor
+ set lineNumber $linenumber
+ set inline_asm $inlineasm
+ if {$linestart == {}} {
set lineStart $lineNumber.0
- } {
- set lineStart $lineNumber.$lineStart
+ } else {
+ set lineStart $lineNumber.$linestart
}
- if {$lineEnd == {}} {
- set lineEnd [$editor index "$lineStart lineend"]
- } {
+ if {$lineend == {}} {
+ set lineEnd [$editor index [list $lineStart lineend]]
+ } else {
set lineEnd $lineNumber.$lineEnd
}
- if {[lindex $args 3] != {}} {
- set start_offset [lindex $args 3]
- } {
+ if {$linestart != {}} {
+ set start_offset $linestart
+ } else {
set start_offset 0
}
@@ -339,7 +335,7 @@ namespace eval ASMsyntaxHighlight {
if {$comment_start == 0} {
set data {}
delete_tags
- } {
+ } else {
set data [string range $data 0 [expr {$comment_start - 1}]]
regsub {\s+$} $data {} data
}
@@ -358,7 +354,13 @@ namespace eval ASMsyntaxHighlight {
}
# Determinate 1st segment of the line
- regexp {^\s*[^\s:\(]+:?} $data seg_0
+ regexp {^\s*[^\s]+:?} $data seg_0
+ if {[regexp {\w\(} $seg_0]} {
+ regsub {\(.*$} $seg_0 {} seg_0
+ }
+ if {[string last {:} $seg_0] != -1} {
+ set seg_0 [string range $seg_0 0 [string last {:} $seg_0]]
+ }
set seg_0_end [string length $seg_0]
regsub {^\s+} $seg_0 {} seg_0
@@ -415,7 +417,7 @@ namespace eval ASMsyntaxHighlight {
if {![string length $seg_2]} {
put_error_on_segment 1
}
-
+
set seg_1 [string tolower $seg_1]
if {$seg_1 == {db} || $seg_1 == {.db} || $seg_1 == {byte} || $seg_1 == {.byte}} {
parse_operands
@@ -423,7 +425,7 @@ namespace eval ASMsyntaxHighlight {
$editor tag add tag_string \
$lineNumber.$seg_2_start \
[list $lineNumber.0 lineend]
- } {
+ } else {
parse_expressions
}
}
@@ -444,7 +446,7 @@ namespace eval ASMsyntaxHighlight {
if {
$validation_L0 &&
([regexp {^\d} $seg_1] || ![regexp {^\w+$} $seg_1])
- } {
+ } then {
put_error_on_segment 1
}
determinate_segment_2
@@ -464,7 +466,7 @@ namespace eval ASMsyntaxHighlight {
if {![string length $seg_2]} {
put_error_on_segment 0
}
-
+
set seg_0 [string tolower $seg_0]
if {$seg_0 == {db} || $seg_0 == {.db} || $seg_0 == {byte} || $seg_0 == {.byte}} {
parse_operands
@@ -472,7 +474,7 @@ namespace eval ASMsyntaxHighlight {
$editor tag add tag_string \
$lineNumber.$seg_2_start \
[list $lineNumber.0 lineend]
- } {
+ } else {
parse_expressions
}
}
@@ -494,6 +496,7 @@ namespace eval ASMsyntaxHighlight {
{unknown} {
determinate_segment_1
set seg_1_info [parse_segment $seg_1_start $seg_1_end $seg_1]
+
switch -- [lindex $seg_1_info 0] {
{control_0} {
determinate_segment_2
@@ -521,7 +524,7 @@ namespace eval ASMsyntaxHighlight {
$editor tag add tag_string \
$lineNumber.$seg_2_start \
[list $lineNumber.0 lineend]
- } {
+ } else {
parse_expressions
}
}
@@ -529,7 +532,7 @@ namespace eval ASMsyntaxHighlight {
if {
$validation_L0 &&
([regexp {^\d} $seg_0] || ![regexp {^\w+$} $seg_0])
- } {
+ } then {
put_error_on_segment 0
}
@@ -540,7 +543,7 @@ namespace eval ASMsyntaxHighlight {
$lineNumber.$seg_0_end
determinate_segment_2
parse_arguments
- } {
+ } else {
$editor tag add tag_constant_def \
$lineNumber.$seg_0_start \
$lineNumber.$seg_0_end
@@ -561,11 +564,12 @@ namespace eval ASMsyntaxHighlight {
}
{unknown} {
$editor tag add tag_macro $lineNumber.$seg_0_start $lineNumber.$seg_0_end
+
if {
$validation_L0 &&
([regexp {^\d} $seg_0] || ![regexp {^\w+$} $seg_0])
- } {
- put_error_on_segment 0
+ } then {
+ put_error_on_segment 0
}
determinate_segment_1_take_back
determinate_segment_2
@@ -576,7 +580,7 @@ namespace eval ASMsyntaxHighlight {
if {
$validation_L0 &&
([regexp {^\d} $seg_0] || ![regexp {^\w+$} $seg_0])
- } {
+ } then {
put_error_on_segment 0
}
}
@@ -592,7 +596,7 @@ namespace eval ASMsyntaxHighlight {
# @return void
proc delete_tags {} {
variable editor ;# ID of the text widget
- variable hightlight_tags ;# Highlight tags definition
+ variable highlight_tags ;# Highlight tags definition
variable lineStart ;# Index of line start
variable lineEnd ;# Index of line end
@@ -603,8 +607,8 @@ namespace eval ASMsyntaxHighlight {
$editor tag remove $tag $lineStart_truestart $lineStart_truestart+1l
}
- # Remove tags acording to pattern
- foreach tag $hightlight_tags {
+ # Remove tags according to pattern
+ foreach tag $highlight_tags {
$editor tag remove [lindex $tag 0] $lineStart_truestart $lineEnd
}
}
@@ -633,13 +637,14 @@ namespace eval ASMsyntaxHighlight {
variable last_index_backup ;# Auxiliary variable (some index)
# Line is empty
- if {![regexp {^\s*[^\s\(]+} $data seg_1]} {
+ # if {![regexp {^\s*[^\s\(]+} $data seg_1]}
+ if {![regexp {^\s*[^\s]+} $data seg_1]} {
set seg_1 {}
set seg_1_end $last_index
set seg_1_start $last_index
# Line is not empty
- } {
+ } else {
set data_backup $data
set last_index_backup $last_index
@@ -692,16 +697,17 @@ namespace eval ASMsyntaxHighlight {
# @parm String segment_data - content of segment to parse
# @return List - {segment_type expression_length} or {segment_type {}} or {{} {}}
proc parse_segment {start end segment_data} {
- variable controls_type0 ;# control sequencies without any argument
- variable controls_type1 ;# control sequencies with exactly 1 argument
+ variable controls_type0 ;# control sequencies without any argument
+ variable controls_type1 ;# control sequencies with exactly 1 argument
- variable keyword_lists ;# list of all reserved keywords
- variable editor ;# ID of the text widget
- variable lineNumber ;# Number of current line
- variable lineStart ;# Index of line start
- variable lineEnd ;# Index of line end
- variable data ;# Content of the line
- variable validation_L0 ;# Bool: Basic validation enabled
+ variable keyword_lists ;# list of all reserved keywords
+ variable editor ;# ID of the text widget
+ variable lineNumber ;# Number of current line
+ variable lineStart ;# Index of line start
+ variable lineEnd ;# Index of line end
+ variable data ;# Content of the line
+ variable validation_L0 ;# Bool: Basic validation enabled
+ variable inline_asm ;# Bool: Is inline assembler
# Local variables
set seg_type {} ;# segment type
@@ -729,7 +735,7 @@ namespace eval ASMsyntaxHighlight {
set seg_type $type
break
}
- } {
+ } else {
if {[lsearch -ascii -exact $keyword_list $segment_data] != -1} {
$editor tag add $tag $lineNumber.$start $lineNumber.$end
set seg_type $type
@@ -740,7 +746,6 @@ namespace eval ASMsyntaxHighlight {
# If segment type could not be recognized -> check for labels, macro's and controls
if {$seg_type == {}} {
-
# Handle compiler control sequences
if {[string index $segment_data 0] == {$}} {
set segment_data [string range $segment_data 1 end]
@@ -789,12 +794,22 @@ namespace eval ASMsyntaxHighlight {
}
# Labels
- } elseif {[regexp -nocase {^\w+:$} $segment_data]} {
+ } elseif {[regexp -nocase {^[^\s]*:$} $segment_data]} {
$editor tag add tag_label $lineNumber.$start $lineNumber.$end
set seg_type label
+ if {$inline_asm} {
+ if {![regexp -nocase {^\w+\$:$} $segment_data]} {
+ $editor tag add tag_error $lineNumber.$start $lineNumber.$end
+ }
+ } else {
+ if {![regexp -nocase {^[a-zA-Z]\w*:$} $segment_data]} {
+ $editor tag add tag_error $lineNumber.$start $lineNumber.$end
+ }
+ }
+
# Unknown type - possibly macro instruction
- } {
+ } else {
set seg_type unknown
}
}
@@ -817,9 +832,9 @@ namespace eval ASMsyntaxHighlight {
$editor tag add tag_symbol $lineNumber.$start_index $lineNumber.[expr {$start_index + 1}]
set end [expr {$end_index - 1}]
$editor tag add tag_symbol $lineNumber.$end $lineNumber.$end_index
-
+
$editor tag add tag_string $lineNumber.[expr {$start_index + 1}] $lineNumber.$end
- } {
+ } else {
if {$validation_L0} {
$editor tag add tag_error \
$lineNumber.$control_start $lineNumber.$control_end
@@ -840,7 +855,7 @@ namespace eval ASMsyntaxHighlight {
variable seg_0_end ;# End index of seg_0
variable seg_1_end ;# End index of seg_1
variable seg_2_end ;# End index of seg_2
-
+
if {!$validation_L0} {
return
}
@@ -876,9 +891,9 @@ namespace eval ASMsyntaxHighlight {
if {[regexp {^\s*$} $seg_2]} {return 0}
- while 1 {
+ while {1} {
# Handle redutant commas
- while 1 {
+ while {1} {
if {![regexp {^\s*\,} $seg_2]} {break}
set space_len 0
@@ -964,9 +979,9 @@ namespace eval ASMsyntaxHighlight {
set original_data $seg_2
set data [hide_strings $seg_2]
- while 1 {
+ while {1} {
# Handle redutant commas
- while 1 {
+ while {1} {
if {![regexp {^\s*\,} $data]} {break}
set space_len 0
@@ -1003,7 +1018,7 @@ namespace eval ASMsyntaxHighlight {
set space_len [string length $space]
set opr_start [expr {$last_index + $space_len}]
set operand [string range $operand $space_len end]
- } {
+ } else {
set opr_start $last_index
}
@@ -1012,7 +1027,7 @@ namespace eval ASMsyntaxHighlight {
set space_len [string length $space]
set opr_end [expr {$operand_len - $space_len}]
set operand [string range $operand 0 $opr_end]
- } {
+ } else {
set opr_end $operand_len
}
incr opr_end $last_index
@@ -1058,7 +1073,7 @@ namespace eval ASMsyntaxHighlight {
default {
if {[lsearch -ascii -exact {R0 R1 R2 R3 R4 R5 R6 R7 DPTR A AB C} $opr] != -1} {
lappend opr_types $opr
- } {
+ } else {
lappend opr_types {D}
}
}
@@ -1091,14 +1106,14 @@ namespace eval ASMsyntaxHighlight {
if {$validation_L0 && $len < 3} {
put_tag_on_operand tag_error
}
- if {$len > 3} {
+ if {$len > 3 && [string index $operand 1] != "\\"} {
put_tag_on_operand tag_string
- } {
+ } else {
put_tag_on_operand tag_imm_char
}
# Label in inline assembler
- } elseif {[regexp {^\d+\$$} $operand]} {
+ } elseif {[regexp {^\w+\$$} $operand]} {
put_tag_on_operand tag_imm_constant
# Operand has no value => incorrect operand
@@ -1108,10 +1123,10 @@ namespace eval ASMsyntaxHighlight {
$lineNumber.$opr_start $lineNumber.$opr_start+1c
} elseif {
- $validation_L0 &&
- ([string length $operand] == 0 || ![regexp {^[\w\$\.\\]+$} $operand])
- } {
- put_tag_on_operand tag_error
+ $validation_L0 &&
+ ([string length $operand] == 0 || ![regexp {^(\?\?)?[\w\$\.\\]+$} $operand])
+ } then {
+ put_tag_on_operand tag_error
# Operand value determinated successfully
} else {
@@ -1136,7 +1151,7 @@ namespace eval ASMsyntaxHighlight {
$operand != {DPTR} &&
$operand != {A+PC} &&
$operand != {A+DPTR}
- } {
+ } then {
put_tag_on_operand tag_error
}
@@ -1150,12 +1165,11 @@ namespace eval ASMsyntaxHighlight {
$lineNumber.$opr_start $lineNumber.$opr_start+1c
} elseif {
- $validation_L0 &&
- ([string length $operand] == 0 || ![regexp {^'?[\w\.]+'?$} $operand])
- } {
-
- # Operand has no value => incorrect operand
- put_tag_on_operand tag_error
+ $validation_L0 &&
+ ([string length $operand] == 0 || ![regexp {^'?[\w\.]+'?$} $operand])
+ } then {
+ # Operand has no value => incorrect operand
+ put_tag_on_operand tag_error
} else {
parse_operand_auxiliary $spec_bits {
@@ -1187,7 +1201,7 @@ namespace eval ASMsyntaxHighlight {
put_tag_on_operand tag_sfr
# Something else than SFR
- } {
+ } else {
parse_operand_auxiliary2 $tag_list
}
}
@@ -1206,9 +1220,9 @@ namespace eval ASMsyntaxHighlight {
variable inline_asm ;# Is inline assembler
# Label in inline assembler
- if {$inline_asm && [regexp {^\d+\$$} $operand]} {
+ if {$inline_asm && [regexp {^\w+\$$} $operand]} {
put_tag_on_operand [lindex $tag_list 6]
-
+
# Expression
} elseif {[regexp {\(|\)|\+|\-|\%|\=|\>|\<|\*|\/} $operand]} {
parse_expression $operand $opr_start $opr_end
@@ -1248,14 +1262,14 @@ namespace eval ASMsyntaxHighlight {
}
# Radix determinated correctly - continue normaly
- } {
+ } else {
# check for allowed operand value range
if {$validation_L0 && $opr_in_dec == {error}} {
## Operand value is invalid => incorrect operand
put_tag_on_operand tag_error
- } {
+ } else {
if {$validation_L0 && ($opr_in_dec > 65535 || $opr_in_dec < 0)} {
## Operand value is out of range => incorrect operand
@@ -1263,7 +1277,7 @@ namespace eval ASMsyntaxHighlight {
}
}
- # highlight acording to numeric base
+ # highlight according to numeric base
switch -- $opr_base {
{hex} {put_tag_on_operand [lindex $tag_list 1]}
{dec} {put_tag_on_operand [lindex $tag_list 2]}
@@ -1274,13 +1288,13 @@ namespace eval ASMsyntaxHighlight {
}
}
- # defined by a symbolic name
- } {
+ # Defined as a symbolic name
+ } else {
put_tag_on_operand [lindex $tag_list 6]
if {
- $validation_L0 && ($operand != {$}) && ![regexp {^\w+$} $operand]
- } {
- put_tag_on_operand tag_error
+ $validation_L0 && ($operand != {$}) && ![regexp {^(\?\?)?\w+$} $operand]
+ } then {
+ put_tag_on_operand tag_error
}
}
}
@@ -1302,6 +1316,18 @@ namespace eval ASMsyntaxHighlight {
# @parm String number - number to analyze
# @return List - {base decimal_value} or {base "error"}
proc which_radix {norange number} {
+ # Handle prefix notation for hexadecimal numbers, like 0xfa
+ if {
+ [string index $number 0] == {0}
+ &&
+ ([string index $number 1] == {x} || [string index $number 1] == {X})
+ &&
+ [string is xdigit [string index $number 2]]
+ } then {
+ set number [string replace $number 0 1]
+ append number {h}
+ }
+
set original_len [string length $number]
set len [string length [string trimleft $number {0}]]
if {$original_len > 1 && $len == 1} {
@@ -1318,12 +1344,12 @@ namespace eval ASMsyntaxHighlight {
if {[string index $number 0] == {'}} {
set number [string range $number 1 end]
- set base ascii
- if {[string length $number] == 1} {
+ set base {ascii}
+ if {[string length $number] == 1 || [string index $number 0] == "\\"} {
set dec_val 0
} elseif {[string length $number] > 1} {
- set base string
+ set base {string}
set dec_val 0
}
}
@@ -1358,7 +1384,7 @@ namespace eval ASMsyntaxHighlight {
if {[regexp {^[0-7]*$} $number]} {
if {$len != 3} {
set dec_val 0
- } {
+ } else {
if {[string index $number 0] <= 3} {
set dec_val 0
}
@@ -1376,7 +1402,7 @@ namespace eval ASMsyntaxHighlight {
if {[regexp {^[0-7]*$} $number]} {
if {$len != 3} {
set dec_val 0
- } {
+ } else {
if {[string index $number 0] <= 3} {
set dec_val 0
}
@@ -1399,7 +1425,7 @@ namespace eval ASMsyntaxHighlight {
}
# done ...
- return "$base $dec_val"
+ return [list $base $dec_val]
}
## Highlight expressions (eg. '( 10d - X MOD 55h)')
@@ -1426,7 +1452,7 @@ namespace eval ASMsyntaxHighlight {
# Remove strings
set e_idx 0
- while 1 {
+ while {1} {
if {![regexp -start $e_idx -- {'[^']*'} $data string_data]} {
break
}
@@ -1443,28 +1469,28 @@ namespace eval ASMsyntaxHighlight {
}
# remove and highlight '('
- set opended_par 0
- while 1 {
+ set opened_par 0
+ while {1} {
set symbol_idx [string first {(} $data]
if {$symbol_idx == -1} {break}
- incr opended_par
+ incr opened_par
set data [string replace $data $symbol_idx $symbol_idx { }]
incr symbol_idx $start_index
$editor tag add tag_symbol $lineNumber.$symbol_idx $lineNumber.[expr {$symbol_idx + 1}]
}
# remove and highlight ')'
- while 1 {
+ while {1} {
set symbol_idx [string first {)} $data]
if {$symbol_idx == -1} {break}
- incr opended_par -1
+ incr opened_par -1
set data [string replace $data $symbol_idx $symbol_idx { }]
incr symbol_idx $start_index
$editor tag add tag_symbol $lineNumber.$symbol_idx $lineNumber.[expr {$symbol_idx + 1}]
}
# chcek if parenthesies are balanced
- if {$validation_L0 && $opended_par != 0} {
+ if {$validation_L0 && $opened_par != 0} {
$editor tag add tag_error $lineNumber.$start_index $lineNumber.$end_index
}
@@ -1473,7 +1499,7 @@ namespace eval ASMsyntaxHighlight {
regsub -all {\t} $adjusted_data { } adjusted_data
append adjusted_data { }
foreach symbol $expr_instructions {
- while 1 {
+ while {1} {
set symbol_idx [string first " $symbol " $adjusted_data]
if {$symbol_idx == -1} {break}
set original_symbol_idx $symbol_idx
@@ -1500,7 +1526,7 @@ namespace eval ASMsyntaxHighlight {
$editor tag add tag_error \
$lineNumber.[expr {$symbol_idx + 1}] \
$lineNumber.$symbol_end_index
- } {
+ } else {
foreach smb $expr_instructions {
if {![string first $smb $tmp]} {
$editor tag add tag_error \
@@ -1515,7 +1541,7 @@ namespace eval ASMsyntaxHighlight {
}
# Highlight expression symbols (1 char) and remove them from the string
foreach symbol $expr_symbols {
- while 1 {
+ while {1} {
set symbol_idx [string first $symbol $data]
if {$symbol_idx == -1} {break}
set original_symbol_idx $symbol_idx
@@ -1530,9 +1556,9 @@ namespace eval ASMsyntaxHighlight {
$validation_L0 && (
!$original_symbol_idx
||
- ![regexp {^\s*((\'\\?[^']\')|\w|\$)} [string range $data $symbol_idx_org_1 end]]
+ ![regexp {^\s*((\'\\?[^']+\')|\w|\$)} [string range $data $symbol_idx_org_1 end]]
)
- } {
+ } then {
$editor tag add tag_error \
$lineNumber.$symbol_idx \
$lineNumber.$symbol_idx_1
@@ -1544,7 +1570,7 @@ namespace eval ASMsyntaxHighlight {
set last_index $start_index
set original_data $data
set data [hide_strings $data]
- while 1 {
+ while {1} {
if {![regexp {[^\s]+} $data value]} {break}
@@ -1595,11 +1621,11 @@ namespace eval ASMsyntaxHighlight {
} elseif {[regexp {^(\d|')} $data]} {
# Gain information about the value
- set opr_info [which_radix 1 $data]
+ set opr_info [which_radix 1 [$editor get $lineNumber.$start_index $lineNumber.$end_index]]
set opr_base [lindex $opr_info 0]
set opr_in_dec [lindex $opr_info 1]
- # Highlight value acording to info
+ # Highlight value according to info
if {$opr_base == {}} {
$editor tag add tag_unknown_base $lineNumber.$start_index $lineNumber.$end_index
if {$validation_L0 && ![regexp {^[0-9A-Fa-f]+$} $data]} {
@@ -1611,7 +1637,7 @@ namespace eval ASMsyntaxHighlight {
$editor tag add tag_error $lineNumber.$start_index $lineNumber.$end_index
}
- # Highlight acording to numeric base
+ # Highlight according to numeric base
switch -- $opr_base {
{hex} { ;# Hexadecimal
$editor tag add tag_hex $lineNumber.$start_index $lineNumber.$end_index
@@ -1638,11 +1664,11 @@ namespace eval ASMsyntaxHighlight {
# Constant
if {[lsearch -ascii -exact $spec_registers [string toupper $data]] != -1} {
set tag tag_sfr
- } {
+ } else {
set tag tag_constant
}
$editor tag add $tag $lineNumber.$start_index $lineNumber.$end_index
- if {$validation_L0 && ![regexp {^((\w+)|\$)$} $data]} {
+ if {$validation_L0 && ![regexp {^(((\?\?)?\w+)|\$)$} $data]} {
$editor tag add tag_error $lineNumber.$start_index $lineNumber.$end_index
}
}
@@ -1655,7 +1681,7 @@ namespace eval ASMsyntaxHighlight {
if {[string first {'} $data] == -1} {return $data}
# Perform replacement
- while 1 {
+ while {1} {
if {![regexp {'[^']*'} $data string]} {
break
}
@@ -1673,3 +1699,7 @@ namespace eval ASMsyntaxHighlight {
foreach item ${::ASMsyntaxHighlight::all_controls} {
lappend ::ASMsyntaxHighlight::all_controls__with_dolar "\$$item"
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/Csyntaxhighlight.tcl b/lib/editor/Csyntaxhighlight.tcl
index 8bdc913..c4ecd2a 100755..100644
--- a/lib/editor/Csyntaxhighlight.tcl
+++ b/lib/editor/Csyntaxhighlight.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _CSYNTAXHIGHLIGHT_TCL ] } {
+set _CSYNTAXHIGHLIGHT_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements syntax highlighting interface for ISO C language
@@ -40,18 +45,23 @@ namespace eval CsyntaxHighlight {
#if #ifdef #ifndef
#else #elif #endif
#line #pragma #undef
+ #warning
}
# List of data type specifiers
variable data_types {
void int float double char signed unsigned
long short uchar ushort uint ulong const
export extern static mutable volatile
+
+ __data __near __xdata __far __idata __pdata __code
+ __bit __sfr __sfr16 __sfr32 __sbit __at
}
# List of C keywords
variable keywords {
auto break case _endasm while union continue
default do else enum sizeof for namespace
if goto return struct switch typedef using
+ _asm __asm __endasm
}
# List of doxygen tags -- No argument
variable doxy_tags_type0 {
@@ -69,7 +79,8 @@ namespace eval CsyntaxHighlight {
# List of doxygen tags -- Name after tag
variable doxy_tags_type2 {
@brief @ingroup @name @mainpage
- @fn @var @typedef
+ @fn @var @typedef @author
+ @authors
}
# List of HTML tags (HTML 4.0 Strict)
variable html_tags {
@@ -99,11 +110,12 @@ namespace eval CsyntaxHighlight {
# {
# {tag_name ?foreground? ?overstrike? ?italic? ?bold?}
# }
- variable hightlight_tags {
+ variable highlight_tags {
{tag_c_keyword #0000DD 0 0 1}
{tag_c_data_type #00CC00 0 0 1}
{tag_c_dec #0000FF 0 0 0}
{tag_c_hex #8800FF 0 0 0}
+ {tag_c_bin #5555AA 0 0 0}
{tag_c_oct #883300 0 0 0}
{tag_c_char #DD00DD 0 0 0}
{tag_c_float #AA00AA 0 0 0}
@@ -127,26 +139,22 @@ namespace eval CsyntaxHighlight {
}
## Define highlighting text tags in the given text widget
- # @parm Widget - ID of the target text widget
- # @parm Int - font size
- # @parm String - font family
- # @parm List = default - Highlighting tags definition
+ # @parm Widget text_widget - ID of the target text widget
+ # @parm Int fontSize - font size
+ # @parm String fontFamily - font family
+ # @parm List highlight=default - Highlighting tags definition
+ # @parm Bool nobold=0 - Ignore bold flag
# @return void
- proc create_tags args {
- variable hightlight_tags ;# Highlight tags definition
+ proc create_tags {text_widget fontSize fontFamily {highlight {}} {nobold 0}} {
+ variable highlight_tags ;# Highlight tags definition
# Handle arguments
- set text_widget [lindex $args 0] ;# text widget
- set fontSize [lindex $args 1] ;# font size
- set fontFamily [lindex $args 2] ;# font family
- if {[llength $args] > 3} { ;# highlighting definition
- set hightlight [lindex $args 3]
- } {
- set hightlight $hightlight_tags
+ if {$highlight == {}} { ;# highlighting definition
+ set highlight $highlight_tags
}
# Iterate over highlighting tags definition
- foreach item $hightlight {
+ foreach item $highlight {
# Create array of tag attributes
for {set i 0} {$i < 5} {incr i} {
set tag($i) [lindex $item $i]
@@ -159,13 +167,13 @@ namespace eval CsyntaxHighlight {
# Fonr slant
if {$tag(3) == 1} {
set tag(3) italic
- } {
+ } else {
set tag(3) roman
}
# Font weight
- if {$tag(4) == 1} {
+ if {$tag(4) == 1 && !$nobold} {
set tag(4) bold
- } {
+ } else {
set tag(4) normal
}
@@ -190,6 +198,7 @@ namespace eval CsyntaxHighlight {
tag_c_bracket tag_c_symbol tag_c_keyword
tag_c_data_type tag_c_char tag_c_dec
tag_c_oct tag_c_hex tag_c_float
+ tag_c_bin
} {
$text_widget tag raise $t tag_normal
}
@@ -245,7 +254,7 @@ namespace eval CsyntaxHighlight {
$editor tag add tag_c_preprocessor $line_start $line_end-1c
$editor tag add tag_c_symbol $line_end-1c $line_end
return 7
- } {
+ } else {
$editor tag add tag_c_preprocessor $line_start $line_end
return 1
}
@@ -274,7 +283,7 @@ namespace eval CsyntaxHighlight {
# Highlight directive argument
if {$directive == {#include}} {
set prep_tag {tag_c_prep_lib}
- } {
+ } else {
set prep_tag {tag_c_preprocessor}
}
@@ -284,7 +293,7 @@ namespace eval CsyntaxHighlight {
set cur_line_end $com_start
incr cur_line_end -1
set cur_line_end $line_number.$cur_line_end
- } {
+ } else {
set cur_line_end $line_end
}
@@ -308,14 +317,14 @@ namespace eval CsyntaxHighlight {
return $cur_status
# Inline assembler
- } elseif {[regexp {^\s*_asm\s*$} $line_content]} {
+ } elseif {[regexp {^\s*_?_asm\s*$} $line_content]} {
$editor tag add tag_c_keyword $line_start $line_end
return 5
}
}
# Split line into fields with different highlight status
- while 1 {
+ while {1} {
set incr_last_i 0
switch -- $status {
1 { ;# Normal
@@ -384,12 +393,12 @@ namespace eval CsyntaxHighlight {
}
4 { ;# String
set l_idx $last_idx_s
- while 1 {
+ while {1} {
set idx [string first "\"" $line_content $l_idx]
if {$idx < 1} {break}
if {[string index $line_content [expr {$idx - 1}]] == "\\"} {
incr l_idx
- } {
+ } else {
break
}
}
@@ -399,7 +408,7 @@ namespace eval CsyntaxHighlight {
set status 1
}
5 { ;# Inline assembler
- if {[regexp {^\s*_endasm[^\w]*} $line_content]} {
+ if {[regexp {^\s*_?_endasm[^\w]*} $line_content]} {
mode_normal 0 [string length $line_content]
return 1
}
@@ -409,10 +418,10 @@ namespace eval CsyntaxHighlight {
break
}
6 { ;# Inline assembler -- within asm block
- if {[regexp {^\s*_endasm[^\w]*} $line_content]} {
+ if {[regexp {^\s*_?_endasm[^\w]*} $line_content]} {
mode_normal 0 [string length $line_content]
return 1
- } {
+ } else {
break
}
}
@@ -437,14 +446,14 @@ namespace eval CsyntaxHighlight {
# Return final status
if {$this_line_only} {
return 1
- } {
+ } else {
return $status
}
}
## Auxiliary procedure for procedure highlight
# This procedure calls other procedures to perform syntax
- #+ highlight acording to the given highlight status
+ #+ highlight according to the given highlight status
# @parm Int status - Highlight status
# @parm Int idx0 - Start index
# @parm Int idx1 - End index
@@ -501,7 +510,7 @@ namespace eval CsyntaxHighlight {
set string [string range $line_content $idx0 [expr {$idx1 - 1}]]
# Highlight escaped characters and character between them
- while 1 {
+ while {1} {
# Search for backslash
set idx [string first "\\" $string $idx]
if {$idx == -1} {break}
@@ -545,18 +554,18 @@ namespace eval CsyntaxHighlight {
set words [split [regsub -all {>} [regsub -all {<} $string { &}] {& }]]
# Adjust HTML tags with argument(s) (they must be represented as a single word)
- set tag_opended 0
+ set tag_opened 0
set result_words {}
foreach word $words {
- if {!$tag_opended} {
+ if {!$tag_opened} {
append result_words { } ;# Insert a common space
- } {
+ } else {
append result_words "\xA0" ;# Insert NBSP
}
- if {!$tag_opended && [regexp {^<\w+$} $word]} {
- set tag_opended 1
- } elseif {$tag_opended && [string index $word end] == {>}} {
- set tag_opended 0
+ if {!$tag_opened && [regexp {^<\w+$} $word]} {
+ set tag_opened 1
+ } elseif {$tag_opened && [string index $word end] == {>}} {
+ set tag_opened 0
}
append result_words [regsub -all {[\{\}]} $word {\\&}]
}
@@ -670,7 +679,7 @@ namespace eval CsyntaxHighlight {
$editor tag add tag_c_dox_hargval \
$line_number.[expr {$idx0 + $idx + $sub_idx + $first_equ_mark}] \
$line_number.[expr {$idx0 + $idx + $sub_idx + $sub_len}]
- } {
+ } else {
set first_equ_mark $sub_len
}
@@ -727,7 +736,7 @@ namespace eval CsyntaxHighlight {
if {
$char == {(} || $char == {)} || $char == "\{" ||
$char == "\}" || $char == {[} || $char == {]}
- } {
+ } then {
$editor tag add tag_c_bracket $line_number.$j $line_number.$j+1c
# Other symbols
@@ -743,7 +752,7 @@ namespace eval CsyntaxHighlight {
{
set idx -1
foreach word $words {
- while 1 {
+ while {1} {
incr idx
set idx [string first $word $string $idx]
if {$idx == -1} {break}
@@ -765,7 +774,7 @@ namespace eval CsyntaxHighlight {
set idx -1
set len 0
set tags {}
- foreach word [split $string {   ;=,+-<>!|&*/?:%^\{\}[]()}] {
+ foreach word [split $string {   ;=,+-<>!|&*/?:%^{}[]()}] {
if {$word == {}} {continue}
incr idx
@@ -774,9 +783,11 @@ namespace eval CsyntaxHighlight {
# Char
if {![string is digit -strict [string index $word 0]]} {
- if {[regexp {^'[^']*'$} $word]} {
+ if {$word == {''}} {
+ set tags {tag_error}
+ } elseif {[regexp {^'[^']+'$} $word]} {
set tags {tag_c_char}
- } {
+ } else {
continue
}
@@ -787,10 +798,10 @@ namespace eval CsyntaxHighlight {
set tags {tag_c_dec}
} elseif {!$validation_L0 || [regexp {^0[0-7]+$} $word]} {
set tags {tag_c_oct}
- } {
+ } else {
set tags {tag_c_oct tag_error}
}
- } {
+ } else {
set tags {tag_c_dec}
}
@@ -801,12 +812,26 @@ namespace eval CsyntaxHighlight {
||
[string index $word 1] == {X}
)
- } {
- if {!$validation_L0 || [string is xdigit -strict [string range $word 2 end]]} {
- set tags {tag_c_hex}
- } {
- set tags {tag_c_hex tag_error}
- }
+ } then {
+ if {!$validation_L0 || [string is xdigit -strict [string range $word 2 end]]} {
+ set tags {tag_c_hex}
+ } else {
+ set tags {tag_c_hex tag_error}
+ }
+
+ # Bin
+ } elseif {
+ [string index $word 0] == {0} && (
+ [string index $word 1] == {b}
+ ||
+ [string index $word 1] == {B}
+ )
+ } then {
+ if {!$validation_L0 || [regexp {^[01]+$} [string range $word 2 end]]} {
+ set tags {tag_c_bin}
+ } else {
+ set tags {tag_c_bin tag_error}
+ }
# Float
} elseif {[regexp {^\d+\.\d+$} $word]} {
@@ -832,7 +857,7 @@ namespace eval CsyntaxHighlight {
# @return void
proc delete_tags {} {
variable editor ;# Widget: Editor text widget
- variable hightlight_tags ;# Highlight tags definition
+ variable highlight_tags ;# Highlight tags definition
variable line_start ;# Index of line start
variable line_end ;# Index of line end
@@ -842,12 +867,16 @@ namespace eval CsyntaxHighlight {
$editor tag remove c_lang_func $line_start $line_start+1l
$editor tag remove c_lang_var $line_start $line_start+1l
- # Remove tags acording to pattern
- foreach tag $hightlight_tags {
+ # Remove tags according to pattern
+ foreach tag $highlight_tags {
$editor tag remove [lindex $tag 0] $line_start $line_end
}
- foreach tag $::ASMsyntaxHighlight::hightlight_tags {
+ foreach tag $::ASMsyntaxHighlight::highlight_tags {
$editor tag remove [lindex $tag 0] $line_start $line_end
}
}
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/LSTsyntaxhighlight.tcl b/lib/editor/LSTsyntaxhighlight.tcl
index c108de9..62f622f 100755..100644
--- a/lib/editor/LSTsyntaxhighlight.tcl
+++ b/lib/editor/LSTsyntaxhighlight.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _LSTSYNTAXHIGHLIGHT_TCL ] } {
+set _LSTSYNTAXHIGHLIGHT_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements syntax highlighting interface for code listing
@@ -33,7 +38,7 @@ namespace eval LSTsyntaxHighlight {
# {
# {tag_name ?foreground? ?overstrike? ?italic? ?bold?}
# }
- variable hightlight_tags {
+ variable highlight_tags {
{tag_lst_number #000000 0 0 1}
{tag_lst_code #000000 0 0 1}
{tag_lst_address #000000 0 0 1}
@@ -74,26 +79,22 @@ namespace eval LSTsyntaxHighlight {
## Define highlighting text tags in the given text widget
- # @parm Widget - ID of the target text widget
- # @parm Int - font size
- # @parm String - font family
- # @parm List = default - Highlighting tags definition
+ # @parm Widget text_widget - ID of the target text widget
+ # @parm Int fontSize - font size
+ # @parm String fontFamily - font family
+ # @parm List highlight=default - Highlighting tags definition
+ # @parm Bool nobold=0 - Ignore bold flag
# @return void
- proc create_tags args {
- variable hightlight_tags ;# Highlight tags definition
+ proc create_tags {text_widget fontSize fontFamily {highlight {}} {nobold 0}} {
+ variable highlight_tags ;# Highlight tags definition
# Handle arguments
- set text_widget [lindex $args 0] ;# text widget
- set fontSize [lindex $args 1] ;# font size
- set fontFamily [lindex $args 2] ;# font family
- if {[llength $args] > 3} { ;# highlighting definition
- set hightlight [lindex $args 3]
- } {
- set hightlight $hightlight_tags
+ if {$highlight == {}} { ;# highlighting definition
+ set highlight $highlight_tags
}
# Iterate over highlighting tags definition
- foreach item $hightlight {
+ foreach item $highlight {
# Create array of tag attributes
for {set i 0} {$i < 5} {incr i} {
set tag($i) [lindex $item $i]
@@ -106,13 +107,13 @@ namespace eval LSTsyntaxHighlight {
# Fonr slant
if {$tag(3) == 1} {
set tag(3) italic
- } {
+ } else {
set tag(3) roman
}
# Font weight
- if {$tag(4) == 1} {
+ if {$tag(4) == 1 && !$nobold} {
set tag(4) bold
- } {
+ } else {
set tag(4) normal
}
@@ -152,7 +153,7 @@ namespace eval LSTsyntaxHighlight {
# Remove current highlighting tags
if {[string length [string trim $line_content]]} {
delete_tags
- } {
+ } else {
return 0
}
@@ -169,7 +170,7 @@ namespace eval LSTsyntaxHighlight {
return 1
}
}
-
+
# Search for error/warning messages
if {[regexp {^(\s+@@@@@)|^(\*\*\*\*)|^(\s+\^)} $line_content]} {
$editor tag add tag_lst_error $line_start $line_end
@@ -194,7 +195,7 @@ namespace eval LSTsyntaxHighlight {
if {${::ExternalCompiler::selected_assembler} == 3} {
set asm_start_index 19
as31_highlight 19
-|
+
# ASEM-51
} elseif {
[regexp {^\s*\d+(\:|\+)} $line_content] ||
@@ -205,7 +206,7 @@ namespace eval LSTsyntaxHighlight {
set asm_start_index 33
set idx -1
set cor 0
- while 1 {
+ while {1} {
set idx [string first "\t" $lineText [expr {$idx + 1}]]
if {$idx == -1} {break}
@@ -224,28 +225,32 @@ namespace eval LSTsyntaxHighlight {
sdcc_highlight 32
::R_ASMsyntaxHighlight::highlight $editor $line_number 1 32
return 1
-
+
# MCU 8051 IDE Assembler
} else {
set asm_start_index 31
mcu8051ide_highlight $asm_start_index
}
- # Highlight assembly code
+ # Highlight remaining assembly code
::ASMsyntaxHighlight::highlight $editor $line_number 1 $asm_start_index
+
+ # Make sure there are no ASM error tags, they don't make sense here
+ $editor tag remove tag_error $line_number.$asm_start_index $line_end
+
return 1
}
- ## Remove previously defined syntax highlighting tags
+ ## Remove previously put syntax highlighting tags
# @return void
proc delete_tags {} {
- variable hightlight_tags ;# Highlight tags definition
+ variable highlight_tags ;# Highlight tags definition
variable editor ;# Widget: Editor text widget
variable line_start ;# Index of line start
variable line_end ;# Index of line end
- # Remove tags acording to pattern
- foreach tag $hightlight_tags {
+ # Remove tags according to pattern
+ foreach tag $highlight_tags {
$editor tag remove [lindex $tag 0] $line_start $line_end
}
}
@@ -292,7 +297,7 @@ namespace eval LSTsyntaxHighlight {
variable line_content ;# String: Line content
variable line_start ;# Index of line start
variable line_end ;# Index of line end
-
+
set idx 0 ;# Regular expression match start index
set foo 0 ;# Foo :)
@@ -305,11 +310,11 @@ namespace eval LSTsyntaxHighlight {
set idx [string first $substring $line_content $idx]
$editor tag add tag_lst_line $line_number.$idx $line_number.[expr {$idx + $substr_len}]
incr idx $substr_len
- } {
+ } else {
set idx 6
set foo 1
}
-
+
# Highlight for inclusion level
if {[regexp -start $idx -- {\A[ \d]\d} $line_content substring]} {
set substr_len [string length $substring]
@@ -345,7 +350,7 @@ namespace eval LSTsyntaxHighlight {
$editor tag add tag_lst_number $line_number.$idx $line_number.[expr {$idx + $substr_len}]
incr idx $substr_len
}
-
+
# Highlight processor code
} elseif {[regexp -start $idx -- {\A\s+([[:xdigit:]]{2} )*[[:xdigit:]]{2}} $line_content substring]} {
set substr_len [string length $substring]
@@ -377,13 +382,13 @@ namespace eval LSTsyntaxHighlight {
variable line_content ;# String: Line content
variable line_start ;# Index of line start
variable line_end ;# Index of line end
-
+
set idx 0 ;# Regular expression match start index
-
+
# Alter line
set line_content [string range $line_content 0 [expr {$asm_start_index - 1}]]
-
- # Highlight processor code
+
+ # Highlight processor code
if {[regexp -start $idx -- {\A [[:xdigit:]]{2,}} $line_content substring]} {
set substr_len [string length $substring]
set idx [string first $substring $line_content $idx]
@@ -400,7 +405,7 @@ namespace eval LSTsyntaxHighlight {
set idx [string first $substring $line_content $idx]
$editor tag add tag_lst_address $line_number.$idx $line_number.[expr {$idx + $substr_len}]
incr idx $substr_len
-
+
# Highlight processor code
if {[regexp -start $idx -- {\A\s+[[:xdigit:]]{2,}} $line_content substring]} {
set substr_len [string length $substring]
@@ -417,7 +422,7 @@ namespace eval LSTsyntaxHighlight {
$editor tag add tag_lst_number $line_number.$idx $line_number.[expr {$idx + $substr_len}]
incr idx $substr_len
}
-
+
# Highlight inclusion level
if {[regexp -start $idx -- {\A\s+\=\d+} $line_content substring]} {
set substr_len [string length $substring]
@@ -441,3 +446,7 @@ namespace eval LSTsyntaxHighlight {
}
}
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/R_ASMsyntaxhighlight.tcl b/lib/editor/R_ASMsyntaxhighlight.tcl
index 2408bff..250da57 100755..100644
--- a/lib/editor/R_ASMsyntaxhighlight.tcl
+++ b/lib/editor/R_ASMsyntaxhighlight.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2008 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _R_ASMSYNTAXHIGHLIGHT_TCL ] } {
+set _R_ASMSYNTAXHIGHLIGHT_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements syntax highlighting interface for reallocable assembly
@@ -86,24 +91,20 @@ namespace eval R_ASMsyntaxHighlight {
variable validation_L1 1 ;# Bool: Advancet validation enabled
## Define highlighting text tags in the given text widget
- # @parm Widget - ID of the target text widget
- # @parm Int - font size
- # @parm String - font family
- # @parm List = default - Highlighting tags definition
+ # @parm Widget text_widget - ID of the target text widget
+ # @parm Int fontSize - font size
+ # @parm String fontFamily - font family
+ # @parm List highlight=default - Highlighting tags definition
+ # @parm Bool nobold=0 - Ignore bold flag
# @return void
- proc create_tags args {
+ proc create_tags {text_widget fontSize fontFamily {highlight {}} {nobold 0}} {
# Handle arguments
- set text_widget [lindex $args 0] ;# text widget
- set fontSize [lindex $args 1] ;# font size
- set fontFamily [lindex $args 2] ;# font family
- if {[llength $args] > 3} { ;# highlighting definition
- set hightlight [lindex $args 3]
- } {
- set hightlight $::ASMsyntaxHighlight::hightlight_tags
+ if {$highlight == {}} { ;# highlighting definition
+ set highlight $::ASMsyntaxHighlight::highlight_tags
}
# Iterate over highlighting tags definition
- foreach item $hightlight {
+ foreach item $highlight {
# Create array of tag attributes
for {set i 0} {$i < 5} {incr i} {
set tag($i) [lindex $item $i]
@@ -116,13 +117,13 @@ namespace eval R_ASMsyntaxHighlight {
# Fonr slant
if {$tag(3) == 1} {
set tag(3) italic
- } {
+ } else {
set tag(3) roman
}
# Font weight
- if {$tag(4) == 1} {
+ if {$tag(4) == 1 && !$nobold} {
set tag(4) bold
- } {
+ } else {
set tag(4) normal
}
@@ -142,13 +143,13 @@ namespace eval R_ASMsyntaxHighlight {
}
## Perform syntax highlight on the given line in the given widget
- # @parm Widget Editor - Text widget
- # @parm Int LineNumber - Number of line to highlight
- # @parm Bool inline_asm - Inline assembler
- # @parm Int boundary_0 = 0 - Start index
- # @parm Int boundary_1 = end - End index
+ # @parm Widget p_editor - Text widget
+ # @parm Int linenumber - Number of line to highlight
+ # @parm Bool inlineasm=0 - Inline assembler
+ # @parm Int linestart=0 - Start index
+ # @parm Int lineend=end - End index
# @return Bool - result
- proc highlight args {
+ proc highlight {p_editor linenumber {inlineasm 0} {linestart {}} {lineend {}}} {
variable editor ;# ID of the text widget
variable lineNumber ;# Number of current line
variable lineStart ;# Index of line start
@@ -170,27 +171,22 @@ namespace eval R_ASMsyntaxHighlight {
variable validation_L0 ;# Bool: Basic validation enabled
# Parse input arguments
- set editor [lindex $args 0]
- set lineNumber [lindex $args 1]
- set inline_asm [lindex $args 2]
- set lineStart [lindex $args 3]
- set lineEnd [lindex $args 4]
- if {$inline_asm == {}} {
- set inline_asm 0
- }
- if {$lineStart == {}} {
+ set editor $p_editor
+ set lineNumber $linenumber
+ set inline_asm $inlineasm
+ if {$linestart == {}} {
set lineStart $lineNumber.0
- } {
- set lineStart $lineNumber.$lineStart
+ } else {
+ set lineStart $lineNumber.$linestart
}
- if {$lineEnd == {}} {
+ if {$lineend == {}} {
set lineEnd [$editor index "$lineStart lineend"]
- } {
+ } else {
set lineEnd $lineNumber.$lineEnd
}
- if {[lindex $args 3] != {}} {
- set start_offset [lindex $args 3]
- } {
+ if {$linestart != {}} {
+ set start_offset $linestart
+ } else {
set start_offset 0
}
@@ -227,7 +223,7 @@ namespace eval R_ASMsyntaxHighlight {
if {$comment_start == 0} {
set data {}
delete_tags
- } {
+ } else {
set data [string range $data 0 [expr {$comment_start - 1}]]
regsub {\s+$} $data {} data
}
@@ -295,7 +291,7 @@ namespace eval R_ASMsyntaxHighlight {
if {
$validation_L0 &&
([regexp {^\d} $seg_1] || ![regexp {^\w+$} $seg_1])
- } {
+ } then {
put_error_on_segment 1
}
determinate_segment_2
@@ -314,7 +310,7 @@ namespace eval R_ASMsyntaxHighlight {
determinate_segment_2
if {[string tolower $seg_0] == {.optsdcc}} {
$editor tag add tag_string $lineNumber.$seg_0_end $lineEnd
- } {
+ } else {
parse_expressions
}
}
@@ -376,8 +372,8 @@ namespace eval R_ASMsyntaxHighlight {
# Remove tag error
$editor tag remove tag_error $lineStart_truestart $lineEnd
- # Remove tags acording to pattern
- foreach tag $::ASMsyntaxHighlight::hightlight_tags {
+ # Remove tags according to pattern
+ foreach tag $::ASMsyntaxHighlight::highlight_tags {
$editor tag remove [lindex $tag 0] $lineStart_truestart $lineEnd
}
}
@@ -412,7 +408,7 @@ namespace eval R_ASMsyntaxHighlight {
set seg_1_start $last_index
# Line is not empty
- } {
+ } else {
set data_backup $data
set last_index_backup $last_index
@@ -508,7 +504,7 @@ namespace eval R_ASMsyntaxHighlight {
} elseif {$segment_data == {=} || $segment_data == {==}} {
$editor tag add tag_symbol $lineNumber.$start $lineNumber.$end
set seg_type {assignment}
- } {
+ } else {
set seg_type {unknown}
}
}
@@ -565,9 +561,9 @@ namespace eval R_ASMsyntaxHighlight {
if {[regexp {^\s*$} $seg_2]} {return 0}
- while 1 {
+ while {1} {
# Handle redutant commas
- while 1 {
+ while {1} {
if {![regexp {^\s*\,} $seg_2]} {break}
set space_len 0
@@ -639,9 +635,9 @@ namespace eval R_ASMsyntaxHighlight {
set original_data $seg_2
set data [hide_strings $seg_2]
- while 1 {
+ while {1} {
# Handle redutant commas
- while 1 {
+ while {1} {
if {![regexp {^\s*\,} $data]} {break}
set space_len 0
@@ -672,7 +668,7 @@ namespace eval R_ASMsyntaxHighlight {
set space_len [string length $space]
set opr_start [expr {$last_index + $space_len}]
set operand [string range $operand $space_len end]
- } {
+ } else {
set opr_start $last_index
}
@@ -681,7 +677,7 @@ namespace eval R_ASMsyntaxHighlight {
set space_len [string length $space]
set opr_end [expr {$operand_len - $space_len}]
set operand [string range $operand 0 $opr_end]
- } {
+ } else {
set opr_end $operand_len
}
incr opr_end $last_index
@@ -725,7 +721,7 @@ namespace eval R_ASMsyntaxHighlight {
default {
if {[lsearch -ascii -exact {R0 R1 R2 R3 R4 R5 R6 R7 DPTR A AB C} $opr] != -1} {
lappend ::ASMsyntaxHighlight::opr_types $opr
- } {
+ } else {
lappend ::ASMsyntaxHighlight::opr_types {D}
}
}
@@ -756,7 +752,7 @@ namespace eval R_ASMsyntaxHighlight {
if {$len > 3} {
put_tag_on_operand tag_string
- } {
+ } else {
put_tag_on_operand tag_imm_char
}
@@ -773,7 +769,7 @@ namespace eval R_ASMsyntaxHighlight {
} elseif {
$validation_L0 &&
([string length $operand] == 0 || ![regexp {^[\w\.\\]+$} $operand])
- } {
+ } then {
# put_tag_on_operand tag_error
# Operand value determinated successfully
@@ -804,12 +800,11 @@ namespace eval R_ASMsyntaxHighlight {
$lineNumber.$opr_start $lineNumber.$opr_start+1c
} elseif {
- $validation_L0 &&
- ([string length $operand] == 0 || ![regexp {^'?[\w\.]+'?$} $operand])
- } {
-
- # Operand has no value => incorrect operand
-# put_tag_on_operand tag_error
+ $validation_L0 &&
+ ([string length $operand] == 0 || ![regexp {^'?[\w\.]+'?$} $operand])
+ } then {
+ # Operand has no value => incorrect operand
+# put_tag_on_operand tag_error
} else {
parse_operand_auxiliary $::ASMsyntaxHighlight::spec_bits {
@@ -841,7 +836,7 @@ namespace eval R_ASMsyntaxHighlight {
put_tag_on_operand tag_sfr
# Something else than SFR
- } {
+ } else {
parse_operand_auxiliary2 $tag_list
}
}
@@ -897,8 +892,8 @@ namespace eval R_ASMsyntaxHighlight {
put_tag_on_operand [lindex $tag_list 0]
# Radix determinated correctly - continue normaly
- } {
- # highlight acording to numeric base
+ } else {
+ # highlight according to numeric base
switch -- $opr_base {
{hex} {put_tag_on_operand [lindex $tag_list 1]}
{dec} {put_tag_on_operand [lindex $tag_list 2]}
@@ -910,7 +905,7 @@ namespace eval R_ASMsyntaxHighlight {
}
# defined by a symbolic name
- } {
+ } else {
put_tag_on_operand [lindex $tag_list 6]
}
}
@@ -996,7 +991,7 @@ namespace eval R_ASMsyntaxHighlight {
if {[regexp {^[0-7]*$} $number]} {
if {$len != 3} {
set dec_val 0
- } {
+ } else {
if {[string index $number 0] <= 3} {
set dec_val 0
}
@@ -1014,7 +1009,7 @@ namespace eval R_ASMsyntaxHighlight {
if {[regexp {^[0-7]*$} $number]} {
if {$len != 3} {
set dec_val 0
- } {
+ } else {
if {[string index $number 0] <= 3} {
set dec_val 0
}
@@ -1037,7 +1032,7 @@ namespace eval R_ASMsyntaxHighlight {
}
# done ...
- return "$base $dec_val"
+ return [list $base $dec_val]
}
## Highlight expressions (eg. '( 10d - X MOD 55h)')
@@ -1062,7 +1057,7 @@ namespace eval R_ASMsyntaxHighlight {
# Remove strings
set e_idx 0
- while 1 {
+ while {1} {
if {![regexp -start $e_idx -- {'[^']*'} $data string_data]} {
break
}
@@ -1079,22 +1074,22 @@ namespace eval R_ASMsyntaxHighlight {
}
# remove and highlight '('
- set opended_par 0
- while 1 {
+ set opened_par 0
+ while {1} {
set symbol_idx [string first {(} $data]
if {$symbol_idx == -1} {break}
- incr opended_par
+ incr opened_par
set data [string replace $data $symbol_idx $symbol_idx { }]
incr symbol_idx $start_index
$editor tag add tag_symbol $lineNumber.$symbol_idx $lineNumber.[expr {$symbol_idx + 1}]
}
# remove and highlight ')'
- while 1 {
+ while {1} {
set symbol_idx [string first {)} $data]
if {$symbol_idx == -1} {break}
- incr opended_par -1
+ incr opened_par -1
set data [string replace $data $symbol_idx $symbol_idx { }]
incr symbol_idx $start_index
$editor tag add tag_symbol $lineNumber.$symbol_idx $lineNumber.[expr {$symbol_idx + 1}]
@@ -1105,7 +1100,7 @@ namespace eval R_ASMsyntaxHighlight {
regsub {\t} $adjusted_data { } adjusted_data
# highlight expr. symbols (1 char) and remove them from the string
foreach symbol $expr_symbols {
- while 1 {
+ while {1} {
set symbol_idx [string first $symbol $data]
if {$symbol_idx == -1} {break}
set original_symbol_idx $symbol_idx
@@ -1122,7 +1117,7 @@ namespace eval R_ASMsyntaxHighlight {
set last_index $start_index
set original_data $data
set data [hide_strings $data]
- while 1 {
+ while {1} {
if {![regexp {[^\s]+} $data value]} {break}
set value_S_idx [string first $value $data]
@@ -1175,13 +1170,13 @@ namespace eval R_ASMsyntaxHighlight {
set opr_base [lindex $opr_info 0]
set opr_in_dec [lindex $opr_info 1]
- # Highlight value acording to info
+ # Highlight value according to info
if {$opr_base == {}} {
$editor tag add tag_unknown_base $lineNumber.$start_index $lineNumber.$end_index
return
}
- # Highlight acording to numeric base
+ # Highlight according to numeric base
switch -- $opr_base {
{hex} { ;# Hexadecimal
$editor tag add tag_hex $lineNumber.$start_index $lineNumber.$end_index
@@ -1217,7 +1212,7 @@ namespace eval R_ASMsyntaxHighlight {
if {[string first {'} $data] == -1} {return $data}
# Perform replacement
- while 1 {
+ while {1} {
if {![regexp {'[^']*'} $data string]} {
break
}
@@ -1230,3 +1225,7 @@ namespace eval R_ASMsyntaxHighlight {
return $data
}
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/autocompletion.tcl b/lib/editor/autocompletion.tcl
index a5c9234..04dca79 100755..100644
--- a/lib/editor/autocompletion.tcl
+++ b/lib/editor/autocompletion.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,20 +21,64 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _AUTOCOMPLETION_TCL ] } {
+set _AUTOCOMPLETION_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements autocompletion related procedures
# This file should be loaded into class Editor in file "editor.tcl"
# --------------------------------------------------------------------------
-
-## Refresh list of avaliable SFR's and SFB's on the target uC
+common invoke_com_win_in_p 0 ;# Bool: invoke_completion_popup_window in progress
+common completion_win_opened 0 ;# Bool: Editor popup-based completion window opended
+
+## Array: Strings available for autocompletion
+ # Index 0 - Labels in assembly
+ # Index 1 - Constants/variables
+ # Index 2 - C variables
+ # Index 3 - Macros
+ # Index 4 - SFR's
+ # Index 5 - Expression symbols
+ # Index 6 - Doxygen tags
+ # Index 7 - C Functions
+private variable autocompletion_list
+private variable completion_win_str_i 1.0 ;# TextIndex: String to complete - start index
+private variable completion_win_end_i 1.0 ;# TextIndex: String to complete - end index
+private variable completion_win_mode 0 ;# Int: Completion window mode
+private variable comp_win_loading_in_p 0 ;# Bool: Completion window list loading is in progress
+private variable comp_win_loading_max 1 ;# Int: Maximum for progressbar in the completion window
+private variable macl_invocations 0 ;# Int: Number of invocations of "manage_autocompletion_list"
+private variable doxytag_fg {#000000} ;# Color: Highlight color for doxygen tag
+private variable indirect_fg {#000000} ;# Color: Highlight color for indirect address
+private variable symbol_fg {#000000} ;# Color: Highlight color for asm. symbol
+private variable sfr_fg {#000000} ;# Color: Highlight color for SFR
+private variable label_fg {#000000} ;# Color: Highlight color for asm. label
+private variable macro_fg {#000000} ;# Color: Highlight color for asm. macro
+private variable const_fg {#000000} ;# Color: Highlight color for asm. const
+private variable dir_fg {#000000} ;# Color: Highlight color for asm. directive
+private variable cs_fg {#000000} ;# Color: Highlight color for constrol sequence
+private variable ins_fg {#000000} ;# Color: Highlight color for instruction
+private variable doxytag_font ${::Editor::defaultFont} ;# Font: Font for doxygen tag
+private variable indirect_font ${::Editor::defaultFont} ;# Font: Font for indirect address
+private variable symbol_font ${::Editor::defaultFont} ;# Font: Font for asm. symbol
+private variable sfr_font ${::Editor::defaultFont} ;# Font: Font for SFR
+private variable label_font ${::Editor::defaultFont} ;# Font: Font for asm. label
+private variable macro_font ${::Editor::defaultFont} ;# Font: Font for asm. macro
+private variable const_font ${::Editor::defaultFont} ;# Font: Font for asm. const
+private variable dir_font ${::Editor::defaultFont} ;# Font: Font for asm. directive
+private variable cs_font ${::Editor::defaultFont} ;# Font: Font for constrol sequence
+private variable ins_font ${::Editor::defaultFont} ;# Font: Font for instruction
+
+
+## Refresh list of available SFR's and SFB's on the target uC
# @return void
-public method refresh_avaliable_SFR {} {
- set autocompletion_list(4) [lsort -ascii [$parentObject cget -avaliable_SFR]]
+public method refresh_available_SFR {} {
+ set autocompletion_list(4) [lsort -ascii [$parentObject cget -available_SFR]]
}
-
## Clear list of words for autocompletion window
# @return void
public method clear_autocompletion_list {} {
@@ -49,14 +93,21 @@ public method clear_autocompletion_list {} {
#+ autocompletion list up to date
# @parm TextIndex start_index - Start
# @parm TextIndex end_index - End
+ # @parm Bool do_spellcheck - Perform spell check
# @return void
-public method detete_text_in_editor {start_index end_index} {
+public method detete_text_in_editor {start_index end_index {do_spellcheck 1}} {
autocompletion_maybe_important_change $start_index $end_index
+ if {$do_spellcheck} {
+ spellcheck_change_detected_pre
+ }
$editor delete $start_index $end_index
+ if {$do_spellcheck} {
+ spellcheck_change_detected_post
+ }
}
## Inform autocompletion mechanism about possibly deleted symbol
- # @parm TextIndex start_index - Begining on area to to analyze
+ # @parm TextIndex start_index - Beginning on area to to analyze
# @parm TextIndex end_index - End on area to to analyze
# @return void
public method autocompletion_maybe_important_change {start_index end_index} {
@@ -97,7 +148,7 @@ public method autocompletion_maybe_important_change {start_index end_index} {
set idx [lsearch -ascii -exact $autocompletion_list($index) $string]
if {$idx != -1} {
$parentObject rightPanel_adjust_symbol_list \
- all $string $index 0
+ all $string $index 0 $this
set autocompletion_list($index) \
[lreplace $autocompletion_list($index) $idx $idx]
@@ -135,24 +186,33 @@ private method autocompletion_c_syntax_analyze {line_number} {
set end 0
set string {}
- # Find part which consist of alfanumeric characters
- if {![regexp -start $start -- {\w+} $line string]} {
- return
+ # Find part which consist of alphanumeric characters
+ while {1} {
+ if {![regexp -start $start -- {\w+} $line string]} {
+ return
+ }
+
+ incr start
+ set end [expr {$start + [string length $string]}]
+
+ if {[string is digit [string index $string 0]]} {
+ incr start [string length $string]
+ } else {
+ break
+ }
}
- set start [string first $string $line $start]
- set end [expr {$start + [string length $string]}]
# Mark the word
if {[regexp -start $end -- {\s*\(} $line]} {
$editor tag add c_lang_func $line_number.$start $line_number.$end
- } {
+ } else {
$editor tag add c_lang_var $line_number.$start $line_number.$end
}
}
}
## Inform autocompletion mechanism about possibly newly defined symbol
- # @parm Int line_number - Line number
+ # @parm Int line_number - Line number
# @return void
public method manage_autocompletion_list {line_number} {
# Detect new symbol
@@ -184,7 +244,7 @@ public method manage_autocompletion_list {line_number} {
||
[lsearch -ascii -exact ${::CsyntaxHighlight::keywords} $string] != -1
} then {
- return
+ continue
}
}
@@ -196,9 +256,9 @@ public method manage_autocompletion_list {line_number} {
# Append to the autocompletion list
if {[lsearch -ascii -exact $autocompletion_list($index) $string] == -1} {
lappend autocompletion_list($index) $string
-
$parentObject rightPanel_adjust_symbol_list \
- $line_number $string $index 1
+ $line_number $string $index 1 $this
+ $parentObject rightPanel_sm_select $line_number
}
}
}
@@ -220,7 +280,7 @@ public method manage_autocompletion_list {line_number} {
# 2 - C functions
# 3 - Indirect values
# 4 - Doxygen tags
- # @parm String str - Incomplite instruction or directive
+ # @parm String str - Incomplete instruction or directive
# @parm Int x - Relative X position of the popup window (relative to editor)
# @parm Int y - Relative Y position of the popup window (relative to editor)
# @return void
@@ -281,13 +341,14 @@ private method invoke_completion_popup_window {mode start_idx end_idx} {
# Create lisbox and scrollbar
set frame [frame $win.frame]
- set listbox [ListBox $frame.listbox \
- -relief flat -bd 0 -selectfill 1 \
- -selectbackground {#AAAAFF} \
- -bg white -cursor left_ptr \
+ set listbox [ListBox $frame.listbox \
+ -relief flat -bd 0 -selectfill 0 \
+ -selectbackground {#AAAAFF} \
+ -bg white -cursor left_ptr \
-yscrollcommand "$frame.scrollbar set" \
- -selectmode single -width 0 -height 0 \
- -highlightthickness 0 -padx 2 \
+ -selectmode single -width 0 -height 0 \
+ -highlightthickness 0 -padx 2 \
+ -font $defaultFont_bold \
]
set completion_listbox $listbox
pack $listbox -side left -fill both -expand 1
@@ -316,7 +377,7 @@ private method invoke_completion_popup_window {mode start_idx end_idx} {
set listbox ".completion_win.frame.listbox"
$listbox selection clear
$listbox delete [$listbox items]
- update idle
+ update idletasks
if {$loading || $comp_win_loading_in_p} {
if {!($comp_win_loading_max > 1)} {
@@ -456,7 +517,7 @@ private method invoke_completion_popup_window {mode start_idx end_idx} {
}
# Control sequences
- } {
+ } else {
foreach command ${::ASMsyntaxHighlight::all_controls__with_dolar} {
set shortcmd [string range $command 0 $end]
if {$shortcmd == $str} {
@@ -615,10 +676,10 @@ public method close_completion_popup_window {} {
#+ state of this object
# @return void
proc close_completion_popup_window_NOW {} {
- if {$invoke_com_win_in_p} {return}
- set invoke_com_win_in_p 1
+ if {${::Editor::invoke_com_win_in_p}} {return}
+ set ::Editor::invoke_com_win_in_p 1
- if {$completion_win_opened} {
+ if {${::Editor::completion_win_opened}} {
catch {
grab release .completion_win
}
@@ -627,8 +688,8 @@ proc close_completion_popup_window_NOW {} {
}
}
- set completion_win_opened 0
- set invoke_com_win_in_p 0
+ set ::Editor::completion_win_opened 0
+ set ::Editor::invoke_com_win_in_p 0
}
## Auxiliary method for method "Key"
@@ -788,7 +849,7 @@ private method aux_Key_autocompletion_5 {wordstart wordend} {
## Determinate color for instructions, directives, etc.
# @return void
private method refresh_highlighting_for_autocompletion {} {
- foreach key ${::ASMsyntaxHighlight::hightlight_tags} {
+ foreach key ${::ASMsyntaxHighlight::highlight_tags} {
if {[lindex $key 0] == {tag_instruction}} {
set ins_fg [lindex $key 1]
set ins_font [$editor tag cget tag_instruction -font]
@@ -828,7 +889,7 @@ private method refresh_highlighting_for_autocompletion {} {
}
if {$prog_language == 1} {
- foreach key ${::CsyntaxHighlight::hightlight_tags} {
+ foreach key ${::CsyntaxHighlight::highlight_tags} {
if {[lindex $key 0] == {tag_c_dox_tag}} {
set doxytag_fg [lindex $key 1]
set doxytag_font [$editor tag cget tag_c_dox_tag -font]
@@ -836,3 +897,7 @@ private method refresh_highlighting_for_autocompletion {} {
}
}
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/commandline.tcl b/lib/editor/commandline.tcl
index 4fe39c3..4e15e0a 100755..100644
--- a/lib/editor/commandline.tcl
+++ b/lib/editor/commandline.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _COMMANDLINE_TCL ] } {
+set _COMMANDLINE_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements procedures related to editor command line
@@ -50,7 +55,7 @@ public method cmd_line_key {key} {
{Delete} {
if {[llength [$cmd_line tag nextrange sel 1.0]]} {
$cmd_line delete sel.first sel.last
- } {
+ } else {
if {[$cmd_line index insert] != [$cmd_line index {insert lineend}]} {
$cmd_line delete insert {insert+1c}
}
@@ -59,7 +64,7 @@ public method cmd_line_key {key} {
{BackSpace} {
if {[llength [$cmd_line tag nextrange sel 1.0]]} {
$cmd_line delete sel.first sel.last
- } {
+ } else {
if {[$cmd_line index insert] != [$cmd_line index {insert linestart}]} {
$cmd_line delete {insert-1c} insert
}
@@ -149,7 +154,7 @@ public method cmd_line_enter {} {
}
set command [cmd_line_get_possible_cmds $command]
if {$command == {}} {
- Sbar [mc "EDITOR COMMAND LINE: invalid command, type `help list' to get list of avaliable commands"]
+ Sbar [mc "EDITOR COMMAND LINE: invalid command, type `help list' to get list of available commands"]
return
} elseif {[llength $command] > 1} {
Sbar [mc "Ambiguous command"]
@@ -164,8 +169,8 @@ public method cmd_line_enter {} {
Sbar [mc "EDITOR COMMAND LINE: wrong # args (command: %s)" "char"]
}
if {![llength $args]} {
- cmd_line_help_window {Help} [mc \
- "This is MCU 8051 IDE command line\n\nusage: <b>command \[argumets\]</b>\n\nEnter <b>help list</b> for list of avaliable commands or\n<b>help <STRING command></b> for help for individual command"]
+ cmd_line_help_window [mc "Help"] [mc \
+ "This is MCU 8051 IDE command line\n\nusage: <b>command \[arguments\]</b>\n\nEnter <b>help list</b> for list of available commands or\n<b>help <STRING command></b> for help for individual command"]
return
}
set command [lindex $args 0]
@@ -179,7 +184,7 @@ public method cmd_line_enter {} {
switch -- $command {
{list} {
- cmd_line_help_window [mc "Avaliable commands"] \
+ cmd_line_help_window [mc "Available commands"] \
"<b>d2h</b> [mc {DEC -> HEX}]
<b>d2o</b> [mc {DEC -> OCT}]
<b>d2b</b> [mc {DEC -> BIN}]
@@ -199,7 +204,7 @@ public method cmd_line_enter {} {
<b>breakpoint</b> [mc {Add/Remove breakpoint}]
<b>capitalize</b> [mc {Capitalize selection}]
<b>clear</b> [mc {Clear history}]
- <b>comment</b> [mc {Comment slected text}]
+ <b>comment</b> [mc {Comment selected text}]
<b>copy</b> [mc {Copy selection}]
<b>custom</b> [mc {Custom command}]
<b>cut</b> [mc {Cut selection}]
@@ -236,11 +241,11 @@ public method cmd_line_enter {} {
}
{hibernate} {
cmd_line_help_window [mc "Command hibernate"] [mc \
- "<b>hibernate</b> \[<STRING target-file>\]\nHibernate running program (avaliliable only when simulator is stated).\n\nThis function saves current state of the simulator engine for future resumption. If no target is not specified it will invoke file selection dialog"]
+ "<b>hibernate</b> \[<STRING target-file>\]\nHibernate running program (available only when simulator is stated).\n\nThis function saves current state of the simulator engine for future resumption. If no target is not specified it will invoke file selection dialog"]
}
{resume} {
cmd_line_help_window [mc "Command resume"] [mc \
- "<b>resume</b> \[<STRING source-file>\]\nResume hibernated program (avaliliable only when simulator is stated).\n\nThis function restores previous state of the simulator engine stored in the given file. If no source is not specified it will invoke file selection dialog"]
+ "<b>resume</b> \[<STRING source-file>\]\nResume hibernated program (available only when simulator is stated).\n\nThis function restores previous state of the simulator engine stored in the given file. If no source is not specified it will invoke file selection dialog"]
}
{switch-mcu} {
cmd_line_help_window [mc "Command switch-mcu"] [mc \
@@ -248,15 +253,15 @@ public method cmd_line_enter {} {
}
{set-xcode} {
cmd_line_help_window [mc "Command set-xcode"] [mc \
- "<b>set-xcode</b> <INT size>\nChange capacity of external program memory.\nNote: this command also close CODE memory hexeditor"]
+ "<b>set-xcode</b> <INT size>\nChange capacity of external program memory.\nNote: this command also close CODE memory hex editor"]
}
{set-xdata} {
cmd_line_help_window [mc "Command set-xdata"] [mc \
- "<b>set-xdata</b> <INT size>\nChange capacity of external data memory.\nNote: this command also close XDATA memory hexeditor"]
+ "<b>set-xdata</b> <INT size>\nChange capacity of external data memory.\nNote: this command also close XDATA memory hex editor"]
}
{run} {
cmd_line_help_window [mc "Command run"] [mc \
- "Run simulation (avaliliable only when simulator is stated)"]
+ "Run simulation (available only when simulator is stated)"]
}
{exit} {
cmd_line_help_window [mc "Command exit"] [mc \
@@ -276,7 +281,7 @@ public method cmd_line_enter {} {
}
{help} {
cmd_line_help_window [mc "Command help"] [mc \
- "<b>help</b> <STRING command>\nShows help for the given command\n\n<b>help list</b>\nShows list of avaliable command"]
+ "<b>help</b> <STRING command>\nShows help for the given command\n\n<b>help list</b>\nShows list of available command"]
}
{open} {
cmd_line_help_window [mc "Command open"] [mc \
@@ -304,7 +309,7 @@ public method cmd_line_enter {} {
}
{date} {
cmd_line_help_window [mc "Command date"] [mc \
- "<b>date</b> <STRING format>\nInserts formated date at the current position in text\n\n<b>Format string:</b>\n%% => %\n%a => Weekday name (Mon, Tue, etc.)\n%A => Weekday name (Monday, Tuesday, etc.)\n%b => Month name (Jan, Feb, etc.)\n%B => Full month name\n%C => Year (19 or 20)\n%d => Day of month (01 - 31)\n%D => %m/%d/%y\n%h => Abbreviated month name.\n%H => Hour (00 - 23)\n%I => Hour (01 - 12)\n%j => Day of year (001 - 366)\n%k => Hour (0 - 23)\n%l => Hour (1 - 12).\n%m => Month (01 - 12)\n%M => Minute (00 - 59)\n%n => Newline\n%p => AM/PM\n%R => %H:%M.\n%s => Unix timestamp\n%S => Seconds (00 - 59)\n%t => Tab\n%T => %H:%M:%S.\n%u => Weekday number (Monday = 1, Sunday = 7)\n%w => Weekday number (Sunday = 0, Saturday = 6)\n%y => Year without century (00 - 99)\n%Y => Year with century (e.g. 1459)"]
+ "<b>date</b> <STRING format>\nInserts formatted date at the current position in text\n\n<b>Format string:</b>\n%% => %\n%a => Weekday name (Mon, Tue, etc.)\n%A => Weekday name (Monday, Tuesday, etc.)\n%b => Month name (Jan, Feb, etc.)\n%B => Full month name\n%C => Year (19 or 20)\n%d => Day of month (01 - 31)\n%D => %m/%d/%y\n%h => Abbreviated month name.\n%H => Hour (00 - 23)\n%I => Hour (01 - 12)\n%j => Day of year (001 - 366)\n%k => Hour (0 - 23)\n%l => Hour (1 - 12).\n%m => Month (01 - 12)\n%M => Minute (00 - 59)\n%n => Newline\n%p => AM/PM\n%R => %H:%M.\n%s => Unix timestamp\n%S => Seconds (00 - 59)\n%t => Tab\n%T => %H:%M:%S.\n%u => Weekday number (Monday = 1, Sunday = 7)\n%w => Weekday number (Sunday = 0, Saturday = 6)\n%y => Year without century (00 - 99)\n%Y => Year with century (e.g. 1459)"]
}
{clear} {
cmd_line_help_window [mc "Command clear"] [mc \
@@ -344,7 +349,7 @@ public method cmd_line_enter {} {
}
{toupper} {
cmd_line_help_window [mc "Command toupper"] [mc \
- "Convert selected text to upppercase"]
+ "Convert selected text to uppercase"]
}
{capitalize} {
cmd_line_help_window [mc "Command capitalize"] [mc \
@@ -392,11 +397,11 @@ public method cmd_line_enter {} {
}
{step} {
cmd_line_help_window [mc "Command step"] [mc \
- "Step program (avaliliable only when simulator is stated)"]
+ "Step program (available only when simulator is stated)"]
}
{animate} {
cmd_line_help_window [mc "Command animate"] [mc \
- "Animate program (avaliliable only when simulator is stated)"]
+ "Animate program (available only when simulator is stated)"]
}
{d2h} {
cmd_line_help_window [mc "Command d2h"] [mc \
@@ -459,7 +464,7 @@ public method cmd_line_enter {} {
if {![llength $args]} {
::X::__hibernate
- } {
+ } else {
::X::__hibernate_to [lindex $args 0] $filename
}
Sbar [mc "Success"]
@@ -472,7 +477,7 @@ public method cmd_line_enter {} {
if {![llength $args]} {
::X::__resume
- } {
+ } else {
::X::__resume_from [lindex $args 0] $filename
}
Sbar [mc "Success"]
@@ -486,15 +491,15 @@ public method cmd_line_enter {} {
set arg [string toupper [lindex $args 0]]
if {$arg == {list}} {
set arg {}
- foreach mcu ${::X::avaliable_processors} {
+ foreach mcu ${::X::available_processors} {
append arg $mcu
append arg "\n"
}
cmd_line_help_window {Supported microcontrollers} $arg
- } {
- if {[lsearch ${::X::avaliable_processors} $arg] == -1} {
+ } else {
+ if {[lsearch ${::X::available_processors} $arg] == -1} {
Sbar [mc "EDITOR COMMAND LINE: Unsupported processor `%s'" "$arg"]
- } {
+ } else {
::X::change_processor $arg
}
}
@@ -525,13 +530,13 @@ public method cmd_line_enter {} {
set icode [expr {[lindex [${::X::actualProject} cget -procData] 2] * 1024}]
if {$arg > (0xFFFF - $icode)} {
- Sbar [mc "EDITOR COMMAND LINE: This MCU has CODE memory limit 0x10000 B (65536) (command: %s)"] "set-xdata"
+ Sbar [mc "EDITOR COMMAND LINE: This MCU has CODE memory limit 0x10000 B (65536) (command: %s)"] "set-xcode"
return
}
if {[lindex [${::X::actualProject} cget -procData] 1] != {yes}} {
Sbar [mc "This MCU cannot have connected external program memory"]
- } {
+ } else {
${::X::actualProject} configure -P_option_mcu_xcode $arg
::X::close_hexedit code ${::X::actualProject}
${::X::actualProject} simulator_resize_code_memory $arg
@@ -568,7 +573,7 @@ public method cmd_line_enter {} {
if {[lindex [${::X::actualProject} cget -procData] 0] != {yes}} {
Sbar [mc "This MCU cannot have connected external data memory"]
- } {
+ } else {
${::X::actualProject} configure -P_option_mcu_xdata $arg
::X::close_hexedit xdata ${::X::actualProject}
${::X::actualProject} simulator_resize_xdata_memory $arg
@@ -601,17 +606,17 @@ public method cmd_line_enter {} {
}
if {$fullFileName != {}} {
set dir [file dirname $fullFileName]
- } {
+ } else {
set dir $projectPath
}
set filename [file join $dir [lindex $args 0]]
if {![file exists $filename] || ![file isfile $filename]} {
Sbar [mc "EDITOR COMMAND LINE: wrong # args (command: %s)" "unindent"]
}
- if {[${X::actualProject} openfile $filename 1 . def def 0 0 {}] != {}} {
- ${X::actualProject} switch_to_last
- update idle
- ${X::actualProject} editor_procedure {} parseAll {}
+ if {[${::X::actualProject} openfile $filename 1 . def def 0 0 {}] != {}} {
+ ${::X::actualProject} switch_to_last
+ update idletasks
+ ${::X::actualProject} editor_procedure {} parseAll {}
Sbar [mc "Success"]
}
}
@@ -639,7 +644,7 @@ public method cmd_line_enter {} {
{date} {
if {[catch {$editor insert insert [clock format [clock seconds] -format $args]}]} {
Sbar [mc "EDITOR COMMAND LINE: Invalid format string"]
- } {
+ } else {
parse [expr {int([$editor index insert])}]
Sbar [mc "Success"]
}
@@ -647,7 +652,7 @@ public method cmd_line_enter {} {
{char} {
if {[llength $args] > 1} {
Sbar [mc "EDITOR COMMAND LINE: wrong # args (command: %s)" "char"]
- } {
+ } else {
Sbar [mc "Success"]
}
set char [lindex $args 0]
@@ -661,7 +666,7 @@ public method cmd_line_enter {} {
{goto} {
if {[llength $args] > 1} {
Sbar [mc "EDITOR COMMAND LINE: wrong # args (command: %s)" "goto"]
- } {
+ } else {
Sbar [mc "Success"]
}
set target_line [lindex $args 0]
@@ -672,7 +677,7 @@ public method cmd_line_enter {} {
}
if {$target_line > [editor_linescount]} {
Sbar [mc "Target line out of range"]
- } {
+ } else {
goto $target_line
Sbar [mc "Success"]
}
@@ -680,7 +685,7 @@ public method cmd_line_enter {} {
{replace} {
if {[llength $args] > 2} {
Sbar [mc "EDITOR COMMAND LINE: wrong # args (command: %s)" "replace"]
- } {
+ } else {
Sbar [mc "Success"]
}
set pattern [lindex $args 0]
@@ -754,8 +759,8 @@ public method cmd_line_enter {} {
set result [find $fromCursor $Backwards $regExp $noCase $inSelection 1.0 $pattern]
if {[lindex $result 0] == -1} {
Sbar [mc "String not found: %s" [lindex $result 1]]
- } {
- Sbar [mc "Found %s occurences" [lindex $result 2]]
+ } else {
+ Sbar [mc "Found %s occurrence" [lindex $result 2]]
}
}
{cut} {
@@ -850,14 +855,14 @@ public method cmd_line_enter {} {
command_without_args $args
}
default {
- Sbar [mc "EDITOR COMMAND LINE: invalid command, type `help list' to get list of avaliable commands"]
+ Sbar [mc "EDITOR COMMAND LINE: invalid command, type `help list' to get list of available commands"]
}
}
# Manage command line history
if {int([$cmd_line index end-1l]) == int([$cmd_line index insert])} {
$cmd_line insert {insert lineend} "\n"
- } {
+ } else {
set txt [$cmd_line get {insert linestart} {insert lineend}]
$cmd_line mark set insert end
$cmd_line insert insert $txt
@@ -959,9 +964,9 @@ private method command_without_args {args} {
}
## Highlight current contents of editor command line
- # @parm Bool = 0 - Disable popup-based completion
+ # @parm Bool no_completion=0 - Disable popup-based completion
# @return void
-private method cmd_line_highlight args {
+private method cmd_line_highlight {{no_completion 0}} {
# Remove all tags from command line
foreach tag {tag_cmd tag_argument tag_option tag_error} {
$cmd_line tag remove $tag {insert linestart} {insert lineend}
@@ -988,7 +993,7 @@ private method cmd_line_highlight args {
if {[llength $command] == 1} {
$cmd_line tag add tag_cmd $startIdx $lineNumber.$endIdx
} elseif {$endIdx && [llength $command] > 1 && [$cmd_line compare $lineNumber.$endIdx == insert]} {
- if {$cline_completion && $args != 1} {
+ if {$cline_completion && !$no_completion} {
# Automaticaly complete command
set possible_cmd [lindex $command 0]
set insert [$cmd_line index insert]
@@ -1012,7 +1017,7 @@ private method cmd_line_highlight args {
incr endIdx [string length $opt]
if {[lsearch $commands_with_option $command] != -1} {
$cmd_line tag add tag_option $lineNumber.$startIdx $lineNumber.$endIdx
- } {
+ } else {
$cmd_line tag add tag_error $lineNumber.$startIdx $lineNumber.$endIdx
}
}
@@ -1078,7 +1083,7 @@ private method cmd_line_menu_postdown {commands} {
%W selection set"
# Finalize window initialization (global grab)
- update idle
+ update idletasks
catch {
grab -global $win
raise $win
@@ -1100,7 +1105,7 @@ private method cmd_line_menu_postdown {commands} {
public method cmd_line_down {} {
if {![winfo exists $cmd_line_listbox]} {
return 0
- } {
+ } else {
$cmd_line_listbox selection set [$cmd_line_listbox item 0]
focus -force $cmd_line_listbox
return 1
@@ -1167,14 +1172,14 @@ private method cmd_line_help_window {header content} {
}
# Create window
- set win [toplevel .editor_cmd_help_widow -bg {#EEEEEE}]
+ set win [toplevel .editor_cmd_help_widow -bg ${::COMMON_BG_COLOR}]
wm overrideredirect $win 1
bind $win <ButtonPress-1> "$this cmd_line_win_B1 %X %Y"
bind $win <FocusOut> "$this cmd_line_menu_close_now"
# Create header
- set header_frame [frame $win.header]
+ set header_frame [frame $win.header -bg {#AAAAFF}]
pack [label $header_frame.lbl_heder \
-text $header -fg {#FF0000} \
-bg {#AAAAFF} -bd 0 -anchor w \
@@ -1207,7 +1212,7 @@ private method cmd_line_help_window {header content} {
# Create map of bold font tags
regsub -all -line {^\t+} $content {} content
set bold_tag_map {}
- while 1 {
+ while {1} {
set tag_pair {}
set idx [string first {<b>} $content]
@@ -1241,7 +1246,7 @@ private method cmd_line_help_window {header content} {
# Show the window
set x [winfo rootx $cmd_line]
set y [expr {[winfo rooty $cmd_line] + [winfo height $cmd_line]}]
- update idle
+ update idletasks
if {150 > ([winfo height .] - $y)} {
incr y -150
incr y -[winfo height $cmd_line]
@@ -1255,21 +1260,25 @@ private method cmd_line_help_window {header content} {
}
## Focus on editor / editor command line
- # @parm Bool = 0 - Do not call proc. "cmd_line_on"
+ # @parm Bool no_cmd_line_on=0 - Do not call proc. "cmd_line_on"
# @return void
-public method cmd_line_focus args {
+public method cmd_line_focus {{no_cmd_line_on 0}} {
# Show command line
if {![winfo viewable $cmd_line]} {
pack $cmd_line -side top -fill x
- if {$args != 1} {
+ if {!$no_cmd_line_on} {
${::X::actualProject} cmd_line_on
}
}
if {[focus] == $cmd_line} {
focus $editor
- } {
+ } else {
focus $cmd_line
}
update
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/editor.tcl b/lib/editor/editor.tcl
index d4d9bec..e375386 100755..100644
--- a/lib/editor/editor.tcl
+++ b/lib/editor/editor.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _EDITOR_TCL ] } {
+set _EDITOR_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements source code editor with syntax highligh and
@@ -46,23 +51,6 @@ source "${::LIB_DIRNAME}/editor/LSTsyntaxhighlight.tcl"
set ::editor_search_count 0
class Editor {
-
- # Load procedures related to editor command line
- source "${::LIB_DIRNAME}/editor/commandline.tcl"
-
- # Load procedures related to exports to other data formats
- source "${::LIB_DIRNAME}/editor/exports.tcl"
-
- # Load autocompletion related procedures
- source "${::LIB_DIRNAME}/editor/autocompletion.tcl"
-
- # Load general purpose procedures
- source "${::LIB_DIRNAME}/editor/generalproc.tcl"
-
- # Load event handlers
- source "${::LIB_DIRNAME}/editor/eventhandlers.tcl"
-
-
## COMMON
## Editor to use
# 0 - Native editor
@@ -118,32 +106,36 @@ class Editor {
{tag_simulator_curr #AAFFAA}
{tag_error_line #FFDDDD}
{tag_trailing_space #E8FFF0}
+ {tag_breakpoint_INVALID #888888}
}
# Font for command line: Normal help window text
- common cl_hw_nrml_font [font create \
- -family $::DEFAULT_FIXED_FONT \
- -size -14 \
+ common cl_hw_nrml_font [font create \
+ -family $::DEFAULT_FIXED_FONT \
+ -size [expr {int(-14 * $::font_size_factor)}] \
]
# Font for command line: Bold help window text
- common cl_hw_bold_font [font create \
- -family $::DEFAULT_FIXED_FONT \
- -size -14 \
- -weight bold \
+ common cl_hw_bold_font [font create \
+ -family $::DEFAULT_FIXED_FONT \
+ -size [expr {int(-14 * $::font_size_factor)}] \
+ -weight bold \
]
# Font for command line: Subheader in help window text
- common cl_hw_hdr_font [font create \
- -family $::DEFAULT_FIXED_FONT \
- -size -14 \
- -weight bold \
+ common cl_hw_hdr_font [font create \
+ -family $::DEFAULT_FIXED_FONT \
+ -size [expr {int(-14 * $::font_size_factor)}] \
+ -weight bold \
]
# Font for command line: Main header in help window text
- common cmd_line_win_font [font create \
- -size -17 -weight bold \
- -family {helvetica} \
+ common cmd_line_win_font [font create \
+ -size [expr {int(-17 * $::font_size_factor)}] \
+ -weight bold \
+ -family {helvetica} \
]
- common cmd_line_fontSize 14 ;# Font size for command line
- common cmd_line_fontFamily $::DEFAULT_FIXED_FONT ;# Font family for command line
+ # Font size for command line
+ common cmd_line_fontSize [expr {int(14 * $::font_size_factor)}]
+ # Font family for command line
+ common cmd_line_fontFamily $::DEFAULT_FIXED_FONT
# Font for editor command line
common cmd_line_font [font create \
-family $cmd_line_fontFamily \
@@ -174,8 +166,13 @@ class Editor {
Unindent Uppercase Lowercase Capitalize
}
- common fontSize 13 ;# Default font size
- common fontFamily $::DEFAULT_FIXED_FONT ;# Default font family
+ # Maximum width of the tab character, measured in number of spaces
+ common tab_width 8
+
+ # Default font size
+ common fontSize [expr {int(13 * $::font_size_factor)}]
+ # Default font family
+ common fontFamily $::DEFAULT_FIXED_FONT
# Default font for editor
common defaultFont \
@@ -193,17 +190,17 @@ class Editor {
common defaultCharWidth 0 ;# Width of one character of the default font
common defaultCharHeight 0 ;# Height of one character of the default font
# Font for status bar (Normal)
- common statusBarFont \
- [font create \
- -size -12 \
- -family $::DEFAULT_FIXED_FONT \
+ common statusBarFont \
+ [font create \
+ -size [expr {int(-12 * $::font_size_factor)}] \
+ -family $::DEFAULT_FIXED_FONT \
]
# Font for status bar (Bold)
- common statusBarBoldFont \
- [font create \
- -size -12 \
- -weight bold \
- -family $::DEFAULT_FIXED_FONT \
+ common statusBarBoldFont \
+ [font create \
+ -size [expr {int(-12 * $::font_size_factor)}] \
+ -weight bold \
+ -family $::DEFAULT_FIXED_FONT \
]
# Definition of editor popup menu
common EDITORMENU {
@@ -257,17 +254,17 @@ class Editor {
{checkbutton "Bookmark" {$edit:bookmark} {::Editor::bookmark} 1 0 0
{Bookmark ${::Editor::pmenu_cline}}}
{separator}
- {command "Configure panel" "" 0 {configDialogs_mkDialog Colors}
+ {command "Configure panel" "" 0 {configDialogues_mkDialog Colors}
{configure} "Invoke editor configuration dialog"}
{command "Hide" "" 0 {show_hine_IconB}
{2leftarrow} "Hide this panel"}
}
# Definition of popup menu for line numbers
common LNMENU {
- {checkbutton "Breakpont" {$edit:breakpoint} {::Editor::breakpoint} 1 0 0
+ {checkbutton "Breakpoint" {$edit:breakpoint} {::Editor::breakpoint} 1 0 0
{Breakpoint ${::Editor::pmenu_cline}}}
{separator}
- {command "Configure panel" "" 0 {configDialogs_mkDialog Colors}
+ {command "Configure panel" "" 0 {configDialogues_mkDialog Colors}
{configure} "Invoke editor configuration dialog"}
{command "Hide panel" "" 0 {show_hine_LineN}
{2leftarrow} "Hide this panel"}
@@ -283,7 +280,7 @@ class Editor {
{view_remove} ""}
{separator}
{command "Back" {$edit:prev} 0 {__prev_editor_from_pmenu}
- {left} "Go to prevoius file in the file list"}
+ {left} "Go to previous file in the file list"}
{command "Forward" {$edit:next} 0 {__next_editor_from_pmenu}
{right} "Go to next file in the file list"}
}
@@ -292,11 +289,11 @@ class Editor {
public variable editor ;# text widget identifier
public variable ed_sc_frame ;# frame identifier (need packing)
public variable show_iconBorder 1 ;# on/off indicator for Icon Border (bool)
- public variable show_lineNum 1 ;# on/off indicator for Line NUmbers (bool)
+ public variable show_lineNum 1 ;# on/off indicator for Line Numbers (bool)
public variable iconBorder ;# Identifier of Icon Border text widget
public variable lineNumbers ;# Identifier of Line Numbers text widget
public variable scrollbar ;# Identifier of scrollbar widget
- public variable lastEnd 1 ;# Last end index of Edior text widget (for speed optimalization)
+ public variable lastEnd 2 ;# Last end index of Editor text widget (for speed optimization)
public variable Sbar_lock_file ;# Identifier of image label widget at the left site of status bar
public variable Sbar_sim_mode ;# Identifier of label widget at the left site of status bar
public variable Sbar_ssim_mode
@@ -307,7 +304,7 @@ class Editor {
public variable Sbar_total ;# ID of label showing total number of lines
public variable Sbar_image ;# Identifier of floppy disk icon at the middle site of status bar
public variable Sbar_fileName ;# Identifier of the text of filename at the right site of status bar
- public variable Sbar_prog_lang ;# ID of text specifing file type at the right site of status bar
+ public variable Sbar_prog_lang ;# ID of text specifying file type at the right site of status bar
public variable fullFileName ;# Full file name of the current file ("" == untitled)
public variable filename ;# Name of currently opened file or 'untitled'
public variable modified 0 ;# Boolean value indicating than the text has been modified since last save
@@ -316,6 +313,7 @@ class Editor {
public variable ro_mode 0 ;# Bool: Read only mode
## PRIVATE
+ private variable file_change_notif_flg 0 ;# Bool: The opened file was modified on disk by another program
private variable finishigh_hg_dlg_wdg {} ;# Widget: Finishing highlight dialog
private variable finishigh_hg_dlg_tmr {} ;# Timer: Finishing highlight dialog
private variable object_initialized 0 ;# Bool: Flag "Object initialized"
@@ -335,7 +333,7 @@ class Editor {
private variable left_frame_L ;# ID of frame containing Line Numbers
private variable left_frame_R ;# ID of frame containing Icon Border
private variable LN_menu ;# Identifier of popup menu for line numbers
- private variable frozen 0 ;# True if editor is in simulator mode
+ private variable frozen 0 ;# Bool: True if the editor is in simulator mode
private variable getDataAsXHTML_abort 0 ;# Set this variable to 1 to immediate stop export to XHTML
private variable getDataAsLaTeX_abort 0 ;# Set this variable to 1 to immediate stop export to LaTeX
private variable changeLCase_abort 0 ;# Set this variable to 1 to immediate stop changing letter case
@@ -356,7 +354,7 @@ class Editor {
private variable autosave_timer {} ;# ID of autosave timer (command "after")
private variable key_handler_buffer {} ;# List: Buffer for <Key> event handler
private variable key_handler_in_progress 0 ;# Bool: <Key> event handler in progress
- private variable statusbar_menu_config {} ;# List: Statusbra menu configuration list
+ private variable statusbar_menu_config {} ;# List: Status bar menu configuration list
private variable auto_switching_lock 0 ;# Bool: Automatic file switching enabled
private variable selection_in_progress 0 ;# Bool: Procedure "editor_selection" in progress
private variable selection_mode 0 ;# Bool: Block selection mode flag
@@ -373,49 +371,32 @@ class Editor {
private variable top_frame_idx 0 ;# Int: Unique number of container frame for embedded editor
private variable pid {} ;# Int: Process indentifier of embedded external editor (e.g. Vim)
- ## Array: Strings avaliable for autocompletion
- # Index 0 - Labels in assembly
- # Index 1 - Constants/variables
- # Index 2 - C variables
- # Index 3 - Macros
- # Index 4 - SFR's
- # Index 5 - Expression symbols
- # Index 6 - Doxygen tags
- # Index 7 - C Functions
- common invoke_com_win_in_p 0 ;# Bool: invoke_completion_popup_window in progress
- common completion_win_opened 0 ;# Bool: Editor popup-based completion window opended
- private variable autocompletion_list
- private variable completion_win_str_i 1.0 ;# TextIndex: String to complete - start index
- private variable completion_win_end_i 1.0 ;# TextIndex: String to complete - end index
- private variable completion_win_mode 0 ;# Int: Completion window mode
- private variable comp_win_loading_in_p 0 ;# Bool: Completion window list loading is in progress
- private variable comp_win_loading_max 1 ;# Int: Maximum for progressbar in the completion window
- private variable macl_invocations 0 ;# Int: Number of invocations of "manage_autocompletion_list"
- private variable doxytag_fg {#000000} ;# Color: Highlight color for doxygen tag
- private variable indirect_fg {#000000} ;# Color: Highlight color for indirect address
- private variable symbol_fg {#000000} ;# Color: Highlight color for asm. symbol
- private variable sfr_fg {#000000} ;# Color: Highlight color for SFR
- private variable label_fg {#000000} ;# Color: Highlight color for asm. label
- private variable macro_fg {#000000} ;# Color: Highlight color for asm. macro
- private variable const_fg {#000000} ;# Color: Highlight color for asm. const
- private variable dir_fg {#000000} ;# Color: Highlight color for asm. directive
- private variable cs_fg {#000000} ;# Color: Highlight color for constrol sequence
- private variable ins_fg {#000000} ;# Color: Highlight color for instruction
- private variable doxytag_font $defaultFont ;# Font: Font for doxygen tag
- private variable indirect_font $defaultFont ;# Font: Font for indirect address
- private variable symbol_font $defaultFont ;# Font: Font for asm. symbol
- private variable sfr_font $defaultFont ;# Font: Font for SFR
- private variable label_font $defaultFont ;# Font: Font for asm. label
- private variable macro_font $defaultFont ;# Font: Font for asm. macro
- private variable const_font $defaultFont ;# Font: Font for asm. const
- private variable dir_font $defaultFont ;# Font: Font for asm. directive
- private variable cs_font $defaultFont ;# Font: Font for constrol sequence
- private variable ins_font $defaultFont ;# Font: Font for instruction
+
+
+ # Load procedures related to editor command line
+ source "${::LIB_DIRNAME}/editor/commandline.tcl"
+
+ # Load procedures related to exports to other data formats
+ source "${::LIB_DIRNAME}/editor/exports.tcl"
+
+ # Load autocompletion related procedures
+ source "${::LIB_DIRNAME}/editor/autocompletion.tcl"
+
+ # Load general purpose procedures
+ source "${::LIB_DIRNAME}/editor/generalproc.tcl"
+
+ # Load event handlers
+ source "${::LIB_DIRNAME}/editor/eventhandlers.tcl"
+
+ # Spell checker interface
+ source "${::LIB_DIRNAME}/editor/spell_check.tcl"
+
+
## Object constructor
# @parm Bool create_tags - Create highlighting tags
- # @parm String eol_char - EOL (one of {lf cr crlf})
- # @parm String enc - Character encoding (some iso-8859-x or utf-8)
+ # @parm String eol_char - EOL (one of {lf cr crlf})
+ # @parm String enc - Character encoding (some iso-8859-x or utf-8)
# @parm Bool read_only - Read only flag
# @parm Bool switch_lock - Automatic file switching enabled
# @parm widget parentobject - Reference to parent object
@@ -427,6 +408,14 @@ class Editor {
constructor {create_tags eol_char enc read_only switch_lock parentobject fileName filepath Cmd_prefix data sh} {
close_completion_popup_window_NOW
+ set bold_font [font create -size -$fontSize -family $fontFamily -weight {bold}]
+ set italic_font [font create -size -$fontSize -family $fontFamily -slant {italic}]
+ if {[font metrics $bold_font -displayof . -linespace] < [font metrics $italic_font -displayof . -linespace]} {
+ set defaultFont_bold $italic_font
+ } else {
+ set defaultFont_bold $bold_font
+ }
+
# Configure specific ttk styles
ttk::style configure Editor_DarkBg.TButton \
-background {#DDDDDD} \
@@ -435,7 +424,7 @@ class Editor {
-relief flat
ttk::style map Editor_DarkBg.TButton \
-relief [list active raised !active flat]
-
+
# increment instance counter
incr count
@@ -455,11 +444,11 @@ class Editor {
set parentObject $parentobject ;# Identifier parent GUI component (some frame widget)
set fullFileName $filepath ;# Full file name (including path) of current file
set filename $fileName ;# Name of currently opened file or 'untitled'
- refresh_avaliable_SFR
+ refresh_available_SFR
if {$sh == {}} {
determinate_prog_lang 0
- } {
+ } else {
set prog_language_old $prog_language
set prog_language $sh
}
@@ -472,19 +461,22 @@ class Editor {
}
# Create frames
- set ed_sc_frame [frame .editor_frame$count]
- set top_frame [frame $ed_sc_frame.editor_top_frame -relief sunken -bd 1]
- set left_frame [frame $top_frame.editor_left_frame]
- set left_frame_L [frame $left_frame.left -bg $iconBorder_bg]
- set left_frame_R [frame $left_frame.right -bg $lineNumbers_bg]
- set bottom_frame [frame $ed_sc_frame.bottom_frame]
- set statusbar [frame $bottom_frame.editor_status -bg #DDDDDD]
+ set ed_sc_frame [frame .editor_frame$count]
+ set top_frame [frame $ed_sc_frame.editor_top_frame -relief sunken -bd 1]
+ set left_frame [frame $top_frame.editor_left_frame]
+ set left_frame_L [frame $left_frame.left -bg $iconBorder_bg]
+ set left_frame_R [frame $left_frame.right -bg $lineNumbers_bg]
+ set bottom_frame [frame $ed_sc_frame.bottom_frame]
+ set statusbar [frame $bottom_frame.editor_status -bg #DDDDDD]
# Create command line
- set cmd_line [text $bottom_frame.cmd_line \
- -bd 1 -bg #FFFFFF -highlightcolor #8888FF \
- -highlightthickness 1 -height 1 \
- -font $cmd_line_font \
+ set cmd_line [text $bottom_frame.cmd_line \
+ -bd 1 \
+ -bg {#FFFFFF} \
+ -highlightcolor {#8888FF} \
+ -highlightthickness 1 \
+ -height 1 \
+ -font $cmd_line_font \
]
setStatusTip -widget $cmd_line \
-text [mc "Editor command line, type `help' for more"]
@@ -537,8 +529,9 @@ class Editor {
# Create "Editor"
frame $top_frame.f -bd 0 -bg $normal_text_bg -cursor xterm
+
+ set tab_width_un [expr {$tab_width * [font measure $defaultFont_bold 0]}]
set editor [text $top_frame.f.editor \
- -yscrollcommand "$this scrollSet" \
-bg $normal_text_bg \
-font $defaultFont_bold \
-undo 1 -exportselection 1 \
@@ -547,6 +540,7 @@ class Editor {
-selectborderwidth 1 \
-bd 0 -relief flat \
-tabstyle wordprocessor \
+ -tabs [list $tab_width_un left] \
]
bind $top_frame.f <Button-1> "$this click_under_editor %x %y; break"
bind $top_frame.f <Button-4> "$this scroll scroll -3 units; break"
@@ -581,21 +575,21 @@ class Editor {
pack $top_frame -side top -fill both -expand 1
## Create statusbar
- set stat_menu $statusbar.popup_menu
+ set stat_menu $statusbar.popup_menu
set status_left [frame $statusbar.editor_status_left -bg #DDDDDD]
- set status_middle [frame $statusbar.editor_status_middle -width 16 -bg #DDDDDD -width 20]
+ set status_middle [frame $statusbar.editor_status_middle -width 16 -bg #DDDDDD]
set status_right [frame $statusbar.editor_status_right -bg #DDDDDD]
set ins_mode_lbl [Label $statusbar.ins_mode_lbl \
- -text [mc "INS"] -fg #000000 -pady 0 \
- -bg #DDDDDD -cursor hand2 \
- -helptext [mc "Insertion mode"] \
- -font $statusBarBoldFont \
+ -text [mc "INS"] -fg #000000 -pady 0 \
+ -bg #DDDDDD -cursor hand2 \
+ -helptext [mc "Insertion mode"] \
+ -font $statusBarBoldFont \
]
set sel_mode_lbl [Label $statusbar.sel_mode_lbl \
- -text [mc "NORM"] -fg #000000 -pady 0 \
- -bg #DDDDDD -cursor hand2 \
- -helptext [mc "Selection mode"] \
- -font $statusBarBoldFont -width 7 \
+ -text [mc "NORM"] -fg #000000 -pady 0 \
+ -bg #DDDDDD -cursor hand2 \
+ -helptext [mc "Selection mode"] \
+ -font $statusBarBoldFont -width 7 \
]
setStatusTip -widget $sel_mode_lbl -text [mc "Selection mode -- BLK == block; NORM == normal"]
bind $sel_mode_lbl <Button-1> "$this switch_sel_mode"
@@ -603,7 +597,7 @@ class Editor {
pack $status_left -side left -padx 10
pack $status_middle -side left
pack $ins_mode_lbl -side left -padx 5
- pack $sel_mode_lbl -side left -padx 5
+ pack $sel_mode_lbl -side left -padx 5 -pady 3
pack $status_right -side right -fill x -padx 10
# Frame for "Line: x Col: x Total: x"
@@ -715,6 +709,7 @@ class Editor {
}
# Create text tags
+ $editor tag configure tag_wrong_spelling -underline 1
if {$create_tags} {
create_highlighting_tags
}
@@ -766,6 +761,10 @@ class Editor {
bind $editor <Button-4> "$this scroll scroll -3 units; break"
bind $editor <Button-5> "$this scroll scroll +3 units; break"
+ bind $editor <XF86Back> {::X::__prev_editor}
+ bind $editor <XF86Forward> {::X::__next_editor}
+ bind $editor <XF86Reload> {::X::__reload}
+
# Other
foreach key {
<Double-Shift-Button-1> <Shift-Button-1>
@@ -815,6 +814,8 @@ class Editor {
$this recalc_status_counter {}
}
break"
+ bind $editor <Control-Shift-Up> "$this control_shift_updown 1; break"
+ bind $editor <Control-Shift-Down> "$this control_shift_updown 0; break"
bind $editor <Control-Insert> "$this copy; break"
bind $editor <Shift-Insert> "$this paste; break"
bind $editor <Shift-Delete> "$this cut; break"
@@ -822,6 +823,8 @@ class Editor {
bind $editor <Control-Key-Up> "$this control_up; break"
bind $editor <Key-Down> "$this down; break"
bind $editor <Key-Up> "$this up; break"
+ bind $editor <Control-Key-Home> "$this control_home; break"
+ bind $editor <Control-Key-End> "$this control_end; break"
bind $editor <Key-Home> "$this home_press; break"
bind $editor <Shift-Key-Home> "$this shift_home; break"
bind $editor <Key-Insert> "$this switch_ins_ovr; break"
@@ -842,7 +845,7 @@ class Editor {
bind $editor <Shift-KP_Enter> "$this shift_enter; break"
bind $editor <Return> "$this enter; break"
bind $editor <KP_Enter> "$this enter; break"
- bind $editor <Key> "$this Key %A; break"
+ bind $editor <Key> "$this Key %A %K; break"
bind $editor <KeyRelease> "$this KeyRelease %K; break"
bind $editor <ButtonRelease-3> "$this popupMenu %X %Y %x %y; break"
bind $editor <Key-Menu> "$this Key_Menu; break"
@@ -897,17 +900,20 @@ class Editor {
update
break"
bind $editor <Button-1> "
+ # Check spelling on the line which we are now leaving
+ $this spellcheck_check_all \[expr {int(\[%W index insert\])}\]
+
[bind Text <Button-1>]
$this rightPanel_adjust \[expr {int(\[%W index insert\])}\]
$this resetUpDownIndex
- $this recalc_status_counter {%x %y}
+ $this recalc_status_counter
focus -force $editor
break"
bind $editor <B1-Motion> "
[bind Text <B1-Motion>]
$this rightPanel_adjust \[expr {int(\[%W index @%x,%y\])}\]
$this resetUpDownIndex
- $this recalc_status_counter {%x %y}
+ $this recalc_status_counter
break"
bind $editor <<Selection>> "$this editor_selection; break"
@@ -957,7 +963,6 @@ class Editor {
bind $editor <FocusIn> "$parentObject filelist_editor_selected $this"
bind $cmd_line <FocusIn> "$parentObject filelist_editor_selected $this"
-
# Set event bindings for "Line numbers"
bind $lineNumbers <Button-1> "
$parentObject filelist_editor_selected $this
@@ -989,15 +994,19 @@ class Editor {
bindtags $iconBorder [list $iconBorder . all]
# Finalize initialization
+ $editor configure -yscrollcommand "$this scrollSet"
set object_initialized 1
change_RO_MODE $ro_mode
+
+ # Start watching for changes in the file
+ FSnotifications::watch $fullFileName [list ::Editor::file_change_notif $this]
}
## Object destructor
destructor {
if {$editor_to_use} {
kill_childern
- } {
+ } else {
# Stop autosave timer
catch {
after cancel $autosave_timer
@@ -1051,21 +1060,36 @@ class Editor {
public method refresh_font_settings {} {
if {$editor_to_use} {return}
+ # Set new font specification variables
+ set defaultCharHeight_org $defaultCharHeight
+ set defaultFont [font create -size -$fontSize -family $fontFamily]
+ set bold_font [font create -size -$fontSize -family $fontFamily -weight {bold}]
+ set italic_font [font create -size -$fontSize -family $fontFamily -slant {italic}]
+ if {[font metrics $bold_font -displayof $editor -linespace] < [font metrics $italic_font -displayof $editor -linespace]} {
+ set defaultFont_bold $italic_font
+ } else {
+ set defaultFont_bold $bold_font
+ }
+ set defaultCharWidth [font measure $defaultFont_bold -displayof $editor { }]
+ set defaultCharHeight [font metrics $defaultFont_bold -displayof $editor -linespace]
+
# Remove all text tags
foreach tag [$editor tag names] {
if {[lsearch {
sel tag_current_line tag_bookmark
- tag_breakpoint tag_simulator_curr tag_error_line
+ tag_breakpoint tag_breakpoint_INVALID tag_simulator_curr
+ tag_error_line
} $tag] != -1
} then {
break
}
$editor tag remove $tag 1.0 end
}
- # Change fonts
+ # Change fonts and tab width
+ set tab_width_un [expr {$tab_width * [font measure $defaultFont_bold 0]}]
$iconBorder configure -font $defaultFont_bold
$lineNumbers configure -font $defaultFont_bold
- $editor configure -font $defaultFont_bold
+ $editor configure -font $defaultFont_bold -tabs [list $tab_width_un left]
$lineNumbers tag configure right -justify right
$lineNumbers tag configure center -justify center
@@ -1074,19 +1098,13 @@ class Editor {
# Enable writing to the left border
$iconBorder configure -state normal
- # Set new font
- set defaultCharHeight_org $defaultCharHeight
- set defaultFont [font create -size -$fontSize -family $fontFamily]
- set defaultFont_bold [font create -size -$fontSize -family $fontFamily -weight {bold}]
- set defaultCharWidth [font measure $defaultFont_bold -displayof $editor { }]
- set defaultCharHeight [font metrics $defaultFont_bold -displayof $editor -linespace]
# Adjust bookmark images
if {$defaultCharHeight_org != $defaultCharHeight} {
set indexes {}
if {$defaultCharHeight_org < 9} {
set idx 1.0
set idx_prev $idx
- while 1 {
+ while {1} {
set idx [$iconBorder search -exact -- {*} $idx]
if {$idx == {}} {break}
if {[$iconBorder compare $idx_prev >= $idx]} {break}
@@ -1094,7 +1112,7 @@ class Editor {
set idx_prev $idx
set idx [$iconBorder index "$idx+1c"]
}
- } {
+ } else {
foreach img [$iconBorder image names] {
lappend indexes [$iconBorder index $img]
}
@@ -1104,10 +1122,10 @@ class Editor {
$iconBorder delete $idx "$idx+1c"
$iconBorder insert $idx {*}
}
- } {
+ } else {
if {$defaultCharHeight < 15} {
set image {dot}
- } {
+ } else {
set image {bookmark}
}
foreach idx $indexes {
@@ -1122,7 +1140,7 @@ class Editor {
$iconBorder configure -state disabled
# Reset line wrap settings
set highlighted_lines [string repeat 0 [string bytelength $highlighted_lines]]
- update idle
+ update idletasks
highlight_visible_area
# Adjust editor height
@@ -1135,7 +1153,7 @@ class Editor {
if {$ins_ovr_mode} {
$ins_mode_lbl configure -text [mc "INS"] -fg #000000
$editor configure -blockcursor 0
- } {
+ } else {
$ins_mode_lbl configure -text [mc "OVR"] -fg #FF0000
$editor configure -blockcursor 1
}
@@ -1168,7 +1186,7 @@ class Editor {
## Determinate whether editor text has been modified
# and adjust internal variables
# @parm bool force - 1: "I'm sure it has been modified !"
- # 0: "discover it automaticaly"
+ # 0: "discover it automatically"
# @return bool - a new modified flag or {}
public method recalc_status_modified {force} {
@@ -1189,11 +1207,11 @@ class Editor {
catch {
after cancel $autosave_timer
}
- set autosave_timer [after [expr {$autosave * 60000}] [list $this save]]
+ set autosave_timer [after [expr {$autosave * 60000}] "catch {$this save}"]
}
# Not modifed
- } {
+ } else {
# Adjust editor status bar
pack forget $Sbar_image
@@ -1212,24 +1230,18 @@ class Editor {
return $modified
}
- ## Call ::configDialogs::mkDialog $args
+ ## Call ::configDialogues::mkDialog $args
# @return void
- public method configDialogs_mkDialog args {
- ::configDialogs::editor::mkDialog $args
+ public method configDialogues_mkDialog args {
+ ::configDialogues::editor::mkDialog $args
}
## Recalculate variables related to bookmarks, line numbers and list of highlighted lines
- # @parm Bool force = 1 - perform recalcutaion even if length of text wasn't changed
+ # @parm Bool force=1 - perform recalcutaion even if length of text wasn't changed
# @return bool - 0: failed; 1: successful
- public method recalc_left_frame args {
+ public method recalc_left_frame {{force 0}} {
if {$editor_to_use} {return}
- # Parse arguments
- set force [lindex $args 0]
- if {$force == {}} {
- set force 0
- }
-
# Determinate editor lines count and End index
set End [$editor index end]
set Tlines [expr {int($End)}]
@@ -1245,8 +1257,7 @@ class Editor {
incr Tlines -1
# Determinate iconBorder lines count - 1
- set Ilines [expr {int([$iconBorder index end]) - $number_of_wraps}]
- incr Ilines -1
+ set Ilines [expr {int([$iconBorder index end]) - $number_of_wraps - 1}]
# Remove wrap markers from line numbers
if {$number_of_wraps && ($Ilines != $Tlines)} {
@@ -1315,13 +1326,13 @@ class Editor {
$parentObject rightPanel_shift_symbols $Actline [expr {$Actline - $diff - 1}]
# rewrite breakpoints
- rewrite_breakpoint_tags
+ rewrite_breakpoint_tags 1
## Some lines have been added
} elseif {$Ilines < $Tlines} {
# Determinate how many lines should be added
- set diff $Tlines
- incr diff -$Ilines
+ set diff [expr {$Tlines - $Ilines}]
+
set ins [string repeat "\n" $diff]
set BMStr [string range [string repeat {0 } $diff] 0 end-1]
set insIndex $Actline
@@ -1379,8 +1390,8 @@ class Editor {
$editor tag add tag_bookmark [expr {$insIndex - 1}].0 $insIndex.0
}
- } {
- # Adjust list of highlighted lines
+ } else {
+ # Adjust list of lighted lines
set highlighted_lines [string replace \
$highlighted_lines $insIndex $insIndex \
[string repeat 0 [expr {$diff + 1}]]]
@@ -1409,7 +1420,7 @@ class Editor {
$iconBorder configure -state disabled
# rewrite breakpoints
- rewrite_breakpoint_tags
+ rewrite_breakpoint_tags 1
}
## Recalculate Line Numbers
@@ -1426,7 +1437,7 @@ class Editor {
if {$Llines > $Tlines} { ;# too many lines -> remove some ones
$lineNumbers delete $End end
- } elseif {$Llines < $Tlines} { ;# not enought lines -> add some ones
+ } elseif {$Llines < $Tlines} { ;# not enough lines -> add some ones
# Create string to insert to Line Numbers
set ins {}
for {set i [expr {$Llines + 1}]} {$i <= $Tlines} {incr i} {
@@ -1444,16 +1455,15 @@ class Editor {
# Restore wrap markers
if {$number_of_wraps} {
set remaining $number_of_wraps
- set i 1
- foreach wrap $map_of_wraped_lines {
+ for {set i [expr {[llength $map_of_wraped_lines] - 1}]} {$i > 0} {incr i -1} {
+ set wrap [lindex $map_of_wraped_lines $i]
if {$wrap > 0} {
- $lineNumbers insert $i.0 [string repeat "$wrap_char\n" $wrap]
- $lineNumbers tag add center $i.0 [expr {$i + $wrap}].0
- incr i $wrap
+ set ln [expr {$i + 1}]
+ $lineNumbers insert $ln.0 [string repeat "$wrap_char\n" $wrap]
+ $lineNumbers tag add center $ln.0 [expr {$ln + $wrap}].0
incr remaining -$wrap
}
if {!$remaining} {break}
- incr i
}
}
# Disable Line Numbers
@@ -1481,16 +1491,19 @@ class Editor {
# Adjust list of bookmarks
if {[lindex $bookmarks $lineNumber] == 1} {
$parentObject rightPanel_bm_select $lineNumber
- } {
+ } else {
$parentObject rightPanel_bm_unselect
}
# Adjust list of breakpoints
if {[lindex $breakpoints $lineNumber] == 1} {
$parentObject rightPanel_bp_select $lineNumber
- } {
+ } else {
$parentObject rightPanel_bp_unselect
}
+
+ # Adjust list of symbols
+ $parentObject rightPanel_sm_select $lineNumber
}
## Line wrapping manager - variant 2
@@ -1507,7 +1520,7 @@ class Editor {
set new_wrap [get_count_of_lines $line_number.0 "$line_number.0 lineend"]
incr new_wrap -1
# Empty line
- } {
+ } else {
set new_wrap 0
}
@@ -1519,7 +1532,7 @@ class Editor {
if {$line_number >= [llength $map_of_wraped_lines]} {
Configure
return
- } {
+ } else {
lset map_of_wraped_lines $line_number $new_wrap
}
@@ -1536,10 +1549,9 @@ class Editor {
$iconBorder configure -state normal
if {$new_wrap > $wrap} {
set diff [expr {$new_wrap - $wrap}]
- set ins [string repeat "$wrap_char\n" $diff]
incr number_of_wraps $diff
- $lineNumbers insert $line_number.0 $ins
- $iconBorder insert $line_number.0 $ins
+ $lineNumbers insert $line_number.0 [string repeat "$wrap_char\n" $diff]
+ $iconBorder insert $line_number.0 [string repeat "\n" $diff]
$lineNumbers tag add center $line_number.0 [expr {$line_number + $diff}].0
} elseif {$new_wrap < $wrap} {
set diff [expr {$wrap - $new_wrap}]
@@ -1578,7 +1590,7 @@ class Editor {
if {$line_number >= [llength $map_of_wraped_lines]} {
Configure
return
- } {
+ } else {
lset map_of_wraped_lines $line_number $new_wrap
}
@@ -1595,14 +1607,13 @@ class Editor {
$iconBorder configure -state normal
if {$new_wrap > $wrap} {
set diff [expr {$new_wrap - $wrap}]
- set ins [string repeat "$wrap_char\n" $diff]
incr number_of_wraps $diff
- $lineNumbers insert $line_number.0 $ins
- $iconBorder insert $line_number.0 $ins
+ $lineNumbers insert $line_number.0 [string repeat "$wrap_char\n" $diff]
+ $iconBorder insert $line_number.0 [string repeat "\n" $diff]
$lineNumbers tag add center $line_number.0 [expr {$line_number + $diff}].0
} elseif {$new_wrap < $wrap} {
set diff [expr {$wrap - $new_wrap}]
- incr number_of_wraps $diff
+ set number_of_wraps [expr {$number_of_wraps - $diff}]
$lineNumbers delete $line_number.0 $line_number.0+${diff}l
$iconBorder delete $line_number.0 $line_number.0+${diff}l
}
@@ -1673,7 +1684,7 @@ class Editor {
if {$highlight_status == {}} {
set highlight_status 0
}
- } {
+ } else {
set highlight_status 1
}
@@ -1717,12 +1728,15 @@ class Editor {
set i $lineNumber
set last_visible_line [expr {int([lindex [$editor yview] 1] * int([$editor index end])) + 1}]
- # Highlight all line after the current one until it is nessesary
- while 1 {
+ # Highlight all line after the current one until it is not nessesary
+ while {1} {
autocompletion_maybe_important_change $i.0 $i.0
set highlight_status_org [string index $highlighted_lines $i]
set highlight_status [CsyntaxHighlight::highlight $editor $i $highlight_status]
autocompletion_c_syntax_analyze $i
+ if {$i == $lineNumber} {
+ manage_autocompletion_list $i
+ }
set highlighted_lines \
[string replace $highlighted_lines $i $i $highlight_status]
if {
@@ -1761,9 +1775,10 @@ class Editor {
## Parse given line
# Restore highlight, recalculate counters on status bar, adjust right panel
- # @parm Int lineNumber - number of the target line
+ # @parm Int lineNumber - Number of the target line
+ # @parm Bool force_spell_check - Force spelling check
# @return Bool - result from wrap manager
- public method parse {lineNumber} {
+ public method parse {lineNumber {force_spell_check 0}} {
# Check if the given line number is valid
if {$lineNumber >= int([$editor index end])} {
set lineNumber [expr {int([$editor index end]) - 1}]
@@ -1772,7 +1787,7 @@ class Editor {
# Is the given line number is the current line ?
if {int([$editor index insert]) == $lineNumber} {
set curLine 1
- } {
+ } else {
set curLine 0
}
@@ -1827,6 +1842,11 @@ class Editor {
validate_line $lineNumber 0
}
+ # Check spelling if not current line and if enabled
+ if {!$curLine || $force_spell_check} {
+ spellcheck_check_all $lineNumber 1
+ }
+
# Recalculate counters on status bar
if {$curLine} {
recalc_status_counter {}
@@ -1840,7 +1860,7 @@ class Editor {
if {${::ASMsyntaxHighlight::validation_L0}} {
if {[llength [$editor tag nextrange tag_error $lineNumber.0 [list $lineNumber.0 lineend]]]} {
set add 1
- } {
+ } else {
set remove 1
}
# Remove tag "tag_error_line"
@@ -1859,7 +1879,7 @@ class Editor {
if {[lindex $bookmarks $lineNumber] == 1} {
set image {bm_ex}
- } {
+ } else {
set image {exclamation}
}
@@ -1902,19 +1922,21 @@ class Editor {
}
## Finalize syntax validation on the given line (validates operands only)
- # @parm Int - Number of line in source code
- # @parm Bool = 1 - Affect panel "Instruction details"
+ # @parm Int line - Number of line in source code
+ # @parm Bool ins_det=1 - Affect panel "Instruction details"
# @return void
- private method validate_line args {
- # Parse input arguments
- set line [lindex $args 0]
- set ins_det [lindex $args 1]
- if {$ins_det == {}} {
- set ins_det 1
+ private method validate_line {line {ins_det 1}} {
+ # Check if basic validation is enabled
+ if {!${::ASMsyntaxHighlight::validation_L0}} {
+ return
}
- # Check if basic validation is enabled
- if {!${::ASMsyntaxHighlight::validation_L0}} {return}
+ # Validate breakpoint first
+ if {[is_breakpoint_valid $line]} {
+ mark_breakpoint_as_valid $line
+ } else {
+ mark_breakpoint_as_invalid $line
+ }
# Detereminate range of instruction tag
set ins_range [$editor tag nextrange tag_instruction $line.0 "$line.0 lineend"]
@@ -1927,11 +1949,12 @@ class Editor {
if {[lsearch -ascii -exact ${CompilerConsts::AllInstructions} $instruction] == -1} {
return
}
- } {
+
+ } else {
return
}
- # Inset selection in "Instruction details" tab on the Right Panel
+ # Unset selection in "Instruction details" tab on the Right Panel
if {$ins_det} {
$parentObject rightPanel_ins_unselect
}
@@ -1970,7 +1993,7 @@ class Editor {
if {$opr_set == $operands} {
if {$i} {
lappend matches0 $idx
- } {
+ } else {
lappend matches $idx
}
}
@@ -1998,7 +2021,7 @@ class Editor {
}
}
- # Highlight coresponding operand sets in "Instruction details"
+ # Highlight corresponding operand sets in "Instruction details"
if {[llength $matches] || [llength $matches0]} {
if {$ins_det} {
if {[llength $matches]} {
@@ -2008,7 +2031,7 @@ class Editor {
$parentObject rightPanel_ins_select 0 $matches0
}
}
- } {
+ } else {
$editor tag add tag_error [lindex $ins_range 0] [lindex $ins_range 1]
}
@@ -2016,7 +2039,7 @@ class Editor {
set sfr_range_start $line.0
set sfr_range {}
set sfr_name {}
- while 1 {
+ while {1} {
# Try to find SFR
set sfr_range [$editor tag nextrange tag_sfr $sfr_range_start [list $line.0 lineend]]
if {![llength $sfr_range]} {
@@ -2030,10 +2053,10 @@ class Editor {
if {[string index $sfr_name 0] == {/}} {
set sfr_name [string range $sfr_name 1 end]
}
-
+
if {
[lsearch -ascii -exact \
- [$parentObject cget -avaliable_SFR] \
+ [$parentObject cget -available_SFR] \
[string toupper $sfr_name] \
] == -1
} then {
@@ -2043,8 +2066,8 @@ class Editor {
}
}
- ## Adjust content of the given line in list of bookmakrs and list of breakpoint (in right panel)
- # This function should be called after change content of any line
+ ## Adjust content of the given line in list of bookmarks and list of breakpoint (in right panel)
+ # This function should be called after change in content of a line
# @parm Int lineNumber - line number
# @return void
private method rightPanel_changeLineContent {lineNumber} {
@@ -2054,6 +2077,7 @@ class Editor {
$parentObject rightPanel_add_bookmark $lineNumber
$parentObject rightPanel_bm_select $lineNumber
}
+
# Adjust list of breakpoints
if {[lindex $breakpoints $lineNumber] == 1} {
$parentObject rightPanel_remove_breakpoint $lineNumber
@@ -2090,7 +2114,7 @@ class Editor {
private method wrap_aux_line2idx {line} {
if {$number_of_wraps} {
set i 1
- while 1 {
+ while {1} {
incr line [expr { -1 - [lindex $map_of_wraped_lines $i]}]
if {$line < 1 || $line == {}} {break}
incr i
@@ -2104,7 +2128,7 @@ class Editor {
## Focus on the editor widget
# @return void
public method focus_in {} {
- focus $editor
+ focus -force $editor
}
## Get ranges for all highlighting tags on the given line
@@ -2119,9 +2143,9 @@ class Editor {
# Iterate over defined highlighting tags
foreach tag [concat \
- ${ASMsyntaxHighlight::hightlight_tags} \
- ${CsyntaxHighlight::hightlight_tags} \
- ${LSTsyntaxHighlight::hightlight_tags} \
+ ${ASMsyntaxHighlight::highlight_tags} \
+ ${CsyntaxHighlight::highlight_tags} \
+ ${LSTsyntaxHighlight::highlight_tags} \
{tag_macro_def tag_constant_def} \
] {
@@ -2130,7 +2154,7 @@ class Editor {
# Determinate range of the tag
set range {}
- while 1 {
+ while {1} {
# Determinate start index
set startIdx [lindex $range [expr {[llength $range] - 1}]]
if {$startIdx == {}} {
@@ -2157,9 +2181,63 @@ class Editor {
return $ranges
}
+ ## Make breakpoint on the specified line as VALID (reachable)
+ # @param Int line_number - line number
+ # @return void
+ private method mark_breakpoint_as_valid {line_number} {
+ if {[lindex $breakpoints $line_number] != 1} {
+ return
+ }
+
+ set line_number [wrap_aux_idx2line $line_number]
+
+ $lineNumbers tag remove tag_breakpoint_INVALID $line_number.0 [list $line_number.0+1l]
+ $lineNumbers tag add tag_breakpoint $line_number.0 [list $line_number.0+1l]
+ }
+
+ ## Make breakpoint on the specified line as INVALID (unreachable)
+ # @param Int line_number - line number
+ # @return void
+ private method mark_breakpoint_as_invalid {line_number} {
+ if {[lindex $breakpoints $line_number] != 1} {
+ return
+ }
+
+ set line_number [wrap_aux_idx2line $line_number]
+
+ $lineNumbers tag remove tag_breakpoint $line_number.0 [list $line_number.0+1l]
+ $lineNumbers tag add tag_breakpoint_INVALID $line_number.0 [list $line_number.0+1l]
+ }
+
+ ## Determinate whether breakpoint on the specified line is valid or could be
+ #+ valid in case there is no breakpoint yet
+ # @param Int line_number - line number
+ # @return Bool - 1 == is valid; 0 == is NOT valid
+ private method is_breakpoint_valid {line_number} {
+
+ if {$prog_language == 2 || $prog_language == 3} {
+ return 0
+ }
+
+ if {
+ !$prog_language
+ &&
+ ${::ASMsyntaxHighlight::validation_L0}
+ &&
+ ![llength [$editor tag nextrange tag_instruction $line_number.0 [list $line_number.0 lineend]]]
+ &&
+ ![llength [$editor tag nextrange tag_macro $line_number.0 [list $line_number.0 lineend]]]
+ } then {
+ return 0
+ }
+
+ return 1
+ }
+
## Restore breakpoint tags in "Line numbers"
+ # @parm Bool ignore_wrap=0 - Ignore line wrapping (see recalc_left_frame)
# @return void
- private method rewrite_breakpoint_tags {} {
+ private method rewrite_breakpoint_tags {{ignore_wrap 0}} {
if {$editor_to_use} {return}
# Enable line numbers
@@ -2167,10 +2245,33 @@ class Editor {
# Remove current tags
$lineNumbers tag remove tag_breakpoint 1.0 end
+ $lineNumbers tag remove tag_breakpoint_INVALID 1.0 end
+
# Restore tags
- foreach line [lsearch -ascii -exact -all $breakpoints 1] {
- append line {.0}
- $lineNumbers tag add tag_breakpoint $line "$line+1l"
+ if {!$ignore_wrap && $number_of_wraps} {
+ set i 0
+ set line 0
+ foreach wrap $map_of_wraped_lines {
+ if {[lindex $breakpoints $line] == 1} {
+ if {[is_breakpoint_valid $line]} {
+ $lineNumbers tag add tag_breakpoint $i.0 "$i.0+1l"
+ } else {
+ $lineNumbers tag add tag_breakpoint_INVALID $i.0 "$i.0+1l"
+ }
+ }
+
+ incr wrap
+ incr i $wrap
+ incr line
+ }
+ } else {
+ foreach line [lsearch -ascii -exact -all $breakpoints 1] {
+ if {[is_breakpoint_valid $line]} {
+ $lineNumbers tag add tag_breakpoint $line.0 "$line.0+1l"
+ } else {
+ $lineNumbers tag add tag_breakpoint_INVALID $line.0 "$line.0+1l"
+ }
+ }
}
# Disable line numbers
@@ -2187,7 +2288,7 @@ class Editor {
# Create tag in editor
$editor tag configure [lindex $tag_definition 0] -background [lindex $tag_definition 1]
# Create tag in line numbers
- if {[lindex $tag_definition 0] == {tag_breakpoint}} {
+ if {[lsearch {tag_breakpoint_INVALID tag_breakpoint} [lindex $tag_definition 0]] != -1} {
$lineNumbers tag configure [lindex $tag_definition 0] \
-background [lindex $tag_definition 1] -relief raised -borderwidth 1
}
@@ -2248,16 +2349,16 @@ class Editor {
# @return void
public method makePopupMenu {} {
if {[winfo exists $menu]} {destroy $menu}
- menuFactory $EDITORMENU $menu 0 $cmd_prefix 0 {}
+ menuFactory $EDITORMENU $menu 0 $cmd_prefix 0 {} [namespace current]
if {[winfo exists $stat_menu]} {destroy $stat_menu}
- menuFactory $STATMENU $stat_menu 0 {::X::} 0 {}
+ menuFactory $STATMENU $stat_menu 0 {::X::} 0 {} [namespace current]
if {[winfo exists $IB_menu]} {destroy $IB_menu}
- menuFactory $IBMENU $IB_menu 0 "$this " 0 {}
+ menuFactory $IBMENU $IB_menu 0 "$this " 0 {} [namespace current]
if {[winfo exists $LN_menu]} {destroy $LN_menu}
- menuFactory $LNMENU $LN_menu 0 "$this " 0 {}
+ menuFactory $LNMENU $LN_menu 0 "$this " 0 {} [namespace current]
}
## Configure state of statusbar popup menu entries
@@ -2271,40 +2372,35 @@ class Editor {
set statusbar_menu_config [list 1 1 1 1]
}
if {$split != {}} {
- lset statusbar_menu_config 0 $split
+ lset statusbar_menu_config 0 [expr "$split"]
}
if {$close != {}} {
- lset statusbar_menu_config 1 $close
+ lset statusbar_menu_config 1 [expr "$close"]
}
if {$prev != {}} {
- lset statusbar_menu_config 2 $prev
+ lset statusbar_menu_config 2 [expr "$prev"]
}
if {$next != {}} {
- lset statusbar_menu_config 3 $next
+ lset statusbar_menu_config 3 [expr "$next"]
}
}
## Rewrite left site of editor status bar
- # @parm List - Relative mouse cursor coordinates ({%x,%y})
- # {} == keyboard input (eg. leftArrow pressed)
- # @parm Bool = 1 - Highlight current line and such things
+ # @parm List coord={} - Relative mouse cursor coordinates ({%x,%y})
+ # {} == keyboard input (eg. leftArrow pressed)
+ # @parm Bool perform_highlight=1 - Highlight current line and such things
# @return void
- public method recalc_status_counter args {
+ public method recalc_status_counter {{coord {}} {perform_highlight 1}} {
if {$editor_to_use} {return}
- # Procedure can executed only in editor mode
- if {$frozen} {return}
+# # Procedure can executed only in normal editor mode
+# if {$frozen} {return}
# Parse arguments
- if {[lindex $args 0] == {}} {
+ if {$coord == {}} {
set coord insert
- } {
- set coord "@[lindex $args {0 0}],[lindex $args {0 1}]"
- }
- if {[lindex $args 1] == {}} {
- set perform_highlight 1
- } {
- set perform_highlight [lindex $args 1]
+ } else {
+ set coord "@[lindex $coord 0],[lindex $coord 1]"
}
# Translate text index into number
@@ -2319,7 +2415,7 @@ class Editor {
if {[regexp {\t} $lineText]} {
set idx -1
set cor 0
- while 1 {
+ while {1} {
set idx [string first "\t" $lineText [expr {$idx + 1}]]
if {$idx == -1 || $idx > $Index} {break}
@@ -2337,7 +2433,7 @@ class Editor {
incr tmp
$editor tag add tag_current_line $line.0 $tmp.0
set last_cur_line $line
- } {
+ } else {
$editor tag add tag_current_line $line.0 $tmp.0
}
@@ -2399,15 +2495,15 @@ class Editor {
if {[llength $ins_range]} {
$parentObject rightPanel_ins_change [$editor get [lindex $ins_range 0] [lindex $ins_range 1]]
- } {
+ } else {
set ins_range [$editor tag nextrange tag_directive {insert linestart} {insert lineend}]
if {[llength $ins_range]} {
$parentObject rightPanel_dir_change D [$editor get [lindex $ins_range 0] [lindex $ins_range 1]]
- } {
+ } else {
set ins_range [$editor tag nextrange tag_control {insert linestart} {insert lineend}]
if {[llength $ins_range]} {
$parentObject rightPanel_dir_change C [$editor get [lindex $ins_range 0] [lindex $ins_range 1]]
- } {
+ } else {
$parentObject rightPanel_ins_clear
}
}
@@ -2427,7 +2523,7 @@ class Editor {
} then {
if {$up__down} {
return [$editor index {insert-1l linestart}]
- } {
+ } else {
return [$editor index {insert+1l linestart}]
}
@@ -2439,14 +2535,14 @@ class Editor {
# Determinate target column number
if {!$lastUpDownIndex} {
set lastUpDownIndex $col
- } {
+ } else {
set col $lastUpDownIndex
}
# Traslate column number to text index
if {$up__down} {
incr lineNum -1
- } {
+ } else {
incr lineNum
}
@@ -2464,7 +2560,7 @@ class Editor {
if {[string first "\t" $lineText] != -1} {
set idx -1
set cor 0
- while 1 {
+ while {1} {
set idx [string first "\t" $lineText [expr {$idx + 1}]]
if {$idx == -1} {break}
@@ -2480,6 +2576,9 @@ class Editor {
# @parm Int col - Column number
# @return TextIndex - Resulting insertIndex
private method column_to_text_index {lineNum col} {
+ if {!$col} {
+ return 0
+ }
set lineText [$editor get $lineNum.0 [list $lineNum.0 lineend]]
if {[string first "\t" $lineText] != -1} {
@@ -2564,7 +2663,7 @@ class Editor {
# Determinate width of the selected block
if {abs($col_s1 - $col_s0) < abs($col_e1 - $col_e0)} {
set width [expr {abs($col_s1 - $col_s0)}]
- } {
+ } else {
set width [expr {abs($col_e1 - $col_e0)}]
}
@@ -2572,14 +2671,15 @@ class Editor {
$editor tag remove sel 0.0 end
set col 0
for {set row $row_s0} {$row <= $row_e1} {incr row} {
- set col [column_to_text_index $row $col_s0]
- if {[$editor compare $row.$col >= [list $row.0 lineend]]} {
+ set col0 [column_to_text_index $row $col_s0]
+ set col1 [column_to_text_index $row [expr {$col_s0 + $width}]]
+ if {[$editor compare $row.$col0 >= [list $row.0 lineend]]} {
continue
}
- if {[$editor compare $row.$col+${width}c > [list $row.0 lineend]]} {
- $editor tag add sel $row.$col [list $row.0 lineend]
- } {
- $editor tag add sel $row.$col $row.$col+${width}c
+ if {[$editor compare $row.$col1 > [list $row.0 lineend]]} {
+ $editor tag add sel $row.$col0 [list $row.0 lineend]
+ } else {
+ $editor tag add sel $row.$col0 $row.$col1
}
}
}
@@ -2635,7 +2735,7 @@ class Editor {
if {[catch {
if {$filename == {}} {
cd [$parentObject cget -projectPath]
- } {
+ } else {
cd [file dirname $filename]
}
}]} then {
@@ -2650,7 +2750,7 @@ class Editor {
+sb -bg "$normal_text_bg" -b 0 -w 0 -sl 0 \
-fn "xft:$fontFamily:pixelsize=$fontSize" \
-e $cmd &]
- } {
+ } else {
set pid [exec -- urxvt -embed [expr [winfo id $top_frame]] \
+sb -bg "$normal_text_bg" -b 0 -w 0 -sl 0 \
-fn "xft:$fontFamily:pixelsize=$fontSize" \
@@ -2662,7 +2762,7 @@ class Editor {
+sb -bg "$normal_text_bg" -b 0 -w 0 -sl 0 \
-fn "xft:$fontFamily:pixelsize=$fontSize" \
-e $cmd $opt &]
- } {
+ } else {
set pid [exec -- urxvt -embed [expr [winfo id $top_frame]] \
+sb -bg "$normal_text_bg" -b 0 -w 0 -sl 0 \
-fn "xft:$fontFamily:pixelsize=$fontSize" \
@@ -2676,7 +2776,7 @@ class Editor {
-icon error \
-type ok \
-title [mc "FATAL ERROR"] \
- -message [mc "Unable to start embedded editor due to an unknow error. This error did not occured in MCU 8051 IDE code but somewhere else. Please try to restart MCU 8051 IDE with --reset-user-settings"]
+ -message [mc "Unable to start embedded editor due to an unknown error. This error did not occurred in MCU 8051 IDE code but somewhere else. Please try to restart MCU 8051 IDE with --reset-user-settings"]
}
# Return to previous directory
@@ -2687,7 +2787,7 @@ class Editor {
# @parm String filename - Name of file to open with the external editor
# @return void
public method recreate_terminal {filename} {
- update idle
+ update idletasks
if {![winfo exists $ed_sc_frame]} {return}
set top_frame [frame $ed_sc_frame.top_frame_$top_frame_idx -container 1]
pack $top_frame -expand 1 -fill both
@@ -2697,7 +2797,7 @@ class Editor {
incr top_frame_idx
}
- ## Determinate file type acording to its name externsion
+ ## Determinate file type according to its name extension
# @parm Bool reset - Reset syntax highlight
# @return void
private method determinate_prog_lang {reset} {
@@ -2727,12 +2827,16 @@ class Editor {
private method prog_lang_changed {} {
if {$editor_to_use} {return}
# Clear current highlighting tags
- $editor tag remove tag_error 0.0 end
- $editor tag remove tag_error_line 0.0 end
- foreach tag [concat \
- ${::CsyntaxHighlight::hightlight_tags} \
- ${::ASMsyntaxHighlight::hightlight_tags} \
- ${LSTsyntaxHighlight::hightlight_tags} \
+ $editor tag remove tag_error 0.0 end
+ $editor tag remove tag_error_line 0.0 end
+ $editor tag remove tag_constant_def 0.0 end
+ $editor tag remove tag_macro_def 0.0 end
+ $editor tag remove c_lang_func 0.0 end
+ $editor tag remove c_lang_var 0.0 end
+ foreach tag [concat \
+ ${::CsyntaxHighlight::highlight_tags} \
+ ${::ASMsyntaxHighlight::highlight_tags} \
+ ${::LSTsyntaxHighlight::highlight_tags} \
] {
$editor tag remove [lindex $tag 0] 0.0 end
}
@@ -2760,7 +2864,7 @@ class Editor {
# Adjust main menu and main toolbar
if {$prog_language == 1} {
set uses_c 1
- } {
+ } else {
set uses_c 0
}
::X::adjust_mainmenu_and_toolbar_to_editor {} $uses_c
@@ -2779,8 +2883,12 @@ class Editor {
$Sbar_prog_lang configure -fg {#00DDEE} -text "LST"
} elseif {$prog_language == 3} {
$Sbar_prog_lang configure -fg {#0000DD} -text "ASX"
- } {
+ } else {
$Sbar_prog_lang configure -fg {#00CC00} -text "ASM"
}
}
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/eventhandlers.tcl b/lib/editor/eventhandlers.tcl
index c6d1083..279b2e2 100755..100644
--- a/lib/editor/eventhandlers.tcl
+++ b/lib/editor/eventhandlers.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _EVENTHANDLERS_TCL ] } {
+set _EVENTHANDLERS_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements event handlers
@@ -138,7 +143,7 @@ public method scroll args {
if {$unit != {p}} {
incr line [lindex $args 1]
- } {
+ } else {
incr line [expr {30 * [lindex $args 1]}]
}
incr line -1
@@ -157,7 +162,7 @@ public method scroll args {
}
highlight_visible_area ;# Highlight lines which hasn't been highlighted yet
- update idle
+ update idletasks
set tmp_row $row
if {$number_of_wraps} {
@@ -187,7 +192,7 @@ public method scroll args {
}
# Done ...
- update idle
+ update idletasks
set scroll_in_progress 0
}
@@ -207,12 +212,12 @@ public method popupMenu {X Y x y} {
]
if {$address == {}} {
set state {disabled}
- } {
+ } else {
set state {normal}
}
$menu entryconfigure [::mc "LJMP this line"] -state $state
$menu entryconfigure [::mc "LCALL this line"] -state $state
- } {
+ } else {
$menu entryconfigure [::mc "LJMP this line"] -state disabled
$menu entryconfigure [::mc "LCALL this line"] -state disabled
}
@@ -262,7 +267,7 @@ public method statusbar_popup_menu {editor X Y} {
if {[lindex $statusbar_menu_config 0] != 0} {
set state normal
- } {
+ } else {
set state disabled
}
$stat_menu entryconfigure [::mc "Split vertical"] -state $state
@@ -270,21 +275,21 @@ public method statusbar_popup_menu {editor X Y} {
if {[lindex $statusbar_menu_config 1] != 0} {
set state normal
- } {
+ } else {
set state disabled
}
$stat_menu entryconfigure [::mc "Close current view"] -state $state
if {[lindex $statusbar_menu_config 2] != 0} {
set state normal
- } {
+ } else {
set state disabled
}
$stat_menu entryconfigure [::mc "Back"] -state $state
if {[lindex $statusbar_menu_config 3] != 0} {
set state normal
- } {
+ } else {
set state disabled
}
$stat_menu entryconfigure [::mc "Forward"] -state $state
@@ -322,9 +327,83 @@ public method control_up {} {
$editor yview scroll -1 units
}
+## Handles event: "Control-Shift-Key-Up" and "Control-Shift-Key-Down"
+ # @parm Bool up__down - 1 == Control-Shift-Key-Up; 0 == Control-Shift-Key-Down
+ # @return void
+public method control_shift_updown {up__down} {
+ if {$up__down} {
+ if {int([$editor index insert]) == 1} {
+ return
+ }
+ } else {
+ if {(int([$editor index insert]) + 1) == int([$editor index end])} {
+ return
+ }
+ }
+
+ $editor configure -autoseparators 0
+ if {$up__down} {
+ set target_idx [$editor index {insert-1l}]
+ autocompletion_maybe_important_change [$editor index {insert-1l linestart}] [$editor index {insert lineend}]
+ } else {
+ set target_idx [$editor index {insert+1l}]
+ autocompletion_maybe_important_change [$editor index {insert linestart}] [$editor index {insert+1l lineend}]
+ }
+
+ catch {
+ $editor tag remove sel 1.0 end
+ }
+
+ set line0 [$editor get {insert linestart} {insert lineend}]
+ if {$up__down} {
+ set line1 [$editor get {insert-1l linestart} {insert-1l lineend}]
+ } else {
+ set line1 [$editor get {insert+1l linestart} {insert+1l lineend}]
+ }
+
+ $editor delete {insert linestart} {insert lineend}
+ if {$up__down} {
+ $editor delete {insert-1l linestart} {insert-1l lineend}
+ } else {
+ $editor delete {insert+1l linestart} {insert+1l lineend}
+ }
+
+ $editor insert insert $line1
+ if {$up__down} {
+ $editor insert {insert-1l} $line0
+ } else {
+ $editor insert {insert+1l} $line0
+ }
+
+ set idx [expr {int([$editor index insert])}]
+ parse $idx
+ manage_autocompletion_list $idx
+ if {$up__down} {
+ set idx [expr {int([$editor index insert-1l])}]
+ } else {
+ set idx [expr {int([$editor index insert+1l])}]
+ }
+ parse $idx
+ manage_autocompletion_list $idx
+
+ # Check spelling on the other line
+ update
+ spellcheck_check_all [expr {int([$editor index insert])}] 1
+
+ # Move insertion cursor
+ $editor mark set insert $target_idx
+ $editor see insert
+
+ $editor edit separator
+ $editor configure -autoseparators 1
+}
+
## Handles event: "Shift-Key-Down"
# @return void
public method shift_down {} {
+ # Check spelling on the line which we are noe leaving
+ spellcheck_check_all [expr {int([$editor index insert])}]
+
tk::TextKeySelect $editor [get_up_down_idx 0]
# Adjust selection in list of bookmarks and list of breakpoints
@@ -338,6 +417,9 @@ public method shift_down {} {
## Handles event: "Shift-Key-Up"
# @return void
public method shift_up {} {
+ # Check spelling on the line which we are noe leaving
+ spellcheck_check_all [expr {int([$editor index insert])}]
+
tk::TextKeySelect $editor [get_up_down_idx 1]
# Adjust selection in list of bookmarks and list of breakpoints
@@ -351,6 +433,9 @@ public method shift_up {} {
## Handles event: "Key-Up"
# @return void
public method up {} {
+ # Check spelling on the line which we are now leaving
+ spellcheck_check_all [expr {int([$editor index insert])}]
+
# Move insertion cursor
$editor mark set insert [get_up_down_idx 1]
@@ -370,6 +455,9 @@ public method up {} {
## Handles event: "Key-Down"
# @return void
public method down {} {
+ # Check spelling on the line which we are now leaving
+ spellcheck_check_all [expr {int([$editor index insert])}]
+
# Focus completion popup window
if {$completion_win_opened} {
catch {
@@ -427,7 +515,7 @@ public method shift_home {} {
}
# Nothing selected
- } {
+ } else {
set idx [$editor index insert]
home_press
catch {
@@ -436,12 +524,32 @@ public method shift_home {} {
if {[$editor compare $idx < insert]} {
$editor tag add sel $idx insert
- } {
+ } else {
$editor tag add sel insert $idx
}
}
}
+## Handles event: "Control-Key-Home"
+ # @return void
+public method control_home {} {
+ $editor mark set insert 1.0
+ rightPanel_adjust [expr {int([$editor index insert])}]
+ resetUpDownIndex
+ recalc_status_counter {} 0
+ $editor see insert
+}
+
+## Handles event: "Control-Key-End"
+ # @return void
+public method control_end {} {
+ $editor mark set insert end
+ rightPanel_adjust [expr {int([$editor index insert])}]
+ resetUpDownIndex
+ recalc_status_counter {} 0
+ $editor see insert
+}
+
## Handles event: "Key-Home"
# @return void
public method home_press {} {
@@ -455,10 +563,10 @@ public method home_press {} {
set col [string length $space]
if {$col_original == $col} {
$editor mark set insert $row.0
- } {
+ } else {
$editor mark set insert $row.$col
}
- } {
+ } else {
$editor mark set insert $row.0
}
@@ -468,6 +576,7 @@ public method home_press {} {
}
# Adjust status bar counters
+ resetUpDownIndex
recalc_status_counter {} 0
$editor see insert
}
@@ -477,7 +586,7 @@ public method home_press {} {
public method tab_press {} {
if {$spaces_no_tabs} {
set indent_char [string repeat { } $number_of_spaces]
- } {
+ } else {
set indent_char "\t"
}
@@ -486,7 +595,7 @@ public method tab_press {} {
Key $indent_char
# Something selected -> indent
- } {
+ } else {
# convert selection indexes to line numbers
set start [expr {int([$editor index sel.first])}]
set end_o [$editor index sel.last]
@@ -514,6 +623,9 @@ public method shift_enter {} {
if {$critical_edit_proc} {return}
set critical_edit_proc 1
+ # Check spelling on the line which we are noe leaving
+ spellcheck_check_all [expr {int([$editor index insert])}]
+
deleteselection
$editor insert insert "\n"
@@ -553,10 +665,13 @@ public method enter {} {
set idx [expr {int($idx)}]
incr idx
+ # Check spelling on the line which we are noe leaving
+ spellcheck_check_all $idx
+
# Keep indention of the previous line
if {$intentation_mode == {normal}} {
- # Determinate indetication charactes
+ # Determinate indetication characters
set prev_line [$editor get \
[$editor index {insert-1l linestart}] \
[$editor index {insert-1l lineend}] \
@@ -620,7 +735,7 @@ public method KeyRelease {key} {
if {[lsearch {ISO_Next_Group ISO_Prev_Group Alt_R Alt_L Control Meta Shift_L Shift_R} $key] == -1} {
if {$do_not_hide_comp_win} {
set do_not_hide_comp_win 0
- } {
+ } else {
close_completion_popup_window
}
}
@@ -628,8 +743,8 @@ public method KeyRelease {key} {
## Handles event: 'Key'
# @return void
-public method Key {key} {
- # Skip values with no meaning
+public method Key {key {key_k {}}} {
+ # Skip values with no meaning for us herw
if {![string is print -strict $key] && $key != "\t"} {
return
}
@@ -643,6 +758,7 @@ public method Key {key} {
set key_handler_in_progress 1
set scroll_in_progress 1 ;# Block scrolling
+ spellcheck_change_detected_pre
autocompletion_maybe_important_change insert insert
$editor configure -autoseparators 0
@@ -665,7 +781,7 @@ public method Key {key} {
$editor tag remove sel 1.0 end
# Insert the selected character twice
- } {
+ } else {
set next_char [$editor get insert insert+1c]
$editor insert insert $key
switch -- $key {
@@ -730,6 +846,7 @@ public method Key {key} {
set key_handler_in_progress 0
update
set scroll_in_progress 0 ;# Unblock scrolling
+ spellcheck_change_detected_post
}
## Handles event: 'Key-Delete'
@@ -738,7 +855,7 @@ public method key_delete {} {
if {![$this deleteselection 1]} {
if {[$editor compare {insert linestart} != {insert+1c linestart}]} {
set remove_trailing_space 1
- } {
+ } else {
set remove_trailing_space 0
}
@@ -752,6 +869,7 @@ public method key_delete {} {
$this resetUpDownIndex
$this recalc_left_frame
+ $this parse [expr {int([$editor index insert])}]
update
}
@@ -779,3 +897,7 @@ public method key_backspace {} {
$this parse [expr {int([$editor index insert])}]
update
}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/exports.tcl b/lib/editor/exports.tcl
index 2ce2ed4..26441c7 100755..100644
--- a/lib/editor/exports.tcl
+++ b/lib/editor/exports.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _EXPORTS_TCL ] } {
+set _EXPORTS_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements exports to other data formats (XHTML && LaTeX)
@@ -73,9 +78,9 @@ public method highlight_all {} {
public method getDataAsXHTML_count_of_iterations {} {
set result 0
foreach tag_def [concat \
- ${ASMsyntaxHighlight::hightlight_tags} \
- ${CsyntaxHighlight::hightlight_tags} \
- ${LSTsyntaxHighlight::hightlight_tags} \
+ ${ASMsyntaxHighlight::highlight_tags} \
+ ${CsyntaxHighlight::highlight_tags} \
+ ${LSTsyntaxHighlight::highlight_tags} \
] {
set range [$editor tag ranges [lindex $tag_def 0]]
incr result [llength $range]
@@ -91,8 +96,8 @@ public method getDataAsLaTeX_abort_now {} {
}
## Export editor content as LaTeX source (include colors)
- # @return String - LaTeX source code
-public method getDataAsLaTeX {} {
+ # @parm File file - Target data channel
+public method getDataAsLaTeX {file} {
# Reset abort variables
set getDataAsLaTeX_abort 0
@@ -122,22 +127,22 @@ public method getDataAsLaTeX {} {
}
# Create LaTeX preamble
- set latex "\\documentclass\[a4paper,12pt\]{article}"
- append latex "\n\n% Creator: ${::APPNAME}\n\n"
- append latex "\\usepackage\[utf-8\]{inputenc}\n"
- append latex "\\usepackage\[T1\]{fontenc}\n"
- append latex "\\usepackage{color}\n"
- append latex "\\title{$filename}\n"
- append latex "\\date{[clock format [clock seconds] -format {%D}]}\n"
- append latex "\n% define highlighting\n"
+ puts -nonewline $file "\\documentclass\[a4paper,12pt\]{article}"
+ puts -nonewline $file "\n\n% Creator: ${::APPNAME}\n\n"
+ puts -nonewline $file "\\usepackage\[utf8\]{inputenc}\n"
+ puts -nonewline $file "\\usepackage\[T1\]{fontenc}\n"
+ puts -nonewline $file "\\usepackage{color}\n"
+ puts -nonewline $file "\\title{$filename}\n"
+ puts -nonewline $file "\\date{[clock format [clock seconds] -format {%D}]}\n"
+ puts -nonewline $file "\n% define highlighting\n"
## Determinate highlighting tag ranges and define colors for 'color' package
set ranges {}
# Iterate over predefined highlighting tags
foreach tag_def [concat \
- ${ASMsyntaxHighlight::hightlight_tags} \
- ${CsyntaxHighlight::hightlight_tags} \
- ${LSTsyntaxHighlight::hightlight_tags} \
+ ${ASMsyntaxHighlight::highlight_tags} \
+ ${CsyntaxHighlight::highlight_tags} \
+ ${LSTsyntaxHighlight::highlight_tags} \
] {
# Conditional abort
@@ -148,13 +153,24 @@ public method getDataAsLaTeX {} {
# Local variables
set color [lindex $tag_def 1] ;# RGB color
- set red [string range $color 1 2] ;# Color - RED
- set green [string range $color 3 4] ;# Color - GREEN
- set blue [string range $color 5 6] ;# Color - BLUE
set tag [lindex $tag_def 0] ;# Tag name
set range [$editor tag ranges $tag] ;# List of tag ranges
set len [llength $range] ;# Number of ranges
- set mirror_tag {} ;# Tag with exatly the same highlight
+ set mirror_tag {} ;# Tag with exatly the same highlight
+
+ # Convert 48b color format to 24b format
+ if {[string length $color] == 13} {
+ set new_color {#}
+ for {set i 1} {$i < [string length $color]} {incr i 4} {
+ append new_color [string range $color $i [expr {$i + 1}]]
+ }
+ set color $new_color
+ }
+
+ # Decompose the color code
+ set red [string range $color 1 2] ;# Color - RED
+ set green [string range $color 3 4] ;# Color - GREEN
+ set blue [string range $color 5 6] ;# Color - BLUE
# Determinate mirror tag
switch -- $tag {
@@ -163,7 +179,7 @@ public method getDataAsLaTeX {} {
}
if {$mirror_tag != {}} {
set mirror_range [$editor tag ranges $mirror_tag]
- } {
+ } else {
set mirror_range {}
}
@@ -179,7 +195,7 @@ public method getDataAsLaTeX {} {
set green [string range [expr "0x$green / 255.0"] 0 4]
set blue [string range [expr "0x$blue / 255.0"] 0 4]
# Define color (for package color)
- append latex "\\definecolor{highlight_$tag}{rgb}{$red, $green, $blue}\n"
+ puts -nonewline $file "\\definecolor{highlight_$tag}{rgb}{$red, $green, $blue}\n"
# Adjust map of text tags
set mirror_tag {}
@@ -220,7 +236,7 @@ public method getDataAsLaTeX {} {
set spaces 0
set correction 0
- while 1 {
+ while {1} {
set idx [string first "\t" $textLine [expr {$idx + 1}]]
if {$idx == -1} {break}
@@ -258,7 +274,7 @@ public method getDataAsLaTeX {} {
# Determinate string to insert
if {[lindex $range 2]} {
set tag "'\{\\color{highlight_[lindex $range 1]}\\verb'"
- } {
+ } else {
set tag "'\}\\verb'"
}
@@ -289,13 +305,10 @@ public method getDataAsLaTeX {} {
regsub -all "\a" $text {'\\verb"'"\\verb'} text
# Create final LaTeX document
- append latex "\n\n\\begin{document}\n"
- append latex "\\ \\\\\n"
- append latex $text
- append latex "\n\\end{document}"
-
- # Return result
- return $latex
+ puts -nonewline $file "\n\n\\begin{document}\n"
+ puts -nonewline $file "\\ \\\\\n"
+ puts -nonewline $file $text
+ puts -nonewline $file "\n\\end{document}"
}
## Abort export to XHTML
@@ -305,8 +318,8 @@ public method getDataAsXHTML_abort_now {} {
}
## Export editor content as XHTML source (include colors)
- # @return String - XHTML source code
-public method getDataAsXHTML {} {
+ # @parm File file - Target data channel
+public method getDataAsXHTML {file} {
# Reset abort variables
set getDataAsXHTML_abort 0
@@ -336,26 +349,26 @@ public method getDataAsXHTML {} {
}
# Create XHTML header
- set html "<?xml version='1.0' encoding='utf-8' standalone='no'?>\n"
- append html "<!DOCTYPE html PUBLIC\n"
- append html "\t'-//W3C//DTD XHTML 1.1//EN'\n"
- append html "\t'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>\n"
- append html "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>\n"
- append html "<!--\n\tCreator: ${::APPNAME}\n\tDate: [clock format [clock seconds] -format {%D}]\n-->\n"
- append html "\t<head>\n"
- append html "\t\t<title>$filename</title>\n"
- append html "\t\t<meta http-equiv=\"Content-Type\" content=\"application/xhtml+xml; charset=UTF-8\" />\n"
- append html "\t\t<meta name=\"Generator\" content=\"${::APPNAME}\" />\n"
- append html "\t\t<style type=\"text/css\">\n"
- append html "\t\t\tbody {\n\t\t\t\tfont-family: $fontFamily;\n\t\t\t\tfont-size: ${fontSize}px;\n\t\t\t}\n"
+ puts -nonewline $file "<?xml version='1.0' encoding='utf-8' standalone='no'?>\n"
+ puts -nonewline $file "<!DOCTYPE html PUBLIC\n"
+ puts -nonewline $file "\t'-//W3C//DTD XHTML 1.1//EN'\n"
+ puts -nonewline $file "\t'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>\n"
+ puts -nonewline $file "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>\n"
+ puts -nonewline $file "<!-- Creator: ${::APPNAME} -->\n"
+ puts -nonewline $file "\t<head>\n"
+ puts -nonewline $file "\t\t<title>$filename</title>\n"
+ puts -nonewline $file "\t\t<meta http-equiv=\"Content-Type\" content=\"application/xhtml+xml; charset=UTF-8\" />\n"
+ puts -nonewline $file "\t\t<meta name=\"Generator\" content=\"${::APPNAME}\" />\n"
+ puts -nonewline $file "\t\t<style type=\"text/css\">\n"
+ puts -nonewline $file "\t\t\tbody {\n\t\t\t\tfont-family: $fontFamily;\n\t\t\t\tfont-size: ${fontSize}px;\n\t\t\t}\n"
## Determinate highlighting tag ranges and define inline CSS
set ranges {}
# Iterate over predefined highlighting tags
foreach tag_def [concat \
- ${ASMsyntaxHighlight::hightlight_tags} \
- ${CsyntaxHighlight::hightlight_tags} \
- ${LSTsyntaxHighlight::hightlight_tags} \
+ ${ASMsyntaxHighlight::highlight_tags} \
+ ${CsyntaxHighlight::highlight_tags} \
+ ${LSTsyntaxHighlight::highlight_tags} \
] {
# Conditional abort
@@ -377,7 +390,7 @@ public method getDataAsXHTML {} {
}
if {$mirror_tag != {}} {
set mirror_range [$editor tag ranges $mirror_tag]
- } {
+ } else {
set mirror_range {}
}
@@ -388,19 +401,30 @@ public method getDataAsXHTML {} {
# Adjust tag name
set tag [string replace $tag 0 3]
+ set color [lindex $tag_def 1]
+
+ # Convert 48b color format to 24b format
+ if {[string length $color] == 13} {
+ set new_color {#}
+ for {set i 1} {$i < [string length $color]} {incr i 4} {
+ append new_color [string range $color $i [expr {$i + 1}]]
+ }
+ set color $new_color
+ }
+
# create CSS
- append html "\t\t\t.$tag {\n"
- append html "\t\t\t\tcolor: [lindex $tag_def 1];\n"
+ puts -nonewline $file "\t\t\t.$tag {\n"
+ puts -nonewline $file "\t\t\t\tcolor: $color;\n"
if {[lindex $tag_def 2]} {
- append html "\t\t\t\ttext-decoration: line-through;\n"
+ puts -nonewline $file "\t\t\t\ttext-decoration: line-through;\n"
}
if {[lindex $tag_def 3]} {
- append html "\t\t\t\tfont-style: italic;\n"
+ puts -nonewline $file "\t\t\t\tfont-style: italic;\n"
}
if {[lindex $tag_def 4]} {
- append html "\t\t\t\tfont-weight: bold;\n"
+ puts -nonewline $file "\t\t\t\tfont-weight: bold;\n"
}
- append html "\t\t\t}\n"
+ puts -nonewline $file "\t\t\t}\n"
for {set i 0} {$i < $len} {incr i} {
lappend ranges [list [lindex $range $i] $tag 1]
@@ -416,8 +440,8 @@ public method getDataAsXHTML {} {
}
}
}
- append html "\t\t</style>\n"
- append html "\t</head>\n"
+ puts -nonewline $file "\t\t</style>\n"
+ puts -nonewline $file "\t</head>\n"
# Sort tag ranges (recursive)
set ranges [lsort -command "::FileList::editor__sort_tag_ranges" $ranges]
@@ -457,7 +481,7 @@ public method getDataAsXHTML {} {
# Deterinate string to insert
if {[lindex $range 2]} {
set tag "span class='[lindex $range 1]'"
- } {
+ } else {
set tag {/span}
}
@@ -475,12 +499,13 @@ public method getDataAsXHTML {} {
regsub -all "\b" $text {\&gt;} text
# Create final XHTML document
- append html "\t<body>\n\t\t<pre>\n"
- append html "\t\t<!-- CODE BLOCK - begin -->\n"
- append html $text
- append html "\t\t<!-- CODE BLOCK - end -->\n"
- append html "\t\t</pre>\n\t</body>\n</html>"
-
- # Return result
- return $html
+ puts -nonewline $file "\t<body>\n\t\t<pre>\n"
+ puts -nonewline $file "\t\t<!-- CODE BLOCK - begin -->\n"
+ puts -nonewline $file $text
+ puts -nonewline $file "\t\t<!-- CODE BLOCK - end -->\n"
+ puts -nonewline $file "\t\t</pre>\n\t</body>\n</html>"
+}
+
+# >>> File inclusion guard
}
+# <<< File inclusion guard
diff --git a/lib/editor/generalproc.tcl b/lib/editor/generalproc.tcl
index f73be85..3bf8767 100755..100644
--- a/lib/editor/generalproc.tcl
+++ b/lib/editor/generalproc.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,6 +21,11 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _GENERALPROC_TCL ] } {
+set _GENERALPROC_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# Implements general purpose procedures
@@ -43,7 +48,7 @@ public method switch_sel_mode {} {
if {$selection_mode} {
adjust_selection_to_block
$sel_mode_lbl configure -text [mc "BLK"] -fg #0088CC
- } {
+ } else {
if {[llength [$editor tag nextrange sel 1.0]]} {
$editor tag add sel sel.first sel.last
}
@@ -73,7 +78,7 @@ public method getBreakpoints {} {
# @parm Bool inSelection - Search in the selected block / search globaly
# @parm String Sindex - index in the text where the search should start
# @parm String String - String to search
- # @return List - {indexMatchBegining indexMatchEnd matchesCount}
+ # @return List - {indexMatchBeginning indexMatchEnd matchesCount}
public method find {fromCursor Backwards regExp noCase inSelection Sindex String} {
## adjust search options
@@ -85,10 +90,10 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String
if {$inSelection} {
set Sindex sel.first
set Eindex sel.last
- } {
+ } else {
if {$Backwards} {
set Eindex 1.0
- } {
+ } else {
set Eindex {end}
}
}
@@ -97,12 +102,12 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String
if {$fromCursor} {
# Sindex
set Sindex {insert}
- } {
+ } else {
# Sindex
if {$Sindex == {}} {
if {$Backwards} {
set Sindex end
- } {
+ } else {
set Sindex 1.0
}
}
@@ -112,7 +117,7 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String
if {$Backwards} {
append Sindex -[expr {[string length $String] - 1}]c
set direction {-backwards}
- } {
+ } else {
set direction {-forwards}
}
@@ -125,7 +130,7 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String
set index [$editor search $direction $regexp -nocase \
-count {::editor_search_count} -- \
$String $Sindex $Eindex]
- } {
+ } else {
set index [$editor search $direction $regexp \
-count {::editor_search_count} -- \
$String $Sindex $Eindex]
@@ -149,14 +154,14 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String
# Goto line with the found match and select that matched string
if {$Backwards} {
goto $lineNumber.$colNumber
- } {
+ } else {
goto $lineNumber.$end_col
}
$editor tag remove sel 1.0 end
$editor tag add sel $index $lineNumber.$end_col
- # set result acording to values determinated above
+ # set result according to values determinated above
set matches "$index $lineNumber.$end_col ${::editor_search_count}"
- } {
+ } else {
# set result to something like 'nothing found'
set matches "$Sindex $Sindex 0"
}
@@ -196,33 +201,58 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme
if {$critical_edit_proc} {return 0}
set critical_edit_proc 1
- ## Derminate indexes of area to be affected
+ ## Derminate indexes of the area to be affected
if {$fromCursor} {
# from actual cursor position
set index {insert}
- } {
+ } else {
if {$Backwards} {
set index {end}
- } {
+ } else {
set index 1.0
}
}
## Perform replacement for each match
- while $remaining {
+ set index_org {}
+ set index_new {}
+ while {1} {
# Initiate search and determinate count of remaining matches
- set result [find $fromCursor $Backwards $regExp $noCase 0 $index $SearchString]
-
- set remaining [lindex $result 2]
- if {$remaining == 0} {break}
-
- # Determinate index where to reinitiate search
- set index [lindex $result [expr {!$Backwards}]]
+ set last_chance 0
+ while {1} {
+ set result [find $fromCursor $Backwards $regExp $noCase 0 $index $SearchString]
+
+ set remaining [lindex $result 2]
+ if {$remaining == 0} {break}
+
+ # Determinate index where to reinitiate search
+ set index_org $index_new
+ set index [lindex $result [expr {!$Backwards}]]
+ set index_new $index
+ if {$index_org == $index} {
+ if {$last_chance} {
+ break
+ } else {
+ if {!$Backwards} {
+ set index [$editor index [list $index {+1c}]]
+ } else {
+ set index [$editor index [list $index {-1c}]]
+ }
+ set last_chance 1
+ }
+ } else {
+ set last_chance 0
+ break
+ }
+ }
+ if {$last_chance || $remaining == 0 || $remaining == {}} {
+ break
+ }
- # "Annoy user" if there is requested confirmation before each replace
+ # Ask user if there is requested confirmation before each replace
if {$confirm} {
# invoke confirmation command and setup new parameters
- switch [$confirmCMD] {
+ switch -- [$confirmCMD] {
0 { ;# Replace
set cnd 1
}
@@ -246,8 +276,8 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme
break
}
}
- } {
- # automaticaly replace all without any prompt
+ } else {
+ # automatically replace all without any prompt
set cnd 1
}
@@ -272,7 +302,7 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme
for {set line $start} {$line <= $end} {incr line} {
parse $line
}
- } {
+ } else {
for {set line $start} {$line <= $end} {incr line} {
restore_line_markers $line
}
@@ -303,9 +333,9 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme
# @return void
public method select_all {} {
catch {
- $editor tag remove sel 1.0 end
+ $editor tag remove sel 1.0 end
}
- $editor tag add sel 1.0 end
+ $editor tag add sel 1.0 end
}
## Comment the selected area or current line
@@ -323,7 +353,7 @@ public method comment {} {
if {[getselection] == {}} {
set restore_sel 0
set end $start
- } {
+ } else {
set restore_sel 1
set start [expr {int([$editor index sel.first])}]
set end_o [$editor index sel.last]
@@ -345,7 +375,7 @@ public method comment {} {
set by_lines 1
set restore_sel 0
set end $start
- } {
+ } else {
set start_o [$editor index sel.first]
set start [expr {int($start_o)}]
set end_o [$editor index sel.last]
@@ -353,7 +383,7 @@ public method comment {} {
if {$end == $end_o && $start == $start_o} {
set restore_sel 1
set by_lines 1
- } {
+ } else {
set restore_sel 0
set by_lines 0
}
@@ -370,7 +400,7 @@ public method comment {} {
restore_line_markers $line
}
# Comment only selected characters
- } {
+ } else {
$editor insert $end_o { */}
$editor insert $start_o {/* }
$editor tag add sel sel.first-3c sel.last+3c
@@ -388,7 +418,7 @@ public method comment {} {
# Restore highlight
if {$prog_language == 1 && ![string index $highlighted_lines $start] == 6} {
parse $start
- } {
+ } else {
for {set i $start} {$i <= $end} {incr i} {
parse $i
}
@@ -417,7 +447,7 @@ public method uncomment {} {
if {[getselection] == {}} {
set restore_sel 0
set end $start
- } {
+ } else {
set restore_sel 1
set start [expr {int([$editor index sel.first])}]
set end_o [$editor index sel.last]
@@ -431,7 +461,7 @@ public method uncomment {} {
set line_data [$editor get $line.0 "$line.0 lineend"]
if {[regexp {^\s*;\s*} $line_data comment]} {
- detete_text_in_editor $line.0 $line.[string length $comment]
+ detete_text_in_editor $line.0 $line.[string length $comment] 0
regsub {;} $comment {} comment
$editor insert $line.0 $comment
restore_line_markers $line
@@ -447,7 +477,7 @@ public method uncomment {} {
set by_lines 1
set restore_sel 0
set end $start
- } {
+ } else {
set start_o [$editor index sel.first]
set start [expr {int($start_o)}]
set end_o [$editor index sel.last]
@@ -455,7 +485,7 @@ public method uncomment {} {
if {$end == $end_o && $start == $start_o} {
set restore_sel 1
set by_lines 1
- } {
+ } else {
set restore_sel 0
set by_lines 0
}
@@ -476,8 +506,8 @@ public method uncomment {} {
set succesful 1
set start_data [string length $start_data]
set end_data [string length $end_data]
- detete_text_in_editor $end_o-${end_data}c $end_o
- detete_text_in_editor $start_o $start_o+${start_data}c
+ detete_text_in_editor $end_o-${end_data}c $end_o 0
+ detete_text_in_editor $start_o $start_o+${start_data}c 0
}
}
@@ -486,13 +516,13 @@ public method uncomment {} {
set line_data [$editor get $line.0 [list $line.0 lineend]]
if {[regexp {^\s*// ?} $line_data line_data]} {
set line_data [string length $line_data]
- detete_text_in_editor $line.0 $line.$line_data
+ detete_text_in_editor $line.0 $line.$line_data 0
manage_autocompletion_list $line
set succesful 1
}
restore_line_markers $line
}
- } {
+ } else {
$editor edit separator
$editor configure -autoseparators 1
return $succesful
@@ -504,7 +534,7 @@ public method uncomment {} {
# Restore highlight
if {$prog_language == 1 && ![string index $highlighted_lines $start] == 6} {
parse $start
- } {
+ } else {
for {set i $start} {$i <= $end} {incr i} {
parse $i
}
@@ -517,6 +547,13 @@ public method uncomment {} {
}
+ # Perform spell checking for all the affected lines
+ if {$spellchecker_enabled} {
+ for {set i $start} {$i <= $end} {incr i} {
+ spellcheck_check_all $i
+ }
+ }
+
# Return result
return $succesful
}
@@ -545,7 +582,7 @@ public method goto {textIndex} {
[$editor index "$textIndex +1 line linestart"]
}
recalc_status_counter {} 0
- update idle
+ update idletasks
$editor see insert
}
@@ -599,7 +636,7 @@ public method indent {} {
set restore_sel 0
set start [expr {int([$editor index insert])}]
set end $start
- } {
+ } else {
set restore_sel 1
set start [expr {int([$editor index sel.first])}]
set end_o [$editor index sel.last]
@@ -610,7 +647,7 @@ public method indent {} {
# indent each line in the block
if {$spaces_no_tabs} {
set indent_char [string repeat { } $number_of_spaces]
- } {
+ } else {
set indent_char "\t"
}
for {set line $start} {$line <= $end} {incr line} {
@@ -635,7 +672,7 @@ public method unindent {} {
set restore_sel 0
set start [expr {int([$editor index insert])}]
set end [expr {int([$editor index insert])}]
- } {
+ } else {
set restore_sel 1
set start [expr {int([$editor index sel.first])}]
set end_o [$editor index sel.last]
@@ -655,7 +692,7 @@ public method unindent {} {
} elseif {[regexp {^\t} $line_data]} {
detete_text_in_editor $line.0 $line.1
}
- } {
+ } else {
if {[regexp {^[\t( )]} $line_data]} {
detete_text_in_editor $line.0 $line.1
}
@@ -717,15 +754,15 @@ public method get_md5 {} {
## Add/Remove bookmark to/from current line
# Directly depends on variable "bookmarks" (managed by proc. recalc_left_frame)
- # @parm Int = NULL - target text index
+ # @parm Int idx=NULL - target text index
# @return bool - 0: bookmark removed; 1: bookmark created
-public method Bookmark args {
+public method Bookmark {{idx {}}} {
if {$editor_to_use} {return}
# Determinate line number
- if {$args != {}} {
- set lineNumber [expr {int($args)}]
- } {
+ if {$idx != {}} {
+ set lineNumber [expr {int($idx)}]
+ } else {
set lineNumber [expr {int([$editor index insert])}]
}
@@ -758,10 +795,10 @@ public method Bookmark args {
$iconBorder image create $lineNumber_i.0 \
-image ::ICONS::16::dot \
-align center
- } {
+ } else {
if {[llength [$editor tag nextrange tag_error $lineNumber.0 [list $lineNumber.0 lineend]]]} {
set image {bm_ex}
- } {
+ } else {
set image {bookmark}
}
$iconBorder image create $lineNumber_i.0 \
@@ -769,7 +806,7 @@ public method Bookmark args {
-align center
}
# Remove icon
- } {
+ } else {
$iconBorder delete $lineNumber_i.0 $lineNumber_i.2
if {
[llength [$editor tag nextrange tag_error $lineNumber.0 [list $lineNumber.0 lineend]]]
@@ -794,14 +831,14 @@ public method Bookmark args {
$parentObject rightPanel_add_bookmark $lineNumber
$parentObject rightPanel_bm_select $lineNumber
# Remove the tag
- } {
+ } else {
$editor tag remove tag_bookmark $lineNumber.0 $tmp.0
$parentObject rightPanel_remove_bookmark $lineNumber
$parentObject rightPanel_bm_unselect
}
# Enable scrolling
- update idle
+ update idletasks
set scroll_in_progress 0
# Done ...
@@ -810,14 +847,14 @@ public method Bookmark args {
## Add/Remove breapoint to/from current line
# Directly depends on variable "breakpoints" (managed by proc. recalc_left_frame)
- # @parm Int = NULL - target text index
+ # @parm Int idx=NULL - target text index
# @return bool - 0: breakpoint removed; 1: breakpoint created; or {}
-public method Breakpoint args {
+public method Breakpoint {{idx {}}} {
# Determinate line number
- if {$args != {}} {
- set lineNumber [expr {int($args)}]
- } {
+ if {$idx != {}} {
+ set lineNumber [expr {int($idx)}]
+ } else {
set lineNumber [expr {int([$editor index insert])}]
}
@@ -844,12 +881,21 @@ public method Breakpoint args {
# Add the tag
if {$make} {
- $lineNumbers tag add tag_breakpoint $lineNumber_i.0 $tmp.0
+ # Detereminate whether the breakpoint will be valid or not
+ if {[is_breakpoint_valid $lineNumber]} {
+ set tag {tag_breakpoint}
+ } else {
+ set tag {tag_breakpoint_INVALID}
+ }
+
+ $lineNumbers tag add $tag $lineNumber_i.0 $tmp.0
$parentObject rightPanel_add_breakpoint $lineNumber
$parentObject rightPanel_bp_select $lineNumber
+
# Remove the tag
- } {
+ } else {
$lineNumbers tag remove tag_breakpoint $lineNumber_i.0 $tmp.0
+ $lineNumbers tag remove tag_breakpoint_INVALID $lineNumber_i.0 $tmp.0
$parentObject rightPanel_remove_breakpoint $lineNumber
$parentObject rightPanel_bp_unselect
}
@@ -863,7 +909,7 @@ public method Breakpoint args {
}
# Enable scrolling
- update idle
+ update idletasks
set scroll_in_progress 0
# done ...
@@ -910,6 +956,7 @@ public method clear_all_breakpoints {} {
# Clear breakpoint tags from line numbers
$lineNumbers tag remove tag_breakpoint 1.0 end
+ $lineNumbers tag remove tag_breakpoint_INVALID 1.0 end
# Clear right panel
$parentObject rightPanel_clear_all_breakpoints
@@ -991,7 +1038,7 @@ public method insertData {data position} {
# Insert data
$editor insert $position [regsub -all {[\u0000-\u0008\u000B-\u000C\u000E-\u001F\u007F-\u009F]} $data {}]
# Highlight
- update idle
+ update idletasks
parseAll
}
@@ -1065,7 +1112,7 @@ private method get_count_of_lines {index0 index1} {
# Translate tabulators to spaces
set idx -1
set cor 0
- while 1 {
+ while {1} {
set idx [string first "\t" $lineText [expr {$idx + 1}]]
if {$idx == -1} {break}
@@ -1076,7 +1123,7 @@ private method get_count_of_lines {index0 index1} {
set line_width [font measure $defaultFont_bold -displayof $editor $lineText]
incr line_width [expr {$cor * $defaultCharWidth}]
# Line doesn't contain tabulators
- } {
+ } else {
set line_width [font measure $defaultFont_bold -displayof $editor $lineText]
}
@@ -1090,14 +1137,6 @@ private method get_count_of_lines {index0 index1} {
return $new_wrap
}
-## Get data of bookmarks and breapoints
- # @return List - {bookmarks breakpoints} (eg. {00011 10100})
-public method export_line_markers_data {} {
- set result [join $bookmarks {}]
- lappend result [join $breakpoints {}]
- return $result
-}
-
## Get total number of lines in editor
# @return Int - result
public method getLinesCount {} {
@@ -1107,28 +1146,66 @@ public method getLinesCount {} {
return [expr {int($result) - 1}]
}
+## Get data of bookmarks and breapoints
+ # @return List - {bookmarks breakpoints} (eg. {{1 15 96} {2 45}})
+public method export_line_markers_data {} {
+ set foo [lsearch -ascii -exact -all $bookmarks 1]
+ if {![llength $foo]} {
+ set foo 0
+ }
+ set bar [lsearch -ascii -exact -all $breakpoints 1]
+ if {![llength $bar]} {
+ set bar 0
+ }
+ return [list $foo $bar]
+}
+
## Import list of bookmarks and breapoints
# This function also validates given input data
# This function does not do anything with the right panel
- # @parm String Bookmarks - bookmakrs (eg. 00011010)
- # @parm String Breakpoints - breakpoints (eg. 011010000000)
+ # @parm String Bookmarks - bookmakrs (eg. {1 15 96})
+ # @parm String Breakpoints - breakpoints (eg. {2 45})
# @return void
public method import_line_markers_data {Bookmarks Breakpoints} {
if {$editor_to_use} {return}
+ # Determinate number of the last line in the editor
+ set lastEnd [expr {int([$editor index end])}]
+
# Check validity of the given data
- if {![regexp {^[01]*$} $Bookmarks]} {
- puts stderr [mc "Invalid list of bookmarks -- bookmarks discarded"]
+ if {[string index $Bookmarks 0] == {0}} {
+ if {![regexp {^[01]*$} $Bookmarks]} {
+ puts stderr [mc "Invalid list of bookmarks -- bookmarks discarded"]
+ set Bookmarks {}
+ }
+ } else {
+ set foo $Bookmarks
set Bookmarks {}
+ for {set i 0} {$i <= $lastEnd} {incr i} {
+ if {[lsearch -ascii -exact $foo $i] != -1} {
+ append Bookmarks 1
+ } else {
+ append Bookmarks 0
+ }
+ }
}
- if {![regexp {^[01]*$} $Breakpoints]} {
- puts stderr [mc "Invalid list of breakpoints -- bookmarks discarded"]
+ if {[string index $Breakpoints 0] == {0}} {
+ if {![regexp {^[01]*$} $Breakpoints]} {
+ puts stderr [mc "Invalid list of breakpoints -- bookmarks discarded"]
+ set Breakpoints {}
+ }
+ } else {
+ set foo $Breakpoints
set Breakpoints {}
+ for {set i 0} {$i <= $lastEnd} {incr i} {
+ if {[lsearch -ascii -exact $foo $i] != -1} {
+ append Breakpoints 1
+ } else {
+ append Breakpoints 0
+ }
+ }
}
- # Determinate number of the last line in the editor
- set lastEnd [expr {int([$editor index end])}]
-
# Initialize list of highlighted lines
set highlighted_lines [string repeat 0 $lastEnd]
@@ -1164,7 +1241,7 @@ public method import_line_markers_data {Bookmarks Breakpoints} {
$iconBorder image create $line.0 \
-image ::ICONS::16::dot \
-align center
- } {
+ } else {
$iconBorder image create $line.0 \
-image ::ICONS::16::bookmark \
-align center
@@ -1269,7 +1346,7 @@ public method set_lock {bool} {
DynamicHelp::add $Sbar_lock_file -text [mc "Unlock file switching"]
$Sbar_lock_file configure \
-image ::ICONS::16::lock
- } {
+ } else {
setStatusTip -widget $Sbar_lock_file -text [mc "File switching unlocked"]
Sbar -freeze [mc "File switching unlocked"]
DynamicHelp::add $Sbar_lock_file -text [mc "Lock file switching"]
@@ -1280,12 +1357,18 @@ public method set_lock {bool} {
}
## Invert simulator lock
- # @retunr void
+ # @return void
public method invert_lock {} {
set_lock [expr {!$auto_switching_lock}]
$parentObject set_editor_lock $this $auto_switching_lock
}
+## Get value of internal flag "frozen"
+ # @return Bool - True if the editor is in simulator mode, or disabled mode
+public method get_flag_frozen {} {
+ return $frozen
+}
+
## Switch from editor mode to simulator mode
# This operation will cause error if editor is in mode disabled
# @return void
@@ -1309,7 +1392,7 @@ public method freeze {} {
if {!$frozen} {
pack $Sbar_ssim_mode -side right
pack $Sbar_lock_file -side left
- } {
+ } else {
pack $Sbar_sim_mode -side right
}
# Disable some popup menu items
@@ -1357,7 +1440,6 @@ public method thaw {} {
if {!$ro_mode} {
$editor configure -state normal
}
- focus -force $editor
set idx [$editor index "insert linestart"]
$editor tag add tag_current_line $idx "$idx + 1 line"
pack $Sbar_CRT_frame
@@ -1379,6 +1461,11 @@ public method thaw {} {
}
# Recalculate counters
recalc_status_counter {} 0
+
+ # Check the flag "file_change_notif_flg" and if set, inform the user
+ #+ about modification to the currently opened file done by another
+ #+ program.
+ check_file_change_notif
}
## Move simulator line (line representing current position in simulator engine)
@@ -1442,12 +1529,15 @@ public method highlight_visible_area {} {
# Highlight the current view
for {set line $start} {$line <= $end} {incr line} {
if {[string index $highlighted_lines $line] == 0} {
- if {![parse $line]} {
+ if {![parse $line 1]} {
if {$line != $start} {break}
}
}
}
+ # Ensure that the current line is also checked for correct spelling
+ spellcheck_check_all [expr {int([$editor index insert])}] 1
+
# Restore previous editor state
if {$frozen} {$editor configure -state disabled}
}
@@ -1458,6 +1548,7 @@ public method highlight_visible_area {} {
# if it is not then invoke procedure 'X::__save_as'
# @return Bool - result
public method save {} {
+ if {$ro_mode} {return 1}
if {$editor_to_use} {return 1}
if {$save_in_progress} {return 1}
set save_in_progress 1
@@ -1474,9 +1565,13 @@ public method save {} {
catch {
file rename -force $fullFileName "$fullFileName~"
}
+
+ # Stop watching for modification of this file on disk (we will reenable it later)
+ FSnotifications::forget $fullFileName
}
+
if {[catch {
- set chanel [open $fullFileName w 420]
+ set chanel [open $fullFileName w 0640]
}]} then {
tk_messageBox \
-parent . \
@@ -1485,6 +1580,10 @@ public method save {} {
-title [mc "Permission denied"] \
-message [mc "Unable to open file:\n\"%s\"\nfor writing" $fullFileName]
set save_in_progress 0
+
+ # Again start watching for modification of this file on disk
+ FSnotifications::watch $fullFileName [list ::Editor::file_change_notif $this]
+
return 0
}
fconfigure $chanel -translation $eol -encoding $encoding
@@ -1494,6 +1593,9 @@ public method save {} {
$editor edit modified 0
set modified 0
+ # Again start watching for modification of this file on disk
+ FSnotifications::watch $fullFileName [list ::Editor::file_change_notif $this]
+
# Stop autosave timer
catch {
after cancel $autosave_timer
@@ -1501,17 +1603,174 @@ public method save {} {
}
# Change application status
- Sbar [mc "File %s saved" $fullFileName]
::X::adjust_title
set save_in_progress 0
if {$fullFileName == {}} {
return 0
- } {
+ } else {
+ if {$::MICROSOFT_WINDOWS} { ;# "/" --> "\"
+ regsub -all {/} $fullFileName "\\" fullFileName_win
+ } else {
+ set fullFileName_win $fullFileName
+ }
+ Sbar [mc "File %s saved" $fullFileName_win]
return 1
}
}
+## Set internal flag "file_change_notif_flg" to true
+ #
+ # The flag indicates that the file opened in this editor was modified on disk
+ # by another program. The flag is automatically cleared when the user is
+ # informed about the modification to the file.
+ #
+ # @return void
+public method set_file_change_notif_flg {} {
+ set file_change_notif_flg 1
+}
+
+## Check flag "file_change_notif_flg" and if set, inform the user about this.
+ #
+ # The flag file_change_notif_flg indicates that the file opened in this editor
+ # was modified on disk by another program. The flag is automatically cleared by
+ # this method. The user is informed via a dialog window giving him three
+ # options, reload the file, overwrite it on disk, and ignore it.
+ #
+ # @return void
+public method check_file_change_notif {} {
+ # Check the flag, and clear it if it was set
+ if {!$file_change_notif_flg} {
+ return
+ }
+ set file_change_notif_flg 0
+
+ # Create the dialog window
+ set dialog [toplevel .file_change_notif_dlg]
+
+ # Create top frame (dialog icon and text of the message)
+ set dlg_top_frame [frame $dialog.top_frame]
+ pack [label $dlg_top_frame.image -image ::ICONS::32::messagebox_warning] -side left -padx 5
+ pack [label $dlg_top_frame.label \
+ -justify left \
+ -text [mc "The file '%s' was modified from outside of this program.\n\nWhat do you want to do with the modified file?" [file tail $fullFileName]] \
+ ] -side left -fill x -expand 1 -padx 5
+
+ # Create bottom bar with dialog buttons
+ set button_frame [frame $dialog.button_frame]
+ pack [ttk::button $button_frame.button_reload \
+ -text [mc "Reload in editor"] \
+ -compound left \
+ -image ::ICONS::16::reload \
+ -command "
+ $parentObject filelist_reload_file $this 1
+ grab release $dialog
+ destroy $dialog
+ " \
+ ] -side left -padx 2
+ pack [ttk::button $button_frame.button_overwrt \
+ -text [mc "Overwrite on disk"] \
+ -compound left \
+ -image ::ICONS::16::filesave \
+ -command "
+ $this save
+ grab release $dialog
+ destroy $dialog
+ " \
+ ] -side left -padx 2
+ pack [ttk::button $button_frame.button_cancel \
+ -text [mc "Do nothing"] \
+ -compound left \
+ -image ::ICONS::16::cancel \
+ -command "
+ grab release $dialog
+ destroy $dialog
+ " \
+ ] -side left -padx 2
+
+ # Pack window frames
+ pack $dlg_top_frame -side top -fill x -expand 1 -padx 5 -pady 10
+ pack $button_frame -side bottom -side right -padx 5 -pady 5
+
+ bind $dialog <Escape> "
+ grab release $dialog
+ destroy $dialog
+ "
+
+ # Set dialog attributes (modal window)
+ wm iconphoto $dialog ::ICONS::16::status_unknown
+ wm title $dialog [mc "File changed on disk"]
+ wm state $dialog normal
+ wm minsize $dialog 400 110
+ wm transient $dialog .
+ wm protocol $dialog WM_DELETE_WINDOW "
+ grab release $dialog
+ destroy $dialog
+ "
+ update
+ catch {
+ grab $dialog
+ }
+ raise $dialog
+ focus -force $button_frame.button_cancel
+ tkwait window $dialog
+}
+
+## File change notification callback
+ #
+ # This function is supposed to be called by the FSnotifications component when
+ # a modification to the currently opened file was made by another program.
+ #
+ # @return void
+proc file_change_notif {editor_ref filename} {
+ # This call is invalid if there are no projects opened
+ if {![llength ${::X::openedProjects}]} {
+ return
+ }
+
+ # Attempt to find the corresponding project and editor index number
+ foreach project ${::X::openedProjects} {
+ set list_of_editors [$project cget -editors]
+ set actual_editor [$project cget -actualEditor]
+ set actual_editor2 [$project cget -actualEditor2]
+ set editor_idx [lsearch -ascii -exact $list_of_editors $editor_ref]
+
+ if {$editor_idx == -1} {
+ # Editor editor index number not found, move on to another project
+ continue
+ }
+
+ # Try to get the "frozen" flag from the editor
+ if {[catch {
+ set editor_frozen [$editor_ref get_flag_frozen]
+ }]} then {
+ # Unable to comply, that probably means that the editor
+ # does not exist any more
+ return
+ }
+
+ # Set the "file_change_notif_flg" flag
+ $project editor_procedure $editor_idx set_file_change_notif_flg {}
+
+ # Check the "file_change_notif_flg" flag right away, if the
+ #+ editor is currently visible to the user
+ if {
+ ($project == ${::X::actualProject})
+ &&
+ ($editor_idx == $actual_editor || $editor_idx == $actual_editor2)
+ } then {
+ # If the editor is in frozen state, i.e. the MCU
+ # simulator is engaged, then don't annoy with nonsense
+ # messages, and instead inform the user later.
+ if {!$editor_frozen} {
+ $project editor_procedure $editor_idx check_file_change_notif {}
+ }
+ }
+
+ break
+ }
+}
+
## Set variable 'fullFileName' for later file save (method 'save')
# note: also change editors status bar
# @parm String full_filename - the full filename (including path)
@@ -1520,6 +1779,16 @@ public method save {} {
public method set_FileName {full_filename rootName} {
if {$editor_to_use} {return}
+ # Start watching for changes in the file (on disk)
+ if {$fullFileName != {}} {
+ # Stop watching the old file
+ FSnotifications::watch forget $fullFileName
+ }
+ if {$full_filename != {}} {
+ # Start watching the new file
+ FSnotifications::watch $full_filename [list ::Editor::file_change_notif $this]
+ }
+
# set variables
set fullFileName $full_filename
set filename $rootName
@@ -1535,7 +1804,7 @@ public method getFileName {} {
return [list [file dirname $fullFileName] $filename]
}
-## Change letter case acording to the given options
+## Change letter case according to the given options
# @parm List options - list of 21 values, each must be one of {- L -U}
# '-' - keep case
# 'U' - Uppercase
@@ -1563,13 +1832,13 @@ public method change_letter_case {options} {
tag_imm_dec tag_imm_bin
tag_imm_constant tag_imm_unknown
tag_macro
- } \
+ } \
{
# Evaluate option
if {$option == {-}} {continue}
if {$option == {U}} {
set option {toupper}
- } {
+ } else {
set option {tolower}
}
@@ -1744,7 +2013,7 @@ public method copy {} {
Sbar [mc "Unable to execute: nothing selected"]
return 0
# Adjust clipboard content
- } {
+ } else {
clipboard clear
clipboard append $data
return 1
@@ -1752,11 +2021,11 @@ public method copy {} {
}
## Paste clipboard content to the text at the cursor position
- # @parm Bool = 0 - Use X selection instead of the clipboard
- # @
- # @
+ # @parm Bool use_X_sel=0 - Use X selection instead of the clipboard
+ # @parm Int x - X coordinate
+ # @parm Int y - Y coordinate
# @return bool - 1: successful; 0: failed
-public method paste args {
+public method paste {{use_X_sel 0} {x {}} {y {}}} {
if {$critical_edit_proc} {return}
set critical_edit_proc 1
@@ -1765,9 +2034,9 @@ public method paste args {
set original_cur_pos [$editor index insert]
}
- if {[lindex $args 0] == {1}} {
+ if {$use_X_sel} {
set cmd {selection}
- } {
+ } else {
set cmd {clipboard}
}
@@ -1780,9 +2049,7 @@ public method paste args {
return 0
}
- if {[lindex $args 0] == {1}} {
- set x [lindex $args 1]
- set y [lindex $args 2]
+ if {$use_X_sel} {
$editor mark set insert @$x,$y
catch {
$editor tag remove sel 0.0 end
@@ -1793,15 +2060,16 @@ public method paste args {
$editor configure -autoseparators 0
deleteselection
recalc_left_frame
- # insert data to the text, restore syntax hightlight and return 1
+ # insert data to the text, restore syntax highlight
$editor insert [$editor index insert] $data
recalc_left_frame
recalc_status_counter {}
$editor see [$editor index insert]
- update idle
+ update idletasks
set line [expr {int([$editor index insert])}]
rightPanel_adjust $line
parse $line
+ spellcheck_check_all $line 2 ;# Perform spell check for the current line
highlight_visible_area
$editor edit separator
$editor configure -autoseparators 1
@@ -1895,7 +2163,7 @@ public method cut {} {
set critical_edit_proc 0
return 0
# Cut
- } {
+ } else {
# Adjust clipboard content
deleteselection
clipboard clear
@@ -1957,8 +2225,10 @@ public method kill_childern {} {
if {$editor_to_use} {
bind $top_frame <Destroy> {}
if {!$::MICROSOFT_WINDOWS} { ;# There is no kill command on Microsoft Windows
- catch {
- exec -- kill $pid
+ if {$pid != [pid] && $pid != 0} {
+ catch {
+ exec -- kill $pid
+ }
}
}
catch {
@@ -1967,7 +2237,7 @@ public method kill_childern {} {
}
}
-## Get ID of file type (programing language used)
+## Get ID of file type (programming language used)
# @return Int - 0 == Assembly language; 1 == C language
public method get_language {} {
if {$prog_language == -1} {
@@ -1979,12 +2249,12 @@ public method get_language {} {
} else {
return 0
}
- } {
+ } else {
return $prog_language
}
}
-## Set file type (programing language used)
+## Set file type (programming language used)
# @parm Int lang - -1 == unknown; 0 == Assembly language; 1 == C language
# @return void
public method force_language {lang} {
@@ -2173,7 +2443,7 @@ public method getFileStatistics {} {
if {$found} {continue}
if {[string is wordchar -strict $char]} {
incr words_and_numbers
- } {
+ } else {
incr others
}
}
@@ -2181,7 +2451,7 @@ public method getFileStatistics {} {
# Determinate line type excluding empty lines
if {$last_words == $words && $last_keywords == $keywords && $last_comments < $comments} {
incr commented_lines
- } {
+ } else {
incr normal_lines
}
}
@@ -2200,12 +2470,22 @@ public method getFileStatistics {} {
}
## Set read only mode
- # @parm Bool mode_frag - 1 == Read only; 0 = Read and write
- # @return void
+ # @parm Bool mode_frag - 1 == Read only; 0 == Read and write
+ # @return Bool - true == ok; false == cannot comply!
public method change_RO_MODE {mode_frag} {
if {$editor_to_use} {return}
set ro_mode $mode_frag
+ if {!$ro_mode && [$parentObject cget -S_flag_read_only]} {
+ tk_messageBox \
+ -parent . \
+ -type ok \
+ -icon warning \
+ -title [mc "Read-only project"] \
+ -message [mc "This project has a special purpose, modifications to this project are not allowed."]
+ return 0
+ }
+
# Set to read only
if {$ro_mode} {
$editor configure -state disabled
@@ -2220,7 +2500,7 @@ public method change_RO_MODE {mode_frag} {
set state {disabled}
# Set to normal mode
- } {
+ } else {
$editor configure -state normal
$ins_mode_lbl configure \
-bg {#DDDDDD} \
@@ -2237,6 +2517,7 @@ public method change_RO_MODE {mode_frag} {
$menu entryconfigure [::mc $entry] -state $state
}
::X::adjust_mainmenu_and_toolbar_to_editor $ro_mode {}
+ return 1
}
## Perform program jump
@@ -2257,7 +2538,7 @@ public method ljmp_this_line {} {
set lineNum [$parentObject simulator_getCurrentLine]
if {$lineNum != {}} {
$parentObject move_simulator_line $lineNum
- } {
+ } else {
$parentObject editor_procedure {} unset_simulator_line {}
}
$parentObject Simulator_sync_PC_etc
@@ -2268,8 +2549,8 @@ public method ljmp_this_line {} {
public method lcall_this_line {} {
if {$editor_to_use} {return}
# Determinate target address
- set address [$parentObject simulator_line2address \
- [expr {int([$editor index insert])}] \
+ set address [$parentObject simulator_line2address \
+ [expr {int([$editor index insert])}] \
[$parentObject simulator_get_filenumber $fullFileName] \
]
if {$address == {}} {
@@ -2281,8 +2562,12 @@ public method lcall_this_line {} {
set lineNum [$parentObject simulator_getCurrentLine]
if {$lineNum != {}} {
$parentObject move_simulator_line $lineNum
- } {
+ } else {
$parentObject editor_procedure {} unset_simulator_line {}
}
$parentObject Simulator_sync_PC_etc
-} \ No newline at end of file
+}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard
diff --git a/lib/editor/spell_check.tcl b/lib/editor/spell_check.tcl
new file mode 100644
index 0000000..7759607
--- /dev/null
+++ b/lib/editor/spell_check.tcl
@@ -0,0 +1,1325 @@
+#!/usr/bin/tclsh
+# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
+
+############################################################################
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
+# martin.osmera@gmail.com #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+# >>> File inclusion guard
+if { ! [ info exists _SPELL_CHECK_TCL ] } {
+set _SPELL_CHECK_TCL _
+# <<< File inclusion guard
+
+# --------------------------------------------------------------------------
+# DESCRIPTION
+# Spell checker interface used by the source code editor.
+#
+# Used spell checker is Hunspell.
+#
+#
+# COMMUNICATION CONNECTIONS WITH HUNSPELL:
+# -----------------------------------------
+#
+# +-------------------+ (4) +----------+ (5) +------------------+
+# | receive_and_print | | | Hunspell | | | external_command |
+# | (RAP) | ---> | | ---> | |
+# +-------------------+ +----------+ +------------------+
+# ^ |--(2) |--3
+# (1)--| v v
+# +--------------------------------------------------------+
+# | spell_check |
+# +--------------------------------------------------------+
+#
+# 1: Send a word to check along with commands to execute in case of correct and wrong spelling
+# 2: Receive the identifier for IPC with the RAP (variable spellchecker_RAP_ID)
+# 3: Receive response from the Hunspell via IPC
+# 4: Send a word to check to the Hunspell via a pipe
+# 5: Receive response from the Hunspell via a pipe
+#
+# --------------------------------------------------------------------------
+
+## COMMON
+common spellchecker_enabled 0 ;# Bool: Flag spell checking enabled
+common spellchecker_dictionary {} ;# String: Dictionary to use (e.g. en_US or cs_CZ)
+common spellchecker_process_pid [list] ;# List of Ints: Process identifiers of the spell checker and support processes
+common spellchecker_command_LIFO [list] ;# List: LIFO for commands invoked by spell checker {correct_spelling_cmd wrong_spelling_cmd}
+common spellchecker_RAP_ID {} ;# String: Application name of ``receive_and_print'' for IPC
+common spellchecker_attempts_to_restart 0 ;# Int: Number of failed attempts to restart the spell checker process
+common spellchecker_started_flag ;# None: When this variable is set that means that the spell checker process has been started
+common spellchecker_start_failed 0 ;# Bool: Flag spellchecker_started_flag was set but the spell checker process was not actually started
+common spellchecker_start_timer {} ;# AfterTimer: Watch dog timer for start of of the spell checker process
+common available_dictionaries [list] ;# List of Strings: Dictionaries available to the Hunspell
+common hunspell_process {} ;# Channel: Hunspell process invoked by command open in order to gain list of dictionaries
+
+## PRIVATE
+private variable spellcheck_line_pre {} ;# String: Content of the line where change_detected_pre was performed
+private variable spellcheck_line_number {} ;# Int: Number of the last line where change_detected_pre was performed, see spellcheck_check_all
+private variable spellcheck_lock 0 ;# Bool: Inhibit method ``spellcheck_check_all''
+
+## COMMON
+
+## List: Language codes and language names according to: ISO-639-1
+ # Format:
+ # {
+ # { Language_Name Language_Code }
+ # ...
+ # }
+common LANGUAGE_CODES_AND_NAMES {
+ {{Abkhazian} {ab}} {{Afar} {aa}}
+ {{Afrikaans} {af}} {{Akan} {ak}}
+ {{Albanian} {sq}} {{Amharic} {am}}
+ {{Arabic} {ar}} {{Aragonese} {an}}
+ {{Armenian} {hy}} {{Assamese} {as}}
+ {{Avaric} {av}} {{Avestan} {ae}}
+ {{Aymara} {ay}} {{Azerbaijani} {az}}
+ {{Bambara} {bm}} {{Bashkir} {ba}}
+ {{Basque} {eu}} {{Belarusian} {be}}
+ {{Bengali} {bn}} {{Bihari languages} {bh}}
+ {{Bislama} {bi}} {{Bokmål, Norwegian} {nb}}
+ {{Bosnian} {bs}} {{Breton} {br}}
+ {{Bulgarian} {bg}} {{Burmese} {my}}
+ {{Castilian} {es}} {{Catalan} {ca}}
+ {{Central Khmer} {km}} {{Chamorro} {ch}}
+ {{Chechen} {ce}} {{Chewa} {ny}}
+ {{Chichewa} {ny}} {{Chinese} {zh}}
+ {{Chuang} {za}} {{Church Slavic} {cu}}
+ {{Church Slavonic} {cu}} {{Chuvash} {cv}}
+ {{Cornish} {kw}} {{Corsican} {co}}
+ {{Cree} {cr}} {{Croatian} {hr}}
+ {{Czech} {cs}} {{Danish} {da}}
+ {{Dhivehi} {dv}} {{Divehi} {dv}}
+ {{Dutch} {nl}} {{Dzongkha} {dz}}
+ {{English} {en}} {{Esperanto} {eo}}
+ {{Estonian} {et}} {{Ewe} {ee}}
+ {{Faroese} {fo}} {{Fijian} {fj}}
+ {{Finnish} {fi}} {{Flemish} {nl}}
+ {{French} {fr}} {{Fulah} {ff}}
+ {{Gaelic} {gd}} {{Galician} {gl}}
+ {{Ganda} {lg}} {{Georgian} {ka}}
+ {{German} {de}} {{Gikuyu} {ki}}
+ {{Greek, Modern} {el}} {{Greenlandic} {kl}}
+ {{Guarani} {gn}} {{Gujarati} {gu}}
+ {{Haitian} {ht}} {{Haitian Creole} {ht}}
+ {{Hausa} {ha}} {{Hebrew} {he}}
+ {{Herero} {hz}} {{Hindi} {hi}}
+ {{Hiri Motu} {ho}} {{Hungarian} {hu}}
+ {{Icelandic} {is}} {{Ido} {io}}
+ {{Igbo} {ig}} {{Indonesian} {id}}
+ {{Interlingue} {ie}} {{Inuktitut} {iu}}
+ {{Inupiaq} {ik}} {{Irish} {ga}}
+ {{Italian} {it}} {{Japanese} {ja}}
+ {{Javanese} {jv}} {{Kalaallisut} {kl}}
+ {{Kannada} {kn}} {{Kanuri} {kr}}
+ {{Kashmiri} {ks}} {{Kazakh} {kk}}
+ {{Kikuyu} {ki}} {{Kinyarwanda} {rw}}
+ {{Kirghiz} {ky}} {{Komi} {kv}}
+ {{Kongo} {kg}} {{Korean} {ko}}
+ {{Kuanyama} {kj}} {{Kurdish} {ku}}
+ {{Kwanyama} {kj}} {{Kyrgyz} {ky}}
+ {{Lao} {lo}} {{Latin} {la}}
+ {{Latvian} {lv}} {{Letzeburgesch} {lb}}
+ {{Limburgan} {li}} {{Limburger} {li}}
+ {{Limburgish} {li}} {{Lingala} {ln}}
+ {{Lithuanian} {lt}} {{Luba-Katanga} {lu}}
+ {{Luxembourgish} {lb}} {{Macedonian} {mk}}
+ {{Malagasy} {mg}} {{Malay} {ms}}
+ {{Malayalam} {ml}} {{Maldivian} {dv}}
+ {{Maltese} {mt}} {{Manx} {gv}}
+ {{Maori} {mi}} {{Marathi} {mr}}
+ {{Marshallese} {mh}} {{Moldavian} {ro}}
+ {{Moldovan} {ro}} {{Mongolian} {mn}}
+ {{Nauru} {na}} {{Navaho} {nv}}
+ {{Navajo} {nv}} {{Ndebele, North} {nd}}
+ {{Ndebele, South} {nr}} {{Ndonga} {ng}}
+ {{Nepali} {ne}} {{North Ndebele} {nd}}
+ {{Northern Sami} {se}} {{Norwegian} {no}}
+ {{Norwegian Bokmål} {nb}} {{Norwegian Nynorsk} {nn}}
+ {{Nuosu} {ii}} {{Nyanja} {ny}}
+ {{Nynorsk, Norwegian} {nn}} {{Occidental} {ie}}
+ {{Occitan} {oc}} {{Ojibwa} {oj}}
+ {{Old Bulgarian} {cu}} {{Old Church Slavonic} {cu}}
+ {{Old Slavonic} {cu}} {{Oriya} {or}}
+ {{Oromo} {om}} {{Ossetian} {os}}
+ {{Ossetic} {os}} {{Pali} {pi}}
+ {{Panjabi} {pa}} {{Pashto} {ps}}
+ {{Persian} {fa}} {{Polish} {pl}}
+ {{Portuguese} {pt}} {{Punjabi} {pa}}
+ {{Pushto} {ps}} {{Quechua} {qu}}
+ {{Romanian} {ro}} {{Romansh} {rm}}
+ {{Rundi} {rn}} {{Russian} {ru}}
+ {{Samoan} {sm}} {{Sango} {sg}}
+ {{Sanskrit} {sa}} {{Sardinian} {sc}}
+ {{Scottish Gaelic} {gd}} {{Serbian} {sr}}
+ {{Shona} {sn}} {{Sichuan Yi} {ii}}
+ {{Sindhi} {sd}} {{Sinhala} {si}}
+ {{Sinhalese} {si}} {{Slovak} {sk}}
+ {{Slovenian} {sl}} {{Somali} {so}}
+ {{Sotho, Southern} {st}} {{South Ndebele} {nr}}
+ {{Spanish} {es}} {{Sundanese} {su}}
+ {{Swahili} {sw}} {{Swati} {ss}}
+ {{Swedish} {sv}} {{Tagalog} {tl}}
+ {{Tahitian} {ty}} {{Tajik} {tg}}
+ {{Tamil} {ta}} {{Tatar} {tt}}
+ {{Telugu} {te}} {{Thai} {th}}
+ {{Tibetan} {bo}} {{Tigrinya} {ti}}
+ {{Tonga} {to}} {{Tsonga} {ts}}
+ {{Tswana} {tn}} {{Turkish} {tr}}
+ {{Turkmen} {tk}} {{Twi} {tw}}
+ {{Uighur} {ug}} {{Ukrainian} {uk}}
+ {{Urdu} {ur}} {{Uyghur} {ug}}
+ {{Uzbek} {uz}} {{Valencian} {ca}}
+ {{Venda} {ve}} {{Vietnamese} {vi}}
+ {{Volapük} {vo}} {{Walloon} {wa}}
+ {{Welsh} {cy}} {{Western Frisian} {fy}}
+ {{Wolof} {wo}} {{Xhosa} {xh}}
+ {{Yiddish} {yi}} {{Yoruba} {yo}}
+ {{Zhuang} {za}} {{Zulu} {zu}}
+}
+
+## List: Country codes with names of their flags file in directory ``${::ROOT_DIRNAME}/icons/flag/''
+ # Format:
+ # {
+ # { Country_Name Country_Code Flag_File_Name_Without_Extension }
+ # ...
+ # }
+common COUNTRY_CODES_AND_FLAGS {
+ {{Afghanistan} AF Afghanistan}
+ {{Åland Islands} AX {}}
+ {{Albania} AL Albania}
+ {{Algeria} DZ Algeria}
+ {{American Samoa} AS American_Samoa}
+ {{Andorra} AD Andorra}
+ {{Angola} AO Angola}
+ {{Anguilla} AI Anguilla}
+ {{Antarctica} AQ {}}
+ {{Antigua And Barbuda} AG Antigua_and_Barbuda}
+ {{Argentina} AR Argentina}
+ {{Armenia} AM Armenia}
+ {{Aruba} AW Aruba}
+ {{Australia} AU Australia}
+ {{Austria} AT Austria}
+ {{Azerbaijan} AZ Azerbaijan}
+
+ {{Bahamas} BS Bahamas}
+ {{Bahrain} BH Bahrain}
+ {{Bangladesh} BD Bangladesh}
+ {{Barbados} BB Barbados}
+ {{Belarus} BY Belarus}
+ {{Belgium} BE Belgium}
+ {{Belize} BZ Belize}
+ {{Benin} BJ Benin}
+ {{Bermuda} BM Bermuda}
+ {{Bhutan} BT Bhutan}
+ {{Bolivia, Plurinational State Of} BO Bolivia}
+ {{Bosnia And Herzegovina} BA Bosnia}
+ {{Botswana} BW Botswana}
+ {{Bouvet Island} BV {}}
+ {{Brazil} BR Brazil}
+ {{British Indian Ocean Territory} IO {}}
+ {{Brunei Darussalam} BN Brunei}
+ {{Bulgaria} BG Bulgaria}
+ {{Burkina Faso} BF Burkina_Faso}
+ {{Burundi} BI Burundi}
+
+ {{Cambodia} KH Cambodia}
+ {{Cameroon} CM Cameroon}
+ {{Canada} CA Canada}
+ {{Cape Verde} CV Cape_Verde}
+ {{Cayman Islands} KY Cayman_Islands}
+ {{Central African Republic} CF Central_African_Republic}
+ {{Chad} TD Chad}
+ {{Chile} CL Chile}
+ {{China} CN China}
+ {{Christmas Island} CX Christmas_Island}
+ {{Cocos (Keeling) Islands} CC {}}
+ {{Colombia} CO Colombia}
+ {{Comoros} KM Comoros}
+ {{Congo} CG Republic_of_the_Congo}
+ {{Congo, The Democratic Republic Of The} CD Democratic_Republic_of_the_Congo}
+ {{Cook Islands} CK Cook_Islands}
+ {{Costa Rica} CR Costa_Rica}
+ {{Côte D'Ivoire} CI Cote_dIvoire}
+ {{Croatia} HR Croatia}
+ {{Cuba} CU Cuba}
+ {{Cyprus} CY Cyprus}
+ {{Czech Republic} CZ Czech_Republic}
+
+ {{Denmark} DK Denmark}
+ {{Djibouti} DJ Djibouti}
+ {{Dominica} DM Dominica}
+ {{Dominican Republic} DO Dominican_Republic}
+
+ {{Ecuador} EC Ecuador}
+ {{Egypt} EG Egypt}
+ {{El Salvador} SV El_Salvador}
+ {{Equatorial Guinea} GQ Equatorial_Guinea}
+ {{Eritrea} ER Eritrea}
+ {{Estonia} EE Estonia}
+ {{Ethiopia} ET Ethiopia}
+
+ {{Falkland Islands (Malvinas)} FK Falkland_Islands}
+ {{Faroe Islands} FO Faroe_Islands}
+ {{Fiji} FJ Fiji}
+ {{Finland} FI Finland}
+ {{France} FR France}
+ {{French Guiana} GF {}}
+ {{French Polynesia} PF French_Polynesia}
+ {{French Southern Territories} TF {}}
+
+ {{Gabon} GA Gabon}
+ {{Gambia} GM Gambia}
+ {{Georgia} GE Georgia}
+ {{Germany} DE Germany}
+ {{Ghana} GH Ghana}
+ {{Gibraltar} GI Gibraltar}
+ {{Greece} GR Greece}
+ {{Greenland} GL Greenland}
+ {{Grenada} GD Grenada}
+ {{Guadeloupe} GP {}}
+ {{Guam} GU Guam}
+ {{Guatemala} GT Guatemala}
+ {{Guernsey} GG {}}
+ {{Guinea} GN Guinea}
+ {{Guinea-Bissau} GW Guinea_Bissau}
+ {{Guyana} GY Guyana}
+
+ {{Haiti} HT Haiti}
+ {{Heard Island And Mcdonald Islands} HM {}}
+ {{Holy See (Vatican City State)} VA {}}
+ {{Honduras} HN Honduras}
+ {{Hong Kong} HK Hong_Kong}
+ {{Hungary} HU Hungary}
+
+ {{Iceland} IS Iceland}
+ {{India} IN India}
+ {{Indonesia} ID Indonesia}
+ {{Iran, Islamic Republic Of} IR Iran}
+ {{Iraq} IQ Iraq}
+ {{Ireland} IE Ireland}
+ {{Isle Of Man} IM {}}
+ {{Israel} IL Israel}
+ {{Italy} IT Italy}
+
+ {{Jamaica} JM Jamaica}
+ {{Japan} JP Japan}
+ {{Jersey} JE {}}
+ {{Jordan} JO Jordan}
+
+ {{Kazakhstan} KZ Kazakhstan}
+ {{Kenya} KE Kenya}
+ {{Kiribati} KI Kiribati}
+ {{Korea, Democratic People'S Republic Of} KP North_Korea}
+ {{Korea, Republic Of} KR South_Korea}
+ {{Kuwait} KW Kuwait}
+ {{Kyrgyzstan} KG Kyrgyzstan}
+
+ {{Lao People'S Democratic Republic} LA Laos}
+ {{Latvia} LV Latvia}
+ {{Lebanon} LB Lebanon}
+ {{Lesotho} LS Lesotho}
+ {{Liberia} LR Liberia}
+ {{Libyan Arab Jamahiriya} LY Libya}
+ {{Liechtenstein} LI Liechtenstein}
+ {{Lithuania} LT Lithuania}
+ {{Luxembourg} LU Luxembourg}
+
+ {{Macao} MO Macao}
+ {{Macedonia, The Former Yugoslav Republic Of} MK Macedonia}
+ {{Madagascar} MG Madagascar}
+ {{Malawi} MW Malawi}
+ {{Malaysia} MY Malaysia}
+ {{Maldives} MV Maldives}
+ {{Mali} ML Mali}
+ {{Malta} MT Malta}
+ {{Marshall Islands} MH Marshall_Islands}
+ {{Martinique} MQ Martinique}
+ {{Mauritania} MR Mauritania}
+ {{Mauritius} MU Mauritius}
+ {{Mayotte} YT {}}
+ {{Mexico} MX Mexico}
+ {{Micronesia, Federated States Of} FM Micronesia}
+ {{Moldova, Republic Of} MD Moldova}
+ {{Monaco} MC Monaco}
+ {{Mongolia} MN Mongolia}
+ {{Montenegro} ME {}}
+ {{Montserrat} MS Montserrat}
+ {{Morocco} MA Morocco}
+ {{Mozambique} MZ Mozambique}
+ {{Myanmar} MM Myanmar}
+
+ {{Namibia} NA Namibia}
+ {{Nauru} NR Nauru}
+ {{Nepal} NP Nepal}
+ {{Netherlands} NL Netherlands}
+ {{Netherlands Antilles} AN Netherlands_Antilles}
+ {{New Caledonia} NC {}}
+ {{New Zealand} NZ New_Zealand}
+ {{Nicaragua} NI Nicaragua}
+ {{Niger} NE Niger}
+ {{Nigeria} NG Nigeria}
+ {{Niue} NU Niue}
+ {{Norfolk Island} NF Norfolk_Island}
+ {{Northern Mariana Islands} MP {}}
+ {{Norway} NO Norway}
+
+ {{Oman} OM Oman}
+
+ {{Pakistan} PK Pakistan}
+ {{Palau} PW Palau}
+ {{Palestinian Territory, Occupied} PS {}}
+ {{Panama} PA Panama}
+ {{Papua New Guinea} PG Papua_New_Guinea}
+ {{Paraguay} PY Paraguay}
+ {{Peru} PE Peru}
+ {{Philippines} PH Philippines}
+ {{Pitcairn} PN Pitcairn_Islands}
+ {{Poland} PL Poland}
+ {{Portugal} PT Portugal}
+ {{Puerto Rico} PR Puerto_Rico}
+
+ {{Qatar} QA Qatar}
+
+ {{Réunion} RE {}}
+ {{Romania} RO Romania}
+ {{Russian Federation} RU Russian_Federation}
+ {{Rwanda} RW Rwanda}
+
+ {{Saint Barthélemy} BL {}}
+ {{Saint Helena, Ascension And Tristan Da Cunha} SH {}}
+ {{Saint Kitts And Nevis} KN Saint_Kitts_and_Nevis}
+ {{Saint Lucia} LC Saint_Lucia}
+ {{Saint Martin} MF {}}
+ {{Saint Pierre And Miquelon} PM Saint_Pierre}
+ {{Saint Vincent And The Grenadines} VC Saint_Vicent_and_the_Grenadines}
+ {{Samoa} WS Samoa}
+ {{San Marino} SM San_Marino}
+ {{Sao Tome And Principe} ST Sao_Tome_and_Principe}
+ {{Saudi Arabia} SA Saudi_Arabia}
+ {{Senegal} SN Senegal}
+ {{Serbia} RS {}}
+ {{Seychelles} SC Seychelles}
+ {{Sierra Leone} SL Sierra_Leone}
+ {{Singapore} SG Singapore}
+ {{Slovakia} SK Slovakia}
+ {{Slovenia} SI Slovenia}
+ {{Solomon Islands} SB Soloman_Islands}
+ {{Somalia} SO Somalia}
+ {{South Africa} ZA South_Africa}
+ {{South Georgia And The South Sandwich Islands} GS South_Georgia}
+ {{Spain} ES Spain}
+ {{Sri Lanka} LK Sri_Lanka}
+ {{Sudan} SD Sudan}
+ {{Suriname} SR Suriname}
+ {{Svalbard And Jan Mayen} SJ {}}
+ {{Swaziland} SZ Swaziland}
+ {{Sweden} SE Sweden}
+ {{Switzerland} CH Switzerland}
+ {{Syrian Arab Republic} SY Syria}
+
+ {{Taiwan, Province Of China} TW Taiwan}
+ {{Tajikistan} TJ Tajikistan}
+ {{Tanzania, United Republic Of} TZ Tanzania}
+ {{Thailand} TH Thailand}
+ {{Timor-Leste} TL Timor-Leste}
+ {{Togo} TG Togo}
+ {{Tokelau} TK {}}
+ {{Tonga} TO Tonga}
+ {{Trinidad And Tobago} TT Trinidad_and_Tobago}
+ {{Tunisia} TN Tunisia}
+ {{Turkey} TR Turkey}
+ {{Turkmenistan} TM Turkmenistan}
+ {{Turks And Caicos Islands} TC Turks_and_Caicos_Islands}
+ {{Tuvalu} TV Tuvalu}
+
+ {{Uganda} UG Uganda}
+ {{Ukraine} UA Ukraine}
+ {{United Arab Emirates} AE UAE}
+ {{United Kingdom} GB United_Kingdom}
+ {{United States} US United_States_of_America}
+ {{United States Minor Outlying Islands} UM {}}
+ {{Uruguay} UY Uruguay}
+ {{Uzbekistan} UZ Uzbekistan}
+
+ {{Vanuatu} VU Vanuatu}
+ {{Vatican City State} VA Vatican_City}
+ {{Venezuela, Bolivarian Republic Of} VE Venezuela}
+ {{Viet Nam} VN Vietnam}
+ {{Virgin Islands, British} VG British_Virgin_Islands}
+ {{Virgin Islands, U.S.} VI US_Virgin_Islands}
+
+ {{Wallis And Futuna} WF Wallis_and_Futuna}
+ {{Western Sahara} EH {}}
+
+ {{Yemen} YE Yemen}
+ {{Zambia} ZM Zambia}
+ {{Zimbabwe} ZW Zimbabwe}
+}
+
+## Kill spell checker and its support processes
+ # @return void
+proc kill_spellchecker_process {} {
+ # Reset some class variables
+ set ::Editor::spellchecker_RAP_ID {}
+ set ::Editor::spellchecker_command_LIFO [list]
+
+ # Abort if the spell checker process is not running
+ if {${::Editor::spellchecker_process_pid} == {}} {
+ return
+ }
+
+ # Kill the spell checker and its support processes
+ foreach pid ${::Editor::spellchecker_process_pid} {
+ if {$pid == [pid] || $pid == 0} {
+ continue
+ }
+ catch {
+ exec -- kill $pid 2>/dev/null
+ }
+ }
+ set ::Editor::spellchecker_process_pid {}
+}
+
+## Restart the spell checker process with new new configuration
+ # @return void
+proc restart_spellchecker_process {} {
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ kill_spellchecker_process
+
+ if {[lsearch -ascii -exact ${::Editor::available_dictionaries} ${::Editor::spellchecker_dictionary}] == -1} {
+ set ::Editor::spellchecker_enabled 0
+ set ::Editor::spellchecker_dictionary {}
+ } else {
+ start_spellchecker_process
+ wait_for_spellchecker_process
+ }
+}
+
+## Start the spell checker (Hunspell) and its support processes
+ # @return void
+proc start_spellchecker_process {} {
+ # Abort if either the feature is disabled or the Hunspell is not available
+ if {!${::Editor::spellchecker_enabled} || !${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Start watch dog timer
+ set ::Editor::spellchecker_start_timer [after 10000 {
+ set ::Editor::spellchecker_start_failed 1
+ set ::Editor::spellchecker_started_flag 1
+ }]
+
+ # Attempt to start the processes
+ if {[catch {
+ set ::Editor::spellchecker_process_pid [exec -- \
+ tclsh ${::LIB_DIRNAME}/receive_and_print.tcl \
+ [tk appname] \
+ ::Editor::set_spellchecker_RAP_ID \
+ | hunspell \
+ -a \
+ -i utf8 \
+ -d ${::Editor::spellchecker_dictionary} \
+ | tclsh ${::LIB_DIRNAME}/external_command.tcl \
+ [tk appname] \
+ ::Editor::spellchecker_exit_callback \
+ ::Editor::spellchecker_receive_response \
+ & \
+ ]
+ }]} then {
+ # FAILURE
+ set ::Editor::spellchecker_start_failed 1
+ set ::Editor::spellchecker_started_flag 1
+ }
+}
+
+## Wait until the spell checker (Hunspell) and its support processes are started
+ # @return void
+proc wait_for_spellchecker_process {} {
+ # Abort if either the feature is disabled or the Hunspell is not available
+ if {!${::Editor::spellchecker_enabled} || !${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Wait until the spell checker (Hunspell) and its support processes are started
+ vwait ::Editor::spellchecker_started_flag
+ unset ::Editor::spellchecker_started_flag
+
+ # Stop the watch dog timer
+ catch {
+ after cancel ${::Editor::spellchecker_start_timer}
+ }
+
+ # Handle spellchecker start-up failure
+ if {${::Editor::spellchecker_start_failed}} {
+ # Set some class variables
+ set ::Editor::spellchecker_RAP_ID {}
+ set ::Editor::spellchecker_enabled 0
+ set ::Editor::spellchecker_start_failed 0
+
+ # Destroy the splash screen if displayed
+ if {[winfo exists .splash]} {
+ destroy .splash
+ }
+
+ # Display graphical error message
+ tk_messageBox \
+ -parent . \
+ -type ok \
+ -icon error \
+ -title [mc "Hunspell error"] \
+ -message [mc "Unable to start the spell checker. Please try to re-install the hunspell. Spell checking function will not be available"]
+ }
+}
+
+## Receive the identifier for IPC with the RAP
+ # @parm String id - Appname of the receive_and_print process
+ # @return void
+proc set_spellchecker_RAP_ID {id} {
+ set ::Editor::spellchecker_RAP_ID $id
+}
+
+## Handle Hunspell process termination
+ #
+ # It is assumed that the process terminates only on some error condition or
+ # on an explicit request for termination. Aim of this method is attempt to
+ # restart the Hunspell process and its support processes if it crashed for any
+ # reason.
+ #
+ # @parm List args - Anything, it doesn't matter
+ # @return void
+proc spellchecker_exit_callback {args} {
+ # Abort if the termination was intentional
+ if {${::Editor::spellchecker_RAP_ID} == {}} {
+ return
+ }
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ set ::Editor::spellchecker_RAP_ID {}
+ puts stderr "Spell checker process exited -- attempting to restart"
+
+ # Attempt to restart
+ incr ::Editor::spellchecker_attempts_to_restart
+ if {${::Editor::spellchecker_attempts_to_restart} < 10} {
+ start_spellchecker_process
+ } else {
+ puts stderr "Attempt to restart failed, to many attempts -- aborting"
+ set spellchecker_attempts_to_restart 0
+ }
+}
+
+## Receive response from the Hunspell
+ # @parm List args - One line of the response
+ # @return void
+proc spellchecker_receive_response {args} {
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # We are interested only in the first field of the response
+ set response [string trim [lindex $args 0]]
+
+ # Handle the initial response (sent once the Hunspell is started)
+ if {[lindex $response 0] == {@(#)}} {
+ set spellchecker_command_LIFO [list]
+ set ::Editor::spellchecker_started_flag 1
+ return
+ }
+
+ # Decide what to do with the response
+ switch -- $response {
+ {} { ;# Empty response -- means nothing
+ }
+ {*} { ;# Word is correct
+ catch {
+ eval [lindex $spellchecker_command_LIFO {0 0}]
+ }
+ set spellchecker_command_LIFO [lreplace $spellchecker_command_LIFO 0 0]
+ }
+ default { ;# Everything else
+ catch {
+ eval [lindex $spellchecker_command_LIFO {0 1}]
+ }
+ set spellchecker_command_LIFO [lreplace $spellchecker_command_LIFO 0 0]
+ }
+ }
+}
+
+## Send a word to the Hunspell process for evaluation
+ # @parm String word - Work to check for correct spelling
+ # @parm String wrong_command = {} - Command to execute here if the word is badly spelled
+ # @parm String correct_command = {} - Command to execute here if the word is correctly spelled
+ # @return void
+proc spellchecker_check_word {word {wrong_command {}} {correct_command {}}} {
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Abort if receive and print process has not been initialized
+ if {${::Editor::spellchecker_RAP_ID} == {}} {
+ return
+ }
+
+ # Append command to their queue
+ lappend spellchecker_command_LIFO [list $correct_command $wrong_command]
+
+ # Send the word to the Hunspell process
+ if {!${::MICROSOFT_WINDOWS}} {
+ ::X::secure_send ${::Editor::spellchecker_RAP_ID} print_line "{$word}"
+ } else {
+ dde eval ${::Editor::spellchecker_RAP_ID} print_line "{$word}"
+ }
+}
+
+## Refresh list of available spell checker dictionaries (refresh in GUI)
+ # @return void
+proc refresh_available_dictionaries {} {
+ # Abort if the Hunspell program is not available
+ if {!${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Set widget descriptor for the dictionary selection menu
+ set m {.spell_checker_conf_menu}
+
+ # Destroy the dictionary selection menu if it exists
+ if {[winfo exists $m]} {
+ destroy $m
+ }
+
+ # Create new dictionary selection menu
+ menu $m ;# Main part
+ menu $m.by_country ;# Cascade "Set dictionary by country"
+ menu $m.by_language ;# Cascade "Set dictionary by language"
+
+ # Define contents of the newly created menu
+ $m add command \
+ -label [mc "Refresh list of dictionaries"] \
+ -image ::ICONS::16::reload \
+ -compound left \
+ -command {
+ ::Editor::refresh_available_dictionaries
+ ::Editor::adjust_spell_checker_config_button
+ }
+ $m add command \
+ -label [mc "Turn off spell checking"] \
+ -image ::ICONS::16::exit \
+ -compound left \
+ -command {::Editor::switch_SC_dictionary {}}
+ $m add separator
+ $m add cascade \
+ -label [mc "Set dictionary by language"] \
+ -menu $m.by_language
+ $m add cascade \
+ -label [mc "Set dictionary by country"] \
+ -menu $m.by_country
+
+ ## Get list of available Hunspell dictionaries
+ set ::Editor::available_dictionaries [list]
+ # Start watchdog timer for the Hunspell process
+ set spellchecker_start_timer [after 10000 {
+ catch {
+ close ${::Editor::hunspell_process}
+ }
+ }]
+ if {[catch {
+ # Run Hunspell in a mode in which it prints available dictionaries
+ if {!${::MICROSOFT_WINDOWS}} {
+ set hunspell_process [open {| /bin/sh -c "hunspell -D 2>&1 | awk '{print(\$0)} /^LOADED DICTIONARY/ {exit 0}' || exit 1"} "r"]
+ } else {
+ puts stderr "Sorry, this feature is not implemented on MS Windows yet."
+ error "Not available on Windows."
+ }
+
+ }]} then {
+ # Error condition
+ puts stderr "Unable to start the Hunspell process"
+
+ } else {
+ # Bool: Accept this line of output from the process
+ set accept_flag 0
+
+ # Read list of dictionaries (file names along with pats)
+ while {![eof $hunspell_process]} {
+ # Read line from the process
+ set line [gets $hunspell_process]
+
+ # Ignore everything besides section ``AVAILABLE DICTIONARIES''
+ if {![string first {AVAILABLE DICTIONARIES} $line]} {
+ set accept_flag 1
+ continue
+ } elseif {![string first {LOADED DICTIONARY:} $line]} {
+ break
+ } elseif {!$accept_flag} {
+ continue
+ }
+
+ # Determinate language code and country code and append it to the
+ #+ list of available dictionaries
+ set line [lindex [split $line [file separator]] end]
+ set line [split $line {_}]
+ if {[lindex $line 0] == {hyph}} {
+ continue
+# set line [lreplace $line 0 0]
+ }
+ if {![string length [lindex $line 0]] || ![string length [lindex $line 1]]} {
+ continue
+ }
+ if {![string is alpha [lindex $line 0]] || ![string is alpha [lindex $line 1]]} {
+ continue
+ }
+ set dictionary [string tolower [lindex $line 0]]_[string toupper [lindex $line 1]]
+ if {[lsearch -ascii -exact ${::Editor::available_dictionaries} $dictionary] == -1} {
+ lappend ::Editor::available_dictionaries $dictionary
+ }
+ }
+ }
+
+ # Cancel the watchdog timer
+ catch {
+ after cancel $spellchecker_start_timer
+ }
+
+ # If there are no dictionaries available to use then abort right away
+ if {![llength ${::Editor::available_dictionaries}]} {
+ return
+ }
+
+
+ ## Enrich the gained list with some additional information
+ #
+ # Format of the resulting list:
+ # {
+ # {Language_code Country_code Country_name Language_name Flag_icon}
+ # ...
+ # }
+ set available_dictionaries_complex [list]
+ foreach dictionary ${::Editor::available_dictionaries} {
+ # Determinate language code and country code
+ set dictionary [split $dictionary {_}] ;# List: Language and country codes, e.g. {en GB}
+ set language_code [lindex $dictionary 0] ;# String: Language code, e.g. "en"
+ set country_code [lindex $dictionary 1] ;# String: County code, e.g. "GB"
+ set country_and_flag {} ;# List: Country name and flag icon name, e.g. {"United Kingdom" United_Kingdom}
+ set country_name {} ;# String: Country name, e.g. "United Kingdom"
+ set flag_icon {} ;# String: Flag icon name, e.g. "United_Kingdom"
+ set language_name {} ;# String: Language name, e.g. "English"
+
+ # Determinate country name and flag file name
+ set idx [lsearch -ascii -exact -index 1 ${::Editor::COUNTRY_CODES_AND_FLAGS} $country_code]
+ if {$idx != -1} {
+ set country_and_flag [lindex ${::Editor::COUNTRY_CODES_AND_FLAGS} $idx]
+ set country_name [lindex $country_and_flag 0]
+ set flag_icon [lindex $country_and_flag 2]
+ } else {
+ set country_name $country_code
+ }
+ if {$flag_icon == {}} {
+ set flag_icon {empty}
+ }
+
+ # Determinate language name
+ set idx [lsearch -ascii -exact -index 1 ${::Editor::LANGUAGE_CODES_AND_NAMES} $language_code]
+ if {$idx != -1} {
+ set language_name [lindex ${::Editor::LANGUAGE_CODES_AND_NAMES} [list $idx 0]]
+ } else {
+ set language_name $language_code
+ }
+
+ if {$country_name == {}} {
+ set country_name {???}
+ }
+ if {$language_name == {}} {
+ set language_name {???}
+ }
+
+ # Append item to the resulting list
+ lappend available_dictionaries_complex [list $language_code $country_code [mc $country_name] [mc $language_name] $flag_icon]
+ }
+
+ # Generate content of the "Set by country" menu
+ set local_menu {}
+ set capital_leter {}
+ set last_capital_leter {}
+ foreach dictionary [lsort -dictionary -index 2 [lsort -dictionary -index 3 $available_dictionaries_complex]] {
+ # Gain some facts about the dictionary file
+ set language_code [lindex $dictionary 0]
+ set country_code [lindex $dictionary 1]
+ set country_name [lindex $dictionary 2]
+ set language_name [lindex $dictionary 3]
+ set flag_icon [lindex $dictionary 4]
+
+ # Create sub-menu if necessary
+ set capital_leter [string toupper [string index $country_name 0]]
+
+ if {$capital_leter != $last_capital_leter} {
+ set last_capital_leter $capital_leter
+ set local_menu [menu $m.by_country.m_[string tolower $capital_leter]]
+ $m.by_country add cascade -label "$capital_leter ..." -menu $local_menu
+ }
+
+ # Create the menu item
+ $local_menu add command \
+ -command "::Editor::switch_SC_dictionary {${language_code}_${country_code}}" \
+ -label "$country_name ($language_name)" \
+ -image ::ICONS::flag::$flag_icon \
+ -compound left
+ }
+
+ # Generate content of the "Set by language" menu
+ set local_menu {}
+ set capital_leter {}
+ set last_capital_leter {}
+ foreach dictionary [lsort -dictionary -index 3 [lsort -dictionary -index 2 $available_dictionaries_complex]] {
+ # Gain some facts about the dictionary file
+ set language_code [lindex $dictionary 0]
+ set country_code [lindex $dictionary 1]
+ set country_name [lindex $dictionary 2]
+ set language_name [lindex $dictionary 3]
+ set flag_icon [lindex $dictionary 4]
+
+ # Create sub-menu if necessary
+ set capital_leter [string toupper [string index $language_name 0]]
+ if {$capital_leter != $last_capital_leter} {
+ set last_capital_leter $capital_leter
+ set local_menu [menu $m.by_language.m_[string tolower $capital_leter]]
+ $m.by_language add cascade -label "$capital_leter ..." -menu $local_menu
+ }
+
+ # Create the menu item
+ $local_menu add command \
+ -command "::Editor::switch_SC_dictionary {${language_code}_${country_code}}" \
+ -label "$language_name ($country_name)" \
+ -image ::ICONS::flag::$flag_icon \
+ -compound left
+ }
+}
+
+## Switch current dictionary
+ # @parm String dictionary - Dictionary name like: ``en_GB'' or ``en_AU''
+ # @return void
+proc switch_SC_dictionary {dictionary} {
+ # Abort if the Hunspell program is not available
+ if {!${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Chech whether the requested dictionary is available
+ if {[lsearch -ascii -exact ${::Editor::available_dictionaries} $dictionary] == -1} {
+ set dictionary {}
+ }
+
+ # Empty dictionary name means disable the feature
+ if {[string length $dictionary]} {
+ set ::Editor::spellchecker_enabled 1
+ } else {
+ set ::Editor::spellchecker_enabled 0
+ }
+
+ # Adjust configuration button
+ .statusbarSB configure \
+ -image ::ICONS::16::player_time \
+ -text "<>"
+
+ # Clear spell checker's tags in all text editors
+ foreach project ${::X::openedProjects} {
+ foreach editor [$project cget -editors] {
+ $editor spellchecker_clear_tags
+ }
+ }
+
+ # Switch the dictionary
+ set ::Editor::spellchecker_dictionary $dictionary
+ restart_spellchecker_process
+ adjust_spell_checker_config_button
+
+ # Refresh all editors
+ foreach project ${::X::openedProjects} {
+ foreach editor [$project cget -editors] {
+ $editor parseAll
+ }
+ }
+}
+
+## Adjust spell checker configuration button to current spell checker configuration
+ # @return void
+proc adjust_spell_checker_config_button {} {
+ # Abort if the Hunspell program is not available
+ if {!${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Spell checker configuration menu
+ set m {.spell_checker_conf_menu}
+
+ ## Spell checker is DISABLED
+ if {!$::Editor::spellchecker_enabled} {
+ $m entryconfigure [mc "Turn off spell checking"] -state disabled
+ .statusbarSB configure \
+ -image ::ICONS::flag::empty \
+ -text "none"
+
+ ## Spell checker is ENABLED
+ } else {
+ $m entryconfigure [mc "Turn off spell checking"] -state normal
+
+ set c_l [split ${::Editor::spellchecker_dictionary} {_}]
+ set idx [lsearch -ascii -exact -index 1 ${::Editor::COUNTRY_CODES_AND_FLAGS} [lindex $c_l 1]]
+ if {$idx != -1} {
+ set flag_icon [lindex ${::Editor::COUNTRY_CODES_AND_FLAGS} [list $idx 2]]
+ } else {
+ set flag_icon {empty}
+ }
+
+ .statusbarSB configure \
+ -image ::ICONS::flag::$flag_icon \
+ -text [lindex $c_l 0]
+ }
+}
+
+## By calling this method we mark the target line as something which is a subject for a change
+ # Purpose is to handle insertions of single characters and deletions of single characters
+ # @note This method inhibits method spellcheck_check_all until spellcheck_change_detected_post is called
+ # @see spellcheck_change_detected_post
+ # @parm Int line_number = {} - Number of the target line, {} means the current line
+ # @return void
+private method spellcheck_change_detected_pre {{line_number {}}} {
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Abort conditions
+ if {!$spellchecker_enabled || !${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+
+ # Inhibit method spellcheck_check_all until spellcheck_change_detected_post is called
+ set spellcheck_lock 1
+
+ # Adjust parameters
+ if {$line_number == {}} {
+ set line_number [expr {int([$editor index insert])}]
+ }
+
+ # Store the target line
+ set spellcheck_line_number $line_number
+ set spellcheck_line_pre [$editor get [list $line_number.0 linestart] [list $line_number.0 lineend]]
+}
+
+## By calling this method we finalize the process started by calling to method spellcheck_change_detected_pre
+ # Purpose is to handle insertions of single characters and deletions of single characters
+ # @see spellcheck_change_detected_pre
+ # @parm Int line_number = {} - Number of the target line, {} means the current line
+ # @return void
+private method spellcheck_change_detected_post {{line_number {}}} {
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Abort conditions
+ if {!$spellchecker_enabled || !${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+
+ # cancel the inhibition of method spellcheck_check_all
+ set spellcheck_lock 0
+
+ # Adjust parameters
+ if {$line_number == {}} {
+ set line_number [expr {int([$editor index insert])}]
+ }
+
+ # Determinate ranges of text indexes delimiting strings to check for spelling
+ if {$prog_language == -1} {
+ set target_ranges [list [list $line_number.0 [$editor index [list $line_number.0 lineend]]]]
+ } else {
+ set target_ranges [list]
+ set range [list $line_number.0 $line_number.0]
+ while {1} {
+ set range [concat \
+ [$editor tag nextrange tag_comment [lindex $range 1] [list $line_number.0 lineend]] \
+ [$editor tag nextrange tag_c_comment [lindex $range 1] [list $line_number.0 lineend]] \
+ [$editor tag nextrange tag_c_dox_comment [lindex $range 1] [list $line_number.0 lineend]] \
+ ]
+
+ if {![llength $range]} {
+ break
+ }
+
+ lappend target_ranges $range
+ }
+ }
+
+ # Gain entire line from the editor
+ set line [$editor get [list $line_number.0 linestart] [list $line_number.0 lineend]]
+
+ if {[string length $line] > [string length $spellcheck_line_pre]} {
+ set new_longer_that_org 1
+ } else {
+ set new_longer_that_org 0
+ }
+
+ # Compare the line to its previous content and check changed word(s)
+ set fixed_shift 0 ;# Total pre string shift from all cycles
+ set force_check 0 ;# Enforce spell check of the next word regardless the comparison
+ foreach range $target_ranges {
+ # Determinate start and end column
+ scan [lindex $range 0] {%d.%d} _ start
+ scan [lindex $range 1] {%d.%d} _ end
+
+ set word {} ;# String: Word to check
+ set char {} ;# Char: Character gained from the source line
+ set idx_pre $start ;# Int: Index in $spellcheck_line_pre
+ set word_len 0 ;# Int: Length of the word
+ set skip_word 0 ;# Bool: Flag skip this one word
+ set change_detected 0 ;# Bool: Flag the word was changed
+ set char_next [string index $line $start] ;# Char: Same as char but maybe a little ahead
+
+ # Take into accound shift from previous cycles
+ incr idx_pre $fixed_shift
+
+ for {set idx $start} {$idx < $end} {incr idx; incr idx_pre} {
+ set char $char_next
+ set char_next [string index $line [expr {$idx + 1}]]
+ set char_pre_next [string index $spellcheck_line_pre [expr {$idx_pre + 1}]]
+ set char_pre [string index $spellcheck_line_pre $idx_pre]
+
+ if {[string is alnum $char]} {
+ # If the word contains one or more digits, skip it, digits in a word
+ #+ would cause Hunspell to behave in a way that we don't want here
+ if {[string is digit $char]} {
+ set skip_word 1
+ }
+
+ # Lines are different
+ if {$char_pre != $char} {
+ set change_detected 1
+
+ # Character deleted -- shift the pre string >> 1
+ if {$char_pre_next == $char && !$new_longer_that_org} {
+ incr idx_pre
+ incr fixed_shift
+ # Character inserted -- shift the pre string << 1
+ } elseif {$char_pre == $char_next && $new_longer_that_org} {
+ incr idx_pre -1
+ incr fixed_shift -1
+ }
+
+ # Character appended at the end of the word -- shift the pre string << 1,
+ #+ and check for the next word unconditionally
+ } elseif {
+ [string is alnum $char_pre_next]
+ &&
+ ![string is alnum $char_next]
+ &&
+ $char_pre_next != $char_next
+ } then {
+ incr idx_pre -1
+ incr fixed_shift -1
+ set change_detected 1
+ set force_check 1
+ }
+
+ # Append the character to the word
+ append word $char
+ incr word_len
+
+ # This is not the last character in the line
+ if {$idx < ($end - 1)} {
+ continue
+ # This IS the last character in the line
+ } else {
+ incr idx
+ }
+ }
+
+ # Skip empty words
+ if {!$word_len} {
+ continue
+ }
+
+ # Send the word to the spell checker
+ if {$change_detected && !$skip_word} {
+ set change_detected 0
+ $editor tag remove tag_wrong_spelling $line_number.$idx-${word_len}c-1c $line_number.$idx
+
+ spellchecker_check_word $word \
+ [list $editor tag add tag_wrong_spelling $line_number.$idx-${word_len}c $line_number.$idx] \
+ [list $editor tag remove tag_wrong_spelling $line_number.$idx-${word_len}c $line_number.$idx]
+ }
+
+ # Enforce spell check of the next word regardless the comparison
+ if {$force_check} {
+ set force_check 0
+ set change_detected 1
+ }
+
+ # Reset
+ set word {}
+ set word_len 0
+ set skip_word 0
+ }
+ }
+}
+
+## Check spelling on the specified line
+ #
+ # This method will not perform the task if $spellcheck_line_number is equal to
+ # the given source line, unless the force parameter is set to true.
+ # @note
+ # Spell checking is performed only for comments unless the programming language
+ # is not specified
+ # @parm Int line_number - Number of line to check
+ # @parm Int force = 0 - 1: Force the method to perform the spell check; 2: Force even over $spellcheck_lock
+ # @return void
+public method spellcheck_check_all {line_number {force 0}} {
+ # This function was not yet ported to MS Windows
+ if {$::MICROSOFT_WINDOWS} {
+ return
+ }
+
+ # Abort conditions
+ if {($force != 2 && $spellcheck_lock) || !$spellchecker_enabled || !${::PROGRAM_AVAILABLE(hunspell)}} {
+ return
+ }
+ if {!$force && ($spellcheck_line_number != $line_number)} {
+ return
+ }
+ set spellcheck_line_number {}
+
+ # Remove bad spelling tags
+ $editor tag remove tag_wrong_spelling $line_number.0 [list $line_number.0 lineend]
+
+ # Determinate ranges of text indexes delimiting strings to check for spelling
+ if {$prog_language == -1} {
+ set target_ranges [list [list $line_number.0 [$editor index [list $line_number.0 lineend]]]]
+ } else {
+ set target_ranges [list]
+ set range [list $line_number.0 $line_number.0]
+ while {1} {
+ set range [concat \
+ [$editor tag nextrange tag_comment [lindex $range 1] [list $line_number.0 lineend]] \
+ [$editor tag nextrange tag_c_comment [lindex $range 1] [list $line_number.0 lineend]] \
+ [$editor tag nextrange tag_c_dox_comment [lindex $range 1] [list $line_number.0 lineend]] \
+ ]
+
+ if {![llength $range]} {
+ break
+ }
+
+ lappend target_ranges $range
+ }
+ }
+
+ # Gain entire line from the editor
+ set line [$editor get $line_number.0 [list $line_number.0 lineend]]
+
+ # Check spelling for the given ranges
+ foreach range $target_ranges {
+ # Determinate start and end column
+ scan [lindex $range 0] {%d.%d} _ start
+ scan [lindex $range 1] {%d.%d} _ end
+
+ set word {} ;# String: Word to check
+ set char {} ;# Char: Character gained from the source line
+ set word_len 0 ;# Int: Length of the word
+ set skip_word 0 ;# Bool: Flag skip this one word
+
+ # Iterate over characters in the source line
+ for {set idx $start} {$idx < $end} {incr idx} {
+ set char [string index $line $idx]
+
+ if {[string is alnum $char]} {
+ # If the word contains one or more digits, skip it digits in a word
+ #+ would cause Hunspell to behave in a way that we don't want here
+ if {[string is digit $char]} {
+ set skip_word 1
+ }
+
+ # Append the character to the word
+ append word $char
+ incr word_len
+
+ # This is not the last character in the line
+ if {$idx < ($end - 1)} {
+ continue
+ # This IS the last character in the line
+ } else {
+ incr idx
+ }
+ }
+
+ # Skip empty words
+ if {!$word_len} {
+ continue
+ }
+
+ # Send the word to the spell checker
+ if {!$skip_word} {
+ spellchecker_check_word \
+ $word \
+ [list $editor tag add tag_wrong_spelling $line_number.$idx-${word_len}c $line_number.$idx]
+ }
+
+ # Reset
+ set word {}
+ set word_len 0
+ set skip_word 0
+ }
+ }
+}
+
+## Clear all tags marking the misspelled words
+ # @return void
+public method spellchecker_clear_tags {} {
+ $editor tag remove tag_wrong_spelling 0.0 end
+}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard