mhayashi1120 / Emacs-wgrep

Writable grep buffer and apply the changes to files

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Could you make wgrep support helm-grep-mode

jixiuf opened this issue · comments

(wgrep-to-grep-mode)---> wgrep-to-origin-mode

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

I have write these code


;;;###autoload
(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)
  (wgrep-setup-internal))

(defun wgrep-prepare-to-edit-4-helm-grep ()
  (unless wgrep-prepared
    (save-excursion
      (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))
        (end-of-line)
        (while (not (eobp))
          (setq beg (point-at-bol) )
          (setq end (point-at-eol))
          (if  (string-match wgrep-line-file-regexp (buffer-substring beg end))
              (progn
                (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)
          (end-of-line)
          )

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

        (wgrep-prepare-context)
        (setq wgrep-prepared t)))))



(defun wgrep-helm-grep-prepare-command-results ()
  (let ((cache (make-hash-table)))
    (while (not (eobp))
      (cond
       ((looking-at wgrep-line-file-regexp)
        (let* ((f   (match-string 1))
              (helm-realvalue  (get-text-property 0 'helm-realvalue f))
              filename
              line
              (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)
            (save-excursion
              (wgrep-prepare-context-while filename line nil))
            (wgrep-prepare-context-while filename line t)
            ;; end of context output `--'.
            (forward-line -1))))
       ((looking-at "^--+$")
        (put-text-property
         (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 ()
  (interactive)
  (let ((buf (grep helm-grep-last-cmd-line)))
    (helm-keyboard-quit)
    (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.

https://github.com/emacs-helm/helm/wiki#wiki-savegrepsession
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 )
filename:linenum:MatchedLines

-*- 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 <agnar.renolen@emap.no>
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.

https://github.com/mhayashi1120/Emacs-wgrep/tree/BR-helm-support

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

--- 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))
      (cond
       ((looking-at wgrep-line-file-regexp)
        (let* ((f   (match-string 1))
              (helm-realvalue  (get-text-property 0 'helm-realvalue f))     %%  absolutepath:linenum:matched_content
              filename
              line
              (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)

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

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!