complition
This commit is contained in:
+108
@@ -75,6 +75,67 @@ impl Language {
|
||||
Self::Python => "python",
|
||||
}
|
||||
}
|
||||
|
||||
/// Идентификатор языка для LSP (`languageId` в `textDocument/didOpen`).
|
||||
///
|
||||
/// Отличается от [`Self::name`] тем же, чем `highlight_name`: LSP ждёт
|
||||
/// `javascript`, а не `js`.
|
||||
pub fn lsp_name(self) -> &'static str {
|
||||
match self {
|
||||
Self::Rust => "rust",
|
||||
Self::Go => "go",
|
||||
Self::JavaScript => "javascript",
|
||||
Self::Json => "json",
|
||||
Self::Python => "python",
|
||||
}
|
||||
}
|
||||
|
||||
/// Определяет язык подсветки по имени файла.
|
||||
///
|
||||
/// Используется при открытии файла с диска (`app:open(path)`), чтобы
|
||||
/// подсветка включалась автоматически там, где для неё есть грамматика.
|
||||
pub fn from_path(path: &str) -> Option<Self> {
|
||||
let extension = path.rsplit_once('.')?.1.to_ascii_lowercase();
|
||||
match extension.as_str() {
|
||||
"rs" => Some(Self::Rust),
|
||||
"go" => Some(Self::Go),
|
||||
"js" | "mjs" | "cjs" | "jsx" => Some(Self::JavaScript),
|
||||
"json" => Some(Self::Json),
|
||||
"py" => Some(Self::Python),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Язык LSP по расширению имени файла.
|
||||
///
|
||||
/// Нужен для документов, у которых подсветка ещё не включена: LSP-сервер
|
||||
/// выбирается и получает `languageId` независимо от tree-sitter.
|
||||
pub fn language_id_from_path(name: &str) -> &'static str {
|
||||
let extension = name
|
||||
.rsplit_once('.')
|
||||
.map(|(_, extension)| extension.to_ascii_lowercase());
|
||||
|
||||
match extension.as_deref() {
|
||||
Some("rs") => "rust",
|
||||
Some("go") => "go",
|
||||
Some("js" | "mjs" | "cjs") => "javascript",
|
||||
Some("jsx") => "javascriptreact",
|
||||
Some("ts") => "typescript",
|
||||
Some("tsx") => "typescriptreact",
|
||||
Some("json") => "json",
|
||||
Some("py") => "python",
|
||||
Some("md" | "markdown") => "markdown",
|
||||
Some("toml") => "toml",
|
||||
Some("yaml" | "yml") => "yaml",
|
||||
Some("lua") => "lua",
|
||||
Some("c" | "h") => "c",
|
||||
Some("cc" | "cpp" | "cxx" | "hpp" | "hh") => "cpp",
|
||||
Some("sh" | "bash") => "shellscript",
|
||||
Some("html" | "htm") => "html",
|
||||
Some("css") => "css",
|
||||
_ => "plaintext",
|
||||
}
|
||||
}
|
||||
|
||||
/// Открытый в редакторе документ.
|
||||
@@ -115,6 +176,17 @@ impl Document {
|
||||
self.content != self.saved_content
|
||||
}
|
||||
|
||||
/// Идентификатор языка для LSP.
|
||||
///
|
||||
/// Если подсветка уже включена, берётся её язык. Иначе язык угадывается
|
||||
/// по расширению имени вкладки — так LSP работает и без `set_language`.
|
||||
pub fn lsp_language_id(&self) -> String {
|
||||
if let Some(language) = self.language {
|
||||
return language.lsp_name().to_owned();
|
||||
}
|
||||
language_id_from_path(&self.name).to_owned()
|
||||
}
|
||||
|
||||
/// Помечает текущее содержимое сохранённым.
|
||||
pub fn mark_saved(&mut self) {
|
||||
self.saved_content = self.content.clone();
|
||||
@@ -207,6 +279,42 @@ impl Workspace {
|
||||
self.bump();
|
||||
}
|
||||
|
||||
/// Открывает файл с диска как вкладку и делает её активной.
|
||||
///
|
||||
/// Если вкладка с таким именем уже открыта и не содержит несохранённых
|
||||
/// изменений, её содержимое обновляется из файла — повторный `app:open`
|
||||
/// не создаёт дубликат. Грязная вкладка не трогается: открывается новая.
|
||||
pub fn open_file(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
content: impl Into<String>,
|
||||
language: Option<Language>,
|
||||
) -> usize {
|
||||
let name = name.into();
|
||||
let content = content.into();
|
||||
|
||||
if let Some(index) = self
|
||||
.documents
|
||||
.iter()
|
||||
.position(|document| document.name == name && !document.is_dirty())
|
||||
{
|
||||
let document = &mut self.documents[index];
|
||||
document.content = content;
|
||||
document.mark_saved();
|
||||
document.language = language;
|
||||
self.active = index;
|
||||
self.bump();
|
||||
return index;
|
||||
}
|
||||
|
||||
let mut document = Document::new(name, content);
|
||||
document.language = language;
|
||||
self.documents.push(document);
|
||||
self.active = self.documents.len() - 1;
|
||||
self.bump();
|
||||
self.active
|
||||
}
|
||||
|
||||
/// Закрывает вкладку и выбирает соседнюю.
|
||||
///
|
||||
/// Если закрывается последняя вкладка, вместо неё открывается пустой документ.
|
||||
|
||||
Reference in New Issue
Block a user