Skip to content

Commit

Permalink
fixing navigationHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
xeno-by committed Jan 30, 2012
1 parent bc6a35b commit fa87e8d
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 18 deletions.
16 changes: 13 additions & 3 deletions Packages/BufferScroll/BufferScroll.py
Expand Up @@ -21,17 +21,27 @@ class BufferScroll(sublime_plugin.EventListener):

def on_load(self, view):
if view.file_name() != None and view.file_name() != '':
if unlock(): return
if unlock():
print("buffer_scroll: on_load locked")
return
else:
print("buffer_scroll: on_load unlocked")

self.restore(view)
sublime.set_timeout(lambda: self.restoreScroll(view), 200)

# xeno.by: very stupid, yes, but that's the only way to keep position
# after the file has been reloading because of external modifications
def on_activated(self, view):
if view.file_name() != None and view.file_name() != '':
if unlock(): return
if unlock():
print("buffer_scroll: on_activated locked")
return
else:
print("buffer_scroll: on_activated unlocked")

self.restore(view)
sublime.set_timeout(lambda: self.restore(view), 200)
sublime.set_timeout(lambda: self.restoreScroll(view), 200)

# the application is not sending "on_close" event when closing
# or switching the projects, then we need to save the data on focus lost
Expand Down
1 change: 1 addition & 0 deletions Packages/Default/exec.py
Expand Up @@ -105,6 +105,7 @@ def run(self, cmd = [], file_regex = "", line_regex = "", working_dir = "",
# # self.output_view = self.window.get_output_panel("exec")
wannabes = filter(lambda v: v.name() == (title or " ".join(cmd)), self.window.views())
self.output_view = wannabes[0] if len(wannabes) else self.window.new_file()
self.output_view.settings().set("no_history", True)
self.output_view.set_name(title or " ".join(cmd))
self.output_view.set_scratch(True)
self.output_view.show(self.output_view.size())
Expand Down
6 changes: 6 additions & 0 deletions Packages/Myke/Myke.py
Expand Up @@ -70,6 +70,12 @@ def run(self, edit):
view.settings().set("result_base_dir", env["WorkingDir"])
window.focus_view(view)

view.settings().erase("no_history")
pt = view.text_point(1, 1)
view.sel().clear()
view.sel().add(sublime.Region(pt))
view.show(pt)

message = "Myke %s upon %s" % (env["Action"], env["Target"])
args = env["Args"] if "Args" in env else None
if args: message = "%s with args %s" % (message, args)
Expand Down
139 changes: 125 additions & 14 deletions Packages/NavigationHistory/navigationHistory.py
@@ -1,14 +1,18 @@
import sublime, sublime_plugin
import time
import os
from collections import deque

MAX_SIZE = 64
LINE_THRESHOLD = 2
TIME_THRESHOLD = 1000

class Location(object):
"""A location in the history
"""

def __init__(self, path, line, col):
self.time = time.time() * 1000
self.path = path
self.line = line
self.col = col
Expand Down Expand Up @@ -38,7 +42,10 @@ def __init__(self, max_size=MAX_SIZE):
self._back = deque([], max_size) # items before self._current
self._forward = deque([], max_size) # items after self._current

self._record_movement_invoked = 0 # number of times `record_movement' has been invoked
self._last_movement = None # last recorded movement
self._last_history = None # last recorded movement that got into history
self._last_navigation = None # last recorded navigation (alt+left or alt+right)

def record_movement(self, location):
"""Record movement to the given location, pushing history if
Expand All @@ -47,21 +54,45 @@ def record_movement(self, location):

if location:
if self.has_changed(location):
self.push(location)
self.mark_location(location)

def mark_location(self, location):
"""Remember the current location, for the purposes of being able
to do a has_changed() check.
"""
self._last_movement = location.copy()
print("nav_history: " + str(location.path) + ":" + str(location.line) + ":" + str(location.col))

if self._current:
time_delta = abs(location.time - self._current.time)
print("time delta is: " + str(time_delta))
subsume = self._current.path == location.path and time_delta <= TIME_THRESHOLD
if subsume:
print("nav_history: subsumed current")
if self.has_changed(location):
self._current = location
self._last_movement = location.copy()
self._last_history = location.copy()
else:
print("nav_history: discarded both")
prev = self._back and self._back.pop()
if prev:
self._last_movement = prev.copy()
self._current = prev
self._last_history = location.copy()
else:
self.push(location)
self._last_movement = location.copy()
self._last_history = location.copy()
else:
self.push(location)
self._last_movement = location.copy()
self._last_history = location.copy()
else:
self._last_movement = location.copy()

def has_changed(self, location):
"""Determine if the given location combination represents a
significant enough change to warrant pushing history.
"""

return self._last_movement is None or not self._last_movement.near(location)
changed_movement = self._last_movement is None or not self._last_movement.near(location)
changed_history = self._last_history is None or not self._last_history.near(location)
changed_navigation = self._last_navigation is None or not self._last_navigation.near(location)
return changed_movement and changed_history and changed_navigation

def push(self, location):
"""Push the given location to the back history. Clear the forward
Expand All @@ -84,6 +115,8 @@ def back(self):
self._forward.appendleft(self._current)
self._current = self._back.pop()
self._last_movement = self._current # preempt, so we don't re-push

self._last_navigation = self._current
return self._current

def forward(self):
Expand All @@ -97,6 +130,8 @@ def forward(self):
self._back.append(self._current)
self._current = self._forward.popleft()
self._last_movement = self._current # preempt, so we don't re-push

self._last_navigation = self._current
return self._current

_histories = {} # window id -> History
Expand All @@ -121,16 +156,35 @@ class NavigationHistoryRecorder(sublime_plugin.EventListener):
"""

def on_selection_modified(self, view):
self.possiblyRecordMovement(view)

def on_activated(self, view):
self.possiblyRecordMovement(view)

def possiblyRecordMovement(self, view):
"""When the selection is changed, possibly record movement in the
history
"""
history = get_history()
if history is None:
return

path = view.file_name()
row, col = view.rowcol(view.sel()[0].a)
history.record_movement(Location(path, row + 1, col + 1))
if view.settings().get("repl") or view.settings().get("no_history"):
return

is_not_previewed = False
window = sublime.active_window()
for window_view in window.views():
if (window_view.id() == view.id()):
is_not_previewed = True

if is_not_previewed:
path = view.file_name()
if not path and view.name(): path = view.id()
if path:
row, col = view.rowcol(view.sel()[0].a)
history.record_movement(Location(path, row + 1, col + 1))


# def on_close(self, view):
# """When a view is closed, check to see if the window was closed too
Expand All @@ -157,8 +211,26 @@ def run(self, edit):

location = history.back()
if location:
print("back to: " + str(location.path) + ":" + str(location.line) + ":" + str(location.col))

window = sublime.active_window()
window.open_file("%s:%d:%d" % (location.path, location.line, location.col), sublime.ENCODED_POSITION)
if not isinstance(location.path, int):
window.open_file("%s:%d:%d" % (location.path, location.line, location.col), sublime.ENCODED_POSITION)
else:
found = False
for view in window.views():
if view.id() == location.path:
found = True
lock_buffer_scroll()
window.focus_view(view)
pt = view.text_point(location.line, location.col)
view.sel().clear()
view.sel().add(sublime.Region(pt))
view.show(pt)
if not found:
window.run_command("navigation_history_backward")
else:
print("back to: None")

class NavigationHistoryForward(sublime_plugin.TextCommand):
"""Go forward in history
Expand All @@ -171,5 +243,44 @@ def run(self, edit):

location = history.forward()
if location:
print("forward to: " + str(location.path) + ":" + str(location.line) + ":" + str(location.col))

window = sublime.active_window()
window.open_file("%s:%d:%d" % (location.path, location.line, location.col), sublime.ENCODED_POSITION)
if not isinstance(location.path, int):
window.open_file("%s:%d:%d" % (location.path, location.line, location.col), sublime.ENCODED_POSITION)
else:
found = False
for view in window.views():
if view.id() == location.path:
found = True
lock_buffer_scroll()
window.focus_view(view)
pt = view.text_point(location.line, location.col)
view.sel().clear()
view.sel().add(sublime.Region(pt))
view.show(pt)
if not found:
window.run_command("navigation_history_forward")
else:
print("forward to: None")

bufferscroll_lockfile = sublime.packages_path() + "/User/BufferScroll.lock"

def lock_buffer_scroll():
with file(bufferscroll_lockfile, "a"):
os.utime(bufferscroll_lockfile, None)

def unlock_buffer_scroll():
def do_unlock():
try:
if os.path.exists(bufferscroll_lockfile):
os.remove(bufferscroll_lockfile)
except IOError as e:
pass

locked = os.path.exists(bufferscroll_lockfile)
if locked:
sublime.set_timeout(do_unlock, 200)
return True
else:
return False
2 changes: 1 addition & 1 deletion Packages/User/Package Control.sublime-settings
@@ -1,5 +1,5 @@
{
"auto_upgrade_last_run": 1327952804,
"auto_upgrade_last_run": 1327962613,
"installed_packages":
[
"BufferScroll",
Expand Down

0 comments on commit fa87e8d

Please sign in to comment.