Anonymous avatar Anonymous committed 4b213c8

Initial import.

Comments (0)

Files changed (6)

+.pyc$
+.cache$
+The MIT License
+
+Copyright (c) 2011 Oktay Acikalin <ok@ryotic.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+orgmode for Sublime Text 2
+==========================
+
+* About
+
+  My shot on bringing Org-Mode {3} to Sublime Text 2 {4}. This project is still in very early development. Nobody knows what will come next :). This won't be a simple copycat of the original one. I want to "port" useful things in a way that works best for Sublime Text 2. So there may be things that aren't in either version or just behave more or less differently.
+
+* Features
+
+  Here's a list of all the features implemented so far:
+
+  - Context sensitive highlighting
+    - Headlines
+    - Pages
+    - Breaks
+    - tacks
+    - Checkboxes
+    - Checkbox summaries
+    - External links
+  - Context sensitive actions
+    - Toggle checkbox on pressing enter
+    - Auto update of checkbox summary on toggle of checkboxes
+    - External link opener on pressing enter
+      (currently only working on OSX)
+
+* Todo [0/5]
+
+  - [ ] External link opener on pressing enter [1/3]
+    - [X] on OSX
+    - [ ] on Linux
+    - [ ] on Windows
+  - [ ] Recalc number of children in checkbox summary on pressing enter.
+  - [ ] When (un-)checking *all* checkboxes of siblings, toggle parent checkbox.
+  - [ ] Either make highlight_code_remarks.py configurable thru view settings so that orgmode can control its regex patterns or fork/extend it to archive an equal goal.
+  - [ ] Inter-document links
+    - [ ] Highlighting
+    - [ ] Jump between similar numbers on pressing enter
+
+* Known Issues
+
+  - When creating an empty checkbox summary and hitting an checkbox below the cursor will be placed a little bit to the left. Seems like the selection is being rebuilt incorrectly due to the added chars for the summary.
+  - Subsequent indent of wrapped paragraphs don't respect stars, tacks and checkboxes.
+  
+* External links
+
+  {1} Homepage [[https://bitbucket.org/theblacklion/sublime_orgmode/]]
+  {2} Issue tracker [[https://bitbucket.org/theblacklion/sublime_orgmode/issues?status=new&status=open]]
+  {3} Sublime Text 2 [[http://www.sublimetext.com/2]]
+  {4} Org-Mode for Emacs [[http://orgmode.org/]]
+import os
+import subprocess
+import re
+
+import sublime
+import sublime_plugin
+
+
+OPEN_LINK_COMMAND = ['open']
+
+
+class OrgmodeOpenLink(sublime_plugin.TextCommand):
+    '''
+    @todo: If the link is a local org-file open it via sublime, otherwise use OPEN_LINK_COMMAND.
+    @todo: Implement mechanisms for Linux and Windows.
+    '''
+
+    def run(self, edit):
+        view = self.view
+        for sel in view.sel():
+            if 'link.orgmode' not in view.scope_name(sel.end()):
+                continue
+            region = view.extract_scope(sel.end())
+            content = view.substr(region)
+            if content.startswith('[[') and content.endswith(']]'):
+                content = content[2:-2]
+            content = os.path.expandvars(content)
+            content = os.path.expanduser(content)
+            cmd = OPEN_LINK_COMMAND + [content]
+            process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            stdout, stderr = process.communicate()
+            if stdout:
+                sublime.status_message(stdout)
+            if stderr:
+                sublime.error_message(stderr)
+
+class OrgmodeToggleCheckbox(sublime_plugin.TextCommand):
+
+    def __init__(self, *args, **kwargs):
+        super(OrgmodeToggleCheckbox, self).__init__(*args, **kwargs)
+        indent_pattern = r'^(\s*).*$'
+        summary_pattern = r'(\[\d*[/]\d*\])'
+        self.indent_regex = re.compile(indent_pattern)
+        self.summary_regex = re.compile(summary_pattern)
+
+    def get_indent(self, content):
+        if type(content) is sublime.Region:
+            content = self.view.substr(content)
+        match = self.indent_regex.match(content)
+        indent = match.group(1)
+        return indent
+
+    def find_parent(self, region):
+        view = self.view
+        row, col = view.rowcol(region.begin())
+        line = view.line(region)
+        content = view.substr(line)
+        # print content
+        indent = self.get_indent(content)
+        # print repr(indent)
+        row -= 1
+        found = False
+        while row >= 0:
+            point = view.text_point(row, 0)
+            line = view.line(point)
+            content = view.substr(line)
+            if len(content.strip()):
+                cur_indent = self.get_indent(content)
+                if len(cur_indent) < len(indent):
+                    found = True
+                    break
+            row -= 1
+        if found:
+            # print row
+            point = view.text_point(row, 0)
+            line = view.line(point)
+            return line
+
+    def find_siblings(self, child, parent):
+        view = self.view
+        row, col = view.rowcol(parent.begin())
+        parent_indent = self.get_indent(parent)
+        child_indent = self.get_indent(child)
+        # print '***', repr(parent_indent), repr(child_indent)
+        siblings = []
+        row += 1
+        last_row, _ = view.rowcol(view.size())
+        while row <= last_row:  # Don't go past end of document.
+            line = view.text_point(row, 0)
+            line = view.line(line)
+            content = view.substr(line)
+            # print content
+            if len(content.strip()):
+                cur_indent = self.get_indent(content)
+                if len(cur_indent) <= len(parent_indent):
+                    # print 'OUT'
+                    break  # Indent same as parent found!
+                if len(cur_indent) == len(child_indent):
+                    # print 'MATCH'
+                    siblings.append((line, content))
+            row += 1
+        return siblings
+
+    def get_summary(self, line):
+        view = self.view
+        row, _ = view.rowcol(line.begin())
+        content = view.substr(line)
+        # print content
+        match = self.summary_regex.search(content)
+        if not match:
+            return None
+        # summary = match.group(1)
+        # print repr(summary)
+        # print dir(match), match.start(), match.span()
+        col_start, col_stop = match.span()
+        return sublime.Region(
+            view.text_point(row, col_start),
+            view.text_point(row, col_stop),
+        )
+
+    def run(self, edit):
+        view = self.view
+        backup = []
+        for sel in view.sel():
+            if 'checkbox.orgmode' not in view.scope_name(sel.end()):
+                continue
+            backup.append(sel)
+            region = view.extract_scope(sel.end())
+            content = view.substr(region)
+            if '[X]' in content:
+                content = content.replace('[X]', '[ ]')
+            elif '[ ]' in content:
+                content = content.replace('[ ]', '[X]')
+            view.replace(edit, region, content)
+            parent = self.find_parent(region)
+            if parent:
+                # print parent, region
+                summary = self.get_summary(parent)
+                if not summary:
+                    continue
+                children = self.find_siblings(view.line(region), parent)
+                # print children
+                num_children = len(children)
+                checked_children = len(filter(lambda child: '[X]' in child[1], children))
+                # print checked_children, num_children
+                view.replace(edit, summary, '[%d/%d]' % (checked_children, num_children))
+        view.sel().clear()
+        for region in backup:
+            view.sel().add(region)

orgmode.sublime-settings

+{
+	"word_wrap": true,
+    "translate_tabs_to_spaces": true,
+    "tab_size": 2,
+    "auto_indent": true,
+    "indent_subsequent_lines": true,
+    "detect_indentation": false,
+    "line_numbers": false,
+    "save_on_focus_lost": true,
+    "rulers": [80],
+    "gutter": true
+}

orgmode.tmLanguage

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>fileTypes</key>
+	<array>
+		<string>org</string>
+	</array>
+	<key>keyEquivalent</key>
+	<string>^~P</string>
+	<key>name</key>
+	<string>orgmode</string>
+	<key>patterns</key>
+	<array>
+		<dict>
+			<key>name</key>
+			<string>page.orgmode</string>
+			<key>match</key>
+			<string>^(\-\-\-) .*\n?$</string>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>break.orgmode</string>
+			<key>match</key>
+			<string>^(\~)+ .*\n?$</string>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>headline.orgmode</string>
+			<key>match</key>
+			<string>^\s*(\*)+ [^\[\]]*</string>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>tack.orgmode</string>
+			<key>match</key>
+			<string>^\s*(\-) </string>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>checkbox.orgmode</string>
+			<key>match</key>
+			<string>(\[[xX ]\])\s?</string>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>summary.checkbox.orgmode</string>
+			<key>match</key>
+			<string>(\[\d*[/]\d*\])</string>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>link.orgmode</string>
+			<key>match</key>
+			<string>\[\[(.+)\]\]</string>
+		</dict>
+	</array>
+	<key>scopeName</key>
+	<string>text.orgmode</string>
+	<key>uuid</key>
+	<string>D0287542-2284-452C-8648-B885B3E16B6F</string>
+</dict>
+</plist>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.