Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CodeLite symlink handling #3572

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions CodeLite/fileutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
#include <memory>
#include <wx/filename.h>


static bool bRealPathModeResolveSymlinks = true;

thread_local std::unordered_set<wxChar> VALID_CHARS = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
Expand Down Expand Up @@ -595,10 +598,10 @@ unsigned int FileUtils::UTF8Length(const wchar_t* uptr, unsigned int tlen)
}

// This is readlink on steroids: it also makes-absolute, and dereferences any symlinked dirs in the path
wxString FileUtils::RealPath(const wxString& filepath)
wxString FileUtils::RealPath(const wxString& filepath, bool forced)
{
#if defined(__WXGTK__) || defined(__WXOSX__)
if (!filepath.empty()) {
if (!filepath.empty() && (forced || bRealPathModeResolveSymlinks)) {
#if defined(__FreeBSD__) || defined(__WXOSX__)
wxStructStat stbuff;
if ((::wxLstat(filepath, &stbuff) != 0) || !S_ISLNK(stbuff.st_mode)) {
Expand All @@ -617,6 +620,17 @@ wxString FileUtils::RealPath(const wxString& filepath)
return filepath;
}

bool FileUtils::RealPathGetModeResolveSymlinks(void)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this code formatted using clang-format ? I suspect not

{
return bRealPathModeResolveSymlinks;
}

void FileUtils::RealPathSetModeResolveSymlinks(bool resolveSymlinks)
{
bRealPathModeResolveSymlinks = resolveSymlinks;
}


std::string FileUtils::ToStdString(const wxString& str) { return StringUtils::ToStdString(str); }

bool FileUtils::ReadBufferFromFile(const wxFileName& fn, wxString& data, size_t bufferSize)
Expand Down
4 changes: 3 additions & 1 deletion CodeLite/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ class WXDLLIMPEXP_CL FileUtils
/**
* @brief (on Linux) makes-absolute filepath, and dereferences it and any symlinked dirs in the path
*/
static wxString RealPath(const wxString& filepath);
static wxString RealPath(const wxString& filepath, bool forced=false);
static bool RealPathGetModeResolveSymlinks(void);
static void RealPathSetModeResolveSymlinks(bool resolveSymlinks);

/**
* @brief convert string into std::string
Expand Down
4 changes: 4 additions & 0 deletions LiteEditor/editorsettingsdockingwidows.cpp
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should be under the "Misc" section, "Tabs" is more for the visualization of the tab control (height, orientation etc)

Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,8 @@ EditorSettingsDockingWindows::EditorSettingsDockingWindows(wxWindow* parent, Opt
AddProperty(_("Find next/Find previous actions override search string with current selection (like Find next at caret/prev at caret)"),
m_options->GetFindNextOrPreviousUseSelection(),
UPDATE_BOOL_CB(SetFindNextOrPreviousUseSelection));
AddHeader(_("File path handling"));
AddProperty(_("Resolve symlinks in file paths"),
m_options->GetRealPathResolveSymlinks(),
UPDATE_BOOL_CB(SetRealPathResolveSymlinks));
}
35 changes: 22 additions & 13 deletions LiteEditor/mainbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void MainBook::OnProjectFileAdded(clCommandEvent& e)
for (size_t i = 0; i < files.GetCount(); i++) {
clEditor* editor = FindEditor(files.Item(i));
if (editor) {
wxString fileName = CLRealPath(editor->GetFileName().GetFullPath());
wxString fileName = FileUtils::RealPath(editor->GetFileName().GetFullPath());
if (files.Index(fileName) != wxNOT_FOUND) {
editor->SetProject(ManagerST::Get()->GetProjectNameByFile(fileName));
}
Expand All @@ -272,7 +272,7 @@ void MainBook::OnProjectFileRemoved(clCommandEvent& e)
const wxArrayString& files = e.GetStrings();
for (size_t i = 0; i < files.GetCount(); ++i) {
clEditor* editor = FindEditor(files.Item(i));
if (editor && files.Index(CLRealPath(editor->GetFileName().GetFullPath())) != wxNOT_FOUND) {
if (editor && files.Index(FileUtils::RealPath(editor->GetFileName().GetFullPath())) != wxNOT_FOUND) {
editor->SetProject(wxEmptyString);
}
}
Expand Down Expand Up @@ -451,7 +451,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)
{
#ifdef __WXGTK__
// On gtk either fileName or the editor filepath (or both) may be (or their paths contain) symlinks
wxString fileNameDest = CLRealPath(fullpath);
wxString fileNameDest = FileUtils::RealPath(fullpath, true);
#endif

for (size_t i = 0; i < m_book->GetPageCount(); ++i) {
Expand All @@ -465,7 +465,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)
}
} else {
// local path
wxString unixStyleFile(CLRealPath(editor->GetFileName().GetFullPath()));
wxString unixStyleFile(FileUtils::RealPath(editor->GetFileName().GetFullPath()));
wxString nativeFile(unixStyleFile);
#ifdef __WXMSW__
unixStyleFile.Replace(wxT("\\"), wxT("/"));
Expand All @@ -485,7 +485,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)

#if defined(__WXGTK__)
// Try again, dereferencing the editor fpath
wxString editorDest = CLRealPath(unixStyleFile);
wxString editorDest = FileUtils::RealPath(unixStyleFile, true);
if (editorDest.Cmp(fullpath) == 0 || editorDest.Cmp(fileNameDest) == 0) {
return i;
}
Expand All @@ -509,12 +509,13 @@ wxWindow* MainBook::FindPage(const wxString& text)
{
for (size_t i = 0; i < m_book->GetPageCount(); i++) {
clEditor* editor = dynamic_cast<clEditor*>(m_book->GetPage(i));
if (editor && CLRealPath(editor->GetFileName().GetFullPath()).CmpNoCase(text) == 0) {
if (editor && FileUtils::RealPath(editor->GetFileName().GetFullPath()).CmpNoCase(text) == 0) {
return editor;
}

if (m_book->GetPageText(i) == text)
if (m_book->GetPageText(i) == text) {
return m_book->GetPage(i);
}
}
return NULL;
}
Expand Down Expand Up @@ -620,7 +621,14 @@ clEditor* MainBook::OpenFile(const wxString& file_name,
int bmp /*= wxNullBitmap*/,
const wxString& tooltip /* wxEmptyString */)
{
wxFileName fileName(CLRealPath(file_name));
wxFileName fileName(FileUtils::RealPath(file_name));

if (fileName.IsRelative()) {
if (clWorkspaceManager::Get().IsWorkspaceOpened()) {
wxFileName wsPath = clWorkspaceManager::Get().GetWorkspace()->GetDir();
fileName.MakeAbsolute(wsPath.GetFullPath());
}
}
fileName.MakeAbsolute();

#ifdef __WXMSW__
Expand Down Expand Up @@ -1220,7 +1228,7 @@ bool MainBook::DoSelectPage(wxWindow* win)

} else {
wxCommandEvent event(wxEVT_ACTIVE_EDITOR_CHANGED);
event.SetString(CLRealPath(editor->GetFileName().GetFullPath()));
event.SetString(FileUtils::RealPath(editor->GetFileName().GetFullPath()));
EventNotifier::Get()->AddPendingEvent(event);
}
return true;
Expand Down Expand Up @@ -1737,7 +1745,7 @@ WelcomePage* MainBook::GetWelcomePage(bool createIfMissing)

clEditor* MainBook::OpenFileAsync(const wxString& file_name, std::function<void(IEditor*)>&& callback)
{
wxString real_path = CLRealPath(file_name);
wxString real_path = FileUtils::RealPath(file_name, true);
auto editor = FindEditor(real_path);
if (editor) {
push_callback(std::move(callback), real_path);
Expand All @@ -1748,7 +1756,7 @@ clEditor* MainBook::OpenFileAsync(const wxString& file_name, std::function<void(
m_book->SetSelection(index);
}
} else {
editor = OpenFile(real_path);
editor = OpenFile(file_name);
if (editor) {
push_callback(std::move(callback), real_path);
}
Expand Down Expand Up @@ -1813,11 +1821,12 @@ void MainBook::OnIdle(wxIdleEvent& event)
auto editor = GetActiveEditor();
CHECK_PTR_RET(editor);

execute_callbacks_for_file(CLRealPath(editor->GetFileName().GetFullPath()));
execute_callbacks_for_file(FileUtils::RealPath(editor->GetFileName().GetFullPath(), true));
}

void MainBook::OnEditorModified(clCommandEvent& event) { event.Skip(); }

void MainBook::OnEditorSaved(clCommandEvent& event) { event.Skip(); }

void MainBook::OnSessionLoaded(clCommandEvent& event) { event.Skip(); }
void MainBook::OnSessionLoaded(clCommandEvent& event) { event.Skip(); }

2 changes: 1 addition & 1 deletion Plugin/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ wxFileName wxReadLink(const wxFileName& filename)
if (wxIsFileSymlink(filename)) {
#if defined(__WXGTK__)
// Use 'realpath' on Linux, otherwise this breaks on relative symlinks, and (untested) on symlinks-to-symlinks
return wxFileName(CLRealPath(filename.GetFullPath()));
return wxFileName(FileUtils::RealPath(filename.GetFullPath(), true));

#else // OSX
wxFileName realFileName;
Expand Down
6 changes: 6 additions & 0 deletions Plugin/optionsconfig.cpp
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to avoid adding new entries to the OptionsConfig, please use clConfig instead where it makes sense. i.e. if the configuration entry is part of a "family" of entries that are already exist in OptionsConfig then it should go there, otherwise, we should use clConfig

Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ OptionsConfig::OptionsConfig(wxXmlNode* node)
, m_dontAutoFoldResults(true)
, m_dontOverrideSearchStringWithSelection(false)
, m_findNextOrPreviousUseSelection(true)
, m_realPathResolveSymlinks(true)
, m_showDebugOnRun(true)
, m_caretUseCamelCase(true)
, m_wordWrap(false)
Expand Down Expand Up @@ -211,6 +212,9 @@ OptionsConfig::OptionsConfig(wxXmlNode* node)
node, wxT("DontOverrideSearchStringWithSelection"), m_dontOverrideSearchStringWithSelection);
m_findNextOrPreviousUseSelection = XmlUtils::ReadBool(
node, wxT("FindNextOrPreviousUseSelection"), m_findNextOrPreviousUseSelection);
m_realPathResolveSymlinks = XmlUtils::ReadBool(
node, wxT("RealPathResolveSymlinks"), m_realPathResolveSymlinks);
FileUtils::RealPathSetModeResolveSymlinks(m_realPathResolveSymlinks);
m_showDebugOnRun = XmlUtils::ReadBool(node, wxT("ShowDebugOnRun"), m_showDebugOnRun);
m_caretUseCamelCase = XmlUtils::ReadBool(node, wxT("m_caretUseCamelCase"), m_caretUseCamelCase);
m_wordWrap = XmlUtils::ReadBool(node, wxT("m_wordWrap"), m_wordWrap);
Expand Down Expand Up @@ -315,6 +319,8 @@ wxXmlNode* OptionsConfig::ToXml() const
BoolToString(m_dontOverrideSearchStringWithSelection));
n->AddAttribute(wxT("FindNextOrPreviousUseSelection"),
BoolToString(m_findNextOrPreviousUseSelection));
n->AddAttribute(wxT("RealPathResolveSymlinks"),
BoolToString(m_realPathResolveSymlinks));
n->AddAttribute(wxT("ShowDebugOnRun"), BoolToString(m_showDebugOnRun));
n->AddAttribute(wxT("ConsoleCommand"), m_programConsoleCommand);
n->AddAttribute(wxT("EOLMode"), m_eolMode);
Expand Down
8 changes: 8 additions & 0 deletions Plugin/optionsconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "clEditorConfig.h"
#include "codelite_exports.h"
#include "configuration_object.h"
#include "fileutils.h"

#include <memory>
#include <wx/colour.h>
Expand Down Expand Up @@ -142,6 +143,7 @@ class WXDLLIMPEXP_SDK OptionsConfig : public ConfObject
bool m_dontAutoFoldResults;
bool m_dontOverrideSearchStringWithSelection;
bool m_findNextOrPreviousUseSelection;
bool m_realPathResolveSymlinks;
bool m_showDebugOnRun;
bool m_caretUseCamelCase;
bool m_dontTrimCaretLine;
Expand Down Expand Up @@ -232,6 +234,12 @@ class WXDLLIMPEXP_SDK OptionsConfig : public ConfObject
m_findNextOrPreviousUseSelection = findNextOrPreviousUseSelection;
}
bool GetFindNextOrPreviousUseSelection() const { return m_findNextOrPreviousUseSelection; }
void SetRealPathResolveSymlinks(bool realPathResolveSymlinks)
{
m_realPathResolveSymlinks = realPathResolveSymlinks;
FileUtils::RealPathSetModeResolveSymlinks(m_realPathResolveSymlinks);
}
bool GetRealPathResolveSymlinks() const { return m_realPathResolveSymlinks; }
void SetShowDebugOnRun(bool showDebugOnRun) { this->m_showDebugOnRun = showDebugOnRun; }
bool GetShowDebugOnRun() const { return m_showDebugOnRun; }
bool GetDisableSemicolonShift() const { return m_disableSemicolonShift; }
Expand Down
Loading