Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
*.pyc
*~
*.orig
*.swp
2 changes: 1 addition & 1 deletion snapopen.plugin
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Plugin]
Loader=python
Loader=python3
Module=snapopen
IAge=3
Name=Snap Open
Expand Down
133 changes: 101 additions & 32 deletions snapopen/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from gi.repository import GObject, Gedit, Gtk, Gio, Gdk
import os, os.path
from urllib import pathname2url
from urllib.request import pathname2url
import tempfile

max_result = 50
app_string = "Snap open"

def send_message(window, object_path, method, **kwargs):
return window.get_message_bus().send_sync(object_path, method, **kwargs)

ui_str="""<ui>
<menubar name="MenuBar">
<menu name="FileMenu" action="File">
Expand All @@ -22,7 +25,7 @@ class SnapOpenPluginInstance:
def __init__( self, plugin, window ):
self._window = window
self._plugin = plugin
self._rootdir = "file://" + os.getcwd()
self._dirs = [] # to be filled
self._tmpfile = os.path.join(tempfile.gettempdir(), 'snapopen.%s.%s' % (os.getuid(),os.getpid()))
self._show_hidden = False
self._liststore = None;
Expand Down Expand Up @@ -96,7 +99,7 @@ def _init_ui( self ):

#mouse event on list
def on_list_mouse( self, widget, event ):
if event.type == gtk.gdk._2BUTTON_PRESS:
if event.type == Gdk.EventType._2BUTTON_PRESS:
self.open_selected_item( event )

#key selects from list (passthrough 3 args)
Expand Down Expand Up @@ -125,6 +128,7 @@ def on_pattern_entry( self, widget, event ):

self._liststore.clear()
maxcount = 0
print(cmd)
hits = os.popen(cmd).readlines()
for file in hits:
file = file.rstrip().replace("./", "") #remove cwd prefix
Expand All @@ -145,24 +149,98 @@ def on_pattern_entry( self, widget, event ):
if iter != None:
self._hit_list.get_selection().select_iter(iter)

def get_git_base_dir( self, path ):
""" Get git base dir if given path is inside a git repo. None otherwise. """
try:
cmd = "cd '%s' 2> /dev/null; git rev-parse --show-toplevel 2> /dev/null" % path
print(cmd)
gitdir = os.popen(cmd).readlines()
except:
gitdir = ''
if len(gitdir) > 0:
return gitdir[0].replace("\n","")
return None

def map_to_git_base_dirs( self ):
""" Replace paths with respective git repo base dirs if it exists """
# use git repo base dir is more suitable if we are inside a git repo, for any dir we have guessed before
dirs = []
for d in self._dirs:
gitdir = self.get_git_base_dir(d)
if gitdir is None:
dirs.append(d)
else:
dirs.append(gitdir)
self._dirs = dirs
# we could have introduced duplicates here
self.ensure_unique_entries()

def ensure_unique_entries( self ):
""" Remove duplicates from dirs list """
# this also looks for paths already included in other paths
unique = []
for d in self._dirs:
d = d.replace("file://","").replace("//","/")
should_append = True
for i,u in enumerate(unique): # replace everyone with its wider parent
if u in d: # already this one, or a parent
should_append = False
elif d in u: # replace with the parent
unique[i] = d
should_append = False

if should_append:
unique.append(d)

self._dirs = set(unique)

def get_dirs_string( self ):
""" Gets the quoted string built with dir list, ready to be passed on to 'find' """
string = ''
for d in self._dirs:
string += "'%s' " % d
return string

#on menuitem activation (incl. shortcut)
def on_snapopen_action( self ):
self._init_ui()

fbroot = self.get_filebrowser_root()
# build paths list
self._dirs = []

# append current local open files dirs
for doc in self._window.get_documents():
location = doc.get_location()
if location and doc.is_local():
self._dirs.append( location.get_parent().get_uri() )

# append filebrowser root if available
fbroot = self.get_filebrowser_root()
if fbroot != "" and fbroot is not None:
self._rootdir = fbroot
self._snapopen_window.set_title(app_string + " (File Browser root)")
else:
self._snapopen_window.set_title(app_string + " (Working dir): " + self._rootdir)
self._dirs.append(fbroot)

# cache the file list in the background
# ensure_unique_entries is executed after mapping to git base dir
# but it's cheaper, then do it before too, avoiding extra work
self.ensure_unique_entries()

# replace each path with its git base dir if exists
self.map_to_git_base_dirs()

# append gedit dir (usually too wide for a quick search) if we have nothing so far
if len(self._dirs) == 0:
self._dirs = [ os.getcwd() ]

# build filters list
#modify lines below as needed, these defaults work pretty well
imagefilter = " ! -iname '*.jpg' ! -iname '*.jpeg' ! -iname '*.gif' ! -iname '*.png' ! -iname '*.psd' ! -iname '*.tif' "
dirfilter = " ! -path '*.svn*' ! -path '*.git*' "
binfilter = " ! -iname '*.o' ! -iname '*.so' ! -iname '*.lo' ! -iname '*.Plo' ! -iname '*.a' ! -iname '*.pyc' "
os.popen("cd %s; find . -type f %s > %s 2> /dev/null &" % (self._rootdir.replace("file://", ""), imagefilter + dirfilter + binfilter, self._tmpfile))
filters = " ! -iname '*.jpg' ! -iname '*.jpeg' ! -iname '*.gif' ! -iname '*.png' ! -iname '*.psd' ! -iname '*.tif' "
filters += " ! -path '*.svn*' ! -path '*.git*' "
filters += " ! -iname '*.o' ! -iname '*.so' ! -iname '*.lo' ! -iname '*.Plo' ! -iname '*.a' ! -iname '*.pyc' "
filters += " ! -iname '*~' ! -iname '*.swp' "

# cache the file list in the background
cmd = "find %s -type f %s > %s 2> /dev/null &" % (self.get_dirs_string(), filters, self._tmpfile)
print(cmd)
os.popen(cmd)

self._snapopen_window.show()
self._glade_entry_name.select_region(0,-1)
Expand Down Expand Up @@ -194,29 +272,19 @@ def old_get_tab_from_uri(self, window, uri):

#opens (or switches to) the given file
def _open_file( self, filename ):
uri = self._rootdir + "/" + pathname2url(filename)
#uri = self._rootdir + "/" + pathname2url(filename)
uri = "file://" + pathname2url(filename)
gio_file = Gio.file_new_for_uri(uri)
tab = self._window.get_tab_from_location(gio_file)
if tab == None:
tab = self._window.create_tab_from_location( gio_file, None, 0, 0, False, False )
self._window.set_active_tab( tab )

# FILEBROWSER integration
# filebrowser integration
def get_filebrowser_root(self):
base = u'org.gnome.gedit.plugins.filebrowser'

settings = Gio.Settings.new(base)
root = settings.get_string('virtual-root')

if root is not None:
filter_mode = settings.get_strv('filter-mode')

if 'hide-hidden' in filter_mode:
self._show_hidden = False
else:
self._show_hidden = True

return root
res = send_message(self._window, '/plugins/filebrowser', 'get_root')
if res.location is not None:
return res.location.get_path()

# STANDARD PLUMMING
class SnapOpenPlugin(GObject.Object, Gedit.WindowActivatable):
Expand All @@ -229,16 +297,17 @@ def __init__(self):
GObject.Object.__init__(self)

def _get_instance( self ):
return self.window.get_data( self.DATA_TAG )
return self.window.DATA_TAG

def _set_instance( self, instance ):
self.window.set_data( self.DATA_TAG, instance )
self.window.DATA_TAG = instance

def do_activate( self ):
self._set_instance( SnapOpenPluginInstance( self, self.window ) )

def do_deactivate( self ):
self._get_instance().deactivate()
if self._get_instance():
self._get_instance().deactivate()
self._set_instance( None )

def do_update_ui( self ):
Expand Down
4 changes: 2 additions & 2 deletions snapopen/snapopen.ui
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkWindow" id="SnapOpenWindow">
<property name="width_request">500</property>
<property name="height_request">360</property>
<property name="width_request">900</property>
<property name="height_request">400</property>
<property name="can_focus">False</property>
<property name="border_width">11</property>
<property name="title" translatable="yes">Snap Open file...</property>
Expand Down