-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathorgextended.py
190 lines (165 loc) · 6.72 KB
/
orgextended.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import sublime
import sublime_plugin
import datetime
import re
from pathlib import Path
import os
import fnmatch
import OrgExtended.orgparse.node as node
from OrgExtended.orgparse.sublimenode import *
import OrgExtended.orgutil.util as util
import OrgExtended.orgutil.navigation as nav
import OrgExtended.orgutil.template as templateEngine
import logging
import sys
import traceback
import OrgExtended.orgfolding as folding
import OrgExtended.orgdb as db
import OrgExtended.asettings as sets
import OrgExtended.orgcapture as capture
import OrgExtended.orglinks as links
import OrgExtended.orgclocking as clocking
import OrgExtended.orgnotifications as notice
import OrgExtended.orgdatepicker as datepicker
import OrgExtended.pymitter as evt
import OrgExtended.packagecon as pkgcon
log = None
def InstallIfNeeded(pkg, name):
log.debug("Checking for " + name)
if(not pkgcon.IsInstalled(pkg)):
log.debug("Installing " + name)
pkgcon.Install(pkg)
# Lets get our windows in sync now that we are loaded.
def sync_up_on_loaded():
window = sublime.active_window()
window.run_command("org_on_load_sync_up", {})
notice.Setup()
datepicker.SetupMouse()
# Install required packages to operate org extended
InstallIfNeeded(pkgcon.TABLE_PACKAGE, "Table Editor")
InstallIfNeeded(pkgcon.PS_PACKAGE, "Powershell")
# This is where we can start to load our DB!
def plugin_loaded():
evt.Get().off("tagsfound",db.Get().OnTags)
sets.setup_user_settings()
# Load our settings file.
# We probably need a command to reload it
# When it is modified, and probably to reload
# the DB automatically when your orgs change.
sets.Load()
clocking.Load()
# To enable debug logging, set the env var to a non-blank value.
# This is the same pattern that neovintageous uses and I think
# it is a reasonably decent mechanism
_DEBUG = bool(os.getenv('SUBLIME_ORGEXTENDED_DEBUG'))
_DEBUG = _DEBUG or sets.Get("enableDebugLogging",False)
#_DEBUG = True
if _DEBUG:
logger = logging.getLogger('OrgExtended')
logger.propagate = 0
if not logger.hasHandlers():
logger.setLevel(logging.DEBUG)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter(
'Org: %(levelname)-7s [%(filename)15s:%(lineno)4d] %(message)s'
))
logger.addHandler(stream_handler)
logger.debug('debug logger initialized')
global log
log = logging.getLogger(__name__)
db.Get().RebuildDb()
#window = sublime.active_window()
#if window is None:
sublime.set_timeout_async(lambda: sync_up_on_loaded(), 1000)
log.debug("DONE INITIALIZING ORG CAPTURE")
# This is called when our plugin unloads!
def plugin_unloaded():
links.onShutdown()
if(notice):
notice.Get().stop()
def onLoad(view):
if(view and view.file_name() and util.isPotentialOrgFile(view.file_name())):
folding.onLoad(view)
links.onLoad(view)
RE_TABLE_MATCH = re.compile(r"^\s*\|")
# Core events to dispatch to each of our subsystems.
# This simple direct call is sufficient for our needs
class OrgCore(sublime_plugin.EventListener):
def on_load(self, view):
# If this is an org file we need to let the
# folding system and others get a crack at this
# file. OnLoad will potentially pre-fold the file
# or show images in the file.
onLoad(view)
def on_post_window_command(self, window, cmd, args):
#print("****** CMD: " + cmd)
capture.onPostWindowCommand(window,cmd,args)
def on_post_save(self, view):
if(util.isPotentialOrgFile(view.file_name())):
db.Get().Reload(view)
def on_deactivated(self, view):
capture.onDeactivated(view)
def on_activated(self, view):
if(util.isPotentialOrgFile(view.file_name())):
folding.onActivated(view)
def ShouldLocalFold(self, view):
file = db.Get().FindInfo(view.file_name())
if(file != None and file.HasChanged(view)):
file.LoadS(view)
return folding.ShouldFoldLocalCycle(view)
def ShouldGlobalFold(self, view):
file = db.Get().FindInfo(view.file_name())
return (not self.ShouldLocalFold(view)) and (file != None and type(file.AtInView(view,db.Get())) is node.OrgRootNode)
def ShouldFoldLinks(self, view):
return (not self.ShouldGlobalFold(view)) and folding.am_in_link(view)
def ShouldTableTab(self,view):
cur = view.sel()[0]
l = view.line(cur.begin())
line = view.substr(l)
return RE_TABLE_MATCH.search(line)
def ShouldFoldBlock(self,view):
cur = view.sel()[0]
names = view.scope_name(cur.begin())
return 'fence.dynamicblock' in names
def IsOrgSyntax(self,view):
cur = view.sel()[0]
names = view.scope_name(cur.begin())
return 'text.orgmode' in names
def ShouldFoldCheckbox(self, view):
return (not self.ShouldGlobalFold(view)) and folding.ShouldFoldCheckbox(view)
def on_query_context(self, view, key, operator, operand, match_all):
# A key wants to be inserted, what context are we in for that?
rc = False
if(operator == sublime.OP_EQUAL and (util.isPotentialOrgFile(view.file_name()) or self.IsOrgSyntax(view))):
if(key == 'org_heading'):
rc = operand == self.ShouldLocalFold(view)
elif(key == 'org_global'):
rc = operand == self.ShouldGlobalFold(view)
elif(key == 'org_link'):
rc = operand == self.ShouldFoldLinks(view)
elif(key == 'org_table'):
rc = operand == self.ShouldTableTab(view)
elif(key == 'org_block'):
rc = operand == self.ShouldFoldBlock(view)
elif(key == 'org_checkbox'):
rc = operand == self.ShouldFoldCheckbox(view)
return rc
# Create a new file.
class OrgNewFileCommand(sublime_plugin.WindowCommand):
def run(self):
view = self.window.new_file()
view.set_syntax_file('Packages/OrgExtended/OrgExtended.sublime-syntax')
# Iterate over all open "tabs" and sync them up so they are folded the way they are supposed to be.
class OrgOnLoadSyncUpCommand(sublime_plugin.WindowCommand):
def run(self):
sheets = self.window.sheets()
for sheet in sheets:
view = sheet.view()
if(view):
# Todo detect buffer type as well in the future?
# for now we can only do files on disk
if(view.file_name()):
log.debug("OnLoad: " + view.file_name())
else:
log.debug("Loading Unamed Buffer: " + str(view.id()))
onLoad(view)