v2 / vlib / v / fmt / vfmt_on_off.v
66 lines · 59 sloc · 2.3 KB · b52b8429d4456df3070c39681ad010d33801bcf4
Raw
1module fmt
2
3import v.util
4
5// By default, vfmt *always reformats all source code passed to it* in an uniform way.
6// This works in the vast majority of the cases, providing a very nice default and
7// consistent look & feel for most V codebases, and eliminating countless hours of bike
8// shedding discussions about whether using spaces or tabs is better, and where {} and
9// () should be put, and whether comments should be aligned or not.
10//
11// However, there are indeed situations, where careful manual formatting can increase
12// understanding and maintainability of the code. For example, if you write matrix heavy
13// code, you may want to preserve the look of your carefully written beautiful matrices,
14// so that every reader of your code can bask in their glory.
15//
16// To enable such manual formatting, this file supports using `vfmt off` and `vfmt on`
17// line comments, which can be used for turning off and on vfmt *locally* in selected
18// blocks of code, while leaving the vast majority of the code, to be formatted by vfmt.
19//
20// TLDR:
21// All lines after `// vfmt off` are passed on *without any modification* to the output.
22// All lines after `// vfmt on` are going to be formatted, and then added to the output.
23
24struct FormatState {
25mut:
26 is_vfmt_on bool = true
27 last_off_source_line int // the source line where // vfmt off was encountered first
28 last_off_out_len int // f.out.len when // vfmt off was encountered first
29}
30
31fn (mut fs FormatState) reset() {
32 fs.is_vfmt_on = true
33 fs.last_off_source_line = 0
34 fs.last_off_out_len = 0
35}
36
37pub fn (mut f Fmt) vfmt_off(off_line int) {
38 // only trigger once on on->off edges:
39 if !f.format_state.is_vfmt_on {
40 return
41 }
42 f.format_state.is_vfmt_on = false
43 f.format_state.last_off_source_line = off_line
44 f.format_state.last_off_out_len = f.out.len
45}
46
47pub fn (mut f Fmt) vfmt_on(on_line int) {
48 // only trigger once on off->on edges:
49 if f.format_state.is_vfmt_on {
50 return
51 }
52 f.out.cut_to(f.format_state.last_off_out_len)
53 f.out.writeln('')
54 source_lines := f.get_source_lines()#[f.format_state.last_off_source_line + 1..on_line]
55 for line in source_lines {
56 f.out.writeln(line)
57 }
58 f.format_state.reset()
59}
60
61pub fn (mut f Fmt) get_source_lines() []string {
62 if f.file.path != '' {
63 return unsafe { util.cached_file2sourcelines(f.file.path) }
64 }
65 return f.source_text.split('\n')
66}
67