krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Commit 78d3547c3b

78d3547c3b4bcce571ecbc11310c02080c530d57

parent: dac348a0b8

Verified · cmc

cmc <hello@cleberg.net> · 2026-10-08 03:50 UTC

Property keys with colons, as org-property-re reads them

A drawer line :header-args:sh: :results verbatim has the key
header-args:sh; it was read as header-args with the value
"sh: :results verbatim", so it applied to every language.

Layout: unified · split

Sources/OrgCore/Semantic/HeadingInfo.swift +4 −1
@@ -17,7 +17,10 @@ public struct Property: Sendable, Equatable {
17 let trimmed = line.trimmingCharacters(in: .whitespacesAndNewlines) 17 let trimmed = line.trimmingCharacters(in: .whitespacesAndNewlines)
18 guard trimmed.hasPrefix(":") else { return nil } 18 guard trimmed.hasPrefix(":") else { return nil }
19 let rest = trimmed.dropFirst() 19 let rest = trimmed.dropFirst()
20 guard let colon = rest.firstIndex(of: ":") else { return nil } 20 // `org-property-re`: the key ends at the first colon followed by a blank or the end,
21 // so `:header-args:sh:` is one key.
22 guard let colon = rest.indices.first(where: { rest[$0] == ":" && (rest.index(after: $0) == rest.endIndex || rest[rest.index(after: $0)].isWhitespace) })
23 else { return nil }
21 var key = rest[..<colon] 24 var key = rest[..<colon]
22 guard !key.isEmpty else { return nil } 25 guard !key.isEmpty else { return nil }
23 let additive = key.hasSuffix("+") 26 let additive = key.hasSuffix("+")
Tests/OrgCoreTests/BabelTests.swift +1
@@ -143,6 +143,7 @@ struct BabelTests {
143 "#+begin_src emacs-lisp :var x=4\n(* x x)\n#+end_src\n", 143 "#+begin_src emacs-lisp :var x=4\n(* x x)\n#+end_src\n",
144 "#+PROPERTY: header-args :results output\n#+begin_src sh\nprintf 'a b\\nc d\\n'\n#+end_src\n", 144 "#+PROPERTY: header-args :results output\n#+begin_src sh\nprintf 'a b\\nc d\\n'\n#+end_src\n",
145 "* Heading\n:PROPERTIES:\n:header-args:sh: :results verbatim\n:END:\n#+begin_src sh\necho 1 2\n#+end_src\n", 145 "* Heading\n:PROPERTIES:\n:header-args:sh: :results verbatim\n:END:\n#+begin_src sh\necho 1 2\n#+end_src\n",
146 "* Heading\n:PROPERTIES:\n:header-args:sh: :results verbatim\n:END:\n#+begin_src python\nreturn [[1, 2]]\n#+end_src\n",
146 "#+HEADER: :results output\n#+begin_src sh\nprintf 'x y\\nz w\\n'\n#+end_src\n", 147 "#+HEADER: :results output\n#+begin_src sh\nprintf 'x y\\nz w\\n'\n#+end_src\n",
147 // `:cmdline`, `:stdin` and `:shebang`. 148 // `:cmdline`, `:stdin` and `:shebang`.
148 "#+begin_src sh :cmdline one \"two words\" :results output\nfor a in \"$@\"; do echo \"[$a]\"; done\n#+end_src\n", 149 "#+begin_src sh :cmdline one \"two words\" :results output\nfor a in \"$@\"; do echo \"[$a]\"; done\n#+end_src\n",