Source code for eye.helpers.file_search_plugins.grep

# this project is licensed under the WTFPLv2, see COPYING.txt for details

from logging import getLogger
import os

from eye.helpers.build import SimpleBuilder
from eye.helpers.file_search_plugins.base import registerPlugin, SearchPlugin
from eye.procutils import find_command
from eye.qt import Slot

__all__ = ('AckGrep', 'AgGrep', 'BasicGrep')


LOGGER = getLogger(__name__)


class GrepProcess(SimpleBuilder):
	pattern = r'^(?P<path>.+):(?P<line>\d+):(?P<snippet>.*)$'

	def __init__(self, **kwargs):
		super().__init__(**kwargs)
		self.removeCategory('builder')


class GrepLike(SearchPlugin):
	cmd_base = None

	def __init__(self, **kwargs):
		super().__init__(**kwargs)
		self.runner = GrepProcess()
		self.runner.started.connect(self.started)
		self.runner.warningPrinted.connect(self._got_result)
		self.runner.finished.connect(self.finished)

	def __del__(self):
		self.interrupt()

	@classmethod
	def is_available(cls, path):
		return find_command(cls.cmd_base[0]) is not None

	@classmethod
	def search_root_path(cls, path):
		path = path or '.'
		if os.path.isfile(path):
			path = os.path.dirname(path)
		return path

	@Slot(dict)
	def _got_result(self, d):
		self.found.emit(d)

	def interrupt(self):
		self.runner.interrupt()

	def search(self, path, pattern, case_sensitive=True):
		path = path or '.'
		cmd = list(self.cmd_base)
		if not case_sensitive:
			cmd.append('-i')

		cmd.append(pattern)
		cmd.append(path)
		self.runner.rootpath = path
		self.runner.setWorkingDirectory(path)
		self.runner.run(cmd)


[docs] @registerPlugin class AckGrep(GrepLike): id = 'ack' # ack insists on using stdin despite being given filepaths cmd_base = ['ack-grep', '--nofilter']
[docs] @registerPlugin class AgGrep(GrepLike): id = 'ag' cmd_base = ['ag']
[docs] @registerPlugin class BasicGrep(GrepLike): id = 'rgrep' cmd_base = ['grep', '-n', '-R']
@registerPlugin class RipGrep(GrepLike): id = 'rg' cmd_base = ['rg', '-n']