【问题标题】:what's the use for paredit-convolute-sexp in paredit modeparedit 模式下 paredit-convolute-sexp 有什么用
【发布时间】:2013-08-12 16:25:05
【问题描述】:

它改变了

(a b c d (1 2 |3 4) ha ha ha)

进入

|(1 2 (a b c d 3 4 ha ha ha))

这种转换有什么用?

【问题讨论】:

    标签: elisp paredit


    【解决方案1】:

    也只是关于实际使用的快速补充,您可能想查看本教程的 1:40 分钟: http://emacsrocks.com/e14.html

    呼叫 M-?将光标放在do-something的开头拓宽了let的范围,由此而来:

    (defun my-other-command ()
      (when (and (this-predicate)
                 (that-predicate))
        (let ((v (calculate-v))
              (x (calculate-x)))
          (do-something)
          (do-some-more)
          (do-a-third-thing))))
    

    直接到这里:

    (defun my-other-command ()
      (let ((v (calculate-v))
            (x (calculate-x)))
        (when (and (this-predicate)
                   (that-predicate))
          (do-something)
          (do-some-more)
          (do-a-third-thing))))
    

    干杯! 安德烈斯

    【讨论】:

    • @MihaiMaruseac 实际上,Andres 的帖子确实回答了这个问题。普通读者可能不清楚,但M-? 调用paredit-convolute-sexp。因此,他说卷积对于扩大 let 构造的范围很有用,这实际上比 SheetJS 目前接受的答案更有帮助。
    • @MihaiMaruseac Andres 的帖子被标记为“2015 年 1 月 30 日 15:22”,而您的评论在一个小时零一分钟后发表。他的帖子上也没有“已编辑...”链接。最后,问题本身似乎没有改变(2013 年 8 月 12 日 16:25)。我错过了什么?
    • 我不知道,但我删除了我的评论,因为现在它没有用了。
    【解决方案2】:

    严格来说,它用于反转内部表达式的嵌套。

    举个例子:

    (let [foo bar] (if a b| c))
    

    变成

    (if a b (let [foo bar]| c))
    

    至于用例,我从未有过具体的实际用途,但它是更大宏的一个很好的构建块

    【讨论】:

    • 最好有一个更大的宏示例,其中使用卷积作为构建块。
    【解决方案3】:

    添加到 Nirk 的答案

    对于 smartparens 用户,M-x sp-prefix-save-excursion M-x sp-convolute-sexp 更改

    (let [foo bar] (if a b| c))
    

    (let [foo bar] (if a b |c))
    

    进入

    (if a b (let [foo bar] |c))
    

    对于 paredit 用户,M-x paredit-convolute-sexp 更改

    (let [foo bar] (if a b| c))
    

    (let [foo bar] (if a b |c))
    

    进入

    |(if a b(let [foo bar]  c))
    

    |(if a b (let [foo bar] c))
    

    对于两者都不使用的人,如果包含,您仍然可以使用卷积命令

    (require 'paredit)
    (require 'smartparens)
    

    在 init 文件中,仅这两行不会将您的 Emacs 设置为使用 paredit 模式或 smartparens 模式,所以一切都很好。如果您从包存档安装 paredit 包,自动加载文件可能会或可能不会将 Emacs 设置为使用 paredit 模式,并且 paredit 没有自定义界面。如果你安装了 smartparens 包,无论 autoloads 文件做什么,你都可以使用自定义界面将 smartparens-global-mode 设置为 nil,如果它的默认值不是 nil(虽然现在默认是 nil)。

    【讨论】:

      【解决方案4】:

      大多数示例都显示范围缩小,但如果您意识到您在 if 中有一个 let 表单并意识到您需要在 if 的另一个分支中使用这些绑定,我希望您很可能会使用它形式也是如此。

      假设你是一个巨魔,你发现了一个看起来很美味的小偷。

      (defn eat-hobbit [hobbit]
        (if (is-cooked? hobbit)
          (eat! hobbit)
          (let [is-fat (< too-greasy (:fat-content hobbit))]
            (if is-fat
              (eat! (deep-fry hobbit))
              (eat! (saute hobbit))))))
      

      您意识到您可能应该做出更好的健康选择,而不仅仅是吃掉您遇到的所有霍比特人,无论是否煮熟,因此您决定首先根据霍比特人的脂肪含量来决定是否吃。在决定吃之前你需要知道is-fat!所以,你想提升let。将光标放在(let [is-fat ...]M-? 中的绑定向量之后(并用M-j M-q 清理空白):

      (defn eat-hobbit [hobbit]
        (let [is-fat (< too-greasy (:fat-content hobbit))]
          (if (is-cooked? hobbit)
            (eat! hobbit)
            (if is-fat
              (eat! (deep-fry hobbit))
              (eat! (saute hobbit))))))
      

      您还没有做出更好的食物选择,但现在绑定在正确的范围内,可以做出更好的决定。

      让我们再试一次。我们真的应该先问霍比特人是不是胖,所以把光标放在(if is-fatM-?之后(再用M-j M-q清理):

      (defn eat-hobbit [hobbit]
        (let [is-fat (< too-greasy (:fat-content hobbit))]
          (if is-fat
            (if (is-cooked? hobbit)
              (eat! hobbit)
      
              (eat! (deep-fry hobbit))
              (eat! (saute hobbit))))))
      

      嗯。这还不是很有效——if 中有一个额外的表单——但它非常接近我们想要的位置。在这一点上,我们可以轻松地使用更常见的 paredit 绑定来 barf、转置和/或杀死 if 中的额外形式,这取决于我们对健康饮食的意图有多真诚。为简洁起见,我们还可以将两个 if 表单拼接在一起。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-19
        • 1970-01-01
        • 2023-03-11
        相关资源
        最近更新 更多