[已解决]编程问题,各位大佬进来看下,谢谢!

目前的代码

现有两个函数,分别是:

(defun count-words-in-defun ()
    "计算函数定义中单词总量"
  (beginning-of-defun) ;; 移动位点至函数定义的开头
  (let ((count 0) ;; 函数定义单词总量
        (end
         (save-excursion (end-of-defun) (point)))) ;; 函数定义的末尾的位置
    (save-excursion
      (while (and (< (point) end)
                  ;; regexp-mean:匹配1个或多个构词要素字符或构成符号字符以及后面除了空白字符之外
                  ;; 的字符和再后面加上任意数目的空白字符。
                  (re-search-forward "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" end t))
        (setq count (1+ count))))
    count))

(defun count-words-defun-file ()
    (save-excursion
      (let ((lengths-list))
        (goto-char (point-min))
        (while (re-search-forward "^(defun" nil t)
          (setq lengths-list
                (cons (count-words-in-defun) lengths-list)))
        lengths-list)))

其中count-words-in-defun函数的作用是计算函数定义中的单词或符号总量,而 count-words-defun-file的作用是计算某个文件中所有函数的总单词或符号总量。

遇到的问题

在我调用count-words-defun-file时却好像进入了死循环,问题找了半天没找到是哪段代 码错了,请各位大佬帮忙看下!谢谢!

目前感觉是count-words-defun-file下的while循环出了问题

不知道 count-words 符不符合你的需求。可以选中区域然后count-words

count-words和count-words-defun是完全不同的因为count-words-defun可以处理当函数定义内部出现这种函数名(test-test)时处理成单个符号,所以count-words-defun还能处理符号的个数。

count-words-defun-file 每次re-search-forward结束后,调用count-words-in-defun第一行的beginning-of-defun又跳回去了,自然死循环

1 个赞

对!:joy:看来我得先学习下emacs的调试功能,多谢你的帮忙!

Some note on your code

(defun count-words-in-defun ()
  "计算函数定义中单词总量"
  ;; NOTE: 错误的代码
  (beginning-of-defun) ;; 移动位点至函数定义的开头
  (let ((count 0)      ;; 函数定义单词总量
        ;; NOTE: 可用 (cdr (bounds-of-thing-at-point 'defun)) 获取end
        (end
          (save-excursion (end-of-defun) (point)))) ;; 函数定义的末尾的位置
    (save-excursion
      (while (and
              ;; NOTE: re-search-forward后不需要再做这个判断, 因为保证了不会越界
              (< (point) end)
              ;; regexp-mean:匹配1个或多个构词要素字符或构成符号字符以及后面除了空白字符之外
              ;; 的字符和再后面加上任意数目的空白字符。
              (re-search-forward "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" end t))
        ;; NOTE: 可用(cl-incf count) 代替
        (setq count (1+ count))))
    count))

(defun count-words-defun-file ()
  (save-excursion
    (let ((lengths-list))
      (goto-char (point-min))
      (while (re-search-forward "^(defun" nil t)
        ;; NOTE: 可用 (push (count-words-in-defun) lengths-list) 代替
        (setq lengths-list
              (cons (count-words-in-defun) lengths-list)))
      lengths-list)))

另:可以花点时间了解rx生成正则表达式

多谢大佬对我知识的扩展,我发现一个更好(快捷)的解决方案,就是删除count-words-defun函数中的save-excursion函数,因为我们调用的count-words-defun-file内已经有save-excursion函数确保位点和标记可以复原了。

现在还有个xr,可以把re转成rx格式(终于能看懂了