Allow to configure the AI Assistant Chat UI keybindings.

Allow to prefer the LSP formatter over the command line formatter in the formatter plugin, changed that option as the default for the cases where we use clangd (which fallbacks to clang-format but does diff the file).
This commit is contained in:
Martín Lucas Golini
2025-03-31 22:40:15 -03:00
parent 1a6d87d347
commit 473d4b48c9
7 changed files with 49 additions and 12 deletions

View File

@@ -16,7 +16,8 @@
"language": ["c", "cpp", "objective-c", "java"],
"file_patterns": ["%.inl$", "%.cpp$", "%.hpp$", "%.cc$", "%.cxx$", "%.c++$", "%.hh$", "%.hxx$", "%.h++$", "%.objcpp$", "%.m$", "%.java$"],
"command": "clang-format --style=file $FILENAME",
"url": "https://clang.llvm.org/docs/ClangFormat.html"
"url": "https://clang.llvm.org/docs/ClangFormat.html",
"prefer_lsp_formatter": true
},
{
"language": "python",
@@ -70,7 +71,8 @@
"file_patterns": ["%.zig$"],
"command": "zig fmt $FILENAME",
"type": "inplace",
"url": "https://ziglang.org"
"url": "https://ziglang.org",
"prefer_lsp_formatter": true
},
{
"language": "haskell",

View File

@@ -49,7 +49,7 @@ class EE_API TextDocument {
TextRange result{};
std::vector<TextRange> captures{};
bool isValid() const { return result.isValid(); }
bool operator==( const SearchResult& other ) {
bool operator==( const SearchResult& other ) const {
return result == other.result && captures == other.captures;
}
};

View File

@@ -19,7 +19,20 @@ using json = nlohmann::json;
namespace ecode {
static std::initializer_list<std::string> AIAssistantCommandList = {
"new-ai-assistant",
"ai-prompt",
"ai-add-chat",
"ai-chat-history",
"ai-clone-chat",
"ai-settings",
"ai-toggle-private-chat",
"ai-save-chat",
"ai-rename-chat",
"ai-show-menu",
"ai-chat-toggle-role",
"ai-refresh-local-models",
"new-ai-assistant"
};
static std::map<std::string, LLMProvider> parseLLMProviders( const nlohmann::json& j ) {
@@ -192,7 +205,7 @@ void AIAssistantPlugin::load( PluginManager* pluginManager ) {
FileSystem::fileGet( filePath, data );
if ( !data.empty() ) {
auto j = nlohmann::json::parse( data, nullptr, false );
if ( !j.empty() ){
if ( !j.empty() ) {
inputText = chatUI->unserialize( j );
}
}
@@ -285,6 +298,17 @@ void AIAssistantPlugin::loadAIAssistantConfig( const std::string& path, bool upd
if ( mKeyBindings.empty() ) {
mKeyBindings["new-ai-assistant"] = "mod+shift+m";
mKeyBindings["ai-prompt"] = "mod+return";
mKeyBindings["ai-add-chat"] = "mod+shift+return";
mKeyBindings["ai-chat-history"] = "mod+h";
mKeyBindings["ai-clone-chat"] = "mod+shift+c";
mKeyBindings["ai-settings"] = "mod+shift+s";
mKeyBindings["ai-toggle-private-chat"] = "mod+shift+p";
mKeyBindings["ai-save-chat"] = "mod+s";
mKeyBindings["ai-rename-chat"] = "f2";
mKeyBindings["ai-show-menu"] = "mod+m";
mKeyBindings["ai-chat-toggle-role"] = "mod+shift+r";
mKeyBindings["ai-refresh-local-models"] = "mod+shift+l";
}
auto& kb = j["keybindings"];
@@ -374,8 +398,10 @@ PluginRequestHandle AIAssistantPlugin::processMessage( const PluginMessage& msg
switch ( msg.type ) {
case ecode::PluginMessageType::UIReady: {
for ( const auto& kb : mKeyBindings ) {
getPluginContext()->getMainLayout()->getKeyBindings().addKeybindString( kb.second,
kb.first );
if ( !String::startsWith( kb.first, "ai-" ) ) {
getPluginContext()->getMainLayout()->getKeyBindings().addKeybindString(
kb.second, kb.first );
}
}
if ( !mUIInit )

View File

@@ -435,7 +435,12 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) :
but->setTooltipText( but->getTooltipText() + " (" + kb + ")" );
};
const auto addKb = [this]( const std::string& kb, const std::string& cmd ) {
const auto addKb = [this]( std::string kb, const std::string& cmd, bool searchDefined = true ) {
if ( searchDefined && getPlugin() ) {
const auto& find = getPlugin()->getKeybindings().find( cmd );
if ( find != getPlugin()->getKeybindings().end() && !find->second.empty() )
kb = find->second;
}
getKeyBindings().addKeybindString( kb, cmd );
mChatInput->addKeyBindingString( kb, cmd );
};
@@ -462,8 +467,8 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) :
appendShortcutToTooltip( mChatUserRole, "ai-chat-toggle-role" );
appendShortcutToTooltip( mRefreshModels, "ai-refresh-local-models" );
addKb( "mod+keypad enter", "ai-prompt" );
addKb( "mod+shift+keypad enter", "ai-add-chat" );
addKb( "mod+keypad enter", "ai-prompt", false );
addKb( "mod+shift+keypad enter", "ai-add-chat", false );
}
std::optional<LLMModel> LLMChatUI::getModel( const std::string& provider,

View File

@@ -237,6 +237,7 @@ void FormatterPlugin::loadFormatterConfig( const std::string& path, bool updateC
formatter.command = obj["command"].get<std::string>();
formatter.url = obj.value( "url", "" );
formatter.preferLSPFormatter = obj.value( "prefer_lsp_formatter", false );
if ( obj.contains( "type" ) ) {
std::string typeStr( obj["type"].get<std::string>() );
@@ -356,7 +357,7 @@ void FormatterPlugin::formatDoc( UICodeEditor* editor ) {
Clock clock;
std::shared_ptr<TextDocument> doc = editor->getDocumentRef();
auto formatter = supportsFormatter( doc );
if ( formatter.command.empty() ) {
if ( formatter.preferLSPFormatter || formatter.command.empty() ) {
if ( supportsLSPFormatter( doc ) )
formatDocWithLSP( doc );
return;

View File

@@ -29,12 +29,13 @@ class FormatterPlugin : public Plugin {
FormatterType type{ FormatterType::Output };
std::vector<std::string> languages{};
std::string url;
bool preferLSPFormatter{ false };
};
static PluginDefinition Definition() {
return {
"autoformatter", "Auto Formatter", "Enables the code formatter/prettifier plugin.",
FormatterPlugin::New, { 0, 2, 5 }, FormatterPlugin::NewSync };
FormatterPlugin::New, { 0, 2, 6 }, FormatterPlugin::NewSync };
}
static Plugin* New( PluginManager* pluginManager );

View File

@@ -93,6 +93,8 @@ class PluginBase : public Plugin {
virtual String::HashType getConfigFileHash() override { return mConfigHash; }
const std::map<std::string, std::string>& getKeybindings() { return mKeyBindings; }
protected:
//! Keep track of the registered editors + all the listeners registered to each editor
UnorderedMap<UICodeEditor*, std::vector<Uint32>> mEditors;