Forge
csharpdeeb25a2
1namespace CascadeIDE.Services;
2
3/// <summary>
4/// Каталог логов inlay: в репозитории рядом с <c>CascadeIDE.sln</c> (<c>.inlay-logs/</c>), не в <c>bin</c> — удобно читать из Cursor.
5/// Пробрасывается в процесс как <see cref="EnvironmentVariableName"/> (см. <see cref="EnsureInlayLogEnvironment" /> в <c>Program.Main</c>),
6/// чтобы вендорный AvaloniaEdit писал в тот же каталог без ссылки на CascadeIDE.
7/// </summary>
8internal static class InlayLogPaths
9{
10 /// <summary>Имя переменной окружения: абсолютный путь каталога для <c>inlay-*.log</c>.</summary>
11 public const string EnvironmentVariableName = "CASCADE_INLAY_LOG_DIR";
12
13 private static string? _cached;
14
15 /// <summary>Каталог для append-логов (создаётся при записи).</summary>
16 public static string GetLogDirectory()
17 {
18 // Env выставляется в Main после возможных ранних вызовов — всегда перекрывает кэш.
19 var fromEnv = Environment.GetEnvironmentVariable(EnvironmentVariableName);
20 if (!string.IsNullOrWhiteSpace(fromEnv))
21 return CanonicalFilePath.Normalize(fromEnv.Trim());
22
23 if (_cached is not null)
24 return _cached;
25
26 if (TryFindDirectoryWithSolutionFile(out var slnDir))
27 {
28 _cached = Path.Combine(slnDir, ".inlay-logs");
29 return _cached;
30 }
31
32 _cached = Path.Combine(AppContext.BaseDirectory, ".cascade-ide");
33 return _cached;
34 }
35
36 /// <summary>
37 /// Выставить <see cref="EnvironmentVariableName" />, если пользователь его не задал — до инициализации AvaloniaEdit.
38 /// </summary>
39 public static void EnsureInlayLogEnvironment()
40 {
41 if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(EnvironmentVariableName)))
42 return;
43
44 string dir;
45 if (TryFindDirectoryWithSolutionFile(out var slnDir))
46 dir = Path.Combine(slnDir, ".inlay-logs");
47 else
48 dir = Path.Combine(AppContext.BaseDirectory, ".cascade-ide");
49
50 try
51 {
52 Environment.SetEnvironmentVariable(EnvironmentVariableName, dir);
53 }
54 catch
55 {
56 // ignore
57 }
58 }
59
60 private static bool TryFindDirectoryWithSolutionFile([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? directory)
61 {
62 directory = null;
63 var current = AppContext.BaseDirectory;
64 for (var depth = 0; depth < 16 && !string.IsNullOrEmpty(current); depth++)
65 {
66 if (File.Exists(Path.Combine(current, "CascadeIDE.sln")))
67 {
68 directory = current;
69 return true;
70 }
71
72 current = Path.GetDirectoryName(current)!;
73 }
74
75 return false;
76 }
77}
78
View only · write via MCP/CIDE