1 module served.commands.color; 2 3 import std.conv; 4 import std.format; 5 import std.regex; 6 7 import served.types; 8 9 static immutable colorRegex = ctRegex!`#([0-9a-fA-F]{2}){3,4}|"#([0-9a-fA-F]{2}){3,4}"`; 10 11 @protocolMethod("textDocument/documentColor") 12 ColorInformation[] provideDocumentColor(DocumentColorParams params) 13 { 14 Document document = documents[params.textDocument.uri]; 15 if (document.getLanguageId != "dml") 16 return null; 17 18 ColorInformation[] ret; 19 20 { 21 // if we ever want to make serve-d multi-threaded, want to lock here 22 // document.lock(); 23 // scope (exit) 24 // document.unlock(); 25 26 size_t cacheBytes; 27 Position cachePos; 28 foreach (match; matchAll(document.rawText, colorRegex)) 29 { 30 const(char)[] text = match.hit; 31 if (text[0] == '"') 32 text = text[1 .. $ - 1]; 33 assert(text[0] == '#', "broken regex match"); 34 text = text[1 .. $]; 35 assert(text.length == 6 || text.length == 8, "broken regex match"); 36 37 TextRange range; 38 cachePos = range.start = document.movePositionBytes(cachePos, cacheBytes, cacheBytes = match.pre.length); 39 cachePos = range.end = document.movePositionBytes(cachePos, cacheBytes, cacheBytes = match.pre.length + match.hit.length); 40 41 Color color; 42 if (text.length == 8) 43 { 44 color.alpha = text[0 .. 2].to!int(16) / 255.0; 45 text = text[2 .. $]; 46 } 47 color.red = text[0 .. 2].to!int(16) / 255.0; 48 color.green = text[2 .. 4].to!int(16) / 255.0; 49 color.blue = text[4 .. 6].to!int(16) / 255.0; 50 ret ~= ColorInformation(range, color); 51 } 52 } 53 54 return ret; 55 } 56 57 @protocolMethod("textDocument/colorPresentation") 58 ColorPresentation[] provideColorPresentations(ColorPresentationParams params) 59 { 60 Document document = documents[params.textDocument.uri]; 61 if (document.getLanguageId != "dml") 62 return null; 63 64 // only hex supported 65 string hex; 66 if (params.color.alpha != 1) 67 hex = format!"#%02x%02x%02x%02x"( 68 cast(int)(params.color.alpha * 255), 69 cast(int)(params.color.red * 255), 70 cast(int)(params.color.green * 255), 71 cast(int)(params.color.blue * 255) 72 ); 73 else 74 hex = format!"#%02x%02x%02x"( 75 cast(int)(params.color.red * 255), 76 cast(int)(params.color.green * 255), 77 cast(int)(params.color.blue * 255) 78 ); 79 80 return [ColorPresentation(hex)]; 81 }