mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-03 22:04:24 +00:00 
			
		
		
		
	Implement textDocument/documentHighlight
This commit is contained in:
		
							parent
							
								
									20bf746ee9
								
							
						
					
					
						commit
						71d1b1ffc6
					
				@ -538,6 +538,7 @@ std::unique_ptr<IpcMessageQueue> BuildIpcMessageQueue(const std::string& name, s
 | 
			
		||||
  RegisterId<Ipc_TextDocumentDidSave>(ipc.get());
 | 
			
		||||
  RegisterId<Ipc_TextDocumentComplete>(ipc.get());
 | 
			
		||||
  RegisterId<Ipc_TextDocumentDefinition>(ipc.get());
 | 
			
		||||
  RegisterId<Ipc_TextDocumentDocumentHighlight>(ipc.get());
 | 
			
		||||
  RegisterId<Ipc_TextDocumentHover>(ipc.get());
 | 
			
		||||
  RegisterId<Ipc_TextDocumentReferences>(ipc.get());
 | 
			
		||||
  RegisterId<Ipc_TextDocumentDocumentSymbol>(ipc.get());
 | 
			
		||||
@ -561,6 +562,7 @@ void RegisterMessageTypes() {
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentDidSave>();
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentComplete>();
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentDefinition>();
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentHighlight>();
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentHover>();
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentReferences>();
 | 
			
		||||
  MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentSymbol>();
 | 
			
		||||
@ -918,6 +920,49 @@ void QueryDbMainLoop(
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case IpcId::TextDocumentDocumentHighlight: {
 | 
			
		||||
      auto msg = static_cast<Ipc_TextDocumentDocumentHighlight*>(message.get());
 | 
			
		||||
 | 
			
		||||
      QueryFileId file_id;
 | 
			
		||||
      QueryableFile* file = FindFile(db, msg->params.textDocument.uri.GetPath(), &file_id);
 | 
			
		||||
      if (!file) {
 | 
			
		||||
        std::cerr << "Unable to find file " << msg->params.textDocument.uri.GetPath() << std::endl;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      Out_TextDocumentDocumentHighlight response;
 | 
			
		||||
      response.id = msg->id;
 | 
			
		||||
 | 
			
		||||
      // TODO: consider refactoring into FindSymbolsAtLocation(file);
 | 
			
		||||
      int target_line = msg->params.position.line + 1;
 | 
			
		||||
      int target_column = msg->params.position.character + 1;
 | 
			
		||||
      for (const SymbolRef& ref : file->def.all_symbols) {
 | 
			
		||||
        if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
 | 
			
		||||
          ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
 | 
			
		||||
 | 
			
		||||
          // Found symbol. Return references to highlight.
 | 
			
		||||
          std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
 | 
			
		||||
          response.result.reserve(uses.size());
 | 
			
		||||
          for (const QueryableLocation& use : uses) {
 | 
			
		||||
            if (use.path != file_id)
 | 
			
		||||
              continue;
 | 
			
		||||
 | 
			
		||||
            optional<lsLocation> ls_location = GetLsLocation(db, working_files, use);
 | 
			
		||||
            if (!ls_location)
 | 
			
		||||
              continue;
 | 
			
		||||
 | 
			
		||||
            lsDocumentHighlight highlight;
 | 
			
		||||
            highlight.kind = lsDocumentHighlightKind::Text;
 | 
			
		||||
            highlight.range = ls_location->range;
 | 
			
		||||
            response.result.push_back(highlight);
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      SendOutMessageToClient(language_client, response);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case IpcId::TextDocumentHover: {
 | 
			
		||||
      auto msg = static_cast<Ipc_TextDocumentHover*>(message.get());
 | 
			
		||||
 | 
			
		||||
@ -929,13 +974,14 @@ void QueryDbMainLoop(
 | 
			
		||||
      Out_TextDocumentHover response;
 | 
			
		||||
      response.id = msg->id;
 | 
			
		||||
 | 
			
		||||
      // TODO: consider refactoring into FindSymbolsAtLocation(file);
 | 
			
		||||
      int target_line = msg->params.position.line + 1;
 | 
			
		||||
      int target_column = msg->params.position.character + 1;
 | 
			
		||||
      for (const SymbolRef& ref : file->def.all_symbols) {
 | 
			
		||||
        if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
 | 
			
		||||
          ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
 | 
			
		||||
 | 
			
		||||
          // Found symbol. Return references.
 | 
			
		||||
          // Found symbol. Return hover.
 | 
			
		||||
          optional<lsRange> ls_range = GetLsRange(working_files->GetFileByFilename(file->def.usr), ref.loc.range);
 | 
			
		||||
          if (!ls_range)
 | 
			
		||||
            continue;
 | 
			
		||||
@ -1282,8 +1328,8 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
 | 
			
		||||
      response.result.capabilities.codeLensProvider->resolveProvider = false;
 | 
			
		||||
 | 
			
		||||
      response.result.capabilities.definitionProvider = true;
 | 
			
		||||
      response.result.capabilities.documentHighlightProvider = true;
 | 
			
		||||
      response.result.capabilities.hoverProvider = true;
 | 
			
		||||
 | 
			
		||||
      response.result.capabilities.referencesProvider = true;
 | 
			
		||||
 | 
			
		||||
      response.result.capabilities.documentSymbolProvider = true;
 | 
			
		||||
@ -1310,6 +1356,7 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
 | 
			
		||||
    case IpcId::TextDocumentDidSave:
 | 
			
		||||
    case IpcId::TextDocumentCompletion:
 | 
			
		||||
    case IpcId::TextDocumentDefinition:
 | 
			
		||||
    case IpcId::TextDocumentDocumentHighlight:
 | 
			
		||||
    case IpcId::TextDocumentHover:
 | 
			
		||||
    case IpcId::TextDocumentReferences:
 | 
			
		||||
    case IpcId::TextDocumentDocumentSymbol:
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,10 @@ bool operator==(const Id<T>& a, const Id<T>& b) {
 | 
			
		||||
  assert(a.group == b.group && "Cannot compare Ids from different groups");
 | 
			
		||||
  return a.id == b.id;
 | 
			
		||||
}
 | 
			
		||||
template <typename T>
 | 
			
		||||
bool operator!=(const Id<T>& a, const Id<T>& b) {
 | 
			
		||||
  return !(a == b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using IndexTypeId = Id<IndexedTypeDef>;
 | 
			
		||||
using IndexFuncId = Id<IndexedFuncDef>;
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,8 @@ const char* IpcIdToString(IpcId id) {
 | 
			
		||||
    return "textDocument/completion";
 | 
			
		||||
  case IpcId::TextDocumentDefinition:
 | 
			
		||||
    return "textDocument/definition";
 | 
			
		||||
  case IpcId::TextDocumentDocumentHighlight:
 | 
			
		||||
    return "textDocument/documentHighlight";
 | 
			
		||||
  case IpcId::TextDocumentHover:
 | 
			
		||||
    return "textDocument/hover";
 | 
			
		||||
  case IpcId::TextDocumentReferences:
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ enum class IpcId : int {
 | 
			
		||||
  TextDocumentDidSave,
 | 
			
		||||
  TextDocumentCompletion,
 | 
			
		||||
  TextDocumentDefinition,
 | 
			
		||||
  TextDocumentDocumentHighlight,
 | 
			
		||||
  TextDocumentHover,
 | 
			
		||||
  TextDocumentReferences,
 | 
			
		||||
  TextDocumentDocumentSymbol,
 | 
			
		||||
 | 
			
		||||
@ -166,6 +166,11 @@ std::string lsDocumentUri::GetPath() const {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::replace(result.begin(), result.end(), '\\', '/');
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
  //std::transform(result.begin(), result.end(), result.begin(), ::tolower);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -488,6 +488,29 @@ struct lsTextDocumentEdit {
 | 
			
		||||
};
 | 
			
		||||
MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits);
 | 
			
		||||
 | 
			
		||||
// A document highlight kind.
 | 
			
		||||
enum class lsDocumentHighlightKind {
 | 
			
		||||
  // A textual occurrence.
 | 
			
		||||
  Text = 1,
 | 
			
		||||
  // Read-access of a symbol, like reading a variable.
 | 
			
		||||
  Read = 2,
 | 
			
		||||
  // Write-access of a symbol, like writing to a variable.
 | 
			
		||||
  Write = 3
 | 
			
		||||
};
 | 
			
		||||
MAKE_REFLECT_TYPE_PROXY(lsDocumentHighlightKind, int);
 | 
			
		||||
 | 
			
		||||
// A document highlight is a range inside a text document which deserves
 | 
			
		||||
// special attention. Usually a document highlight is visualized by changing
 | 
			
		||||
// the background color of its range.
 | 
			
		||||
struct lsDocumentHighlight {
 | 
			
		||||
	// The range this highlight applies to.
 | 
			
		||||
	lsRange range;
 | 
			
		||||
 | 
			
		||||
	// The highlight kind, default is DocumentHighlightKind.Text.
 | 
			
		||||
  lsDocumentHighlightKind kind = lsDocumentHighlightKind::Text;
 | 
			
		||||
};
 | 
			
		||||
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind);
 | 
			
		||||
 | 
			
		||||
// TODO: WorkspaceEdit
 | 
			
		||||
// TODO: DocumentFilter
 | 
			
		||||
// TODO: DocumentSelector
 | 
			
		||||
@ -1131,6 +1154,20 @@ struct Out_TextDocumentDefinition : public lsOutMessage<Out_TextDocumentDefiniti
 | 
			
		||||
};
 | 
			
		||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
 | 
			
		||||
 | 
			
		||||
// Document highlight
 | 
			
		||||
struct Ipc_TextDocumentDocumentHighlight : public IpcMessage<Ipc_TextDocumentDocumentHighlight> {
 | 
			
		||||
  const static IpcId kIpcId = IpcId::TextDocumentDocumentHighlight;
 | 
			
		||||
 | 
			
		||||
  lsRequestId id;
 | 
			
		||||
  lsTextDocumentPositionParams params;
 | 
			
		||||
};
 | 
			
		||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentHighlight, id, params);
 | 
			
		||||
struct Out_TextDocumentDocumentHighlight : public lsOutMessage<Out_TextDocumentDocumentHighlight> {
 | 
			
		||||
  lsRequestId id;
 | 
			
		||||
  NonElidedVector<lsDocumentHighlight> result;
 | 
			
		||||
};
 | 
			
		||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result);
 | 
			
		||||
 | 
			
		||||
// Hover
 | 
			
		||||
struct Ipc_TextDocumentHover : public IpcMessage<Ipc_TextDocumentHover> {
 | 
			
		||||
  const static IpcId kIpcId = IpcId::TextDocumentHover;
 | 
			
		||||
 | 
			
		||||
@ -141,6 +141,7 @@ std::string NormalizePath(const std::string& path) {
 | 
			
		||||
 | 
			
		||||
  std::string result = buffer;
 | 
			
		||||
  std::replace(result.begin(), result.end(), '\\', '/');
 | 
			
		||||
  //std::transform(result.begin(), result.end(), result.begin(), ::tolower);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user