Author: Jonas Devlieghere Date: 2023-05-01T14:11:11-07:00 New Revision: b12b35ad4bec98c028a1926e4891e746b1f55d2f
URL: https://github.com/llvm/llvm-project/commit/b12b35ad4bec98c028a1926e4891e746b1f55d2f DIFF: https://github.com/llvm/llvm-project/commit/b12b35ad4bec98c028a1926e4891e746b1f55d2f.diff LOG: [lldb] Add debugger.external-editor setting Add a new setting (debugger.external-editor) to specify an external editor. The setting takes precedence over the existing LLDB_EXTERNAL_EDITOR environment variable. Differential revision: https://reviews.llvm.org/D149565 Added: lldb/test/Shell/Settings/TestExternalEditor.test Modified: lldb/include/lldb/Core/Debugger.h lldb/include/lldb/Host/Host.h lldb/source/Core/CoreProperties.td lldb/source/Core/Debugger.cpp lldb/source/Host/common/Host.cpp lldb/source/Host/macosx/objcxx/Host.mm lldb/source/Interpreter/CommandInterpreter.cpp lldb/source/Target/Thread.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 1d9d691bc2b06..12c1c046fbcef 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -293,9 +293,12 @@ class Debugger : public std::enable_shared_from_this<Debugger>, void SetPrompt(const char *) = delete; bool GetUseExternalEditor() const; - bool SetUseExternalEditor(bool use_external_editor_p); + llvm::StringRef GetExternalEditor() const; + + bool SetExternalEditor(llvm::StringRef editor); + bool GetUseColor() const; bool SetUseColor(bool use_color); diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h index 3fdf59dfb2324..30549cd789149 100644 --- a/lldb/include/lldb/Host/Host.h +++ b/lldb/include/lldb/Host/Host.h @@ -236,7 +236,8 @@ class Host { bool run_in_shell = true, bool hide_stderr = false); - static llvm::Error OpenFileInExternalEditor(const FileSpec &file_spec, + static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor, + const FileSpec &file_spec, uint32_t line_no); /// Check if we're running in an interactive graphical session. diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index 62729923f366b..ccee2a64fcbae 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -135,6 +135,10 @@ let Definition = "debugger" in { Global, DefaultFalse, Desc<"Whether to use an external editor or not.">; + def ExternalEditor: Property<"external-editor", "String">, + Global, + DefaultStringValue<"">, + Desc<"External editor to use when use-external-editor is enabled.">; def UseColor: Property<"use-color", "Boolean">, Global, DefaultTrue, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 581b29e6bc1ef..ee51dd75a9ff7 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -372,6 +372,16 @@ bool Debugger::SetUseExternalEditor(bool b) { return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); } +llvm::StringRef Debugger::GetExternalEditor() const { + const uint32_t idx = ePropertyExternalEditor; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + +bool Debugger::SetExternalEditor(llvm::StringRef editor) { + const uint32_t idx = ePropertyExternalEditor; + return m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, editor); +} + bool Debugger::GetUseColor() const { const uint32_t idx = ePropertyUseColor; return m_collection_sp->GetPropertyAtIndexAsBoolean( diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index c8ebb6f84c004..49eac0b0fa7b0 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -546,7 +546,8 @@ void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); } #endif #if !defined(__APPLE__) -llvm::Error Host::OpenFileInExternalEditor(const FileSpec &file_spec, +llvm::Error Host::OpenFileInExternalEditor(llvm::StringRef editor, + const FileSpec &file_spec, uint32_t line_no) { return llvm::errorCodeToError( std::error_code(ENOTSUP, std::system_category())); diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm index 848fa0d79f4da..5a151b9ecc8ff 100644 --- a/lldb/source/Host/macosx/objcxx/Host.mm +++ b/lldb/source/Host/macosx/objcxx/Host.mm @@ -325,7 +325,8 @@ repeat with the_window in (get windows)\n\ #endif // TARGET_OS_OSX -llvm::Error Host::OpenFileInExternalEditor(const FileSpec &file_spec, +llvm::Error Host::OpenFileInExternalEditor(llvm::StringRef editor, + const FileSpec &file_spec, uint32_t line_no) { #if !TARGET_OS_OSX return llvm::errorCodeToError( @@ -391,41 +392,36 @@ repeat with the_window in (get windows)\n\ auto on_exit = llvm::make_scope_exit( [&]() { AEDisposeDesc(&(file_and_line_desc.descContent)); }); - static std::optional<FSRef> g_app_fsref; - static std::string g_app_error; - static std::once_flag g_once_flag; - std::call_once(g_once_flag, [&]() { - if (const char *external_editor = ::getenv("LLDB_EXTERNAL_EDITOR")) { - LLDB_LOG(log, "Looking for external editor: {0}", external_editor); - - FSRef app_fsref; - CFCString editor_name(external_editor, kCFStringEncodingUTF8); - long app_error = ::LSFindApplicationForInfo( - /*inCreator=*/kLSUnknownCreator, /*inBundleID=*/NULL, - /*inName=*/editor_name.get(), /*outAppRef=*/&app_fsref, - /*outAppURL=*/NULL); - if (app_error == noErr) { - g_app_fsref = app_fsref; - } else { - g_app_error = - llvm::formatv("could not find external editor \"{0}\": " - "LSFindApplicationForInfo returned error {1}", - external_editor, app_error) - .str(); - } - } - }); + if (editor.empty()) { + if (const char *lldb_external_editor = ::getenv("LLDB_EXTERNAL_EDITOR")) + editor = lldb_external_editor; + } - if (!g_app_error.empty()) - return llvm::createStringError(llvm::inconvertibleErrorCode(), g_app_error); + std::optional<FSRef> app_fsref; + if (!editor.empty()) { + LLDB_LOG(log, "Looking for external editor: {0}", editor); + + app_fsref.emplace(); + CFCString editor_name(editor.data(), kCFStringEncodingUTF8); + long app_error = ::LSFindApplicationForInfo( + /*inCreator=*/kLSUnknownCreator, /*inBundleID=*/NULL, + /*inName=*/editor_name.get(), /*outAppRef=*/&(*app_fsref), + /*outAppURL=*/NULL); + if (app_error != noErr) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + llvm::formatv("could not find external editor \"{0}\": " + "LSFindApplicationForInfo returned error {1}", + editor, app_error)); + } // Build app launch parameters. LSApplicationParameters app_params; ::memset(&app_params, 0, sizeof(app_params)); app_params.flags = kLSLaunchDefaults | kLSLaunchDontAddToRecents | kLSLaunchDontSwitch; - if (g_app_fsref) - app_params.application = &(g_app_fsref.value()); + if (app_fsref) + app_params.application = &(*app_fsref); ProcessSerialNumber psn; std::array<CFURLRef, 1> file_array = {file_URL.get()}; diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index f89cff49f0aeb..ba6188430344c 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -3272,7 +3272,8 @@ bool CommandInterpreter::SaveTranscript( const FileSpec file_spec; error = file->GetFileSpec(const_cast<FileSpec &>(file_spec)); if (error.Success()) { - if (llvm::Error e = Host::OpenFileInExternalEditor(file_spec, 1)) + if (llvm::Error e = Host::OpenFileInExternalEditor( + m_debugger.GetExternalEditor(), file_spec, 1)) result.AppendError(llvm::toString(std::move(e))); } } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index fa4c2c6a3557c..c71e65398f103 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -303,10 +303,12 @@ bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx, bool already_shown = false; SymbolContext frame_sc( frame_sp->GetSymbolContext(eSymbolContextLineEntry)); - if (GetProcess()->GetTarget().GetDebugger().GetUseExternalEditor() && - frame_sc.line_entry.file && frame_sc.line_entry.line != 0) { + const Debugger &debugger = GetProcess()->GetTarget().GetDebugger(); + if (debugger.GetUseExternalEditor() && frame_sc.line_entry.file && + frame_sc.line_entry.line != 0) { if (llvm::Error e = Host::OpenFileInExternalEditor( - frame_sc.line_entry.file, frame_sc.line_entry.line)) { + debugger.GetExternalEditor(), frame_sc.line_entry.file, + frame_sc.line_entry.line)) { LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e), "OpenFileInExternalEditor failed: {0}"); } else { @@ -1731,6 +1733,7 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, frame_sp->GetSymbolContext(eSymbolContextLineEntry)); if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { if (llvm::Error e = Host::OpenFileInExternalEditor( + target->GetDebugger().GetExternalEditor(), frame_sc.line_entry.file, frame_sc.line_entry.line)) { LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e), "OpenFileInExternalEditor failed: {0}"); diff --git a/lldb/test/Shell/Settings/TestExternalEditor.test b/lldb/test/Shell/Settings/TestExternalEditor.test new file mode 100644 index 0000000000000..de0195ae8ac55 --- /dev/null +++ b/lldb/test/Shell/Settings/TestExternalEditor.test @@ -0,0 +1,4 @@ +REQUIRES: system-darwin +RUN: %lldb -o 'settings set use-external-editor true' -o 'setting set external-editor foo' -o 'session save' -b 2>&1 | FileCheck %s +RUN: LLDB_EXTERNAL_EDITOR="foo" %lldb -o 'settings set use-external-editor true' -o 'session save' -b 2>&1 | FileCheck %s +CHECK: error: could not find external editor "foo": LSFindApplicationForInfo returned error _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits