diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs
index 4be3e71b..cfe466ed 100644
--- a/helix-core/src/lib.rs
+++ b/helix-core/src/lib.rs
@@ -45,6 +45,30 @@ pub(crate) fn find_first_non_whitespace_char(text: RopeSlice, line_num: usize) -
     None
 }
 
+pub fn find_root(root: Option<&str>) -> Option<std::path::PathBuf> {
+    let current_dir = std::env::current_dir().expect("unable to determine current directory");
+
+    let root = match root {
+        Some(root) => {
+            let root = std::path::Path::new(root);
+            if root.is_absolute() {
+                root.to_path_buf()
+            } else {
+                current_dir.join(root)
+            }
+        }
+        None => current_dir,
+    };
+
+    for ancestor in root.ancestors() {
+        // TODO: also use defined roots if git isn't found
+        if ancestor.join(".git").is_dir() {
+            return Some(ancestor.to_path_buf());
+        }
+    }
+    None
+}
+
 #[cfg(not(embed_runtime))]
 pub fn runtime_dir() -> std::path::PathBuf {
     // runtime env var || dir where binary is located
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs
index 8a3aabd9..a1c1134a 100644
--- a/helix-lsp/src/client.rs
+++ b/helix-lsp/src/client.rs
@@ -3,7 +3,7 @@ use crate::{
     Call, Error, OffsetEncoding, Result,
 };
 
-use helix_core::{ChangeSet, Rope};
+use helix_core::{find_root, ChangeSet, Rope};
 
 // use std::collections::HashMap;
 use std::future::Future;
@@ -218,13 +218,14 @@ impl Client {
 
     pub async fn initialize(&mut self) -> Result<()> {
         // TODO: delay any requests that are triggered prior to initialize
+        let root = find_root(None).and_then(|root| lsp::Url::from_file_path(root).ok());
 
         #[allow(deprecated)]
         let params = lsp::InitializeParams {
             process_id: Some(std::process::id()),
+            // root_path is obsolete, use root_uri
             root_path: None,
-            // root_uri: Some(lsp_types::Url::parse("file://localhost/")?),
-            root_uri: None, // set to project root in the future
+            root_uri: root,
             initialization_options: None,
             capabilities: lsp::ClientCapabilities {
                 text_document: Some(lsp::TextDocumentClientCapabilities {
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index fe334117..15fac7ad 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1,5 +1,5 @@
 use helix_core::{
-    comment, coords_at_pos, graphemes, indent, match_brackets,
+    comment, coords_at_pos, find_root, graphemes, indent, match_brackets,
     movement::{self, Direction},
     object, pos_at_coords,
     regex::{self, Regex},
@@ -1093,30 +1093,6 @@ pub fn command_mode(cx: &mut Context) {
     cx.push_layer(Box::new(prompt));
 }
 
-fn find_root(root: Option<&str>) -> Option<PathBuf> {
-    let current_dir = std::env::current_dir().expect("unable to determine current directory");
-
-    let root = match root {
-        Some(root) => {
-            let root = Path::new(root);
-            if root.is_absolute() {
-                root.to_path_buf()
-            } else {
-                current_dir.join(root)
-            }
-        }
-        None => current_dir,
-    };
-
-    for ancestor in root.ancestors() {
-        // TODO: also use defined roots if git isn't found
-        if ancestor.join(".git").is_dir() {
-            return Some(ancestor.to_path_buf());
-        }
-    }
-    None
-}
-
 pub fn file_picker(cx: &mut Context) {
     let root = find_root(None).unwrap_or_else(|| PathBuf::from("./"));
     let picker = ui::file_picker(root);