Nick
Nick

Reputation: 9051

How to make "todo" in markdown in sublime text?

I am migrating to sublime text with markdownediting from emacs orgmode. With the help of markdownediting, sublime is fine with markdown. But I haven't figure out how to make TODO list, and toggle between TODO and DONE. Is there a way to do it? or any plugin works well with markdownediting?

Upvotes: 3

Views: 5864

Answers (1)

Nick
Nick

Reputation: 9051

I installed the mdTodo plugin for Sublime text.

It works but the TODO list displayed as bulletin list (in html) on GitHub, which looks not so good.

I found that GitHub supports the orgmode-style TODO list:

https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments

https://github.com/blog/1825-task-lists-in-all-markdown-documents

Solar System Exploration, 1950s – 1960s

  • [ ] Mercury
  • [x] Venus
  • [x] Earth (Orbit/Moon)
  • [x] Mars
  • [ ] Jupiter
  • [ ] Saturn
  • [ ] Uranus
  • [ ] Neptune
  • [ ] Comet Haley

enter image description here

So I modified the mdTodo source code, makes it works on orgmode-style TODO list.

Here is my modification: (mdTodo.py in the package folder)

import sublime, sublime_plugin
from datetime import datetime 

class ItodoBase(sublime_plugin.TextCommand):
  def run(self, edit):
    filename = self.view.file_name()
    # list of allowed filetypes
    allowed_filetypes = ('.md', '.markdown', '.mdown')
    if filename is None or not filename.endswith(allowed_filetypes):
      return False  
    self.runCommand(edit)

class NewCommand(ItodoBase):
  def runCommand(self, edit):
    for region in self.view.sel():
      lines = self.view.lines(region)
      lines.reverse()
      for line in lines:
        # don't add a newline when creating new item with cursor is at an empty line
        if not line:
          line_contents = '-'
          self.view.insert(edit, line.begin(), line_contents)
        # add a newline when creating new item when cursor is at another line
        else:
          line_contents = self.view.substr(line) + '\n-'
          self.view.replace(edit, line, line_contents)

class CompleteCommand(ItodoBase):
  def runCommand(self, edit):    
    for region in self.view.sel():
      lines = self.view.lines(region)
      lines.reverse()
      for line in lines:
        line_head = self.view.find("- \[[x ]\]", line.begin())
        line_contents = self.view.substr(line).strip()
        # prepend @done if item is ongoing
        if line_contents.startswith("- [ ]"):
          self.view.insert(edit, line.end(), " @done (%s)" % datetime.now().strftime("%Y-%m-%d %H:%M"))
          self.view.replace(edit, line_head, "- [x]")
        # undo @todo
        elif line_contents.startswith('- [x]'):
          subfix = self.view.find('(\s)*@done(.)+\)$', line.begin())
          self.view.erase(edit, subfix)
          self.view.replace(edit, line_head, "- [ ]")

I hope this would be helpful to those migrated to Sublime text from Emacs (org-mode).

Update

The default shortcut ctrl+shift+d conflicts with the default duplicate line command.

Solution:

path_to_sublime\Sublime Text 3\Packages\mdTodo\Default (Windows).sublime-keymap

Comment out this line

[   // iTodo plugin
     { "keys": ["ctrl+shift+d"], "command": "complete" }
]

and change it in the user keybinds file.

I binded it to:

     { "keys": ["ctrl+alt+d"], "command": "complete" }

Upvotes: 3

Related Questions