<commit_before>namespace import ::tcl::mathop::*
namespace eval geekosphere::tbar::widget::menu {


	namespace eval autocomplete {
		variable toComplete
		variable completeList
		variable currentPositionInCompleteList
		set toComplete ""
		set completeList [list]
		set currentPositionInCompleteList 0
		proc getNextSuggestion {toCompl completeLi} {
			variable toComplete
			variable completeList
			variable currentPositionInCompleteList
			if {$toComplete ne $toCompl || $completeList ne $completeLi} {
				set currentPositionInCompleteList 0
				set toComplete $toCompl
				set completeList $completeLi
			}

			set filteredList [lsearch -all -inline $completeList $toCompl*]
			
			incr currentPositionInCompleteList
			if {$currentPositionInCompleteList > [llength $filteredList]} {
				set currentPositionInCompleteList 0
			}
			return [lindex $filteredList $currentPositionInCompleteList]
		}
	}

	proc fillListBoxWithExecutables {listBox executables} {
		$listBox delete 0 end
		foreach item $executables {
			$listBox insert end $item
		}
	}

	proc filterExecutables {filterString} {
		set executables [getExecutablesInPath]
		return [lsearch -all -inline $executables $filterString*]
	}

	proc getExecutablesInPath {} {
		set ret [list]
		foreach path [split $::env(PATH) ":"] {
			foreach file [glob -nocomplain $path/*] {
				if {![file isdirectory $file] && [file executable $file]} {
					lappend ret [file tail $file]
				}
			}
		
		}
		return [lsort -dictionary $ret]
	}

	proc handleEntryKeyPress {entry listBox key} {
		set curselection [$listBox curselection]
			if {$key eq "Return"} {
				handleReturn $entry $listBox $curselection
			} elseif {$key eq "Up"} {
				handleUp $listBox $curselection
			} elseif {$key eq "Down"} {
				handleDown $listBox $curselection
			}
			if {$key eq "Tab"} {
				handleTab $entry $listBox 
			} elseif {$key ne "Return" && $key ne "Up" && $key ne "Down"} {
				handleOtherKey $listBox
			}
	}

	proc handleReturn {entry listBox curselection} {
		if {$curselection eq ""} {
			return
		}
		set command [$listBox get $curselection $curselection]
		open |$command r
		$entry delete 0 end
		fillListBoxWithExecutables $listBox [filterExecutables ""]
	}

	proc handleUp {listBox curselection} {
		if {$curselection eq ""} {
			set newSelection 0
		} else {
			set newSelection [- $curselection 1]
		}
		$listBox selection clear 0 end
		$listBox selection set $newSelection
	}

	proc handleDown {listBox curselection} {
		if {$curselection eq ""} {
			set newSelection 0
		} else {
			set newSelection [+ $curselection 1]
		}
		$listBox selection clear 0 end
		$listBox selection set $newSelection
	}

	proc handleTab {entry listBox} {
		$entry delete 0 end
		$entry insert 0 [geekosphere::tbar::widget::menu::autocomplete::getNextSuggestion [$entry get] [$listBox get 0 end]]
		selectListBoxItemByString $listBox [$entry get]
	}

	proc handleOtherKey {listBox} {
		after 10 {
			geekosphere::tbar::widget::menu::fillListBoxWithExecutables .box [geekosphere::tbar::widget::menu::filterExecutables [.e get]]
			.box selection set 0
		}
	}

	proc selectListBoxItemByString {listBox string} {
		set items [$listBox get 0 end]
		set indexOfString [lsearch $items $string]
		if {$indexOfString != -1} {
			$listBox selection clear 0 end
			$listBox selection set $indexOfString $indexOfString
			$listBox see $indexOfString
		}
	}

	# testcode
	package require Tk
	pack [listbox .box -selectmode single] -fill both -expand 1
	pack [entry .e] -fill both -side bottom
	geekosphere::tbar::widget::menu::fillListBoxWithExecutables .box [geekosphere::tbar::widget::menu::filterExecutables ""]
	bind .e <Key> {
		puts %K
		geekosphere::tbar::widget::menu::handleEntryKeyPress .e .box %K
	}
	.box configure -takefocus 0 -exportselection 0
}

<commit_msg>[ADD] mouse press selection<commit_after>namespace import ::tcl::mathop::*
namespace eval geekosphere::tbar::widget::menu {


	namespace eval autocomplete {
		variable toComplete
		variable completeList
		variable currentPositionInCompleteList
		set toComplete ""
		set completeList [list]
		set currentPositionInCompleteList 0
		proc getNextSuggestion {toCompl completeLi} {
			variable toComplete
			variable completeList
			variable currentPositionInCompleteList
			if {$toComplete ne $toCompl || $completeList ne $completeLi} {
				set currentPositionInCompleteList 0
				set toComplete $toCompl
				set completeList $completeLi
			}

			set filteredList [lsearch -all -inline $completeList $toCompl*]
			
			incr currentPositionInCompleteList
			if {$currentPositionInCompleteList > [llength $filteredList]} {
				set currentPositionInCompleteList 0
			}
			return [lindex $filteredList $currentPositionInCompleteList]
		}
	}

	proc fillListBoxWithExecutables {listBox executables} {
		$listBox delete 0 end
		foreach item $executables {
			$listBox insert end $item
		}
	}

	proc filterExecutables {filterString} {
		set executables [getExecutablesInPath]
		return [lsearch -all -inline $executables $filterString*]
	}

	proc getExecutablesInPath {} {
		set ret [list]
		foreach path [split $::env(PATH) ":"] {
			foreach file [glob -nocomplain $path/*] {
				if {![file isdirectory $file] && [file executable $file]} {
					lappend ret [file tail $file]
				}
			}
		
		}
		return [lsort -dictionary $ret]
	}

	proc handleEntryKeyPress {entry listBox key} {
		set curselection [$listBox curselection]
		if {$key eq "Return"} {
			handleReturn $entry $listBox $curselection
		} elseif {$key eq "Up"} {
			handleUp $listBox $curselection
		} elseif {$key eq "Down"} {
			handleDown $listBox $curselection
		}
		if {$key eq "Tab"} {
			handleTab $entry $listBox 
		} elseif {$key ne "Return" && $key ne "Up" && $key ne "Down"} {
			handleOtherKey $listBox
		}
	}

	proc handleReturn {entry listBox curselection} {
		if {$curselection eq ""} {
			return
		}
		set command [$listBox get $curselection $curselection]
		open |$command r
		$entry delete 0 end
		fillListBoxWithExecutables $listBox [filterExecutables ""]
	}

	proc handleUp {listBox curselection} {
		if {$curselection eq ""} {
			set newSelection 0
		} else {
			set newSelection [- $curselection 1]
		}
		$listBox selection clear 0 end
		$listBox selection set $newSelection
	}

	proc handleDown {listBox curselection} {
		if {$curselection eq ""} {
			set newSelection 0
		} else {
			set newSelection [+ $curselection 1]
		}
		$listBox selection clear 0 end
		$listBox selection set $newSelection
	}

	proc handleTab {entry listBox} {
		$entry delete 0 end
		$entry insert 0 [geekosphere::tbar::widget::menu::autocomplete::getNextSuggestion [$entry get] [$listBox get 0 end]]
		selectListBoxItemByString $listBox [$entry get]
	}

	proc handleOtherKey {listBox} {
		after 10 {
			geekosphere::tbar::widget::menu::fillListBoxWithExecutables .box [geekosphere::tbar::widget::menu::filterExecutables [.e get]]
			.box selection set 0
		}
	}

	proc selectListBoxItemByString {listBox string} {
		set items [$listBox get 0 end]
		set indexOfString [lsearch $items $string]
		if {$indexOfString != -1} {
			$listBox selection clear 0 end
			$listBox selection set $indexOfString $indexOfString
			$listBox see $indexOfString
		}
	}

	# testcode
	package require Tk
	pack [listbox .box -selectmode single] -fill both -expand 1
	pack [entry .e] -fill both -side bottom
	geekosphere::tbar::widget::menu::fillListBoxWithExecutables .box [geekosphere::tbar::widget::menu::filterExecutables ""]
	bind .e <Key> {
		geekosphere::tbar::widget::menu::handleEntryKeyPress .e .box %K
	}
	bind .box <Button-1> {
		after 10 {
			.e delete 0 end
			.e insert 0 [.box get [.box curselection]]
		}
	}
	.box configure -takefocus 0 -exportselection 0
	# BUG: tab to a value, delete field, type first letter of value, tab again
}


{'fraction_non_alphanumeric': 0.10323078903333763, 'fraction_numerical': 0.006564551422319475, 'mean_word_length': 4.085078534031414, 'pattern_counts': {'":': 2, '<': 6, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2049178', 'n_tokens_mistral': 2822, 'n_tokens_neox': 2435, 'n_words': 739}