cursor.go 15 KB

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