From e04024343dfea1aadb2d58ac847b66d7843e4a83 Mon Sep 17 00:00:00 2001 From: "D. LoBraico" Date: Mon, 11 Mar 2013 16:36:36 -0500 Subject: [PATCH 1/4] replaces sed with elisp in re-tag action --- mu4e/mu4e-actions.el | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/mu4e/mu4e-actions.el b/mu4e/mu4e-actions.el index 415765a3e..1aacd6748 100644 --- a/mu4e/mu4e-actions.el +++ b/mu4e/mu4e-actions.el @@ -189,6 +189,25 @@ store your org-contacts." this setting on already tagged messages can lead to messages with multiple tags headers") +(defun contains-line-matching (regexp path) + "Determine whether the file at path contains a line matching + the given regexp." + (with-temp-buffer + (insert-file-contents path) + (save-excursion (beginning-of-buffer) + (if (re-search-forward regexp nil t) + t + nil)))) + +(defun replace-first-line-matching (regexp to-string path) + "Replace the first line in the file at path that matches regexp + with the string replace" + (with-temp-file path + (insert-file-contents path) + (save-excursion (beginning-of-buffer) + (if (re-search-forward regexp nil t) + (replace-match to-string nil nil))))) + (defun mu4e-action-retag-message (msg &optional retag-arg) "Change tags of a message. Example: +tag \"+long tag\" -oldtag adds 'tag' and 'long tag', and removes oldtag." @@ -216,15 +235,15 @@ store your org-contacts." (setq tagstr (mapconcat 'identity taglist sep)) (setq tagstr (replace-regexp-in-string "[\\/&]" "\\\\\\&" tagstr)) - (if (string= (shell-command-to-string (format "sed -n '1,/^$/ {/^%s:/I p}' \"%s\"" - mu4e-action-tags-header path)) "") + (if (not (contains-line-matching (concat header ":.*") path)) ;; Add tags header just before the content - (call-process "sed" nil nil nil "-i" - (format "1,/^$/s/^$/%s: %s\\n/I" header tagstr) path) + (replace-first-line-matching "^$" (concat header ": " tagstr "\n") path) - ;; replaces keywords with sed, restricted to the header - (call-process "sed" nil nil nil "-i" - (format "1,/^$/s/^%s:.*$/%s: %s/I" header header tagstr) path)) + ;; replaces keywords, restricted to the header + (replace-first-line-matching + (concat header ":.*") + (concat header ": " tagstr) + path)) (mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", "))) (mu4e-refresh-message path maildir))) From fd53bde69476a572c7c8211db65c06b5569e82d9 Mon Sep 17 00:00:00 2001 From: "D. LoBraico" Date: Mon, 11 Mar 2013 16:36:36 -0500 Subject: [PATCH 2/4] * mu4e: replaces sed with elisp in re-tag action --- mu4e/mu4e-actions.el | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/mu4e/mu4e-actions.el b/mu4e/mu4e-actions.el index 415765a3e..3b507470d 100644 --- a/mu4e/mu4e-actions.el +++ b/mu4e/mu4e-actions.el @@ -189,6 +189,25 @@ store your org-contacts." this setting on already tagged messages can lead to messages with multiple tags headers") +(defun contains-line-matching (regexp path) + "Determine whether the file at path contains a line matching + the given regexp." + (with-temp-buffer + (insert-file-contents path) + (save-excursion (beginning-of-buffer) + (if (re-search-forward regexp nil t) + t + nil)))) + +(defun replace-first-line-matching (regexp to-string path) + "Replace the first line in the file at path that matches regexp + with the string replace" + (with-temp-file path + (insert-file-contents path) + (save-excursion (beginning-of-buffer) + (if (re-search-forward regexp nil t) + (replace-match to-string nil nil))))) + (defun mu4e-action-retag-message (msg &optional retag-arg) "Change tags of a message. Example: +tag \"+long tag\" -oldtag adds 'tag' and 'long tag', and removes oldtag." @@ -214,17 +233,19 @@ store your org-contacts." (setq taglist (sort (delete-dups taglist) 'string<)) (setq tagstr (mapconcat 'identity taglist sep)) - (setq tagstr (replace-regexp-in-string "[\\/&]" "\\\\\\&" tagstr)) - (if (string= (shell-command-to-string (format "sed -n '1,/^$/ {/^%s:/I p}' \"%s\"" - mu4e-action-tags-header path)) "") + (setq tagstr (replace-regexp-in-string "[\\&]" "\\\\\\&" tagstr)) + (setq tagstr (replace-regexp-in-string "[/]" "\\&" tagstr)) + + (if (not (contains-line-matching (concat header ":.*") path)) ;; Add tags header just before the content - (call-process "sed" nil nil nil "-i" - (format "1,/^$/s/^$/%s: %s\\n/I" header tagstr) path) + (replace-first-line-matching "^$" (concat header ": " tagstr "\n") path) - ;; replaces keywords with sed, restricted to the header - (call-process "sed" nil nil nil "-i" - (format "1,/^$/s/^%s:.*$/%s: %s/I" header header tagstr) path)) + ;; replaces keywords, restricted to the header + (replace-first-line-matching + (concat header ":.*") + (concat header ": " tagstr) + path)) (mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", "))) (mu4e-refresh-message path maildir))) From 0d4d7b4ff10d930c2b25deed594078f2fd0ff0d4 Mon Sep 17 00:00:00 2001 From: "D. LoBraico" Date: Sat, 16 Mar 2013 12:40:12 -0500 Subject: [PATCH 3/4] * mu4e: uses correct helper function naming conventions. --- mu4e/mu4e-actions.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mu4e/mu4e-actions.el b/mu4e/mu4e-actions.el index 3b507470d..6558894f1 100644 --- a/mu4e/mu4e-actions.el +++ b/mu4e/mu4e-actions.el @@ -189,7 +189,7 @@ store your org-contacts." this setting on already tagged messages can lead to messages with multiple tags headers") -(defun contains-line-matching (regexp path) +(defun mu4e-contains-line-matching (regexp path) "Determine whether the file at path contains a line matching the given regexp." (with-temp-buffer @@ -199,7 +199,7 @@ store your org-contacts." t nil)))) -(defun replace-first-line-matching (regexp to-string path) +(defun mu4e-replace-first-line-matching (regexp to-string path) "Replace the first line in the file at path that matches regexp with the string replace" (with-temp-file path @@ -237,12 +237,12 @@ store your org-contacts." (setq tagstr (replace-regexp-in-string "[\\&]" "\\\\\\&" tagstr)) (setq tagstr (replace-regexp-in-string "[/]" "\\&" tagstr)) - (if (not (contains-line-matching (concat header ":.*") path)) + (if (not (mu4e-contains-line-matching (concat header ":.*") path)) ;; Add tags header just before the content - (replace-first-line-matching "^$" (concat header ": " tagstr "\n") path) + (mu4e-replace-first-line-matching "^$" (concat header ": " tagstr "\n") path) ;; replaces keywords, restricted to the header - (replace-first-line-matching + (mu4e-replace-first-line-matching (concat header ":.*") (concat header ": " tagstr) path)) From bce9282332d97184c2bde761b2a7aef8737e4c8f Mon Sep 17 00:00:00 2001 From: "D. LoBraico" Date: Sat, 16 Mar 2013 12:42:41 -0500 Subject: [PATCH 4/4] * mu4e: Whoops, uses actual correct helper function naming conventions (~ instead of -) --- mu4e/mu4e-actions.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mu4e/mu4e-actions.el b/mu4e/mu4e-actions.el index 6558894f1..509db3df7 100644 --- a/mu4e/mu4e-actions.el +++ b/mu4e/mu4e-actions.el @@ -189,7 +189,7 @@ store your org-contacts." this setting on already tagged messages can lead to messages with multiple tags headers") -(defun mu4e-contains-line-matching (regexp path) +(defun mu4e~contains-line-matching (regexp path) "Determine whether the file at path contains a line matching the given regexp." (with-temp-buffer @@ -199,7 +199,7 @@ store your org-contacts." t nil)))) -(defun mu4e-replace-first-line-matching (regexp to-string path) +(defun mu4e~replace-first-line-matching (regexp to-string path) "Replace the first line in the file at path that matches regexp with the string replace" (with-temp-file path @@ -237,12 +237,12 @@ store your org-contacts." (setq tagstr (replace-regexp-in-string "[\\&]" "\\\\\\&" tagstr)) (setq tagstr (replace-regexp-in-string "[/]" "\\&" tagstr)) - (if (not (mu4e-contains-line-matching (concat header ":.*") path)) + (if (not (mu4e~contains-line-matching (concat header ":.*") path)) ;; Add tags header just before the content - (mu4e-replace-first-line-matching "^$" (concat header ": " tagstr "\n") path) + (mu4e~replace-first-line-matching "^$" (concat header ": " tagstr "\n") path) ;; replaces keywords, restricted to the header - (mu4e-replace-first-line-matching + (mu4e~replace-first-line-matching (concat header ":.*") (concat header ": " tagstr) path))