Sublime Forum

openLastClosedFile

#1

I’m used to press ctrl+shift+t to get a closed tab back in my browser that’s why I did the same thing in sublime text and since there was no such keybinding available I implemented my own plugin and added a keymap for it.

This plugin allows you to reopen closed files.
You can open more then one closed file by repeating the command.

Changelog v1.0.2:
Fixed not using package folder to save tmp file when --data commandline option is used

Changelog v1.0.1:
Fixed wrong loading filename

# openLastClosedFile plugin v1.0.2
#
# example keybinding:
# <binding key="shift+ctrl+t" command="openLastClosedFile"/>
#
# Known issues:
#	there has to be one tab open to make the keybinding work

import sublime, sublimeplugin, os

# we need to be able to load the filenames when command gets called
class openLastClosedFileSecure(sublimeplugin.Plugin):
	def onClose(self, view):
		# untitled / not saved files have no filename
		if view.fileName() <> None:
			file = open(sublime.packagesPath()+"\\User\\openLastClosedFile.tmp", 'a')
			file.writelines(view.fileName()+"\n")
			file.close()
		
		print sublime.packagesPath()


class openLastClosedFileCommand(sublimeplugin.TextCommand):
	def run(self, view, args):
		fileName = sublime.packagesPath()+"\\User\\openLastClosedFile.tmp"

		if os.path.isfile(fileName):
			readFile = open(fileName,"r")
			lines = readFile.readlines()
			readFile.close()

			length = len(lines)
			
			if length > 0:
				lastline = lines[length-1]
				lastline = lastline.rstrip("\n")
				
				view.window().openFile(lastline, 0, 0)
				
				writeFile = open(fileName, "w")
				writeFile.writelines([item for item in lines[0:length-1]])
				writeFile.close()

get it here: pastebin.com/rXQ3XNcb

(old version v1.0.1) pastebin.com/Fw3ZUJ1z

0 Likes

Undo tab close / recently closed tabs
#2

The packages are not always in appdata: see the “–data” command line option. You can find them using “sublime.packagesPath()”

0 Likes

#3

Thanks! I updated the plugin to use sublime.packagesPath().

0 Likes

#4

This is my version of this plugin :smile:

import sublime, sublime_plugin
import os

last_closed_file_path = sublime.packages_path() + "/User/last_closed_file.path"

class OpenLastClosedFileCommand(sublime_plugin.WindowCommand):
	def run(self):
		if os.path.exists(last_closed_file_path):
			self.window.open_file(open(last_closed_file_path).read().strip())

class OpenLastClosedFileEvent(sublime_plugin.EventListener):
	def on_close(self, view):
		f = open(last_closed_file_path, "wb")
		f.write(view.file_name())
		f.close()

P.S.: It works without anything opened.

0 Likes

#5

Minor tweak not to record unsaved disk files (New files without name):

import sublime, sublime_plugin
import os

last_closed_file_path = sublime.packages_path() + "/User/last_closed_file.path"

class OpenLastClosedFileCommand(sublime_plugin.WindowCommand):
	def run(self):
		if os.path.exists(last_closed_file_path):
			self.window.open_file(open(last_closed_file_path).read().strip())

class OpenLastClosedFileEvent(sublime_plugin.EventListener):
	def on_close(self, view):
		if view.file_name() != None:
			f = open(last_closed_file_path, "wb")
			f.write(view.file_name())
			f.close()
0 Likes

#6

I’m on fire… now with history length, defined on line 5.

import sublime, sublime_plugin
import os

last_closed_file_path = sublime.packages_path() + "/User/last_closed_file.path"
last_closed_file_max = 10

def get_history():
	f = open(last_closed_file_path, "rb")
	history = f.readlines()
	f.close()

	return history

def save_history(history):
	f = open(last_closed_file_path, "wb")
	f.write("\n".join(map(str, history)))
	f.close()

class OpenLastClosedFileCommand(sublime_plugin.WindowCommand):
	def run(self):
		if os.path.exists(last_closed_file_path):
			history = get_history()

			if len(history) > 0:
				self.window.open_file(history.pop().strip())
				save_history(history)

class OpenLastClosedFileEvent(sublime_plugin.EventListener):
	def on_close(self, view):
		if view.file_name() != None:
			history = get_history()

			history.append(view.file_name())
			if len(history) >last_closed_file_max:
				history = history-last_closed_file_max:]

			save_history(history)
0 Likes

#7

Oh boy I never knew about this plugin :smile: I was asking how to do this in the suggestion forums and had a shortcut key to open the single last file but this is great :smiley: thank you so much!

0 Likes

#8

I’m being really dumb, but how do you setup this plugin? I’ve yet to add any plugins to Sublime so all I did was select “New Plugin” from the menu and pasted the code in, saved the file then setup the key binding as mentioned in the example but it does not seem to run.

0 Likes

#9

Phunky,

Your user key bindings are probably the older style. Throw this in there:

{ "keys": "ctrl+shift+t"], "command": "open_last_closed_file" }

…and I had to create a file in User called “last_closed_file.path” before it started to work.

I noticed something though, at least with dresende’s latest version-- once a closed file is re-opened, it will start to walk the directory up each time you invoke the plugin. That is, say I close this file:

then if I hit ctrl+shift+t again, it will “re-open” the User directory, then the Packages directory, etc. Think it needs a bit of tuning but I really like the concept.

0 Likes

#10

Excellent plugin. Thanks.

Slightly off topic, but what is the easiest way to debug these plugins? Say, nothing happens; where do I go? Are there any log/puts commands in python? Does it go anywhere?

Thanks!

0 Likes

#11

Thank you so much ehamiter, that got the plugin working :smile:

0 Likes

#12

Inspired by dresende’s code, but not quite content, I implemented a slightly enhanced version of this plugin. This plugin keeps track of both closed files as well as the files that have been opened. The default behavior of the plugin is to open the most recently closed file, but it can also provide access to a searchable quick panel with the recently closed files followed by a history of the files that have been opened. This can be helpful when using multiple projects or when wanting to reopen a file that you closed a few hours or days ago.

The implementation uses the sublime.Settings API methods to store and cache the file open/close history. The history file is saved in the User sub-directory of the Packages directory (as History.sublime-settings). The history is formatted in JSON like the rest of the sublime settings.

import sublime, sublime_plugin
import os

HISTORY_SETTINGS_FILE = "History.sublime-settings"
HISTORY_MAX_ENTRIES=500

def get_history(setting_name):
    """load the history using sublime's built-in functionality for accessing settings"""
    history = sublime.load_settings(HISTORY_SETTINGS_FILE)
    if history.has(setting_name):
        return history.get(setting_name)
    else:
        return ]

def set_history(setting_name, setting_values):
    """save the history using sublime's built-in functionality for accessing settings"""
    history = sublime.load_settings(HISTORY_SETTINGS_FILE)
    history.set(setting_name, setting_values)
    sublime.save_settings(HISTORY_SETTINGS_FILE)


class OpenRecentlyClosedFileEvent(sublime_plugin.EventListener):
    """class to keep a history of the files that have been opened and closed"""

    def on_close(self, view):
        self.add_to_history(view, "closed", "opened")

    def on_load(self, view):
        self.add_to_history(view, "opened", "closed")

    def add_to_history(self, view, add_to_setting, remove_from_setting):
        filename = os.path.normpath(view.file_name())
        if filename != None:
            add_to_list = get_history(add_to_setting)
            remove_from_list = get_history(remove_from_setting)

            # remove this file from both of the lists
            while filename in remove_from_list:
                remove_from_list.remove(filename)
            while filename in add_to_list:
                add_to_list.remove(filename)

            # add this file to the top of the "add_to_list" (but only if the file actually exists)
            if os.path.exists(filename):
                add_to_list.insert(0, filename)

            # write the history back (making sure to limit the length of the histories)
            set_history(add_to_setting, add_to_list[0:HISTORY_MAX_ENTRIES])
            set_history(remove_from_setting, remove_from_list[0:HISTORY_MAX_ENTRIES])

class OpenRecentlyClosedFileCommand(sublime_plugin.WindowCommand):
    """class to either open the last closed file or show a quick panel with the file access history (closed files first)"""

    def run(self, show_quick_panel=False):
        self.reload_history()
        if show_quick_panel:
            self.window.show_quick_panel(self.file_list, self.open_file)
        else:
            self.open_file(0)

    def reload_history(self):
        history = sublime.load_settings(HISTORY_SETTINGS_FILE)
        self.file_list = get_history("closed") + get_history("opened")

    def open_file(self, index):
        if index >= 0 and len(self.file_list) > index:
            self.window.open_file(self.file_list[index])

I use the following shortcuts to access the plugin:

{ "keys": "ctrl+shift+t"], "command": "open_recently_closed_file", "args": {"show_quick_panel": true} },
{ "keys": "ctrl+alt+shift+t"], "command": "open_recently_closed_file" }
1 Like

Mnemonics for "Open Recent" file list
#13

I added an updated version and uploaded it to github. Unfortunately commiting to github is blocked from my work so I had to add it as a gist.

The updated version now keeps both a global and a per-project history. This allows you to access the file history specific to the active project or the file history across all projects. I find this extremely helpful when opening a project after a few days and forgetting the name of a file that I closed when I last accessed that project.

gist.github.com/1133602

0 Likes

#14

This is sweet jbjornson! I find myself constantly closing files by accident all the time. I only wish it would restore the tab to the same location, like Firefox does.

0 Likes

#15

Glad you like it :smile:

I just had a quick check of the api and it looks like there is something that might help with that: window.set_view_index(view, group, index)

I’ll have a look and see if I can get something to work.

0 Likes

#16

Done (finally). It should now restore the tab to the previous location. Please let me know if it works…
gist.github.com/1133602

0 Likes

#17

I mirrored this plugin on github (here) so it can be installed via Package Control (just search for “File History”).

0 Likes

#18

Thanks FichteFoll!

0 Likes