Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / internal / lsp / browser / browser.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package browser provides utilities for interacting with users' browsers.
6 package browser
7
8 import (
9         "os"
10         "os/exec"
11         "runtime"
12         "time"
13 )
14
15 // Commands returns a list of possible commands to use to open a url.
16 func Commands() [][]string {
17         var cmds [][]string
18         if exe := os.Getenv("BROWSER"); exe != "" {
19                 cmds = append(cmds, []string{exe})
20         }
21         switch runtime.GOOS {
22         case "darwin":
23                 cmds = append(cmds, []string{"/usr/bin/open"})
24         case "windows":
25                 cmds = append(cmds, []string{"cmd", "/c", "start"})
26         default:
27                 if os.Getenv("DISPLAY") != "" {
28                         // xdg-open is only for use in a desktop environment.
29                         cmds = append(cmds, []string{"xdg-open"})
30                 }
31         }
32         cmds = append(cmds,
33                 []string{"chrome"},
34                 []string{"google-chrome"},
35                 []string{"chromium"},
36                 []string{"firefox"},
37         )
38         return cmds
39 }
40
41 // Open tries to open url in a browser and reports whether it succeeded.
42 func Open(url string) bool {
43         for _, args := range Commands() {
44                 cmd := exec.Command(args[0], append(args[1:], url)...)
45                 if cmd.Start() == nil && appearsSuccessful(cmd, 3*time.Second) {
46                         return true
47                 }
48         }
49         return false
50 }
51
52 // appearsSuccessful reports whether the command appears to have run successfully.
53 // If the command runs longer than the timeout, it's deemed successful.
54 // If the command runs within the timeout, it's deemed successful if it exited cleanly.
55 func appearsSuccessful(cmd *exec.Cmd, timeout time.Duration) bool {
56         errc := make(chan error, 1)
57         go func() {
58                 errc <- cmd.Wait()
59         }()
60
61         select {
62         case <-time.After(timeout):
63                 return true
64         case err := <-errc:
65                 return err == nil
66         }
67 }