github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/cmds/core/less/main.go (about) 1 // Copyright 2018 the u-root 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 // less pages through a file 6 // 7 // Synopsis: 8 // less [OPTIONS] FILE 9 // 10 // Options: 11 // -profile FILE: Save profile in this file 12 // -tabstop NUMBER: Number of spaces per tab 13 // 14 // Keybindings: 15 // Control: 16 // 17 // * q: Quit 18 // 19 // Scrolling: 20 // 21 // * j: Scroll down 22 // * k: Scroll up 23 // * g: Scroll to top 24 // * G: Scroll to bottom 25 // * Pgdn: Scroll down one screen full 26 // * Pgup: Scroll up one screen full 27 // * ^D: Scroll down one half screen full 28 // * ^U: Scroll up one half screen full 29 // 30 // Searching: 31 // 32 // * /: Enter search regex (re2 syntax). Press enter to search. 33 // * n: Jump down to next search result 34 // * N: Jump up to previous search result 35 // 36 // Author: 37 // Michael Pratt (github.com/prattmic) whom we are forever grateful for 38 // writing https://github.com/prattmic/lesser. 39 package main 40 41 import ( 42 "bytes" 43 "fmt" 44 "log" 45 "os" 46 "runtime/pprof" 47 "syscall" 48 49 "github.com/nsf/termbox-go" 50 flag "github.com/spf13/pflag" 51 "github.com/u-root/u-root/pkg/less" 52 ) 53 54 var profile = flag.String("profile", "", "Save profile in this file") 55 var tabStop = flag.Int("tabstop", 8, "Number of spaces per tab") 56 57 func mmapFile(f *os.File) ([]byte, error) { 58 stat, err := f.Stat() 59 if err != nil { 60 return nil, err 61 } 62 63 return syscall.Mmap(int(f.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_PRIVATE) 64 } 65 66 func main() { 67 flag.Usage = func() { 68 fmt.Fprintf(os.Stderr, "Usage of %s: %s filename\n", os.Args[0], os.Args[0]) 69 flag.PrintDefaults() 70 } 71 flag.Parse() 72 73 if len(flag.Args()) != 1 { 74 flag.Usage() 75 os.Exit(1) 76 } 77 78 name := flag.Arg(0) 79 f, err := os.Open(name) 80 if err != nil { 81 log.Fatalf("failed to open %s: %v", name, err) 82 } 83 84 m, err := mmapFile(f) 85 if err != nil { 86 log.Fatalf("failed to mmap file: %v", err) 87 } 88 defer syscall.Munmap(m) 89 90 err = termbox.Init() 91 if err != nil { 92 log.Fatalf("Failed to init: %v", err) 93 } 94 defer termbox.Close() 95 96 if *profile != "" { 97 p, err := os.Create(*profile) 98 if err != nil { 99 log.Fatalf("Failed to create profile: %v", err) 100 } 101 defer p.Close() 102 pprof.StartCPUProfile(p) 103 defer pprof.StopCPUProfile() 104 } 105 106 l := less.NewLess(bytes.NewReader(m), *tabStop) 107 l.Run() 108 }