edit.tcl 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. ###########################################################
  2. # Name: edit.tcl
  3. # Author: Daniele Bonini (posta@elettronica.lol)
  4. # Date: 27/11/2023
  5. # Desc: Edit Menu namespace of RadXIDE.
  6. #
  7. # Edit Menu namespace scaffolding and most of the code
  8. # here presented and distributed contains excerpts
  9. # from [alited](https://github.com/aplsimple/alited
  10. # by Alex Plotnikov and contributors to the project.
  11. # The original code of these excerpts could be
  12. # borrowed from other sources which the author
  13. # and the contributors to this RadXIDE have no
  14. # knowledge about.
  15. #
  16. # License: MIT. Copyrights 5 Mode (Last implementation and adaptations.)
  17. # Copyright (c) 2021-2023 Alex Plotnikov https://aplsimple.github.io (original scaffolding and excerpts.)
  18. #
  19. ###########################################################
  20. namespace eval edit {
  21. # ________________________ find _________________________ #
  22. proc find {} {
  23. # Open the Find window to start a text search
  24. namespace upvar ::radxide dan dan project project
  25. set t $dan(TEXT)
  26. set args {}
  27. if {$project(CUR_FILE_PATH) ne {}} {
  28. #tk_textCopy $t
  29. #catch {clipboard get} clipcontent
  30. #set sel $clipcontent
  31. set sel [::radxide::win::InitFindInText 0 $t]
  32. #tk_messageBox -title $dan(TITLE) -icon info -message $sel
  33. set args "-buttons {butSearch SEARCH ::radxide::win::findTextOK butCANCEL CANCEL ::radxide::win::findTextCancel}"
  34. catch {lassign [::radxide::win::input "Find" {} "Find text" [list \
  35. ent "{} {} {-w 64}" "{$sel}"] \
  36. -head "Search for:" {*}$args] res}
  37. }
  38. }
  39. # ________________________ GotoLine _________________________ #
  40. proc GotoLine {} {
  41. # Open the Go To Line window
  42. namespace upvar ::radxide dan dan project project
  43. set t $dan(TEXT)
  44. set args {}
  45. set ln 1
  46. if {$project(CUR_FILE_PATH) ne {}} {
  47. #tk_messageBox -title $dan(TITLE) -icon info -message "Go To Line"
  48. set args "-buttons {butGo GO ::radxide::win::GotoLineOK butCANCEL CANCEL ::radxide::win::GotoLineCancel}"
  49. catch {lassign [::radxide::win::input "GotoLine" {} "Go to Line" [list \
  50. ent "{} {} {-w 28}" "{$ln}"] \
  51. -head "Go to line:" {*}$args] res}
  52. }
  53. }
  54. # ________________________ Indent _________________________ #
  55. proc Indent {{from "event"}} {
  56. # Indent selected lines of text.
  57. namespace upvar ::radxide dan dan
  58. set indent $dan(TAB_IN_SPACE)
  59. set len [string length $dan(TAB_IN_SPACE)]
  60. set sels [SelectedLines]
  61. set wtxt [lindex $sels 0]
  62. #::apave::undoIn $wtxt
  63. foreach {l1 l2} [lrange $sels 1 end] {
  64. for {set l $l1} {$l<=$l2} {incr l} {
  65. set line [$wtxt get $l.0 $l.end]
  66. if {[string trim $line] eq {}} {
  67. $wtxt replace $l.0 $l.end {}
  68. } else {
  69. set leadsp [leadingSpaces $line]
  70. set sp [expr {$leadsp % $len}]
  71. # align by the indent edge
  72. if {$sp==0} {
  73. set ind $indent
  74. } else {
  75. set ind [string repeat " " [expr {$len - $sp}]]
  76. }
  77. $wtxt insert $l.0 $ind
  78. }
  79. }
  80. }
  81. #::apave::undoOut $wtxt
  82. #alited::main::HighlightLine
  83. focus $dan(TEXT)
  84. if {$from eq "event"} {
  85. return -code break
  86. }
  87. }
  88. # ________________________ leadingSpaces _________________________ #
  89. proc leadingSpaces {line} {
  90. # Returns a number of leading spaces of a line
  91. # line - the line
  92. return [expr {[string length $line]-[string length [string trimleft $line]]}]
  93. }
  94. # ________________________ makeCopy _________________________ #
  95. proc makeCopy {{from "event"}} {
  96. # Copy from the editor to the clipboard
  97. #clipboard clear
  98. #clipboard append $txt
  99. namespace upvar ::radxide dan dan
  100. set t $dan(TEXT)
  101. tk_textCopy $t
  102. if {$from eq "event"} {
  103. return -code break
  104. }
  105. }
  106. #_________________________ makeCut ________________________ #
  107. proc makeCut {{from "event"}} {
  108. # Cut from the editor to the clipboard
  109. #set canvas %W
  110. #eval [clipboard get -type TkCanvasItem]
  111. namespace upvar ::radxide dan dan
  112. set t $dan(TEXT)
  113. tk_textCut $t
  114. after 1000 "::radxide::win::fillGutter .danwin.fra.pan.fra2.text .danwin.fra.pan.fra2.gutText 5 1 #FFFFFF #222223"
  115. #$dan(TEXT) yview [$dan(TEXT) index insert]
  116. #$dan(GUTTEXT) yview moveto [lindex [$dan(TEXT) yview] 1]
  117. if {$from eq "event"} {
  118. return -code break
  119. }
  120. }
  121. # ________________________ makeNewLine _________________________ #
  122. proc makeNewLine {} {
  123. namespace upvar ::radxide dan dan
  124. set wt $dan(TEXT)
  125. # getting previous line
  126. set idx1 [$wt index {insert linestart}]
  127. set idx2 [$wt index {insert lineend}]
  128. set line [$wt get $idx1 $idx2]
  129. # erasing tabs, replacing them with spaces..
  130. set line [string map {\t $dan(TAB_IN_SPACE)} $line]
  131. # calculating identation..
  132. set orilength [string length $line]
  133. set newlength [string length [string trimleft $line]]
  134. set nspacesofindent [expr $orilength - $newlength]
  135. # inserintg correct identation..
  136. $wt insert [$wt index {insert}] \n[string repeat " " $nspacesofindent]
  137. set idx3 [$wt index insert]
  138. set idx4 [$wt index "$idx3 +1 line"]
  139. ::tk::TextSetCursor $wt $idx3
  140. ::radxide::win::fillGutter .danwin.fra.pan.fra2.text .danwin.fra.pan.fra2.gutText 5 1 "#FFFFFF" "#222223"
  141. #$dan(TEXT) yview [$dan(TEXT) index insert]
  142. #$dan(GUTTEXT) yview moveto [lindex [$dan(TEXT) yview] 1]
  143. return -code break
  144. }
  145. #_________________________ makePaste ________________________ #
  146. proc makePaste {{from "event"}} {
  147. # Paste from the clipboard to the editor
  148. #set canvas %W
  149. #eval [clipboard get -type TkCanvasItem]
  150. namespace upvar ::radxide dan dan
  151. set t $dan(TEXT)
  152. tk_textPaste $t
  153. after 1000 "::radxide::win::fillGutter .danwin.fra.pan.fra2.text .danwin.fra.pan.fra2.gutText 5 1 #FFFFFF #222223"
  154. #$dan(TEXT) yview [$dan(TEXT) index insert]
  155. #$dan(GUTTEXT) yview moveto [lindex [$dan(TEXT) yview] 1]
  156. if {$from eq "event"} {
  157. return -code break
  158. }
  159. }
  160. #_________________________ makeRedo ________________________ #
  161. proc makeRedo {{from "event"}} {
  162. # Paste from the clipboard to the editor
  163. #set canvas %W
  164. #eval [clipboard get -type TkCanvasItem]
  165. namespace upvar ::radxide dan dan
  166. set t $dan(TEXT)
  167. catch {$t edit redo}
  168. after idle "::radxide::win::fillGutter .danwin.fra.pan.fra2.text .danwin.fra.pan.fra2.gutText 5 1 #FFFFFF #222223"
  169. #$dan(TEXT) yview [$dan(TEXT) index insert]
  170. #$dan(GUTTEXT) yview moveto [lindex [$dan(TEXT) yview] 1]
  171. if {$from eq "event"} {
  172. return -code break
  173. }
  174. }
  175. #_________________________ makeUndo ________________________ #
  176. proc makeUndo {{from "event"}} {
  177. # Paste from the clipboard to the editor
  178. #set canvas %W
  179. #eval [clipboard get -type TkCanvasItem]
  180. namespace upvar ::radxide dan dan
  181. set t $dan(TEXT)
  182. catch {$t edit undo}
  183. after idle "::radxide::win::fillGutter .danwin.fra.pan.fra2.text .danwin.fra.pan.fra2.gutText 5 1 #FFFFFF #222223"
  184. #$dan(TEXT) yview [$dan(TEXT) index insert]
  185. #$dan(GUTTEXT) yview moveto [lindex [$dan(TEXT) yview] 1]
  186. if {$from eq "event"} {
  187. return -code break
  188. }
  189. }
  190. # ________________________ SelectedLines _________________________ #
  191. proc SelectedLines {{wtxt ""} {strict no}} {
  192. # Gets a range of lines of text that are selected at least partly.
  193. # wtxt - text's path
  194. # strict - if yes, only a real selection is counted
  195. # Returns a list of the text widget's path and ranges of selected lines.
  196. namespace upvar ::radxide dan dan
  197. if {$wtxt eq {}} {set wtxt $dan(TEXT)}
  198. set res [list $wtxt]
  199. if {[catch {$wtxt tag ranges sel} sels] || ![llength $sels]} {
  200. if {$strict} {
  201. set sels [list]
  202. } else {
  203. set pos1 [set pos2 [$wtxt index insert]]
  204. set sels [list $pos1 $pos2]
  205. }
  206. }
  207. foreach {pos1 pos2} $sels {
  208. if {$pos1 ne {}} {
  209. set pos21 [$wtxt index "$pos2 linestart"]
  210. if {[$wtxt get $pos21 $pos2] eq {}} {
  211. set pos2 [$wtxt index "$pos2 - 1 line"]
  212. }
  213. }
  214. set l1 [expr {int($pos1)}]
  215. set l2 [expr {max($l1,int($pos2))}]
  216. lappend res $l1 $l2
  217. }
  218. return $res
  219. }
  220. #_________________________ setup ________________________ #
  221. proc setup {} {
  222. # Open the Options window
  223. namespace upvar ::radxide dan dan
  224. tk_messageBox -title $dan(TITLE) -icon info -message "Please check 'radxide.tcl' to customize any variable."
  225. }
  226. # ________________________ UnIndent _________________________ #
  227. proc UnIndent {{from "event"}} {
  228. # Unindent selected lines of text.
  229. namespace upvar ::radxide dan dan
  230. set len [string length $dan(TAB_IN_SPACE)]
  231. set spaces [list { } \t]
  232. set sels [SelectedLines]
  233. set wtxt [lindex $sels 0]
  234. #::apave::undoIn $wtxt
  235. foreach {l1 l2} [lrange $sels 1 end] {
  236. for {set l $l1} {$l<=$l2} {incr l} {
  237. set line [$wtxt get $l.0 $l.end]
  238. if {[string trim $line] eq {}} {
  239. $wtxt replace $l.0 $l.end {}
  240. } elseif {[string index $line 0] in $spaces} {
  241. set leadsp [leadingSpaces $line]
  242. # align by the indent edge
  243. set sp [expr {$leadsp % $len}]
  244. if {$sp==0} {set sp $len}
  245. $wtxt delete $l.0 "$l.0 + ${sp}c"
  246. }
  247. }
  248. }
  249. #::apave::undoOut $wtxt
  250. focus $dan(TEXT)
  251. if {$from eq "event"} {
  252. return -code break
  253. }
  254. }
  255. #_______________________
  256. }
  257. # _________________________________ EOF _________________________________ #