forked from danielmagnussons/orgmode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
orgmode_store.py
171 lines (140 loc) · 5.37 KB
/
orgmode_store.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
from gzip import GzipFile
from os import makedirs
from os.path import lexists, dirname
from pickle import load, dump
import sublime
import sublime_plugin
class OrgmodeStore(sublime_plugin.EventListener):
def __init__(self, *args, **kwargs):
self.debug = False
self.db = {}
self.store = dirname(
sublime.packages_path()) + '/Settings/orgmode-store.bin.gz'
try:
makedirs(dirname(self.store))
except:
pass
try:
with GzipFile(self.store, 'rb') as f:
self.db = load(f)
except:
self.db = {}
self.on_load(sublime.active_window().active_view())
for window in sublime.windows():
self.on_load(window.active_view())
def on_load(self, view):
self.restore(view, 'on_load')
def on_deactivated(self, view):
window = view.window()
if not window:
window = sublime.active_window()
index = window.get_view_index(view)
if index != (-1, -1): # if the view was not closed
self.save(view, 'on_deactivated')
def on_activated(self, view):
self.restore(view, 'on_activated')
def on_pre_close(self, view):
self.save(view, 'on_pre_close')
def on_pre_save(self, view):
self.save(view, 'on_pre_save')
def save(self, view, where='unknow'):
if view is None or not view.file_name():
return
if view.is_loading():
sublime.set_timeout(lambda: self.save(view, where), 100)
return
_id = self.view_index(view)
if _id not in self.db:
self.db[_id] = {}
# if the result of the new collected data is different
# from the old data, then will write to disk
# this will hold the old value for comparison
old_db = dict(self.db[_id])
# if the size of the view change outside the application skip
# restoration
self.db[_id]['id'] = int(view.size())
# marks
self.db[_id]['m'] = [[item.a, item.b]
for item in view.get_regions("mark")]
if self.debug:
print('marks: ' + str(self.db[_id]['m']))
# previous folding save, to be able to refold
if 'f' in self.db[_id] and list(self.db[_id]['f']) != []:
self.db[_id]['pf'] = list(self.db[_id]['f'])
# folding
self.db[_id]['f'] = [[item.a, item.b] for item in view.folded_regions()]
if self.debug:
print('fold: ' + str(self.db[_id]['f']))
# syntax
self.db[_id]['x'] = view.settings().get('syntax')
if self.debug:
print('syntax: ' + str(self.db[_id]['x']))
# write to disk only if something changed
if old_db != self.db[_id] or where == 'on_deactivated':
with GzipFile(self.store, 'wb') as f:
dump(self.db, f, -1)
def view_index(self, view):
window = view.window()
if not window:
window = sublime.active_window()
index = window.get_view_index(view)
return str(window.id()) + str(index)
def restore(self, view, where='unknow'):
if view is None or not view.file_name():
return
if view.is_loading():
sublime.set_timeout(lambda: self.restore(view, where), 100)
return
_id = self.view_index(view)
if self.debug:
print('-----------------------------------')
print('RESTORING from: ' + where)
print('file: ' + view.file_name())
print('_id: ' + _id)
if _id in self.db:
# fold
rs = []
for r in self.db[_id]['f']:
rs.append(sublime.Region(int(r[0]), int(r[1])))
if len(rs):
view.fold(rs)
if self.debug:
print("fold: " + str(rs))
# marks
rs = []
for r in self.db[_id]['m']:
rs.append(sublime.Region(int(r[0]), int(r[1])))
if len(rs):
view.add_regions(
"mark", rs, "mark", "dot", sublime.HIDDEN | sublime.PERSISTENT)
if self.debug:
print('marks: ' + str(self.db[_id]['m']))
# syntax
if view.settings().get('syntax') != self.db[_id]['x'] and lexists(sublime.packages_path() + '/../' + self.db[_id]['x']):
view.settings().set('syntax', self.db[_id]['x'])
if self.debug:
print('syntax: ' + str(self.db[_id]['x']))
class OrgmodeFoldingCommand(sublime_plugin.TextCommand):
"""
Bind to TAB key, and if the current line is not
a headline, a \t would be inserted.
"""
def run(self, edit):
(row,col) = self.view.rowcol(self.view.sel()[0].begin())
line = row +2
print(line)
for s in self.view.sel():
r = self.view.full_line(s)
if self._is_region_folded(r.b + 1, self.view):
print('lol')
self.view.run_command("unfold")
return
pt = self.view.text_point(line, 0)
self.view.sel().clear()
self.view.sel().add(sublime.Region(pt))
self.view.run_command("fold")
def _is_region_folded(self, region, view):
for i in view.folded_regions():
if i.contains(region):
return True
return False