diff --git a/jinja-lsp-nodejs/index.d.ts b/jinja-lsp-nodejs/index.d.ts index 5f3b749..8041c01 100644 --- a/jinja-lsp-nodejs/index.d.ts +++ b/jinja-lsp-nodejs/index.d.ts @@ -78,7 +78,7 @@ export class NodejsLspFiles { /** Actions can come from unsaved context. */ addGlobalContext(uri: string, actions?: Array | undefined | null): void deleteAll(filename: string): void - addOne(id: number, filename: string, content: string, line: number): Array + addOne(id: number, filename: string, content: string, line: number, ext: string): Array getVariables(id: string, line: number): Array | null hover(id: number, filename: string, line: number, position: JsPosition): JsHover | null complete(id: number, filename: string, line: number, position: JsPosition): Array | null diff --git a/jinja-lsp-nodejs/npm/android-arm-eabi/package.json b/jinja-lsp-nodejs/npm/android-arm-eabi/package.json index 2d38e06..55b843f 100644 --- a/jinja-lsp-nodejs/npm/android-arm-eabi/package.json +++ b/jinja-lsp-nodejs/npm/android-arm-eabi/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-android-arm-eabi", - "version": "0.0.7", + "version": "0.0.8", "os": [ "android" ], diff --git a/jinja-lsp-nodejs/npm/android-arm64/package.json b/jinja-lsp-nodejs/npm/android-arm64/package.json index 7a82539..9680ee3 100644 --- a/jinja-lsp-nodejs/npm/android-arm64/package.json +++ b/jinja-lsp-nodejs/npm/android-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-android-arm64", - "version": "0.0.7", + "version": "0.0.8", "os": [ "android" ], diff --git a/jinja-lsp-nodejs/npm/darwin-arm64/package.json b/jinja-lsp-nodejs/npm/darwin-arm64/package.json index 0b4ac1a..d5012dd 100644 --- a/jinja-lsp-nodejs/npm/darwin-arm64/package.json +++ b/jinja-lsp-nodejs/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-darwin-arm64", - "version": "0.0.7", + "version": "0.0.8", "os": [ "darwin" ], diff --git a/jinja-lsp-nodejs/npm/darwin-universal/package.json b/jinja-lsp-nodejs/npm/darwin-universal/package.json index 3d1e1cd..bbff564 100644 --- a/jinja-lsp-nodejs/npm/darwin-universal/package.json +++ b/jinja-lsp-nodejs/npm/darwin-universal/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-darwin-universal", - "version": "0.0.7", + "version": "0.0.8", "os": [ "darwin" ], diff --git a/jinja-lsp-nodejs/npm/freebsd-x64/package.json b/jinja-lsp-nodejs/npm/freebsd-x64/package.json index 01151b3..23dcf9f 100644 --- a/jinja-lsp-nodejs/npm/freebsd-x64/package.json +++ b/jinja-lsp-nodejs/npm/freebsd-x64/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-freebsd-x64", - "version": "0.0.7", + "version": "0.0.8", "os": [ "freebsd" ], diff --git a/jinja-lsp-nodejs/npm/linux-arm-gnueabihf/package.json b/jinja-lsp-nodejs/npm/linux-arm-gnueabihf/package.json index c6a2631..8749944 100644 --- a/jinja-lsp-nodejs/npm/linux-arm-gnueabihf/package.json +++ b/jinja-lsp-nodejs/npm/linux-arm-gnueabihf/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-arm-gnueabihf", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/linux-arm-musleabihf/package.json b/jinja-lsp-nodejs/npm/linux-arm-musleabihf/package.json index a3af135..c0f5e90 100644 --- a/jinja-lsp-nodejs/npm/linux-arm-musleabihf/package.json +++ b/jinja-lsp-nodejs/npm/linux-arm-musleabihf/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-arm-musleabihf", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/linux-arm64-gnu/package.json b/jinja-lsp-nodejs/npm/linux-arm64-gnu/package.json index 43d8ceb..b1f358a 100644 --- a/jinja-lsp-nodejs/npm/linux-arm64-gnu/package.json +++ b/jinja-lsp-nodejs/npm/linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-arm64-gnu", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/linux-arm64-musl/package.json b/jinja-lsp-nodejs/npm/linux-arm64-musl/package.json index 681c1fa..e193a50 100644 --- a/jinja-lsp-nodejs/npm/linux-arm64-musl/package.json +++ b/jinja-lsp-nodejs/npm/linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-arm64-musl", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/linux-riscv64-gnu/package.json b/jinja-lsp-nodejs/npm/linux-riscv64-gnu/package.json index 2ddcbc3..0c4b99d 100644 --- a/jinja-lsp-nodejs/npm/linux-riscv64-gnu/package.json +++ b/jinja-lsp-nodejs/npm/linux-riscv64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-riscv64-gnu", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/linux-x64-gnu/package.json b/jinja-lsp-nodejs/npm/linux-x64-gnu/package.json index 8997ad7..97da981 100644 --- a/jinja-lsp-nodejs/npm/linux-x64-gnu/package.json +++ b/jinja-lsp-nodejs/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-x64-gnu", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/linux-x64-musl/package.json b/jinja-lsp-nodejs/npm/linux-x64-musl/package.json index 8f30346..c7be9ab 100644 --- a/jinja-lsp-nodejs/npm/linux-x64-musl/package.json +++ b/jinja-lsp-nodejs/npm/linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-linux-x64-musl", - "version": "0.0.7", + "version": "0.0.8", "os": [ "linux" ], diff --git a/jinja-lsp-nodejs/npm/win32-arm64-msvc/package.json b/jinja-lsp-nodejs/npm/win32-arm64-msvc/package.json index 04eb041..9d4d7d0 100644 --- a/jinja-lsp-nodejs/npm/win32-arm64-msvc/package.json +++ b/jinja-lsp-nodejs/npm/win32-arm64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-win32-arm64-msvc", - "version": "0.0.7", + "version": "0.0.8", "os": [ "win32" ], diff --git a/jinja-lsp-nodejs/npm/win32-ia32-msvc/package.json b/jinja-lsp-nodejs/npm/win32-ia32-msvc/package.json index e8862f6..9f2c825 100644 --- a/jinja-lsp-nodejs/npm/win32-ia32-msvc/package.json +++ b/jinja-lsp-nodejs/npm/win32-ia32-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-win32-ia32-msvc", - "version": "0.0.7", + "version": "0.0.8", "os": [ "win32" ], diff --git a/jinja-lsp-nodejs/npm/win32-x64-msvc/package.json b/jinja-lsp-nodejs/npm/win32-x64-msvc/package.json index b3c0cb0..5c4634f 100644 --- a/jinja-lsp-nodejs/npm/win32-x64-msvc/package.json +++ b/jinja-lsp-nodejs/npm/win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions-win32-x64-msvc", - "version": "0.0.7", + "version": "0.0.8", "os": [ "win32" ], diff --git a/jinja-lsp-nodejs/package-lock.json b/jinja-lsp-nodejs/package-lock.json index 0bb4bc0..be3a3d0 100644 --- a/jinja-lsp-nodejs/package-lock.json +++ b/jinja-lsp-nodejs/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jinja-lsp/functions", - "version": "0.0.7", + "version": "0.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jinja-lsp/functions", - "version": "0.0.7", + "version": "0.0.8", "license": "MIT", "devDependencies": { "@napi-rs/cli": "^2.18.3", diff --git a/jinja-lsp-nodejs/package.json b/jinja-lsp-nodejs/package.json index cb90f29..974298f 100644 --- a/jinja-lsp-nodejs/package.json +++ b/jinja-lsp-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@jinja-lsp/functions", - "version": "0.0.7", + "version": "0.0.8", "main": "index.js", "types": "index.d.ts", "napi": { diff --git a/jinja-lsp-nodejs/src/lib.rs b/jinja-lsp-nodejs/src/lib.rs index 99b64c3..6d5151e 100644 --- a/jinja-lsp-nodejs/src/lib.rs +++ b/jinja-lsp-nodejs/src/lib.rs @@ -10,6 +10,7 @@ use jinja_lsp_queries::{ parsers::Parsers, search::{ objects::{objects_query, CompletionType, JinjaObject}, + python_identifiers::PythonIdentifier, queries::Queries, snippets_completion::snippets, Identifier, IdentifierType, @@ -59,8 +60,11 @@ pub struct NodejsLspFiles { impl NodejsLspFiles { #[napi(constructor)] pub fn new() -> Self { + let mut lsp_files2 = LspFiles::default(); + lsp_files2.parsers.update_backend("python"); + lsp_files2.queries.update_backend("python"); Self { - lsp_files: LspFiles::default(), + lsp_files: lsp_files2, counter: 0, filters: init_filter_completions(), _snippets: snippets(), @@ -102,43 +106,77 @@ impl NodejsLspFiles { filename: String, content: String, line: u32, + ext: String, ) -> Vec { let mut all_identifiers = vec![]; let params: DidOpenTextDocumentParams = DidOpenTextDocumentParams { text_document: TextDocumentItem::new( - Url::parse(&format!("file:///home/{filename}.{id}.jinja")).unwrap(), + Url::parse(&format!("file:///home/{filename}.{id}.{ext}")).unwrap(), String::new(), 0, content, ), }; self.lsp_files.did_open(params); - let objects = self - .lsp_files - .read_objects(Url::parse(&format!("file:///home/{filename}.{id}.jinja")).unwrap()); - if let Some(objects) = objects { - if let Some(global_actions) = self.action_objects.get(&filename.to_string()) { - for obj in &objects { - let action_object = ActionObject::from(obj); - for global_action in global_actions { - if global_action.compare(&action_object.fields) { - let mut start = JsPosition::from(obj.location.0); - let mut end = JsPosition::from(obj.last_field_end()); - start.line += line; - end.line += line; - let identifier = JsIdentifier { - start, - end, - name: obj.name.to_owned(), - identifier_type: JsIdentifierType::Link, - error: None, - }; - all_identifiers.push(identifier); + match ext.as_str() { + "jinja" => { + let objects = self + .lsp_files + .read_objects(Url::parse(&format!("file:///home/{filename}.{id}.{ext}")).unwrap()); + if let Some(objects) = objects { + if let Some(global_actions) = self.action_objects.get(&filename.to_string()) { + for obj in &objects { + let action_object = ActionObject::from(obj); + for global_action in global_actions { + if global_action.compare(&action_object.fields) { + let mut start = JsPosition::from(obj.location.0); + let mut end = JsPosition::from(obj.last_field_end()); + start.line += line; + end.line += line; + let identifier = JsIdentifier { + start, + end, + name: obj.name.to_owned(), + identifier_type: JsIdentifierType::Link, + error: None, + }; + all_identifiers.push(identifier); + } + } } } } } - } + "py" => { + if let Some(ids) = self + .lsp_files + .read_python_ids(Url::parse(&format!("file:///home/{filename}.{id}.{ext}")).unwrap()) + { + if let Some(global_actions) = self.action_objects.get(&filename.to_string()) { + for obj in &ids { + let action_object = ActionObject::from(obj); + for global_action in global_actions { + if global_action.compare(&action_object.fields) { + let mut start = JsPosition::from(obj.start); + let mut end = JsPosition::from(obj.end); + start.line += line; + end.line += line; + let identifier = JsIdentifier { + start, + end, + name: obj.field.to_owned(), + identifier_type: JsIdentifierType::Link, + error: None, + }; + all_identifiers.push(identifier); + } + } + } + } + } + } + _ => (), + }; // let query = &self.lsp_files.queries.jinja_objects; // let objects = objects_query(query, &tree, Point::new(0, 0), &content, true); // let objects = objects.show(); @@ -630,6 +668,19 @@ impl From<&JinjaObject> for ActionObject { } } +impl From<&PythonIdentifier> for ActionObject { + fn from(value: &PythonIdentifier) -> Self { + let mut fields = vec![]; + let parts = value.field.split('.'); + for field in parts { + fields.push(field.to_string()); + } + // fields.push(value.name.to_owned()); + // for field in &value.fields {} + Self { fields } + } +} + impl ActionObject { pub fn compare(&self, fields: &Vec) -> bool { &self.fields == fields diff --git a/jinja-lsp-queries/src/search/mod.rs b/jinja-lsp-queries/src/search/mod.rs index 2137d7e..5da5da2 100644 --- a/jinja-lsp-queries/src/search/mod.rs +++ b/jinja-lsp-queries/src/search/mod.rs @@ -5,7 +5,7 @@ use self::objects::JinjaObject; pub mod definition; pub mod objects; -mod python_identifiers; +pub mod python_identifiers; pub mod queries; pub mod rust_identifiers; pub mod rust_template_completion; diff --git a/jinja-lsp-queries/src/search/python_identifiers.rs b/jinja-lsp-queries/src/search/python_identifiers.rs index 0e61728..a0f5da6 100644 --- a/jinja-lsp-queries/src/search/python_identifiers.rs +++ b/jinja-lsp-queries/src/search/python_identifiers.rs @@ -1,24 +1,80 @@ +use std::collections::HashMap; + use tree_sitter::{Point, Query, QueryCursor, Tree}; -pub fn _python_identifiers( +pub struct PythonAttributes { + pub attributes: HashMap>, +} + +impl PythonAttributes { + pub fn merge(&self, line: u32) -> Vec { + let mut identifiers = vec![]; + for i in &self.attributes { + let mut start = i.0.to_owned(); + start.row += line as usize; + let mut end = i.0; + let mut name = String::new(); + let len = i.1.len(); + for (index, identifier) in i.1.iter().enumerate() { + name.push_str(&identifier.field); + end = &identifier.end; + if index != len - 1 { + name.push('.'); + } + } + let mut end = end.to_owned(); + end.row += line as usize; + let identifier = PythonIdentifier { + id: 0, + start, + end, + field: name, + }; + identifiers.push(identifier); + } + identifiers + } +} + +#[derive(Default, Debug, Clone, PartialEq, PartialOrd, Ord, Eq)] +pub struct PythonIdentifier { + pub id: usize, + pub start: Point, + pub end: Point, + pub field: String, +} + +pub fn python_identifiers( query: &Query, tree: &Tree, mut _trigger_point: Point, text: &str, - all: bool, -) { + line: u32, +) -> Vec { let closest_node = tree.root_node(); let mut cursor_qry = QueryCursor::new(); let _capture_names = query.capture_names(); + let mut attributes = PythonAttributes { + attributes: HashMap::new(), + }; let matches = cursor_qry.matches(query, closest_node, text.as_bytes()); - let captures = matches.into_iter().flat_map(|m| { - m.captures - .iter() - .filter(|capture| all || capture.node.start_position() <= _trigger_point) - }); - for _capture in captures { - // if check.is_none() { - // break; - // } + for i in matches { + for capture in i.captures { + if let Some(parent) = capture.node.parent() { + let attribute = attributes + .attributes + .entry(parent.start_position()) + .or_default(); + let field = capture.node.utf8_text(text.as_bytes()).unwrap_or_default(); + let identifier = PythonIdentifier { + id: capture.node.id(), + start: capture.node.start_position(), + end: capture.node.end_position(), + field: field.to_string(), + }; + attribute.push(identifier); + } + } } + attributes.merge(line) } diff --git a/jinja-lsp-queries/src/search/queries.rs b/jinja-lsp-queries/src/search/queries.rs index 10670b1..0687397 100644 --- a/jinja-lsp-queries/src/search/queries.rs +++ b/jinja-lsp-queries/src/search/queries.rs @@ -279,11 +279,9 @@ pub static PYTHON_DEFINITIONS: &str = r#" "#; const PYTHON_IDENTIFIERS: &str = r#" -(_ +(attribute (identifier) @identifier ) -(attribute) @attribute - (ERROR) @error "#; diff --git a/jinja-lsp-queries/src/search/test_queries.rs b/jinja-lsp-queries/src/search/test_queries.rs index c475de8..4e1457c 100644 --- a/jinja-lsp-queries/src/search/test_queries.rs +++ b/jinja-lsp-queries/src/search/test_queries.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod query_tests { use crate::search::{ - objects::objects_query, python_identifiers::_python_identifiers, + objects::objects_query, python_identifiers::python_identifiers, snippets_completion::snippets_query, to_range, }; use tree_sitter::{Parser, Point}; @@ -392,14 +392,15 @@ mod query_tests { fn test_python_identifiers() { let cases = [r#" [page.text - for page in retrieval.result.abc] + for page in retrieval.result.other.field] "#]; let query = Queries::default(); let query = query.python_identifiers; for _case in cases { let tree = prepare_python_tree(cases[0]); - _python_identifiers(&query, &tree, Point::new(0, 0), cases[0], true); + let ids = python_identifiers(&query, &tree, Point::new(0, 0), cases[0], 0); + assert_eq!(ids.len(), 2); } } } diff --git a/jinja-lsp/src/lsp_files.rs b/jinja-lsp/src/lsp_files.rs index 52c8cfd..f023232 100644 --- a/jinja-lsp/src/lsp_files.rs +++ b/jinja-lsp/src/lsp_files.rs @@ -4,6 +4,7 @@ use jinja_lsp_queries::{ completion_start, definition::definition_query, objects::{objects_query, JinjaObject}, + python_identifiers::{python_identifiers, PythonIdentifier}, queries::Queries, rust_identifiers::backend_definition_query, rust_template_completion::backend_templates_query, @@ -728,6 +729,23 @@ impl LspFiles { Some(objects) } + pub fn read_python_ids(&self, uri: Url) -> Option> { + let rope = self.documents.get(uri.as_str())?; + let mut writter = FileContent::default(); + let _ = rope.write_to(&mut writter); + let content = writter.content; + let lang_type = self.config.file_ext(&Path::new(uri.as_str()))?; + let trees = self.trees.get(&lang_type)?; + let tree = trees.get(uri.as_str())?; + Some(python_identifiers( + &self.queries.python_identifiers, + tree, + Point::new(0, 0), + &content, + 0, + )) + } + pub fn data_type(&self, uri: Url, hover: Identifier) -> Option { let this_file = self.variables.get(uri.as_str())?; let this_file = this_file