main.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package main
  2. import (
  3. "servitor/config"
  4. "servitor/ui"
  5. "os"
  6. "strings"
  7. "time"
  8. "golang.org/x/term"
  9. )
  10. func main() {
  11. if len(os.Args) < 3 {
  12. help()
  13. }
  14. config, err := config.Parse()
  15. if err != nil {
  16. os.Stderr.WriteString(err.Error() + "\n")
  17. return
  18. }
  19. oldTerminal, err := term.MakeRaw(int(os.Stdin.Fd()))
  20. if err != nil {
  21. panic(err)
  22. }
  23. defer term.Restore(int(os.Stdin.Fd()), oldTerminal)
  24. width, height, err := term.GetSize(int(os.Stdin.Fd()))
  25. if err != nil {
  26. panic(err)
  27. }
  28. state := ui.NewState(config, width, height, printRaw)
  29. go func() {
  30. for {
  31. time.Sleep(500 * time.Millisecond)
  32. width, height, err := term.GetSize(int(os.Stdin.Fd()))
  33. if err != nil {
  34. panic(err)
  35. }
  36. state.SetWidthHeight(width, height)
  37. }
  38. }()
  39. go func() {
  40. /* Perhaps a bad design, but this holds its lock indefinitely on error, allowing for cleanup */
  41. err = state.Subcommand(os.Args[1], os.Args[2])
  42. if err != nil {
  43. term.Restore(int(os.Stdin.Fd()), oldTerminal)
  44. help()
  45. }
  46. }()
  47. buffer := make([]byte, 1)
  48. for {
  49. os.Stdin.Read(buffer)
  50. input := buffer[0]
  51. if input == 3 /*(ctrl+c)*/ {
  52. printRaw("")
  53. return
  54. }
  55. go state.Update(input)
  56. }
  57. }
  58. func printRaw(output string) {
  59. output = strings.ReplaceAll(output, "\n", "\r\n")
  60. _, err := os.Stdout.WriteString("\x1b[0;0H\x1b[2J" + output)
  61. if err != nil {
  62. panic(err)
  63. }
  64. }
  65. const version = "0.0.0"
  66. func help() {
  67. os.Stdout.WriteString(
  68. "Servitor v" + version + `
  69. Commands:
  70. servitor open <url or @>
  71. servitor feed <feed name>
  72. Keybindings:
  73. Navigation:
  74. j - move down
  75. k - move up
  76. space - select the highlighted item
  77. c - view the creator of the highlighted item
  78. r - view the recipient of the highlighted item (e.g. the group it was posted to)
  79. a - view the actor of the activity (e.g. view the retweeter of a retweet)
  80. h - move back in your browser history
  81. l - move forward in your browser history
  82. g - move to the expanded item (i.e. move to the current OP)
  83. ctrl+c - exit the program
  84. Media:
  85. p - open the highlighted user's profile picture
  86. b - open the highlighted user's banner
  87. o - open the content of a post itself (e.g. open the video associated with a video post)
  88. number keys - open a link within the highlighted text
  89. Commands:
  90. :open <url or @>
  91. :feed <feed name>
  92. `)
  93. os.Exit(0)
  94. }