CompletionRequest.h revision 360784
140090Smsmith//===-- CompletionRequest.h -------------------------------------*- C++ -*-===// 240090Smsmith// 340090Smsmith// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 440090Smsmith// See https://llvm.org/LICENSE.txt for license information. 540090Smsmith// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 640090Smsmith// 740090Smsmith//===----------------------------------------------------------------------===// 840090Smsmith 940090Smsmith#ifndef LLDB_UTILITY_COMPLETIONREQUEST_H 1040090Smsmith#define LLDB_UTILITY_COMPLETIONREQUEST_H 1140090Smsmith 1240090Smsmith#include "lldb/Utility/Args.h" 1340090Smsmith#include "lldb/Utility/LLDBAssert.h" 1440090Smsmith#include "lldb/Utility/StringList.h" 1540090Smsmith#include "llvm/ADT/StringRef.h" 1640090Smsmith#include "llvm/ADT/StringSet.h" 1740090Smsmith 1840090Smsmithnamespace lldb_private { 1940090Smsmithenum class CompletionMode { 2040090Smsmith // The current token has been completed. 2140090Smsmith Normal, 2240090Smsmith // The current token has been partially completed. This means that we found 2340090Smsmith // a completion, but that the completed token is still incomplete. Examples 2440090Smsmith // for this are file paths, where we want to complete "/bi" to "/bin/", but 2540116Sjkh // the file path token is still incomplete after the completion. Clients 2640090Smsmith // should not indicate to the user that this is a full completion (e.g. by 2740090Smsmith // not inserting the usual trailing space after a successful completion). 2840090Smsmith Partial, 2994936Smux // The full line has been rewritten by the completion. 3094936Smux RewriteLine, 3140090Smsmith}; 3294936Smux 3394936Smuxclass CompletionResult { 3494936Smuxpublic: 3540090Smsmith /// A single completion and all associated data. 3640090Smsmith class Completion { 37116182Sobrien 38116182Sobrien std::string m_completion; 39116182Sobrien std::string m_descripton; 4094936Smux CompletionMode m_mode; 4140090Smsmith 4294936Smux public: 4394936Smux Completion(llvm::StringRef completion, llvm::StringRef description, 4494936Smux CompletionMode mode) 4594936Smux : m_completion(completion.str()), m_descripton(description.str()), 4694936Smux m_mode(mode) {} 47164033Srwatson const std::string &GetCompletion() const { return m_completion; } 4840090Smsmith const std::string &GetDescription() const { return m_descripton; } 4940090Smsmith CompletionMode GetMode() const { return m_mode; } 5094936Smux 5194936Smux /// Generates a string that uniquely identifies this completion result. 5240090Smsmith std::string GetUniqueKey() const; 5394936Smux }; 5440090Smsmith 55163606Srwatsonprivate: 56163606Srwatson std::vector<Completion> m_results; 57141616Sphk 5840090Smsmith /// List of added completions so far. Used to filter out duplicates. 5994936Smux llvm::StringSet<> m_added_values; 6040090Smsmith 6194936Smuxpublic: 6294936Smux void AddResult(llvm::StringRef completion, llvm::StringRef description, 63202050Simp CompletionMode mode); 64202050Simp 6594936Smux llvm::ArrayRef<Completion> GetResults() const { return m_results; } 6694936Smux 6794936Smux /// Adds all collected completion matches to the given list. 6894936Smux /// The list will be cleared before the results are added. The number of 69160217Sscottl /// results here is guaranteed to be equal to GetNumberOfResults(). 7094936Smux void GetMatches(StringList &matches) const; 7185385Sjhb 72167232Srwatson /// Adds all collected completion descriptions to the given list. 7394936Smux /// The list will be cleared before the results are added. The number of 7494936Smux /// results here is guaranteed to be equal to GetNumberOfResults(). 7594936Smux void GetDescriptions(StringList &descriptions) const; 7694936Smux 7794936Smux std::size_t GetNumberOfResults() const { return m_results.size(); } 7894936Smux}; 7994936Smux 8094936Smux/// \class CompletionRequest CompletionRequest.h 8194936Smux/// "lldb/Utility/ArgCompletionRequest.h" 8294936Smux/// 83107850Salfred/// Contains all information necessary to complete an incomplete command 84107850Salfred/// for the user. Will be filled with the generated completions by the different 85107850Salfred/// completions functions. 86107850Salfred/// 8794936Smuxclass CompletionRequest { 8894936Smuxpublic: 89160217Sscottl /// Constructs a completion request. 90190301Scperciva /// 9194936Smux /// \param [in] command_line 9295839Speter /// The command line the user has typed at this point. 9394936Smux /// 9494936Smux /// \param [in] raw_cursor_pos 9594936Smux /// The position of the cursor in the command line string. Index 0 means 96107849Salfred /// the cursor is at the start of the line. The completion starts from 97106308Srwatson /// this cursor position. 98172930Srwatson /// 99106308Srwatson /// \param [out] result 100106308Srwatson /// The CompletionResult that will be filled with the results after this 101106308Srwatson /// request has been handled. 102128697Sdas CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, 103190301Scperciva CompletionResult &result); 104190301Scperciva 105190301Scperciva llvm::StringRef GetRawLine() const { return m_command; } 106190301Scperciva 107160217Sscottl unsigned GetRawCursorPos() const { return m_raw_cursor_pos; } 108190301Scperciva 109160217Sscottl const Args &GetParsedLine() const { return m_parsed_line; } 110128697Sdas 111128697Sdas Args &GetParsedLine() { return m_parsed_line; } 112128697Sdas 113190301Scperciva const Args::ArgEntry &GetParsedArg() { 114128697Sdas return GetParsedLine()[GetCursorIndex()]; 115128697Sdas } 116128697Sdas 117128697Sdas /// Drops the first argument from the argument list. 118160217Sscottl void ShiftArguments() { 119160217Sscottl m_cursor_index--; 120128697Sdas m_parsed_line.Shift(); 12194936Smux } 12294936Smux 123160217Sscottl /// Adds an empty argument at the end of the argument list and moves 124160217Sscottl /// the cursor to this new argument. 125160217Sscottl void AppendEmptyArgument() { 126160217Sscottl m_parsed_line.AppendArgument(llvm::StringRef()); 127160217Sscottl m_cursor_index++; 128128697Sdas m_cursor_char_position = 0; 129128697Sdas } 13094936Smux 13194936Smux size_t GetCursorIndex() const { return m_cursor_index; } 132164033Srwatson 133164033Srwatson /// Adds a possible completion string. If the completion was already 134164033Srwatson /// suggested before, it will not be added to the list of results. A copy of 13594936Smux /// the suggested completion is stored, so the given string can be free'd 13694936Smux /// afterwards. 137164033Srwatson /// 138164033Srwatson /// \param match The suggested completion. 139164033Srwatson /// \param completion An optional description of the completion string. The 140164033Srwatson /// description will be displayed to the user alongside the completion. 141164033Srwatson /// \param mode The CompletionMode for this completion. 142164033Srwatson void AddCompletion(llvm::StringRef completion, 143164033Srwatson llvm::StringRef description = "", 14494936Smux CompletionMode mode = CompletionMode::Normal) { 14594936Smux m_result.AddResult(completion, description, mode); 146111119Simp } 14794936Smux 148107849Salfred /// Adds a possible completion string if the completion would complete the 14994936Smux /// current argument. 15094936Smux /// 15194936Smux /// \param match The suggested completion. 152107849Salfred /// \param description An optional description of the completion string. The 15394936Smux /// description will be displayed to the user alongside the completion. 154106308Srwatson template <CompletionMode M = CompletionMode::Normal> 155172930Srwatson void TryCompleteCurrentArg(llvm::StringRef completion, 156106308Srwatson llvm::StringRef description = "") { 157106308Srwatson // Trying to rewrite the whole line while checking for the current 158106308Srwatson // argument never makes sense. Completion modes are always hardcoded, so 15994936Smux // this can be a static_assert. 16094936Smux static_assert(M != CompletionMode::RewriteLine, 16194936Smux "Shouldn't rewrite line with this function"); 16294936Smux if (completion.startswith(GetCursorArgumentPrefix())) 16394936Smux AddCompletion(completion, description, M); 16494936Smux } 165107849Salfred 166107849Salfred /// Adds multiple possible completion strings. 167107849Salfred /// 16894936Smux /// \param completions The list of completions. 16994936Smux /// 17094936Smux /// \see AddCompletion 17194936Smux void AddCompletions(const StringList &completions) { 17294936Smux for (const std::string &completion : completions) 17394936Smux AddCompletion(completion); 174107849Salfred } 17594936Smux 17694936Smux /// Adds multiple possible completion strings alongside their descriptions. 17794936Smux /// 17894936Smux /// The number of completions and descriptions must be identical. 17994936Smux /// 18094936Smux /// \param completions The list of completions. 181111119Simp /// \param completions The list of descriptions. 182107849Salfred /// 18394936Smux /// \see AddCompletion 18494936Smux void AddCompletions(const StringList &completions, 18594936Smux const StringList &descriptions) { 18694936Smux lldbassert(completions.GetSize() == descriptions.GetSize()); 187106308Srwatson for (std::size_t i = 0; i < completions.GetSize(); ++i) 188172930Srwatson AddCompletion(completions.GetStringAtIndex(i), 189106308Srwatson descriptions.GetStringAtIndex(i)); 190106308Srwatson } 191106308Srwatson 19294936Smux llvm::StringRef GetCursorArgumentPrefix() const { 19394936Smux return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); 19494936Smux } 195106308Srwatson 196172930Srwatsonprivate: 197106308Srwatson /// The raw command line we are supposed to complete. 198106308Srwatson llvm::StringRef m_command; 199106308Srwatson /// The cursor position in m_command. 20094936Smux unsigned m_raw_cursor_pos; 20194936Smux /// The command line parsed as arguments. 20294936Smux Args m_parsed_line; 20394936Smux /// The index of the argument in which the completion cursor is. 20494936Smux size_t m_cursor_index; 20594936Smux /// The cursor position in the argument indexed by m_cursor_index. 20694936Smux size_t m_cursor_char_position; 20794936Smux 20894936Smux /// The result this request is supposed to fill out. 20994936Smux /// We keep this object private to ensure that no backend can in any way 21094936Smux /// depend on already calculated completions (which would make debugging and 21194936Smux /// testing them much more complicated). 21294936Smux CompletionResult &m_result; 213202050Simp}; 214202050Simp 215202050Simp} // namespace lldb_private 216202050Simp 217202050Simp#endif // LLDB_UTILITY_COMPLETIONREQUEST_H 218202050Simp