Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PlainTasks.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ contexts:
- match: (?<=\s)\@low|✭low
scope: string.other.tag.todo.low
tag:
- match: '(?<=\s)\@(?!(high|today|critical|low|completed|done)[\s\(])[\w\d\.\(\)\-!? :\+]+[ \t]*'
- match: '(?<=\s)\@(?!(?:high|today|critical|low|completed|done)[\s\(])\w+(\((?>[^()]|\g<1>)*+\))*+'
scope: meta.tag.todo
today:
- match: (?<=\s)\@today|✭ᴛᴏᴅᴀʏ
Expand Down
2 changes: 1 addition & 1 deletion PlainTasks.tmLanguage
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@
<key>tag</key>
<dict>
<key>match</key>
<string>(?&lt;=\s)\@(?!(high|today|critical|low|completed|done)[\s\(])[\w\d\.\(\)\-!? :\+]+[ \t]*</string>
<string>(?&lt;=\s)\@(?!(?:high|today|critical|low|completed|done)[\s\(])\w+(\((?&gt;[^()]|\g&lt;1&gt;)*+\))*+</string>
<key>name</key>
<string>meta.tag.todo</string>
</dict>
Expand Down
28 changes: 14 additions & 14 deletions PlainTasksDates.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def run(self, edit):
if not highlight_on:
return

pattern = r'@due(\([^@\n]*\))'
pattern = r'@due(\((?>[^()]|(?1))*+\))'
dates_strings = []
dates_regions = self.view.find_all(pattern, 0, '\\1', dates_strings)
if not dates_regions:
Expand Down Expand Up @@ -548,19 +548,19 @@ def extract_tag(self, point):
tag under cursor (i.e. point)
'''
start = end = point
tag_pattern = r'(?<=\s)(\@[^\(\) ,\.]+)([\w\d\.\(\)\-!? :\+]*)'
line = self.view.line(point)
matches = re.finditer(tag_pattern, self.view.substr(line))
for match in matches:
m_start = line.a + match.start(1)
m_end = line.a + match.end(2)
if m_start <= point <= m_end:
start = line.a + match.start(2)
end = m_end
break
else:
match = None
tag = match.group(0) if match else ''
tag = ''
if 'tag.todo' in self.view.scope_name(point):
reg = self.view.extract_scope(point)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not reliable enough, e.g. there is option to show date preview for due tag within paranthesis "due_preview_offset": 1, as I mentioned in prev pr phantom will change result of extract_scope.
We also should always expect that view may be affected by other plugins so even if user has default "due_preview_offset": 0, still there might be other phantoms.

I think we could try to use view.find method, i.e. check if cursor is on tag then search @ which is related to this tag (it will be either somewhere on left side of cursor or it might be exactly on right side of cursor), then the point of @ is a starting position for view.find which allow to use the regex from syntax, i.e. with atomic group etc. Right?

Copy link
Author

@oliverwilliams84 oliverwilliams84 May 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole thing is a workaround to get it working with the re module.
Phantoms only appear after @Due tags, right? That can be worked around with a one time hack if thats so.

Using view.find will work as long as no phantoms throw off the regex. The key feature missing is the regex recursion that makes it all super easy. Probably a much better solution

A more permanent solution is to remove all phantoms at the beginng of the function and put them back at the end which I think is what the other function does? Means the issue should never resurge. Having a single function to reapply the phantoms or just store them and redraw.


Having "due_preview_offset": 1 means that date is inside the brackets while also next to your current text. This works great for @due(+2) but less good for any with short dates as you end up with both dates in the bracket, (formatting is fixed in another branch to properly encode the date in dd/mm/yy if that setting is picked)

Does the setting need to effect every date? Does look strange with two dates in the brackets but that's why it's a setting.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this @\w+((\((?=([^()]*))\3|[()]*\))*) — it works with re module and seems suitable?
It behaves as your alternative version, which seems alright to me since the last pair of parenthesis is not separated from the tag, there is no whitespace so we can consider it is a part of tag.
What your thoughts are?

Phantoms only appear after @due tags, right?

No, phantoms may appear anywhere, because any plugin can add any phantoms to any views; and it is not possible to fully access existing phantoms.

Using view.find will work as long as no phantoms throw off the regex

Phantoms do not affect search in any way, afaik, only scopes boundaries.

less good for any with short dates as you end up with both dates in the bracket,

The preview is supposed to be displayed only if the existing text will be replaced after pressing tab. I would imagine it has problems due to date format and improper use of dateutil.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll be taking a break for the exam period but I'll finish up a few improvements when I get time. I've got a in-dev copy that works for just the settings I want but I'll need to polish it so it works for the master release

text = self.view.substr(reg)
match = re.search(r'(\@\w*)(\(.*\)|)', text)
start, end = reg.b, reg.b
if match:
if len(match.group(2)) > 0:
start = reg.a + match.start(2)
end = reg.a + match.end(2)

tag = match.group(1)

return sublime.Region(start, end), tag

def generate_calendar(self, date=None):
Expand Down