Commit d453602987
Verified · cmc
Layout: unified · split
Sources/OrgCore/Compute/Babel.swift +22
| @@ -138,6 +138,9 @@ public enum Babel { | ||
| 138 | 138 | if let call = try callAt(context.caret, model: model, text: ns) { |
| 139 | 139 | return located(plan(call.block, params: call.params, model: model, text: ns, options: options, location: call.location, name: call.name, refs: refs)) |
| 140 | 140 | } |
| 141 | if let call = try inlineCallAt(context.caret, tree: context.tree, model: model, text: ns) { | |
| 142 | return located(plan(call.block, params: call.params, model: model, text: ns, options: options, location: call.location, name: nil, inline: true, refs: refs)) | |
| 143 | } | |
| 141 | 144 | if let inline = try inlineAt(context.caret, tree: context.tree, model: model, text: ns) { |
| 142 | 145 | return located(plan(inline.block, params: inline.params, model: model, text: ns, options: options, location: inline.block.range, name: nil, inline: true, refs: refs)) |
| 143 | 146 | } |
| @@ -171,6 +174,25 @@ public enum Babel { | ||
| 171 | 174 | return (block, try Params(block: block, model: model, text: text, extra: extra), location, callName) |
| 172 | 175 | } |
| 173 | 176 | |
| 177 | /// The inline `call_NAME[INSIDE](ARGS)[END]` at `offset`: like `#+CALL`, with the result | |
| 178 | /// after the call. | |
| 179 | static func inlineCallAt(_ offset: Int, tree: OrgTree, model: DocumentModel, text: NSString) throws -> (block: SrcBlockInfo, params: Params, location: Range<Int>)? { | |
| 180 | var node = tree.root | |
| 181 | var found: SyntaxNode? | |
| 182 | while let child = node.child(containing: offset) { | |
| 183 | if child.kind == .inlineBabelCall { found = child } | |
| 184 | node = child | |
| 185 | } | |
| 186 | guard let object = found, let m = object.text.firstMatch(of: /^call_([^()\[\]\s]+)(?:\[([^\]]*)\])?\((.*?)\)(?:\[([^\]]*)\])?$/) else { return nil } | |
| 187 | let name = String(m.1) | |
| 188 | guard let block = model.srcBlocks.first(where: { $0.name == name }) else { throw Failure.message("Reference '\(name)' not found in this buffer") } | |
| 189 | var extra: [[(String, String)]] = [] | |
| 190 | if let inside = m.2 { extra.append(Params.parse(String(inside))) } | |
| 191 | extra.append(splitArguments(String(m.3)).map { (":var", $0) }) | |
| 192 | if let end = m.4 { extra.append(Params.parse(String(end))) } | |
| 193 | return (block, try Params(block: block, model: model, text: text, extra: extra), object.range) | |
| 194 | } | |
| 195 | ||
| 174 | 196 | /// Call arguments split on commas outside quotes and parentheses. |
| 175 | 197 | static func splitArguments(_ s: String) -> [String] { |
| 176 | 198 | var parts: [String] = [] |
Tests/OrgCoreTests/BabelTests.swift +6
| @@ -196,6 +196,12 @@ struct BabelCallTests { | ||
| 196 | 196 | ("Text src_sh[:results raw]{echo raw} end.\n", "src_sh"), |
| 197 | 197 | ("Text src_python{return 6*7} end.\n", "src_python"), |
| 198 | 198 | ("Text src_sh[:var x=3]{echo $x} end.\n", "src_sh"), |
| 199 | (named + "Inline call_double(n=6) here.\n", "call_"), | |
| 200 | (named + "Inline call_double() here.\n", "call_"), | |
| 201 | (named + "Inline call_double(n=6)[:results raw] here.\n", "call_"), | |
| 202 | (named + "Inline call_double[:results verbatim](n=1) here.\n", "call_"), | |
| 203 | (named + "Inline call_double(n=2) {{{results(=0=)}}} here.\n", "call_"), | |
| 204 | (named + "Inline call_double(n=2) and call_double(n=3) here.\n", "call_double(n=3"), | |
| 199 | 205 | ] |
| 200 | 206 | |
| 201 | 207 | @Test(.enabled(if: ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil)) |