@ 261101.7 · fetching

261030.1 · d7b1aa3cc81f67fa0741255f515fedfd101d97de

A scope box starts at the least indent among its rows

A box took its left edge from its first row's indent. A Go raw string whose lines sit at the margin, as in gron_test.go, then ran left of its box and was cut by the border. In gofmt'd code only multi-line strings move; their box now shares its left edge with the box around them.

reading declarations

doc/code-pages.md

@@ -26,7 +26,7 @@ A code page's views, flat, scopes and tree, and raw sit in a row of their own ab  Add `?scopes` to a code page, or follow scopes, and it draws each block of code that spans lines as a sunken box behind its text. Boxes nest as deep as the code goes, and deeper boxes are fainter. -A block is a bracket pair whose ends sit on different lines, or in Python the lines indented under a line that ends with a colon. Brackets and strings within a line, around something, are smaller boxes inside it, down to the innermost, much as vim's `ci(` and `ci"` see them. A string that spans lines is a block.+A block is a bracket pair whose ends sit on different lines, or in Python the lines indented under a line that ends with a colon. Brackets and strings within a line, around something, are smaller boxes inside it, down to the innermost, much as vim's `ci(` and `ci"` see them. A string that spans lines is a block. A box starts at its least indented line, so a raw string's lines at the margin stay inside it.  Fills alternate inward between a light shade and the page's colour, so depth shows without the page darkening. The boxes lie on a layer of their own, so no character moves and copied text is unchanged. 

scope.go

@@ -10,8 +10,8 @@ import (  // A scope is a block of code that spans lines, drawn as a sunken box // behind its text. Monospace text is a grid, so a box is a rectangle of-// cells: from its first row to its last, from the first row's indent to-// past its widest line. A leaf is a bracket pair within one line, eg+// cells: from its first row to its last, from the least indent among its+// rows to past its widest line. A leaf is a bracket pair within one line, eg // (x, y), whose box spans its brackets' cells. Boxes nest without limit. type scope struct { 	first, last int // rows, counted from 0@@ -179,13 +179,18 @@ func findScopes(lines [][]chroma.Token, python bool) []scope { 			in = in[:len(in)-1] 		} 		parent[i] = -1-		s.left = max(indent[s.first], 0) 		if len(in) > 0 { 			parent[i] = in[len(in)-1]-			s.left = max(s.left, found[parent[i]].left) 		} 		s.depth = len(in) + 1+		// A box starts at the least indent among its rows, so no text+		// lies left of it, eg a raw string's lines at the margin. A box+		// thus never starts left of the box around it.+		s.left = indent[s.first] 		for r := s.first; r <= s.last; r++ {+			if indent[r] >= 0 {+				s.left = min(s.left, indent[r])+			} 			s.right = max(s.right, width[r]) 		} 		in = append(in, i)

scope_test.go

@@ -85,6 +85,23 @@ func TestScopeStrings(t *testing.T) { 	} } +// A box starts at the least indent among its rows, so a raw string's+// lines at the margin stay inside it and the boxes around it.+func TestScopeLeftmostRow(t *testing.T) {+	src := "func f() {\n" + // 0+		"\tx := `a\n" + // 1+		"b`\n" + // 2+		"}\n" // 3+	got := scopesOf("a.go", src)+	want := []scope{+		{first: 0, last: 3, left: 0, right: 16, depth: 1},+		{first: 1, last: 2, left: 0, right: 15, depth: 2},+	}+	if !reflect.DeepEqual(got, want) {+		t.Errorf("scopes\n%+v, want\n%+v", got, want)+	}+}+ // A code page draws each scope as an empty box in its first line, after // the line number; a flat page and fences draw none. func TestScopeBoxes(t *testing.T) {