cursor.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. package ansi
  2. import "strconv"
  3. // SaveCursor (DECSC) is an escape sequence that saves the current cursor
  4. // position.
  5. //
  6. // ESC 7
  7. //
  8. // See: https://vt100.net/docs/vt510-rm/DECSC.html
  9. const (
  10. SaveCursor = "\x1b7"
  11. DECSC = SaveCursor
  12. )
  13. // RestoreCursor (DECRC) is an escape sequence that restores the cursor
  14. // position.
  15. //
  16. // ESC 8
  17. //
  18. // See: https://vt100.net/docs/vt510-rm/DECRC.html
  19. const (
  20. RestoreCursor = "\x1b8"
  21. DECRC = RestoreCursor
  22. )
  23. // RequestCursorPosition is an escape sequence that requests the current cursor
  24. // position.
  25. //
  26. // CSI 6 n
  27. //
  28. // The terminal will report the cursor position as a CSI sequence in the
  29. // following format:
  30. //
  31. // CSI Pl ; Pc R
  32. //
  33. // Where Pl is the line number and Pc is the column number.
  34. // See: https://vt100.net/docs/vt510-rm/CPR.html
  35. const RequestCursorPosition = "\x1b[6n"
  36. // RequestExtendedCursorPosition (DECXCPR) is a sequence for requesting the
  37. // cursor position report including the current page number.
  38. //
  39. // CSI ? 6 n
  40. //
  41. // The terminal will report the cursor position as a CSI sequence in the
  42. // following format:
  43. //
  44. // CSI ? Pl ; Pc ; Pp R
  45. //
  46. // Where Pl is the line number, Pc is the column number, and Pp is the page
  47. // number.
  48. // See: https://vt100.net/docs/vt510-rm/DECXCPR.html
  49. const RequestExtendedCursorPosition = "\x1b[?6n"
  50. // CursorUp (CUU) returns a sequence for moving the cursor up n cells.
  51. //
  52. // CSI n A
  53. //
  54. // See: https://vt100.net/docs/vt510-rm/CUU.html
  55. func CursorUp(n int) string {
  56. var s string
  57. if n > 1 {
  58. s = strconv.Itoa(n)
  59. }
  60. return "\x1b[" + s + "A"
  61. }
  62. // CUU is an alias for [CursorUp].
  63. func CUU(n int) string {
  64. return CursorUp(n)
  65. }
  66. // CUU1 is a sequence for moving the cursor up one cell.
  67. const CUU1 = "\x1b[A"
  68. // CursorUp1 is a sequence for moving the cursor up one cell.
  69. //
  70. // This is equivalent to CursorUp(1).
  71. //
  72. // Deprecated: use [CUU1] instead.
  73. const CursorUp1 = "\x1b[A"
  74. // CursorDown (CUD) returns a sequence for moving the cursor down n cells.
  75. //
  76. // CSI n B
  77. //
  78. // See: https://vt100.net/docs/vt510-rm/CUD.html
  79. func CursorDown(n int) string {
  80. var s string
  81. if n > 1 {
  82. s = strconv.Itoa(n)
  83. }
  84. return "\x1b[" + s + "B"
  85. }
  86. // CUD is an alias for [CursorDown].
  87. func CUD(n int) string {
  88. return CursorDown(n)
  89. }
  90. // CUD1 is a sequence for moving the cursor down one cell.
  91. const CUD1 = "\x1b[B"
  92. // CursorDown1 is a sequence for moving the cursor down one cell.
  93. //
  94. // This is equivalent to CursorDown(1).
  95. //
  96. // Deprecated: use [CUD1] instead.
  97. const CursorDown1 = "\x1b[B"
  98. // CursorForward (CUF) returns a sequence for moving the cursor right n cells.
  99. //
  100. // # CSI n C
  101. //
  102. // See: https://vt100.net/docs/vt510-rm/CUF.html
  103. func CursorForward(n int) string {
  104. var s string
  105. if n > 1 {
  106. s = strconv.Itoa(n)
  107. }
  108. return "\x1b[" + s + "C"
  109. }
  110. // CUF is an alias for [CursorForward].
  111. func CUF(n int) string {
  112. return CursorForward(n)
  113. }
  114. // CUF1 is a sequence for moving the cursor right one cell.
  115. const CUF1 = "\x1b[C"
  116. // CursorRight (CUF) returns a sequence for moving the cursor right n cells.
  117. //
  118. // CSI n C
  119. //
  120. // See: https://vt100.net/docs/vt510-rm/CUF.html
  121. //
  122. // Deprecated: use [CursorForward] instead.
  123. func CursorRight(n int) string {
  124. return CursorForward(n)
  125. }
  126. // CursorRight1 is a sequence for moving the cursor right one cell.
  127. //
  128. // This is equivalent to CursorRight(1).
  129. //
  130. // Deprecated: use [CUF1] instead.
  131. const CursorRight1 = CUF1
  132. // CursorBackward (CUB) returns a sequence for moving the cursor left n cells.
  133. //
  134. // # CSI n D
  135. //
  136. // See: https://vt100.net/docs/vt510-rm/CUB.html
  137. func CursorBackward(n int) string {
  138. var s string
  139. if n > 1 {
  140. s = strconv.Itoa(n)
  141. }
  142. return "\x1b[" + s + "D"
  143. }
  144. // CUB is an alias for [CursorBackward].
  145. func CUB(n int) string {
  146. return CursorBackward(n)
  147. }
  148. // CUB1 is a sequence for moving the cursor left one cell.
  149. const CUB1 = "\x1b[D"
  150. // CursorLeft (CUB) returns a sequence for moving the cursor left n cells.
  151. //
  152. // CSI n D
  153. //
  154. // See: https://vt100.net/docs/vt510-rm/CUB.html
  155. //
  156. // Deprecated: use [CursorBackward] instead.
  157. func CursorLeft(n int) string {
  158. return CursorBackward(n)
  159. }
  160. // CursorLeft1 is a sequence for moving the cursor left one cell.
  161. //
  162. // This is equivalent to CursorLeft(1).
  163. //
  164. // Deprecated: use [CUB1] instead.
  165. const CursorLeft1 = CUB1
  166. // CursorNextLine (CNL) returns a sequence for moving the cursor to the
  167. // beginning of the next line n times.
  168. //
  169. // CSI n E
  170. //
  171. // See: https://vt100.net/docs/vt510-rm/CNL.html
  172. func CursorNextLine(n int) string {
  173. var s string
  174. if n > 1 {
  175. s = strconv.Itoa(n)
  176. }
  177. return "\x1b[" + s + "E"
  178. }
  179. // CNL is an alias for [CursorNextLine].
  180. func CNL(n int) string {
  181. return CursorNextLine(n)
  182. }
  183. // CursorPreviousLine (CPL) returns a sequence for moving the cursor to the
  184. // beginning of the previous line n times.
  185. //
  186. // CSI n F
  187. //
  188. // See: https://vt100.net/docs/vt510-rm/CPL.html
  189. func CursorPreviousLine(n int) string {
  190. var s string
  191. if n > 1 {
  192. s = strconv.Itoa(n)
  193. }
  194. return "\x1b[" + s + "F"
  195. }
  196. // CPL is an alias for [CursorPreviousLine].
  197. func CPL(n int) string {
  198. return CursorPreviousLine(n)
  199. }
  200. // CursorHorizontalAbsolute (CHA) returns a sequence for moving the cursor to
  201. // the given column.
  202. //
  203. // Default is 1.
  204. //
  205. // CSI n G
  206. //
  207. // See: https://vt100.net/docs/vt510-rm/CHA.html
  208. func CursorHorizontalAbsolute(col int) string {
  209. var s string
  210. if col > 0 {
  211. s = strconv.Itoa(col)
  212. }
  213. return "\x1b[" + s + "G"
  214. }
  215. // CHA is an alias for [CursorHorizontalAbsolute].
  216. func CHA(col int) string {
  217. return CursorHorizontalAbsolute(col)
  218. }
  219. // CursorPosition (CUP) returns a sequence for setting the cursor to the
  220. // given row and column.
  221. //
  222. // Default is 1,1.
  223. //
  224. // CSI n ; m H
  225. //
  226. // See: https://vt100.net/docs/vt510-rm/CUP.html
  227. func CursorPosition(col, row int) string {
  228. if row <= 0 && col <= 0 {
  229. return HomeCursorPosition
  230. }
  231. var r, c string
  232. if row > 0 {
  233. r = strconv.Itoa(row)
  234. }
  235. if col > 0 {
  236. c = strconv.Itoa(col)
  237. }
  238. return "\x1b[" + r + ";" + c + "H"
  239. }
  240. // CUP is an alias for [CursorPosition].
  241. func CUP(col, row int) string {
  242. return CursorPosition(col, row)
  243. }
  244. // CursorHomePosition is a sequence for moving the cursor to the upper left
  245. // corner of the scrolling region. This is equivalent to `CursorPosition(1, 1)`.
  246. const CursorHomePosition = "\x1b[H"
  247. // SetCursorPosition (CUP) returns a sequence for setting the cursor to the
  248. // given row and column.
  249. //
  250. // CSI n ; m H
  251. //
  252. // See: https://vt100.net/docs/vt510-rm/CUP.html
  253. //
  254. // Deprecated: use [CursorPosition] instead.
  255. func SetCursorPosition(col, row int) string {
  256. if row <= 0 && col <= 0 {
  257. return HomeCursorPosition
  258. }
  259. var r, c string
  260. if row > 0 {
  261. r = strconv.Itoa(row)
  262. }
  263. if col > 0 {
  264. c = strconv.Itoa(col)
  265. }
  266. return "\x1b[" + r + ";" + c + "H"
  267. }
  268. // HomeCursorPosition is a sequence for moving the cursor to the upper left
  269. // corner of the scrolling region. This is equivalent to `SetCursorPosition(1, 1)`.
  270. //
  271. // Deprecated: use [CursorHomePosition] instead.
  272. const HomeCursorPosition = CursorHomePosition
  273. // MoveCursor (CUP) returns a sequence for setting the cursor to the
  274. // given row and column.
  275. //
  276. // CSI n ; m H
  277. //
  278. // See: https://vt100.net/docs/vt510-rm/CUP.html
  279. //
  280. // Deprecated: use [CursorPosition] instead.
  281. func MoveCursor(col, row int) string {
  282. return SetCursorPosition(col, row)
  283. }
  284. // CursorOrigin is a sequence for moving the cursor to the upper left corner of
  285. // the display. This is equivalent to `SetCursorPosition(1, 1)`.
  286. //
  287. // Deprecated: use [CursorHomePosition] instead.
  288. const CursorOrigin = "\x1b[1;1H"
  289. // MoveCursorOrigin is a sequence for moving the cursor to the upper left
  290. // corner of the display. This is equivalent to `SetCursorPosition(1, 1)`.
  291. //
  292. // Deprecated: use [CursorHomePosition] instead.
  293. const MoveCursorOrigin = CursorOrigin
  294. // CursorHorizontalForwardTab (CHT) returns a sequence for moving the cursor to
  295. // the next tab stop n times.
  296. //
  297. // Default is 1.
  298. //
  299. // CSI n I
  300. //
  301. // See: https://vt100.net/docs/vt510-rm/CHT.html
  302. func CursorHorizontalForwardTab(n int) string {
  303. var s string
  304. if n > 1 {
  305. s = strconv.Itoa(n)
  306. }
  307. return "\x1b[" + s + "I"
  308. }
  309. // CHT is an alias for [CursorHorizontalForwardTab].
  310. func CHT(n int) string {
  311. return CursorHorizontalForwardTab(n)
  312. }
  313. // EraseCharacter (ECH) returns a sequence for erasing n characters and moving
  314. // the cursor to the right. This doesn't affect other cell attributes.
  315. //
  316. // Default is 1.
  317. //
  318. // CSI n X
  319. //
  320. // See: https://vt100.net/docs/vt510-rm/ECH.html
  321. func EraseCharacter(n int) string {
  322. var s string
  323. if n > 1 {
  324. s = strconv.Itoa(n)
  325. }
  326. return "\x1b[" + s + "X"
  327. }
  328. // ECH is an alias for [EraseCharacter].
  329. func ECH(n int) string {
  330. return EraseCharacter(n)
  331. }
  332. // CursorBackwardTab (CBT) returns a sequence for moving the cursor to the
  333. // previous tab stop n times.
  334. //
  335. // Default is 1.
  336. //
  337. // CSI n Z
  338. //
  339. // See: https://vt100.net/docs/vt510-rm/CBT.html
  340. func CursorBackwardTab(n int) string {
  341. var s string
  342. if n > 1 {
  343. s = strconv.Itoa(n)
  344. }
  345. return "\x1b[" + s + "Z"
  346. }
  347. // CBT is an alias for [CursorBackwardTab].
  348. func CBT(n int) string {
  349. return CursorBackwardTab(n)
  350. }
  351. // VerticalPositionAbsolute (VPA) returns a sequence for moving the cursor to
  352. // the given row.
  353. //
  354. // Default is 1.
  355. //
  356. // CSI n d
  357. //
  358. // See: https://vt100.net/docs/vt510-rm/VPA.html
  359. func VerticalPositionAbsolute(row int) string {
  360. var s string
  361. if row > 0 {
  362. s = strconv.Itoa(row)
  363. }
  364. return "\x1b[" + s + "d"
  365. }
  366. // VPA is an alias for [VerticalPositionAbsolute].
  367. func VPA(row int) string {
  368. return VerticalPositionAbsolute(row)
  369. }
  370. // VerticalPositionRelative (VPR) returns a sequence for moving the cursor down
  371. // n rows relative to the current position.
  372. //
  373. // Default is 1.
  374. //
  375. // CSI n e
  376. //
  377. // See: https://vt100.net/docs/vt510-rm/VPR.html
  378. func VerticalPositionRelative(n int) string {
  379. var s string
  380. if n > 1 {
  381. s = strconv.Itoa(n)
  382. }
  383. return "\x1b[" + s + "e"
  384. }
  385. // VPR is an alias for [VerticalPositionRelative].
  386. func VPR(n int) string {
  387. return VerticalPositionRelative(n)
  388. }
  389. // HorizontalVerticalPosition (HVP) returns a sequence for moving the cursor to
  390. // the given row and column.
  391. //
  392. // Default is 1,1.
  393. //
  394. // CSI n ; m f
  395. //
  396. // This has the same effect as [CursorPosition].
  397. //
  398. // See: https://vt100.net/docs/vt510-rm/HVP.html
  399. func HorizontalVerticalPosition(col, row int) string {
  400. var r, c string
  401. if row > 0 {
  402. r = strconv.Itoa(row)
  403. }
  404. if col > 0 {
  405. c = strconv.Itoa(col)
  406. }
  407. return "\x1b[" + r + ";" + c + "f"
  408. }
  409. // HVP is an alias for [HorizontalVerticalPosition].
  410. func HVP(col, row int) string {
  411. return HorizontalVerticalPosition(col, row)
  412. }
  413. // HorizontalVerticalHomePosition is a sequence for moving the cursor to the
  414. // upper left corner of the scrolling region. This is equivalent to
  415. // `HorizontalVerticalPosition(1, 1)`.
  416. const HorizontalVerticalHomePosition = "\x1b[f"
  417. // SaveCurrentCursorPosition (SCOSC) is a sequence for saving the current cursor
  418. // position for SCO console mode.
  419. //
  420. // CSI s
  421. //
  422. // This acts like [DECSC], except the page number where the cursor is located
  423. // is not saved.
  424. //
  425. // See: https://vt100.net/docs/vt510-rm/SCOSC.html
  426. const (
  427. SaveCurrentCursorPosition = "\x1b[s"
  428. SCOSC = SaveCurrentCursorPosition
  429. )
  430. // SaveCursorPosition (SCP or SCOSC) is a sequence for saving the cursor
  431. // position.
  432. //
  433. // CSI s
  434. //
  435. // This acts like Save, except the page number where the cursor is located is
  436. // not saved.
  437. //
  438. // See: https://vt100.net/docs/vt510-rm/SCOSC.html
  439. //
  440. // Deprecated: use [SaveCurrentCursorPosition] instead.
  441. const SaveCursorPosition = "\x1b[s"
  442. // RestoreCurrentCursorPosition (SCORC) is a sequence for restoring the current
  443. // cursor position for SCO console mode.
  444. //
  445. // CSI u
  446. //
  447. // This acts like [DECRC], except the page number where the cursor was saved is
  448. // not restored.
  449. //
  450. // See: https://vt100.net/docs/vt510-rm/SCORC.html
  451. const (
  452. RestoreCurrentCursorPosition = "\x1b[u"
  453. SCORC = RestoreCurrentCursorPosition
  454. )
  455. // RestoreCursorPosition (RCP or SCORC) is a sequence for restoring the cursor
  456. // position.
  457. //
  458. // CSI u
  459. //
  460. // This acts like Restore, except the cursor stays on the same page where the
  461. // cursor was saved.
  462. //
  463. // See: https://vt100.net/docs/vt510-rm/SCORC.html
  464. //
  465. // Deprecated: use [RestoreCurrentCursorPosition] instead.
  466. const RestoreCursorPosition = "\x1b[u"
  467. // SetCursorStyle (DECSCUSR) returns a sequence for changing the cursor style.
  468. //
  469. // Default is 1.
  470. //
  471. // CSI Ps SP q
  472. //
  473. // Where Ps is the cursor style:
  474. //
  475. // 0: Blinking block
  476. // 1: Blinking block (default)
  477. // 2: Steady block
  478. // 3: Blinking underline
  479. // 4: Steady underline
  480. // 5: Blinking bar (xterm)
  481. // 6: Steady bar (xterm)
  482. //
  483. // See: https://vt100.net/docs/vt510-rm/DECSCUSR.html
  484. // See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
  485. func SetCursorStyle(style int) string {
  486. if style < 0 {
  487. style = 0
  488. }
  489. return "\x1b[" + strconv.Itoa(style) + " q"
  490. }
  491. // DECSCUSR is an alias for [SetCursorStyle].
  492. func DECSCUSR(style int) string {
  493. return SetCursorStyle(style)
  494. }
  495. // SetPointerShape returns a sequence for changing the mouse pointer cursor
  496. // shape. Use "default" for the default pointer shape.
  497. //
  498. // OSC 22 ; Pt ST
  499. // OSC 22 ; Pt BEL
  500. //
  501. // Where Pt is the pointer shape name. The name can be anything that the
  502. // operating system can understand. Some common names are:
  503. //
  504. // - copy
  505. // - crosshair
  506. // - default
  507. // - ew-resize
  508. // - n-resize
  509. // - text
  510. // - wait
  511. //
  512. // See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
  513. func SetPointerShape(shape string) string {
  514. return "\x1b]22;" + shape + "\x07"
  515. }
  516. // ReverseIndex (RI) is an escape sequence for moving the cursor up one line in
  517. // the same column. If the cursor is at the top margin, the screen scrolls
  518. // down.
  519. //
  520. // This has the same effect as [RI].
  521. const ReverseIndex = "\x1bM"
  522. // HorizontalPositionAbsolute (HPA) returns a sequence for moving the cursor to
  523. // the given column. This has the same effect as [CUP].
  524. //
  525. // Default is 1.
  526. //
  527. // CSI n `
  528. //
  529. // See: https://vt100.net/docs/vt510-rm/HPA.html
  530. func HorizontalPositionAbsolute(col int) string {
  531. var s string
  532. if col > 0 {
  533. s = strconv.Itoa(col)
  534. }
  535. return "\x1b[" + s + "`"
  536. }
  537. // HPA is an alias for [HorizontalPositionAbsolute].
  538. func HPA(col int) string {
  539. return HorizontalPositionAbsolute(col)
  540. }
  541. // HorizontalPositionRelative (HPR) returns a sequence for moving the cursor
  542. // right n columns relative to the current position. This has the same effect
  543. // as [CUP].
  544. //
  545. // Default is 1.
  546. //
  547. // CSI n a
  548. //
  549. // See: https://vt100.net/docs/vt510-rm/HPR.html
  550. func HorizontalPositionRelative(n int) string {
  551. var s string
  552. if n > 0 {
  553. s = strconv.Itoa(n)
  554. }
  555. return "\x1b[" + s + "a"
  556. }
  557. // HPR is an alias for [HorizontalPositionRelative].
  558. func HPR(n int) string {
  559. return HorizontalPositionRelative(n)
  560. }
  561. // Index (IND) is an escape sequence for moving the cursor down one line in the
  562. // same column. If the cursor is at the bottom margin, the screen scrolls up.
  563. // This has the same effect as [IND].
  564. const Index = "\x1bD"