Skip to content

Commit 65c7190

Browse files
Merge pull request #280 from joaomsa/configurable-tags-column
Allow configurable org tags column
2 parents c26378c + 48c41e3 commit 65c7190

File tree

5 files changed

+85
-27
lines changed

5 files changed

+85
-27
lines changed

DOCS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,15 @@ Example value: `{'agenda-archives'}`
368368

369369
### Tags settings
370370

371+
#### **org_tags_column**
372+
*type*: `number`
373+
*default value*: `80`
374+
The column to which tags should be indented in a headline.
375+
If this number is positive, it specifies the column.
376+
If it is negative, it means that the tags should be flushright to that column.
377+
For example, -80 works well for a normal 80 character screen.
378+
When 0, place tags directly after headline text, with only one space in between.
379+
371380
#### **org_use_tag_inheritance**
372381
*type*: `boolean`
373382
*default value*: `true`

doc/orgmode.txt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ CONTENTS *orgmode-content
4141
1.2.2.11. org_agenda_skip_deadline_if_done.|orgmode-org_agenda_skip_deadline_if_done|
4242
1.2.2.12. org_agenda_text_search_extra_files.|orgmode-org_agenda_text_search_extra_files|
4343
1.2.3. Tags settings...............................|orgmode-tags_settings|
44-
1.2.3.1. org_use_tag_inheritance.....|orgmode-org_use_tag_inheritance|
45-
1.2.3.2. org_tags_exclude_from_inheritance.|orgmode-org_tags_exclude_from_inheritance|
44+
1.2.3.1. org_tags_column.....................|orgmode-org_tags_column|
45+
1.2.3.2. org_use_tag_inheritance.....|orgmode-org_use_tag_inheritance|
46+
1.2.3.3. org_tags_exclude_from_inheritance.|orgmode-org_tags_exclude_from_inheritance|
4647
1.3. Mappings...............................................|orgmode-mappings|
4748
1.3.1. Global mappings...........................|orgmode-global_mappings|
4849
1.3.1.1. org_agenda...............................|orgmode-org_agenda|
@@ -566,6 +567,16 @@ Example value: `{'agenda-archives'}`
566567

567568
TAGS SETTINGS *orgmode-tags_settings*
568569

570+
ORG_TAGS_COLUMN *orgmode-org_tags_column*
571+
572+
type: `number`
573+
default value: `80`
574+
The column to which tags should be indented in a headline.
575+
If this number is positive, it specifies the column.
576+
If it is negative, it means that the tags should be flushright to that column.
577+
For example, -80 works well for a normal 80 character screen.
578+
When 0, place tags directly after headline text, with only one space in between.
579+
569580
ORG_USE_TAG_INHERITANCE *orgmode-org_use_tag_inheritance*
570581

571582
type: `boolean`

lua/orgmode/config/defaults.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ return {
2121
org_priority_default = 'B',
2222
org_priority_lowest = 'C',
2323
org_archive_location = '%s_archive::',
24+
org_tags_column = 80,
2425
org_use_tag_inheritance = true,
2526
org_tags_exclude_from_inheritance = {},
2627
org_hide_leading_stars = false,

lua/orgmode/org/mappings.lua

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,28 @@ function OrgMappings:archive()
6666
end
6767

6868
function OrgMappings:set_tags()
69-
local headline = Files.get_closest_headline()
70-
local own_tags = headline:get_own_tags()
71-
local tags = vim.fn.OrgmodeInput('Tags: ', utils.tags_to_string(own_tags), Files.autocomplete_tags)
72-
return self:_set_headline_tags(headline, tags)
69+
local headline = Headline:new(tree_utils.closest_headline())
70+
local _, current_tags = headline:tags()
71+
72+
local tags = vim.fn.OrgmodeInput('Tags: ', current_tags, Files.autocomplete_tags)
73+
74+
return headline:set_tags(tags)
7375
end
7476

7577
function OrgMappings:toggle_archive_tag()
76-
local headline = Files.get_closest_headline()
77-
local own_tags = headline:get_own_tags()
78-
if vim.tbl_contains(own_tags, 'ARCHIVE') then
79-
own_tags = vim.tbl_filter(function(tag)
78+
local headline = Headline:new(tree_utils.closest_headline())
79+
local _, current_tags = headline:tags()
80+
81+
local parsed = utils.parse_tags_string(current_tags)
82+
if vim.tbl_contains(parsed, 'ARCHIVE') then
83+
parsed = vim.tbl_filter(function(tag)
8084
return tag ~= 'ARCHIVE'
81-
end, own_tags)
85+
end, parsed)
8286
else
83-
table.insert(own_tags, 'ARCHIVE')
87+
table.insert(parsed, 'ARCHIVE')
8488
end
85-
return self:_set_headline_tags(headline, utils.tags_to_string(own_tags))
89+
90+
return headline:set_tags(utils.tags_to_string(parsed))
8691
end
8792

8893
function OrgMappings:cycle()
@@ -852,19 +857,6 @@ function OrgMappings:_adjust_date(amount, span, fallback)
852857
return vim.api.nvim_feedkeys(utils.esc(fallback), 'n', true)
853858
end
854859

855-
function OrgMappings:_set_headline_tags(headline, tags_string)
856-
local tags = tags_string:gsub('^:+', ''):gsub(':+$', ''):gsub(':+', ':')
857-
if tags ~= '' then
858-
tags = ':' .. tags .. ':'
859-
end
860-
local line_without_tags = headline.line
861-
:gsub(vim.pesc(utils.tags_to_string(headline:get_own_tags())) .. '%s*$', '')
862-
:gsub('%s*$', '')
863-
local spaces = 80 - math.min(vim.api.nvim_strwidth(line_without_tags), 79)
864-
local new_line = string.format('%s%s%s', line_without_tags, string.rep(' ', spaces), tags):gsub('%s*$', '')
865-
return vim.fn.setline(headline.range.start_line, new_line)
866-
end
867-
868860
---@return string|nil
869861
function OrgMappings:_get_link_under_cursor()
870862
local found_link = nil

lua/orgmode/treesitter/headline.lua

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,51 @@ function Headline:priority()
2828
return self:parse('%[#(%w+)%]')
2929
end
3030

31+
function Headline:tags()
32+
local node = self.headline:field('tags')[1]
33+
local text = ''
34+
if node then
35+
text = query.get_node_text(node, 0)
36+
end
37+
return node, text
38+
end
39+
40+
function Headline:set_tags(tags)
41+
local predecessor = nil
42+
for _, node in ipairs(ts_utils.get_named_children(self.headline)) do
43+
if node:type() ~= 'tag_list' then
44+
predecessor = node
45+
end
46+
end
47+
48+
local pred_end_row, pred_end_col, _ = predecessor:end_()
49+
local end_col = vim.api.nvim_strwidth(vim.fn.getline(pred_end_row + 1))
50+
51+
local text = ''
52+
tags = vim.trim(tags):gsub('^:', ''):gsub(':$', '')
53+
if tags ~= '' then
54+
tags = ':' .. tags .. ':'
55+
56+
local to_col = config.org_tags_column
57+
if to_col < 0 then
58+
local tags_width = vim.api.nvim_strwidth(tags)
59+
to_col = math.abs(to_col) - tags_width
60+
end
61+
62+
local spaces = math.max(to_col - pred_end_col, 1)
63+
text = string.rep(' ', spaces) .. tags
64+
end
65+
66+
vim.api.nvim_buf_set_text(0, pred_end_row, pred_end_col, pred_end_row, end_col, { text })
67+
end
68+
69+
function Headline:align_tags()
70+
local current_tags, current_text = self:tags()
71+
if current_tags then
72+
self:set_tags(current_text)
73+
end
74+
end
75+
3176
function Headline:set_priority(priority)
3277
local current_priority = self:priority()
3378
if current_priority then
@@ -96,7 +141,7 @@ function Headline:dates()
96141
end
97142

98143
for _, node in ipairs(ts_utils.get_named_children(plan)) do
99-
local name = vim.treesitter.query.get_node_text(node:named_child(0), 0)
144+
local name = query.get_node_text(node:named_child(0), 0)
100145
dates[name] = node
101146
end
102147
return dates

0 commit comments

Comments
 (0)