用於以編程方式在緩衝區周圍導航的好語言不可知的抽象是sexp和語法表:如果模式的語法表構建良好,則可以使用forward-sexp
和scan-sexps
移動。我會說只有當這些不會這樣做時才使用regexp,如果你最終確實有re-search-forward
(參見BOUND
參數),那麼即使使用它們提供的值也是如此。
同樣使用syntax-ppss
可以很容易辨別內部註釋或字符串文字,或處理字符轉義情況。查看已授予的Emacs Lisp信息節點Syntax Tables
,SEXP的可能縮進Lisp的,因爲一切都是一個列表運作良好,可以很容易地問(syntax-ppss)
,如「多少級深(point)
?」的問題。使用塊分隔符如Ruby的begin
和end
,您將進入瘋狂的正則表達式領域。
因此,要在其他語言中獲得(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塊。
我正在尋找更多*更高級別抽象的想法。 – 2012-07-07 21:04:14
我不確定你是否能夠獲得更高的語言能力。我曾經想過嵌套層次,但是通常可以從前一行的縮進和內容中推導出來 – sabof 2012-07-07 21:14:52
如果你問一般如何進行縮進,你可能想要決定一些上下文(例如塊體,參數列表,字符串,註釋等),一個決定哪一個適用的函數和將爲它們中的每一個執行縮進的函數。 不要急於將現有代碼視爲低級或骯髒技巧。每次按TAB時是否要整個文件進行解析和驗證?可能不會。 – sabof 2012-07-07 23:22:05