2012-07-07 23 views
4

本月我花了一些時間與Emacs Lisp爭取嘗試自動縮進,以更好地滿足我的需求。令人驚訝的是,大多數縮進代碼的低級別是如何。我見過只是極少數的抽象,例如什麼是自定義函數寫入自動代碼的好的*抽象*?

  • 搜索一個正則表達式的第一個實例,是不是在一個字符串或註釋

我懷疑還有更多有用那裏的抽象將有助於編寫更容易理解和更易於修改的縮進代碼。 (即使我引用的抽象可以改進爲「將這個函數重複應用於這些參數,直到函數返回nil或點不在字符串或註釋中」。)

我正在使用emacs,我已經用vim標記了這個問題,因爲我會從任何地方採取好主意。

如果您想要編程乾淨,設計良好,模塊化的自定義縮進功能,您會使用什麼抽象?(我也很高興地看到指針代碼,你想使用好抽象,或只是被設計得很好。)

回答

4

這聽起來像你正在尋找的東西更高的水平,但淅淅瀝瀝23 SMIE來到 ,這試圖通常解決這個問題。但是它適用於主要模式 開發人員,而不是修改現有的縮進行爲。

編輯:主要的抽象似乎是

  • 一個相當弱的運營商優先分析器通過卑劣伎倆詞法

  • 每個令牌補充得到一個「虛擬縮進的概念',它將出現在開始一行的地方

  • 每個標記都有一個'parent',它是封閉句法結構的開始。

進入成本出現相當大的,而軟件是伴隨着本免責聲明:

在實踐中,[中]默認縮進風格可能不夠好。你會想在許多不同的情況下調整它。

(編輯結束)


你說什麼:

搜索一個正則表達式的第一個實例,是不是在一個字符串或註釋

通過撥打 syntax-ppssre-search-backward即可輕鬆完成

1

一些有用的內置原語,我知道:

  • 縮線至
  • 當前壓痕

有用的原語,盡我所知,不是的一部分emacs的:

  • 後藤以前也非空行
  • 線匹配-P(正則表達式)
  • 內-P(開閉弦弦)

隨意完成這個名單 - 我還沒有找到emacs的壓痕很多資源。

+0

我正在尋找更多*更高級別抽象的想法。 – 2012-07-07 21:04:14

+0

我不確定你是否能夠獲得更高的語言能力。我曾經想過嵌套層次,但是通常可以從前一行的縮進和內容中推導出來 – sabof 2012-07-07 21:14:52

+0

如果你問一般如何進行縮進,你可能想要決定一些上下文(例如塊體,參數列表,字符串,註釋等),一個決定哪一個適用的函數和將爲它們中的每一個執行縮進的函數。 不要急於將現有代碼視爲低級或骯髒技巧。每次按TAB時是否要整個文件進行解析和驗證?可能不會。 – sabof 2012-07-07 23:22:05

1

用於以編程方式在緩衝區周圍導航的好語言不可知的抽象是sexp和語法表:如果模式的語法表構建良好,則可以使用forward-sexpscan-sexps移動。我會說只有當這些不會這樣做時才使用regexp,如果你最終確實有re-search-forward(參見BOUND參數),那麼即使使用它們提供的值也是如此。

同樣使用syntax-ppss可以很容易辨別內部註釋或字符串文字,或處理字符轉義情況。查看已授予的Emacs Lisp信息節點Syntax Tables

,SEXP的可能縮進Lisp的,因爲一切都是一個列表運作良好,可以很容易地問(syntax-ppss),如「多少級深(point)?」的問題。使用塊分隔符如Ruby的beginend,您將進入瘋狂的正則表達式領域。

因此,要在其他語言中獲得(syntax-ppss)的好處,您需要爲其編寫解析器。例如ruby-mode實現了一個解析器,並且在nxml-mode上也有一個令人難以置信的例子。

另請注意,您可以使用with-syntax-table做很多事情,因爲它允許您暫時從不同角度查看緩衝區。這不是縮進,但考慮http://github.com/capitaomorte/autopair這個例子,讓我忽略了一些括號類型現在

(defvar autopair-empty-syntax-table 
    (let ((empty (make-syntax-table))) 
    (dotimes (char 256) 
     (let ((syntax-entry (aref empty char))) 
     (when (and (consp syntax-entry) 
        (or (eq (car (string-to-syntax "(")) 
          (car syntax-entry)) 
         (eq (car (string-to-syntax ")")) 
          (car syntax-entry)))) 
      (modify-syntax-entry char "w" empty)))) 
    empty) 
    "A syntax table no \"(\" or \")\" syntaxes") 

(defun autopair-just-for-delim-syntax-table (delim) 
    "A syntax table that has \"parenthesis\" syntax just for DELIM." 
    (let* ((syntax-entry (aref (syntax-table) delim)) 
     (other-syntax-entry (and syntax-entry 
            (cdr syntax-entry) 
            (aref (syntax-table) (cdr syntax-entry))))) 
    (when (consp other-syntax-entry) 
     (let ((retval (make-syntax-table autopair-empty-syntax-table))) 
     (aset retval delim syntax-entry) 
     (aset retval (cdr syntax-entry) other-syntax-entry) 
     retval)))) 

,在混合[](){}情況下緩衝,這是完全不同的,要求(syntax-ppss)(with-syntax-table (autopair-just-for-delim-syntax-table ?{) (syntax-ppss))其中後者僅計數{}。例如,我不知道你想要縮進哪種語言,但是這可以幫助你合理縮進C塊。

+0

我的模式的語法表理解各種括號,字符串和註釋。它對管理縮進的任何關鍵字一無所知。此外,語法表還不夠強大,無法知道有兩種「單詞」(字母數字或符號)。所以我覺得我對事物的理解不夠,無法跟進你的建議。 +1無論如何:-) – 2012-07-08 21:34:05

+0

我基本上說你必須編寫你自己的解析器,但是語法表'syntax-ppss'和'scan-sexps'有很大的幫助。還編輯了答案以澄清'with-syntax-table'的用處 – 2012-07-08 22:43:42

相關問題