1 module workspaced.helpers;
2 
3 import std.ascii;
4 import std.string;
5 
6 string determineIndentation(scope const(char)[] code)
7 {
8 	const(char)[] indent = null;
9 	foreach (line; code.lineSplitter)
10 	{
11 		if (line.strip.length == 0)
12 			continue;
13 		indent = line[0 .. $ - line.stripLeft.length];
14 	}
15 	return indent.idup;
16 }
17 
18 int stripLineEndingLength(scope const(char)[] code)
19 {
20 	if (code.endsWith("\r\n"))
21 		return 2;
22 	else if (code.endsWith("\r", "\n"))
23 		return 1;
24 	else
25 		return 0;
26 }
27 
28 bool isIdentifierChar(dchar c)
29 {
30 	return c.isAlphaNum || c == '_';
31 }
32 
33 ptrdiff_t indexOfKeyword(scope const(char)[] code, string keyword, ptrdiff_t start = 0)
34 {
35 	ptrdiff_t index = start;
36 	while (true)
37 	{
38 		index = code.indexOf(keyword, index);
39 		if (index == -1)
40 			break;
41 
42 		if ((index > 0 && code[index - 1].isIdentifierChar)
43 				|| (index + keyword.length < code.length && code[index + keyword.length].isIdentifierChar))
44 		{
45 			index++;
46 			continue;
47 		}
48 		else
49 			break;
50 	}
51 	return index;
52 }
53 
54 bool endsWithKeyword(scope const(char)[] code, string keyword)
55 {
56 	return code == keyword || (code.endsWith(keyword) && code[$ - 1 - keyword.length]
57 			.isIdentifierChar);
58 }
59 
60 bool isIdentifierSeparatingChar(dchar c)
61 {
62 	return c < 48 || (c > 57 && c < 65) || c == '[' || c == '\\' || c == ']'
63 		|| c == '`' || (c > 122 && c < 128) || c == '\u2028' || c == '\u2029'; // line separators
64 }