[gnome-builder: 32/139] libide-lsp: break language server code into static library



commit 7f33e2225f6d05f7638e8937887a61f2cf088f2c
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jan 9 16:02:25 2019 -0800

    libide-lsp: break language server code into static library
    
    This moves the language server code into a new library and renames it's
    prefix into IdeLsp. It also refactors things to conform to the new libide
    designs elsewhere in Builder.

 .../langserv/ide-langserv-diagnostic-provider.c    | 257 -----------
 src/libide/langserv/ide-langserv-symbol-tree.c     | 193 --------
 src/libide/langserv/ide-langserv-util.c            |  80 ----
 src/libide/langserv/meson.build                    |  44 --
 .../ide-langserv-client.c => lsp/ide-lsp-client.c} | 486 ++++++++++-----------
 .../ide-langserv-client.h => lsp/ide-lsp-client.h} |  52 +--
 .../ide-lsp-completion-item.c}                     |  68 ++-
 .../ide-lsp-completion-item.h}                     |  25 +-
 .../ide-lsp-completion-provider.c}                 | 181 ++++----
 .../ide-lsp-completion-provider.h}                 |  25 +-
 .../ide-lsp-completion-results.c}                  |  65 ++-
 .../ide-lsp-completion-results.h}                  |  14 +-
 src/libide/lsp/ide-lsp-diagnostic-provider.c       | 253 +++++++++++
 .../ide-lsp-diagnostic-provider.h}                 |  28 +-
 .../ide-lsp-formatter.c}                           | 239 +++++-----
 .../ide-lsp-formatter.h}                           |  24 +-
 .../ide-lsp-highlighter.c}                         | 157 ++++---
 .../ide-lsp-highlighter.h}                         |  29 +-
 .../ide-lsp-hover-provider.c}                      | 175 ++++----
 .../ide-lsp-hover-provider.h}                      |  24 +-
 .../ide-lsp-rename-provider.c}                     | 155 +++----
 .../ide-lsp-rename-provider.h}                     |  32 +-
 .../ide-lsp-symbol-node-private.h}                 |   9 +-
 .../ide-lsp-symbol-node.c}                         |  98 ++---
 .../ide-lsp-symbol-node.h}                         |  18 +-
 .../ide-lsp-symbol-resolver.c}                     | 242 +++++-----
 .../ide-lsp-symbol-resolver.h}                     |  32 +-
 .../ide-lsp-symbol-tree-private.h}                 |   6 +-
 src/libide/lsp/ide-lsp-symbol-tree.c               | 190 ++++++++
 .../ide-lsp-symbol-tree.h}                         |  12 +-
 .../ide-langserv-types.h => lsp/ide-lsp-types.h}   |   4 +
 src/libide/lsp/ide-lsp-util.c                      |  80 ++++
 .../ide-langserv-util.h => lsp/ide-lsp-util.h}     |  12 +-
 src/libide/lsp/libide-lsp.h                        |  42 ++
 src/libide/lsp/meson.build                         |  94 ++++
 35 files changed, 1720 insertions(+), 1725 deletions(-)
---
diff --git a/src/libide/langserv/ide-langserv-client.c b/src/libide/lsp/ide-lsp-client.c
similarity index 65%
rename from src/libide/langserv/ide-langserv-client.c
rename to src/libide/lsp/ide-lsp-client.c
index 54de50392..8d9e2485c 100644
--- a/src/libide/langserv/ide-langserv-client.c
+++ b/src/libide/lsp/ide-lsp-client.c
@@ -1,4 +1,4 @@
-/* ide-langserv-client.c
+/* ide-lsp-client.c
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,7 +18,7 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-client"
+#define G_LOG_DOMAIN "ide-lsp-client"
 
 #include "config.h"
 
@@ -26,23 +26,13 @@
 #include <dazzle.h>
 #include <glib/gi18n.h>
 #include <jsonrpc-glib.h>
+#include <libide-code.h>
+#include <libide-projects.h>
+#include <libide-sourceview.h>
+#include <libide-threading.h>
 #include <unistd.h>
 
-#include "ide-context.h"
-#include "ide-debug.h"
-
-#include "application/ide-application.h"
-#include "buffers/ide-buffer.h"
-#include "buffers/ide-buffer-manager.h"
-#include "diagnostics/ide-diagnostic.h"
-#include "diagnostics/ide-diagnostics.h"
-#include "diagnostics/ide-source-location.h"
-#include "diagnostics/ide-source-range.h"
-#include "langserv/ide-langserv-client.h"
-#include "projects/ide-project.h"
-#include "vcs/ide-vcs.h"
-#include "threading/ide-task.h"
-#include "util/ide-glib.h"
+#include "ide-lsp-client.h"
 
 typedef struct
 {
@@ -52,9 +42,9 @@ typedef struct
   GIOStream      *io_stream;
   GHashTable     *diagnostics_by_file;
   GPtrArray      *languages;
-} IdeLangservClientPrivate;
+} IdeLspClientPrivate;
 
-G_DEFINE_TYPE_WITH_PRIVATE (IdeLangservClient, ide_langserv_client, IDE_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (IdeLspClient, ide_lsp_client, IDE_TYPE_OBJECT)
 
 enum {
   FILE_CHANGE_TYPE_CREATED = 1,
@@ -86,7 +76,7 @@ static GParamSpec *properties [N_PROPS];
 static guint signals [N_SIGNALS];
 
 static gboolean
-ide_langserv_client_supports_buffer (IdeLangservClient *self,
+ide_lsp_client_supports_buffer (IdeLspClient *self,
                                      IdeBuffer         *buffer)
 {
   GtkSourceLanguage *language;
@@ -94,7 +84,7 @@ ide_langserv_client_supports_buffer (IdeLangservClient *self,
   gboolean ret = FALSE;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (IDE_IS_BUFFER (buffer));
 
   language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
@@ -107,16 +97,16 @@ ide_langserv_client_supports_buffer (IdeLangservClient *self,
 }
 
 static void
-ide_langserv_client_clear_diagnostics (IdeLangservClient *self,
-                                       const gchar       *uri)
+ide_lsp_client_clear_diagnostics (IdeLspClient *self,
+                                  const gchar  *uri)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(GFile) file = NULL;
 
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (uri != NULL);
 
   IDE_TRACE_MSG ("Clearing diagnostics for %s", uri);
@@ -128,9 +118,9 @@ ide_langserv_client_clear_diagnostics (IdeLangservClient *self,
 }
 
 static void
-ide_langserv_client_buffer_saved (IdeLangservClient *self,
-                                  IdeBuffer         *buffer,
-                                  IdeBufferManager  *buffer_manager)
+ide_lsp_client_buffer_saved (IdeLspClient     *self,
+                             IdeBuffer        *buffer,
+                             IdeBufferManager *buffer_manager)
 {
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
@@ -138,14 +128,14 @@ ide_langserv_client_buffer_saved (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
 
-  if (!ide_langserv_client_supports_buffer (self, buffer))
+  if (!ide_lsp_client_supports_buffer (self, buffer))
     IDE_EXIT;
 
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
 
   params = JSONRPC_MESSAGE_NEW (
     "textDocument", "{",
@@ -153,8 +143,7 @@ ide_langserv_client_buffer_saved (IdeLangservClient *self,
     "}"
   );
 
-  ide_langserv_client_send_notification_async (self, "textDocument/didSave",
-                                               params, NULL, NULL, NULL);
+  ide_lsp_client_send_notification_async (self, "textDocument/didSave", params, NULL, NULL, NULL);
 
   IDE_EXIT;
 }
@@ -165,11 +154,11 @@ ide_langserv_client_buffer_saved (IdeLangservClient *self,
  */
 
 static void
-ide_langserv_client_buffer_insert_text (IdeLangservClient *self,
-                                        GtkTextIter       *location,
-                                        const gchar       *new_text,
-                                        gint               len,
-                                        IdeBuffer         *buffer)
+ide_lsp_client_buffer_insert_text (IdeLspClient *self,
+                                   GtkTextIter  *location,
+                                   const gchar  *new_text,
+                                   gint          len,
+                                   IdeBuffer    *buffer)
 {
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
@@ -181,13 +170,13 @@ ide_langserv_client_buffer_insert_text (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (location != NULL);
   g_assert (IDE_IS_BUFFER (buffer));
 
   copy = g_strndup (new_text, len);
 
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
   version = (gint64)ide_buffer_get_change_count (buffer);
 
   line = gtk_text_iter_get_line (location);
@@ -215,14 +204,14 @@ ide_langserv_client_buffer_insert_text (IdeLangservClient *self,
       "}",
     "]");
 
-  ide_langserv_client_send_notification_async (self, "textDocument/didChange",
+  ide_lsp_client_send_notification_async (self, "textDocument/didChange",
                                                params, NULL, NULL, NULL);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_buffer_delete_range (IdeLangservClient *self,
+ide_lsp_client_buffer_delete_range (IdeLspClient *self,
                                          GtkTextIter       *begin_iter,
                                          GtkTextIter       *end_iter,
                                          IdeBuffer         *buffer)
@@ -242,12 +231,12 @@ ide_langserv_client_buffer_delete_range (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (begin_iter != NULL);
   g_assert (end_iter != NULL);
   g_assert (IDE_IS_BUFFER (buffer));
 
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
   version = (gint)ide_buffer_get_change_count (buffer);
 
   copy_begin = *begin_iter;
@@ -284,14 +273,14 @@ ide_langserv_client_buffer_delete_range (IdeLangservClient *self,
       "}",
     "]");
 
-  ide_langserv_client_send_notification_async (self, "textDocument/didChange",
+  ide_lsp_client_send_notification_async (self, "textDocument/didChange",
                                                params, NULL, NULL, NULL);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_buffer_loaded (IdeLangservClient *self,
+ide_lsp_client_buffer_loaded (IdeLspClient *self,
                                    IdeBuffer         *buffer,
                                    IdeBufferManager  *buffer_manager)
 {
@@ -307,26 +296,26 @@ ide_langserv_client_buffer_loaded (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
 
-  if (!ide_langserv_client_supports_buffer (self, buffer))
+  if (!ide_lsp_client_supports_buffer (self, buffer))
     IDE_EXIT;
 
   g_signal_connect_object (buffer,
                            "insert-text",
-                           G_CALLBACK (ide_langserv_client_buffer_insert_text),
+                           G_CALLBACK (ide_lsp_client_buffer_insert_text),
                            self,
                            G_CONNECT_SWAPPED);
 
   g_signal_connect_object (buffer,
                            "delete-range",
-                           G_CALLBACK (ide_langserv_client_buffer_delete_range),
+                           G_CALLBACK (ide_lsp_client_buffer_delete_range),
                            self,
                            G_CONNECT_SWAPPED);
 
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
   version = (gint64)ide_buffer_get_change_count (buffer);
 
   gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &begin, &end);
@@ -347,14 +336,14 @@ ide_langserv_client_buffer_loaded (IdeLangservClient *self,
     "}"
   );
 
-  ide_langserv_client_send_notification_async (self, "textDocument/didOpen",
+  ide_lsp_client_send_notification_async (self, "textDocument/didOpen",
                                                params, NULL, NULL, NULL);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_buffer_unloaded (IdeLangservClient *self,
+ide_lsp_client_buffer_unloaded (IdeLspClient *self,
                                      IdeBuffer         *buffer,
                                      IdeBufferManager  *buffer_manager)
 {
@@ -364,14 +353,14 @@ ide_langserv_client_buffer_unloaded (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
 
-  if (!ide_langserv_client_supports_buffer (self, buffer))
+  if (!ide_lsp_client_supports_buffer (self, buffer))
     IDE_EXIT;
 
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
 
   params = JSONRPC_MESSAGE_NEW (
     "textDocument", "{",
@@ -379,21 +368,21 @@ ide_langserv_client_buffer_unloaded (IdeLangservClient *self,
     "}"
   );
 
-  ide_langserv_client_send_notification_async (self, "textDocument/didClose",
+  ide_lsp_client_send_notification_async (self, "textDocument/didClose",
                                                params, NULL, NULL, NULL);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_buffer_manager_bind (IdeLangservClient *self,
+ide_lsp_client_buffer_manager_bind (IdeLspClient *self,
                                          IdeBufferManager  *buffer_manager,
                                          DzlSignalGroup    *signal_group)
 {
   guint n_items;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
   g_assert (DZL_IS_SIGNAL_GROUP (signal_group));
 
@@ -404,15 +393,15 @@ ide_langserv_client_buffer_manager_bind (IdeLangservClient *self,
       g_autoptr(IdeBuffer) buffer = NULL;
 
       buffer = g_list_model_get_item (G_LIST_MODEL (buffer_manager), i);
-      ide_langserv_client_buffer_loaded (self, buffer, buffer_manager);
+      ide_lsp_client_buffer_loaded (self, buffer, buffer_manager);
     }
 }
 
 static void
-ide_langserv_client_buffer_manager_unbind (IdeLangservClient *self,
+ide_lsp_client_buffer_manager_unbind (IdeLspClient *self,
                                            DzlSignalGroup    *signal_group)
 {
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (DZL_IS_SIGNAL_GROUP (signal_group));
 
   /* TODO: We need to track everything we've notified so that we
@@ -421,7 +410,7 @@ ide_langserv_client_buffer_manager_unbind (IdeLangservClient *self,
 }
 
 static void
-ide_langserv_client_project_file_trashed (IdeLangservClient *self,
+ide_lsp_client_project_file_trashed (IdeLspClient *self,
                                           GFile             *file,
                                           IdeProject        *project)
 {
@@ -431,7 +420,7 @@ ide_langserv_client_project_file_trashed (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (G_IS_FILE (file));
   g_assert (IDE_IS_PROJECT (project));
 
@@ -446,19 +435,19 @@ ide_langserv_client_project_file_trashed (IdeLangservClient *self,
     "]"
   );
 
-  ide_langserv_client_send_notification_async (self, "workspace/didChangeWatchedFiles",
+  ide_lsp_client_send_notification_async (self, "workspace/didChangeWatchedFiles",
                                                params, NULL, NULL, NULL);
 
-  ide_langserv_client_clear_diagnostics (self, uri);
+  ide_lsp_client_clear_diagnostics (self, uri);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_project_file_renamed (IdeLangservClient *self,
-                                          GFile             *src,
-                                          GFile             *dst,
-                                          IdeProject        *project)
+ide_lsp_client_project_file_renamed (IdeLspClient *self,
+                                     GFile        *src,
+                                     GFile        *dst,
+                                     IdeProject   *project)
 {
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *src_uri = NULL;
@@ -467,7 +456,7 @@ ide_langserv_client_project_file_renamed (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (G_IS_FILE (src));
   g_assert (G_IS_FILE (dst));
   g_assert (IDE_IS_PROJECT (project));
@@ -488,32 +477,33 @@ ide_langserv_client_project_file_renamed (IdeLangservClient *self,
     "]"
   );
 
-  ide_langserv_client_send_notification_async (self, "workspace/didChangeWatchedFiles",
+  ide_lsp_client_send_notification_async (self, "workspace/didChangeWatchedFiles",
                                                params, NULL, NULL, NULL);
 
-  ide_langserv_client_clear_diagnostics (self, src_uri);
+  ide_lsp_client_clear_diagnostics (self, src_uri);
 
   IDE_EXIT;
 }
 
 static IdeDiagnostics *
-ide_langserv_client_translate_diagnostics (IdeLangservClient *self,
-                                           IdeFile           *file,
-                                           GVariantIter      *diagnostics)
+ide_lsp_client_translate_diagnostics (IdeLspClient *self,
+                                      GFile        *file,
+                                      GVariantIter *diagnostics)
 {
   g_autoptr(GPtrArray) ar = NULL;
+  g_autoptr(IdeDiagnostics) ret = NULL;
   GVariant *value;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (diagnostics != NULL);
 
-  ar = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_diagnostic_unref);
+  ar = g_ptr_array_new_with_free_func (g_object_unref);
 
   while (g_variant_iter_loop (diagnostics, "v", &value))
     {
-      g_autoptr(IdeSourceLocation) begin_loc = NULL;
-      g_autoptr(IdeSourceLocation) end_loc = NULL;
+      g_autoptr(IdeLocation) begin_loc = NULL;
+      g_autoptr(IdeLocation) end_loc = NULL;
       g_autoptr(IdeDiagnostic) diag = NULL;
       g_autoptr(GVariant) range = NULL;
       const gchar *message = NULL;
@@ -550,8 +540,8 @@ ide_langserv_client_translate_diagnostics (IdeLangservClient *self,
       if (!success)
         continue;
 
-      begin_loc = ide_source_location_new (file, begin.line, begin.column, 0);
-      end_loc = ide_source_location_new (file, end.line, end.column, 0);
+      begin_loc = ide_location_new (file, begin.line, begin.column);
+      end_loc = ide_location_new (file, end.line, end.column);
 
       switch (severity)
         {
@@ -571,19 +561,27 @@ ide_langserv_client_translate_diagnostics (IdeLangservClient *self,
         }
 
       diag = ide_diagnostic_new (severity, message, begin_loc);
-      ide_diagnostic_take_range (diag, ide_source_range_new (begin_loc, end_loc));
+      ide_diagnostic_take_range (diag, ide_range_new (begin_loc, end_loc));
 
       g_ptr_array_add (ar, g_steal_pointer (&diag));
     }
 
-  return ide_diagnostics_new (IDE_PTR_ARRAY_STEAL_FULL (&ar));
+  ret = ide_diagnostics_new ();
+
+  if (ar != NULL)
+    {
+      for (guint i = 0; i < ar->len; i++)
+        ide_diagnostics_add (ret, g_ptr_array_index (ar, i));
+    }
+
+  return g_steal_pointer (&ret);
 }
 
 static void
-ide_langserv_client_text_document_publish_diagnostics (IdeLangservClient *self,
-                                                       GVariant          *params)
+ide_lsp_client_text_document_publish_diagnostics (IdeLspClient *self,
+                                                  GVariant     *params)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(GVariantIter) json_diagnostics = NULL;
   const gchar *uri = NULL;
   gboolean success;
@@ -591,7 +589,7 @@ ide_langserv_client_text_document_publish_diagnostics (IdeLangservClient *self,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (params != NULL);
 
   success = JSONRPC_MESSAGE_PARSE (params,
@@ -601,16 +599,12 @@ ide_langserv_client_text_document_publish_diagnostics (IdeLangservClient *self,
 
   if (success)
     {
-      g_autoptr(IdeFile) ifile = NULL;
       g_autoptr(GFile) file = NULL;
       g_autoptr(IdeDiagnostics) diagnostics = NULL;
-      IdeContext *context;
 
-      context = ide_object_get_context (IDE_OBJECT (self));
       file = g_file_new_for_uri (uri);
-      ifile = ide_file_new (context, file);
 
-      diagnostics = ide_langserv_client_translate_diagnostics (self, ifile, json_diagnostics);
+      diagnostics = ide_lsp_client_translate_diagnostics (self, file, json_diagnostics);
 
       IDE_TRACE_MSG ("%"G_GSIZE_FORMAT" diagnostics received for %s",
                      diagnostics ? ide_diagnostics_get_size (diagnostics) : 0,
@@ -623,7 +617,7 @@ ide_langserv_client_text_document_publish_diagnostics (IdeLangservClient *self,
        */
       g_hash_table_insert (priv->diagnostics_by_file,
                            g_object_ref (file),
-                           ide_diagnostics_ref (diagnostics));
+                           g_object_ref (diagnostics));
 
       g_signal_emit (self, signals [PUBLISHED_DIAGNOSTICS], 0, file, diagnostics);
     }
@@ -632,37 +626,37 @@ ide_langserv_client_text_document_publish_diagnostics (IdeLangservClient *self,
 }
 
 static void
-ide_langserv_client_real_notification (IdeLangservClient *self,
-                                       const gchar       *method,
-                                       GVariant          *params)
+ide_lsp_client_real_notification (IdeLspClient *self,
+                                  const gchar  *method,
+                                  GVariant     *params)
 {
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (method != NULL);
 
   if (params != NULL)
     {
       if (g_str_equal (method, "textDocument/publishDiagnostics"))
-        ide_langserv_client_text_document_publish_diagnostics (self, params);
+        ide_lsp_client_text_document_publish_diagnostics (self, params);
     }
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_send_notification (IdeLangservClient *self,
-                                       const gchar       *method,
-                                       GVariant          *params,
-                                       JsonrpcClient     *rpc_client)
+ide_lsp_client_send_notification (IdeLspClient  *self,
+                                  const gchar   *method,
+                                  GVariant      *params,
+                                  JsonrpcClient *rpc_client)
 {
   GQuark detail;
 
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (method != NULL);
   g_assert (JSONRPC_IS_CLIENT (rpc_client));
 
@@ -682,10 +676,10 @@ ide_langserv_client_send_notification (IdeLangservClient *self,
 }
 
 static void
-ide_langserv_client_finalize (GObject *object)
+ide_lsp_client_finalize (GObject *object)
 {
-  IdeLangservClient *self = (IdeLangservClient *)object;
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClient *self = (IdeLspClient *)object;
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   g_assert (IDE_IS_MAIN_THREAD ());
 
@@ -695,17 +689,17 @@ ide_langserv_client_finalize (GObject *object)
   g_clear_object (&priv->buffer_manager_signals);
   g_clear_object (&priv->project_signals);
 
-  G_OBJECT_CLASS (ide_langserv_client_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_client_parent_class)->finalize (object);
 }
 
 static gboolean
-ide_langserv_client_real_supports_language (IdeLangservClient *self,
-                                            const gchar       *language_id)
+ide_lsp_client_real_supports_language (IdeLspClient *self,
+                                       const gchar  *language_id)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
   g_assert (language_id != NULL);
 
   for (guint i = 0; i < priv->languages->len; i++)
@@ -720,13 +714,13 @@ ide_langserv_client_real_supports_language (IdeLangservClient *self,
 }
 
 static void
-ide_langserv_client_get_property (GObject    *object,
-                                  guint       prop_id,
-                                  GValue     *value,
-                                  GParamSpec *pspec)
+ide_lsp_client_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
 {
-  IdeLangservClient *self = IDE_LANGSERV_CLIENT (object);
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClient *self = IDE_LSP_CLIENT (object);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   switch (prop_id)
     {
@@ -740,13 +734,13 @@ ide_langserv_client_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_client_set_property (GObject      *object,
-                                  guint         prop_id,
-                                  const GValue *value,
-                                  GParamSpec   *pspec)
+ide_lsp_client_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
 {
-  IdeLangservClient *self = IDE_LANGSERV_CLIENT (object);
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClient *self = IDE_LSP_CLIENT (object);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   switch (prop_id)
     {
@@ -760,16 +754,16 @@ ide_langserv_client_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_client_class_init (IdeLangservClientClass *klass)
+ide_lsp_client_class_init (IdeLspClientClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_client_finalize;
-  object_class->get_property = ide_langserv_client_get_property;
-  object_class->set_property = ide_langserv_client_set_property;
+  object_class->finalize = ide_lsp_client_finalize;
+  object_class->get_property = ide_lsp_client_get_property;
+  object_class->set_property = ide_lsp_client_set_property;
 
-  klass->notification = ide_langserv_client_real_notification;
-  klass->supports_language = ide_langserv_client_real_supports_language;
+  klass->notification = ide_lsp_client_real_notification;
+  klass->supports_language = ide_lsp_client_real_supports_language;
 
   properties [PROP_IO_STREAM] =
     g_param_spec_object ("io-stream",
@@ -784,7 +778,7 @@ ide_langserv_client_class_init (IdeLangservClientClass *klass)
     g_signal_new ("notification",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-                  G_STRUCT_OFFSET (IdeLangservClientClass, notification),
+                  G_STRUCT_OFFSET (IdeLspClientClass, notification),
                   NULL, NULL, NULL,
                   G_TYPE_NONE,
                   2,
@@ -795,7 +789,7 @@ ide_langserv_client_class_init (IdeLangservClientClass *klass)
     g_signal_new ("supports-language",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (IdeLangservClientClass, supports_language),
+                  G_STRUCT_OFFSET (IdeLspClientClass, supports_language),
                   g_signal_accumulator_true_handled, NULL,
                   NULL,
                   G_TYPE_BOOLEAN,
@@ -806,7 +800,7 @@ ide_langserv_client_class_init (IdeLangservClientClass *klass)
     g_signal_new ("published-diagnostics",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (IdeLangservClientClass, published_diagnostics),
+                  G_STRUCT_OFFSET (IdeLspClientClass, published_diagnostics),
                   NULL, NULL, NULL,
                   G_TYPE_NONE,
                   2,
@@ -816,9 +810,9 @@ ide_langserv_client_class_init (IdeLangservClientClass *klass)
 }
 
 static void
-ide_langserv_client_init (IdeLangservClient *self)
+ide_lsp_client_init (IdeLspClient *self)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   g_assert (IDE_IS_MAIN_THREAD ());
 
@@ -827,34 +821,34 @@ ide_langserv_client_init (IdeLangservClient *self)
   priv->diagnostics_by_file = g_hash_table_new_full ((GHashFunc)g_file_hash,
                                                      (GEqualFunc)g_file_equal,
                                                      g_object_unref,
-                                                     (GDestroyNotify)ide_diagnostics_unref);
+                                                     (GDestroyNotify)g_object_unref);
 
   priv->buffer_manager_signals = dzl_signal_group_new (IDE_TYPE_BUFFER_MANAGER);
 
   dzl_signal_group_connect_object (priv->buffer_manager_signals,
                                    "buffer-loaded",
-                                   G_CALLBACK (ide_langserv_client_buffer_loaded),
+                                   G_CALLBACK (ide_lsp_client_buffer_loaded),
                                    self,
                                    G_CONNECT_SWAPPED);
   dzl_signal_group_connect_object (priv->buffer_manager_signals,
                                    "buffer-saved",
-                                   G_CALLBACK (ide_langserv_client_buffer_saved),
+                                   G_CALLBACK (ide_lsp_client_buffer_saved),
                                    self,
                                    G_CONNECT_SWAPPED);
   dzl_signal_group_connect_object (priv->buffer_manager_signals,
                                    "buffer-unloaded",
-                                   G_CALLBACK (ide_langserv_client_buffer_unloaded),
+                                   G_CALLBACK (ide_lsp_client_buffer_unloaded),
                                    self,
                                    G_CONNECT_SWAPPED);
 
   g_signal_connect_object (priv->buffer_manager_signals,
                            "bind",
-                           G_CALLBACK (ide_langserv_client_buffer_manager_bind),
+                           G_CALLBACK (ide_lsp_client_buffer_manager_bind),
                            self,
                            G_CONNECT_SWAPPED);
   g_signal_connect_object (priv->buffer_manager_signals,
                            "unbind",
-                           G_CALLBACK (ide_langserv_client_buffer_manager_unbind),
+                           G_CALLBACK (ide_lsp_client_buffer_manager_unbind),
                            self,
                            G_CONNECT_SWAPPED);
 
@@ -862,24 +856,24 @@ ide_langserv_client_init (IdeLangservClient *self)
 
   dzl_signal_group_connect_object (priv->project_signals,
                                    "file-trashed",
-                                   G_CALLBACK (ide_langserv_client_project_file_trashed),
+                                   G_CALLBACK (ide_lsp_client_project_file_trashed),
                                    self,
                                    G_CONNECT_SWAPPED);
   dzl_signal_group_connect_object (priv->project_signals,
                                    "file-renamed",
-                                   G_CALLBACK (ide_langserv_client_project_file_renamed),
+                                   G_CALLBACK (ide_lsp_client_project_file_renamed),
                                    self,
                                    G_CONNECT_SWAPPED);
 }
 
 static void
-ide_langserv_client_initialize_cb (GObject      *object,
-                                   GAsyncResult *result,
-                                   gpointer      user_data)
+ide_lsp_client_initialize_cb (GObject      *object,
+                              GAsyncResult *result,
+                              gpointer      user_data)
 {
   JsonrpcClient *rpc_client = (JsonrpcClient *)object;
-  g_autoptr(IdeLangservClient) self = user_data;
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  g_autoptr(IdeLspClient) self = user_data;
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(GVariant) reply = NULL;
   g_autoptr(GError) error = NULL;
   IdeBufferManager *buffer_manager;
@@ -891,13 +885,13 @@ ide_langserv_client_initialize_cb (GObject      *object,
   g_assert (IDE_IS_MAIN_THREAD ());
   g_assert (JSONRPC_IS_CLIENT (rpc_client));
   g_assert (G_IS_ASYNC_RESULT (result));
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
 
   if (!jsonrpc_client_call_finish (rpc_client, result, &reply, &error))
     {
       /* translators: %s is replaced with the error message */
       g_debug (_("Failed to initialize language server: %s"), error->message);
-      ide_langserv_client_stop (self);
+      ide_lsp_client_stop (self);
       IDE_EXIT;
     }
 
@@ -911,42 +905,39 @@ ide_langserv_client_initialize_cb (GObject      *object,
 
   context = ide_object_get_context (IDE_OBJECT (self));
 
-  buffer_manager = ide_context_get_buffer_manager (context);
+  buffer_manager = ide_buffer_manager_from_context (context);
   dzl_signal_group_set_target (priv->buffer_manager_signals, buffer_manager);
 
-  project = ide_context_get_project (context);
+  project = ide_project_from_context (context);
   dzl_signal_group_set_target (priv->project_signals, project);
 
   IDE_EXIT;
 }
 
-IdeLangservClient *
-ide_langserv_client_new (IdeContext *context,
-                         GIOStream  *io_stream)
+IdeLspClient *
+ide_lsp_client_new (GIOStream *io_stream)
 {
-  g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
+  g_return_val_if_fail (G_IS_IO_STREAM (io_stream), NULL);
 
-  return g_object_new (IDE_TYPE_LANGSERV_CLIENT,
-                       "context", context,
+  return g_object_new (IDE_TYPE_LSP_CLIENT,
                        "io-stream", io_stream,
                        NULL);
 }
 
 void
-ide_langserv_client_start (IdeLangservClient *self)
+ide_lsp_client_start (IdeLspClient *self)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *root_path = NULL;
   g_autofree gchar *root_uri = NULL;
   IdeContext *context;
-  IdeVcs *vcs;
   GFile *workdir;
 
   IDE_ENTRY;
 
   g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (self));
 
   context = ide_object_get_context (IDE_OBJECT (self));
 
@@ -962,12 +953,11 @@ ide_langserv_client_start (IdeLangservClient *self)
 
   g_signal_connect_object (priv->rpc_client,
                            "notification",
-                           G_CALLBACK (ide_langserv_client_send_notification),
+                           G_CALLBACK (ide_lsp_client_send_notification),
                            self,
                            G_CONNECT_SWAPPED);
 
-  vcs = ide_context_get_vcs (context);
-  workdir = ide_vcs_get_working_directory (vcs);
+  workdir = ide_context_ref_workdir (context);
   root_path = g_file_get_path (workdir);
   root_uri = g_file_get_uri (workdir);
 
@@ -988,33 +978,33 @@ ide_langserv_client_start (IdeLangservClient *self)
                              "initialize",
                              params,
                              NULL,
-                             ide_langserv_client_initialize_cb,
+                             ide_lsp_client_initialize_cb,
                              g_object_ref (self));
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_client_close_cb (GObject      *object,
-                              GAsyncResult *result,
-                              gpointer      user_data)
+ide_lsp_client_close_cb (GObject      *object,
+                         GAsyncResult *result,
+                         gpointer      user_data)
 {
-  g_autoptr(IdeLangservClient) self = user_data;
+  g_autoptr(IdeLspClient) self = user_data;
   JsonrpcClient *client = (JsonrpcClient *)object;
 
   g_assert (IDE_IS_MAIN_THREAD ());
   g_assert (G_IS_ASYNC_RESULT (result));
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
 
   jsonrpc_client_close_finish (client, result, NULL);
 }
 
 static void
-ide_langserv_client_shutdown_cb (GObject      *object,
-                                 GAsyncResult *result,
-                                 gpointer      user_data)
+ide_lsp_client_shutdown_cb (GObject      *object,
+                            GAsyncResult *result,
+                            gpointer      user_data)
 {
-  g_autoptr(IdeLangservClient) self = user_data;
+  g_autoptr(IdeLspClient) self = user_data;
   JsonrpcClient *client = (JsonrpcClient *)object;
   g_autoptr(GError) error = NULL;
 
@@ -1023,28 +1013,28 @@ ide_langserv_client_shutdown_cb (GObject      *object,
   g_assert (IDE_IS_MAIN_THREAD ());
   g_assert (JSONRPC_IS_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
-  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_LSP_CLIENT (self));
 
   if (!jsonrpc_client_call_finish (client, result, NULL, &error))
     g_debug ("%s", error->message);
   else
     jsonrpc_client_close_async (client,
                                 NULL,
-                                ide_langserv_client_close_cb,
+                                ide_lsp_client_close_cb,
                                 g_steal_pointer (&self));
 
   IDE_EXIT;
 }
 
 void
-ide_langserv_client_stop (IdeLangservClient *self)
+ide_lsp_client_stop (IdeLspClient *self)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   IDE_ENTRY;
 
   g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (self));
 
   if (priv->rpc_client != NULL)
     {
@@ -1052,7 +1042,7 @@ ide_langserv_client_stop (IdeLangservClient *self)
                                  "shutdown",
                                  NULL,
                                  NULL,
-                                 ide_langserv_client_shutdown_cb,
+                                 ide_lsp_client_shutdown_cb,
                                  g_object_ref (self));
       g_clear_object (&priv->rpc_client);
     }
@@ -1061,9 +1051,9 @@ ide_langserv_client_stop (IdeLangservClient *self)
 }
 
 static void
-ide_langserv_client_call_cb (GObject      *object,
-                             GAsyncResult *result,
-                             gpointer      user_data)
+ide_lsp_client_call_cb (GObject      *object,
+                        GAsyncResult *result,
+                        gpointer      user_data)
 {
   JsonrpcClient *client = (JsonrpcClient *)object;
   g_autoptr(GVariant) reply = NULL;
@@ -1088,8 +1078,8 @@ ide_langserv_client_call_cb (GObject      *object,
 }
 
 /**
- * ide_langserv_client_call_async:
- * @self: An #IdeLangservClient
+ * ide_lsp_client_call_async:
+ * @self: An #IdeLspClient
  * @method: the method to call
  * @params: (nullable) (transfer none): An #GVariant or %NULL
  * @cancellable: (nullable): A cancellable or %NULL
@@ -1100,29 +1090,29 @@ ide_langserv_client_call_cb (GObject      *object,
  *
  * If @params is floating, it's floating reference is consumed.
  *
- * Since: 3.32
+ * Since: 3.26
  */
 void
-ide_langserv_client_call_async (IdeLangservClient   *self,
-                                const gchar         *method,
-                                GVariant            *params,
-                                GCancellable        *cancellable,
-                                GAsyncReadyCallback  callback,
-                                gpointer             user_data)
+ide_lsp_client_call_async (IdeLspClient        *self,
+                           const gchar         *method,
+                           GVariant            *params,
+                           GCancellable        *cancellable,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
 
   IDE_ENTRY;
 
   g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (self));
   g_return_if_fail (method != NULL);
   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
   g_return_if_fail (!priv->rpc_client || JSONRPC_IS_CLIENT (priv->rpc_client));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_client_call_async);
+  ide_task_set_source_tag (task, ide_lsp_client_call_async);
 
   if (priv->rpc_client == NULL)
     ide_task_return_new_error (task,
@@ -1134,24 +1124,24 @@ ide_langserv_client_call_async (IdeLangservClient   *self,
                                method,
                                params,
                                cancellable,
-                               ide_langserv_client_call_cb,
+                               ide_lsp_client_call_cb,
                                g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 gboolean
-ide_langserv_client_call_finish (IdeLangservClient  *self,
-                                 GAsyncResult       *result,
-                                 GVariant          **return_value,
-                                 GError            **error)
+ide_lsp_client_call_finish (IdeLspClient  *self,
+                            GAsyncResult  *result,
+                            GVariant     **return_value,
+                            GError       **error)
 {
   g_autoptr(GVariant) local_return_value = NULL;
   gboolean ret;
 
   IDE_ENTRY;
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_CLIENT (self), FALSE);
+  g_return_val_if_fail (IDE_IS_LSP_CLIENT (self), FALSE);
   g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
 
   local_return_value = ide_task_propagate_pointer (IDE_TASK (result), error);
@@ -1164,9 +1154,9 @@ ide_langserv_client_call_finish (IdeLangservClient  *self,
 }
 
 static void
-ide_langserv_client_send_notification_cb (GObject      *object,
-                                          GAsyncResult *result,
-                                          gpointer      user_data)
+ide_lsp_client_send_notification_cb (GObject      *object,
+                                     GAsyncResult *result,
+                                     gpointer      user_data)
 {
   JsonrpcClient *client = (JsonrpcClient *)object;
   g_autoptr(IdeTask) task = user_data;
@@ -1188,8 +1178,8 @@ ide_langserv_client_send_notification_cb (GObject      *object,
 }
 
 /**
- * ide_langserv_client_send_notification_async:
- * @self: An #IdeLangservClient
+ * ide_lsp_client_send_notification_async:
+ * @self: An #IdeLspClient
  * @method: the method to notification
  * @params: (nullable) (transfer none): An #GVariant or %NULL
  * @cancellable: (nullable): A cancellable or %NULL
@@ -1200,28 +1190,28 @@ ide_langserv_client_send_notification_cb (GObject      *object,
  *
  * If @params is floating, it's reference is consumed.
  *
- * Since: 3.32
+ * Since: 3.26
  */
 void
-ide_langserv_client_send_notification_async (IdeLangservClient   *self,
-                                             const gchar         *method,
-                                             GVariant            *params,
-                                             GCancellable        *cancellable,
-                                             GAsyncReadyCallback  notificationback,
-                                             gpointer             user_data)
+ide_lsp_client_send_notification_async (IdeLspClient        *self,
+                                        const gchar         *method,
+                                        GVariant            *params,
+                                        GCancellable        *cancellable,
+                                        GAsyncReadyCallback  notificationback,
+                                        gpointer             user_data)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
 
   IDE_ENTRY;
 
   g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (self));
   g_return_if_fail (method != NULL);
   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, notificationback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_client_send_notification_async);
+  ide_task_set_source_tag (task, ide_lsp_client_send_notification_async);
 
   if (priv->rpc_client == NULL)
     ide_task_return_new_error (task,
@@ -1233,23 +1223,23 @@ ide_langserv_client_send_notification_async (IdeLangservClient   *self,
                                             method,
                                             params,
                                             cancellable,
-                                            ide_langserv_client_send_notification_cb,
+                                            ide_lsp_client_send_notification_cb,
                                             g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 gboolean
-ide_langserv_client_send_notification_finish (IdeLangservClient  *self,
-                                              GAsyncResult       *result,
-                                              GError            **error)
+ide_lsp_client_send_notification_finish (IdeLspClient  *self,
+                                         GAsyncResult  *result,
+                                         GError       **error)
 {
   gboolean ret;
 
   IDE_ENTRY;
 
   g_return_val_if_fail (IDE_IS_MAIN_THREAD (), FALSE);
-  g_return_val_if_fail (IDE_IS_LANGSERV_CLIENT (self), FALSE);
+  g_return_val_if_fail (IDE_IS_LSP_CLIENT (self), FALSE);
   g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
 
   ret = ide_task_propagate_boolean (IDE_TASK (result), error);
@@ -1258,62 +1248,62 @@ ide_langserv_client_send_notification_finish (IdeLangservClient  *self,
 }
 
 void
-ide_langserv_client_get_diagnostics_async (IdeLangservClient   *self,
-                                           GFile               *file,
-                                           GCancellable        *cancellable,
-                                           GAsyncReadyCallback  callback,
-                                           gpointer             user_data)
+ide_lsp_client_get_diagnostics_async (IdeLspClient        *self,
+                                      GFile               *file,
+                                      GBytes              *content,
+                                      const gchar         *lang_id,
+                                      GCancellable        *cancellable,
+                                      GAsyncReadyCallback  callback,
+                                      gpointer             user_data)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   IdeDiagnostics *diagnostics;
 
   g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (self));
   g_return_if_fail (G_IS_FILE (file));
   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_client_get_diagnostics_async);
+  ide_task_set_source_tag (task, ide_lsp_client_get_diagnostics_async);
 
   diagnostics = g_hash_table_lookup (priv->diagnostics_by_file, file);
 
   if (diagnostics != NULL)
     ide_task_return_pointer (task,
-                             ide_diagnostics_ref (diagnostics),
-                             (GDestroyNotify)ide_diagnostics_unref);
+                             g_object_ref (diagnostics),
+                             (GDestroyNotify)g_object_unref);
   else
     ide_task_return_pointer (task,
-                             ide_diagnostics_new (NULL),
-                             (GDestroyNotify)ide_diagnostics_unref);
+                             ide_diagnostics_new (),
+                             (GDestroyNotify)g_object_unref);
 }
 
 /**
- * ide_langserv_client_get_diagnostics_finish:
- * @self: an #IdeLangservClient
+ * ide_lsp_client_get_diagnostics_finish:
+ * @self: an #IdeLspClient
  * @result: a #GAsyncResult
  * @diagnostics: (nullable) (out): A location for a #IdeDiagnostics or %NULL
  * @error: A location for a #GError or %NULL
  *
- * Completes a request to ide_langserv_client_get_diagnostics_async().
+ * Completes a request to ide_lsp_client_get_diagnostics_async().
  *
  * Returns: %TRUE if successful and @diagnostics is set, otherwise %FALSE
  *   and @error is set.
- *
- * Since: 3.32
  */
 gboolean
-ide_langserv_client_get_diagnostics_finish (IdeLangservClient  *self,
-                                            GAsyncResult       *result,
-                                            IdeDiagnostics    **diagnostics,
-                                            GError            **error)
+ide_lsp_client_get_diagnostics_finish (IdeLspClient    *self,
+                                       GAsyncResult    *result,
+                                       IdeDiagnostics **diagnostics,
+                                       GError         **error)
 {
   g_autoptr(IdeDiagnostics) local_diagnostics = NULL;
   g_autoptr(GError) local_error = NULL;
   gboolean ret;
 
   g_return_val_if_fail (IDE_IS_MAIN_THREAD (), FALSE);
-  g_return_val_if_fail (IDE_IS_LANGSERV_CLIENT (self), FALSE);
+  g_return_val_if_fail (IDE_IS_LSP_CLIENT (self), FALSE);
   g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
 
   local_diagnostics = ide_task_propagate_pointer (IDE_TASK (result), &local_error);
@@ -1329,13 +1319,13 @@ ide_langserv_client_get_diagnostics_finish (IdeLangservClient  *self,
 }
 
 void
-ide_langserv_client_add_language (IdeLangservClient *self,
-                                  const gchar       *language_id)
+ide_lsp_client_add_language (IdeLspClient *self,
+                             const gchar  *language_id)
 {
-  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+  IdeLspClientPrivate *priv = ide_lsp_client_get_instance_private (self);
 
   g_return_if_fail (IDE_IS_MAIN_THREAD ());
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (self));
   g_return_if_fail (language_id != NULL);
 
   g_ptr_array_add (priv->languages, g_strdup (language_id));
diff --git a/src/libide/langserv/ide-langserv-client.h b/src/libide/lsp/ide-lsp-client.h
similarity index 69%
rename from src/libide/langserv/ide-langserv-client.h
rename to src/libide/lsp/ide-lsp-client.h
index 0bf94fef8..ffcb79fa4 100644
--- a/src/libide/langserv/ide-langserv-client.h
+++ b/src/libide/lsp/ide-lsp-client.h
@@ -1,4 +1,4 @@
-/* ide-langserv-client.h
+/* ide-lsp-client.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,82 +20,78 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "ide-object.h"
+#include <libide-core.h>
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_CLIENT (ide_langserv_client_get_type())
+#define IDE_TYPE_LSP_CLIENT (ide_lsp_client_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservClient, ide_langserv_client, IDE, LANGSERV_CLIENT, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspClient, ide_lsp_client, IDE, LSP_CLIENT, IdeObject)
 
-struct _IdeLangservClientClass
+struct _IdeLspClientClass
 {
   IdeObjectClass parent_class;
 
-  void     (*notification)          (IdeLangservClient *self,
+  void     (*notification)          (IdeLspClient *self,
                                      const gchar       *method,
                                      GVariant          *params);
-  gboolean (*supports_language)     (IdeLangservClient *self,
+  gboolean (*supports_language)     (IdeLspClient *self,
                                      const gchar       *language_id);
-  void     (*published_diagnostics) (IdeLangservClient *self,
+  void     (*published_diagnostics) (IdeLspClient *self,
                                      GFile             *file,
                                      IdeDiagnostics    *diagnostics);
 
   /*< private >*/
-  gpointer _reserved1;
-  gpointer _reserved2;
-  gpointer _reserved3;
-  gpointer _reserved4;
-  gpointer _reserved5;
-  gpointer _reserved6;
-  gpointer _reserved7;
-  gpointer _reserved8;
+  gpointer _reserved[16];
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_client_new                      (IdeContext           *context,
-                                                                 GIOStream            *io_stream);
+IdeLspClient *ide_lsp_client_new                      (GIOStream            *io_stream);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_client_add_language             (IdeLangservClient    *self,
+void               ide_lsp_client_add_language             (IdeLspClient    *self,
                                                                  const gchar          *language_id);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_client_start                    (IdeLangservClient    *self);
+void               ide_lsp_client_start                    (IdeLspClient    *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_client_stop                     (IdeLangservClient    *self);
+void               ide_lsp_client_stop                     (IdeLspClient    *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_client_call_async               (IdeLangservClient    *self,
+void               ide_lsp_client_call_async               (IdeLspClient    *self,
                                                                  const gchar          *method,
                                                                  GVariant             *params,
                                                                  GCancellable         *cancellable,
                                                                  GAsyncReadyCallback   callback,
                                                                  gpointer              user_data);
 IDE_AVAILABLE_IN_3_32
-gboolean           ide_langserv_client_call_finish              (IdeLangservClient    *self,
+gboolean           ide_lsp_client_call_finish              (IdeLspClient    *self,
                                                                  GAsyncResult         *result,
                                                                  GVariant            **return_value,
                                                                  GError              **error);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_client_send_notification_async  (IdeLangservClient    *self,
+void               ide_lsp_client_send_notification_async  (IdeLspClient    *self,
                                                                  const gchar          *method,
                                                                  GVariant             *params,
                                                                  GCancellable         *cancellable,
                                                                  GAsyncReadyCallback   notificationback,
                                                                  gpointer              user_data);
 IDE_AVAILABLE_IN_3_32
-gboolean           ide_langserv_client_send_notification_finish (IdeLangservClient    *self,
+gboolean           ide_lsp_client_send_notification_finish (IdeLspClient    *self,
                                                                  GAsyncResult         *result,
                                                                  GError              **error);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_client_get_diagnostics_async    (IdeLangservClient    *self,
+void               ide_lsp_client_get_diagnostics_async    (IdeLspClient    *self,
                                                                  GFile                *file,
+                                                                 GBytes *content,
+                                                                 const gchar *lang_id,
                                                                  GCancellable         *cancellable,
                                                                  GAsyncReadyCallback   callback,
                                                                  gpointer              user_data);
 IDE_AVAILABLE_IN_3_32
-gboolean           ide_langserv_client_get_diagnostics_finish   (IdeLangservClient    *self,
+gboolean           ide_lsp_client_get_diagnostics_finish   (IdeLspClient    *self,
                                                                  GAsyncResult         *result,
                                                                  IdeDiagnostics      **diagnostics,
                                                                  GError              **error);
diff --git a/src/libide/langserv/ide-langserv-completion-item.c b/src/libide/lsp/ide-lsp-completion-item.c
similarity index 55%
rename from src/libide/langserv/ide-langserv-completion-item.c
rename to src/libide/lsp/ide-lsp-completion-item.c
index f5b83b187..7763b0139 100644
--- a/src/libide/langserv/ide-langserv-completion-item.c
+++ b/src/libide/lsp/ide-lsp-completion-item.c
@@ -1,4 +1,4 @@
-/* ide-langserv-completion-item.c
+/* ide-lsp-completion-item.c
  *
  * Copyright 2018-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,21 +18,17 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-completion-item"
+#define G_LOG_DOMAIN "ide-lsp-completion-item"
 
 #include "config.h"
 
+#include <libide-sourceview.h>
 #include <jsonrpc-glib.h>
 
-#include "ide-debug.h"
+#include "ide-lsp-completion-item.h"
+#include "ide-lsp-util.h"
 
-#include "completion/ide-completion.h"
-#include "langserv/ide-langserv-completion-item.h"
-#include "langserv/ide-langserv-util.h"
-#include "snippets/ide-snippet-chunk.h"
-#include "symbols/ide-symbol.h"
-
-struct _IdeLangservCompletionItem
+struct _IdeLspCompletionItem
 {
   GObject parent_instance;
   GVariant *variant;
@@ -41,37 +37,37 @@ struct _IdeLangservCompletionItem
   guint kind;
 };
 
-G_DEFINE_TYPE_WITH_CODE (IdeLangservCompletionItem, ide_langserv_completion_item, G_TYPE_OBJECT,
+G_DEFINE_TYPE_WITH_CODE (IdeLspCompletionItem, ide_lsp_completion_item, G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_COMPLETION_PROPOSAL, NULL))
 
 static void
-ide_langserv_completion_item_finalize (GObject *object)
+ide_lsp_completion_item_finalize (GObject *object)
 {
-  IdeLangservCompletionItem *self = (IdeLangservCompletionItem *)object;
+  IdeLspCompletionItem *self = (IdeLspCompletionItem *)object;
 
   g_clear_pointer (&self->variant, g_variant_unref);
 
-  G_OBJECT_CLASS (ide_langserv_completion_item_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_completion_item_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_completion_item_class_init (IdeLangservCompletionItemClass *klass)
+ide_lsp_completion_item_class_init (IdeLspCompletionItemClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_completion_item_finalize;
+  object_class->finalize = ide_lsp_completion_item_finalize;
 }
 
 static void
-ide_langserv_completion_item_init (IdeLangservCompletionItem *self)
+ide_lsp_completion_item_init (IdeLspCompletionItem *self)
 {
 }
 
-IdeLangservCompletionItem *
-ide_langserv_completion_item_new (GVariant *variant)
+IdeLspCompletionItem *
+ide_lsp_completion_item_new (GVariant *variant)
 {
   g_autoptr(GVariant) unboxed = NULL;
-  IdeLangservCompletionItem *self;
+  IdeLspCompletionItem *self;
   gint64 kind = 0;
 
   g_return_val_if_fail (variant != NULL, NULL);
@@ -79,71 +75,71 @@ ide_langserv_completion_item_new (GVariant *variant)
   if (g_variant_is_of_type (variant, G_VARIANT_TYPE_VARIANT))
     variant = unboxed = g_variant_get_variant (variant);
 
-  self = g_object_new (IDE_TYPE_LANGSERV_COMPLETION_ITEM, NULL);
+  self = g_object_new (IDE_TYPE_LSP_COMPLETION_ITEM, NULL);
   self->variant = g_variant_ref_sink (variant);
 
   g_variant_lookup (variant, "label", "&s", &self->label);
   g_variant_lookup (variant, "detail", "&s", &self->detail);
 
   if (JSONRPC_MESSAGE_PARSE (variant, "kind", JSONRPC_MESSAGE_GET_INT64 (&kind)))
-    self->kind = ide_langserv_decode_completion_kind (kind);
+    self->kind = ide_lsp_decode_completion_kind (kind);
 
   return self;
 }
 
 gchar *
-ide_langserv_completion_item_get_markup (IdeLangservCompletionItem *self,
+ide_lsp_completion_item_get_markup (IdeLspCompletionItem *self,
                                          const gchar               *typed_text)
 {
-  g_return_val_if_fail (IDE_IS_LANGSERV_COMPLETION_ITEM (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self), NULL);
 
   return ide_completion_fuzzy_highlight (self->label, typed_text);
 }
 
 const gchar *
-ide_langserv_completion_item_get_return_type (IdeLangservCompletionItem *self)
+ide_lsp_completion_item_get_return_type (IdeLspCompletionItem *self)
 {
-  g_return_val_if_fail (IDE_IS_LANGSERV_COMPLETION_ITEM (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self), NULL);
 
-  /* TODO: How do we get this from langserv? */
+  /* TODO: How do we get this from lsp? */
 
   return NULL;
 }
 
 const gchar *
-ide_langserv_completion_item_get_icon_name (IdeLangservCompletionItem *self)
+ide_lsp_completion_item_get_icon_name (IdeLspCompletionItem *self)
 {
-  g_return_val_if_fail (IDE_IS_LANGSERV_COMPLETION_ITEM (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self), NULL);
 
   return ide_symbol_kind_get_icon_name (self->kind);
 }
 
 const gchar *
-ide_langserv_completion_item_get_detail (IdeLangservCompletionItem *self)
+ide_lsp_completion_item_get_detail (IdeLspCompletionItem *self)
 {
-  g_return_val_if_fail (IDE_IS_LANGSERV_COMPLETION_ITEM (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self), NULL);
 
   return self->detail;
 }
 
 /**
- * ide_langserv_completion_item_get_snippet:
- * @self: a #IdeLangservCompletionItem
+ * ide_lsp_completion_item_get_snippet:
+ * @self: a #IdeLspCompletionItem
  *
  * Creates a new snippet for the completion item to be inserted into
  * the document.
  *
  * Returns: (transfer full): an #IdeSnippet
  *
- * Since: 3.32
+ * Since: 3.30
  */
 IdeSnippet *
-ide_langserv_completion_item_get_snippet (IdeLangservCompletionItem *self)
+ide_lsp_completion_item_get_snippet (IdeLspCompletionItem *self)
 {
   g_autoptr(IdeSnippet) snippet = NULL;
   g_autoptr(IdeSnippetChunk) chunk = NULL;
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_COMPLETION_ITEM (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self), NULL);
 
   snippet = ide_snippet_new (NULL, NULL);
   chunk = ide_snippet_chunk_new ();
diff --git a/src/libide/langserv/ide-langserv-completion-item.h b/src/libide/lsp/ide-lsp-completion-item.h
similarity index 52%
rename from src/libide/langserv/ide-langserv-completion-item.h
rename to src/libide/lsp/ide-lsp-completion-item.h
index d1b7d503a..b61b85277 100644
--- a/src/libide/langserv/ide-langserv-completion-item.h
+++ b/src/libide/lsp/ide-lsp-completion-item.h
@@ -1,4 +1,4 @@
-/* ide-langserv-completion-item.h
+/* ide-lsp-completion-item.h
  *
  * Copyright 2018-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,30 +20,31 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "completion/ide-completion-proposal.h"
-#include "snippets/ide-snippet.h"
+#include <libide-sourceview.h>
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_COMPLETION_ITEM (ide_langserv_completion_item_get_type())
+#define IDE_TYPE_LSP_COMPLETION_ITEM (ide_lsp_completion_item_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_FINAL_TYPE (IdeLangservCompletionItem, ide_langserv_completion_item, IDE, 
LANGSERV_COMPLETION_ITEM, GObject)
+G_DECLARE_FINAL_TYPE (IdeLspCompletionItem, ide_lsp_completion_item, IDE, LSP_COMPLETION_ITEM, GObject)
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservCompletionItem *ide_langserv_completion_item_new             (GVariant *variant);
+IdeLspCompletionItem *ide_lsp_completion_item_new             (GVariant *variant);
 IDE_AVAILABLE_IN_3_32
-const gchar               *ide_langserv_completion_item_get_icon_name   (IdeLangservCompletionItem *self);
+const gchar               *ide_lsp_completion_item_get_icon_name   (IdeLspCompletionItem *self);
 IDE_AVAILABLE_IN_3_32
-const gchar               *ide_langserv_completion_item_get_return_type (IdeLangservCompletionItem *self);
+const gchar               *ide_lsp_completion_item_get_return_type (IdeLspCompletionItem *self);
 IDE_AVAILABLE_IN_3_32
-const gchar               *ide_langserv_completion_item_get_detail      (IdeLangservCompletionItem *self);
+const gchar               *ide_lsp_completion_item_get_detail      (IdeLspCompletionItem *self);
 IDE_AVAILABLE_IN_3_32
-gchar                     *ide_langserv_completion_item_get_markup      (IdeLangservCompletionItem *self,
+gchar                     *ide_lsp_completion_item_get_markup      (IdeLspCompletionItem *self,
                                                                          const gchar               
*typed_text);
 IDE_AVAILABLE_IN_3_32
-IdeSnippet                *ide_langserv_completion_item_get_snippet     (IdeLangservCompletionItem *self);
+IdeSnippet                *ide_lsp_completion_item_get_snippet     (IdeLspCompletionItem *self);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-completion-provider.c 
b/src/libide/lsp/ide-lsp-completion-provider.c
similarity index 54%
rename from src/libide/langserv/ide-langserv-completion-provider.c
rename to src/libide/lsp/ide-lsp-completion-provider.c
index 4e4a817a8..857a088db 100644
--- a/src/libide/langserv/ide-langserv-completion-provider.c
+++ b/src/libide/lsp/ide-lsp-completion-provider.c
@@ -1,4 +1,4 @@
-/* ide-langserv-completion-provider.c
+/* ide-lsp-completion-provider.c
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,37 +18,30 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-completion-provider"
+#define G_LOG_DOMAIN "ide-lsp-completion-provider"
 
 #include "config.h"
 
+#include <libide-code.h>
+#include <libide-sourceview.h>
+#include <libide-threading.h>
 #include <jsonrpc-glib.h>
 
-#include "ide-debug.h"
-
-#include "buffers/ide-buffer.h"
-#include "completion/ide-completion-context.h"
-#include "completion/ide-completion-provider.h"
-#include "completion/ide-completion-list-box-row.h"
-#include "langserv/ide-langserv-completion-provider.h"
-#include "langserv/ide-langserv-completion-item.h"
-#include "langserv/ide-langserv-completion-results.h"
-#include "langserv/ide-langserv-util.h"
-#include "snippets/ide-snippet.h"
-#include "sourceview/ide-source-view.h"
-#include "symbols/ide-symbol.h"
-#include "threading/ide-task.h"
+#include "ide-lsp-completion-provider.h"
+#include "ide-lsp-completion-item.h"
+#include "ide-lsp-completion-results.h"
+#include "ide-lsp-util.h"
 
 typedef struct
 {
-  IdeLangservClient *client;
+  IdeLspClient *client;
   gchar *word;
-} IdeLangservCompletionProviderPrivate;
+} IdeLspCompletionProviderPrivate;
 
 static void provider_iface_init (IdeCompletionProviderInterface *iface);
 
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLangservCompletionProvider, ide_langserv_completion_provider, 
IDE_TYPE_OBJECT,
-                                  G_ADD_PRIVATE (IdeLangservCompletionProvider)
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspCompletionProvider, ide_lsp_completion_provider, IDE_TYPE_OBJECT,
+                                  G_ADD_PRIVATE (IdeLspCompletionProvider)
                                   G_IMPLEMENT_INTERFACE (IDE_TYPE_COMPLETION_PROVIDER, provider_iface_init))
 
 enum {
@@ -60,29 +53,29 @@ enum {
 static GParamSpec *properties [N_PROPS];
 
 static void
-ide_langserv_completion_provider_finalize (GObject *object)
+ide_lsp_completion_provider_finalize (GObject *object)
 {
-  IdeLangservCompletionProvider *self = (IdeLangservCompletionProvider *)object;
-  IdeLangservCompletionProviderPrivate *priv = ide_langserv_completion_provider_get_instance_private (self);
+  IdeLspCompletionProvider *self = (IdeLspCompletionProvider *)object;
+  IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
 
   g_clear_object (&priv->client);
   g_clear_pointer (&priv->word, g_free);
 
-  G_OBJECT_CLASS (ide_langserv_completion_provider_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_completion_provider_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_completion_provider_get_property (GObject    *object,
+ide_lsp_completion_provider_get_property (GObject    *object,
                                                guint       prop_id,
                                                GValue     *value,
                                                GParamSpec *pspec)
 {
-  IdeLangservCompletionProvider *self = IDE_LANGSERV_COMPLETION_PROVIDER (object);
+  IdeLspCompletionProvider *self = IDE_LSP_COMPLETION_PROVIDER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      g_value_set_object (value, ide_langserv_completion_provider_get_client (self));
+      g_value_set_object (value, ide_lsp_completion_provider_get_client (self));
       break;
 
     default:
@@ -91,17 +84,17 @@ ide_langserv_completion_provider_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_completion_provider_set_property (GObject      *object,
+ide_lsp_completion_provider_set_property (GObject      *object,
                                                guint         prop_id,
                                                const GValue *value,
                                                GParamSpec   *pspec)
 {
-  IdeLangservCompletionProvider *self = IDE_LANGSERV_COMPLETION_PROVIDER (object);
+  IdeLspCompletionProvider *self = IDE_LSP_COMPLETION_PROVIDER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      ide_langserv_completion_provider_set_client (self, g_value_get_object (value));
+      ide_lsp_completion_provider_set_client (self, g_value_get_object (value));
       break;
 
     default:
@@ -110,99 +103,97 @@ ide_langserv_completion_provider_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_completion_provider_class_init (IdeLangservCompletionProviderClass *klass)
+ide_lsp_completion_provider_class_init (IdeLspCompletionProviderClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_completion_provider_finalize;
-  object_class->get_property = ide_langserv_completion_provider_get_property;
-  object_class->set_property = ide_langserv_completion_provider_set_property;
+  object_class->finalize = ide_lsp_completion_provider_finalize;
+  object_class->get_property = ide_lsp_completion_provider_get_property;
+  object_class->set_property = ide_lsp_completion_provider_set_property;
 
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
                          "The Language Server client",
-                         IDE_TYPE_LANGSERV_CLIENT,
+                         IDE_TYPE_LSP_CLIENT,
                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static void
-ide_langserv_completion_provider_init (IdeLangservCompletionProvider *self)
+ide_lsp_completion_provider_init (IdeLspCompletionProvider *self)
 {
 }
 
 /**
- * ide_langserv_completion_provider_get_client:
- * @self: An #IdeLangservCompletionProvider
+ * ide_lsp_completion_provider_get_client:
+ * @self: An #IdeLspCompletionProvider
  *
  * Gets the client for the completion provider.
  *
- * Returns: (transfer none) (nullable): An #IdeLangservClient or %NULL
- *
- * Since: 3.32
+ * Returns: (transfer none) (nullable): An #IdeLspClient or %NULL
  */
-IdeLangservClient *
-ide_langserv_completion_provider_get_client (IdeLangservCompletionProvider *self)
+IdeLspClient *
+ide_lsp_completion_provider_get_client (IdeLspCompletionProvider *self)
 {
-  IdeLangservCompletionProviderPrivate *priv = ide_langserv_completion_provider_get_instance_private (self);
+  IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_COMPLETION_PROVIDER (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_PROVIDER (self), NULL);
 
   return priv->client;
 }
 
 void
-ide_langserv_completion_provider_set_client (IdeLangservCompletionProvider *self,
-                                             IdeLangservClient             *client)
+ide_lsp_completion_provider_set_client (IdeLspCompletionProvider *self,
+                                             IdeLspClient             *client)
 {
-  IdeLangservCompletionProviderPrivate *priv = ide_langserv_completion_provider_get_instance_private (self);
+  IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
 
-  g_return_if_fail (IDE_IS_LANGSERV_COMPLETION_PROVIDER (self));
-  g_return_if_fail (!client || IDE_IS_LANGSERV_CLIENT (client));
+  g_return_if_fail (IDE_IS_LSP_COMPLETION_PROVIDER (self));
+  g_return_if_fail (!client || IDE_IS_LSP_CLIENT (client));
 
   if (g_set_object (&priv->client, client))
     g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
 }
 
 static gint
-ide_langserv_completion_provider_get_priority (IdeCompletionProvider *provider,
+ide_lsp_completion_provider_get_priority (IdeCompletionProvider *provider,
                                                IdeCompletionContext  *context)
 {
-  return IDE_LANGSERV_COMPLETION_PROVIDER_PRIORITY;
+  return IDE_LSP_COMPLETION_PROVIDER_PRIORITY;
 }
 
 static void
-ide_langserv_completion_provider_complete_cb (GObject      *object,
+ide_lsp_completion_provider_complete_cb (GObject      *object,
                                               GAsyncResult *result,
                                               gpointer      user_data)
 {
-  IdeLangservCompletionProviderPrivate *priv;
-  IdeLangservCompletionProvider *self;
-  IdeLangservClient *client = (IdeLangservClient *)object;
+  IdeLspCompletionProviderPrivate *priv;
+  IdeLspCompletionProvider *self;
+  IdeLspClient *client = (IdeLspClient *)object;
   g_autoptr(GVariant) return_value = NULL;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GError) error = NULL;
-  IdeLangservCompletionResults *ret;
+  IdeLspCompletionResults *ret;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
 
-  if (!ide_langserv_client_call_finish (client, result, &return_value, &error))
+  if (!ide_lsp_client_call_finish (client, result, &return_value, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       return;
     }
 
   self = ide_task_get_source_object (task);
-  priv = ide_langserv_completion_provider_get_instance_private (self);
+  priv = ide_lsp_completion_provider_get_instance_private (self);
 
-  ret = ide_langserv_completion_results_new (return_value);
+  ret = ide_lsp_completion_results_new (return_value);
   if (priv->word != NULL && *priv->word != 0)
-    ide_langserv_completion_results_refilter (ret, priv->word);
+    ide_lsp_completion_results_refilter (ret, priv->word);
 
   ide_task_return_object (task, g_steal_pointer (&ret));
 
@@ -210,14 +201,14 @@ ide_langserv_completion_provider_complete_cb (GObject      *object,
 }
 
 static void
-ide_langserv_completion_provider_populate_async (IdeCompletionProvider  *provider,
+ide_lsp_completion_provider_populate_async (IdeCompletionProvider  *provider,
                                                  IdeCompletionContext   *context,
                                                  GCancellable           *cancellable,
                                                  GAsyncReadyCallback     callback,
                                                  gpointer                user_data)
 {
-  IdeLangservCompletionProvider *self = (IdeLangservCompletionProvider *)provider;
-  IdeLangservCompletionProviderPrivate *priv = ide_langserv_completion_provider_get_instance_private (self);
+  IdeLspCompletionProvider *self = (IdeLspCompletionProvider *)provider;
+  IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
@@ -228,11 +219,11 @@ ide_langserv_completion_provider_populate_async (IdeCompletionProvider  *provide
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_COMPLETION_PROVIDER (self));
+  g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (self));
   g_assert (IDE_IS_COMPLETION_CONTEXT (context));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_completion_provider_populate_async);
+  ide_task_set_source_tag (task, ide_lsp_completion_provider_populate_async);
 
   if (priv->client == NULL)
     {
@@ -249,7 +240,7 @@ ide_langserv_completion_provider_populate_async (IdeCompletionProvider  *provide
   priv->word = ide_completion_context_get_word (context);
 
   buffer = ide_completion_context_get_buffer (context);
-  uri = ide_buffer_get_uri (IDE_BUFFER (buffer));
+  uri = ide_buffer_dup_uri (IDE_BUFFER (buffer));
 
   line = gtk_text_iter_get_line (&iter);
   column = gtk_text_iter_get_line_offset (&iter);
@@ -264,18 +255,18 @@ ide_langserv_completion_provider_populate_async (IdeCompletionProvider  *provide
     "}"
   );
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/completion",
                                   params,
                                   cancellable,
-                                  ide_langserv_completion_provider_complete_cb,
+                                  ide_lsp_completion_provider_complete_cb,
                                   g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static GListModel *
-ide_langserv_completion_provider_populate_finish (IdeCompletionProvider  *provider,
+ide_lsp_completion_provider_populate_finish (IdeCompletionProvider  *provider,
                                                   GAsyncResult           *result,
                                                   GError                **error)
 {
@@ -292,48 +283,48 @@ ide_langserv_completion_provider_populate_finish (IdeCompletionProvider  *provid
 }
 
 static gboolean
-ide_langserv_completion_provider_refilter (IdeCompletionProvider *provider,
+ide_lsp_completion_provider_refilter (IdeCompletionProvider *provider,
                                            IdeCompletionContext  *context,
                                            GListModel            *model)
 {
-  IdeLangservCompletionResults *results = (IdeLangservCompletionResults *)model;
+  IdeLspCompletionResults *results = (IdeLspCompletionResults *)model;
   g_autofree gchar *word = NULL;
 
-  g_assert (IDE_IS_LANGSERV_COMPLETION_PROVIDER (provider));
+  g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (provider));
   g_assert (IDE_IS_COMPLETION_CONTEXT (context));
-  g_assert (IDE_IS_LANGSERV_COMPLETION_RESULTS (results));
+  g_assert (IDE_IS_LSP_COMPLETION_RESULTS (results));
 
   word = ide_completion_context_get_word (context);
-  ide_langserv_completion_results_refilter (results, word);
+  ide_lsp_completion_results_refilter (results, word);
 
   return TRUE;
 }
 
 static void
-ide_langserv_completion_provider_display_proposal (IdeCompletionProvider   *provider,
+ide_lsp_completion_provider_display_proposal (IdeCompletionProvider   *provider,
                                                    IdeCompletionListBoxRow *row,
                                                    IdeCompletionContext    *context,
                                                    const gchar             *typed_text,
                                                    IdeCompletionProposal   *proposal)
 {
-  IdeLangservCompletionItem *item = (IdeLangservCompletionItem *)proposal;
+  IdeLspCompletionItem *item = (IdeLspCompletionItem *)proposal;
   g_autofree gchar *markup = NULL;
 
-  g_assert (IDE_IS_LANGSERV_COMPLETION_PROVIDER (provider));
+  g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (provider));
   g_assert (IDE_IS_COMPLETION_LIST_BOX_ROW (row));
   g_assert (IDE_IS_COMPLETION_CONTEXT (context));
-  g_assert (IDE_IS_LANGSERV_COMPLETION_ITEM (proposal));
+  g_assert (IDE_IS_LSP_COMPLETION_ITEM (proposal));
 
-  markup = ide_langserv_completion_item_get_markup (item, typed_text);
+  markup = ide_lsp_completion_item_get_markup (item, typed_text);
 
-  ide_completion_list_box_row_set_icon_name (row, ide_langserv_completion_item_get_icon_name (item));
+  ide_completion_list_box_row_set_icon_name (row, ide_lsp_completion_item_get_icon_name (item));
   ide_completion_list_box_row_set_left (row, NULL);
   ide_completion_list_box_row_set_center_markup (row, markup);
   ide_completion_list_box_row_set_right (row, NULL);
 }
 
 static void
-ide_langserv_completion_provider_activate_proposal (IdeCompletionProvider *provider,
+ide_lsp_completion_provider_activate_proposal (IdeCompletionProvider *provider,
                                                     IdeCompletionContext  *context,
                                                     IdeCompletionProposal *proposal,
                                                     const GdkEventKey     *key)
@@ -345,12 +336,12 @@ ide_langserv_completion_provider_activate_proposal (IdeCompletionProvider *provi
 
   g_assert (IDE_IS_COMPLETION_PROVIDER (provider));
   g_assert (IDE_IS_COMPLETION_CONTEXT (context));
-  g_assert (IDE_IS_LANGSERV_COMPLETION_ITEM (proposal));
+  g_assert (IDE_IS_LSP_COMPLETION_ITEM (proposal));
 
   buffer = ide_completion_context_get_buffer (context);
   view = ide_completion_context_get_view (context);
 
-  snippet = ide_langserv_completion_item_get_snippet (IDE_LANGSERV_COMPLETION_ITEM (proposal));
+  snippet = ide_lsp_completion_item_get_snippet (IDE_LSP_COMPLETION_ITEM (proposal));
 
   gtk_text_buffer_begin_user_action (buffer);
   if (ide_completion_context_get_bounds (context, &begin, &end))
@@ -360,23 +351,23 @@ ide_langserv_completion_provider_activate_proposal (IdeCompletionProvider *provi
 }
 
 static gchar *
-ide_langserv_completion_provider_get_comment (IdeCompletionProvider *provider,
+ide_lsp_completion_provider_get_comment (IdeCompletionProvider *provider,
                                               IdeCompletionProposal *proposal)
 {
   g_assert (IDE_IS_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_LANGSERV_COMPLETION_ITEM (proposal));
+  g_assert (IDE_IS_LSP_COMPLETION_ITEM (proposal));
 
-  return g_strdup (ide_langserv_completion_item_get_detail (IDE_LANGSERV_COMPLETION_ITEM (proposal)));
+  return g_strdup (ide_lsp_completion_item_get_detail (IDE_LSP_COMPLETION_ITEM (proposal)));
 }
 
 static void
 provider_iface_init (IdeCompletionProviderInterface *iface)
 {
-  iface->get_priority = ide_langserv_completion_provider_get_priority;
-  iface->populate_async = ide_langserv_completion_provider_populate_async;
-  iface->populate_finish = ide_langserv_completion_provider_populate_finish;
-  iface->refilter = ide_langserv_completion_provider_refilter;
-  iface->display_proposal = ide_langserv_completion_provider_display_proposal;
-  iface->activate_proposal = ide_langserv_completion_provider_activate_proposal;
-  iface->get_comment = ide_langserv_completion_provider_get_comment;
+  iface->get_priority = ide_lsp_completion_provider_get_priority;
+  iface->populate_async = ide_lsp_completion_provider_populate_async;
+  iface->populate_finish = ide_lsp_completion_provider_populate_finish;
+  iface->refilter = ide_lsp_completion_provider_refilter;
+  iface->display_proposal = ide_lsp_completion_provider_display_proposal;
+  iface->activate_proposal = ide_lsp_completion_provider_activate_proposal;
+  iface->get_comment = ide_lsp_completion_provider_get_comment;
 }
diff --git a/src/libide/langserv/ide-langserv-completion-provider.h 
b/src/libide/lsp/ide-lsp-completion-provider.h
similarity index 57%
rename from src/libide/langserv/ide-langserv-completion-provider.h
rename to src/libide/lsp/ide-lsp-completion-provider.h
index 3b8290aad..1c7a5b8c8 100644
--- a/src/libide/langserv/ide-langserv-completion-provider.h
+++ b/src/libide/lsp/ide-lsp-completion-provider.h
@@ -1,4 +1,4 @@
-/* ide-langserv-completion-provider.h
+/* ide-lsp-completion-provider.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,23 +20,24 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "ide-object.h"
+#include <libide-sourceview.h>
 
-#include "completion/ide-completion-provider.h"
-#include "langserv/ide-langserv-client.h"
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_COMPLETION_PROVIDER (ide_langserv_completion_provider_get_type())
+#define IDE_TYPE_LSP_COMPLETION_PROVIDER (ide_lsp_completion_provider_get_type())
 
-#define IDE_LANGSERV_COMPLETION_PROVIDER_PRIORITY 200
+#define IDE_LSP_COMPLETION_PROVIDER_PRIORITY 200
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservCompletionProvider, ide_langserv_completion_provider, IDE, 
LANGSERV_COMPLETION_PROVIDER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspCompletionProvider, ide_lsp_completion_provider, IDE, 
LSP_COMPLETION_PROVIDER, IdeObject)
 
-struct _IdeLangservCompletionProviderClass
+struct _IdeLspCompletionProviderClass
 {
   IdeObjectClass parent_class;
 
@@ -45,9 +46,9 @@ struct _IdeLangservCompletionProviderClass
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_completion_provider_get_client (IdeLangservCompletionProvider *self);
+IdeLspClient *ide_lsp_completion_provider_get_client (IdeLspCompletionProvider *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_completion_provider_set_client (IdeLangservCompletionProvider *self,
-                                                                IdeLangservClient             *client);
+void               ide_lsp_completion_provider_set_client (IdeLspCompletionProvider *self,
+                                                                IdeLspClient             *client);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-completion-results.c 
b/src/libide/lsp/ide-lsp-completion-results.c
similarity index 65%
rename from src/libide/langserv/ide-langserv-completion-results.c
rename to src/libide/lsp/ide-lsp-completion-results.c
index 766c7d0df..fc7253d19 100644
--- a/src/libide/langserv/ide-langserv-completion-results.c
+++ b/src/libide/lsp/ide-lsp-completion-results.c
@@ -1,4 +1,4 @@
-/* ide-langserv-completion-results.c
+/* ide-lsp-completion-results.c
  *
  * Copyright 2018-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,17 +18,16 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-completion-results.h"
+#define G_LOG_DOMAIN "ide-lsp-completion-results.h"
 
 #include "config.h"
 
-#include "ide-debug.h"
+#include <libide-sourceview.h>
 
-#include "completion/ide-completion.h"
-#include "langserv/ide-langserv-completion-item.h"
-#include "langserv/ide-langserv-completion-results.h"
+#include "ide-lsp-completion-item.h"
+#include "ide-lsp-completion-results.h"
 
-struct _IdeLangservCompletionResults
+struct _IdeLspCompletionResults
 {
   GObject   parent_instance;
   GVariant *results;
@@ -43,43 +42,43 @@ typedef struct
 
 static void list_model_iface_init (GListModelInterface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (IdeLangservCompletionResults, ide_langserv_completion_results, G_TYPE_OBJECT,
+G_DEFINE_TYPE_WITH_CODE (IdeLspCompletionResults, ide_lsp_completion_results, G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
 
 static void
-ide_langserv_completion_results_finalize (GObject *object)
+ide_lsp_completion_results_finalize (GObject *object)
 {
-  IdeLangservCompletionResults *self = (IdeLangservCompletionResults *)object;
+  IdeLspCompletionResults *self = (IdeLspCompletionResults *)object;
 
   g_clear_pointer (&self->results, g_variant_unref);
   g_clear_pointer (&self->items, g_array_unref);
 
-  G_OBJECT_CLASS (ide_langserv_completion_results_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_completion_results_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_completion_results_class_init (IdeLangservCompletionResultsClass *klass)
+ide_lsp_completion_results_class_init (IdeLspCompletionResultsClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_completion_results_finalize;
+  object_class->finalize = ide_lsp_completion_results_finalize;
 }
 
 static void
-ide_langserv_completion_results_init (IdeLangservCompletionResults *self)
+ide_lsp_completion_results_init (IdeLspCompletionResults *self)
 {
   self->items = g_array_new (FALSE, FALSE, sizeof (Item));
 }
 
-IdeLangservCompletionResults *
-ide_langserv_completion_results_new (GVariant *results)
+IdeLspCompletionResults *
+ide_lsp_completion_results_new (GVariant *results)
 {
-  IdeLangservCompletionResults *self;
+  IdeLspCompletionResults *self;
   g_autoptr(GVariant) items = NULL;
 
   g_return_val_if_fail (results != NULL, NULL);
 
-  self = g_object_new (IDE_TYPE_LANGSERV_COMPLETION_RESULTS, NULL);
+  self = g_object_new (IDE_TYPE_LSP_COMPLETION_RESULTS, NULL);
   self->results = g_variant_ref_sink (results);
 
   /* Possibly unwrap the {items: []} style result. */
@@ -94,50 +93,50 @@ ide_langserv_completion_results_new (GVariant *results)
         self->results = g_steal_pointer (&items);
     }
 
-  ide_langserv_completion_results_refilter (self, NULL);
+  ide_lsp_completion_results_refilter (self, NULL);
 
   return self;
 }
 
 static GType
-ide_langserv_completion_results_get_item_type (GListModel *model)
+ide_lsp_completion_results_get_item_type (GListModel *model)
 {
-  return IDE_TYPE_LANGSERV_COMPLETION_ITEM;
+  return IDE_TYPE_LSP_COMPLETION_ITEM;
 }
 
 static guint
-ide_langserv_completion_results_get_n_items (GListModel *model)
+ide_lsp_completion_results_get_n_items (GListModel *model)
 {
-  IdeLangservCompletionResults *self = (IdeLangservCompletionResults *)model;
+  IdeLspCompletionResults *self = (IdeLspCompletionResults *)model;
 
-  g_assert (IDE_IS_LANGSERV_COMPLETION_RESULTS (self));
+  g_assert (IDE_IS_LSP_COMPLETION_RESULTS (self));
 
   return self->items->len;
 }
 
 static gpointer
-ide_langserv_completion_results_get_item (GListModel *model,
+ide_lsp_completion_results_get_item (GListModel *model,
                                           guint       position)
 {
-  IdeLangservCompletionResults *self = (IdeLangservCompletionResults *)model;
+  IdeLspCompletionResults *self = (IdeLspCompletionResults *)model;
   g_autoptr(GVariant) child = NULL;
   const Item *item;
 
-  g_assert (IDE_IS_LANGSERV_COMPLETION_RESULTS (self));
+  g_assert (IDE_IS_LSP_COMPLETION_RESULTS (self));
   g_assert (self->results != NULL);
 
   item = &g_array_index (self->items, Item, position);
   child = g_variant_get_child_value (self->results, item->index);
 
-  return ide_langserv_completion_item_new (child);
+  return ide_lsp_completion_item_new (child);
 }
 
 static void
 list_model_iface_init (GListModelInterface *iface)
 {
-  iface->get_item = ide_langserv_completion_results_get_item;
-  iface->get_n_items = ide_langserv_completion_results_get_n_items;
-  iface->get_item_type = ide_langserv_completion_results_get_item_type;
+  iface->get_item = ide_lsp_completion_results_get_item;
+  iface->get_n_items = ide_lsp_completion_results_get_n_items;
+  iface->get_item_type = ide_lsp_completion_results_get_item_type;
 }
 
 static gint
@@ -148,7 +147,7 @@ compare_items (const Item *a,
 }
 
 void
-ide_langserv_completion_results_refilter (IdeLangservCompletionResults *self,
+ide_lsp_completion_results_refilter (IdeLspCompletionResults *self,
                                           const gchar                  *typed_text)
 {
   g_autofree gchar *query = NULL;
@@ -157,7 +156,7 @@ ide_langserv_completion_results_refilter (IdeLangservCompletionResults *self,
   guint index = 0;
   guint old_len;
 
-  g_return_if_fail (IDE_IS_LANGSERV_COMPLETION_RESULTS (self));
+  g_return_if_fail (IDE_IS_LSP_COMPLETION_RESULTS (self));
 
   if ((old_len = self->items->len))
     g_array_remove_range (self->items, 0, old_len);
diff --git a/src/libide/langserv/ide-langserv-completion-results.h 
b/src/libide/lsp/ide-lsp-completion-results.h
similarity index 64%
rename from src/libide/langserv/ide-langserv-completion-results.h
rename to src/libide/lsp/ide-lsp-completion-results.h
index 8bbb02cef..24e3d85e2 100644
--- a/src/libide/langserv/ide-langserv-completion-results.h
+++ b/src/libide/lsp/ide-lsp-completion-results.h
@@ -1,4 +1,4 @@
-/* ide-langserv-completion-results.h
+/* ide-lsp-completion-results.h
  *
  * Copyright 2018-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,19 +20,23 @@
 
 #pragma once
 
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
+
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_COMPLETION_RESULTS (ide_langserv_completion_results_get_type())
+#define IDE_TYPE_LSP_COMPLETION_RESULTS (ide_lsp_completion_results_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_FINAL_TYPE (IdeLangservCompletionResults, ide_langserv_completion_results, IDE, 
LANGSERV_COMPLETION_RESULTS, GObject)
+G_DECLARE_FINAL_TYPE (IdeLspCompletionResults, ide_lsp_completion_results, IDE, LSP_COMPLETION_RESULTS, 
GObject)
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservCompletionResults *ide_langserv_completion_results_new      (GVariant                     
*results);
+IdeLspCompletionResults *ide_lsp_completion_results_new      (GVariant                     *results);
 IDE_AVAILABLE_IN_3_32
-void                          ide_langserv_completion_results_refilter (IdeLangservCompletionResults *self,
+void                          ide_lsp_completion_results_refilter (IdeLspCompletionResults *self,
                                                                         const gchar                  
*typed_text);
 
 G_END_DECLS
diff --git a/src/libide/lsp/ide-lsp-diagnostic-provider.c b/src/libide/lsp/ide-lsp-diagnostic-provider.c
new file mode 100644
index 000000000..3dfeb5ce2
--- /dev/null
+++ b/src/libide/lsp/ide-lsp-diagnostic-provider.c
@@ -0,0 +1,253 @@
+/* ide-lsp-diagnostic-provider.c
+ *
+ * Copyright 2016-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-lsp-diagnostic-provider"
+
+#include "config.h"
+
+#include <dazzle.h>
+#include <json-glib/json-glib.h>
+#include <libide-code.h>
+#include <libide-threading.h>
+
+#include "ide-lsp-diagnostic-provider.h"
+
+typedef struct
+{
+  IdeLspClient *client;
+  DzlSignalGroup    *client_signals;
+} IdeLspDiagnosticProviderPrivate;
+
+static void diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspDiagnosticProvider, ide_lsp_diagnostic_provider, IDE_TYPE_OBJECT,
+                                  G_ADD_PRIVATE (IdeLspDiagnosticProvider)
+                                  G_IMPLEMENT_INTERFACE (IDE_TYPE_DIAGNOSTIC_PROVIDER, 
diagnostic_provider_iface_init))
+
+enum {
+  PROP_0,
+  PROP_CLIENT,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_lsp_diagnostic_provider_get_diagnostics_cb (GObject      *object,
+                                                     GAsyncResult *result,
+                                                     gpointer      user_data)
+{
+  IdeLspClient *client = (IdeLspClient *)object;
+  g_autoptr(IdeDiagnostics) diagnostics = NULL;
+  g_autoptr(IdeTask) task = user_data;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (IDE_IS_LSP_CLIENT (client));
+  g_assert (IDE_IS_TASK (task));
+
+  if (!ide_lsp_client_get_diagnostics_finish (client, result, &diagnostics, &error))
+    ide_task_return_error (task, g_steal_pointer (&error));
+  else
+    ide_task_return_pointer (task, g_steal_pointer (&diagnostics), g_object_unref);
+}
+
+static void
+ide_lsp_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
+                                            GFile                 *file,
+                                            GBytes                *content,
+                                            const gchar           *lang_id,
+                                            GCancellable          *cancellable,
+                                            GAsyncReadyCallback    callback,
+                                            gpointer               user_data)
+{
+  IdeLspDiagnosticProvider *self = (IdeLspDiagnosticProvider *)provider;
+  IdeLspDiagnosticProviderPrivate *priv = ide_lsp_diagnostic_provider_get_instance_private (self);
+  g_autoptr(IdeTask) task = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_LSP_DIAGNOSTIC_PROVIDER (self));
+  g_assert (G_IS_FILE (file));
+  g_assert (content != NULL);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, ide_lsp_diagnostic_provider_diagnose_async);
+
+  if (priv->client == NULL)
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_NOT_SUPPORTED,
+                                 "Improperly configured %s is missing IdeLspClient",
+                                 G_OBJECT_TYPE_NAME (self));
+      IDE_EXIT;
+    }
+
+  ide_lsp_client_get_diagnostics_async (priv->client,
+                                        file,
+                                        content,
+                                        lang_id,
+                                        cancellable,
+                                        ide_lsp_diagnostic_provider_get_diagnostics_cb,
+                                        g_steal_pointer (&task));
+
+  IDE_EXIT;
+}
+
+static IdeDiagnostics *
+ide_lsp_diagnostic_provider_diagnose_finish (IdeDiagnosticProvider  *provider,
+                                             GAsyncResult           *result,
+                                             GError                **error)
+{
+  IdeDiagnostics *ret;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_LSP_DIAGNOSTIC_PROVIDER (provider));
+  g_assert (IDE_IS_TASK (result));
+
+  ret = ide_task_propagate_pointer (IDE_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface)
+{
+  iface->diagnose_async = ide_lsp_diagnostic_provider_diagnose_async;
+  iface->diagnose_finish = ide_lsp_diagnostic_provider_diagnose_finish;
+}
+
+static void
+ide_lsp_diagnostic_provider_finalize (GObject *object)
+{
+  IdeLspDiagnosticProvider *self = (IdeLspDiagnosticProvider *)object;
+  IdeLspDiagnosticProviderPrivate *priv = ide_lsp_diagnostic_provider_get_instance_private (self);
+
+  g_clear_object (&priv->client_signals);
+  g_clear_object (&priv->client);
+
+  G_OBJECT_CLASS (ide_lsp_diagnostic_provider_parent_class)->finalize (object);
+}
+
+static void
+ide_lsp_diagnostic_provider_get_property (GObject    *object,
+                                               guint       prop_id,
+                                               GValue     *value,
+                                               GParamSpec *pspec)
+{
+  IdeLspDiagnosticProvider *self = IDE_LSP_DIAGNOSTIC_PROVIDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_CLIENT:
+      g_value_set_object (value, ide_lsp_diagnostic_provider_get_client (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_lsp_diagnostic_provider_set_property (GObject      *object,
+                                               guint         prop_id,
+                                               const GValue *value,
+                                               GParamSpec   *pspec)
+{
+  IdeLspDiagnosticProvider *self = IDE_LSP_DIAGNOSTIC_PROVIDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_CLIENT:
+      ide_lsp_diagnostic_provider_set_client (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_lsp_diagnostic_provider_class_init (IdeLspDiagnosticProviderClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_lsp_diagnostic_provider_finalize;
+  object_class->get_property = ide_lsp_diagnostic_provider_get_property;
+  object_class->set_property = ide_lsp_diagnostic_provider_set_property;
+
+  properties [PROP_CLIENT] =
+    g_param_spec_object ("client",
+                         "Client",
+                         "The Language Server client",
+                         IDE_TYPE_LSP_CLIENT,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_lsp_diagnostic_provider_init (IdeLspDiagnosticProvider *self)
+{
+  IdeLspDiagnosticProviderPrivate *priv = ide_lsp_diagnostic_provider_get_instance_private (self);
+
+  priv->client_signals = dzl_signal_group_new (IDE_TYPE_LSP_CLIENT);
+
+  dzl_signal_group_connect_object (priv->client_signals,
+                                   "published-diagnostics",
+                                   G_CALLBACK (ide_diagnostic_provider_emit_invalidated),
+                                   self,
+                                   G_CONNECT_SWAPPED);
+}
+
+/**
+ * ide_lsp_diagnostic_provider_get_client:
+ *
+ * Gets the client used by diagnostic provider.
+ *
+ * Returns: (nullable) (transfer none): An #IdeLspClient or %NULL.
+ */
+IdeLspClient *
+ide_lsp_diagnostic_provider_get_client (IdeLspDiagnosticProvider *self)
+{
+  IdeLspDiagnosticProviderPrivate *priv = ide_lsp_diagnostic_provider_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_LSP_DIAGNOSTIC_PROVIDER (self), NULL);
+
+  return priv->client;
+}
+
+void
+ide_lsp_diagnostic_provider_set_client (IdeLspDiagnosticProvider *self,
+                                             IdeLspClient             *client)
+{
+  IdeLspDiagnosticProviderPrivate *priv = ide_lsp_diagnostic_provider_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_LSP_DIAGNOSTIC_PROVIDER (self));
+  g_return_if_fail (!client || IDE_IS_LSP_CLIENT (client));
+
+  if (g_set_object (&priv->client, client))
+    {
+      dzl_signal_group_set_target (priv->client_signals, client);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
+    }
+}
diff --git a/src/libide/langserv/ide-langserv-diagnostic-provider.h 
b/src/libide/lsp/ide-lsp-diagnostic-provider.h
similarity index 55%
rename from src/libide/langserv/ide-langserv-diagnostic-provider.h
rename to src/libide/lsp/ide-lsp-diagnostic-provider.h
index f056d6f4b..cc63d9cd7 100644
--- a/src/libide/langserv/ide-langserv-diagnostic-provider.h
+++ b/src/libide/lsp/ide-lsp-diagnostic-provider.h
@@ -1,4 +1,4 @@
-/* ide-langserv-diagnostic-provider.h
+/* ide-lsp-diagnostic-provider.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,35 +20,33 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "ide-object.h"
+#include <libide-code.h>
 
-#include "diagnostics/ide-diagnostic-provider.h"
-#include "langserv/ide-langserv-client.h"
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_DIAGNOSTIC_PROVIDER (ide_langserv_diagnostic_provider_get_type())
+#define IDE_TYPE_LSP_DIAGNOSTIC_PROVIDER (ide_lsp_diagnostic_provider_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservDiagnosticProvider, ide_langserv_diagnostic_provider, IDE, 
LANGSERV_DIAGNOSTIC_PROVIDER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspDiagnosticProvider, ide_lsp_diagnostic_provider, IDE, 
LSP_DIAGNOSTIC_PROVIDER, IdeObject)
 
-struct _IdeLangservDiagnosticProviderClass
+struct _IdeLspDiagnosticProviderClass
 {
   IdeObjectClass parent_class;
 
   /*< private >*/
-  gpointer _reserved1;
-  gpointer _reserved2;
-  gpointer _reserved3;
-  gpointer _reserved4;
+  gpointer _reserved[16];
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_diagnostic_provider_get_client (IdeLangservDiagnosticProvider *self);
+IdeLspClient *ide_lsp_diagnostic_provider_get_client (IdeLspDiagnosticProvider *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_diagnostic_provider_set_client (IdeLangservDiagnosticProvider *self,
-                                                                IdeLangservClient             *client);
+void               ide_lsp_diagnostic_provider_set_client (IdeLspDiagnosticProvider *self,
+                                                                IdeLspClient             *client);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-formatter.c b/src/libide/lsp/ide-lsp-formatter.c
similarity index 50%
rename from src/libide/langserv/ide-langserv-formatter.c
rename to src/libide/lsp/ide-lsp-formatter.c
index 1bdfaee97..0a5c4c244 100644
--- a/src/libide/langserv/ide-langserv-formatter.c
+++ b/src/libide/lsp/ide-lsp-formatter.c
@@ -1,4 +1,4 @@
-/* ide-langserv-formatter.c
+/* ide-lsp-formatter.c
  *
  * Copyright 2017-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,28 +18,21 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-formatter"
+#define G_LOG_DOMAIN "ide-lsp-formatter"
 
 #include "config.h"
 
 #include <jsonrpc-glib.h>
 
-#include "ide-context.h"
-#include "ide-debug.h"
+#include <libide-code.h>
+#include <libide-threading.h>
 
-#include "buffers/ide-buffer.h"
-#include "buffers/ide-buffer-manager.h"
-#include "diagnostics/ide-source-location.h"
-#include "diagnostics/ide-source-range.h"
-#include "langserv/ide-langserv-formatter.h"
-#include "projects/ide-project-edit.h"
-#include "threading/ide-task.h"
-#include "util/ide-glib.h"
+#include "ide-lsp-formatter.h"
 
 typedef struct
 {
-  IdeLangservClient *client;
-} IdeLangservFormatterPrivate;
+  IdeLspClient *client;
+} IdeLspFormatterPrivate;
 
 enum {
   PROP_0,
@@ -49,67 +42,65 @@ enum {
 
 static void formatter_iface_init (IdeFormatterInterface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (IdeLangservFormatter, ide_langserv_formatter, IDE_TYPE_OBJECT,
-                         G_ADD_PRIVATE (IdeLangservFormatter)
+G_DEFINE_TYPE_WITH_CODE (IdeLspFormatter, ide_lsp_formatter, IDE_TYPE_OBJECT,
+                         G_ADD_PRIVATE (IdeLspFormatter)
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_FORMATTER, formatter_iface_init))
 
 static GParamSpec *properties [N_PROPS];
 
 /**
- * ide_langserv_formatter_get_client:
- * @self: a #IdeLangservFormatter
+ * ide_lsp_formatter_get_client:
+ * @self: a #IdeLspFormatter
  *
  * Gets the client to use for the formatter.
  *
- * Returns: (transfer none): An #IdeLangservClient or %NULL.
- *
- * Since: 3.32
+ * Returns: (transfer none): An #IdeLspClient or %NULL.
  */
-IdeLangservClient *
-ide_langserv_formatter_get_client (IdeLangservFormatter *self)
+IdeLspClient *
+ide_lsp_formatter_get_client (IdeLspFormatter *self)
 {
-  IdeLangservFormatterPrivate *priv = ide_langserv_formatter_get_instance_private (self);
+  IdeLspFormatterPrivate *priv = ide_lsp_formatter_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_FORMATTER (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_FORMATTER (self), NULL);
 
   return priv->client;
 }
 
 void
-ide_langserv_formatter_set_client (IdeLangservFormatter *self,
-                                   IdeLangservClient    *client)
+ide_lsp_formatter_set_client (IdeLspFormatter *self,
+                              IdeLspClient    *client)
 {
-  IdeLangservFormatterPrivate *priv = ide_langserv_formatter_get_instance_private (self);
+  IdeLspFormatterPrivate *priv = ide_lsp_formatter_get_instance_private (self);
 
-  g_return_if_fail (IDE_IS_LANGSERV_FORMATTER (self));
+  g_return_if_fail (IDE_IS_LSP_FORMATTER (self));
 
   if (g_set_object (&priv->client, client))
     g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
 }
 
 static void
-ide_langserv_formatter_finalize (GObject *object)
+ide_lsp_formatter_finalize (GObject *object)
 {
-  IdeLangservFormatter *self = (IdeLangservFormatter *)object;
-  IdeLangservFormatterPrivate *priv = ide_langserv_formatter_get_instance_private (self);
+  IdeLspFormatter *self = (IdeLspFormatter *)object;
+  IdeLspFormatterPrivate *priv = ide_lsp_formatter_get_instance_private (self);
 
   g_clear_object (&priv->client);
 
-  G_OBJECT_CLASS (ide_langserv_formatter_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_formatter_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_formatter_get_property (GObject    *object,
-                                     guint       prop_id,
-                                     GValue     *value,
-                                     GParamSpec *pspec)
+ide_lsp_formatter_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
 {
-  IdeLangservFormatter *self = IDE_LANGSERV_FORMATTER (object);
+  IdeLspFormatter *self = IDE_LSP_FORMATTER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      g_value_set_object (value, ide_langserv_formatter_get_client (self));
+      g_value_set_object (value, ide_lsp_formatter_get_client (self));
       break;
 
     default:
@@ -118,17 +109,17 @@ ide_langserv_formatter_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_formatter_set_property (GObject      *object,
-                                     guint         prop_id,
-                                     const GValue *value,
-                                     GParamSpec   *pspec)
+ide_lsp_formatter_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
 {
-  IdeLangservFormatter *self = IDE_LANGSERV_FORMATTER (object);
+  IdeLspFormatter *self = IDE_LSP_FORMATTER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      ide_langserv_formatter_set_client (self, g_value_get_object (value));
+      ide_lsp_formatter_set_client (self, g_value_get_object (value));
       break;
 
     default:
@@ -137,44 +128,44 @@ ide_langserv_formatter_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_formatter_class_init (IdeLangservFormatterClass *klass)
+ide_lsp_formatter_class_init (IdeLspFormatterClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_formatter_finalize;
-  object_class->get_property = ide_langserv_formatter_get_property;
-  object_class->set_property = ide_langserv_formatter_set_property;
+  object_class->finalize = ide_lsp_formatter_finalize;
+  object_class->get_property = ide_lsp_formatter_get_property;
+  object_class->set_property = ide_lsp_formatter_set_property;
 
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
                          "The client to communicate over",
-                         IDE_TYPE_LANGSERV_CLIENT,
+                         IDE_TYPE_LSP_CLIENT,
                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static void
-ide_langserv_formatter_init (IdeLangservFormatter *self)
+ide_lsp_formatter_init (IdeLspFormatter *self)
 {
 }
 
 static void
-ide_langserv_formatter_apply_changes (IdeLangservFormatter *self,
-                                      IdeBuffer            *buffer,
-                                      GVariant             *text_edits)
+ide_lsp_formatter_apply_changes (IdeLspFormatter *self,
+                                 IdeBuffer       *buffer,
+                                 GVariant        *text_edits)
 {
-  g_autoptr(GPtrArray) project_edits = NULL;
+  g_autoptr(GPtrArray) edits = NULL;
+  g_autoptr(IdeContext) context = NULL;
   IdeBufferManager *buffer_manager;
-  IdeContext *context;
   GVariant *text_edit;
-  IdeFile *ifile;
+  GFile *file;
   GVariantIter iter;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_FORMATTER (self));
+  g_assert (IDE_IS_LSP_FORMATTER (self));
   g_assert (text_edits != NULL);
 
   if (!g_variant_is_container (text_edits))
@@ -183,17 +174,16 @@ ide_langserv_formatter_apply_changes (IdeLangservFormatter *self,
       IDE_EXIT;
     }
 
-  ifile = ide_buffer_get_file (buffer);
-  project_edits = g_ptr_array_new_with_free_func (g_object_unref);
+  file = ide_buffer_get_file (buffer);
+  edits = g_ptr_array_new_with_free_func (g_object_unref);
 
   g_variant_iter_init (&iter, text_edits);
 
   while (g_variant_iter_loop (&iter, "v", &text_edit))
     {
-      g_autoptr(IdeSourceLocation) begin_location = NULL;
-      g_autoptr(IdeSourceLocation) end_location = NULL;
-      g_autoptr(IdeSourceRange) range = NULL;
-      g_autoptr(IdeProjectEdit) edit = NULL;
+      g_autoptr(IdeLocation) begin_location = NULL;
+      g_autoptr(IdeLocation) end_location = NULL;
+      g_autoptr(IdeRange) range = NULL;
       const gchar *new_text = NULL;
       gboolean success;
       struct {
@@ -221,44 +211,39 @@ ide_langserv_formatter_apply_changes (IdeLangservFormatter *self,
           continue;
         }
 
-      begin_location = ide_source_location_new (ifile, begin.line, begin.column, 0);
-      end_location = ide_source_location_new (ifile, end.line, end.column, 0);
-      range = ide_source_range_new (begin_location, end_location);
-
-      edit = g_object_new (IDE_TYPE_PROJECT_EDIT,
-                           "range", range,
-                           "replacement", new_text,
-                           NULL);
+      begin_location = ide_location_new (file, begin.line, begin.column);
+      end_location = ide_location_new (file, end.line, end.column);
+      range = ide_range_new (begin_location, end_location);
 
-      g_ptr_array_add (project_edits, g_steal_pointer (&edit));
+      g_ptr_array_add (edits, ide_text_edit_new (range, new_text));
     }
 
-  context = ide_buffer_get_context (buffer);
-  buffer_manager = ide_context_get_buffer_manager (context);
+  context = ide_buffer_ref_context (buffer);
+  buffer_manager = ide_buffer_manager_from_context (context);
 
   ide_buffer_manager_apply_edits_async (buffer_manager,
-                                        IDE_PTR_ARRAY_STEAL_FULL (&project_edits),
+                                        IDE_PTR_ARRAY_STEAL_FULL (&edits),
                                         NULL, NULL, NULL);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_formatter_format_call_cb (GObject      *object,
-                                       GAsyncResult *result,
-                                       gpointer      user_data)
+ide_lsp_formatter_format_call_cb (GObject      *object,
+                                  GAsyncResult *result,
+                                  gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
+  IdeLspClient *client = (IdeLspClient *)object;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GError) error = NULL;
   g_autoptr(GVariant) reply = NULL;
-  IdeLangservFormatter *self;
+  IdeLspFormatter *self;
   IdeBuffer *buffer;
 
-  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (client));
+  g_return_if_fail (IDE_IS_LSP_CLIENT (client));
   g_return_if_fail (G_IS_ASYNC_RESULT (result));
 
-  if (!ide_langserv_client_call_finish (client, result, &reply, &error))
+  if (!ide_lsp_client_call_finish (client, result, &reply, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       return;
@@ -267,24 +252,24 @@ ide_langserv_formatter_format_call_cb (GObject      *object,
   self = ide_task_get_source_object (task);
   buffer = ide_task_get_task_data (task);
 
-  g_assert (IDE_IS_LANGSERV_FORMATTER (self));
+  g_assert (IDE_IS_LSP_FORMATTER (self));
   g_assert (IDE_IS_BUFFER (buffer));
 
-  ide_langserv_formatter_apply_changes (self, buffer, reply);
+  ide_lsp_formatter_apply_changes (self, buffer, reply);
 
   ide_task_return_boolean (task, TRUE);
 }
 
 static void
-ide_langserv_formatter_format_async (IdeFormatter        *formatter,
-                                     IdeBuffer           *buffer,
-                                     IdeFormatterOptions *options,
-                                     GCancellable        *cancellable,
-                                     GAsyncReadyCallback  callback,
-                                     gpointer             user_data)
+ide_lsp_formatter_format_async (IdeFormatter        *formatter,
+                                IdeBuffer           *buffer,
+                                IdeFormatterOptions *options,
+                                GCancellable        *cancellable,
+                                GAsyncReadyCallback  callback,
+                                gpointer             user_data)
 {
-  IdeLangservFormatter *self = (IdeLangservFormatter *)formatter;
-  IdeLangservFormatterPrivate *priv = ide_langserv_formatter_get_instance_private (self);
+  IdeLspFormatter *self = (IdeLspFormatter *)formatter;
+  IdeLspFormatterPrivate *priv = ide_lsp_formatter_get_instance_private (self);
   g_autoptr(GVariant) params = NULL;
   g_autoptr(IdeTask) task = NULL;
   g_autofree gchar *uri = NULL;
@@ -295,18 +280,18 @@ ide_langserv_formatter_format_async (IdeFormatter        *formatter,
   gint tab_size;
   gboolean insert_spaces;
 
-  g_assert (IDE_IS_LANGSERV_FORMATTER (self));
+  g_assert (IDE_IS_LSP_FORMATTER (self));
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_formatter_format_async);
+  ide_task_set_source_tag (task, ide_lsp_formatter_format_async);
   ide_task_set_task_data (task, g_object_ref (buffer), g_object_unref);
 
   gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &begin, &end);
   gtk_text_iter_order (&begin, &end);
 
   version = ide_buffer_get_change_count (buffer);
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
   text = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &begin, &end, TRUE);
 
   tab_size = ide_formatter_options_get_tab_width (options);
@@ -324,18 +309,18 @@ ide_langserv_formatter_format_async (IdeFormatter        *formatter,
     "}"
   );
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/formatting",
                                   params,
                                   cancellable,
-                                  ide_langserv_formatter_format_call_cb,
+                                  ide_lsp_formatter_format_call_cb,
                                   g_steal_pointer (&task));
 }
 
 static gboolean
-ide_langserv_formatter_format_finish (IdeFormatter  *self,
-                                      GAsyncResult  *result,
-                                      GError       **error)
+ide_lsp_formatter_format_finish (IdeFormatter  *self,
+                                 GAsyncResult  *result,
+                                 GError       **error)
 {
   g_assert (IDE_IS_FORMATTER (self));
   g_assert (IDE_IS_TASK (result));
@@ -344,17 +329,17 @@ ide_langserv_formatter_format_finish (IdeFormatter  *self,
 }
 
 static void
-ide_langserv_formatter_format_range_async (IdeFormatter        *formatter,
-                                           IdeBuffer           *buffer,
-                                           IdeFormatterOptions *options,
-                                           const GtkTextIter   *begin,
-                                           const GtkTextIter   *end,
-                                           GCancellable        *cancellable,
-                                           GAsyncReadyCallback  callback,
-                                           gpointer             user_data)
+ide_lsp_formatter_format_range_async (IdeFormatter        *formatter,
+                                      IdeBuffer           *buffer,
+                                      IdeFormatterOptions *options,
+                                      const GtkTextIter   *begin,
+                                      const GtkTextIter   *end,
+                                      GCancellable        *cancellable,
+                                      GAsyncReadyCallback  callback,
+                                      gpointer             user_data)
 {
-  IdeLangservFormatter *self = (IdeLangservFormatter *)formatter;
-  IdeLangservFormatterPrivate *priv = ide_langserv_formatter_get_instance_private (self);
+  IdeLspFormatter *self = (IdeLspFormatter *)formatter;
+  IdeLspFormatterPrivate *priv = ide_lsp_formatter_get_instance_private (self);
   g_autoptr(GVariant) params = NULL;
   g_autoptr(IdeTask) task = NULL;
   g_autofree gchar *uri = NULL;
@@ -367,11 +352,11 @@ ide_langserv_formatter_format_range_async (IdeFormatter        *formatter,
     gint character;
   } b, e;
 
-  g_assert (IDE_IS_LANGSERV_FORMATTER (self));
+  g_assert (IDE_IS_LSP_FORMATTER (self));
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_formatter_format_async);
+  ide_task_set_source_tag (task, ide_lsp_formatter_format_async);
   ide_task_set_task_data (task, g_object_ref (buffer), g_object_unref);
 
   if (gtk_text_iter_compare (begin, end) > 0)
@@ -382,7 +367,7 @@ ide_langserv_formatter_format_range_async (IdeFormatter        *formatter,
     }
 
   version = ide_buffer_get_change_count (buffer);
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
   text = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), begin, end, TRUE);
 
   tab_size = ide_formatter_options_get_tab_width (options);
@@ -416,18 +401,18 @@ ide_langserv_formatter_format_range_async (IdeFormatter        *formatter,
     "}"
   );
 
-  ide_langserv_client_call_async (priv->client,
-                                  "textDocument/rangeFormatting",
-                                  params,
-                                  cancellable,
-                                  ide_langserv_formatter_format_call_cb,
-                                  g_steal_pointer (&task));
+  ide_lsp_client_call_async (priv->client,
+                             "textDocument/rangeFormatting",
+                             params,
+                             cancellable,
+                             ide_lsp_formatter_format_call_cb,
+                             g_steal_pointer (&task));
 }
 
 static gboolean
-ide_langserv_formatter_format_range_finish (IdeFormatter  *self,
-                                            GAsyncResult  *result,
-                                            GError       **error)
+ide_lsp_formatter_format_range_finish (IdeFormatter  *self,
+                                       GAsyncResult  *result,
+                                       GError       **error)
 {
   g_assert (IDE_IS_FORMATTER (self));
   g_assert (IDE_IS_TASK (result));
@@ -438,8 +423,8 @@ ide_langserv_formatter_format_range_finish (IdeFormatter  *self,
 static void
 formatter_iface_init (IdeFormatterInterface *iface)
 {
-  iface->format_async = ide_langserv_formatter_format_async;
-  iface->format_finish = ide_langserv_formatter_format_finish;
-  iface->format_range_async = ide_langserv_formatter_format_range_async;
-  iface->format_range_finish = ide_langserv_formatter_format_range_finish;
+  iface->format_async = ide_lsp_formatter_format_async;
+  iface->format_finish = ide_lsp_formatter_format_finish;
+  iface->format_range_async = ide_lsp_formatter_format_range_async;
+  iface->format_range_finish = ide_lsp_formatter_format_range_finish;
 }
diff --git a/src/libide/langserv/ide-langserv-formatter.h b/src/libide/lsp/ide-lsp-formatter.h
similarity index 60%
rename from src/libide/langserv/ide-langserv-formatter.h
rename to src/libide/lsp/ide-lsp-formatter.h
index 8a473901e..d842ed4bb 100644
--- a/src/libide/langserv/ide-langserv-formatter.h
+++ b/src/libide/lsp/ide-lsp-formatter.h
@@ -1,4 +1,4 @@
-/* ide-langserv-formatter.h
+/* ide-lsp-formatter.h
  *
  * Copyright 2017-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,20 +20,22 @@
 
 #pragma once
 
-#include "ide-object.h"
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "formatting/ide-formatter.h"
-#include "langserv/ide-langserv-client.h"
+#include <libide-code.h>
+
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_FORMATTER (ide_langserv_formatter_get_type())
+#define IDE_TYPE_LSP_FORMATTER (ide_lsp_formatter_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_FINAL_TYPE (IdeLangservFormatter, ide_langserv_formatter, IDE, LANGSERV_FORMATTER, IdeObject)
+G_DECLARE_FINAL_TYPE (IdeLspFormatter, ide_lsp_formatter, IDE, LSP_FORMATTER, IdeObject)
 
-struct _IdeLangservFormatter
+struct _IdeLspFormatter
 {
   IdeObject parent_class;
 
@@ -42,9 +44,9 @@ struct _IdeLangservFormatter
 };
 
 IDE_AVAILABLE_IN_3_32
-void                  ide_langserv_formatter_set_client (IdeLangservFormatter *self,
-                                                         IdeLangservClient    *client);
+void                  ide_lsp_formatter_set_client (IdeLspFormatter *self,
+                                                         IdeLspClient    *client);
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient    *ide_langserv_formatter_get_client (IdeLangservFormatter *self);
+IdeLspClient    *ide_lsp_formatter_get_client (IdeLspFormatter *self);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-highlighter.c b/src/libide/lsp/ide-lsp-highlighter.c
similarity index 67%
rename from src/libide/langserv/ide-langserv-highlighter.c
rename to src/libide/lsp/ide-lsp-highlighter.c
index 4b1a476cc..20b570b67 100644
--- a/src/libide/langserv/ide-langserv-highlighter.c
+++ b/src/libide/lsp/ide-lsp-highlighter.c
@@ -1,4 +1,4 @@
-/* ide-langserv-highlighter.c
+/* ide-lsp-highlighter.c
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,18 +18,15 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-highlighter"
+#define G_LOG_DOMAIN "ide-lsp-highlighter"
 
 #include "config.h"
 
 #include <dazzle.h>
+#include <libide-code.h>
 #include <jsonrpc-glib.h>
 
-#include "ide-debug.h"
-
-#include "highlighting/ide-highlight-engine.h"
-#include "highlighting/ide-highlight-index.h"
-#include "langserv/ide-langserv-highlighter.h"
+#include "ide-lsp-highlighter.h"
 
 #define DELAY_TIMEOUT_MSEC 333
 
@@ -44,7 +41,7 @@ typedef struct
 {
   IdeHighlightEngine *engine;
 
-  IdeLangservClient  *client;
+  IdeLspClient  *client;
   IdeHighlightIndex  *index;
   DzlSignalGroup     *buffer_signals;
 
@@ -52,13 +49,13 @@ typedef struct
 
   guint               active : 1;
   guint               dirty : 1;
-} IdeLangservHighlighterPrivate;
+} IdeLspHighlighterPrivate;
 
 static void highlighter_iface_init                (IdeHighlighterInterface *iface);
-static void ide_langserv_highlighter_queue_update (IdeLangservHighlighter  *self);
+static void ide_lsp_highlighter_queue_update (IdeLspHighlighter  *self);
 
-G_DEFINE_TYPE_WITH_CODE (IdeLangservHighlighter, ide_langserv_highlighter, IDE_TYPE_OBJECT,
-                         G_ADD_PRIVATE (IdeLangservHighlighter)
+G_DEFINE_TYPE_WITH_CODE (IdeLspHighlighter, ide_lsp_highlighter, IDE_TYPE_OBJECT,
+                         G_ADD_PRIVATE (IdeLspHighlighter)
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_HIGHLIGHTER, highlighter_iface_init))
 
 enum {
@@ -70,14 +67,14 @@ enum {
 static GParamSpec *properties [N_PROPS];
 
 static void
-ide_langserv_highlighter_set_index (IdeLangservHighlighter *self,
+ide_lsp_highlighter_set_index (IdeLspHighlighter *self,
                                     IdeHighlightIndex      *index)
 {
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
 
   g_clear_pointer (&priv->index, ide_highlight_index_unref);
   if (index != NULL)
@@ -95,26 +92,26 @@ ide_langserv_highlighter_set_index (IdeLangservHighlighter *self,
 }
 
 static void
-ide_langserv_highlighter_document_symbol_cb (GObject      *object,
+ide_lsp_highlighter_document_symbol_cb (GObject      *object,
                                              GAsyncResult *result,
                                              gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
-  g_autoptr(IdeLangservHighlighter) self = user_data;
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspClient *client = (IdeLspClient *)object;
+  g_autoptr(IdeLspHighlighter) self = user_data;
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
   g_autoptr(GVariant) return_value = NULL;
   g_autoptr(GError) error = NULL;
   GVariantIter iter;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
 
   priv->active = FALSE;
 
-  if (!ide_langserv_client_call_finish (client, result, &return_value, &error))
+  if (!ide_lsp_client_call_finish (client, result, &return_value, &error))
     {
       if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
         g_debug ("%s", error->message);
@@ -181,22 +178,22 @@ ide_langserv_highlighter_document_symbol_cb (GObject      *object,
             ide_highlight_index_insert (index, name, (gpointer)tag);
         }
 
-      ide_langserv_highlighter_set_index (self, index);
+      ide_lsp_highlighter_set_index (self, index);
     }
 
   if (priv->dirty)
-    ide_langserv_highlighter_queue_update (self);
+    ide_lsp_highlighter_queue_update (self);
 
   IDE_EXIT;
 }
 
 static gboolean
-ide_langserv_highlighter_update_symbols (gpointer data)
+ide_lsp_highlighter_update_symbols (gpointer data)
 {
-  IdeLangservHighlighter *self = data;
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighter *self = data;
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
 
   priv->queued_update = 0;
 
@@ -207,7 +204,7 @@ ide_langserv_highlighter_update_symbols (gpointer data)
       IdeBuffer *buffer;
 
       buffer = ide_highlight_engine_get_buffer (priv->engine);
-      uri = ide_buffer_get_uri (buffer);
+      uri = ide_buffer_dup_uri (buffer);
 
       params = JSONRPC_MESSAGE_NEW (
         "textDocument", "{",
@@ -218,11 +215,11 @@ ide_langserv_highlighter_update_symbols (gpointer data)
       priv->active = TRUE;
       priv->dirty = FALSE;
 
-      ide_langserv_client_call_async (priv->client,
+      ide_lsp_client_call_async (priv->client,
                                       "textDocument/documentSymbol",
                                       params,
                                       NULL,
-                                      ide_langserv_highlighter_document_symbol_cb,
+                                      ide_lsp_highlighter_document_symbol_cb,
                                       g_object_ref (self));
     }
 
@@ -230,13 +227,13 @@ ide_langserv_highlighter_update_symbols (gpointer data)
 }
 
 static void
-ide_langserv_highlighter_queue_update (IdeLangservHighlighter *self)
+ide_lsp_highlighter_queue_update (IdeLspHighlighter *self)
 {
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
 
   priv->dirty = TRUE;
 
@@ -248,7 +245,7 @@ ide_langserv_highlighter_queue_update (IdeLangservHighlighter *self)
   if (priv->queued_update == 0 && priv->active == FALSE)
     {
       priv->queued_update = g_timeout_add (DELAY_TIMEOUT_MSEC,
-                                           ide_langserv_highlighter_update_symbols,
+                                           ide_lsp_highlighter_update_symbols,
                                            self);
     }
 
@@ -256,20 +253,20 @@ ide_langserv_highlighter_queue_update (IdeLangservHighlighter *self)
 }
 
 static void
-ide_langserv_highlighter_buffer_line_flags_changed (IdeLangservHighlighter *self,
+ide_lsp_highlighter_buffer_line_flags_changed (IdeLspHighlighter *self,
                                                     IdeBuffer              *buffer)
 {
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
   g_assert (IDE_IS_BUFFER (buffer));
 
-  ide_langserv_highlighter_queue_update (self);
+  ide_lsp_highlighter_queue_update (self);
 }
 
 static void
-ide_langserv_highlighter_dispose (GObject *object)
+ide_lsp_highlighter_dispose (GObject *object)
 {
-  IdeLangservHighlighter *self = (IdeLangservHighlighter *)object;
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighter *self = (IdeLspHighlighter *)object;
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
   priv->engine = NULL;
 
@@ -279,21 +276,21 @@ ide_langserv_highlighter_dispose (GObject *object)
   g_clear_object (&priv->buffer_signals);
   g_clear_object (&priv->client);
 
-  G_OBJECT_CLASS (ide_langserv_highlighter_parent_class)->dispose (object);
+  G_OBJECT_CLASS (ide_lsp_highlighter_parent_class)->dispose (object);
 }
 
 static void
-ide_langserv_highlighter_get_property (GObject    *object,
+ide_lsp_highlighter_get_property (GObject    *object,
                                        guint       prop_id,
                                        GValue     *value,
                                        GParamSpec *pspec)
 {
-  IdeLangservHighlighter *self = IDE_LANGSERV_HIGHLIGHTER (object);
+  IdeLspHighlighter *self = IDE_LSP_HIGHLIGHTER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      g_value_set_object (value, ide_langserv_highlighter_get_client (self));
+      g_value_set_object (value, ide_lsp_highlighter_get_client (self));
       break;
 
     default:
@@ -302,17 +299,17 @@ ide_langserv_highlighter_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_highlighter_set_property (GObject      *object,
+ide_lsp_highlighter_set_property (GObject      *object,
                                        guint         prop_id,
                                        const GValue *value,
                                        GParamSpec   *pspec)
 {
-  IdeLangservHighlighter *self = IDE_LANGSERV_HIGHLIGHTER (object);
+  IdeLspHighlighter *self = IDE_LSP_HIGHLIGHTER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      ide_langserv_highlighter_set_client (self, g_value_get_object (value));
+      ide_lsp_highlighter_set_client (self, g_value_get_object (value));
       break;
 
     default:
@@ -321,28 +318,28 @@ ide_langserv_highlighter_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_highlighter_class_init (IdeLangservHighlighterClass *klass)
+ide_lsp_highlighter_class_init (IdeLspHighlighterClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->dispose = ide_langserv_highlighter_dispose;
-  object_class->get_property = ide_langserv_highlighter_get_property;
-  object_class->set_property = ide_langserv_highlighter_set_property;
+  object_class->dispose = ide_lsp_highlighter_dispose;
+  object_class->get_property = ide_lsp_highlighter_get_property;
+  object_class->set_property = ide_lsp_highlighter_set_property;
 
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
                          "Client",
-                         IDE_TYPE_LANGSERV_CLIENT,
+                         IDE_TYPE_LSP_CLIENT,
                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static void
-ide_langserv_highlighter_init (IdeLangservHighlighter *self)
+ide_lsp_highlighter_init (IdeLspHighlighter *self)
 {
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
   priv->buffer_signals = dzl_signal_group_new (IDE_TYPE_BUFFER);
 
@@ -356,40 +353,38 @@ ide_langserv_highlighter_init (IdeLangservHighlighter *self)
    */
   dzl_signal_group_connect_object (priv->buffer_signals,
                                    "line-flags-changed",
-                                   G_CALLBACK (ide_langserv_highlighter_buffer_line_flags_changed),
+                                   G_CALLBACK (ide_lsp_highlighter_buffer_line_flags_changed),
                                    self,
                                    G_CONNECT_SWAPPED);
 }
 
 /**
- * ide_langserv_highlighter_get_client:
- *
- * Returns: (transfer none) (nullable): An #IdeLangservHighlighter or %NULL.
+ * ide_lsp_highlighter_get_client:
  *
- * Since: 3.32
+ * Returns: (transfer none) (nullable): An #IdeLspHighlighter or %NULL.
  */
-IdeLangservClient *
-ide_langserv_highlighter_get_client (IdeLangservHighlighter *self)
+IdeLspClient *
+ide_lsp_highlighter_get_client (IdeLspHighlighter *self)
 {
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_HIGHLIGHTER (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_HIGHLIGHTER (self), NULL);
 
   return priv->client;
 }
 
 void
-ide_langserv_highlighter_set_client (IdeLangservHighlighter *self,
-                                     IdeLangservClient      *client)
+ide_lsp_highlighter_set_client (IdeLspHighlighter *self,
+                                     IdeLspClient      *client)
 {
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
-  g_return_if_fail (IDE_IS_LANGSERV_HIGHLIGHTER (self));
-  g_return_if_fail (!client || IDE_IS_LANGSERV_CLIENT (client));
+  g_return_if_fail (IDE_IS_LSP_HIGHLIGHTER (self));
+  g_return_if_fail (!client || IDE_IS_LSP_CLIENT (client));
 
   if (g_set_object (&priv->client, client))
     {
-      ide_langserv_highlighter_queue_update (self);
+      ide_lsp_highlighter_queue_update (self);
       g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
     }
 }
@@ -424,19 +419,19 @@ select_next_word (GtkTextIter *begin,
 }
 
 static void
-ide_langserv_highlighter_update (IdeHighlighter       *highlighter,
+ide_lsp_highlighter_update (IdeHighlighter       *highlighter,
                                  IdeHighlightCallback  callback,
                                  const GtkTextIter    *range_begin,
                                  const GtkTextIter    *range_end,
                                  GtkTextIter          *location)
 {
-  IdeLangservHighlighter *self = (IdeLangservHighlighter *)highlighter;
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighter *self = (IdeLspHighlighter *)highlighter;
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
   GtkSourceBuffer *source_buffer;
   GtkTextIter begin;
   GtkTextIter end;
 
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
   g_assert (callback != NULL);
 
   if (priv->index == NULL)
@@ -488,15 +483,15 @@ completed:
 }
 
 static void
-ide_langserv_highlighter_set_engine (IdeHighlighter     *highlighter,
+ide_lsp_highlighter_set_engine (IdeHighlighter     *highlighter,
                                      IdeHighlightEngine *engine)
 {
-  IdeLangservHighlighter *self = (IdeLangservHighlighter *)highlighter;
-  IdeLangservHighlighterPrivate *priv = ide_langserv_highlighter_get_instance_private (self);
+  IdeLspHighlighter *self = (IdeLspHighlighter *)highlighter;
+  IdeLspHighlighterPrivate *priv = ide_lsp_highlighter_get_instance_private (self);
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_HIGHLIGHTER (self));
+  g_assert (IDE_IS_LSP_HIGHLIGHTER (self));
   g_assert (!engine || IDE_IS_HIGHLIGHT_ENGINE (engine));
 
   priv->engine = engine;
@@ -509,7 +504,7 @@ ide_langserv_highlighter_set_engine (IdeHighlighter     *highlighter,
 
       buffer = ide_highlight_engine_get_buffer (engine);
       dzl_signal_group_set_target (priv->buffer_signals, buffer);
-      ide_langserv_highlighter_queue_update (self);
+      ide_lsp_highlighter_queue_update (self);
     }
 
   IDE_EXIT;
@@ -518,6 +513,6 @@ ide_langserv_highlighter_set_engine (IdeHighlighter     *highlighter,
 static void
 highlighter_iface_init (IdeHighlighterInterface *iface)
 {
-  iface->update = ide_langserv_highlighter_update;
-  iface->set_engine = ide_langserv_highlighter_set_engine;
+  iface->update = ide_lsp_highlighter_update;
+  iface->set_engine = ide_lsp_highlighter_set_engine;
 }
diff --git a/src/libide/langserv/ide-langserv-highlighter.h b/src/libide/lsp/ide-lsp-highlighter.h
similarity index 55%
rename from src/libide/langserv/ide-langserv-highlighter.h
rename to src/libide/lsp/ide-lsp-highlighter.h
index 9c0463281..603c63be0 100644
--- a/src/libide/langserv/ide-langserv-highlighter.h
+++ b/src/libide/lsp/ide-lsp-highlighter.h
@@ -1,4 +1,4 @@
-/* ide-langserv-highlighter.h
+/* ide-lsp-highlighter.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,34 +20,33 @@
 
 #pragma once
 
-#include "ide-object.h"
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "highlighting/ide-highlighter.h"
-#include "langserv/ide-langserv-client.h"
+#include <libide-code.h>
+
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_HIGHLIGHTER (ide_langserv_highlighter_get_type())
+#define IDE_TYPE_LSP_HIGHLIGHTER (ide_lsp_highlighter_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservHighlighter, ide_langserv_highlighter, IDE, LANGSERV_HIGHLIGHTER, 
IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspHighlighter, ide_lsp_highlighter, IDE, LSP_HIGHLIGHTER, IdeObject)
 
-struct _IdeLangservHighlighterClass
+struct _IdeLspHighlighterClass
 {
   IdeObjectClass parent_class;
 
   /*< private >*/
-  gpointer _reserved1;
-  gpointer _reserved2;
-  gpointer _reserved3;
-  gpointer _reserved4;
+  gpointer _reserved[8];
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_highlighter_get_client (IdeLangservHighlighter *self);
+IdeLspClient *ide_lsp_highlighter_get_client (IdeLspHighlighter *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_highlighter_set_client (IdeLangservHighlighter *self,
-                                                        IdeLangservClient      *client);
+void               ide_lsp_highlighter_set_client (IdeLspHighlighter *self,
+                                                        IdeLspClient      *client);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-hover-provider.c b/src/libide/lsp/ide-lsp-hover-provider.c
similarity index 66%
rename from src/libide/langserv/ide-langserv-hover-provider.c
rename to src/libide/lsp/ide-lsp-hover-provider.c
index 15c453171..1e38087f7 100644
--- a/src/libide/langserv/ide-langserv-hover-provider.c
+++ b/src/libide/lsp/ide-lsp-hover-provider.c
@@ -1,4 +1,4 @@
-/* ide-langserv-hover-provider.c
+/* ide-lsp-hover-provider.c
  *
  * Copyright 2018-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,47 +18,42 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-hover-provider"
+#define G_LOG_DOMAIN "ide-lsp-hover-provider"
 
 #include "config.h"
 
 #include <jsonrpc-glib.h>
+#include <libide-code.h>
+#include <libide-sourceview.h>
+#include <libide-threading.h>
 
-#include "ide-debug.h"
-
-#include "application/ide-application.h"
-#include "buffers/ide-buffer.h"
-#include "hover/ide-hover-context.h"
-#include "hover/ide-hover-provider.h"
-#include "langserv/ide-langserv-hover-provider.h"
-#include "threading/ide-task.h"
-#include "util/ide-marked-content.h"
+#include "ide-lsp-hover-provider.h"
 
 /**
- * SECTION:ide-langserv-hover-provider
- * @title: IdeLangservHoverProvider
+ * SECTION:ide-lsp-hover-provider
+ * @title: IdeLspHoverProvider
  * @short_description: Interactive hover integration for language servers
  *
- * The #IdeLangservHoverProvider provides integration with language servers
+ * The #IdeLspHoverProvider provides integration with language servers
  * that support hover requests. This can display markup in the interactive
  * tooltip that is displayed in the editor.
  *
- * Since: 3.32
+ * Since: 3.30
  */
 
 typedef struct
 {
-  IdeLangservClient *client;
+  IdeLspClient *client;
   gchar *category;
   gint priority;
-} IdeLangservHoverProviderPrivate;
+} IdeLspHoverProviderPrivate;
 
 static void hover_provider_iface_init (IdeHoverProviderInterface *iface);
 
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLangservHoverProvider,
-                                  ide_langserv_hover_provider,
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspHoverProvider,
+                                  ide_lsp_hover_provider,
                                   IDE_TYPE_OBJECT,
-                                  G_ADD_PRIVATE (IdeLangservHoverProvider)
+                                  G_ADD_PRIVATE (IdeLspHoverProvider)
                                   G_IMPLEMENT_INTERFACE (IDE_TYPE_HOVER_PROVIDER, hover_provider_iface_init))
 
 enum {
@@ -122,12 +117,12 @@ parse_marked_string (GVariant *v)
           g_variant_lookup (asv, "value", "&s", &value);
 
 #if 0
-          if (!dzl_str_empty0 (lang) && !dzl_str_empty0 (value))
+          if (!ide_str_empty0 (lang) && !ide_str_empty0 (value))
             g_string_append_printf (str, "```%s\n%s\n```", lang, value);
-          else if (!dzl_str_empty0 (value))
+          else if (!ide_str_empty0 (value))
             g_string_append (str, value);
 #else
-          if (!dzl_str_empty0 (value))
+          if (!ide_str_empty0 (value))
             g_string_append_printf (gstr, "```\n%s\n```", value);
 #endif
         }
@@ -142,29 +137,29 @@ parse_marked_string (GVariant *v)
 }
 
 static void
-ide_langserv_hover_provider_dispose (GObject *object)
+ide_lsp_hover_provider_dispose (GObject *object)
 {
-  IdeLangservHoverProvider *self = (IdeLangservHoverProvider *)object;
-  IdeLangservHoverProviderPrivate *priv = ide_langserv_hover_provider_get_instance_private (self);
+  IdeLspHoverProvider *self = (IdeLspHoverProvider *)object;
+  IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
 
   IDE_ENTRY;
 
   g_clear_object (&priv->client);
   g_clear_pointer (&priv->category, g_free);
 
-  G_OBJECT_CLASS (ide_langserv_hover_provider_parent_class)->dispose (object);
+  G_OBJECT_CLASS (ide_lsp_hover_provider_parent_class)->dispose (object);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_hover_provider_get_property (GObject    *object,
+ide_lsp_hover_provider_get_property (GObject    *object,
                                           guint       prop_id,
                                           GValue     *value,
                                           GParamSpec *pspec)
 {
-  IdeLangservHoverProvider *self = IDE_LANGSERV_HOVER_PROVIDER (object);
-  IdeLangservHoverProviderPrivate *priv = ide_langserv_hover_provider_get_instance_private (self);
+  IdeLspHoverProvider *self = IDE_LSP_HOVER_PROVIDER (object);
+  IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
 
   switch (prop_id)
     {
@@ -173,7 +168,7 @@ ide_langserv_hover_provider_get_property (GObject    *object,
       break;
 
     case PROP_CLIENT:
-      g_value_set_object (value, ide_langserv_hover_provider_get_client (self));
+      g_value_set_object (value, ide_lsp_hover_provider_get_client (self));
       break;
 
     case PROP_PRIORITY:
@@ -186,13 +181,13 @@ ide_langserv_hover_provider_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_hover_provider_set_property (GObject      *object,
+ide_lsp_hover_provider_set_property (GObject      *object,
                                           guint         prop_id,
                                           const GValue *value,
                                           GParamSpec   *pspec)
 {
-  IdeLangservHoverProvider *self = IDE_LANGSERV_HOVER_PROVIDER (object);
-  IdeLangservHoverProviderPrivate *priv = ide_langserv_hover_provider_get_instance_private (self);
+  IdeLspHoverProvider *self = IDE_LSP_HOVER_PROVIDER (object);
+  IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
 
   switch (prop_id)
     {
@@ -202,7 +197,7 @@ ide_langserv_hover_provider_set_property (GObject      *object,
       break;
 
     case PROP_CLIENT:
-      ide_langserv_hover_provider_set_client (self, g_value_get_object (value));
+      ide_lsp_hover_provider_set_client (self, g_value_get_object (value));
       break;
 
     case PROP_PRIORITY:
@@ -215,36 +210,36 @@ ide_langserv_hover_provider_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_hover_provider_class_init (IdeLangservHoverProviderClass *klass)
+ide_lsp_hover_provider_class_init (IdeLspHoverProviderClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->dispose = ide_langserv_hover_provider_dispose;
-  object_class->get_property = ide_langserv_hover_provider_get_property;
-  object_class->set_property = ide_langserv_hover_provider_set_property;
+  object_class->dispose = ide_lsp_hover_provider_dispose;
+  object_class->get_property = ide_lsp_hover_provider_get_property;
+  object_class->set_property = ide_lsp_hover_provider_set_property;
 
   /**
-   * IdeLangservHoverProvider:client:
+   * IdeLspHoverProvider:client:
    *
-   * The "client" property is the #IdeLangservClient that should be used to
+   * The "client" property is the #IdeLspClient that should be used to
    * communicate with the Language Server peer process.
    *
-   * Since: 3.32
+   * Since: 3.30
    */
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
                          "The client to communicate with",
-                         IDE_TYPE_LANGSERV_CLIENT,
+                         IDE_TYPE_LSP_CLIENT,
                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
 
   /**
-   * IdeLangservHoverProvider:category:
+   * IdeLspHoverProvider:category:
    *
    * The "category" property is the category name to use when displaying
    * the hover contents.
    *
-   * Since: 3.32
+   * Since: 3.30
    */
   properties [PROP_CATEGORY] =
     g_param_spec_string ("category",
@@ -266,18 +261,18 @@ ide_langserv_hover_provider_class_init (IdeLangservHoverProviderClass *klass)
 }
 
 static void
-ide_langserv_hover_provider_init (IdeLangservHoverProvider *self)
+ide_lsp_hover_provider_init (IdeLspHoverProvider *self)
 {
 }
 
 static void
-ide_langserv_hover_provider_hover_cb (GObject      *object,
+ide_lsp_hover_provider_hover_cb (GObject      *object,
                                       GAsyncResult *result,
                                       gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
-  IdeLangservHoverProvider *self;
-  IdeLangservHoverProviderPrivate *priv;
+  IdeLspClient *client = (IdeLspClient *)object;
+  IdeLspHoverProvider *self;
+  IdeLspHoverProviderPrivate *priv;
   g_autoptr(GVariant) reply = NULL;
   g_autoptr(GVariant) contents = NULL;
   g_autoptr(IdeMarkedContent) marked = NULL;
@@ -287,16 +282,16 @@ ide_langserv_hover_provider_hover_cb (GObject      *object,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
   self = ide_task_get_source_object (task);
-  priv = ide_langserv_hover_provider_get_instance_private (self);
+  priv = ide_lsp_hover_provider_get_instance_private (self);
 
-  g_assert (IDE_IS_LANGSERV_HOVER_PROVIDER (self));
+  g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
 
-  if (!ide_langserv_client_call_finish (client, result, &reply, &error))
+  if (!ide_lsp_client_call_finish (client, result, &reply, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       IDE_EXIT;
@@ -337,15 +332,15 @@ ide_langserv_hover_provider_hover_cb (GObject      *object,
 }
 
 static void
-ide_langserv_hover_provider_hover_async (IdeHoverProvider    *provider,
+ide_lsp_hover_provider_hover_async (IdeHoverProvider    *provider,
                                          IdeHoverContext     *context,
                                          const GtkTextIter   *iter,
                                          GCancellable        *cancellable,
                                          GAsyncReadyCallback  callback,
                                          gpointer             user_data)
 {
-  IdeLangservHoverProvider *self = (IdeLangservHoverProvider *)provider;
-  IdeLangservHoverProviderPrivate *priv = ide_langserv_hover_provider_get_instance_private (self);
+  IdeLspHoverProvider *self = (IdeLspHoverProvider *)provider;
+  IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
@@ -356,14 +351,14 @@ ide_langserv_hover_provider_hover_async (IdeHoverProvider    *provider,
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_HOVER_PROVIDER (self));
+  g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
   g_assert (IDE_IS_HOVER_CONTEXT (context));
   g_assert (iter != NULL);
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
   ide_task_set_task_data (task, g_object_ref (context), g_object_unref);
-  ide_task_set_source_tag (task, ide_langserv_hover_provider_hover_async);
+  ide_task_set_source_tag (task, ide_lsp_hover_provider_hover_async);
 
   if (priv->client == NULL)
     {
@@ -375,7 +370,7 @@ ide_langserv_hover_provider_hover_async (IdeHoverProvider    *provider,
     }
 
   buffer = IDE_BUFFER (gtk_text_iter_get_buffer (iter));
-  uri = ide_buffer_get_uri (buffer);
+  uri = ide_buffer_dup_uri (buffer);
   line = gtk_text_iter_get_line (iter);
   column = gtk_text_iter_get_line_offset (iter);
 
@@ -389,20 +384,20 @@ ide_langserv_hover_provider_hover_async (IdeHoverProvider    *provider,
     "}"
   );
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (priv->client));
+  g_assert (IDE_IS_LSP_CLIENT (priv->client));
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/hover",
                                   params,
                                   cancellable,
-                                  ide_langserv_hover_provider_hover_cb,
+                                  ide_lsp_hover_provider_hover_cb,
                                   g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static gboolean
-ide_langserv_hover_provider_hover_finish (IdeHoverProvider  *provider,
+ide_lsp_hover_provider_hover_finish (IdeHoverProvider  *provider,
                                           GAsyncResult      *result,
                                           GError           **error)
 {
@@ -410,7 +405,7 @@ ide_langserv_hover_provider_hover_finish (IdeHoverProvider  *provider,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_HOVER_PROVIDER (provider));
+  g_assert (IDE_IS_LSP_HOVER_PROVIDER (provider));
   g_assert (IDE_IS_TASK (result));
 
   ret = ide_task_propagate_boolean (IDE_TASK (result), error);
@@ -419,65 +414,65 @@ ide_langserv_hover_provider_hover_finish (IdeHoverProvider  *provider,
 }
 
 static void
-ide_langserv_hover_provider_real_load (IdeHoverProvider *provider,
+ide_lsp_hover_provider_real_load (IdeHoverProvider *provider,
                                        IdeSourceView    *view)
 {
-  IdeLangservHoverProvider *self = (IdeLangservHoverProvider *)provider;
+  IdeLspHoverProvider *self = (IdeLspHoverProvider *)provider;
 
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LANGSERV_HOVER_PROVIDER (self));
+  g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
 
-  if (IDE_LANGSERV_HOVER_PROVIDER_GET_CLASS (self)->prepare)
-    IDE_LANGSERV_HOVER_PROVIDER_GET_CLASS (self)->prepare (self);
+  if (IDE_LSP_HOVER_PROVIDER_GET_CLASS (self)->prepare)
+    IDE_LSP_HOVER_PROVIDER_GET_CLASS (self)->prepare (self);
 }
 
 static void
 hover_provider_iface_init (IdeHoverProviderInterface *iface)
 {
-  iface->load = ide_langserv_hover_provider_real_load;
-  iface->hover_async = ide_langserv_hover_provider_hover_async;
-  iface->hover_finish = ide_langserv_hover_provider_hover_finish;
+  iface->load = ide_lsp_hover_provider_real_load;
+  iface->hover_async = ide_lsp_hover_provider_hover_async;
+  iface->hover_finish = ide_lsp_hover_provider_hover_finish;
 }
 
 /**
- * ide_langserv_hover_provider_get_client:
- * @self: an #IdeLangservHoverProvider
+ * ide_lsp_hover_provider_get_client:
+ * @self: an #IdeLspHoverProvider
  *
  * Gets the client that is used for communication.
  *
- * Returns: (transfer none) (nullable): an #IdeLangservClient or %NULL
+ * Returns: (transfer none) (nullable): an #IdeLspClient or %NULL
  *
- * Since: 3.32
+ * Since: 3.30
  */
-IdeLangservClient *
-ide_langserv_hover_provider_get_client (IdeLangservHoverProvider *self)
+IdeLspClient *
+ide_lsp_hover_provider_get_client (IdeLspHoverProvider *self)
 {
-  IdeLangservHoverProviderPrivate *priv = ide_langserv_hover_provider_get_instance_private (self);
+  IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_HOVER_PROVIDER (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_HOVER_PROVIDER (self), NULL);
 
   return priv->client;
 }
 
 /**
- * ide_langserv_hover_provider_set_client:
- * @self: an #IdeLangservHoverProvider
- * @client: an #IdeLangservClient
+ * ide_lsp_hover_provider_set_client:
+ * @self: an #IdeLspHoverProvider
+ * @client: an #IdeLspClient
  *
  * Sets the client to be used to query for hover information.
  *
- * Since: 3.32
+ * Since: 3.30
  */
 void
-ide_langserv_hover_provider_set_client (IdeLangservHoverProvider *self,
-                                        IdeLangservClient        *client)
+ide_lsp_hover_provider_set_client (IdeLspHoverProvider *self,
+                                        IdeLspClient        *client)
 {
-  IdeLangservHoverProviderPrivate *priv = ide_langserv_hover_provider_get_instance_private (self);
+  IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
 
-  g_return_if_fail (IDE_IS_LANGSERV_HOVER_PROVIDER (self));
-  g_return_if_fail (!client || IDE_IS_LANGSERV_CLIENT (client));
+  g_return_if_fail (IDE_IS_LSP_HOVER_PROVIDER (self));
+  g_return_if_fail (!client || IDE_IS_LSP_CLIENT (client));
 
   if (g_set_object (&priv->client, client))
     g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
diff --git a/src/libide/langserv/ide-langserv-hover-provider.h b/src/libide/lsp/ide-lsp-hover-provider.h
similarity index 57%
rename from src/libide/langserv/ide-langserv-hover-provider.h
rename to src/libide/lsp/ide-lsp-hover-provider.h
index 0c0cdf474..73b254135 100644
--- a/src/libide/langserv/ide-langserv-hover-provider.h
+++ b/src/libide/lsp/ide-lsp-hover-provider.h
@@ -1,4 +1,4 @@
-/* ide-langserv-hover-provider.h
+/* ide-lsp-hover-provider.h
  *
  * Copyright 2018-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,31 +20,33 @@
 
 #pragma once
 
-#include "ide-object.h"
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "langserv/ide-langserv-client.h"
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_HOVER_PROVIDER (ide_langserv_hover_provider_get_type())
+#define IDE_TYPE_LSP_HOVER_PROVIDER (ide_lsp_hover_provider_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservHoverProvider, ide_langserv_hover_provider, IDE, 
LANGSERV_HOVER_PROVIDER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspHoverProvider, ide_lsp_hover_provider, IDE, LSP_HOVER_PROVIDER, IdeObject)
 
-struct _IdeLangservHoverProviderClass
+struct _IdeLspHoverProviderClass
 {
   IdeObjectClass parent_class;
 
-  void (*prepare) (IdeLangservHoverProvider *self);
+  void (*prepare) (IdeLspHoverProvider *self);
 
+  /*< private >*/
   gpointer _reserved[8];
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_hover_provider_get_client (IdeLangservHoverProvider *self);
+IdeLspClient *ide_lsp_hover_provider_get_client (IdeLspHoverProvider *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_hover_provider_set_client (IdeLangservHoverProvider *self,
-                                                           IdeLangservClient        *client);
+void               ide_lsp_hover_provider_set_client (IdeLspHoverProvider *self,
+                                                           IdeLspClient        *client);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-rename-provider.c b/src/libide/lsp/ide-lsp-rename-provider.c
similarity index 60%
rename from src/libide/langserv/ide-langserv-rename-provider.c
rename to src/libide/lsp/ide-lsp-rename-provider.c
index ef6cd37e6..e0ae48aff 100644
--- a/src/libide/langserv/ide-langserv-rename-provider.c
+++ b/src/libide/lsp/ide-lsp-rename-provider.c
@@ -1,4 +1,4 @@
-/* ide-langserv-rename-provider.c
+/* ide-lsp-rename-provider.c
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,32 +18,27 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-rename-provider"
+#define G_LOG_DOMAIN "ide-lsp-rename-provider"
 
 #include "config.h"
 
 #include <jsonrpc-glib.h>
+#include <libide-code.h>
+#include <libide-threading.h>
 
-#include "ide-debug.h"
-
-#include "buffers/ide-buffer.h"
-#include "files/ide-file.h"
-#include "langserv/ide-langserv-client.h"
-#include "langserv/ide-langserv-rename-provider.h"
-#include "diagnostics/ide-source-location.h"
-#include "threading/ide-task.h"
-#include "util/ide-glib.h"
+#include "ide-lsp-client.h"
+#include "ide-lsp-rename-provider.h"
 
 typedef struct
 {
-  IdeLangservClient *client;
+  IdeLspClient *client;
   IdeBuffer         *buffer;
-} IdeLangservRenameProviderPrivate;
+} IdeLspRenameProviderPrivate;
 
 static void rename_provider_iface_init (IdeRenameProviderInterface *iface);
 
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLangservRenameProvider, ide_langserv_rename_provider, IDE_TYPE_OBJECT,
-                                  G_ADD_PRIVATE (IdeLangservRenameProvider)
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspRenameProvider, ide_lsp_rename_provider, IDE_TYPE_OBJECT,
+                                  G_ADD_PRIVATE (IdeLspRenameProvider)
                                   G_IMPLEMENT_INTERFACE (IDE_TYPE_RENAME_PROVIDER, 
rename_provider_iface_init))
 
 enum {
@@ -56,38 +51,38 @@ enum {
 static GParamSpec *properties [N_PROPS];
 
 static void
-ide_langserv_rename_provider_set_buffer (IdeLangservRenameProvider *self,
+ide_lsp_rename_provider_set_buffer (IdeLspRenameProvider *self,
                                          IdeBuffer                 *buffer)
 {
-  IdeLangservRenameProviderPrivate *priv = ide_langserv_rename_provider_get_instance_private (self);
+  IdeLspRenameProviderPrivate *priv = ide_lsp_rename_provider_get_instance_private (self);
 
   g_set_weak_pointer (&priv->buffer, buffer);
 }
 
 static void
-ide_langserv_rename_provider_finalize (GObject *object)
+ide_lsp_rename_provider_finalize (GObject *object)
 {
-  IdeLangservRenameProvider *self = (IdeLangservRenameProvider *)object;
-  IdeLangservRenameProviderPrivate *priv = ide_langserv_rename_provider_get_instance_private (self);
+  IdeLspRenameProvider *self = (IdeLspRenameProvider *)object;
+  IdeLspRenameProviderPrivate *priv = ide_lsp_rename_provider_get_instance_private (self);
 
   g_clear_object (&priv->client);
   g_clear_weak_pointer (&priv->buffer);
 
-  G_OBJECT_CLASS (ide_langserv_rename_provider_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_rename_provider_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_rename_provider_get_property (GObject    *object,
+ide_lsp_rename_provider_get_property (GObject    *object,
                                            guint       prop_id,
                                            GValue     *value,
                                            GParamSpec *pspec)
 {
-  IdeLangservRenameProvider *self = IDE_LANGSERV_RENAME_PROVIDER (object);
+  IdeLspRenameProvider *self = IDE_LSP_RENAME_PROVIDER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      g_value_set_object (value, ide_langserv_rename_provider_get_client (self));
+      g_value_set_object (value, ide_lsp_rename_provider_get_client (self));
       break;
 
     default:
@@ -96,21 +91,21 @@ ide_langserv_rename_provider_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_rename_provider_set_property (GObject      *object,
+ide_lsp_rename_provider_set_property (GObject      *object,
                                            guint         prop_id,
                                            const GValue *value,
                                            GParamSpec   *pspec)
 {
-  IdeLangservRenameProvider *self = IDE_LANGSERV_RENAME_PROVIDER (object);
+  IdeLspRenameProvider *self = IDE_LSP_RENAME_PROVIDER (object);
 
   switch (prop_id)
     {
     case PROP_BUFFER:
-      ide_langserv_rename_provider_set_buffer (self, g_value_get_object (value));
+      ide_lsp_rename_provider_set_buffer (self, g_value_get_object (value));
       break;
 
     case PROP_CLIENT:
-      ide_langserv_rename_provider_set_client (self, g_value_get_object (value));
+      ide_lsp_rename_provider_set_client (self, g_value_get_object (value));
       break;
 
     default:
@@ -119,19 +114,19 @@ ide_langserv_rename_provider_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_rename_provider_class_init (IdeLangservRenameProviderClass *klass)
+ide_lsp_rename_provider_class_init (IdeLspRenameProviderClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_rename_provider_finalize;
-  object_class->get_property = ide_langserv_rename_provider_get_property;
-  object_class->set_property = ide_langserv_rename_provider_set_property;
+  object_class->finalize = ide_lsp_rename_provider_finalize;
+  object_class->get_property = ide_lsp_rename_provider_get_property;
+  object_class->set_property = ide_lsp_rename_provider_set_property;
 
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
                          "The Language Server client",
-                         IDE_TYPE_LANGSERV_CLIENT,
+                         IDE_TYPE_LSP_CLIENT,
                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
 
   properties [PROP_BUFFER] =
@@ -145,35 +140,34 @@ ide_langserv_rename_provider_class_init (IdeLangservRenameProviderClass *klass)
 }
 
 static void
-ide_langserv_rename_provider_init (IdeLangservRenameProvider *self)
+ide_lsp_rename_provider_init (IdeLspRenameProvider *self)
 {
 }
 
 static void
-ide_langserv_rename_provider_rename_cb (GObject      *object,
+ide_lsp_rename_provider_rename_cb (GObject      *object,
                                         GAsyncResult *result,
                                         gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
-  IdeLangservRenameProvider *self;
+  IdeLspClient *client = (IdeLspClient *)object;
+  IdeLspRenameProvider *self;
   g_autoptr(GVariant) return_value = NULL;
   g_autoptr(GError) error = NULL;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GPtrArray) ret = NULL;
   g_autoptr(GVariantIter) changes_by_uri = NULL;
-  IdeContext *context;
   const gchar *uri;
   GVariant *changes;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
   self = ide_task_get_source_object (task);
-  g_assert (IDE_IS_LANGSERV_RENAME_PROVIDER (self));
+  g_assert (IDE_IS_LSP_RENAME_PROVIDER (self));
 
-  if (!ide_langserv_client_call_finish (client, result, &return_value, &error))
+  if (!ide_lsp_client_call_finish (client, result, &return_value, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       IDE_EXIT;
@@ -182,14 +176,11 @@ ide_langserv_rename_provider_rename_cb (GObject      *object,
   if (!JSONRPC_MESSAGE_PARSE (return_value, "changes", JSONRPC_MESSAGE_GET_ITER (&changes_by_uri)))
     IDE_EXIT;
 
-  context = ide_object_get_context (IDE_OBJECT (self));
-
   ret = g_ptr_array_new_with_free_func (g_object_unref);
 
   while (g_variant_iter_loop (changes_by_uri, "{sv}", &uri, &changes))
     {
       g_autoptr(GFile) gfile = g_file_new_for_uri (uri);
-      g_autoptr(IdeFile) ifile = ide_file_new (context, gfile);
       GVariantIter changes_iter;
       GVariant *change;
 
@@ -200,10 +191,9 @@ ide_langserv_rename_provider_rename_cb (GObject      *object,
 
       while (g_variant_iter_loop (&changes_iter, "v", &change))
         {
-          g_autoptr(IdeSourceLocation) begin_location = NULL;
-          g_autoptr(IdeSourceLocation) end_location = NULL;
-          g_autoptr(IdeSourceRange) range = NULL;
-          g_autoptr(IdeProjectEdit) edit = NULL;
+          g_autoptr(IdeLocation) begin_location = NULL;
+          g_autoptr(IdeLocation) end_location = NULL;
+          g_autoptr(IdeRange) range = NULL;
           const gchar *new_text = NULL;
           gboolean success;
           struct {
@@ -231,16 +221,11 @@ ide_langserv_rename_provider_rename_cb (GObject      *object,
               continue;
             }
 
-          begin_location = ide_source_location_new (ifile, begin.line, begin.column, 0);
-          end_location = ide_source_location_new (ifile, end.line, end.column, 0);
-          range = ide_source_range_new (begin_location, end_location);
+          begin_location = ide_location_new (gfile, begin.line, begin.column);
+          end_location = ide_location_new (gfile, end.line, end.column);
+          range = ide_range_new (begin_location, end_location);
 
-          edit = g_object_new (IDE_TYPE_PROJECT_EDIT,
-                               "range", range,
-                               "replacement", new_text,
-                               NULL);
-
-          g_ptr_array_add (ret, g_steal_pointer (&edit));
+          g_ptr_array_add (ret, ide_text_edit_new (range, new_text));
         }
     }
 
@@ -250,22 +235,21 @@ ide_langserv_rename_provider_rename_cb (GObject      *object,
 }
 
 static void
-ide_langserv_rename_provider_rename_async (IdeRenameProvider   *provider,
-                                           IdeSourceLocation   *location,
+ide_lsp_rename_provider_rename_async (IdeRenameProvider   *provider,
+                                           IdeLocation   *location,
                                            const gchar         *new_name,
                                            GCancellable        *cancellable,
                                            GAsyncReadyCallback  callback,
                                            gpointer             user_data)
 {
-  IdeLangservRenameProvider *self = (IdeLangservRenameProvider *)provider;
-  IdeLangservRenameProviderPrivate *priv = ide_langserv_rename_provider_get_instance_private (self);
+  IdeLspRenameProvider *self = (IdeLspRenameProvider *)provider;
+  IdeLspRenameProviderPrivate *priv = ide_lsp_rename_provider_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *text = NULL;
   g_autofree gchar *uri = NULL;
   GtkTextIter begin;
   GtkTextIter end;
-  IdeFile *ifile;
   GFile *gfile;
   gint64 version;
   gint line;
@@ -273,13 +257,13 @@ ide_langserv_rename_provider_rename_async (IdeRenameProvider   *provider,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_RENAME_PROVIDER (self));
+  g_assert (IDE_IS_LSP_RENAME_PROVIDER (self));
   g_assert (location != NULL);
   g_assert (new_name != NULL);
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_rename_provider_rename_async);
+  ide_task_set_source_tag (task, ide_lsp_rename_provider_rename_async);
 
   if (priv->client == NULL)
     {
@@ -290,12 +274,11 @@ ide_langserv_rename_provider_rename_async (IdeRenameProvider   *provider,
       IDE_EXIT;
     }
 
-  ifile = ide_source_location_get_file (location);
-  gfile = ide_file_get_file (ifile);
+  gfile = ide_location_get_file (location);
   uri = g_file_get_uri (gfile);
 
-  line = ide_source_location_get_line (location);
-  column = ide_source_location_get_line_offset (location);
+  line = ide_location_get_line (location);
+  column = ide_location_get_line_offset (location);
 
   version = ide_buffer_get_change_count (priv->buffer);
 
@@ -315,18 +298,18 @@ ide_langserv_rename_provider_rename_async (IdeRenameProvider   *provider,
     "newName", JSONRPC_MESSAGE_PUT_STRING (new_name)
   );
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/rename",
                                   params,
                                   cancellable,
-                                  ide_langserv_rename_provider_rename_cb,
+                                  ide_lsp_rename_provider_rename_cb,
                                   g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static gboolean
-ide_langserv_rename_provider_rename_finish (IdeRenameProvider  *provider,
+ide_lsp_rename_provider_rename_finish (IdeRenameProvider  *provider,
                                             GAsyncResult       *result,
                                             GPtrArray         **edits,
                                             GError            **error)
@@ -336,7 +319,7 @@ ide_langserv_rename_provider_rename_finish (IdeRenameProvider  *provider,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_RENAME_PROVIDER (provider));
+  g_assert (IDE_IS_LSP_RENAME_PROVIDER (provider));
   g_assert (IDE_IS_TASK (result));
 
   ar = ide_task_propagate_pointer (IDE_TASK (result), error);
@@ -351,35 +334,33 @@ ide_langserv_rename_provider_rename_finish (IdeRenameProvider  *provider,
 static void
 rename_provider_iface_init (IdeRenameProviderInterface *iface)
 {
-  iface->rename_async = ide_langserv_rename_provider_rename_async;
-  iface->rename_finish = ide_langserv_rename_provider_rename_finish;
+  iface->rename_async = ide_lsp_rename_provider_rename_async;
+  iface->rename_finish = ide_lsp_rename_provider_rename_finish;
 }
 
 /**
- * ide_langserv_rename_provider_get_client:
- *
- * Returns: (transfer none) (nullable): an #IdeLangservClient or %NULL.
+ * ide_lsp_rename_provider_get_client:
  *
- * Since: 3.32
+ * Returns: (transfer none) (nullable): an #IdeLspClient or %NULL.
  */
-IdeLangservClient *
-ide_langserv_rename_provider_get_client (IdeLangservRenameProvider *self)
+IdeLspClient *
+ide_lsp_rename_provider_get_client (IdeLspRenameProvider *self)
 {
-  IdeLangservRenameProviderPrivate *priv = ide_langserv_rename_provider_get_instance_private (self);
+  IdeLspRenameProviderPrivate *priv = ide_lsp_rename_provider_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_RENAME_PROVIDER (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_RENAME_PROVIDER (self), NULL);
 
   return priv->client;
 }
 
 void
-ide_langserv_rename_provider_set_client (IdeLangservRenameProvider *self,
-                                         IdeLangservClient         *client)
+ide_lsp_rename_provider_set_client (IdeLspRenameProvider *self,
+                                         IdeLspClient         *client)
 {
-  IdeLangservRenameProviderPrivate *priv = ide_langserv_rename_provider_get_instance_private (self);
+  IdeLspRenameProviderPrivate *priv = ide_lsp_rename_provider_get_instance_private (self);
 
-  g_return_if_fail (IDE_IS_LANGSERV_RENAME_PROVIDER (self));
-  g_return_if_fail (!client || IDE_IS_LANGSERV_CLIENT (client));
+  g_return_if_fail (IDE_IS_LSP_RENAME_PROVIDER (self));
+  g_return_if_fail (!client || IDE_IS_LSP_CLIENT (client));
 
   if (g_set_object (&priv->client, client))
     g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
diff --git a/src/libide/langserv/ide-langserv-rename-provider.h b/src/libide/lsp/ide-lsp-rename-provider.h
similarity index 55%
rename from src/libide/langserv/ide-langserv-rename-provider.h
rename to src/libide/lsp/ide-lsp-rename-provider.h
index 11c0a23b6..164b6d366 100644
--- a/src/libide/langserv/ide-langserv-rename-provider.h
+++ b/src/libide/lsp/ide-lsp-rename-provider.h
@@ -1,4 +1,4 @@
-/* ide-langserv-rename-provider.h
+/* ide-lsp-rename-provider.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,37 +20,33 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "langserv/ide-langserv-client.h"
-#include "rename/ide-rename-provider.h"
+#include <libide-code.h>
+
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_RENAME_PROVIDER (ide_langserv_rename_provider_get_type())
+#define IDE_TYPE_LSP_RENAME_PROVIDER (ide_lsp_rename_provider_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservRenameProvider, ide_langserv_rename_provider, IDE, 
LANGSERV_RENAME_PROVIDER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspRenameProvider, ide_lsp_rename_provider, IDE, LSP_RENAME_PROVIDER, IdeObject)
 
-struct _IdeLangservRenameProviderClass
+struct _IdeLspRenameProviderClass
 {
   IdeObjectClass parent_instance;
 
   /*< private >*/
-  gpointer _reserved1;
-  gpointer _reserved2;
-  gpointer _reserved3;
-  gpointer _reserved4;
-  gpointer _reserved5;
-  gpointer _reserved6;
-  gpointer _reserved7;
-  gpointer _reserved8;
+  gpointer _reserved[16];
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_rename_provider_get_client (IdeLangservRenameProvider *self);
+IdeLspClient *ide_lsp_rename_provider_get_client (IdeLspRenameProvider *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_rename_provider_set_client (IdeLangservRenameProvider *self,
-                                                            IdeLangservClient         *client);
+void               ide_lsp_rename_provider_set_client (IdeLspRenameProvider *self,
+                                                            IdeLspClient         *client);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-symbol-node-private.h 
b/src/libide/lsp/ide-lsp-symbol-node-private.h
similarity index 88%
rename from src/libide/langserv/ide-langserv-symbol-node-private.h
rename to src/libide/lsp/ide-lsp-symbol-node-private.h
index 1ef4650a3..b20782828 100644
--- a/src/libide/langserv/ide-langserv-symbol-node-private.h
+++ b/src/libide/lsp/ide-lsp-symbol-node-private.h
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-node-private.h
+/* ide-lsp-symbol-node-private.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,18 +20,17 @@
 
 #pragma once
 
-#include "langserv/ide-langserv-symbol-node.h"
+#include "ide-lsp-symbol-node.h"
 
 G_BEGIN_DECLS
 
-struct _IdeLangservSymbolNode
+struct _IdeLspSymbolNode
 {
   IdeSymbolNode parent_instance;
   GNode         gnode;
 };
 
-
-IdeLangservSymbolNode *ide_langserv_symbol_node_new (GFile       *file,
+IdeLspSymbolNode *ide_lsp_symbol_node_new (GFile       *file,
                                                      const gchar *name,
                                                      const gchar *parent_name,
                                                      gint         kind,
diff --git a/src/libide/langserv/ide-langserv-symbol-node.c b/src/libide/lsp/ide-lsp-symbol-node.c
similarity index 51%
rename from src/libide/langserv/ide-langserv-symbol-node.c
rename to src/libide/lsp/ide-lsp-symbol-node.c
index 99b60ab63..4fa7d9870 100644
--- a/src/libide/langserv/ide-langserv-symbol-node.c
+++ b/src/libide/lsp/ide-lsp-symbol-node.c
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-node.c
+/* ide-lsp-symbol-node.c
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,18 +18,16 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-symbol-node"
+#define G_LOG_DOMAIN "ide-lsp-symbol-node"
 
 #include "config.h"
 
-#include "ide-debug.h"
+#include <libide-code.h>
+#include <libide-threading.h>
 
-#include "diagnostics/ide-source-location.h"
-#include "files/ide-file.h"
-#include "langserv/ide-langserv-symbol-node.h"
-#include "langserv/ide-langserv-symbol-node-private.h"
-#include "langserv/ide-langserv-util.h"
-#include "threading/ide-task.h"
+#include "ide-lsp-symbol-node.h"
+#include "ide-lsp-symbol-node-private.h"
+#include "ide-lsp-util.h"
 
 typedef struct
 {
@@ -44,9 +42,9 @@ typedef struct
   IdeSymbolKind kind;
   Location begin;
   Location end;
-} IdeLangservSymbolNodePrivate;
+} IdeLspSymbolNodePrivate;
 
-G_DEFINE_TYPE_WITH_PRIVATE (IdeLangservSymbolNode, ide_langserv_symbol_node, IDE_TYPE_SYMBOL_NODE)
+G_DEFINE_TYPE_WITH_PRIVATE (IdeLspSymbolNode, ide_lsp_symbol_node, IDE_TYPE_SYMBOL_NODE)
 
 static inline gint
 location_compare (const Location *a,
@@ -62,42 +60,38 @@ location_compare (const Location *a,
 }
 
 static void
-ide_langserv_symbol_node_get_location_async (IdeSymbolNode       *node,
+ide_lsp_symbol_node_get_location_async (IdeSymbolNode       *node,
                                              GCancellable        *cancellable,
                                              GAsyncReadyCallback  callback,
                                              gpointer             user_data)
 {
-  IdeLangservSymbolNode *self = (IdeLangservSymbolNode *)node;
-  IdeLangservSymbolNodePrivate *priv = ide_langserv_symbol_node_get_instance_private (self);
+  IdeLspSymbolNode *self = (IdeLspSymbolNode *)node;
+  IdeLspSymbolNodePrivate *priv = ide_lsp_symbol_node_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
-  g_autoptr(IdeFile) ifile = NULL;
-  g_autoptr(IdeSourceLocation) location = NULL;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_SYMBOL_NODE (node));
+  g_assert (IDE_IS_LSP_SYMBOL_NODE (node));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_symbol_node_get_location_async);
-
-  ifile = ide_file_new (NULL, priv->file);
-  location = ide_source_location_new (ifile, priv->begin.line, priv->begin.column, 0);
-
-  ide_task_return_pointer (task, g_steal_pointer (&location), (GDestroyNotify)ide_source_location_unref);
+  ide_task_set_source_tag (task, ide_lsp_symbol_node_get_location_async);
+  ide_task_return_pointer (task,
+                           ide_location_new (priv->file, priv->begin.line, priv->begin.column),
+                           g_object_unref);
 
   IDE_EXIT;
 }
 
-static IdeSourceLocation *
-ide_langserv_symbol_node_get_location_finish (IdeSymbolNode  *node,
+static IdeLocation *
+ide_lsp_symbol_node_get_location_finish (IdeSymbolNode  *node,
                                               GAsyncResult   *result,
                                               GError        **error)
 {
-  IdeSourceLocation *ret;
+  IdeLocation *ret;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_SYMBOL_NODE (node));
+  g_assert (IDE_IS_LSP_SYMBOL_NODE (node));
   g_assert (IDE_IS_TASK (result));
 
   ret = ide_task_propagate_pointer (IDE_TASK (result), error);
@@ -106,37 +100,37 @@ ide_langserv_symbol_node_get_location_finish (IdeSymbolNode  *node,
 }
 
 static void
-ide_langserv_symbol_node_finalize (GObject *object)
+ide_lsp_symbol_node_finalize (GObject *object)
 {
-  IdeLangservSymbolNode *self = (IdeLangservSymbolNode *)object;
-  IdeLangservSymbolNodePrivate *priv = ide_langserv_symbol_node_get_instance_private (self);
+  IdeLspSymbolNode *self = (IdeLspSymbolNode *)object;
+  IdeLspSymbolNodePrivate *priv = ide_lsp_symbol_node_get_instance_private (self);
 
   g_clear_pointer (&priv->parent_name, g_free);
   g_clear_object (&priv->file);
 
-  G_OBJECT_CLASS (ide_langserv_symbol_node_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_symbol_node_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_symbol_node_class_init (IdeLangservSymbolNodeClass *klass)
+ide_lsp_symbol_node_class_init (IdeLspSymbolNodeClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   IdeSymbolNodeClass *symbol_node_class = IDE_SYMBOL_NODE_CLASS (klass);
 
-  object_class->finalize = ide_langserv_symbol_node_finalize;
+  object_class->finalize = ide_lsp_symbol_node_finalize;
 
-  symbol_node_class->get_location_async = ide_langserv_symbol_node_get_location_async;
-  symbol_node_class->get_location_finish = ide_langserv_symbol_node_get_location_finish;
+  symbol_node_class->get_location_async = ide_lsp_symbol_node_get_location_async;
+  symbol_node_class->get_location_finish = ide_lsp_symbol_node_get_location_finish;
 }
 
 static void
-ide_langserv_symbol_node_init (IdeLangservSymbolNode *self)
+ide_lsp_symbol_node_init (IdeLspSymbolNode *self)
 {
   self->gnode.data = self;
 }
 
-IdeLangservSymbolNode *
-ide_langserv_symbol_node_new (GFile       *file,
+IdeLspSymbolNode *
+ide_lsp_symbol_node_new (GFile       *file,
                               const gchar *name,
                               const gchar *parent_name,
                               gint         kind,
@@ -145,19 +139,19 @@ ide_langserv_symbol_node_new (GFile       *file,
                               guint        end_line,
                               guint        end_column)
 {
-  IdeLangservSymbolNode *self;
-  IdeLangservSymbolNodePrivate *priv;
+  IdeLspSymbolNode *self;
+  IdeLspSymbolNodePrivate *priv;
 
   g_return_val_if_fail (G_IS_FILE (file), NULL);
 
-  kind = ide_langserv_decode_symbol_kind (kind);
+  kind = ide_lsp_decode_symbol_kind (kind);
 
-  self = g_object_new (IDE_TYPE_LANGSERV_SYMBOL_NODE,
+  self = g_object_new (IDE_TYPE_LSP_SYMBOL_NODE,
                        "flags", 0,
                        "kind", kind,
                        "name", name,
                        NULL);
-  priv = ide_langserv_symbol_node_get_instance_private (self);
+  priv = ide_lsp_symbol_node_get_instance_private (self);
 
   priv->file = g_object_ref (file);
   priv->parent_name = g_strdup (parent_name);
@@ -170,24 +164,24 @@ ide_langserv_symbol_node_new (GFile       *file,
 }
 
 const gchar *
-ide_langserv_symbol_node_get_parent_name (IdeLangservSymbolNode *self)
+ide_lsp_symbol_node_get_parent_name (IdeLspSymbolNode *self)
 {
-  IdeLangservSymbolNodePrivate *priv = ide_langserv_symbol_node_get_instance_private (self);
+  IdeLspSymbolNodePrivate *priv = ide_lsp_symbol_node_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_SYMBOL_NODE (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_NODE (self), NULL);
 
   return priv->parent_name;
 }
 
 gboolean
-ide_langserv_symbol_node_is_parent_of (IdeLangservSymbolNode *self,
-                                       IdeLangservSymbolNode *other)
+ide_lsp_symbol_node_is_parent_of (IdeLspSymbolNode *self,
+                                       IdeLspSymbolNode *other)
 {
-  IdeLangservSymbolNodePrivate *priv = ide_langserv_symbol_node_get_instance_private (self);
-  IdeLangservSymbolNodePrivate *opriv = ide_langserv_symbol_node_get_instance_private (other);
+  IdeLspSymbolNodePrivate *priv = ide_lsp_symbol_node_get_instance_private (self);
+  IdeLspSymbolNodePrivate *opriv = ide_lsp_symbol_node_get_instance_private (other);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_SYMBOL_NODE (self), FALSE);
-  g_return_val_if_fail (IDE_IS_LANGSERV_SYMBOL_NODE (other), FALSE);
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_NODE (self), FALSE);
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_NODE (other), FALSE);
 
   return (location_compare (&priv->begin, &opriv->begin) <= 0) &&
          (location_compare (&priv->end, &opriv->end) >= 0);
diff --git a/src/libide/langserv/ide-langserv-symbol-node.h b/src/libide/lsp/ide-lsp-symbol-node.h
similarity index 60%
rename from src/libide/langserv/ide-langserv-symbol-node.h
rename to src/libide/lsp/ide-lsp-symbol-node.h
index 526c0a383..0e6573dd9 100644
--- a/src/libide/langserv/ide-langserv-symbol-node.h
+++ b/src/libide/lsp/ide-lsp-symbol-node.h
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-node.h
+/* ide-lsp-symbol-node.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,21 +20,23 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "symbols/ide-symbol-node.h"
+#include <libide-code.h>
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_SYMBOL_NODE (ide_langserv_symbol_node_get_type())
+#define IDE_TYPE_LSP_SYMBOL_NODE (ide_lsp_symbol_node_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_FINAL_TYPE (IdeLangservSymbolNode, ide_langserv_symbol_node, IDE, LANGSERV_SYMBOL_NODE, 
IdeSymbolNode)
+G_DECLARE_FINAL_TYPE (IdeLspSymbolNode, ide_lsp_symbol_node, IDE, LSP_SYMBOL_NODE, IdeSymbolNode)
 
 IDE_AVAILABLE_IN_3_32
-const gchar *ide_langserv_symbol_node_get_parent_name (IdeLangservSymbolNode *self);
+const gchar *ide_lsp_symbol_node_get_parent_name (IdeLspSymbolNode *self);
 IDE_AVAILABLE_IN_3_32
-gboolean     ide_langserv_symbol_node_is_parent_of    (IdeLangservSymbolNode *self,
-                                                       IdeLangservSymbolNode *other);
+gboolean     ide_lsp_symbol_node_is_parent_of    (IdeLspSymbolNode *self,
+                                                       IdeLspSymbolNode *other);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-symbol-resolver.c b/src/libide/lsp/ide-lsp-symbol-resolver.c
similarity index 63%
rename from src/libide/langserv/ide-langserv-symbol-resolver.c
rename to src/libide/lsp/ide-lsp-symbol-resolver.c
index 2c5fb6834..64d5f5e7d 100644
--- a/src/libide/langserv/ide-langserv-symbol-resolver.c
+++ b/src/libide/lsp/ide-lsp-symbol-resolver.c
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-resolver.c
+/* ide-lsp-symbol-resolver.c
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -18,34 +18,30 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-langserv-symbol-resolver"
+#define G_LOG_DOMAIN "ide-lsp-symbol-resolver"
 
 #include "config.h"
 
 #include <jsonrpc-glib.h>
 
-#include "ide-debug.h"
+#include <libide-code.h>
+#include <libide-threading.h>
 
-#include "diagnostics/ide-source-location.h"
-#include "diagnostics/ide-source-range.h"
-#include "files/ide-file.h"
-#include "langserv/ide-langserv-symbol-node.h"
-#include "langserv/ide-langserv-symbol-node-private.h"
-#include "langserv/ide-langserv-symbol-resolver.h"
-#include "langserv/ide-langserv-symbol-tree.h"
-#include "langserv/ide-langserv-symbol-tree-private.h"
-#include "threading/ide-task.h"
-#include "util/ide-glib.h"
+#include "ide-lsp-symbol-node.h"
+#include "ide-lsp-symbol-node-private.h"
+#include "ide-lsp-symbol-resolver.h"
+#include "ide-lsp-symbol-tree.h"
+#include "ide-lsp-symbol-tree-private.h"
 
 typedef struct
 {
-  IdeLangservClient *client;
-} IdeLangservSymbolResolverPrivate;
+  IdeLspClient *client;
+} IdeLspSymbolResolverPrivate;
 
 static void symbol_resolver_iface_init (IdeSymbolResolverInterface *iface);
 
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLangservSymbolResolver, ide_langserv_symbol_resolver, IDE_TYPE_OBJECT,
-                                  G_ADD_PRIVATE (IdeLangservSymbolResolver)
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspSymbolResolver, ide_lsp_symbol_resolver, IDE_TYPE_OBJECT,
+                                  G_ADD_PRIVATE (IdeLspSymbolResolver)
                                   G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_RESOLVER, 
symbol_resolver_iface_init))
 
 enum {
@@ -57,28 +53,28 @@ enum {
 static GParamSpec *properties [N_PROPS];
 
 static void
-ide_langserv_symbol_resolver_finalize (GObject *object)
+ide_lsp_symbol_resolver_finalize (GObject *object)
 {
-  IdeLangservSymbolResolver *self = (IdeLangservSymbolResolver *)object;
-  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
+  IdeLspSymbolResolver *self = (IdeLspSymbolResolver *)object;
+  IdeLspSymbolResolverPrivate *priv = ide_lsp_symbol_resolver_get_instance_private (self);
 
   g_clear_object (&priv->client);
 
-  G_OBJECT_CLASS (ide_langserv_symbol_resolver_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_lsp_symbol_resolver_parent_class)->finalize (object);
 }
 
 static void
-ide_langserv_symbol_resolver_get_property (GObject    *object,
+ide_lsp_symbol_resolver_get_property (GObject    *object,
                                            guint       prop_id,
                                            GValue     *value,
                                            GParamSpec *pspec)
 {
-  IdeLangservSymbolResolver *self = IDE_LANGSERV_SYMBOL_RESOLVER (object);
+  IdeLspSymbolResolver *self = IDE_LSP_SYMBOL_RESOLVER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      g_value_set_object (value, ide_langserv_symbol_resolver_get_client (self));
+      g_value_set_object (value, ide_lsp_symbol_resolver_get_client (self));
       break;
 
     default:
@@ -87,17 +83,17 @@ ide_langserv_symbol_resolver_get_property (GObject    *object,
 }
 
 static void
-ide_langserv_symbol_resolver_set_property (GObject      *object,
+ide_lsp_symbol_resolver_set_property (GObject      *object,
                                            guint         prop_id,
                                            const GValue *value,
                                            GParamSpec   *pspec)
 {
-  IdeLangservSymbolResolver *self = IDE_LANGSERV_SYMBOL_RESOLVER (object);
+  IdeLspSymbolResolver *self = IDE_LSP_SYMBOL_RESOLVER (object);
 
   switch (prop_id)
     {
     case PROP_CLIENT:
-      ide_langserv_symbol_resolver_set_client (self, g_value_get_object (value));
+      ide_lsp_symbol_resolver_set_client (self, g_value_get_object (value));
       break;
 
     default:
@@ -106,75 +102,72 @@ ide_langserv_symbol_resolver_set_property (GObject      *object,
 }
 
 static void
-ide_langserv_symbol_resolver_class_init (IdeLangservSymbolResolverClass *klass)
+ide_lsp_symbol_resolver_class_init (IdeLspSymbolResolverClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_langserv_symbol_resolver_finalize;
-  object_class->get_property = ide_langserv_symbol_resolver_get_property;
-  object_class->set_property = ide_langserv_symbol_resolver_set_property;
+  object_class->finalize = ide_lsp_symbol_resolver_finalize;
+  object_class->get_property = ide_lsp_symbol_resolver_get_property;
+  object_class->set_property = ide_lsp_symbol_resolver_set_property;
 
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
                          "The Language Server client",
-                         IDE_TYPE_LANGSERV_CLIENT,
+                         IDE_TYPE_LSP_CLIENT,
                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static void
-ide_langserv_symbol_resolver_init (IdeLangservSymbolResolver *self)
+ide_lsp_symbol_resolver_init (IdeLspSymbolResolver *self)
 {
 }
 
 /**
- * ide_langserv_symbol_resolver_get_client:
+ * ide_lsp_symbol_resolver_get_client:
  *
  * Gets the client used by the symbol resolver.
  *
- * Returns: (transfer none) (nullable): An #IdeLangservClient or %NULL.
- *
- * Since: 3.32
+ * Returns: (transfer none) (nullable): An #IdeLspClient or %NULL.
  */
-IdeLangservClient *
-ide_langserv_symbol_resolver_get_client (IdeLangservSymbolResolver *self)
+IdeLspClient *
+ide_lsp_symbol_resolver_get_client (IdeLspSymbolResolver *self)
 {
-  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
+  IdeLspSymbolResolverPrivate *priv = ide_lsp_symbol_resolver_get_instance_private (self);
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_RESOLVER (self), NULL);
 
   return priv->client;
 }
 
 void
-ide_langserv_symbol_resolver_set_client (IdeLangservSymbolResolver *self,
-                                         IdeLangservClient         *client)
+ide_lsp_symbol_resolver_set_client (IdeLspSymbolResolver *self,
+                                         IdeLspClient         *client)
 {
-  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
+  IdeLspSymbolResolverPrivate *priv = ide_lsp_symbol_resolver_get_instance_private (self);
 
-  g_return_if_fail (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
-  g_return_if_fail (!client || IDE_IS_LANGSERV_CLIENT (client));
+  g_return_if_fail (IDE_IS_LSP_SYMBOL_RESOLVER (self));
+  g_return_if_fail (!client || IDE_IS_LSP_CLIENT (client));
 
   if (g_set_object (&priv->client, client))
     g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CLIENT]);
 }
 
 static void
-ide_langserv_symbol_resolver_definition_cb (GObject      *object,
+ide_lsp_symbol_resolver_definition_cb (GObject      *object,
                                             GAsyncResult *result,
                                             gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
-  IdeLangservSymbolResolver *self;
+  IdeLspClient *client = (IdeLspClient *)object;
+  IdeLspSymbolResolver *self;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GError) error = NULL;
   g_autoptr(GVariant) return_value = NULL;
   g_autoptr(IdeSymbol) symbol = NULL;
-  g_autoptr(IdeFile) ifile = NULL;
   g_autoptr(GFile) gfile = NULL;
-  g_autoptr(IdeSourceLocation) location = NULL;
+  g_autoptr(IdeLocation) location = NULL;
   g_autoptr(GVariant) variant = NULL;
   GVariantIter iter;
   const gchar *uri;
@@ -186,13 +179,13 @@ ide_langserv_symbol_resolver_definition_cb (GObject      *object,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
   self = ide_task_get_source_object (task);
-  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
+  g_assert (IDE_IS_LSP_SYMBOL_RESOLVER (self));
 
-  if (!ide_langserv_client_call_finish (client, result, &return_value, &error))
+  if (!ide_lsp_client_call_finish (client, result, &return_value, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       IDE_EXIT;
@@ -237,40 +230,38 @@ ide_langserv_symbol_resolver_definition_cb (GObject      *object,
                  uri, (gint)begin.line + 1, (gint)begin.column + 1);
 
   gfile = g_file_new_for_uri (uri);
-  ifile = ide_file_new (ide_object_get_context (IDE_OBJECT (self)), gfile);
-  location = ide_source_location_new (ifile, begin.line, begin.column, 0);
-  symbol = ide_symbol_new ("", IDE_SYMBOL_NONE, IDE_SYMBOL_FLAGS_NONE, location, location, location);
+  location = ide_location_new (gfile, begin.line, begin.column);
+  symbol = ide_symbol_new ("", IDE_SYMBOL_KIND_NONE, IDE_SYMBOL_FLAGS_NONE, location, location);
 
-  ide_task_return_pointer (task, g_steal_pointer (&symbol), (GDestroyNotify)ide_symbol_unref);
+  ide_task_return_pointer (task, g_steal_pointer (&symbol), g_object_unref);
 
   IDE_EXIT;
 }
 
 static void
-ide_langserv_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
-                                                  IdeSourceLocation   *location,
+ide_lsp_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
+                                                  IdeLocation   *location,
                                                   GCancellable        *cancellable,
                                                   GAsyncReadyCallback  callback,
                                                   gpointer             user_data)
 {
-  IdeLangservSymbolResolver *self = (IdeLangservSymbolResolver *)resolver;
-  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
+  IdeLspSymbolResolver *self = (IdeLspSymbolResolver *)resolver;
+  IdeLspSymbolResolverPrivate *priv = ide_lsp_symbol_resolver_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
-  IdeFile *ifile;
   GFile *gfile;
   gint line;
   gint column;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
+  g_assert (IDE_IS_LSP_SYMBOL_RESOLVER (self));
   g_assert (location != NULL);
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_symbol_resolver_lookup_symbol_async);
+  ide_task_set_source_tag (task, ide_lsp_symbol_resolver_lookup_symbol_async);
 
   if (priv->client == NULL)
     {
@@ -282,8 +273,7 @@ ide_langserv_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
       IDE_EXIT;
     }
 
-  if (NULL == (ifile = ide_source_location_get_file (location)) ||
-      NULL == (gfile = ide_file_get_file (ifile)))
+  if (!(gfile = ide_location_get_file (location)))
     {
       ide_task_return_new_error (task,
                                  G_IO_ERROR,
@@ -293,8 +283,8 @@ ide_langserv_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
     }
 
   uri = g_file_get_uri (gfile);
-  line = ide_source_location_get_line (location);
-  column = ide_source_location_get_line_offset (location);
+  line = ide_location_get_line (location);
+  column = ide_location_get_line_offset (location);
 
   params = JSONRPC_MESSAGE_NEW (
     "textDocument", "{",
@@ -306,18 +296,18 @@ ide_langserv_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
     "}"
   );
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/definition",
                                   params,
                                   cancellable,
-                                  ide_langserv_symbol_resolver_definition_cb,
+                                  ide_lsp_symbol_resolver_definition_cb,
                                   g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static IdeSymbol *
-ide_langserv_symbol_resolver_lookup_symbol_finish (IdeSymbolResolver  *resolver,
+ide_lsp_symbol_resolver_lookup_symbol_finish (IdeSymbolResolver  *resolver,
                                                    GAsyncResult       *result,
                                                    GError            **error)
 {
@@ -325,7 +315,7 @@ ide_langserv_symbol_resolver_lookup_symbol_finish (IdeSymbolResolver  *resolver,
 
   IDE_ENTRY;
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_SYMBOL_RESOLVER (resolver), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_RESOLVER (resolver), NULL);
   g_return_val_if_fail (IDE_IS_TASK (result), NULL);
 
   ret = ide_task_propagate_pointer (IDE_TASK (result), error);
@@ -334,13 +324,13 @@ ide_langserv_symbol_resolver_lookup_symbol_finish (IdeSymbolResolver  *resolver,
 }
 
 static void
-ide_langserv_symbol_resolver_document_symbol_cb (GObject      *object,
+ide_lsp_symbol_resolver_document_symbol_cb (GObject      *object,
                                                  GAsyncResult *result,
                                                  gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
+  IdeLspClient *client = (IdeLspClient *)object;
   g_autoptr(IdeTask) task = user_data;
-  g_autoptr(IdeLangservSymbolTree) tree = NULL;
+  g_autoptr(IdeLspSymbolTree) tree = NULL;
   g_autoptr(GError) error = NULL;
   g_autoptr(GVariant) return_value = NULL;
   g_autoptr(GPtrArray) symbols = NULL;
@@ -349,10 +339,10 @@ ide_langserv_symbol_resolver_document_symbol_cb (GObject      *object,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (IDE_IS_TASK (task));
 
-  if (!ide_langserv_client_call_finish (client, result, &return_value, &error))
+  if (!ide_lsp_client_call_finish (client, result, &return_value, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       IDE_EXIT;
@@ -373,7 +363,7 @@ ide_langserv_symbol_resolver_document_symbol_cb (GObject      *object,
 
   while (g_variant_iter_loop (&iter, "v", &node))
     {
-      g_autoptr(IdeLangservSymbolNode) symbol = NULL;
+      g_autoptr(IdeLspSymbolNode) symbol = NULL;
       g_autoptr(GFile) file = NULL;
       const gchar *name = NULL;
       const gchar *container_name = NULL;
@@ -415,14 +405,14 @@ ide_langserv_symbol_resolver_document_symbol_cb (GObject      *object,
 
       file = g_file_new_for_uri (uri);
 
-      symbol = ide_langserv_symbol_node_new (file, name, container_name, kind,
+      symbol = ide_lsp_symbol_node_new (file, name, container_name, kind,
                                              begin.line, begin.column,
                                              end.line, end.column);
 
       g_ptr_array_add (symbols, g_steal_pointer (&symbol));
     }
 
-  tree = ide_langserv_symbol_tree_new (IDE_PTR_ARRAY_STEAL_FULL (&symbols));
+  tree = ide_lsp_symbol_tree_new (IDE_PTR_ARRAY_STEAL_FULL (&symbols));
 
   ide_task_return_pointer (task, g_steal_pointer (&tree), g_object_unref);
 
@@ -430,27 +420,27 @@ ide_langserv_symbol_resolver_document_symbol_cb (GObject      *object,
 }
 
 static void
-ide_langserv_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *resolver,
+ide_lsp_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *resolver,
                                                     GFile               *file,
-                                                    IdeBuffer           *buffer,
+                                                    GBytes              *bytes,
                                                     GCancellable        *cancellable,
                                                     GAsyncReadyCallback  callback,
                                                     gpointer             user_data)
 {
-  IdeLangservSymbolResolver *self = (IdeLangservSymbolResolver *)resolver;
-  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
+  IdeLspSymbolResolver *self = (IdeLspSymbolResolver *)resolver;
+  IdeLspSymbolResolverPrivate *priv = ide_lsp_symbol_resolver_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
+  g_assert (IDE_IS_LSP_SYMBOL_RESOLVER (self));
   g_assert (G_IS_FILE (file));
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_symbol_resolver_get_symbol_tree_async);
+  ide_task_set_source_tag (task, ide_lsp_symbol_resolver_get_symbol_tree_async);
 
   if (priv->client == NULL)
     {
@@ -469,18 +459,18 @@ ide_langserv_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *resolve
     "}"
   );
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/documentSymbol",
                                   params,
                                   cancellable,
-                                  ide_langserv_symbol_resolver_document_symbol_cb,
+                                  ide_lsp_symbol_resolver_document_symbol_cb,
                                   g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static IdeSymbolTree *
-ide_langserv_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *resolver,
+ide_lsp_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *resolver,
                                                      GAsyncResult       *result,
                                                      GError            **error)
 {
@@ -488,7 +478,7 @@ ide_langserv_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *resolve
 
   IDE_ENTRY;
 
-  g_return_val_if_fail (IDE_IS_LANGSERV_SYMBOL_RESOLVER (resolver), NULL);
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_RESOLVER (resolver), NULL);
   g_return_val_if_fail (IDE_IS_TASK (result), NULL);
 
   ret = ide_task_propagate_pointer (IDE_TASK (result), error);
@@ -497,28 +487,25 @@ ide_langserv_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver  *resolve
 }
 
 static void
-ide_langserv_symbol_resolver_find_references_cb (GObject      *object,
+ide_lsp_symbol_resolver_find_references_cb (GObject      *object,
                                                  GAsyncResult *result,
                                                  gpointer      user_data)
 {
-  IdeLangservClient *client = (IdeLangservClient *)object;
+  IdeLspClient *client = (IdeLspClient *)object;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GVariant) reply = NULL;
   g_autoptr(GPtrArray) references = NULL;
   g_autoptr(GError) error = NULL;
-  IdeLangservSymbolResolver *self;
   GVariant *locationv;
   GVariantIter iter;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_CLIENT (client));
+  g_assert (IDE_IS_LSP_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
-  self = ide_task_get_source_object (task);
-
-  if (!ide_langserv_client_call_finish (client, result, &reply, &error))
+  if (!ide_lsp_client_call_finish (client, result, &reply, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       IDE_EXIT;
@@ -534,16 +521,15 @@ ide_langserv_symbol_resolver_find_references_cb (GObject      *object,
       IDE_EXIT;
     }
 
-  references = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_source_range_unref);
+  references = g_ptr_array_new_with_free_func (g_object_unref);
 
   g_variant_iter_init (&iter, reply);
 
   while (g_variant_iter_loop (&iter, "v", &locationv))
     {
-      g_autoptr(IdeSourceLocation) begin_loc = NULL;
-      g_autoptr(IdeSourceLocation) end_loc = NULL;
-      g_autoptr(IdeSourceRange) range = NULL;
-      g_autoptr(IdeFile) ifile = NULL;
+      g_autoptr(IdeLocation) begin_loc = NULL;
+      g_autoptr(IdeLocation) end_loc = NULL;
+      g_autoptr(IdeRange) range = NULL;
       const gchar *uri = NULL;
       GFile *gfile;
       gboolean success;
@@ -576,11 +562,10 @@ ide_langserv_symbol_resolver_find_references_cb (GObject      *object,
         }
 
       gfile = g_file_new_for_uri (uri);
-      ifile = ide_file_new (ide_object_get_context (IDE_OBJECT (self)), gfile);
 
-      begin_loc = ide_source_location_new (ifile, begin.line, begin.line_offset, 0);
-      end_loc = ide_source_location_new (ifile, end.line, end.line_offset, 0);
-      range = ide_source_range_new (begin_loc, end_loc);
+      begin_loc = ide_location_new (gfile, begin.line, begin.line_offset);
+      end_loc = ide_location_new (gfile, end.line, end.line_offset);
+      range = ide_range_new (begin_loc, end_loc);
 
       g_ptr_array_add (references, g_steal_pointer (&range));
     }
@@ -591,40 +576,37 @@ ide_langserv_symbol_resolver_find_references_cb (GObject      *object,
 }
 
 static void
-ide_langserv_symbol_resolver_find_references_async (IdeSymbolResolver   *resolver,
-                                                    IdeSourceLocation   *location,
+ide_lsp_symbol_resolver_find_references_async (IdeSymbolResolver   *resolver,
+                                                    IdeLocation         *location,
+                                                    const gchar         *language_id,
                                                     GCancellable        *cancellable,
                                                     GAsyncReadyCallback  callback,
                                                     gpointer             user_data)
 {
-  IdeLangservSymbolResolver *self = (IdeLangservSymbolResolver *)resolver;
-  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
+  IdeLspSymbolResolver *self = (IdeLspSymbolResolver *)resolver;
+  IdeLspSymbolResolverPrivate *priv = ide_lsp_symbol_resolver_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
   g_autofree gchar *uri = NULL;
-  const gchar *language_id;
-  IdeFile *file;
   GFile *gfile;
   guint line;
   guint line_offset;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
+  g_assert (IDE_IS_LSP_SYMBOL_RESOLVER (self));
   g_assert (location != NULL);
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_source_tag (task, ide_langserv_symbol_resolver_find_references_async);
+  ide_task_set_source_tag (task, ide_lsp_symbol_resolver_find_references_async);
 
-  file = ide_source_location_get_file (location);
-  gfile = ide_file_get_file (file);
+  gfile = ide_location_get_file (location);
   uri = g_file_get_uri (gfile);
 
-  line = ide_source_location_get_line (location);
-  line_offset = ide_source_location_get_line_offset (location);
+  line = ide_location_get_line (location);
+  line_offset = ide_location_get_line_offset (location);
 
-  language_id = ide_file_get_language_id (file);
   if (language_id == NULL)
     language_id = "plain";
 
@@ -642,18 +624,18 @@ ide_langserv_symbol_resolver_find_references_async (IdeSymbolResolver   *resolve
     "}"
   );
 
-  ide_langserv_client_call_async (priv->client,
+  ide_lsp_client_call_async (priv->client,
                                   "textDocument/references",
                                   params,
                                   cancellable,
-                                  ide_langserv_symbol_resolver_find_references_cb,
+                                  ide_lsp_symbol_resolver_find_references_cb,
                                   g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static GPtrArray *
-ide_langserv_symbol_resolver_find_references_finish (IdeSymbolResolver  *self,
+ide_lsp_symbol_resolver_find_references_finish (IdeSymbolResolver  *self,
                                                      GAsyncResult       *result,
                                                      GError            **error)
 {
@@ -661,7 +643,7 @@ ide_langserv_symbol_resolver_find_references_finish (IdeSymbolResolver  *self,
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
+  g_assert (IDE_IS_LSP_SYMBOL_RESOLVER (self));
   g_assert (IDE_IS_TASK (result));
 
   ret = ide_task_propagate_pointer (IDE_TASK (result), error);
@@ -674,10 +656,10 @@ ide_langserv_symbol_resolver_find_references_finish (IdeSymbolResolver  *self,
 static void
 symbol_resolver_iface_init (IdeSymbolResolverInterface *iface)
 {
-  iface->lookup_symbol_async = ide_langserv_symbol_resolver_lookup_symbol_async;
-  iface->lookup_symbol_finish = ide_langserv_symbol_resolver_lookup_symbol_finish;
-  iface->get_symbol_tree_async = ide_langserv_symbol_resolver_get_symbol_tree_async;
-  iface->get_symbol_tree_finish = ide_langserv_symbol_resolver_get_symbol_tree_finish;
-  iface->find_references_async = ide_langserv_symbol_resolver_find_references_async;
-  iface->find_references_finish = ide_langserv_symbol_resolver_find_references_finish;
+  iface->lookup_symbol_async = ide_lsp_symbol_resolver_lookup_symbol_async;
+  iface->lookup_symbol_finish = ide_lsp_symbol_resolver_lookup_symbol_finish;
+  iface->get_symbol_tree_async = ide_lsp_symbol_resolver_get_symbol_tree_async;
+  iface->get_symbol_tree_finish = ide_lsp_symbol_resolver_get_symbol_tree_finish;
+  iface->find_references_async = ide_lsp_symbol_resolver_find_references_async;
+  iface->find_references_finish = ide_lsp_symbol_resolver_find_references_finish;
 }
diff --git a/src/libide/langserv/ide-langserv-symbol-resolver.h b/src/libide/lsp/ide-lsp-symbol-resolver.h
similarity index 54%
rename from src/libide/langserv/ide-langserv-symbol-resolver.h
rename to src/libide/lsp/ide-lsp-symbol-resolver.h
index f37497e99..4fffeec5a 100644
--- a/src/libide/langserv/ide-langserv-symbol-resolver.h
+++ b/src/libide/lsp/ide-lsp-symbol-resolver.h
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-resolver.h
+/* ide-lsp-symbol-resolver.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,39 +20,33 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "ide-object.h"
+#include <libide-code.h>
 
-#include "langserv/ide-langserv-client.h"
-#include "symbols/ide-symbol-resolver.h"
+#include "ide-lsp-client.h"
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_SYMBOL_RESOLVER (ide_langserv_symbol_resolver_get_type())
+#define IDE_TYPE_LSP_SYMBOL_RESOLVER (ide_lsp_symbol_resolver_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_DERIVABLE_TYPE (IdeLangservSymbolResolver, ide_langserv_symbol_resolver, IDE, 
LANGSERV_SYMBOL_RESOLVER, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeLspSymbolResolver, ide_lsp_symbol_resolver, IDE, LSP_SYMBOL_RESOLVER, IdeObject)
 
-struct _IdeLangservSymbolResolverClass
+struct _IdeLspSymbolResolverClass
 {
   IdeObjectClass parent_class;
 
   /*< private >*/
-  gpointer _reserved1;
-  gpointer _reserved2;
-  gpointer _reserved3;
-  gpointer _reserved4;
-  gpointer _reserved5;
-  gpointer _reserved6;
-  gpointer _reserved7;
-  gpointer _reserved8;
+  gpointer _reserved[16];
 };
 
 IDE_AVAILABLE_IN_3_32
-IdeLangservClient *ide_langserv_symbol_resolver_get_client (IdeLangservSymbolResolver *self);
+IdeLspClient *ide_lsp_symbol_resolver_get_client (IdeLspSymbolResolver *self);
 IDE_AVAILABLE_IN_3_32
-void               ide_langserv_symbol_resolver_set_client (IdeLangservSymbolResolver *self,
-                                                            IdeLangservClient         *client);
+void               ide_lsp_symbol_resolver_set_client (IdeLspSymbolResolver *self,
+                                                            IdeLspClient         *client);
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-symbol-tree-private.h 
b/src/libide/lsp/ide-lsp-symbol-tree-private.h
similarity index 83%
rename from src/libide/langserv/ide-langserv-symbol-tree-private.h
rename to src/libide/lsp/ide-lsp-symbol-tree-private.h
index 3ab8eff59..b674ffc2e 100644
--- a/src/libide/langserv/ide-langserv-symbol-tree-private.h
+++ b/src/libide/lsp/ide-lsp-symbol-tree-private.h
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-tree-private.h
+/* ide-lsp-symbol-tree-private.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,10 +20,10 @@
 
 #pragma once
 
-#include "langserv/ide-langserv-symbol-tree.h"
+#include "ide-lsp-symbol-tree.h"
 
 G_BEGIN_DECLS
 
-IdeLangservSymbolTree *ide_langserv_symbol_tree_new (GPtrArray *symbols);
+IdeLspSymbolTree *ide_lsp_symbol_tree_new (GPtrArray *symbols);
 
 G_END_DECLS
diff --git a/src/libide/lsp/ide-lsp-symbol-tree.c b/src/libide/lsp/ide-lsp-symbol-tree.c
new file mode 100644
index 000000000..53ecb51ab
--- /dev/null
+++ b/src/libide/lsp/ide-lsp-symbol-tree.c
@@ -0,0 +1,190 @@
+/* ide-lsp-symbol-tree.c
+ *
+ * Copyright 2016-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-lsp-symbol-tree"
+
+#include "config.h"
+
+#include "ide-lsp-symbol-node.h"
+#include "ide-lsp-symbol-node-private.h"
+#include "ide-lsp-symbol-tree.h"
+#include "ide-lsp-symbol-tree-private.h"
+
+typedef struct
+{
+  GPtrArray *symbols;
+  GNode      root;
+} IdeLspSymbolTreePrivate;
+
+static void symbol_tree_iface_init (IdeSymbolTreeInterface *iface);
+
+struct _IdeLspSymbolTree { GObject object; };
+G_DEFINE_TYPE_WITH_CODE (IdeLspSymbolTree, ide_lsp_symbol_tree, G_TYPE_OBJECT,
+                         G_ADD_PRIVATE (IdeLspSymbolTree)
+                         G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_TREE, symbol_tree_iface_init))
+
+static guint
+ide_lsp_symbol_tree_get_n_children (IdeSymbolTree *tree,
+                                         IdeSymbolNode *parent)
+{
+  IdeLspSymbolTree *self = (IdeLspSymbolTree *)tree;
+  IdeLspSymbolTreePrivate *priv = ide_lsp_symbol_tree_get_instance_private (self);
+
+  g_assert (IDE_IS_LSP_SYMBOL_TREE (self));
+  g_assert (!parent || IDE_IS_LSP_SYMBOL_NODE (parent));
+
+  if (parent == NULL)
+    return g_node_n_children (&priv->root);
+
+  return g_node_n_children (&IDE_LSP_SYMBOL_NODE (parent)->gnode);
+}
+
+static IdeSymbolNode *
+ide_lsp_symbol_tree_get_nth_child (IdeSymbolTree *tree,
+                                        IdeSymbolNode *parent,
+                                        guint          nth)
+{
+  IdeLspSymbolTree *self = (IdeLspSymbolTree *)tree;
+  IdeLspSymbolTreePrivate *priv = ide_lsp_symbol_tree_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_LSP_SYMBOL_TREE (self), NULL);
+  g_return_val_if_fail (!parent || IDE_IS_LSP_SYMBOL_NODE (parent), NULL);
+
+  if (parent == NULL)
+    {
+      g_return_val_if_fail (nth < g_node_n_children (&priv->root), NULL);
+      return g_object_ref (g_node_nth_child (&priv->root, nth)->data);
+    }
+
+  g_return_val_if_fail (nth < g_node_n_children (&IDE_LSP_SYMBOL_NODE (parent)->gnode), NULL);
+  return g_object_ref (g_node_nth_child (&IDE_LSP_SYMBOL_NODE (parent)->gnode, nth)->data);
+}
+
+static void
+symbol_tree_iface_init (IdeSymbolTreeInterface *iface)
+{
+  iface->get_n_children = ide_lsp_symbol_tree_get_n_children;
+  iface->get_nth_child = ide_lsp_symbol_tree_get_nth_child;
+}
+
+static void
+ide_lsp_symbol_tree_finalize (GObject *object)
+{
+  IdeLspSymbolTree *self = (IdeLspSymbolTree *)object;
+  IdeLspSymbolTreePrivate *priv = ide_lsp_symbol_tree_get_instance_private (self);
+
+  g_clear_pointer (&priv->symbols, g_ptr_array_unref);
+
+  G_OBJECT_CLASS (ide_lsp_symbol_tree_parent_class)->finalize (object);
+}
+
+static void
+ide_lsp_symbol_tree_class_init (IdeLspSymbolTreeClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_lsp_symbol_tree_finalize;
+}
+
+static void
+ide_lsp_symbol_tree_init (IdeLspSymbolTree *self)
+{
+}
+
+static void
+add_to_node (GNode                 *node,
+             IdeLspSymbolNode *symbol)
+{
+  /* First, check to see if any of the children are parents of the range of
+   * this symbol. If so, we will defer to adding it to that node.
+   */
+
+  for (GNode *iter = node->children; iter != NULL; iter = iter->next)
+    {
+      IdeLspSymbolNode *child = iter->data;
+
+      /*
+       * If this node is an ancestor of ours, then we can defer to
+       * adding to that node.
+       */
+      if (ide_lsp_symbol_node_is_parent_of (child, symbol))
+        {
+          add_to_node (iter, symbol);
+          return;
+        }
+
+      /*
+       * If we are the parent of the child, then we need to insert
+       * ourselves in its place and add it to our node.
+       */
+      if (ide_lsp_symbol_node_is_parent_of (symbol, child))
+        {
+          /* Add this node to our children */
+          g_node_unlink (&child->gnode);
+          g_node_append (&symbol->gnode, &child->gnode);
+
+          /* add ourselves to the tree at this level */
+          g_node_append (node, &symbol->gnode);
+
+          return;
+        }
+    }
+
+  g_node_append (node, &symbol->gnode);
+}
+
+static void
+ide_lsp_symbol_tree_build (IdeLspSymbolTree *self)
+{
+  IdeLspSymbolTreePrivate *priv = ide_lsp_symbol_tree_get_instance_private (self);
+
+  g_assert (IDE_IS_LSP_SYMBOL_TREE (self));
+  g_assert (priv->symbols != NULL);
+
+  for (guint i = 0; i < priv->symbols->len; i++)
+    add_to_node (&priv->root, g_ptr_array_index (priv->symbols, i));
+}
+
+/**
+ * ide_lsp_symbol_tree_new:
+ * @symbols: (transfer full) (element-type Ide.LspSymbolNode): The symbols
+ *
+ * Creates a new #IdeLspSymbolTree but takes ownership of @ar.
+ *
+ * Returns: (transfer full): A newly allocated #IdeLspSymbolTree.
+ */
+IdeLspSymbolTree *
+ide_lsp_symbol_tree_new (GPtrArray *symbols)
+{
+  IdeLspSymbolTreePrivate *priv;
+  IdeLspSymbolTree *self;
+
+  g_return_val_if_fail (symbols != NULL, NULL);
+
+  IDE_PTR_ARRAY_SET_FREE_FUNC (symbols, g_object_unref);
+
+  self = g_object_new (IDE_TYPE_LSP_SYMBOL_TREE, NULL);
+  priv = ide_lsp_symbol_tree_get_instance_private (self);
+  priv->symbols = symbols;
+
+  ide_lsp_symbol_tree_build (self);
+
+  return self;
+}
diff --git a/src/libide/langserv/ide-langserv-symbol-tree.h b/src/libide/lsp/ide-lsp-symbol-tree.h
similarity index 71%
rename from src/libide/langserv/ide-langserv-symbol-tree.h
rename to src/libide/lsp/ide-lsp-symbol-tree.h
index 7fd480b87..2b12c3d02 100644
--- a/src/libide/langserv/ide-langserv-symbol-tree.h
+++ b/src/libide/lsp/ide-lsp-symbol-tree.h
@@ -1,4 +1,4 @@
-/* ide-langserv-symbol-tree.h
+/* ide-lsp-symbol-tree.h
  *
  * Copyright 2016-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,15 +20,17 @@
 
 #pragma once
 
-#include "symbols/ide-symbol-tree.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "ide-version-macros.h"
+#include <libide-code.h>
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_LANGSERV_SYMBOL_TREE (ide_langserv_symbol_tree_get_type())
+#define IDE_TYPE_LSP_SYMBOL_TREE (ide_lsp_symbol_tree_get_type())
 
 IDE_AVAILABLE_IN_3_32
-G_DECLARE_FINAL_TYPE (IdeLangservSymbolTree, ide_langserv_symbol_tree, IDE, LANGSERV_SYMBOL_TREE, GObject)
+G_DECLARE_FINAL_TYPE (IdeLspSymbolTree, ide_lsp_symbol_tree, IDE, LSP_SYMBOL_TREE, GObject)
 
 G_END_DECLS
diff --git a/src/libide/langserv/ide-langserv-types.h b/src/libide/lsp/ide-lsp-types.h
similarity index 93%
rename from src/libide/langserv/ide-langserv-types.h
rename to src/libide/lsp/ide-lsp-types.h
index 8b1ac3ee6..57913ce08 100644
--- a/src/libide/langserv/ide-langserv-types.h
+++ b/src/libide/lsp/ide-lsp-types.h
@@ -20,6 +20,10 @@
 
 #pragma once
 
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
+
 G_BEGIN_DECLS
 
 typedef enum
diff --git a/src/libide/lsp/ide-lsp-util.c b/src/libide/lsp/ide-lsp-util.c
new file mode 100644
index 000000000..bf3950c1b
--- /dev/null
+++ b/src/libide/lsp/ide-lsp-util.c
@@ -0,0 +1,80 @@
+/* ide-lsp-util.c
+ *
+ * Copyright 2017-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "ide-lsp-util.h"
+
+IdeSymbolKind
+ide_lsp_decode_symbol_kind (guint kind)
+{
+  switch (kind)
+    {
+    case 1:   kind = IDE_SYMBOL_KIND_FILE;         break;
+    case 2:   kind = IDE_SYMBOL_KIND_MODULE;       break;
+    case 3:   kind = IDE_SYMBOL_KIND_NAMESPACE;    break;
+    case 4:   kind = IDE_SYMBOL_KIND_PACKAGE;      break;
+    case 5:   kind = IDE_SYMBOL_KIND_CLASS;        break;
+    case 6:   kind = IDE_SYMBOL_KIND_METHOD;       break;
+    case 7:   kind = IDE_SYMBOL_KIND_PROPERTY;     break;
+    case 8:   kind = IDE_SYMBOL_KIND_FIELD;        break;
+    case 9:   kind = IDE_SYMBOL_KIND_CONSTRUCTOR;  break;
+    case 10:  kind = IDE_SYMBOL_KIND_ENUM;         break;
+    case 11:  kind = IDE_SYMBOL_KIND_INTERFACE;    break;
+    case 12:  kind = IDE_SYMBOL_KIND_FUNCTION;     break;
+    case 13:  kind = IDE_SYMBOL_KIND_VARIABLE;     break;
+    case 14:  kind = IDE_SYMBOL_KIND_CONSTANT;     break;
+    case 15:  kind = IDE_SYMBOL_KIND_STRING;       break;
+    case 16:  kind = IDE_SYMBOL_KIND_NUMBER;       break;
+    case 17:  kind = IDE_SYMBOL_KIND_BOOLEAN;      break;
+    case 18:  kind = IDE_SYMBOL_KIND_ARRAY;        break;
+    default:  kind = IDE_SYMBOL_KIND_NONE;         break;
+    }
+
+  return kind;
+}
+
+IdeSymbolKind
+ide_lsp_decode_completion_kind (guint kind)
+{
+  switch (kind)
+    {
+    case 1:   kind = IDE_SYMBOL_KIND_STRING;       break;
+    case 2:   kind = IDE_SYMBOL_KIND_METHOD;       break;
+    case 3:   kind = IDE_SYMBOL_KIND_FUNCTION;     break;
+    case 4:   kind = IDE_SYMBOL_KIND_CONSTRUCTOR;  break;
+    case 5:   kind = IDE_SYMBOL_KIND_FIELD;        break;
+    case 6:   kind = IDE_SYMBOL_KIND_VARIABLE;     break;
+    case 7:   kind = IDE_SYMBOL_KIND_CLASS;        break;
+    case 8:   kind = IDE_SYMBOL_KIND_INTERFACE;    break;
+    case 9:   kind = IDE_SYMBOL_KIND_MODULE;       break;
+    case 10:  kind = IDE_SYMBOL_KIND_PROPERTY;     break;
+    case 11:  kind = IDE_SYMBOL_KIND_NUMBER;       break;
+    case 12:  kind = IDE_SYMBOL_KIND_SCALAR;       break;
+    case 13:  kind = IDE_SYMBOL_KIND_ENUM_VALUE;   break;
+    case 14:  kind = IDE_SYMBOL_KIND_KEYWORD;      break;
+    case 17:  kind = IDE_SYMBOL_KIND_FILE;         break;
+
+    case 15: /* Snippet */
+    case 16: /* Color */
+    case 18: /* Reference */
+    default:  kind = IDE_SYMBOL_KIND_NONE;         break;
+    }
+
+  return kind;
+}
diff --git a/src/libide/langserv/ide-langserv-util.h b/src/libide/lsp/ide-lsp-util.h
similarity index 74%
rename from src/libide/langserv/ide-langserv-util.h
rename to src/libide/lsp/ide-lsp-util.h
index a6fa02df2..e36f56c33 100644
--- a/src/libide/langserv/ide-langserv-util.h
+++ b/src/libide/lsp/ide-lsp-util.h
@@ -1,4 +1,4 @@
-/* ide-langserv-util.h
+/* ide-lsp-util.h
  *
  * Copyright 2017-2019 Christian Hergert <chergert redhat com>
  *
@@ -20,15 +20,17 @@
 
 #pragma once
 
-#include "ide-version-macros.h"
+#if !defined (IDE_LSP_INSIDE) && !defined (IDE_LSP_COMPILATION)
+# error "Only <libide-lsp.h> can be included directly."
+#endif
 
-#include "symbols/ide-symbol.h"
+#include <libide-code.h>
 
 G_BEGIN_DECLS
 
 IDE_AVAILABLE_IN_3_32
-IdeSymbolKind ide_langserv_decode_symbol_kind     (guint kind);
+IdeSymbolKind ide_lsp_decode_symbol_kind     (guint kind);
 IDE_AVAILABLE_IN_3_32
-IdeSymbolKind ide_langserv_decode_completion_kind (guint kind);
+IdeSymbolKind ide_lsp_decode_completion_kind (guint kind);
 
 G_END_DECLS
diff --git a/src/libide/lsp/libide-lsp.h b/src/libide/lsp/libide-lsp.h
new file mode 100644
index 000000000..a91bcedb4
--- /dev/null
+++ b/src/libide/lsp/libide-lsp.h
@@ -0,0 +1,42 @@
+/* libide-lsp.h
+ *
+ * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+#define IDE_LSP_INSIDE
+
+#include "ide-lsp-types.h"
+
+#include "ide-lsp-client.h"
+#include "ide-lsp-completion-item.h"
+#include "ide-lsp-completion-provider.h"
+#include "ide-lsp-completion-results.h"
+#include "ide-lsp-diagnostic-provider.h"
+#include "ide-lsp-formatter.h"
+#include "ide-lsp-highlighter.h"
+#include "ide-lsp-hover-provider.h"
+#include "ide-lsp-rename-provider.h"
+#include "ide-lsp-symbol-node.h"
+#include "ide-lsp-symbol-resolver.h"
+#include "ide-lsp-symbol-tree.h"
+
+#undef IDE_LSP_INSIDE
diff --git a/src/libide/lsp/meson.build b/src/libide/lsp/meson.build
new file mode 100644
index 000000000..23aba74fa
--- /dev/null
+++ b/src/libide/lsp/meson.build
@@ -0,0 +1,94 @@
+libide_lsp_header_subdir = join_paths(libide_header_subdir, 'lsp')
+libide_include_directories += include_directories('.')
+
+#
+# Public API Headers
+#
+
+libide_lsp_public_headers = [
+  'libide-lsp.h',
+  'ide-lsp-client.h',
+  'ide-lsp-completion-item.h',
+  'ide-lsp-completion-provider.h',
+  'ide-lsp-completion-results.h',
+  'ide-lsp-diagnostic-provider.h',
+  'ide-lsp-formatter.h',
+  'ide-lsp-highlighter.h',
+  'ide-lsp-hover-provider.h',
+  'ide-lsp-rename-provider.h',
+  'ide-lsp-symbol-node.h',
+  'ide-lsp-symbol-resolver.h',
+  'ide-lsp-symbol-tree.h',
+  'ide-lsp-types.h',
+]
+
+libide_lsp_private_headers = [
+  'ide-lsp-util.h',
+  'ide-lsp-symbol-node-private.h',
+  'ide-lsp-symbol-tree-private.h',
+]
+
+install_headers(libide_lsp_public_headers, subdir: libide_lsp_header_subdir)
+
+#
+# Sources
+#
+
+libide_lsp_public_sources = [
+  'ide-lsp-client.c',
+  'ide-lsp-completion-item.c',
+  'ide-lsp-completion-provider.c',
+  'ide-lsp-completion-results.c',
+  'ide-lsp-diagnostic-provider.c',
+  'ide-lsp-formatter.c',
+  'ide-lsp-highlighter.c',
+  'ide-lsp-hover-provider.c',
+  'ide-lsp-rename-provider.c',
+  'ide-lsp-symbol-node.c',
+  'ide-lsp-symbol-resolver.c',
+  'ide-lsp-symbol-tree.c',
+]
+
+libide_lsp_private_sources = [
+  'ide-lsp-util.c',
+]
+
+libide_lsp_sources = libide_lsp_public_sources + libide_lsp_private_sources
+
+#
+# Dependencies
+#
+
+libide_lsp_deps = [
+  libgio_dep,
+  libjsonrpc_glib_dep,
+  libdazzle_dep,
+
+  libide_code_dep,
+  libide_core_dep,
+  libide_io_dep,
+  libide_projects_dep,
+  libide_sourceview_dep,
+  libide_threading_dep,
+]
+
+#
+# Library Definitions
+#
+
+libide_lsp = static_library('ide-lsp-' + libide_api_version, libide_lsp_sources,
+   dependencies: libide_lsp_deps,
+         c_args: libide_args + release_args + ['-DIDE_LSP_COMPILATION'],
+)
+
+libide_lsp_dep = declare_dependency(
+              sources: libide_lsp_private_headers,
+         dependencies: libide_lsp_deps,
+           link_whole: libide_lsp,
+  include_directories: include_directories('.'),
+)
+
+gnome_builder_public_sources += files(libide_lsp_public_sources)
+gnome_builder_public_headers += files(libide_lsp_public_headers)
+gnome_builder_include_subdirs += libide_lsp_header_subdir
+gnome_builder_gir_extra_args += ['--c-include=libide-lsp.h', '-DIDE_LSP_COMPILATION']



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]