Skip to content

Commit

Permalink
add --auto-jump for Leaderf gtags as requirement in issue #191
Browse files Browse the repository at this point in the history
Jump to the tag directly when there is only one match.
  • Loading branch information
Yggdroot committed Apr 29, 2019
1 parent 6e09da7 commit cbf8df2
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 149 deletions.
1 change: 1 addition & 0 deletions autoload/leaderf/Any.vim
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ let g:Lf_Arguments = {
\ {"name": ["--all"], "nargs": 0, "help": "Show tags in the whole project."},
\ ],
\ {"name": ["--result"], "nargs": 1, "choices": ["ctags", "ctags-x", "ctags-mod"], "metavar": "<FORMAT>", "help": "Show result using format, which may be one of: `ctags`(default), `ctags-x`, `ctags-mod`."},
\ {"name": ["--auto-jump"], "nargs": "?", "metavar": "<TYPE>", "help": "Jump to the tag directly when there is only one match. <TYPE> can be 'h', 'v' or 't', which mean jump to a horizontally, vertically split window, or a new tabpage respectively. If <TYPE> is omitted, jump to a position in current window."},
\ ],
\}

Expand Down
8 changes: 4 additions & 4 deletions autoload/leaderf/python/leaderf/anyExpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,10 @@ def __init__(self,
Leaderf[!] gtags --update [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [--accept-dotfiles]
[--skip-unreadable] [--skip-symlink [<TYPE>]] [--gtagslibpath <PATH> [<PATH> ...]]
Leaderf[!] gtags [--current-buffer | --all-buffers | --all] [--result <FORMAT>] [COMMON_OPTIONS]
Leaderf[!] gtags -d <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
[--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -r <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
[--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -d <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
[--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -r <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
[--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -s <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
[--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -g <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
Expand Down
79 changes: 39 additions & 40 deletions autoload/leaderf/python/leaderf/asyncExecutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,36 @@ def execute(self, cmd, encoding=None, cleanup=None, env=None):

stdout_thread.join(0.01)

result = AsyncExecutor.Result(self._outQueue, self._errQueue, encoding, cleanup, self._process)
def read(outQueue, errQueue, encoding, cleanup):
try:
if encoding:
while True:
line = outQueue.get()
if line is None:
break
yield lfBytes2Str(line.rstrip(b"\r\n"), encoding)
else:
while True:
line = outQueue.get()
if line is None:
break
yield lfEncode(lfBytes2Str(line.rstrip(b"\r\n")))

err = b"".join(iter(errQueue.get, None))
if err:
raise Exception(lfBytes2Str(err, encoding))
finally:
try:
if self._process:
self._process.stdout.close()
self._process.stderr.close()
except IOError:
pass

if cleanup:
cleanup()

result = AsyncExecutor.Result(read(self._outQueue, self._errQueue, encoding, cleanup))

return result

Expand All @@ -94,53 +123,23 @@ def killProcess(self):
self._process = None

class Result(object):
def __init__(self, outQueue, errQueue, encoding, cleanup, process):
self._outQueue = outQueue
self._errQueue = errQueue
self._encoding = encoding
self._cleanup = cleanup
self._process = process
self._results = []
def __init__(self, iterable):
self._g = iterable

def __add__(self, iterable):
self._results.append(iterable)
self._g = itertools.chain(self._g, iterable)
return self

def __iadd__(self, iterable):
self._results.append(iterable)
self._g = itertools.chain(self._g, iterable)
return self

def __iter__(self):
try:
if self._encoding:
while True:
line = self._outQueue.get()
if line is None:
break
yield lfBytes2Str(line.rstrip(b"\r\n"), self._encoding)
else:
while True:
line = self._outQueue.get()
if line is None:
break
yield lfEncode(lfBytes2Str(line.rstrip(b"\r\n")))

err = b"".join(iter(self._errQueue.get, None))
if err:
raise Exception(lfBytes2Str(err, self._encoding))
finally:
try:
if self._process:
self._process.stdout.close()
self._process.stderr.close()
except IOError:
pass

if self._cleanup:
self._cleanup()
def join_left(self, iterable):
self._g = itertools.chain(iterable, self._g)
return self

for i in itertools.chain.from_iterable(self._results):
yield i
def __iter__(self):
return self._g


if __name__ == "__main__":
Expand Down
91 changes: 53 additions & 38 deletions autoload/leaderf/python/leaderf/gtagsExpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import os
import os.path
import shutil
import itertools
import subprocess
from .utils import *
from .explorer import *
Expand Down Expand Up @@ -57,67 +58,73 @@ def _processTask(self):
print(e)

def getContent(self, *args, **kwargs):
if "--recall" in kwargs.get("arguments", {}):
arguments_dict = kwargs.get("arguments", {})
if "--recall" in arguments_dict:
return []

if vim.current.buffer.name:
filename = lfDecode(vim.current.buffer.name)
else:
filename = os.path.join(os.getcwd(), 'no_name')

if "--gtagsconf" in kwargs.get("arguments", {}):
self._gtagsconf = kwargs.get("arguments", {})["--gtagsconf"][0]
if "--gtagslabel" in kwargs.get("arguments", {}):
self._gtagslabel = kwargs.get("arguments", {})["--gtagslabel"][0]
if "--gtagsconf" in arguments_dict:
self._gtagsconf = arguments_dict["--gtagsconf"][0]
if "--gtagslabel" in arguments_dict:
self._gtagslabel = arguments_dict["--gtagslabel"][0]

if self._gtagsconf == '' and os.name == 'nt':
self._gtagsconf = os.path.normpath(os.path.join(self._which("gtags.exe"), "..", "share", "gtags", "gtags.conf"))

if "--gtagslibpath" in kwargs.get("arguments", {}):
self._gtagslibpath = [os.path.expanduser(p) for p in kwargs.get("arguments", {})["--gtagslibpath"]]
if "--gtagslibpath" in arguments_dict:
self._gtagslibpath = [os.path.expanduser(p) for p in arguments_dict["--gtagslibpath"]]
else:
self._gtagslibpath = []

if "--update" in kwargs.get("arguments", {}):
if "--accept-dotfiles" in kwargs.get("arguments", {}):
if "--update" in arguments_dict:
if "--accept-dotfiles" in arguments_dict:
self._accept_dotfiles = "--accept-dotfiles "
if "--skip-unreadable" in kwargs.get("arguments", {}):
if "--skip-unreadable" in arguments_dict:
self._skip_unreadable = "--skip-unreadable "
if "--skip-symlink" in kwargs.get("arguments", {}):
skip_symlink = kwargs.get("arguments", {})["--skip-symlink"]
if "--skip-symlink" in arguments_dict:
skip_symlink = arguments_dict["--skip-symlink"]
self._skip_symlink = "--skip-symlink%s " % ('=' + skip_symlink[0] if skip_symlink else "")
self.updateGtags(filename, single_update=False, auto=False)
return
elif "--remove" in kwargs.get("arguments", {}):
elif "--remove" in arguments_dict:
self._remove(filename)
return

if "--path-style" in kwargs.get("arguments", {}):
path_style = "--path-style %s " % kwargs.get("arguments", {})["--path-style"][0]
if "--path-style" in arguments_dict:
path_style = "--path-style %s " % arguments_dict["--path-style"][0]
else:
path_style = ""

auto_jump = False
self._last_result_format = self._result_format
self._result_format = None
if "-d" in kwargs.get("arguments", {}):
pattern = kwargs.get("arguments", {})["-d"][0]
if "-d" in arguments_dict:
pattern = arguments_dict["-d"][0]
pattern_option = "-d -e %s " % pattern
elif "-r" in kwargs.get("arguments", {}):
pattern = kwargs.get("arguments", {})["-r"][0]
if "--auto-jump" in arguments_dict:
auto_jump = True
elif "-r" in arguments_dict:
pattern = arguments_dict["-r"][0]
pattern_option = "-r -e %s " % pattern
elif "-s" in kwargs.get("arguments", {}):
pattern = kwargs.get("arguments", {})["-s"][0]
if "--auto-jump" in arguments_dict:
auto_jump = True
elif "-s" in arguments_dict:
pattern = arguments_dict["-s"][0]
pattern_option = "-s -e %s " % pattern
elif "-g" in kwargs.get("arguments", {}):
pattern = kwargs.get("arguments", {})["-g"][0]
elif "-g" in arguments_dict:
pattern = arguments_dict["-g"][0]
pattern_option = "-g -e %s " % pattern
elif "--by-context" in kwargs.get("arguments", {}):
elif "--by-context" in arguments_dict:
pattern = lfEval('expand("<cword>")')
pattern_option = '--from-here "%d:%s" %s ' % (vim.current.window.cursor[0], vim.current.buffer.name, pattern)
else:
if "--current-buffer" in kwargs.get("arguments", {}):
if "--current-buffer" in arguments_dict:
pattern_option = '-f "%s" -q' % vim.current.buffer.name
elif "--all-buffers" in kwargs.get("arguments", {}):
elif "--all-buffers" in arguments_dict:
pattern_option = '-f "%s" -q' % '" "'.join(b.name for b in vim.buffers)
else: # '--all' or empty means the whole project
pattern_option = None
Expand All @@ -134,8 +141,8 @@ def getContent(self, *args, **kwargs):
dbpath = tmp_dbpath
break

if "--result" in kwargs.get("arguments", {}):
self._result_format = kwargs.get("arguments", {})["--result"][0]
if "--result" in arguments_dict:
self._result_format = arguments_dict["--result"][0]
else:
self._result_format = "ctags"

Expand All @@ -158,22 +165,22 @@ def getContent(self, *args, **kwargs):
content = executor.execute(cmd, env=env)
return content

if "-S" in kwargs.get("arguments", {}):
scope = "--scope %s " % os.path.abspath(kwargs.get("arguments", {})["-S"][0])
if "-S" in arguments_dict:
scope = "--scope %s " % os.path.abspath(arguments_dict["-S"][0])
else:
scope = ""

if "--literal" in kwargs.get("arguments", {}):
if "--literal" in arguments_dict:
literal = "--literal "
else:
literal = ""

if "-i" in kwargs.get("arguments", {}):
if "-i" in arguments_dict:
ignorecase = "-i "
else:
ignorecase = ""

if "--append" not in kwargs.get("arguments", {}) or self._last_result_format is not None:
if "--append" not in arguments_dict or self._last_result_format is not None:
self._pattern_regex = []

# build vim regex, which is used for highlighting
Expand All @@ -196,7 +203,7 @@ def getContent(self, *args, **kwargs):
self._pattern_regex.append(r'\V' + case_pattern + p)
else:
vim_regex = self.translateRegex(case_pattern + p)
if "-g" not in kwargs.get("arguments", {}):
if "-g" not in arguments_dict:
vim_regex = vim_regex.replace('.', r'\w')

self._pattern_regex.append(vim_regex)
Expand Down Expand Up @@ -234,6 +241,13 @@ def getContent(self, *args, **kwargs):
self._executor.append(executor)
content += executor.execute(cmd, env=env)

if auto_jump:
first_two = list(itertools.islice(content, 2))
if len(first_two) == 1:
return first_two
else:
return content.join_left(first_two)

return content

def translateRegex(self, regex, is_perl=False):
Expand Down Expand Up @@ -543,6 +557,7 @@ def _buildCmd(self, dir, **kwargs):
if self._Lf_ExternalCommand:
return self._Lf_ExternalCommand

arguments_dict = kwargs.get("arguments", {})
if self._Lf_UseVersionControlTool:
if self._exists(dir, ".git"):
wildignore = self._Lf_WildIgnore
Expand All @@ -556,7 +571,7 @@ def _buildCmd(self, dir, **kwargs):
for i in wildignore["file"]:
ignore += ' -x "%s"' % i

if "--no-ignore" in kwargs.get("arguments", {}):
if "--no-ignore" in arguments_dict:
no_ignore = ""
else:
no_ignore = "--exclude-standard"
Expand Down Expand Up @@ -616,7 +631,7 @@ def _buildCmd(self, dir, **kwargs):
else:
show_hidden = ""

if "--no-ignore" in kwargs.get("arguments", {}):
if "--no-ignore" in arguments_dict:
no_ignore = "--no-ignore"
else:
no_ignore = ""
Expand Down Expand Up @@ -647,7 +662,7 @@ def _buildCmd(self, dir, **kwargs):
else:
show_hidden = ""

if "--no-ignore" in kwargs.get("arguments", {}):
if "--no-ignore" in arguments_dict:
no_ignore = "-U"
else:
no_ignore = ""
Expand All @@ -673,7 +688,7 @@ def _buildCmd(self, dir, **kwargs):
else:
show_hidden = ""

if "--no-ignore" in kwargs.get("arguments", {}):
if "--no-ignore" in arguments_dict:
no_ignore = "-U"
else:
no_ignore = ""
Expand Down
24 changes: 15 additions & 9 deletions autoload/leaderf/python/leaderf/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ def _accept(self, file, mode, *args, **kwargs):
elif mode == 'h':
lfCmd("split")
elif mode == 'v':
lfCmd("vsplit")
lfCmd("bel vsplit")

kwargs["mode"] = mode
tabpage_count = len(vim.tabpages)
Expand Down Expand Up @@ -1223,29 +1223,35 @@ def selectAll(self):
self._selections[i+1] = id

def startExplorer(self, win_pos, *args, **kwargs):
self.setArguments(kwargs.get("arguments", {}))
arguments_dict = kwargs.get("arguments", {})
self.setArguments(arguments_dict)
self._cli.setNameOnlyFeature(self._getExplorer().supportsNameOnly())
self._cli.setRefineFeature(self._supportsRefine())

if self._getExplorer().getStlCategory() in ["Gtags"] and ("--update" in self._arguments
or "--remove" in self._arguments):
self._getExplorer().getContent(*args, **kwargs)
return
if self._getExplorer().getStlCategory() in ["Gtags"]:
if "--update" in self._arguments or "--remove" in self._arguments:
self._getExplorer().getContent(*args, **kwargs)
return

# lfCmd("echohl WarningMsg | redraw | echo ' searching ...' | echohl NONE")
if self._getExplorer().getStlCategory() in ["Rg", "Gtags"] and "--recall" in self._arguments:
content = self._content
else:
content = self._getExplorer().getContent(*args, **kwargs)
self._getInstance().setCwd(os.getcwd())
if self._getExplorer().getStlCategory() in ["Gtags"] and "--auto-jump" in self._arguments \
and isinstance(content, list) and len(content) == 1:
mode = self._arguments["--auto-jump"][0] if len(self._arguments["--auto-jump"]) else ""
self._accept(content[0], mode)
return

if not content:
lfCmd("echohl Error | redraw | echo ' No content!' | echohl NONE")
return

self._getInstance().setArguments(self._arguments)
if self._getExplorer().getStlCategory() in ["Rg"] and ("-A" in kwargs.get("arguments", {}) \
or "-B" in kwargs.get("arguments", {}) or "-C" in kwargs.get("arguments", {})):
if self._getExplorer().getStlCategory() in ["Rg"] and ("-A" in arguments_dict \
or "-B" in arguments_dict or "-C" in arguments_dict):
self._getInstance().ignoreReverse()

self._getInstance().enterBuffer(win_pos)
Expand All @@ -1260,7 +1266,7 @@ def startExplorer(self, win_pos, *args, **kwargs):
else:
lfCmd("normal! gg")
self._index = 0
self._pattern = kwargs.get("pattern", "") or kwargs.get("arguments", {}).get("--input", [""])[0]
self._pattern = kwargs.get("pattern", "") or arguments_dict.get("--input", [""])[0]
self._cli.setPattern(self._pattern)

self._start_time = time.time()
Expand Down
Loading

0 comments on commit cbf8df2

Please sign in to comment.