[llvm] [clang-repl] Support XDG state directory for history (PR #223037)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 23 23:05:05 PDT 2026
https://github.com/RohanOnKeys updated https://github.com/llvm/llvm-project/pull/223037
>From a3c107f77e97476a2b89cc4d3b809092e890d0ba Mon Sep 17 00:00:00 2001
From: rohan <rohanpxquantum at gmail.com>
Date: Fri, 11 Sep 2026 19:49:56 +0000
Subject: [PATCH] [clang-repl] Support XDG state directory for history
Signed-off-by: rohan <rohanpxquantum at gmail.com>
---
llvm/lib/LineEditor/LineEditor.cpp | 29 +++++++--
llvm/unittests/LineEditor/LineEditor.cpp | 81 ++++++++++++++++++++++++
2 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/LineEditor/LineEditor.cpp b/llvm/lib/LineEditor/LineEditor.cpp
index 3e4004313acf2..d0f3215f3678f 100644
--- a/llvm/lib/LineEditor/LineEditor.cpp
+++ b/llvm/lib/LineEditor/LineEditor.cpp
@@ -10,7 +10,9 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -24,11 +26,30 @@ using namespace llvm;
std::string LineEditor::getDefaultHistoryPath(StringRef ProgName) {
SmallString<32> Path;
- if (sys::path::home_directory(Path)) {
- sys::path::append(Path, "." + ProgName + "-history");
- return std::string(Path);
+ if (!sys::path::home_directory(Path))
+ return std::string();
+
+#ifdef __linux__
+ SmallString<32> LegacyPath(Path);
+ sys::path::append(LegacyPath, "." + ProgName + "-history");
+
+ if (sys::fs::exists(LegacyPath))
+ return std::string(LegacyPath);
+
+ if (auto StateHome = sys::Process::GetEnv("XDG_STATE_HOME")) {
+ Path = *StateHome;
+ } else {
+ sys::path::append(Path, ".local", "state");
}
- return std::string();
+
+ (void)sys::fs::create_directories(Path);
+
+ sys::path::append(Path, ProgName + "-history");
+ return std::string(Path);
+#else
+ sys::path::append(Path, "." + ProgName + "-history");
+ return std::string(Path);
+#endif
}
LineEditor::CompleterConcept::~CompleterConcept() = default;
diff --git a/llvm/unittests/LineEditor/LineEditor.cpp b/llvm/unittests/LineEditor/LineEditor.cpp
index 42e5c6c3c01f5..ea024d78753ae 100644
--- a/llvm/unittests/LineEditor/LineEditor.cpp
+++ b/llvm/unittests/LineEditor/LineEditor.cpp
@@ -80,3 +80,84 @@ TEST_F(LineEditorTest, ListCompleters) {
EXPECT_EQ(LineEditor::CompletionAction::AK_Insert, CA.Kind);
EXPECT_EQ("f", CA.Text);
}
+
+
+#ifdef __linux__
+
+#include <cstdlib>
+
+TEST(LineEditorDefaultHistoryPath, DefaultHistoryPathUsesXDGStateHome) {
+ SmallString<128> TempDir;
+ ASSERT_FALSE(sys::fs::createUniqueDirectory("xdg-state", TempDir));
+
+ setenv("XDG_STATE_HOME", TempDir.c_str(), 1);
+
+ std::string Path = LineEditor::getDefaultHistoryPath("clang-repl");
+
+ EXPECT_EQ((TempDir + "/clang-repl-history").str().str(), Path);
+
+ unsetenv("XDG_STATE_HOME");
+ sys::fs::remove_directories(TempDir);
+}
+
+#endif
+
+#ifdef __linux__
+
+TEST(LineEditorDefaultHistoryPath, ExistingLegacyHistoryTakesPrecedence) {
+ SmallString<128> HomeDir;
+ ASSERT_FALSE(sys::fs::createUniqueDirectory("lineeditor-home", HomeDir));
+
+ SmallString<128> Legacy(HomeDir);
+ sys::path::append(Legacy, ".clang-repl-history");
+
+ std::error_code EC;
+ raw_fd_ostream OS(Legacy, EC);
+ ASSERT_FALSE(EC);
+ OS.close();
+
+ setenv("HOME", HomeDir.c_str(), 1);
+
+ SmallString<128> XDGDir;
+ ASSERT_FALSE(sys::fs::createUniqueDirectory("xdg-state", XDGDir));
+ setenv("XDG_STATE_HOME", XDGDir.c_str(), 1);
+
+ EXPECT_EQ(Legacy.str(), LineEditor::getDefaultHistoryPath("clang-repl"));
+
+ unsetenv("HOME");
+ unsetenv("XDG_STATE_HOME");
+ sys::fs::remove_directories(HomeDir);
+ sys::fs::remove_directories(XDGDir);
+}
+
+#endif
+
+#ifdef __linux__
+
+TEST(LineEditorDefaultHistoryPath, ExistingLegacyHistoryTakesPrecedence) {
+ SmallString<128> HomeDir;
+ ASSERT_FALSE(sys::fs::createUniqueDirectory("lineeditor-home", HomeDir));
+
+ SmallString<128> Legacy(HomeDir);
+ sys::path::append(Legacy, ".clang-repl-history");
+
+ std::error_code EC;
+ raw_fd_ostream OS(Legacy, EC);
+ ASSERT_FALSE(EC);
+ OS.close();
+
+ setenv("HOME", HomeDir.c_str(), 1);
+
+ SmallString<128> XDGDir;
+ ASSERT_FALSE(sys::fs::createUniqueDirectory("xdg-state", XDGDir));
+ setenv("XDG_STATE_HOME", XDGDir.c_str(), 1);
+
+ EXPECT_EQ(Legacy.str(), LineEditor::getDefaultHistoryPath("clang-repl"));
+
+ unsetenv("HOME");
+ unsetenv("XDG_STATE_HOME");
+ sys::fs::remove_directories(HomeDir);
+ sys::fs::remove_directories(XDGDir);
+}
+
+#endif
More information about the llvm-commits
mailing list