mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:53 +00:00
ruff server
: Support Jupyter Notebook (*.ipynb
) files (#11206)
## Summary Closes https://github.com/astral-sh/ruff/issues/10858. `ruff server` now supports `*.ipynb` (aka Jupyter Notebook) files. Extensive internal changes have been made to facilitate this, which I've done some work to contextualize with documentation and an pre-review that highlights notable sections of the code. `*.ipynb` cells should behave similarly to `*.py` documents, with one major exception. The format command `ruff.applyFormat` will only apply to the currently selected notebook cell - if you want to format an entire notebook document, use `Format Notebook` from the VS Code context menu. ## Test Plan The VS Code extension does not yet have Jupyter Notebook support enabled, so you'll first need to enable it manually. To do this, checkout the `pre-release` branch and modify `src/common/server.ts` as follows: Before:  After:  I recommend testing this PR with large, complicated notebook files. I used notebook files from [this popular repository](https://github.com/jakevdp/PythonDataScienceHandbook/tree/master/notebooks) in my preliminary testing. The main thing to test is ensuring that notebook cells behave the same as Python documents, besides the aforementioned issue with `ruff.applyFormat`. You should also test adding and deleting cells (in particular, deleting all the code cells and ensure that doesn't break anything), changing the kind of a cell (i.e. from markup -> code or vice versa), and creating a new notebook file from scratch. Finally, you should also test that source actions work as expected (and across the entire notebook). Note: `ruff.applyAutofix` and `ruff.applyOrganizeImports` are currently broken for notebook files, and I suspect it has something to do with https://github.com/astral-sh/ruff/issues/11248. Once this is fixed, I will update the test plan accordingly. --------- Co-authored-by: nolan <nolan.king90@gmail.com>
This commit is contained in:
parent
84531d1644
commit
b0731ef9cb
39 changed files with 1584 additions and 622 deletions
|
@ -1,6 +1,7 @@
|
|||
//! Scheduling, I/O, and API endpoints.
|
||||
|
||||
use std::num::NonZeroUsize;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use lsp_server as lsp;
|
||||
use lsp_types as types;
|
||||
|
@ -10,6 +11,9 @@ use types::CodeActionOptions;
|
|||
use types::DiagnosticOptions;
|
||||
use types::DidChangeWatchedFilesRegistrationOptions;
|
||||
use types::FileSystemWatcher;
|
||||
use types::NotebookCellSelector;
|
||||
use types::NotebookDocumentSyncOptions;
|
||||
use types::NotebookSelector;
|
||||
use types::OneOf;
|
||||
use types::TextDocumentSyncCapability;
|
||||
use types::TextDocumentSyncKind;
|
||||
|
@ -67,26 +71,26 @@ impl Server {
|
|||
mut workspace_settings,
|
||||
} = AllSettings::from_value(init_params.initialization_options.unwrap_or_default());
|
||||
|
||||
let mut workspace_for_uri = |uri| {
|
||||
let mut workspace_for_path = |path: PathBuf| {
|
||||
let Some(workspace_settings) = workspace_settings.as_mut() else {
|
||||
return (uri, ClientSettings::default());
|
||||
return (path, ClientSettings::default());
|
||||
};
|
||||
let settings = workspace_settings.remove(&uri).unwrap_or_else(|| {
|
||||
tracing::warn!("No workspace settings found for {uri}");
|
||||
let settings = workspace_settings.remove(&path).unwrap_or_else(|| {
|
||||
tracing::warn!("No workspace settings found for {}", path.display());
|
||||
ClientSettings::default()
|
||||
});
|
||||
(uri, settings)
|
||||
(path, settings)
|
||||
};
|
||||
|
||||
let workspaces = init_params
|
||||
.workspace_folders
|
||||
.map(|folders| folders.into_iter().map(|folder| {
|
||||
workspace_for_uri(folder.uri)
|
||||
workspace_for_path(folder.uri.to_file_path().unwrap())
|
||||
}).collect())
|
||||
.or_else(|| {
|
||||
tracing::debug!("No workspace(s) were provided during initialization. Using the current working directory as a default workspace...");
|
||||
let uri = types::Url::from_file_path(std::env::current_dir().ok()?).ok()?;
|
||||
Some(vec![workspace_for_uri(uri)])
|
||||
Some(vec![workspace_for_path(uri.to_file_path().unwrap())])
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!("Failed to get the current working directory while creating a default workspace.")
|
||||
|
@ -100,7 +104,7 @@ impl Server {
|
|||
position_encoding,
|
||||
global_settings,
|
||||
workspaces,
|
||||
)?,
|
||||
),
|
||||
client_capabilities,
|
||||
})
|
||||
}
|
||||
|
@ -252,6 +256,16 @@ impl Server {
|
|||
},
|
||||
)),
|
||||
hover_provider: Some(types::HoverProviderCapability::Simple(true)),
|
||||
notebook_document_sync: Some(types::OneOf::Left(NotebookDocumentSyncOptions {
|
||||
save: Some(false),
|
||||
notebook_selector: [NotebookSelector::ByCells {
|
||||
notebook: None,
|
||||
cells: vec![NotebookCellSelector {
|
||||
language: "python".to_string(),
|
||||
}],
|
||||
}]
|
||||
.to_vec(),
|
||||
})),
|
||||
text_document_sync: Some(TextDocumentSyncCapability::Options(
|
||||
TextDocumentSyncOptions {
|
||||
open_close: Some(true),
|
||||
|
@ -278,8 +292,15 @@ pub(crate) enum SupportedCodeAction {
|
|||
SourceFixAll,
|
||||
/// Maps to `source.organizeImports` and `source.organizeImports.ruff` code action kinds.
|
||||
/// This is a source action that applies import sorting fixes to the currently open document.
|
||||
#[allow(dead_code)] // TODO: remove
|
||||
SourceOrganizeImports,
|
||||
/// Maps to the `notebook.source.fixAll` and `notebook.source.fixAll.ruff` code action kinds.
|
||||
/// This is a source action, specifically for notebooks, that applies all safe fixes
|
||||
/// to the currently open document.
|
||||
NotebookSourceFixAll,
|
||||
/// Maps to `source.organizeImports` and `source.organizeImports.ruff` code action kinds.
|
||||
/// This is a source action, specifically for notebooks, that applies import sorting fixes
|
||||
/// to the currently open document.
|
||||
NotebookSourceOrganizeImports,
|
||||
}
|
||||
|
||||
impl SupportedCodeAction {
|
||||
|
@ -289,6 +310,8 @@ impl SupportedCodeAction {
|
|||
Self::QuickFix => CodeActionKind::QUICKFIX,
|
||||
Self::SourceFixAll => crate::SOURCE_FIX_ALL_RUFF,
|
||||
Self::SourceOrganizeImports => crate::SOURCE_ORGANIZE_IMPORTS_RUFF,
|
||||
Self::NotebookSourceFixAll => crate::NOTEBOOK_SOURCE_FIX_ALL_RUFF,
|
||||
Self::NotebookSourceOrganizeImports => crate::NOTEBOOK_SOURCE_ORGANIZE_IMPORTS_RUFF,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,6 +327,8 @@ impl SupportedCodeAction {
|
|||
Self::QuickFix,
|
||||
Self::SourceFixAll,
|
||||
Self::SourceOrganizeImports,
|
||||
Self::NotebookSourceFixAll,
|
||||
Self::NotebookSourceOrganizeImports,
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue