Skip to content

Commit 2b2f327

Browse files
fix(set_tags): better tag parsing for hyphens and whitespaces (#1098)
* fix: better tag parsing for hyphens and whitespaces 1. hyphens are replaced with underscores 2. whitespaces are treated as separators between multiple tags * lint: format file with stylua * test: edge cases for tag input * fix: hyphens should be replaced with colons
1 parent 72c6d0c commit 2b2f327

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

lua/orgmode/files/headline.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,12 @@ function Headline:set_tags(tags)
270270
local end_col = line:len()
271271

272272
local text = ''
273-
tags = vim.trim(tags):gsub('^:', ''):gsub(':$', '')
273+
tags = vim
274+
.trim(tags)
275+
:gsub('[%s:-]+', ':') -- Convert all whitespace, existing colons and hyphens into a single colon
276+
:gsub('^:', '')
277+
:gsub(':$', '')
278+
274279
if tags ~= '' then
275280
tags = ':' .. tags .. ':'
276281

tests/plenary/api/api_spec.lua

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,27 @@ describe('Api', function()
103103
assert.are.same('Second level', current_file.headlines[2].title)
104104
assert.are.same({ 'WORK', 'OFFICE', 'NESTEDTAG' }, current_file.headlines[2].all_tags)
105105

106-
current_file.headlines[2]:set_tags({ 'PERSONAL', 'HEALTH' }):wait()
106+
current_file.headlines[2]:set_tags({ 'PERSONAL', 'HEALTH', 'TAG1 TAG2', 'TAG3-TAG4-TAG5' }):wait()
107+
108+
assert.are.same({ 'PERSONAL', 'HEALTH', 'TAG1', 'TAG2', 'TAG3', 'TAG4', 'TAG5' }, cur_file().headlines[2].tags)
109+
assert.are.same(
110+
{ 'WORK', 'OFFICE', 'PERSONAL', 'HEALTH', 'TAG1', 'TAG2', 'TAG3', 'TAG4', 'TAG5' },
111+
cur_file().headlines[2].all_tags
112+
)
113+
assert.is.True(vim.fn.getline(5):match(':PERSONAL:HEALTH:TAG1:TAG2:TAG3:TAG4:TAG5:$') ~= nil)
114+
end)
115+
116+
it('should handle edge cases in tag input', function()
117+
helpers.create_file({ '* TODO Test orgmode tags :TAG1:' })
118+
119+
assert.is.True(#api.load() > 1)
120+
local current_file = cur_file()
121+
assert.are.same({ 'TAG1' }, current_file.headlines[1].all_tags)
122+
123+
current_file.headlines[1]:set_tags({ ': -tag1- : tag2:::tag3 tag_4 : @tag5 :' }):wait()
107124

108-
assert.are.same({ 'PERSONAL', 'HEALTH' }, cur_file().headlines[2].tags)
109-
assert.are.same({ 'WORK', 'OFFICE', 'PERSONAL', 'HEALTH' }, cur_file().headlines[2].all_tags)
110-
assert.is.True(vim.fn.getline(5):match(':PERSONAL:HEALTH:$') ~= nil)
125+
assert.are.same({ 'tag1', 'tag2', 'tag3', 'tag_4', '@tag5' }, cur_file().headlines[1].all_tags)
126+
assert.is.True(vim.fn.getline(1):match(':tag1:tag2:tag3:tag_4:@tag5:') ~= nil)
111127
end)
112128

113129
it('should cycle upwards through priorities, starting with default', function()

0 commit comments

Comments
 (0)