gitk: Make web links clickable

This makes gitk look for http or https URLs in the commit description and make the URLs clickable. Clicking on them will invoke an external web browser with the URL. The web browser command is by default "xdg-open" on Linux, "open" on MacOS, and "cmd /c start" on Windows. The command can be changed in the preferences window, and it can include parameters as well as the command name. If it is set to the empty string then URLs will no longer be made clickable. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>

Paul Mackerras committed Aug 27, 2019 at 08:12 UTC 3441de5b9cbc93ebfea0e70bf28b32e2eecba5bd
1 file changed +50 -1
gitk
+50 -1
@@ -7016,6 +7016,7 @@ proc commit_descriptor {p} {
7016
7017 # append some text to the ctext widget, and make any SHA1 ID
7018 # that we know about be a clickable link.
7019 +# Also look for URLs of the form "http[s]://..." and make them web links.
7020 proc appendwithlinks {text tags} {
7021 global ctext linknum curview
7022
@@ -7032,6 +7033,18 @@ proc appendwithlinks {text tags} {
7033 setlink $linkid link$linknum
7034 incr linknum
7035 }
7036 + set wlinks [regexp -indices -all -inline -line \
7037 + {https?://[^[:space:]]+} $text]
7038 + foreach l $wlinks {
7039 + set s2 [lindex $l 0]
7040 + set e2 [lindex $l 1]
7041 + set url [string range $text $s2 $e2]
7042 + incr e2
7043 + $ctext tag delete link$linknum
7044 + $ctext tag add link$linknum "$start + $s2 c" "$start + $e2 c"
7045 + setwlink $url link$linknum
7046 + incr linknum
7047 + }
7048 }
7049
7050 proc setlink {id lk} {
@@ -7064,6 +7077,18 @@ proc setlink {id lk} {
7077 }
7078 }
7079
7080 +proc setwlink {url lk} {
7081 + global ctext
7082 + global linkfgcolor
7083 + global web_browser
7084 +
7085 + if {$web_browser eq {}} return
7086 + $ctext tag conf $lk -foreground $linkfgcolor -underline 1
7087 + $ctext tag bind $lk <1> [list browseweb $url]
7088 + $ctext tag bind $lk <Enter> {linkcursor %W 1}
7089 + $ctext tag bind $lk <Leave> {linkcursor %W -1}
7090 +}
7091 +
7092 proc appendshortlink {id {pre {}} {post {}}} {
7093 global ctext linknum
7094
@@ -7098,6 +7123,16 @@ proc linkcursor {w inc} {
7123 }
7124 }
7125
7126 +proc browseweb {url} {
7127 + global web_browser
7128 +
7129 + if {$web_browser eq {}} return
7130 + # Use eval here in case $web_browser is a command plus some arguments
7131 + if {[catch {eval exec $web_browser [list $url] &} err]} {
7132 + error_popup "[mc "Error starting web browser:"] $err"
7133 + }
7134 +}
7135 +
7136 proc viewnextline {dir} {
7137 global canv linespc
7138
@@ -11488,7 +11523,7 @@ proc create_prefs_page {w} {
11523 proc prefspage_general {notebook} {
11524 global NS maxwidth maxgraphpct showneartags showlocalchanges
11525 global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs
11491 - global hideremotes want_ttk have_ttk maxrefs
11526 + global hideremotes want_ttk have_ttk maxrefs web_browser
11527
11528 set page [create_prefs_page $notebook.general]
11529
@@ -11539,6 +11574,13 @@ proc prefspage_general {notebook} {
11574 pack configure $page.extdifff.l -padx 10
11575 grid x $page.extdifff $page.extdifft -sticky ew
11576
11577 + ${NS}::entry $page.webbrowser -textvariable web_browser
11578 + ${NS}::frame $page.webbrowserf
11579 + ${NS}::label $page.webbrowserf.l -text [mc "Web browser" ]
11580 + pack $page.webbrowserf.l -side left
11581 + pack configure $page.webbrowserf.l -padx 10
11582 + grid x $page.webbrowserf $page.webbrowser -sticky ew
11583 +
11584 ${NS}::label $page.lgen -text [mc "General options"]
11585 grid $page.lgen - -sticky w -pady 10
11586 ${NS}::checkbutton $page.want_ttk -variable want_ttk \
@@ -12310,6 +12352,7 @@ if {[tk windowingsystem] eq "win32"} {
12352 set bgcolor SystemWindow
12353 set fgcolor SystemWindowText
12354 set selectbgcolor SystemHighlight
12355 + set web_browser "cmd /c start"
12356 } else {
12357 set uicolor grey85
12358 set uifgcolor black
@@ -12317,6 +12360,11 @@ if {[tk windowingsystem] eq "win32"} {
12360 set bgcolor white
12361 set fgcolor black
12362 set selectbgcolor gray85
12363 + if {[tk windowingsystem] eq "aqua"} {
12364 + set web_browser "open"
12365 + } else {
12366 + set web_browser "xdg-open"
12367 + }
12368 }
12369 set diffcolors {red "#00a000" blue}
12370 set diffcontext 3
@@ -12390,6 +12438,7 @@ set config_variables {
12438 filesepbgcolor filesepfgcolor linehoverbgcolor linehoverfgcolor
12439 linehoveroutlinecolor mainheadcirclecolor workingfilescirclecolor
12440 indexcirclecolor circlecolors linkfgcolor circleoutlinecolor
12441 + web_browser
12442 }
12443 foreach var $config_variables {
12444 config_init_trace $var