github.com/jmigpin/editor@v1.6.0/util/osutil/misc.go (about)

     1  package osutil
     2  
     3  import (
     4  	"errors"
     5  	"math/rand"
     6  	"net"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  	"runtime"
    11  	"strings"
    12  	"time"
    13  )
    14  
    15  func HomeEnvVar() string {
    16  	h, err := os.UserHomeDir()
    17  	if err != nil {
    18  		return ""
    19  	}
    20  	return h
    21  }
    22  
    23  //----------
    24  
    25  func FilepathHasDirPrefix(s, prefix string) bool {
    26  	// ensure it ends in separator
    27  	sep := string(filepath.Separator)
    28  	if !strings.HasSuffix(prefix, sep) {
    29  		prefix += sep
    30  	}
    31  
    32  	return strings.HasPrefix(s, prefix)
    33  }
    34  
    35  // Result does not start with separator.
    36  func FilepathSplitAt(s string, n int) string {
    37  	if n > len(s) {
    38  		return ""
    39  	}
    40  	for ; n < len(s); n++ {
    41  		if s[n] != filepath.Separator {
    42  			break
    43  		}
    44  	}
    45  	return s[n:]
    46  }
    47  
    48  func FilepathClean(s string) string {
    49  	return filepath.Clean(s)
    50  }
    51  
    52  //----------
    53  
    54  func GetFreeTcpPort() (int, error) {
    55  	addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
    56  	if err != nil {
    57  		return 0, err
    58  	}
    59  	l, err := net.ListenTCP("tcp", addr)
    60  	if err != nil {
    61  		return 0, err
    62  	}
    63  	defer l.Close()
    64  	p := l.Addr().(*net.TCPAddr).Port
    65  	return p, nil
    66  }
    67  
    68  func RandomPort(simpleSeed, min, max int) int {
    69  	seed := time.Now().UnixNano() + int64(os.Getpid()+simpleSeed)
    70  	ra := rand.New(rand.NewSource(int64(seed)))
    71  	return min + ra.Intn(max-min)
    72  }
    73  
    74  //----------
    75  
    76  // doesn't wait for the cmd to end
    77  func OpenBrowser(url string) error {
    78  	var c *exec.Cmd
    79  	switch runtime.GOOS {
    80  	case "windows":
    81  		c = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
    82  	case "darwin":
    83  		c = exec.Command("open", url)
    84  	default: // linux, others...
    85  		c = exec.Command("xdg-open", url)
    86  	}
    87  	return cmdStartWaitAsync(c)
    88  }
    89  
    90  // doesn't wait for the cmd to end
    91  func OpenFilemanager(filename string) error {
    92  	var c *exec.Cmd
    93  	switch runtime.GOOS {
    94  	case "windows":
    95  		c = exec.Command("explorer", "/select,"+filename)
    96  	case "darwin":
    97  		c = exec.Command("open", filename)
    98  	default: // linux, others...
    99  		c = exec.Command("xdg-open", filename)
   100  	}
   101  	return cmdStartWaitAsync(c)
   102  }
   103  
   104  // doesn't wait for the cmd to end
   105  func OpenTerminal(filename string) error {
   106  	var c *exec.Cmd
   107  	switch runtime.GOOS {
   108  	case "windows":
   109  		return errors.New("todo")
   110  	case "darwin":
   111  		return errors.New("todo")
   112  	default: // linux, others...
   113  		c = exec.Command("x-terminal-emulator", "--working-directory="+filename)
   114  	}
   115  	return cmdStartWaitAsync(c)
   116  }
   117  
   118  func cmdStartWaitAsync(c *exec.Cmd) error {
   119  	if err := c.Start(); err != nil {
   120  		return err
   121  	}
   122  	go c.Wait() // async to let run, but wait to clear resources
   123  	return nil
   124  }