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 }