文本替换的lisp语句

谢谢指点!尽量不用第三方库。

发现这段代码其实我昨天已经测试出来了,心中窃喜。问题不在这里。

问题出在循环上面。如果将这段代码运用在目录上,发现有些文件执行一次,有些文件执行N(=文件数)次。

    (dolist (file real-files)
      (with-temp-buffer
        (insert-file-contents file)
        (goto-char (point-min))
        (search-forward str nil t)
        (goto-char (point))
        (kill-whole-line)
        (goto-line line)
        (yank)
        (write-file file)
        ))))

这个代码高亮今天刚研究出来,搜了论坛,没找到解决办法,最后在阅读上面代码的源文件发现的,即:增加emacs-lisp 和 ,但好像只高亮了一个词。

问题:

1,之前的dolist循环能用,这次为何会在文件中重复执行?

2,with-temp-buffer和with-temp-file file 都能执行,结果也一样,请问有区别吗?

3,write-file文件之后,需要关闭文件吗?kill-buffer也没有改变重复执行。

1.代码高亮就是用markdown的代码块语法,你浏览器搜索一下就知道了。

2.write-file和with-temp-file都可以写文件。区别是write-file做了一些额外的操作,所以建议用后者,速度更快。具体区别看这里

3.没有明白你说的重读执行是什么意思。 确实有重复的问题,我找找原因。

4.上面的代码里的 (goto-char (point))可以删掉。(point)返回的就是当前光标的位置,然后将光标移动到当前的位置,等于什么都没做。

就很奇怪,我猜应该是kill-ring的问题:短时间内的多次kill会记录到一次kill-ring中,就会导致yank的内容不断叠加。看来不能用这种方法,还是用变量保存kill的值靠谱。

1 个赞
(kill-whole-line)

可以用

(setq line (buffer-substring (line-beginning-posiion) (line-end-position)))

你得先在let里声明line

2 个赞

大量文件替换还是sed方便

(defun my-get-real-files-in-dir (dir)
  (let ((real-files)
	    (files (directory-files dir)))
    (dolist (file files)
      (unless (or (string= "." (substring file 0 1))
		          (string= "#" (substring file 0 1))
		          (string= "~" (substring file -1)))
	    (push file real-files)))
    real-files))

(defun my-move-matched-text-line-in-dir (dir)
  "move string match line to the second line."
  (interactive "fchoose a directory: ")
  (let ((line 2)
	    (str "某汉字")
	    (files (my-get-real-files-in-dir dir))
	    (line-str ""))
    (dolist (filename files)
      (setq file (concat dir filename))
      (with-temp-buffer
	    (insert-file-contents file)
	    (goto-char (point-min))
	    (search-forward str nil t)
	    (setq line-str (buffer-substring (line-beginning-position) (line-end-position)))
	    (kill-whole-line)
	    (goto-line line)
	    (insert (concat line-str "\n"))
	    (write-region (point-min) (point-max) file)))))
1 个赞

goto-line之后还得goto-char到最后

killline 没有必要了

   (search-forward str nil t)

会search不到,一般都用when包一层

顺利执行,看来是因为yank不可靠,又学到了,谢谢纠正错误!

想在emacs中达成目标,同时也在学习elisp,有个小目标、小练习,能逐渐增长编程能力。

还有一个疑问:说两句话就能搞懂的事情,为何用那么多行语句才能让电脑明白且执行。 嘿嘿 emacs 和 word 是两个不同软件,并不能相互代替,不过就文档编写来说,用 emacs 的 org-mode 简直不要太爽,写完了一键生成 txt 版本,html 版本,word 版本, pdf 版本,要啥给啥,刺激的很呢。