diff options
Diffstat (limited to 'gitk-git/gitk')
| -rwxr-xr-x | gitk-git/gitk | 263 |
1 files changed, 206 insertions, 57 deletions
diff --git a/gitk-git/gitk b/gitk-git/gitk index 95621daefe..5be8b2aeb0 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -9,6 +9,109 @@ exec wish "$0" -- "$@" package require Tk +###################################################################### +## +## Enabling platform-specific code paths + +proc is_Windows {} { + if {$::tcl_platform(platform) eq {windows}} { + return 1 + } + return 0 +} + +###################################################################### +## +## PATH lookup + +if {[is_Windows]} { + set _search_path {} + proc _which {what args} { + global env _search_path + + if {$_search_path eq {}} { + set gitguidir [file dirname [info script]] + regsub -all ";" $gitguidir "\\;" gitguidir + set env(PATH) "$gitguidir;$env(PATH)" + set _search_path [split $env(PATH) {;}] + # Skip empty `PATH` elements + set _search_path [lsearch -all -inline -not -exact \ + $_search_path ""] + } + + if {[lsearch -exact $args -script] >= 0} { + set suffix {} + } else { + set suffix .exe + } + + foreach p $_search_path { + set p [file join $p $what$suffix] + if {[file exists $p]} { + return [file normalize $p] + } + } + return {} + } + + proc sanitize_command_line {command_line from_index} { + set i $from_index + while {$i < [llength $command_line]} { + set cmd [lindex $command_line $i] + if {[llength [file split $cmd]] < 2} { + set fullpath [_which $cmd] + if {$fullpath eq ""} { + throw {NOT-FOUND} "$cmd not found in PATH" + } + lset command_line $i $fullpath + } + + # handle piped commands, e.g. `exec A | B` + for {incr i} {$i < [llength $command_line]} {incr i} { + if {[lindex $command_line $i] eq "|"} { + incr i + break + } + } + } + return $command_line + } + + # Override `exec` to avoid unsafe PATH lookup + + rename exec real_exec + + proc exec {args} { + # skip options + for {set i 0} {$i < [llength $args]} {incr i} { + set arg [lindex $args $i] + if {$arg eq "--"} { + incr i + break + } + if {[string range $arg 0 0] ne "-"} { + break + } + } + set args [sanitize_command_line $args $i] + uplevel 1 real_exec $args + } + + # Override `open` to avoid unsafe PATH lookup + + rename open real_open + + proc open {args} { + set arg0 [lindex $args 0] + if {[string range $arg0 0 0] eq "|"} { + set command_line [string trim [string range $arg0 1 end]] + lset args 0 "| [sanitize_command_line $command_line 0]" + } + uplevel 1 real_open $args + } +} + +# End of safe PATH lookup stuff # Wrap exec/open to sanitize arguments @@ -2042,6 +2145,10 @@ proc confirm_popup {msg {owner .}} { return $confirm_ok } +proc haveselectionclipboard {} { + return [expr {[tk windowingsystem] eq "x11"}] +} + proc setoptions {} { global use_ttk @@ -2162,7 +2269,7 @@ proc makewindow {} { global diffcontextstring diffcontext global ignorespace global maincursor textcursor curtextcursor - global rowctxmenu fakerowmenu mergemax wrapcomment + global rowctxmenu fakerowmenu mergemax wrapcomment wrapdefault global highlight_files gdttype global searchstring sstring global bgcolor fgcolor bglist fglist diffcolors diffbgcolors selectbgcolor @@ -2172,7 +2279,7 @@ proc makewindow {} { global headctxmenu progresscanv progressitem progresscoords statusw global fprogitem fprogcoord lastprogupdate progupdatepending global rprogitem rprogcoord rownumsel numcommits - global have_tk85 use_ttk NS + global have_tk85 have_tk86 use_ttk NS global git_version global worddiff @@ -2296,7 +2403,7 @@ proc makewindow {} { set sha1entry .tf.bar.sha1 set entries $sha1entry set sha1but .tf.bar.sha1label - button $sha1but -text "[mc "SHA1 ID:"] " -state disabled -relief flat \ + button $sha1but -text "[mc "Commit ID:"] " -state disabled -relief flat \ -command gotocommit -width 8 $sha1but conf -disabledforeground [$sha1but cget -foreground] pack .tf.bar.sha1label -side left @@ -2504,7 +2611,7 @@ proc makewindow {} { set ctext .bleft.bottom.ctext text $ctext -background $bgcolor -foreground $fgcolor \ -state disabled -undo 0 -font textfont \ - -yscrollcommand scrolltext -wrap none \ + -yscrollcommand scrolltext -wrap $wrapdefault \ -xscrollcommand ".bleft.bottom.sbhorizontal set" if {$have_tk85} { $ctext conf -tabstyle wordprocessor @@ -2670,8 +2777,13 @@ proc makewindow {} { bind . <Key-Down> "selnextline 1" bind . <Shift-Key-Up> "dofind -1 0" bind . <Shift-Key-Down> "dofind 1 0" - bindkey <Key-Right> "goforw" - bindkey <Key-Left> "goback" + if {$have_tk86} { + bindkey <<NextChar>> "goforw" + bindkey <<PrevChar>> "goback" + } else { + bindkey <Key-Right> "goforw" + bindkey <Key-Left> "goback" + } bind . <Key-Prior> "selnextpage -1" bind . <Key-Next> "selnextpage 1" bind . <$M1B-Home> "allcanvs yview moveto 0.0" @@ -4559,7 +4671,7 @@ proc addviewmenu {n} { .bar.view add radiobutton -label $viewname($n) \ -command [list showview $n] -variable selectedview -value $n #$viewhlmenu add radiobutton -label $viewname($n) \ - # -command [list addvhighlight $n] -variable selectedhlview + # -command [list addvhighlight $n] -variable selectedhlview } proc showview {n} { @@ -7066,7 +7178,7 @@ proc findselectline {l} { # mark the bits of a headline or author that match a find string proc markmatches {canv l str tag matches font row} { - global selectedline + global selectedline foundbgcolor set bbox [$canv bbox $tag] set x0 [lindex $bbox 0] @@ -7080,7 +7192,7 @@ proc markmatches {canv l str tag matches font row} { set xlen [font measure $font [string range $str 0 [expr {$end}]]] set t [$canv create rect [expr {$x0+$xoff}] $y0 \ [expr {$x0+$xlen+2}] $y1 \ - -outline {} -tags [list match$l matches] -fill yellow] + -outline {} -tags [list match$l matches] -fill $foundbgcolor] $canv lower $t if {$row == $selectedline} { $canv raise $t secsel @@ -7415,7 +7527,7 @@ proc selectline {l isnew {desired_loc {}} {switch_to_patch 0}} { global mergemax numcommits pending_select global cmitmode showneartags allcommits global targetrow targetid lastscrollrows - global autoselect autosellen jump_to_here + global autocopy autoselect autosellen jump_to_here global vinlinediff unset -nocomplain pending_select @@ -7481,9 +7593,13 @@ proc selectline {l isnew {desired_loc {}} {switch_to_patch 0}} { $sha1entry delete 0 end $sha1entry insert 0 $id - if {$autoselect} { + if {$autoselect && [haveselectionclipboard]} { $sha1entry selection range 0 $autosellen } + if {$autocopy} { + clipboard clear + clipboard append [string range $id 0 [expr $autosellen - 1]] + } rhighlight_sel $id $ctext conf -state normal @@ -7783,7 +7899,7 @@ proc gettreeline {gtf id} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] lappend treefilelist($id) $fname } if {![eof $gtf]} { @@ -8045,7 +8161,7 @@ proc gettreediffline {gdtf ids} { if {[string index $file 0] eq "\""} { set file [lindex $file 0] } - set file [encoding convertfrom $file] + set file [encoding convertfrom utf-8 $file] if {$file ne [lindex $treediff end]} { lappend treediff $file lappend sublist $file @@ -8190,7 +8306,7 @@ proc makediffhdr {fname ids} { global ctext curdiffstart treediffs diffencoding global ctext_file_names jump_to_here targetline diffline - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] set diffencoding [get_path_encoding $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { @@ -8252,7 +8368,7 @@ proc parseblobdiffline {ids line} { if {![string compare -length 5 "diff " $line]} { if {![regexp {^diff (--cc|--git) } $line m type]} { - set line [encoding convertfrom $line] + set line [encoding convertfrom utf-8 $line] $ctext insert end "$line\n" hunksep continue } @@ -8301,7 +8417,7 @@ proc parseblobdiffline {ids line} { makediffhdr $fname $ids } elseif {![string compare -length 16 "* Unmerged path " $line]} { - set fname [encoding convertfrom [string range $line 16 end]] + set fname [encoding convertfrom utf-8 [string range $line 16 end]] $ctext insert end "\n" set curdiffstart [$ctext index "end - 1c"] lappend ctext_file_names $fname @@ -8354,7 +8470,7 @@ proc parseblobdiffline {ids line} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { setinlist difffilestart $i $curdiffstart @@ -8373,6 +8489,7 @@ proc parseblobdiffline {ids line} { set diffinhdr 0 return } + set line [encoding convertfrom utf-8 $line] $ctext insert end "$line\n" filesep } else { @@ -8827,7 +8944,7 @@ proc sha1change {n1 n2 op} { if {$state == "normal"} { $sha1but conf -state normal -relief raised -text "[mc "Goto:"] " } else { - $sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] " + $sha1but conf -state disabled -relief flat -text "[mc "Commit ID:"] " } } @@ -8846,7 +8963,7 @@ proc gotocommit {} { set matches [longid $id] if {$matches ne {}} { if {[llength $matches] > 1} { - error_popup [mc "Short SHA1 id %s is ambiguous" $id] + error_popup [mc "Short commit ID %s is ambiguous" $id] return } set id [lindex $matches 0] @@ -8863,7 +8980,7 @@ proc gotocommit {} { return } if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} { - set msg [mc "SHA1 id %s is not known" $sha1string] + set msg [mc "Commit ID %s is not known" $sha1string] } else { set msg [mc "Revision %s is not in the current view" $sha1string] } @@ -10125,7 +10242,7 @@ proc showrefs {} { text $top.list -background $bgcolor -foreground $fgcolor \ -selectbackground $selectbgcolor -font mainfont \ -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \ - -width 30 -height 20 -cursor $maincursor \ + -width 60 -height 20 -cursor $maincursor \ -spacing1 1 -spacing3 1 -state disabled $top.list tag configure highlight -background $selectbgcolor if {![lsearch -exact $bglist $top.list]} { @@ -11642,12 +11759,13 @@ proc create_prefs_page {w} { proc prefspage_general {notebook} { global NS maxwidth maxgraphpct showneartags showlocalchanges - global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs + global tabstop wrapcomment wrapdefault limitdiffs + global autocopy autoselect autosellen extdifftool perfile_attrs global hideremotes want_ttk have_ttk maxrefs web_browser set page [create_prefs_page $notebook.general] - ${NS}::label $page.ldisp -text [mc "Commit list display options"] + ${NS}::label $page.ldisp -text [mc "Commit list display options"] -font mainfontbold grid $page.ldisp - -sticky w -pady 10 ${NS}::label $page.spacer -text " " ${NS}::label $page.maxwidthl -text [mc "Maximum graph width (lines)"] @@ -11660,19 +11778,36 @@ proc prefspage_general {notebook} { ${NS}::checkbutton $page.showlocal -text [mc "Show local changes"] \ -variable showlocalchanges grid x $page.showlocal -sticky w - ${NS}::checkbutton $page.autoselect -text [mc "Auto-select SHA1 (length)"] \ - -variable autoselect - spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen - grid x $page.autoselect $page.autosellen -sticky w ${NS}::checkbutton $page.hideremotes -text [mc "Hide remote refs"] \ -variable hideremotes grid x $page.hideremotes -sticky w - ${NS}::label $page.ddisp -text [mc "Diff display options"] + ${NS}::checkbutton $page.autocopy -text [mc "Copy commit ID to clipboard"] \ + -variable autocopy + grid x $page.autocopy -sticky w + if {[haveselectionclipboard]} { + ${NS}::checkbutton $page.autoselect -text [mc "Copy commit ID to X11 selection"] \ + -variable autoselect + grid x $page.autoselect -sticky w + } + spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen + ${NS}::label $page.autosellenl -text [mc "Length of commit ID to copy"] + grid x $page.autosellenl $page.autosellen -sticky w + + ${NS}::label $page.ddisp -text [mc "Diff display options"] -font mainfontbold grid $page.ddisp - -sticky w -pady 10 ${NS}::label $page.tabstopl -text [mc "Tab spacing"] spinbox $page.tabstop -from 1 -to 20 -width 4 -textvariable tabstop grid x $page.tabstopl $page.tabstop -sticky w + + ${NS}::label $page.wrapcommentl -text [mc "Wrap comment text"] + makedroplist $page.wrapcomment wrapcomment none char word + grid x $page.wrapcommentl $page.wrapcomment -sticky w + + ${NS}::label $page.wrapdefaultl -text [mc "Wrap other text"] + makedroplist $page.wrapdefault wrapdefault none char word + grid x $page.wrapdefaultl $page.wrapdefault -sticky w + ${NS}::checkbutton $page.ntag -text [mc "Display nearby tags/heads"] \ -variable showneartags grid x $page.ntag -sticky w @@ -11701,7 +11836,7 @@ proc prefspage_general {notebook} { pack configure $page.webbrowserf.l -padx 10 grid x $page.webbrowserf $page.webbrowser -sticky ew - ${NS}::label $page.lgen -text [mc "General options"] + ${NS}::label $page.lgen -text [mc "General options"] -font mainfontbold grid $page.lgen - -sticky w -pady 10 ${NS}::checkbutton $page.want_ttk -variable want_ttk \ -text [mc "Use themed widgets"] @@ -11720,7 +11855,7 @@ proc prefspage_colors {notebook} { set page [create_prefs_page $notebook.colors] - ${NS}::label $page.cdisp -text [mc "Colors: press to choose"] + ${NS}::label $page.cdisp -text [mc "Colors: press to choose"] -font mainfontbold grid $page.cdisp - -sticky w -pady 10 label $page.ui -padx 40 -relief sunk -background $uicolor ${NS}::button $page.uibut -text [mc "Interface"] \ @@ -11778,7 +11913,7 @@ proc prefspage_colors {notebook} { proc prefspage_fonts {notebook} { global NS set page [create_prefs_page $notebook.fonts] - ${NS}::label $page.cfont -text [mc "Fonts: press to choose"] + ${NS}::label $page.cfont -text [mc "Fonts: press to choose"] -font mainfontbold grid $page.cfont - -sticky w -pady 10 mkfontdisp mainfont $page [mc "Main font"] mkfontdisp textfont $page [mc "Diff display font"] @@ -11791,7 +11926,7 @@ proc doprefs {} { global oldprefs prefstop showneartags showlocalchanges global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs - global hideremotes want_ttk have_ttk + global hideremotes want_ttk have_ttk wrapcomment wrapdefault set top .gitkprefs set prefstop $top @@ -11800,7 +11935,7 @@ proc doprefs {} { return } foreach v {maxwidth maxgraphpct showneartags showlocalchanges \ - limitdiffs tabstop perfile_attrs hideremotes want_ttk} { + limitdiffs tabstop perfile_attrs hideremotes want_ttk wrapcomment wrapdefault} { set oldprefs($v) [set $v] } ttk_toplevel $top @@ -11926,7 +12061,7 @@ proc prefscan {} { global oldprefs prefstop foreach v {maxwidth maxgraphpct showneartags showlocalchanges \ - limitdiffs tabstop perfile_attrs hideremotes want_ttk} { + limitdiffs tabstop perfile_attrs hideremotes want_ttk wrapcomment wrapdefault} { global $v set $v $oldprefs($v) } @@ -11940,7 +12075,8 @@ proc prefsok {} { global oldprefs prefstop showneartags showlocalchanges global fontpref mainfont textfont uifont global limitdiffs treediffs perfile_attrs - global hideremotes + global hideremotes wrapcomment wrapdefault + global ctext catch {destroy $prefstop} unset prefstop @@ -11989,6 +12125,12 @@ proc prefsok {} { if {$hideremotes != $oldprefs(hideremotes)} { rereadrefs } + if {$wrapcomment != $oldprefs(wrapcomment)} { + $ctext tag conf comment -wrap $wrapcomment + } + if {$wrapdefault != $oldprefs(wrapdefault)} { + $ctext configure -wrap $wrapdefault + } } proc formatdate {d} { @@ -12336,7 +12478,7 @@ proc cache_gitattr {attr pathlist} { foreach row [split $rlist "\n"] { if {[regexp "(.*): $attr: (.*)" $row m path value]} { if {[string index $path 0] eq "\""} { - set path [encoding convertfrom [lindex $path 0]] + set path [encoding convertfrom utf-8 [lindex $path 0]] } set path_attr_cache($attr,$path) $value } @@ -12366,7 +12508,6 @@ if { [info exists ::env(GITK_MSGSDIR)] } { set gitk_prefix [file dirname [file dirname [file normalize $argv0]]] set gitk_libdir [file join $gitk_prefix share gitk lib] set gitk_msgsdir [file join $gitk_libdir msgs] - unset gitk_prefix } ## Internationalization (i18n) through msgcat and gettext. See @@ -12458,6 +12599,7 @@ set downarrowlen 5 set mingaplen 100 set cmitmode "patch" set wrapcomment "none" +set wrapdefault "none" set showneartags 1 set hideremotes 0 set maxrefs 20 @@ -12466,6 +12608,7 @@ set maxlinelen 200 set showlocalchanges 1 set limitdiffs 1 set datetimeformat "%Y-%m-%d %H:%M:%S" +set autocopy 0 set autoselect 1 set autosellen 40 set perfile_attrs 0 @@ -12563,7 +12706,8 @@ config_check_tmp_exists 50 set config_variables { mainfont textfont uifont tabstop findmergefiles maxgraphpct maxwidth - cmitmode wrapcomment autoselect autosellen showneartags maxrefs visiblerefs + cmitmode wrapcomment wrapdefault autocopy autoselect autosellen + showneartags maxrefs visiblerefs hideremotes showlocalchanges datetimeformat limitdiffs uicolor want_ttk bgcolor fgcolor uifgcolor uifgdisabledcolor colors diffcolors mergecolors markbgcolor diffcontext selectbgcolor foundbgcolor currentsearchhitbgcolor @@ -12665,6 +12809,7 @@ set nullid2 "0000000000000000000000000000000000000001" set nullfile "/dev/null" set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}] +set have_tk86 [expr {[package vcompare $tk_version "8.6"] >= 0}] if {![info exists have_ttk]} { set have_ttk [llength [info commands ::ttk::style]] } @@ -12729,31 +12874,35 @@ if {[expr {[exec git rev-parse --is-inside-work-tree] == "true"}]} { set worktree [gitworktree] setcoords makewindow -catch { - image create photo gitlogo -width 16 -height 16 +if {$::tcl_platform(platform) eq {windows} && [file exists $gitk_prefix/etc/git.ico]} { + wm iconbitmap . -default $gitk_prefix/etc/git.ico +} else { + catch { + image create photo gitlogo -width 16 -height 16 - image create photo gitlogominus -width 4 -height 2 - gitlogominus put #C00000 -to 0 0 4 2 - gitlogo copy gitlogominus -to 1 5 - gitlogo copy gitlogominus -to 6 5 - gitlogo copy gitlogominus -to 11 5 - image delete gitlogominus + image create photo gitlogominus -width 4 -height 2 + gitlogominus put #C00000 -to 0 0 4 2 + gitlogo copy gitlogominus -to 1 5 + gitlogo copy gitlogominus -to 6 5 + gitlogo copy gitlogominus -to 11 5 + image delete gitlogominus - image create photo gitlogoplus -width 4 -height 4 - gitlogoplus put #008000 -to 1 0 3 4 - gitlogoplus put #008000 -to 0 1 4 3 - gitlogo copy gitlogoplus -to 1 9 - gitlogo copy gitlogoplus -to 6 9 - gitlogo copy gitlogoplus -to 11 9 - image delete gitlogoplus + image create photo gitlogoplus -width 4 -height 4 + gitlogoplus put #008000 -to 1 0 3 4 + gitlogoplus put #008000 -to 0 1 4 3 + gitlogo copy gitlogoplus -to 1 9 + gitlogo copy gitlogoplus -to 6 9 + gitlogo copy gitlogoplus -to 11 9 + image delete gitlogoplus - image create photo gitlogo32 -width 32 -height 32 - gitlogo32 copy gitlogo -zoom 2 2 + image create photo gitlogo32 -width 32 -height 32 + gitlogo32 copy gitlogo -zoom 2 2 - wm iconphoto . -default gitlogo gitlogo32 + wm iconphoto . -default gitlogo gitlogo32 + } } # wait for the window to become visible -tkwait visibility . +if {![winfo viewable .]} {tkwait visibility .} set_window_title update readrefs |
