Skip to content

Could you make wgrep support helm-grep-mode #11

jixiuf opened this Issue Nov 25, 2012 · 10 comments

3 participants

jixiuf commented Nov 25, 2012
(wgrep-to-grep-mode)---> wgrep-to-origin-mode

and wgrep-prepare-to-edit should define a variable like wgrep-results-parser

jixiuf commented Nov 25, 2012

I have write these code

(defun wgrep-helm-grep-setup ()
  ;; helm-grep-mode prints a column number too, so we catch that
  ;; if it exists.  Here \2 is a colon + whitespace separator.  This
  ;; might need to change if (caar grep-regexp-alist) does.
  (set (make-local-variable 'wgrep-line-file-regexp) "^\\([a-zA-Z]?:?[^:]*\\):\\([0-9]+\\):\\(.*\\)")
  (set (make-local-variable 'wgrep-results-parser) 'wgrep-helm-grep-prepare-command-results)

  (define-key helm-grep-mode-map wgrep-enable-key 'wgrep-change-to-wgrep-mode)
  (add-to-list 'wgrep-acceptable-modes 'helm-grep-mode)

(defun wgrep-prepare-to-edit-4-helm-grep ()
  (unless wgrep-prepared
      (let ((inhibit-read-only t)
            (wgrep-inhibit-modification-hook t)
            buffer-read-only beg end onematched
            header-beg header-end found-footer-beg
        ;; Set read-only grep result header
        (setq header-beg (point-min))
        (goto-char (point-min))
        (while (not (eobp))
          (setq beg (point-at-bol) )
          (setq end (point-at-eol))
          (if  (string-match wgrep-line-file-regexp (buffer-substring beg end))
                (unless onematched
                  (setq header-end beg)
                  (put-text-property header-beg header-end 'wgrep-header t)
                  (setq onematched t)
            (put-text-property beg end 'read-only t)
            (when onematched
              (unless found-footer-beg
                (put-text-property beg (point-max) 'wgrep-footer t)
                (setq found-footer-beg beg))
          (forward-line 1)

        (when  (not  found-footer-beg)
          (put-text-property  (1- (point-max)) (point-max) 'wgrep-footer t)

        (setq wgrep-prepared t)))))

(defun wgrep-helm-grep-prepare-command-results ()
  (let ((cache (make-hash-table)))
    (while (not (eobp))
       ((looking-at wgrep-line-file-regexp)
        (let* ((f   (match-string 1))
              (helm-realvalue  (get-text-property 0 'helm-realvalue f))
              (start (match-beginning 0))
              (end (match-end 0))
          (string-match wgrep-line-file-regexp  helm-realvalue )
          (setq filename (match-string 1   helm-realvalue))
          (setq line (string-to-number (match-string 2 helm-realvalue )))

          ;; check relative path grep result
          ;; grep result may be --context result with number between 2 colon.
          ;; ./filename-1-:10:
          ;; that make misunderstand font-locking
          ;; check file existence decrease risk of the misunderstanding.
          (when (or (gethash filename cache nil)
                    (and (file-exists-p filename)
                         (puthash filename t cache)))
            (put-text-property start end 'wgrep-line-filename filename)
            (put-text-property start end 'wgrep-line-number line)
            ;; handle backward and forward following options.
            ;; -A (--after-context) -B (--before-context) -C (--context)
              (wgrep-prepare-context-while filename line nil))
            (wgrep-prepare-context-while filename line t)
            ;; end of context output `--'.
            (forward-line -1))))
       ((looking-at "^--+$")
         (line-beginning-position) (line-end-position)
         'wgrep-ignore t)))
      (forward-line 1))))

;;;###autoload(add-hook 'helm-grep-mode-hook 'wgrep-helm-grep-setup)
(add-hook 'helm-grep-mode-hook 'wgrep-helm-grep-setup)

;; For `unload-feature'
(defun wgrep-helm-unload-function ()
  (remove-hook 'helm-grep-mode-hook 'wgrep-helm-grep-setup))

and when I pess C-cC-c
it doesn't work
and I found , in wgrep-finish-edit it call (wgrep-to-grep-mode)
I think this should be wgrep-to-helm-grep-mode or something like this , it's not easy for me to modify wgrep.el .
so could you help me .


I haven't used `helm-grep' before, but I'm now trying to `helm-do-grep'.

After that, I recognize this is not familiar to wgrep.
I have been realized that `helm' is designed to use only interactive. (at minibuffer)

How about switch to use original `grep' from helm-grep:

(define-key helm-c-grep-map "\C-c\C-w" 'helm-grep-switch-to-grep)

(defun helm-grep-switch-to-grep ()
  (let ((buf (grep helm-grep-last-cmd-line)))
    (switch-to-buffer buf)))

And of course, call `wgrep-change-to-wgrep-mode'.

This is not a direct answer, but I hope you will find it helpful.

jixiuf commented Nov 26, 2012
you can save the helm grep session in a buffer (default named "hgrep') by C-xC-s ,
and the format of hgrep buffer looks like this (similiar to the grep-mode buffer grep )

-*- mode: helm-grep -*-

Grep Results for `Copy':

auto-complete+.el:3:;; Copyright (C) 2009 ahei
auto-complete+.el:33:;; Copy auto-complete+.el to your load-path and add to your .emacs:
auto-document.el:4:;; Copyright (C) 2009  rubikitch
batch-mode.el:2:;;; Copyright (C) 2002, Agnar Renolen <>
compile-dwim.el:3:;; Copyright (C) 2007 Free Software Foundation, Inc.
diff-mode-.el:7:;; Copyright (C) 2004-2011, Drew Adams, all rights reserved.
etags-table.el:3:;; Copyright (C) 2008  Scott Frazer

M-x:helm-do-grep then select a directory ,and use "Copy" as regexp pattern then press C-xC-s ,
then content in "helm grep* buffer is saved to hgrep buffer .


Please try BR-helm-support branch.

Overwrote hgrep buffer is not supported although.
Because `default-directory' may indicate wrong directory.

jixiuf commented Nov 28, 2012
--- this regexp is used in helm-grep.el
 (set (make-local-variable 'wgrep-line-file-regexp) "^\\([a-zA-Z]?:?[^:]*\\):\\([0-9]+\\):\\(.*\\)") 

%% I think we should parse helm-grep-mode result ,in another function  . 
  (set (make-local-variable 'wgrep-results-parser) 'wgrep-helm-grep-prepare-command-results)

you can get the absolute filepath like this .

text in helm-grep-buffer , has a text property named helm-realvalue ,
in the helm-realvalue , file is an absolute path

(let ((cache (make-hash-table)))
    (while (not (eobp))
       ((looking-at wgrep-line-file-regexp)
        (let* ((f   (match-string 1))
              (helm-realvalue  (get-text-property 0 'helm-realvalue f))     %%  absolutepath:linenum:matched_content
              (start (match-beginning 0))
              (end (match-end 0))
          (string-match wgrep-line-file-regexp  helm-realvalue )
          (setq filename (match-string 1   helm-realvalue))
          (setq line (string-to-number (match-string 2 helm-realvalue )))

and in wgrep-finish-edit I think you should not call (wgrep-to-grep-mode),directly ,
you can define another variable like wgrep-results-parser

and With prefix C-u for helm-do-grep , you can grep a directory recursively.

and thanks for your great work .


Thanks to bring wgrep to helm.
The regexp above is now in a defvar named helm-grep-split-line-regexp

You can get the full path of file in the help-echo property:

(get-text-property (point-at-bol) 'help-echo)
@mhayashi1120 mhayashi1120 added a commit that referenced this issue Nov 29, 2012
@mhayashi1120 Issue #11
revert `wgrep-acceptable-modes' for backward compatibility
remove solved todo

@jixiuf Please try it, and I'm waiting for any report.

jixiuf commented Nov 29, 2012

great . it works very well.
I find a bug , when helm-buffer contains special chars , maybe it's helm-grep bug , it can't handle chinese chars very well on windows , I have never test on linux ..


I don't know well about helm, but wgrep works well on my Japanese environment.

Close this issue anyway. Please open new issue if the Chinese problem is more clearly.
Thanks for your many comments!

@mhayashi1120 mhayashi1120 added a commit that referenced this issue Dec 2, 2012
@mhayashi1120 Issue #11
* add new text property `wgrep-fn-*' prepare for file renaming
* parser for helm-grep
* remove dependencies from wgrep-ack.
* make obsolete `wgrep-acceptable-modes' no need to check such thing.
* wgrep-to-grep-mode -> wgrep-to-original-mode
  may back to wrong mode and map
* fix unable cleanup temporary buffer.
* mark ignore if output result is not a valid grep line
  ex: Binary file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.