control_code/csi/
mod.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15use std::str;
16use std::u32;
17use std::io::{self, Write};
18use std::iter::FromIterator;
19use nom;
20use smallvec::SmallVec;
21
22use Format;
23use util::number;
24
25pub const SIZE: usize = 8;
26
27#[derive(Eq, PartialEq, Clone, Debug)]
28pub enum CSI {
29	CursorBackTabulation(u32),
30	CursorHorizontalPosition(u32),
31	CursorForwardTabulation(u32),
32	CursorNextLine(u32),
33	CursorPreviousLine(u32),
34	CursorPositionReport { x: u32, y: u32 },
35	CursorTabulationControl(TabulationControl),
36	CursorBack(u32),
37	CursorDown(u32),
38	CursorForward(u32),
39	CursorPosition { x: u32, y: u32 },
40	CursorUp(u32),
41	CursorLineTabulation(u32),
42	DeviceAttributes(u32),
43	DefineAreaQualification(Qualification),
44	DeleteCharacter(u32),
45	DeleteLine(u32),
46	DeviceStatusReport(Report),
47	DimensionTextArea(u32, u32),
48	EraseArea(Erase),
49	EraseCharacter(u32),
50	EraseDisplay(Erase),
51	EraseField(Erase),
52	EraseLine(Erase),
53	FunctionKey(u32),
54	SelectFont(u32, u32),
55	GraphicCharacterCombination(Combination),
56	GraphicSizeModification { width: u32, height: u32 },
57	InsertCharacter(u32),
58	IdentifyDeviceControlString(Option<u32>),
59	IdentifyGraphicSubrepertoire(Option<u32>),
60	InsertLine(u32),
61	Justify(SmallVec<[Option<u32>; SIZE]>),
62	MediaCopy(Copy),
63	NextPage(u32),
64	Presentation(Expansion),
65	PageFormat(u32),
66	PrecedingPage(u32),
67	PagePosition(u32),
68	PageBack(u32),
69	PageForward(u32),
70	ParallelText(Parallel),
71	GraphicDisposition(SmallVec<[Disposition; SIZE]>),
72	RestoreCursor,
73	Repeat(u32),
74	Reset(SmallVec<[Mode; SIZE]>),
75	CharacterOrientation(u16),
76	SaveCursor,
77	CharacterSpacing(u32),
78	ScrollDown(u32),
79	Movement(Direction),
80	SelectGraphicalRendition(SmallVec<[::SGR::T; SIZE]>),
81	ScrollLeft(u32),
82	LineSpacing(u32),
83	Set(SmallVec<[Mode; SIZE]>),
84	ScrollRight(u32),
85	ReverseString(bool),
86	SizeUnit(Unit),
87	SpaceWidth(u32),
88	ScrollUp(u32),
89	TabulationClear(Tabulation),
90	CursorVerticalPosition(u32),
91
92	Unknown(u8, Option<u8>, SmallVec<[Option<u32>; SIZE]>),
93	Private(u8, Option<u8>, SmallVec<[Option<u32>; SIZE]>),
94}
95
96use self::CSI::*;
97
98#[inline]
99pub fn args<'a, T: 'a, I>(values: I) -> SmallVec<[Option<u32>; SIZE]>
100	where T: Clone + Into<Option<u32>>,
101	      I: IntoIterator<Item = &'a T>
102{
103	let mut result = SmallVec::new();
104
105	for value in values.into_iter() {
106		result.push(value.clone().into());
107	}
108
109	result
110}
111
112#[inline]
113pub fn values<'a, T: 'a, O, I>(values: I) -> SmallVec<[O; SIZE]>
114	where T: Clone + Into<O>,
115	      I: IntoIterator<Item = &'a T>
116{
117	let mut result = SmallVec::new();
118
119	for value in values.into_iter() {
120		result.push(value.clone().into());
121	}
122
123	result
124}
125
126impl Format for CSI {
127	fn fmt<W: Write>(&self, mut f: W) -> io::Result<()> {
128		macro_rules! write {
129			(entry $private:expr) => ({
130				try!(f.write_all(b"\x1B\x5B"));
131
132				if $private {
133					try!(f.write_all(b"?"));
134				}
135			});
136
137			(parameters $args:expr) => ({
138				let     iter = $args;
139				let mut iter = iter.peekable();
140
141				while let Some(value) = iter.next() {
142					if let Some(value) = value.clone() {
143						let value: u32 = value;
144						try!(f.write_all(value.to_string().as_bytes()));
145					}
146
147					if iter.peek().is_some() {
148						try!(f.write_all(&[b';']));
149					}
150				}
151			});
152
153			(identifier $id:expr, $modifier:expr) => ({
154				let id       = $id as u8;
155				let modifier = $modifier.map(|c| c as u8);
156
157				if let Some(modifier) = modifier {
158					try!(f.write_all(&[modifier]));
159				}
160
161				f.write_all(&[id])
162			});
163
164			($id:expr, [$($values:expr),*]) => ({
165				let params = [$(Some(Into::<u32>::into($values))),*];
166				write!($id, params.iter())
167			});
168
169			($id:expr, ![$($values:expr),*]) => ({
170				let params = [$($values),*];
171				write!($id, params.iter())
172			});
173
174			($id:expr, $iter:expr) => ({
175				write!(entry false);
176				write!(parameters $iter);
177
178				f.write_all($id.as_bytes())
179			});
180
181			($id:expr) => ({
182				write!(entry false);
183				f.write_all($id.as_bytes())
184			});
185		}
186
187		match *self {
188			CursorBackTabulation(n) =>
189				write!("Z", [n]),
190
191			CursorHorizontalPosition(n) =>
192				write!("G", [n + 1]),
193
194			CursorForwardTabulation(n) =>
195				write!("I", [n]),
196
197			CursorNextLine(n) =>
198				write!("E", [n]),
199
200			CursorPreviousLine(n) =>
201				write!("F", [n]),
202
203			CursorPositionReport { x, y } =>
204				write!("R", [y + 1, x + 1]),
205
206			CursorTabulationControl(value) =>
207				write!("W", [value]),
208
209			CursorBack(n) =>
210				write!("D", [n]),
211
212			CursorDown(n) =>
213				write!("B", [n]),
214
215			CursorForward(n) =>
216				write!("C", [n]),
217
218			CursorPosition { x, y } =>
219				write!("H", [y + 1, x + 1]),
220
221			CursorUp(n) =>
222				write!("A", [n]),
223
224			CursorLineTabulation(n) =>
225				write!("Y", [n]),
226
227			DeviceAttributes(n) =>
228				write!("c", [n]),
229
230			DefineAreaQualification(value) =>
231				write!("o", [value]),
232
233			DeleteCharacter(n) =>
234				write!("P", [n]),
235
236			DeleteLine(n) =>
237				write!("M", [n]),
238
239			DeviceStatusReport(value) =>
240				write!("n", [value]),
241
242			DimensionTextArea(w, h) =>
243				write!(" T", [w, h]),
244
245			EraseArea(value) =>
246				write!("O", [value]),
247
248			EraseCharacter(n) =>
249				write!("X", [n]),
250
251			EraseField(value) =>
252				write!("N", [value]),
253
254			EraseDisplay(value) =>
255				write!("J", [value]),
256
257			EraseLine(value) =>
258				write!("K", [value]),
259
260			FunctionKey(n) =>
261				write!(" W", [n]),
262
263			SelectFont(a, b) =>
264				write!(" D", [a, b]),
265
266			GraphicCharacterCombination(value) =>
267				write!(" _", [value]),
268
269			GraphicSizeModification { width, height } =>
270				write!(" B", [height, width]),
271
272			InsertCharacter(n) =>
273				write!("@", [n]),
274
275			IdentifyDeviceControlString(n) =>
276				write!(" O", ![n]),
277
278			IdentifyGraphicSubrepertoire(n) =>
279				write!(" M", ![n]),
280
281			InsertLine(n) =>
282				write!("L", [n]),
283
284			Justify(ref args) =>
285				write!(" F", args.iter()),
286
287			MediaCopy(value) =>
288				write!("i", [value]),
289
290			NextPage(n) =>
291				write!("U", [n]),
292
293			Presentation(value) =>
294				write!(" Z", [value]),
295
296			PageFormat(n) =>
297				write!(" J", [n]),
298
299			PrecedingPage(n) =>
300				write!("V", [n]),
301
302			PagePosition(n) =>
303				write!(" P", [n]),
304
305			PageBack(n) =>
306				write!(" R", [n]),
307
308			PageForward(n) =>
309				write!(" Q", [n]),
310
311			ParallelText(value) =>
312				write!("\\", [value]),
313
314			GraphicDisposition(ref dispositions) =>
315				write!(" H", dispositions.iter().map(|&d| Some(Into::<u32>::into(d)))),
316
317			RestoreCursor =>
318				write!("u"),
319
320			Repeat(n) =>
321				write!("b", [n]),
322
323			Reset(ref modes) =>
324				write!("l", modes.iter().map(|&m| Some(Into::<u32>::into(m)))),
325
326			CharacterOrientation(n) =>
327				write!(" e", [match n {
328					0   => 0u32,
329					45  => 1u32,
330					90  => 2u32,
331					135 => 3u32,
332					180 => 4u32,
333					225 => 5u32,
334					270 => 6u32,
335					315 => 7u32,
336					_   => unreachable!(),
337				}]),
338
339			SaveCursor =>
340				write!("s"),
341
342			CharacterSpacing(n) =>
343				write!(" b", [n]),
344
345			ScrollDown(n) =>
346				write!("T", [n]),
347
348			Movement(direction) =>
349				write!("^", [direction]),
350
351			SelectGraphicalRendition(ref attrs) =>
352				write!("m", attrs.iter().flat_map(|&a| Into::<SmallVec<_>>::into(a)).map(Some)),
353
354			ScrollLeft(n) =>
355				write!(" @", [n]),
356
357			LineSpacing(n) =>
358				write!(" h", [n]),
359
360			Set(ref modes) =>
361				write!("h", modes.iter().map(|&m| Into::<u32>::into(m)).map(Some)),
362
363			ScrollRight(n) =>
364				write!(" A", [n]),
365
366			ReverseString(false) =>
367				write!("[", [0u32]),
368
369			ReverseString(true) =>
370				write!("[", [1u32]),
371
372			SizeUnit(unit) =>
373				write!(" I", [unit]),
374
375			SpaceWidth(n) =>
376				write!(" [", [n]),
377
378			ScrollUp(n) =>
379				write!("S", [n]),
380
381			TabulationClear(value) =>
382				write!("g", [value]),
383
384			CursorVerticalPosition(n) =>
385				write!("d", [n + 1]),
386
387			Unknown(id, modifier, ref args) => {
388				write!(entry false);
389				write!(parameters args.iter());
390				write!(identifier id, modifier)
391			}
392
393			Private(id, modifier, ref args) => {
394				write!(entry true);
395				write!(parameters args.iter());
396				write!(identifier id, modifier)
397			}
398		}
399	}
400}
401
402mod erase;
403pub use self::erase::Erase;
404
405mod tabulation_control;
406pub use self::tabulation_control::TabulationControl;
407
408mod tabulation;
409pub use self::tabulation::Tabulation;
410
411mod qualification;
412pub use self::qualification::Qualification;
413
414mod combination;
415pub use self::combination::Combination;
416
417mod copy;
418pub use self::copy::Copy;
419
420mod expansion;
421pub use self::expansion::Expansion;
422
423mod parallel;
424pub use self::parallel::Parallel;
425
426mod disposition;
427pub use self::disposition::Disposition;
428
429mod mode;
430pub use self::mode::Mode;
431
432mod direction;
433pub use self::direction::Direction;
434
435mod unit;
436pub use self::unit::Unit;
437
438mod report;
439pub use self::report::Report;
440
441const DIGIT:    &'static [u8] = b"0123456789\x08\x09\x0A\x0B\x0D";
442const LETTER:   &'static [u8] = b"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
443const MODIFIER: &'static [u8] = b" !\"#$%&'()*+,-./";
444
445named!(pub parse<CSI>,
446	alt!(private | normal));
447
448named!(private<CSI>,
449	do_parse!(
450		char!('?')                        >>
451		args:     parameters              >>
452		modifier: opt!(one_of!(MODIFIER)) >>
453		id:       one_of!(LETTER)         >>
454
455		(Private(id as u8, modifier.map(|c| c as u8), args))));
456
457named!(normal<CSI>,
458	do_parse!(
459		args:     parameters >>
460		modifier: opt!(one_of!(MODIFIER)) >>
461		id:       one_of!(LETTER) >>
462		res:      expr_opt!(standard(id, modifier, args)) >>
463
464		(res)));
465
466named!(pub parameters<SmallVec<[Option<u32>; SIZE]> >,
467	many0!(SIZE, parameter));
468
469named!(pub parameter<Option<u32> >,
470	alt!(
471		char!(';') => { |_| None } |
472		do_parse!(
473			number: is_a!(DIGIT) >>
474			opt!(char!(';')) >>
475
476			(number)) => { |n| Some(number(n)) }));
477
478fn standard(id: char, modifier: Option<char>, args: SmallVec<[Option<u32>; SIZE]>) -> Option<CSI> {
479	match (id, modifier) {
480		('m', None) => SGR(&args),
481		('H', None) => CUP(&args),
482		('D', None) => CUB(&args),
483		('B', None) => CUD(&args),
484		('C', None) => CUF(&args),
485		('A', None) => CUU(&args),
486		('d', None) => VPA(&args),
487		('k', None) => VPB(&args),
488		('e', None) => VPR(&args),
489		('J', None) => ED(&args),
490		('K', None) => EL(&args),
491		('@', None) => ICH(&args),
492		('L', None) => IL(&args),
493		('N', None) => EF(&args),
494		('X', None) => ECH(&args),
495		('P', None) => DCH(&args),
496		('M', None) => DL(&args),
497
498		('Z',  None) => CBT(&args),
499		('G',  None) => CHA(&args),
500		('I',  None) => CHT(&args),
501		('E',  None) => CNL(&args),
502		('F',  None) => CPL(&args),
503		('R',  None) => CPR(&args),
504		('W',  None) => CTC(&args),
505		('Y',  None) => CVT(&args),
506		('c',  None) => DA(&args),
507		('o',  None) => DAQ(&args),
508		('n',  None) => DSR(&args),
509		('O',  None) => EA(&args),
510		('`',  None) => HPA(&args),
511		('j',  None) => HPB(&args),
512		('a',  None) => HPR(&args),
513		('f',  None) => HVP(&args),
514		('i',  None) => MC(&args),
515		('U',  None) => NP(&args),
516		('V',  None) => PP(&args),
517		('\\', None) => PTX(&args),
518		('u',  None) => RCP(&args),
519		('b',  None) => REP(&args),
520		('l',  None) => RM(&args),
521		('s',  None) => SCP(&args),
522		('T',  None) => SD(&args),
523		('^',  None) => SIMD(&args),
524		('h',  None) => SM(&args),
525		('[',  None) => SRS(&args),
526		('S',  None) => SU(&args),
527		('g',  None) => TBC(&args),
528
529		('T', Some(' ')) => DTA(&args),
530		('W', Some(' ')) => FNK(&args),
531		('D', Some(' ')) => FNT(&args),
532		('_', Some(' ')) => GCC(&args),
533		('B', Some(' ')) => GSM(&args),
534		('O', Some(' ')) => IDCS(&args),
535		('M', Some(' ')) => IGS(&args),
536		('F', Some(' ')) => JFY(&args),
537		('Z', Some(' ')) => PEC(&args),
538		('J', Some(' ')) => PFS(&args),
539		('P', Some(' ')) => PPA(&args),
540		('R', Some(' ')) => PPB(&args),
541		('Q', Some(' ')) => PPR(&args),
542		('H', Some(' ')) => QUAD(&args),
543		('e', Some(' ')) => SCO(&args),
544		('b', Some(' ')) => SCS(&args),
545		('@', Some(' ')) => SL(&args),
546		('h', Some(' ')) => SLS(&args),
547		('A', Some(' ')) => SR(&args),
548		('I', Some(' ')) => SSU(&args),
549		('[', Some(' ')) => SSW(&args),
550
551		_ =>
552			Some(Unknown(id as u8, modifier.map(|m| m as u8), args))
553	}
554}
555
556with_args!(CBT<1, args> -> CSI,
557	CursorBackTabulation(arg!(args[0] => 1)));
558
559with_args!(CHA<1, args> -> CSI,
560	CursorHorizontalPosition(arg!(args[0] => 1).saturating_sub(1)));
561
562with_args!(CHT<1, args> -> CSI,
563	CursorForwardTabulation(arg!(args[0] => 1)));
564
565with_args!(CNL<1, args> -> CSI,
566	CursorNextLine(arg!(args[0] => 1)));
567
568with_args!(CPL<1, args> -> CSI,
569	CursorPreviousLine(arg!(args[0] => 1)));
570
571with_args!(CPR<2, args> -> CSI,
572	CursorPositionReport {
573		y: arg!(args[0] => 1).saturating_sub(1),
574		x: arg!(args[1] => 1).saturating_sub(1)
575	});
576
577with_args!(CTC<1, args> -> CSI, ?
578	TabulationControl::parse(arg!(args[0] => 0)).map(CursorTabulationControl));
579
580with_args!(CUB<1, args> -> CSI,
581	CursorBack(arg!(args[0] => 1)));
582
583with_args!(CUD<1, args> -> CSI,
584	CursorDown(arg!(args[0] => 1)));
585
586with_args!(CUF<1, args> -> CSI,
587	CursorForward(arg!(args[0] => 1)));
588
589with_args!(CUP<2, args> -> CSI,
590	CursorPosition {
591		y: arg!(args[0] => 1).saturating_sub(1),
592		x: arg!(args[1] => 1).saturating_sub(1)
593	});
594
595with_args!(CUU<1, args> -> CSI,
596	CursorUp(arg!(args[0] => 1)));
597
598with_args!(CVT<1, args> -> CSI,
599	CursorLineTabulation(arg!(args[0] => 1)));
600
601with_args!(DA<1, args> -> CSI,
602	DeviceAttributes(arg!(args[0] => 0)));
603
604with_args!(DAQ<1, args> -> CSI, ?
605	Qualification::parse(arg!(args[0] => 0)).map(DefineAreaQualification));
606
607with_args!(DCH<1, args> -> CSI,
608	DeleteCharacter(arg!(args[0] => 1)));
609
610with_args!(DL<1, args> -> CSI,
611	DeleteLine(arg!(args[0] => 1)));
612
613with_args!(DSR<1, args> -> CSI, ?
614	Report::parse(arg!(args[0] => 0)).map(DeviceStatusReport));
615
616with_args!(DTA<2, args> -> CSI,
617	DimensionTextArea(arg!(args[0] => 0), arg!(args[1] => 0)));
618
619with_args!(EA<1, args> -> CSI, ?
620	Erase::parse(arg!(args[0] => 0)).map(EraseArea));
621
622with_args!(ECH<1, args> -> CSI,
623	EraseCharacter(arg!(args[0] => 1)));
624
625with_args!(ED<1, args> -> CSI, ?
626	Erase::parse(arg!(args[0] => 0)).map(EraseDisplay));
627
628with_args!(EF<1, args> -> CSI, ?
629	Erase::parse(arg!(args[0] => 0)).map(EraseField));
630
631with_args!(EL<1, args> -> CSI, ?
632	Erase::parse(arg!(args[0] => 0)).map(EraseLine));
633
634with_args!(FNK<1, args> -> CSI,
635	FunctionKey(arg!(args[0] => 0)));
636
637with_args!(FNT<2, args> -> CSI,
638	SelectFont(arg!(args[0] => 0), arg!(args[1] => 0)));
639
640with_args!(GCC<1, args> -> CSI, ?
641	Combination::parse(arg!(args[0] => 0)).map(GraphicCharacterCombination));
642
643with_args!(GSM<2, args> -> CSI,
644	GraphicSizeModification { height: arg!(args[0] => 100), width: arg!(args[1] => 100) });
645
646with_args!(HPA<1, args> -> CSI,
647	CursorHorizontalPosition(arg!(args[0] => 1).saturating_sub(1)));
648
649with_args!(HPB<1, args> -> CSI,
650	CursorBack(arg!(args[0] => 1)));
651
652with_args!(HPR<1, args> -> CSI,
653	CursorForward(arg!(args[0] => 1)));
654
655with_args!(HVP<2, args> -> CSI,
656	CursorPosition {
657		y: arg!(args[0] => 1).saturating_sub(1),
658		x: arg!(args[1] => 1).saturating_sub(1),
659	});
660
661with_args!(ICH<1, args> -> CSI,
662	InsertCharacter(arg!(args[0] => 1)));
663
664with_args!(IDCS<1, args> -> CSI,
665	IdentifyDeviceControlString(arg!(args[0])));
666
667with_args!(IGS<1, args> -> CSI,
668	IdentifyGraphicSubrepertoire(arg!(args[0])));
669
670with_args!(IL<1, args> -> CSI,
671	InsertLine(arg!(args[0] => 1)));
672
673with_args!(JFY<args> -> CSI,
674	Justify(SmallVec::from_iter(args.iter().cloned())));
675
676with_args!(MC<1, args> -> CSI, ?
677	Copy::parse(arg!(args[0] => 0)).map(MediaCopy));
678
679with_args!(NP<1, args> -> CSI,
680	NextPage(arg!(args[0] => 1)));
681
682with_args!(PEC<1, args> -> CSI, ?
683	Expansion::parse(arg!(args[0] => 0)).map(Presentation));
684
685with_args!(PFS<1, args> -> CSI,
686	PageFormat(arg!(args[0] => 0)));
687
688with_args!(PP<1, args> -> CSI,
689	PrecedingPage(arg!(args[0] => 1)));
690
691with_args!(PPA<1, args> -> CSI,
692	PagePosition(arg!(args[0] => 1)));
693
694with_args!(PPB<1, args> -> CSI,
695	PageBack(arg!(args[0] => 1)));
696
697with_args!(PPR<1, args> -> CSI,
698	PageForward(arg!(args[0] => 1)));
699
700with_args!(PTX<1, args> -> CSI, ?
701	Parallel::parse(arg!(args[0] => 0)).map(ParallelText));
702
703with_args!(QUAD<args> -> CSI, ?
704	args.iter().map(|d| d.unwrap_or(0))
705		.map(Disposition::parse)
706		.collect::<Result<SmallVec<_>, _>>()
707		.map(GraphicDisposition));
708
709with_args!(RCP -> CSI,
710	RestoreCursor);
711
712with_args!(REP<1, args> -> CSI,
713	Repeat(arg!(args[0] => 1)));
714
715with_args!(RM<args> -> CSI, ?
716	args.iter().map(|d| d.unwrap_or(0))
717		.map(Mode::parse)
718		.collect::<Result<SmallVec<_>, _>>()
719		.map(Reset));
720
721with_args!(SCO<1, args> -> CSI, ?
722	match arg!(args[0] => 0) {
723		0 => Ok(CharacterOrientation(0)),
724		1 => Ok(CharacterOrientation(45)),
725		2 => Ok(CharacterOrientation(90)),
726		3 => Ok(CharacterOrientation(135)),
727		4 => Ok(CharacterOrientation(180)),
728		5 => Ok(CharacterOrientation(225)),
729		6 => Ok(CharacterOrientation(270)),
730		7 => Ok(CharacterOrientation(315)),
731		_ => Err(nom::ErrorKind::Custom(9002)),
732	});
733
734with_args!(SCP -> CSI,
735	SaveCursor);
736
737with_args!(SCS<1, args> -> CSI,
738	CharacterSpacing(arg!(args[0] => 1)));
739
740with_args!(SD<1, args> -> CSI,
741	ScrollDown(arg!(args[0] => 1)));
742
743with_args!(SIMD<1, args> -> CSI, ?
744	Direction::parse(arg!(args[0] => 0)).map(Movement));
745
746with_args!(SGR<args> -> CSI, ?
747	::SGR::parse(args).map(|v| SelectGraphicalRendition(v)));
748
749with_args!(SL<1, args> -> CSI,
750	ScrollLeft(arg!(args[0] => 1)));
751
752with_args!(SLS<1, args> -> CSI,
753	LineSpacing(arg!(args[0] => 1)));
754
755with_args!(SM<args> -> CSI, ?
756	args.iter().map(|d| d.unwrap_or(0))
757		.map(Mode::parse)
758		.collect::<Result<SmallVec<_>, _>>()
759		.map(Set));
760
761with_args!(SR<1, args> -> CSI,
762	ScrollRight(arg!(args[0] => 1)));
763
764with_args!(SRS<1, args> -> CSI, ?
765	match arg!(args[0] => 0) {
766		0 => Ok(ReverseString(false)),
767		1 => Ok(ReverseString(true)),
768		_ => Err(nom::ErrorKind::Custom(9002)),
769	});
770
771with_args!(SSU<1, args> -> CSI, ?
772	Unit::parse(arg!(args[0] => 0)).map(SizeUnit));
773
774with_args!(SSW<1, args> -> CSI,
775	SpaceWidth(arg!(args[0] => 1)));
776
777with_args!(SU<1, args> -> CSI,
778	ScrollUp(arg!(args[0] => 1)));
779
780with_args!(TBC<1, args> -> CSI, ?
781	Tabulation::parse(arg!(args[0] => 0)).map(TabulationClear));
782
783with_args!(VPA<1, args> -> CSI,
784	CursorVerticalPosition(arg!(args[0] => 1).saturating_sub(1)));
785
786with_args!(VPB<1, args> -> CSI,
787	CursorUp(arg!(args[0] => 1)));
788
789with_args!(VPR<1, args> -> CSI,
790	CursorDown(arg!(args[0] => 1)));
791
792pub mod shim {
793	pub use super::CSI as T;
794	pub use super::CSI::*;
795	pub use super::{args, values, parse, parameters, parameter, SIZE};
796	pub use super::{Erase, TabulationControl, Tabulation, Qualification, Combination, Copy};
797	pub use super::{Expansion, Parallel, Disposition, Mode, Direction, Unit, Report};
798}
799
800#[cfg(test)]
801mod test {
802	mod parse {
803		use {Control, C1, CSI, parse};
804
805		macro_rules! test {
806			($string:expr => $item:expr) => (
807				assert_eq!(Control::C1(C1::ControlSequence($item)),
808					parse($string).unwrap().1);
809			);
810		}
811
812		#[test]
813		fn cbt() {
814			test!(b"\x1B[Z" =>
815				CSI::CursorBackTabulation(1));
816
817			test!(b"\x1B[23Z" =>
818				CSI::CursorBackTabulation(23));
819		}
820
821		#[test]
822		fn cha() {
823			test!(b"\x1B[G" =>
824				CSI::CursorHorizontalPosition(0));
825
826			test!(b"\x1B[43G" =>
827				CSI::CursorHorizontalPosition(42));
828		}
829
830		#[test]
831		fn cht() {
832			test!(b"\x1B[I" =>
833				CSI::CursorForwardTabulation(1));
834
835			test!(b"\x1B[23I" =>
836				CSI::CursorForwardTabulation(23));
837		}
838
839		#[test]
840		fn cnl() {
841			test!(b"\x1B[E" =>
842				CSI::CursorNextLine(1));
843
844			test!(b"\x1B[12E" =>
845				CSI::CursorNextLine(12));
846		}
847
848		#[test]
849		fn cpl() {
850			test!(b"\x1B[F" =>
851				CSI::CursorPreviousLine(1));
852
853			test!(b"\x1B[43F" =>
854				CSI::CursorPreviousLine(43));
855		}
856
857		#[test]
858		fn cpr() {
859			test!(b"\x1B[R" =>
860				CSI::CursorPositionReport { x: 0, y: 0 });
861
862			test!(b"\x1B[2R" =>
863				CSI::CursorPositionReport { x: 0, y: 1 });
864
865			test!(b"\x1B[;2R" =>
866				CSI::CursorPositionReport { x: 1, y: 0 });
867
868			test!(b"\x1B[2;2R" =>
869				CSI::CursorPositionReport { x: 1, y: 1 });
870		}
871
872		#[test]
873		fn ctc() {
874			test!(b"\x1B[W" =>
875				CSI::CursorTabulationControl(CSI::TabulationControl::Character));
876
877			test!(b"\x1B[0W" =>
878				CSI::CursorTabulationControl(CSI::TabulationControl::Character));
879
880			test!(b"\x1B[1W" =>
881				CSI::CursorTabulationControl(CSI::TabulationControl::Line));
882
883			test!(b"\x1B[2W" =>
884				CSI::CursorTabulationControl(CSI::TabulationControl::ClearCharacter));
885
886			test!(b"\x1B[3W" =>
887				CSI::CursorTabulationControl(CSI::TabulationControl::ClearLine));
888
889			test!(b"\x1B[4W" =>
890				CSI::CursorTabulationControl(CSI::TabulationControl::ClearCharacters));
891
892			test!(b"\x1B[5W" =>
893				CSI::CursorTabulationControl(CSI::TabulationControl::ClearAllCharacters));
894
895			test!(b"\x1B[6W" =>
896				CSI::CursorTabulationControl(CSI::TabulationControl::ClearAllLines));
897		}
898
899		#[test]
900		fn cub() {
901			test!(b"\x1B[D" =>
902				CSI::CursorBack(1));
903
904			test!(b"\x1B[37D" =>
905				CSI::CursorBack(37));
906		}
907
908		#[test]
909		fn cud() {
910			test!(b"\x1B[B" =>
911				CSI::CursorDown(1));
912
913			test!(b"\x1B[42B" =>
914				CSI::CursorDown(42));
915		}
916
917		#[test]
918		fn cuf() {
919			test!(b"\x1B[C" =>
920				CSI::CursorForward(1));
921
922			test!(b"\x1B[13C" =>
923				CSI::CursorForward(13));
924		}
925
926		#[test]
927		fn cup() {
928			test!(b"\x1B[H" =>
929				CSI::CursorPosition { x: 0, y: 0 });
930
931			test!(b"\x1B[2;3H" =>
932				CSI::CursorPosition { x: 2, y: 1 });
933
934			test!(b"\x1B[;3H" =>
935				CSI::CursorPosition{ x: 2, y: 0 });
936
937			test!(b"\x1B[2;H" =>
938				CSI::CursorPosition { x: 0, y: 1 });
939
940			test!(b"\x1B[;H" =>
941				CSI::CursorPosition { x: 0, y: 0 });
942		}
943
944		#[test]
945		fn cuu() {
946			test!(b"\x1B[A" =>
947				CSI::CursorUp(1));
948
949			test!(b"\x1B[23A" =>
950				CSI::CursorUp(23));
951		}
952
953		#[test]
954		fn cvt() {
955			test!(b"\x1B[Y" =>
956				CSI::CursorLineTabulation(1));
957
958			test!(b"\x1B[23Y" =>
959				CSI::CursorLineTabulation(23));
960		}
961
962		#[test]
963		fn da() {
964			test!(b"\x1B[c" =>
965				CSI::DeviceAttributes(0));
966
967			test!(b"\x1B[23c" =>
968				CSI::DeviceAttributes(23));
969		}
970
971		#[test]
972		fn daq() {
973			test!(b"\x1B[o" =>
974				CSI::DefineAreaQualification(CSI::Qualification::UnprotectedUnguarded));
975
976			test!(b"\x1B[0o" =>
977				CSI::DefineAreaQualification(CSI::Qualification::UnprotectedUnguarded));
978
979			test!(b"\x1B[1o" =>
980				CSI::DefineAreaQualification(CSI::Qualification::ProtectedGuarded));
981
982			test!(b"\x1B[2o" =>
983				CSI::DefineAreaQualification(CSI::Qualification::GraphicCharacterInput));
984
985			test!(b"\x1B[3o" =>
986				CSI::DefineAreaQualification(CSI::Qualification::NumericInput));
987
988			test!(b"\x1B[4o" =>
989				CSI::DefineAreaQualification(CSI::Qualification::AlphabeticInput));
990
991			test!(b"\x1B[5o" =>
992				CSI::DefineAreaQualification(CSI::Qualification::AlignLast));
993
994			test!(b"\x1B[6o" =>
995				CSI::DefineAreaQualification(CSI::Qualification::ZeroFill));
996
997			test!(b"\x1B[7o" =>
998				CSI::DefineAreaQualification(CSI::Qualification::FieldStart));
999
1000			test!(b"\x1B[8o" =>
1001				CSI::DefineAreaQualification(CSI::Qualification::ProtectedUnguarded));
1002
1003			test!(b"\x1B[9o" =>
1004				CSI::DefineAreaQualification(CSI::Qualification::SpaceFill));
1005
1006			test!(b"\x1B[10o" =>
1007				CSI::DefineAreaQualification(CSI::Qualification::AlignFirst));
1008
1009			test!(b"\x1B[11o" =>
1010				CSI::DefineAreaQualification(CSI::Qualification::Reverse));
1011		}
1012
1013		#[test]
1014		fn dch() {
1015			test!(b"\x1B[P" =>
1016				CSI::DeleteCharacter(1));
1017
1018			test!(b"\x1B[8P" =>
1019				CSI::DeleteCharacter(8));
1020		}
1021
1022		#[test]
1023		fn dl() {
1024			test!(b"\x1B[M" =>
1025				CSI::DeleteLine(1));
1026
1027			test!(b"\x1B[8M" =>
1028				CSI::DeleteLine(8));
1029		}
1030
1031		#[test]
1032		fn dsr() {
1033			test!(b"\x1B[6n" =>
1034				CSI::DeviceStatusReport(CSI::Report::CursorPosition));
1035		}
1036
1037		#[test]
1038		fn dta() {
1039			test!(b"\x1B[ T" =>
1040				CSI::DimensionTextArea(0, 0));
1041
1042			test!(b"\x1B[1 T" =>
1043				CSI::DimensionTextArea(1, 0));
1044
1045			test!(b"\x1B[;1 T" =>
1046				CSI::DimensionTextArea(0, 1));
1047
1048			test!(b"\x1B[1;1 T" =>
1049				CSI::DimensionTextArea(1, 1));
1050		}
1051
1052		#[test]
1053		fn ea() {
1054			test!(b"\x1B[O" =>
1055				CSI::EraseArea(CSI::Erase::ToEnd));
1056
1057			test!(b"\x1B[0O" =>
1058				CSI::EraseArea(CSI::Erase::ToEnd));
1059
1060			test!(b"\x1B[1O" =>
1061				CSI::EraseArea(CSI::Erase::ToStart));
1062
1063			test!(b"\x1B[2O" =>
1064				CSI::EraseArea(CSI::Erase::All));
1065		}
1066
1067		#[test]
1068		fn ech() {
1069			test!(b"\x1B[X" =>
1070				CSI::EraseCharacter(1));
1071
1072			test!(b"\x1B[8X" =>
1073				CSI::EraseCharacter(8));
1074		}
1075
1076		#[test]
1077		fn ed() {
1078			test!(b"\x1B[J" =>
1079				CSI::EraseDisplay(CSI::Erase::ToEnd));
1080
1081			test!(b"\x1B[0J" =>
1082				CSI::EraseDisplay(CSI::Erase::ToEnd));
1083
1084			test!(b"\x1B[1J" =>
1085				CSI::EraseDisplay(CSI::Erase::ToStart));
1086
1087			test!(b"\x1B[2J" =>
1088				CSI::EraseDisplay(CSI::Erase::All));
1089		}
1090
1091		#[test]
1092		fn ef() {
1093			test!(b"\x1B[N" =>
1094				CSI::EraseField(CSI::Erase::ToEnd));
1095
1096			test!(b"\x1B[0N" =>
1097				CSI::EraseField(CSI::Erase::ToEnd));
1098
1099			test!(b"\x1B[1N" =>
1100				CSI::EraseField(CSI::Erase::ToStart));
1101
1102			test!(b"\x1B[2N" =>
1103				CSI::EraseField(CSI::Erase::All));
1104		}
1105
1106		#[test]
1107		fn el() {
1108			test!(b"\x1B[K" =>
1109				CSI::EraseLine(CSI::Erase::ToEnd));
1110
1111			test!(b"\x1B[0K" =>
1112				CSI::EraseLine(CSI::Erase::ToEnd));
1113
1114			test!(b"\x1B[1K" =>
1115				CSI::EraseLine(CSI::Erase::ToStart));
1116
1117			test!(b"\x1B[2K" =>
1118				CSI::EraseLine(CSI::Erase::All));
1119		}
1120
1121		#[test]
1122		fn fnk() {
1123			test!(b"\x1B[ W" =>
1124				CSI::FunctionKey(0));
1125
1126			test!(b"\x1B[13 W" =>
1127				CSI::FunctionKey(13));
1128		}
1129
1130		#[test]
1131		fn fnt() {
1132			test!(b"\x1B[ D" =>
1133				CSI::SelectFont(0, 0));
1134
1135			test!(b"\x1B[13 D" =>
1136				CSI::SelectFont(13, 0));
1137
1138			test!(b"\x1B[;13 D" =>
1139				CSI::SelectFont(0, 13));
1140
1141			test!(b"\x1B[13;13 D" =>
1142				CSI::SelectFont(13, 13));
1143		}
1144
1145		#[test]
1146		fn gcc() {
1147			test!(b"\x1B[ _" =>
1148				CSI::GraphicCharacterCombination(CSI::Combination::Next));
1149
1150			test!(b"\x1B[0 _" =>
1151				CSI::GraphicCharacterCombination(CSI::Combination::Next));
1152
1153			test!(b"\x1B[1 _" =>
1154				CSI::GraphicCharacterCombination(CSI::Combination::Start));
1155
1156			test!(b"\x1B[2 _" =>
1157				CSI::GraphicCharacterCombination(CSI::Combination::End));
1158		}
1159
1160		#[test]
1161		fn gsm() {
1162			test!(b"\x1B[ B" =>
1163				CSI::GraphicSizeModification { width: 100, height: 100 });
1164
1165			test!(b"\x1B[13 B" =>
1166				CSI::GraphicSizeModification { width: 100, height: 13 });
1167
1168			test!(b"\x1B[;13 B" =>
1169				CSI::GraphicSizeModification { width: 13, height: 100 });
1170
1171			test!(b"\x1B[13;13 B" =>
1172				CSI::GraphicSizeModification { width: 13, height: 13 });
1173		}
1174
1175		#[test]
1176		fn hpa() {
1177			test!(b"\x1B[`" =>
1178				CSI::CursorHorizontalPosition(0));
1179
1180			test!(b"\x1B[2`" =>
1181				CSI::CursorHorizontalPosition(1));
1182		}
1183
1184		#[test]
1185		fn hpb() {
1186			test!(b"\x1B[j" =>
1187				CSI::CursorBack(1));
1188
1189			test!(b"\x1B[2j" =>
1190				CSI::CursorBack(2));
1191		}
1192
1193		#[test]
1194		fn hpr() {
1195			test!(b"\x1B[a" =>
1196				CSI::CursorForward(1));
1197
1198			test!(b"\x1B[2a" =>
1199				CSI::CursorForward(2));
1200		}
1201
1202		#[test]
1203		fn hvp() {
1204			test!(b"\x1B[f" =>
1205				CSI::CursorPosition { x: 0, y: 0 });
1206
1207			test!(b"\x1B[13f" =>
1208				CSI::CursorPosition { x: 0, y: 12 });
1209
1210			test!(b"\x1B[;13f" =>
1211				CSI::CursorPosition { x: 12, y: 0 });
1212
1213			test!(b"\x1B[13;13f" =>
1214				CSI::CursorPosition { x: 12, y: 12 });
1215		}
1216
1217		#[test]
1218		fn ich() {
1219			test!(b"\x1B[@" =>
1220				CSI::InsertCharacter(1));
1221
1222			test!(b"\x1B[23@" =>
1223				CSI::InsertCharacter(23));
1224		}
1225
1226		#[test]
1227		fn idcs() {
1228			test!(b"\x1B[ O" =>
1229				CSI::IdentifyDeviceControlString(None));
1230
1231			test!(b"\x1B[1 O" =>
1232				CSI::IdentifyDeviceControlString(Some(1)));
1233		}
1234
1235		#[test]
1236		fn igs() {
1237			test!(b"\x1B[ M" =>
1238				CSI::IdentifyGraphicSubrepertoire(None));
1239
1240			test!(b"\x1B[1 M" =>
1241				CSI::IdentifyGraphicSubrepertoire(Some(1)));
1242		}
1243
1244		#[test]
1245		fn il() {
1246			test!(b"\x1B[L" =>
1247				CSI::InsertLine(1));
1248
1249			test!(b"\x1B[2L" =>
1250				CSI::InsertLine(2));
1251		}
1252
1253		#[test]
1254		fn jfy() {
1255			test!(b"\x1B[1;2 F" =>
1256				CSI::Justify(small_vec![Some(1), Some(2)]));
1257		}
1258
1259		#[test]
1260		fn mc() {
1261			test!(b"\x1B[i" =>
1262				CSI::MediaCopy(CSI::Copy::ToPrimary));
1263
1264			test!(b"\x1B[0i" =>
1265				CSI::MediaCopy(CSI::Copy::ToPrimary));
1266
1267			test!(b"\x1B[1i" =>
1268				CSI::MediaCopy(CSI::Copy::FromPrimary));
1269
1270			test!(b"\x1B[2i" =>
1271				CSI::MediaCopy(CSI::Copy::ToSecondary));
1272
1273			test!(b"\x1B[3i" =>
1274				CSI::MediaCopy(CSI::Copy::FromSecondary));
1275
1276			test!(b"\x1B[4i" =>
1277				CSI::MediaCopy(CSI::Copy::StopPrimary));
1278
1279			test!(b"\x1B[5i" =>
1280				CSI::MediaCopy(CSI::Copy::StartPrimary));
1281
1282			test!(b"\x1B[6i" =>
1283				CSI::MediaCopy(CSI::Copy::StopSecondary));
1284
1285			test!(b"\x1B[7i" =>
1286				CSI::MediaCopy(CSI::Copy::StartSecondary));
1287		}
1288
1289		#[test]
1290		fn np() {
1291			test!(b"\x1B[U" =>
1292				CSI::NextPage(1));
1293
1294			test!(b"\x1B[2U" =>
1295				CSI::NextPage(2));
1296		}
1297
1298		#[test]
1299		fn pec() {
1300			test!(b"\x1B[ Z" =>
1301				CSI::Presentation(CSI::Expansion::Normal));
1302
1303			test!(b"\x1B[0 Z" =>
1304				CSI::Presentation(CSI::Expansion::Normal));
1305
1306			test!(b"\x1B[1 Z" =>
1307				CSI::Presentation(CSI::Expansion::Expanded));
1308
1309			test!(b"\x1B[2 Z" =>
1310				CSI::Presentation(CSI::Expansion::Condensed));
1311		}
1312
1313		#[test]
1314		fn pfs() {
1315			test!(b"\x1B[ J" =>
1316				CSI::PageFormat(0));
1317
1318			test!(b"\x1B[3 J" =>
1319				CSI::PageFormat(3));
1320		}
1321
1322		#[test]
1323		fn pp() {
1324			test!(b"\x1B[V" =>
1325				CSI::PrecedingPage(1));
1326
1327			test!(b"\x1B[3V" =>
1328				CSI::PrecedingPage(3));
1329		}
1330
1331		#[test]
1332		fn ppa() {
1333			test!(b"\x1B[ P" =>
1334				CSI::PagePosition(1));
1335
1336			test!(b"\x1B[3 P" =>
1337				CSI::PagePosition(3));
1338		}
1339
1340		#[test]
1341		fn ppb() {
1342			test!(b"\x1B[ R" =>
1343				CSI::PageBack(1));
1344
1345			test!(b"\x1B[3 R" =>
1346				CSI::PageBack(3));
1347		}
1348
1349		#[test]
1350		fn ppr() {
1351			test!(b"\x1B[ Q" =>
1352				CSI::PageForward(1));
1353
1354			test!(b"\x1B[3 Q" =>
1355				CSI::PageForward(3));
1356		}
1357
1358		#[test]
1359		fn ptx() {
1360			test!(b"\x1B[\\" =>
1361				CSI::ParallelText(CSI::Parallel::End));
1362
1363			test!(b"\x1B[0\\" =>
1364				CSI::ParallelText(CSI::Parallel::End));
1365
1366			test!(b"\x1B[1\\" =>
1367				CSI::ParallelText(CSI::Parallel::Start));
1368
1369			test!(b"\x1B[2\\" =>
1370				CSI::ParallelText(CSI::Parallel::StartSupplementary));
1371
1372			test!(b"\x1B[3\\" =>
1373				CSI::ParallelText(CSI::Parallel::StartPhoneticJapanese));
1374
1375			test!(b"\x1B[4\\" =>
1376				CSI::ParallelText(CSI::Parallel::StartPhoneticChinese));
1377
1378			test!(b"\x1B[5\\" =>
1379				CSI::ParallelText(CSI::Parallel::StopPhonetic));
1380		}
1381
1382		#[test]
1383		fn rcp() {
1384			test!(b"\x1B[u" =>
1385				CSI::RestoreCursor);
1386		}
1387
1388		#[test]
1389		fn rep() {
1390			test!(b"\x1B[b" =>
1391				CSI::Repeat(1));
1392
1393			test!(b"\x1B[10b" =>
1394				CSI::Repeat(10));
1395		}
1396
1397		#[test]
1398		fn rm() {
1399			test!(b"\x1B[1l" =>
1400				CSI::Reset(small_vec![CSI::Mode::GuardedAreaTransfer]));
1401
1402			test!(b"\x1B[2l" =>
1403				CSI::Reset(small_vec![CSI::Mode::KeyboardLock]));
1404
1405			test!(b"\x1B[3l" =>
1406				CSI::Reset(small_vec![CSI::Mode::ControlRepresentation]));
1407
1408			test!(b"\x1B[4l" =>
1409				CSI::Reset(small_vec![CSI::Mode::InsertionReplacement]));
1410
1411			test!(b"\x1B[5l" =>
1412				CSI::Reset(small_vec![CSI::Mode::StatusReportTransfer]));
1413
1414			test!(b"\x1B[6l" =>
1415				CSI::Reset(small_vec![CSI::Mode::Erasure]));
1416
1417			test!(b"\x1B[7l" =>
1418				CSI::Reset(small_vec![CSI::Mode::LineEditing]));
1419
1420			test!(b"\x1B[8l" =>
1421				CSI::Reset(small_vec![CSI::Mode::BidirectionalSupport]));
1422
1423			test!(b"\x1B[9l" =>
1424				CSI::Reset(small_vec![CSI::Mode::DeviceComponentSelect]));
1425
1426			test!(b"\x1B[10l" =>
1427				CSI::Reset(small_vec![CSI::Mode::CharacterEditing]));
1428
1429			test!(b"\x1B[11l" =>
1430				CSI::Reset(small_vec![CSI::Mode::PositioningUnit]));
1431
1432			test!(b"\x1B[12l" =>
1433				CSI::Reset(small_vec![CSI::Mode::SendReceive]));
1434
1435			test!(b"\x1B[13l" =>
1436				CSI::Reset(small_vec![CSI::Mode::FormatEffectorAction]));
1437
1438			test!(b"\x1B[14l" =>
1439				CSI::Reset(small_vec![CSI::Mode::FormatEffectorTransfer]));
1440
1441			test!(b"\x1B[15l" =>
1442				CSI::Reset(small_vec![CSI::Mode::MultipleAreaTransfer]));
1443
1444			test!(b"\x1B[16l" =>
1445				CSI::Reset(small_vec![CSI::Mode::TransferTermination]));
1446
1447			test!(b"\x1B[17l" =>
1448				CSI::Reset(small_vec![CSI::Mode::SelectedAreaTransfer]));
1449
1450			test!(b"\x1B[18l" =>
1451				CSI::Reset(small_vec![CSI::Mode::TabulationStop]));
1452
1453			test!(b"\x1B[21l" =>
1454				CSI::Reset(small_vec![CSI::Mode::GraphicRenditionCombination]));
1455
1456			test!(b"\x1B[22l" =>
1457				CSI::Reset(small_vec![CSI::Mode::ZeroDefault]));
1458		}
1459
1460		#[test]
1461		fn sco() {
1462			test!(b"\x1B[ e" =>
1463				CSI::CharacterOrientation(0));
1464
1465			test!(b"\x1B[0 e" =>
1466				CSI::CharacterOrientation(0));
1467
1468			test!(b"\x1B[1 e" =>
1469				CSI::CharacterOrientation(45));
1470
1471			test!(b"\x1B[2 e" =>
1472				CSI::CharacterOrientation(90));
1473
1474			test!(b"\x1B[3 e" =>
1475				CSI::CharacterOrientation(135));
1476
1477			test!(b"\x1B[4 e" =>
1478				CSI::CharacterOrientation(180));
1479
1480			test!(b"\x1B[5 e" =>
1481				CSI::CharacterOrientation(225));
1482
1483			test!(b"\x1B[6 e" =>
1484				CSI::CharacterOrientation(270));
1485
1486			test!(b"\x1B[7 e" =>
1487				CSI::CharacterOrientation(315));
1488		}
1489
1490		#[test]
1491		fn scp() {
1492			test!(b"\x1B[s" =>
1493				CSI::SaveCursor);
1494		}
1495
1496		#[test]
1497		fn scs() {
1498			test!(b"\x1B[ b" =>
1499				CSI::CharacterSpacing(1));
1500
1501			test!(b"\x1B[23 b" =>
1502				CSI::CharacterSpacing(23));
1503		}
1504
1505		#[test]
1506		fn sd() {
1507			test!(b"\x1B[T" =>
1508				CSI::ScrollDown(1));
1509
1510			test!(b"\x1B[73T" =>
1511				CSI::ScrollDown(73));
1512		}
1513
1514		#[test]
1515		fn simd() {
1516			test!(b"\x1B[^" =>
1517				CSI::Movement(CSI::Direction::Forward));
1518
1519			test!(b"\x1B[0^" =>
1520				CSI::Movement(CSI::Direction::Forward));
1521
1522			test!(b"\x1B[1^" =>
1523				CSI::Movement(CSI::Direction::Backward));
1524		}
1525
1526		#[test]
1527		fn sl() {
1528			test!(b"\x1B[ @" =>
1529				CSI::ScrollLeft(1));
1530
1531			test!(b"\x1B[12 @" =>
1532				CSI::ScrollLeft(12));
1533		}
1534
1535		#[test]
1536		fn sls() {
1537			test!(b"\x1B[ h" =>
1538				CSI::LineSpacing(1));
1539
1540			test!(b"\x1B[12 h" =>
1541				CSI::LineSpacing(12));
1542		}
1543
1544		#[test]
1545		fn sm() {
1546			test!(b"\x1B[1h" =>
1547				CSI::Set(small_vec![CSI::Mode::GuardedAreaTransfer]));
1548
1549			test!(b"\x1B[2h" =>
1550				CSI::Set(small_vec![CSI::Mode::KeyboardLock]));
1551
1552			test!(b"\x1B[3h" =>
1553				CSI::Set(small_vec![CSI::Mode::ControlRepresentation]));
1554
1555			test!(b"\x1B[4h" =>
1556				CSI::Set(small_vec![CSI::Mode::InsertionReplacement]));
1557
1558			test!(b"\x1B[5h" =>
1559				CSI::Set(small_vec![CSI::Mode::StatusReportTransfer]));
1560
1561			test!(b"\x1B[6h" =>
1562				CSI::Set(small_vec![CSI::Mode::Erasure]));
1563
1564			test!(b"\x1B[7h" =>
1565				CSI::Set(small_vec![CSI::Mode::LineEditing]));
1566
1567			test!(b"\x1B[8h" =>
1568				CSI::Set(small_vec![CSI::Mode::BidirectionalSupport]));
1569
1570			test!(b"\x1B[9h" =>
1571				CSI::Set(small_vec![CSI::Mode::DeviceComponentSelect]));
1572
1573			test!(b"\x1B[10h" =>
1574				CSI::Set(small_vec![CSI::Mode::CharacterEditing]));
1575
1576			test!(b"\x1B[11h" =>
1577				CSI::Set(small_vec![CSI::Mode::PositioningUnit]));
1578
1579			test!(b"\x1B[12h" =>
1580				CSI::Set(small_vec![CSI::Mode::SendReceive]));
1581
1582			test!(b"\x1B[13h" =>
1583				CSI::Set(small_vec![CSI::Mode::FormatEffectorAction]));
1584
1585			test!(b"\x1B[14h" =>
1586				CSI::Set(small_vec![CSI::Mode::FormatEffectorTransfer]));
1587
1588			test!(b"\x1B[15h" =>
1589				CSI::Set(small_vec![CSI::Mode::MultipleAreaTransfer]));
1590
1591			test!(b"\x1B[16h" =>
1592				CSI::Set(small_vec![CSI::Mode::TransferTermination]));
1593
1594			test!(b"\x1B[17h" =>
1595				CSI::Set(small_vec![CSI::Mode::SelectedAreaTransfer]));
1596
1597			test!(b"\x1B[18h" =>
1598				CSI::Set(small_vec![CSI::Mode::TabulationStop]));
1599
1600			test!(b"\x1B[21h" =>
1601				CSI::Set(small_vec![CSI::Mode::GraphicRenditionCombination]));
1602
1603			test!(b"\x1B[22h" =>
1604				CSI::Set(small_vec![CSI::Mode::ZeroDefault]));
1605		}
1606
1607		#[test]
1608		fn sr() {
1609			test!(b"\x1B[ A" =>
1610				CSI::ScrollRight(1));
1611
1612			test!(b"\x1B[43 A" =>
1613				CSI::ScrollRight(43));
1614		}
1615
1616		#[test]
1617		fn srs() {
1618			test!(b"\x1B[[" =>
1619				CSI::ReverseString(false));
1620
1621			test!(b"\x1B[0[" =>
1622				CSI::ReverseString(false));
1623
1624			test!(b"\x1B[1[" =>
1625				CSI::ReverseString(true));
1626		}
1627
1628		#[test]
1629		fn ssu() {
1630			test!(b"\x1B[ I" =>
1631				CSI::SizeUnit(CSI::Unit::Character));
1632
1633			test!(b"\x1B[0 I" =>
1634				CSI::SizeUnit(CSI::Unit::Character));
1635
1636			test!(b"\x1B[1 I" =>
1637				CSI::SizeUnit(CSI::Unit::Millimeter));
1638
1639			test!(b"\x1B[2 I" =>
1640				CSI::SizeUnit(CSI::Unit::ComputerDecipoint));
1641
1642			test!(b"\x1B[3 I" =>
1643				CSI::SizeUnit(CSI::Unit::Decidot));
1644
1645			test!(b"\x1B[4 I" =>
1646				CSI::SizeUnit(CSI::Unit::Mil));
1647
1648			test!(b"\x1B[5 I" =>
1649				CSI::SizeUnit(CSI::Unit::BasicMeasuringUnit));
1650
1651			test!(b"\x1B[6 I" =>
1652				CSI::SizeUnit(CSI::Unit::Micrometer));
1653
1654			test!(b"\x1B[7 I" =>
1655				CSI::SizeUnit(CSI::Unit::Pixel));
1656
1657			test!(b"\x1B[8 I" =>
1658				CSI::SizeUnit(CSI::Unit::Decipoint));
1659		}
1660
1661		#[test]
1662		fn ssw() {
1663			test!(b"\x1B[ [" =>
1664				CSI::SpaceWidth(1));
1665
1666			test!(b"\x1B[12 [" =>
1667				CSI::SpaceWidth(12));
1668		}
1669
1670		#[test]
1671		fn su() {
1672			test!(b"\x1B[S" =>
1673				CSI::ScrollUp(1));
1674
1675			test!(b"\x1B[37S" =>
1676				CSI::ScrollUp(37));
1677		}
1678
1679		#[test]
1680		fn tbc() {
1681			test!(b"\x1B[g" =>
1682				CSI::TabulationClear(CSI::Tabulation::Character));
1683
1684			test!(b"\x1B[0g" =>
1685				CSI::TabulationClear(CSI::Tabulation::Character));
1686
1687			test!(b"\x1B[1g" =>
1688				CSI::TabulationClear(CSI::Tabulation::Line));
1689
1690			test!(b"\x1B[2g" =>
1691				CSI::TabulationClear(CSI::Tabulation::Characters));
1692
1693			test!(b"\x1B[3g" =>
1694				CSI::TabulationClear(CSI::Tabulation::AllCharacters));
1695
1696			test!(b"\x1B[4g" =>
1697				CSI::TabulationClear(CSI::Tabulation::AllLines));
1698
1699			test!(b"\x1B[5g" =>
1700				CSI::TabulationClear(CSI::Tabulation::All));
1701		}
1702
1703		#[test]
1704		fn vpa() {
1705			test!(b"\x1B[d" =>
1706				CSI::CursorVerticalPosition(0));
1707
1708			test!(b"\x1B[42d" =>
1709				CSI::CursorVerticalPosition(41));
1710		}
1711
1712		#[test]
1713		fn vpb() {
1714			test!(b"\x1B[k" =>
1715				CSI::CursorUp(1));
1716
1717			test!(b"\x1B[42k" =>
1718				CSI::CursorUp(42));
1719		}
1720
1721		#[test]
1722		fn vpr() {
1723			test!(b"\x1B[e" =>
1724				CSI::CursorDown(1));
1725
1726			test!(b"\x1B[42e" =>
1727				CSI::CursorDown(42));
1728		}
1729	}
1730
1731	mod format {
1732		use {Control, C1, CSI, format, parse};
1733
1734		macro_rules! test {
1735			($code:expr) => (
1736				let item = Control::C1(C1::ControlSequence($code));
1737				assert_eq!(item, parse(&format(&item)).unwrap().1);
1738			);
1739		}
1740
1741		#[test]
1742		fn parameters() {
1743			assert_eq!(&b"\x1B[1;~"[..],
1744				&*format(&Control::C1(C1::ControlSequence(
1745					CSI::Unknown(b'~', None, small_vec![Some(1), None])))));
1746
1747			assert_eq!(&b"\x1B[;1~"[..],
1748				&*format(&Control::C1(C1::ControlSequence(
1749					CSI::Unknown(b'~', None, small_vec![None, Some(1)])))));
1750
1751			assert_eq!(&b"\x1B[1;1~"[..],
1752				&*format(&Control::C1(C1::ControlSequence(
1753					CSI::Unknown(b'~', None, small_vec![Some(1), Some(1)])))));
1754		}
1755
1756		#[test]
1757		fn cbt() {
1758			test!(CSI::CursorBackTabulation(1));
1759			test!(CSI::CursorBackTabulation(23));
1760		}
1761
1762		#[test]
1763		fn cha() {
1764			test!(CSI::CursorHorizontalPosition(0));
1765			test!(CSI::CursorHorizontalPosition(42));
1766		}
1767
1768		#[test]
1769		fn cht() {
1770			test!(CSI::CursorForwardTabulation(1));
1771			test!(CSI::CursorForwardTabulation(23));
1772		}
1773
1774		#[test]
1775		fn cnl() {
1776			test!(CSI::CursorNextLine(1));
1777			test!(CSI::CursorNextLine(12));
1778		}
1779
1780		#[test]
1781		fn cpl() {
1782			test!(CSI::CursorPreviousLine(1));
1783			test!(CSI::CursorPreviousLine(43));
1784		}
1785
1786		#[test]
1787		fn cpr() {
1788			test!(CSI::CursorPositionReport { x: 0, y: 0 });
1789			test!(CSI::CursorPositionReport { x: 0, y: 1 });
1790			test!(CSI::CursorPositionReport { x: 1, y: 0 });
1791			test!(CSI::CursorPositionReport { x: 1, y: 1 });
1792		}
1793
1794		#[test]
1795		fn ctc() {
1796			test!(CSI::CursorTabulationControl(CSI::TabulationControl::Character));
1797			test!(CSI::CursorTabulationControl(CSI::TabulationControl::Line));
1798			test!(CSI::CursorTabulationControl(CSI::TabulationControl::ClearCharacter));
1799			test!(CSI::CursorTabulationControl(CSI::TabulationControl::ClearLine));
1800			test!(CSI::CursorTabulationControl(CSI::TabulationControl::ClearCharacters));
1801			test!(CSI::CursorTabulationControl(CSI::TabulationControl::ClearAllCharacters));
1802			test!(CSI::CursorTabulationControl(CSI::TabulationControl::ClearAllLines));
1803		}
1804
1805		#[test]
1806		fn cub() {
1807			test!(CSI::CursorBack(1));
1808			test!(CSI::CursorBack(37));
1809		}
1810
1811		#[test]
1812		fn cud() {
1813			test!(CSI::CursorDown(1));
1814			test!(CSI::CursorDown(42));
1815		}
1816
1817		#[test]
1818		fn cuf() {
1819			test!(CSI::CursorForward(1));
1820			test!(CSI::CursorForward(13));
1821		}
1822
1823		#[test]
1824		fn cup() {
1825			test!(CSI::CursorPosition { x: 0, y: 0 });
1826			test!(CSI::CursorPosition { x: 1, y: 2 });
1827			test!(CSI::CursorPosition { x: 2, y: 0 });
1828			test!(CSI::CursorPosition { x: 0, y: 1 });
1829		}
1830
1831		#[test]
1832		fn cuu() {
1833			test!(CSI::CursorUp(1));
1834			test!(CSI::CursorUp(23));
1835		}
1836
1837		#[test]
1838		fn cvt() {
1839			test!(CSI::CursorLineTabulation(1));
1840			test!(CSI::CursorLineTabulation(23));
1841		}
1842
1843		#[test]
1844		fn da() {
1845			test!(CSI::DeviceAttributes(0));
1846			test!(CSI::DeviceAttributes(23));
1847		}
1848
1849		#[test]
1850		fn daq() {
1851			test!(CSI::DefineAreaQualification(CSI::Qualification::UnprotectedUnguarded));
1852			test!(CSI::DefineAreaQualification(CSI::Qualification::ProtectedGuarded));
1853			test!(CSI::DefineAreaQualification(CSI::Qualification::GraphicCharacterInput));
1854			test!(CSI::DefineAreaQualification(CSI::Qualification::NumericInput));
1855			test!(CSI::DefineAreaQualification(CSI::Qualification::AlphabeticInput));
1856			test!(CSI::DefineAreaQualification(CSI::Qualification::AlignLast));
1857			test!(CSI::DefineAreaQualification(CSI::Qualification::ZeroFill));
1858			test!(CSI::DefineAreaQualification(CSI::Qualification::FieldStart));
1859			test!(CSI::DefineAreaQualification(CSI::Qualification::ProtectedUnguarded));
1860			test!(CSI::DefineAreaQualification(CSI::Qualification::SpaceFill));
1861			test!(CSI::DefineAreaQualification(CSI::Qualification::AlignFirst));
1862			test!(CSI::DefineAreaQualification(CSI::Qualification::Reverse));
1863		}
1864
1865		#[test]
1866		fn dch() {
1867			test!(CSI::DeleteCharacter(1));
1868			test!(CSI::DeleteCharacter(8));
1869		}
1870
1871		#[test]
1872		fn dl() {
1873			test!(CSI::DeleteLine(1));
1874			test!(CSI::DeleteLine(8));
1875		}
1876
1877		#[test]
1878		fn dsr() {
1879			test!(CSI::DeviceStatusReport(CSI::Report::CursorPosition));
1880		}
1881
1882		#[test]
1883		fn dta() {
1884			test!(CSI::DimensionTextArea(0, 0));
1885			test!(CSI::DimensionTextArea(1, 0));
1886			test!(CSI::DimensionTextArea(0, 1));
1887			test!(CSI::DimensionTextArea(1, 1));
1888		}
1889
1890		#[test]
1891		fn ea() {
1892			test!(CSI::EraseArea(CSI::Erase::ToEnd));
1893			test!(CSI::EraseArea(CSI::Erase::ToStart));
1894			test!(CSI::EraseArea(CSI::Erase::All));
1895		}
1896
1897		#[test]
1898		fn ech() {
1899			test!(CSI::EraseCharacter(1));
1900			test!(CSI::EraseCharacter(8));
1901		}
1902
1903		#[test]
1904		fn ed() {
1905			test!(CSI::EraseDisplay(CSI::Erase::ToEnd));
1906			test!(CSI::EraseDisplay(CSI::Erase::ToStart));
1907			test!(CSI::EraseDisplay(CSI::Erase::All));
1908		}
1909
1910		#[test]
1911		fn ef() {
1912			test!(CSI::EraseField(CSI::Erase::ToEnd));
1913			test!(CSI::EraseField(CSI::Erase::ToEnd));
1914			test!(CSI::EraseField(CSI::Erase::ToStart));
1915			test!(CSI::EraseField(CSI::Erase::All));
1916		}
1917
1918		#[test]
1919		fn el() {
1920			test!(CSI::EraseLine(CSI::Erase::ToEnd));
1921			test!(CSI::EraseLine(CSI::Erase::ToEnd));
1922			test!(CSI::EraseLine(CSI::Erase::ToStart));
1923			test!(CSI::EraseLine(CSI::Erase::All));
1924		}
1925
1926		#[test]
1927		fn fnk() {
1928			test!(CSI::FunctionKey(0));
1929			test!(CSI::FunctionKey(13));
1930		}
1931
1932		#[test]
1933		fn fnt() {
1934			test!(CSI::SelectFont(0, 0));
1935			test!(CSI::SelectFont(13, 0));
1936			test!(CSI::SelectFont(0, 13));
1937			test!(CSI::SelectFont(13, 13));
1938		}
1939
1940		#[test]
1941		fn gcc() {
1942			test!(CSI::GraphicCharacterCombination(CSI::Combination::Next));
1943			test!(CSI::GraphicCharacterCombination(CSI::Combination::Start));
1944			test!(CSI::GraphicCharacterCombination(CSI::Combination::End));
1945		}
1946
1947		#[test]
1948		fn gsm() {
1949			test!(CSI::GraphicSizeModification { width: 100, height: 100 });
1950			test!(CSI::GraphicSizeModification { width: 100, height: 13 });
1951			test!(CSI::GraphicSizeModification { width: 13, height: 100 });
1952			test!(CSI::GraphicSizeModification { width: 13, height: 13 });
1953		}
1954
1955		#[test]
1956		fn hpa() {
1957			test!(CSI::CursorHorizontalPosition(0));
1958			test!(CSI::CursorHorizontalPosition(1));
1959		}
1960
1961		#[test]
1962		fn hpb() {
1963			test!(CSI::CursorBack(1));
1964			test!(CSI::CursorBack(2));
1965		}
1966
1967		#[test]
1968		fn hpr() {
1969			test!(CSI::CursorForward(1));
1970			test!(CSI::CursorForward(2));
1971		}
1972
1973		#[test]
1974		fn ich() {
1975			test!(CSI::InsertCharacter(1));
1976			test!(CSI::InsertCharacter(23));
1977		}
1978
1979		#[test]
1980		fn idcs() {
1981			test!(CSI::IdentifyDeviceControlString(None));
1982			test!(CSI::IdentifyDeviceControlString(Some(1)));
1983		}
1984
1985		#[test]
1986		fn igs() {
1987			test!(CSI::IdentifyGraphicSubrepertoire(None));
1988			test!(CSI::IdentifyGraphicSubrepertoire(Some(1)));
1989		}
1990
1991		#[test]
1992		fn il() {
1993			test!(CSI::InsertLine(1));
1994			test!(CSI::InsertLine(2));
1995		}
1996
1997		#[test]
1998		fn jfy() {
1999			test!(CSI::Justify(small_vec![Some(1), Some(2)]));
2000		}
2001
2002		#[test]
2003		fn mc() {
2004			test!(CSI::MediaCopy(CSI::Copy::ToPrimary));
2005			test!(CSI::MediaCopy(CSI::Copy::FromPrimary));
2006			test!(CSI::MediaCopy(CSI::Copy::ToSecondary));
2007			test!(CSI::MediaCopy(CSI::Copy::FromSecondary));
2008			test!(CSI::MediaCopy(CSI::Copy::StopPrimary));
2009			test!(CSI::MediaCopy(CSI::Copy::StartPrimary));
2010			test!(CSI::MediaCopy(CSI::Copy::StopSecondary));
2011			test!(CSI::MediaCopy(CSI::Copy::StartSecondary));
2012		}
2013
2014		#[test]
2015		fn np() {
2016			test!(CSI::NextPage(1));
2017			test!(CSI::NextPage(2));
2018		}
2019
2020		#[test]
2021		fn pec() {
2022			test!(CSI::Presentation(CSI::Expansion::Normal));
2023			test!(CSI::Presentation(CSI::Expansion::Expanded));
2024			test!(CSI::Presentation(CSI::Expansion::Condensed));
2025		}
2026
2027		#[test]
2028		fn pfs() {
2029			test!(CSI::PageFormat(0));
2030			test!(CSI::PageFormat(3));
2031		}
2032
2033		#[test]
2034		fn pp() {
2035			test!(CSI::PrecedingPage(1));
2036			test!(CSI::PrecedingPage(3));
2037		}
2038
2039		#[test]
2040		fn ppa() {
2041			test!(CSI::PagePosition(1));
2042			test!(CSI::PagePosition(3));
2043		}
2044
2045		#[test]
2046		fn ppb() {
2047			test!(CSI::PageBack(1));
2048			test!(CSI::PageBack(3));
2049		}
2050
2051		#[test]
2052		fn ppr() {
2053			test!(CSI::PageForward(1));
2054			test!(CSI::PageForward(3));
2055		}
2056
2057		#[test]
2058		fn ptx() {
2059			test!(CSI::ParallelText(CSI::Parallel::End));
2060			test!(CSI::ParallelText(CSI::Parallel::Start));
2061			test!(CSI::ParallelText(CSI::Parallel::StartSupplementary));
2062			test!(CSI::ParallelText(CSI::Parallel::StartPhoneticJapanese));
2063			test!(CSI::ParallelText(CSI::Parallel::StartPhoneticChinese));
2064			test!(CSI::ParallelText(CSI::Parallel::StopPhonetic));
2065		}
2066
2067		#[test]
2068		fn rcp() {
2069			test!(CSI::RestoreCursor);
2070		}
2071
2072		#[test]
2073		fn rep() {
2074			test!(CSI::Repeat(1));
2075			test!(CSI::Repeat(10));
2076		}
2077
2078		#[test]
2079		fn rm() {
2080			test!(CSI::Reset(small_vec![CSI::Mode::GuardedAreaTransfer]));
2081			test!(CSI::Reset(small_vec![CSI::Mode::KeyboardLock]));
2082			test!(CSI::Reset(small_vec![CSI::Mode::ControlRepresentation]));
2083			test!(CSI::Reset(small_vec![CSI::Mode::InsertionReplacement]));
2084			test!(CSI::Reset(small_vec![CSI::Mode::StatusReportTransfer]));
2085			test!(CSI::Reset(small_vec![CSI::Mode::Erasure]));
2086			test!(CSI::Reset(small_vec![CSI::Mode::LineEditing]));
2087			test!(CSI::Reset(small_vec![CSI::Mode::BidirectionalSupport]));
2088			test!(CSI::Reset(small_vec![CSI::Mode::DeviceComponentSelect]));
2089			test!(CSI::Reset(small_vec![CSI::Mode::CharacterEditing]));
2090			test!(CSI::Reset(small_vec![CSI::Mode::PositioningUnit]));
2091			test!(CSI::Reset(small_vec![CSI::Mode::SendReceive]));
2092			test!(CSI::Reset(small_vec![CSI::Mode::FormatEffectorAction]));
2093			test!(CSI::Reset(small_vec![CSI::Mode::FormatEffectorTransfer]));
2094			test!(CSI::Reset(small_vec![CSI::Mode::MultipleAreaTransfer]));
2095			test!(CSI::Reset(small_vec![CSI::Mode::TransferTermination]));
2096			test!(CSI::Reset(small_vec![CSI::Mode::SelectedAreaTransfer]));
2097			test!(CSI::Reset(small_vec![CSI::Mode::TabulationStop]));
2098			test!(CSI::Reset(small_vec![CSI::Mode::GraphicRenditionCombination]));
2099			test!(CSI::Reset(small_vec![CSI::Mode::ZeroDefault]));
2100		}
2101
2102		#[test]
2103		fn sco() {
2104			test!(CSI::CharacterOrientation(0));
2105			test!(CSI::CharacterOrientation(45));
2106			test!(CSI::CharacterOrientation(90));
2107			test!(CSI::CharacterOrientation(135));
2108			test!(CSI::CharacterOrientation(180));
2109			test!(CSI::CharacterOrientation(225));
2110			test!(CSI::CharacterOrientation(270));
2111			test!(CSI::CharacterOrientation(315));
2112		}
2113
2114		#[test]
2115		fn scp() {
2116			test!(CSI::SaveCursor);
2117		}
2118
2119		#[test]
2120		fn scs() {
2121			test!(CSI::CharacterSpacing(1));
2122			test!(CSI::CharacterSpacing(23));
2123		}
2124
2125		#[test]
2126		fn sd() {
2127			test!(CSI::ScrollDown(1));
2128			test!(CSI::ScrollDown(73));
2129		}
2130
2131		#[test]
2132		fn simd() {
2133			test!(CSI::Movement(CSI::Direction::Forward));
2134			test!(CSI::Movement(CSI::Direction::Forward));
2135			test!(CSI::Movement(CSI::Direction::Backward));
2136		}
2137
2138		#[test]
2139		fn sl() {
2140			test!(CSI::ScrollLeft(1));
2141			test!(CSI::ScrollLeft(12));
2142		}
2143
2144		#[test]
2145		fn sls() {
2146			test!(CSI::LineSpacing(1));
2147			test!(CSI::LineSpacing(12));
2148		}
2149
2150		#[test]
2151		fn sm() {
2152			test!(CSI::Set(small_vec![CSI::Mode::GuardedAreaTransfer]));
2153			test!(CSI::Set(small_vec![CSI::Mode::KeyboardLock]));
2154			test!(CSI::Set(small_vec![CSI::Mode::ControlRepresentation]));
2155			test!(CSI::Set(small_vec![CSI::Mode::InsertionReplacement]));
2156			test!(CSI::Set(small_vec![CSI::Mode::StatusReportTransfer]));
2157			test!(CSI::Set(small_vec![CSI::Mode::Erasure]));
2158			test!(CSI::Set(small_vec![CSI::Mode::LineEditing]));
2159			test!(CSI::Set(small_vec![CSI::Mode::BidirectionalSupport]));
2160			test!(CSI::Set(small_vec![CSI::Mode::DeviceComponentSelect]));
2161			test!(CSI::Set(small_vec![CSI::Mode::CharacterEditing]));
2162			test!(CSI::Set(small_vec![CSI::Mode::PositioningUnit]));
2163			test!(CSI::Set(small_vec![CSI::Mode::SendReceive]));
2164			test!(CSI::Set(small_vec![CSI::Mode::FormatEffectorAction]));
2165			test!(CSI::Set(small_vec![CSI::Mode::FormatEffectorTransfer]));
2166			test!(CSI::Set(small_vec![CSI::Mode::MultipleAreaTransfer]));
2167			test!(CSI::Set(small_vec![CSI::Mode::TransferTermination]));
2168			test!(CSI::Set(small_vec![CSI::Mode::SelectedAreaTransfer]));
2169			test!(CSI::Set(small_vec![CSI::Mode::TabulationStop]));
2170			test!(CSI::Set(small_vec![CSI::Mode::GraphicRenditionCombination]));
2171			test!(CSI::Set(small_vec![CSI::Mode::ZeroDefault]));
2172		}
2173
2174		#[test]
2175		fn sr() {
2176			test!(CSI::ScrollRight(1));
2177			test!(CSI::ScrollRight(43));
2178		}
2179
2180		#[test]
2181		fn srs() {
2182			test!(CSI::ReverseString(false));
2183			test!(CSI::ReverseString(true));
2184		}
2185
2186		#[test]
2187		fn ssu() {
2188			test!(CSI::SizeUnit(CSI::Unit::Character));
2189			test!(CSI::SizeUnit(CSI::Unit::Millimeter));
2190			test!(CSI::SizeUnit(CSI::Unit::ComputerDecipoint));
2191			test!(CSI::SizeUnit(CSI::Unit::Decidot));
2192			test!(CSI::SizeUnit(CSI::Unit::Mil));
2193			test!(CSI::SizeUnit(CSI::Unit::BasicMeasuringUnit));
2194			test!(CSI::SizeUnit(CSI::Unit::Micrometer));
2195			test!(CSI::SizeUnit(CSI::Unit::Pixel));
2196			test!(CSI::SizeUnit(CSI::Unit::Decipoint));
2197		}
2198
2199		#[test]
2200		fn ssw() {
2201			test!(CSI::SpaceWidth(1));
2202			test!(CSI::SpaceWidth(12));
2203		}
2204
2205		#[test]
2206		fn su() {
2207			test!(CSI::ScrollUp(1));
2208			test!(CSI::ScrollUp(37));
2209		}
2210
2211		#[test]
2212		fn tbc() {
2213			test!(CSI::TabulationClear(CSI::Tabulation::Character));
2214			test!(CSI::TabulationClear(CSI::Tabulation::Line));
2215			test!(CSI::TabulationClear(CSI::Tabulation::Characters));
2216			test!(CSI::TabulationClear(CSI::Tabulation::AllCharacters));
2217			test!(CSI::TabulationClear(CSI::Tabulation::AllLines));
2218			test!(CSI::TabulationClear(CSI::Tabulation::All));
2219		}
2220
2221		#[test]
2222		fn vpa() {
2223			test!(CSI::CursorVerticalPosition(1));
2224			test!(CSI::CursorDown(42));
2225		}
2226
2227		#[test]
2228		fn vpb() {
2229			test!(CSI::CursorUp(1));
2230			test!(CSI::CursorUp(42));
2231		}
2232
2233		#[test]
2234		fn vpr() {
2235			test!(CSI::CursorDown(1));
2236			test!(CSI::CursorDown(42));
2237		}
2238	}
2239}