
在之前的文章中我們通過with-current-buffer和buffer-substring實現(xiàn)了一個從指定buffer中拷貝文本到本buffer的功能。這個算是我們?nèi)腴T了跨buffer操作。實際上Emacs為這種需求提供了專門的函數(shù)背景知識Emacs中的跨buffer文本操作的基礎(chǔ)函數(shù)是(insert-buffer-substring BUFFER optional START END)。它用于將參數(shù)中BUFFER指定的緩沖區(qū)中從START到END這個范圍內(nèi)的文本插入到當前緩沖區(qū)的光標所在位置。我們可以用下面的代碼感受一下(defunmy/copy-messages-buffer-to-this()(interactive)(let((message-buffer(get-buffer*Messages*)))(whenmessage-buffer(let((start)(end))(with-current-buffermessage-buffer(save-restriction(widen)(setqstart(point-min))(setqend(point-max))))(insert-buffer-substringmessage-buffer start end)))))因為START和END參數(shù)實際上是對應(yīng)的是BUFFER中的范圍。所以我們需要切入到對應(yīng)的buffer中去獲取這個坐標的最大和最小值?;谶@個函數(shù)我們可以實現(xiàn)很多好用的跨buffer的文本操作例如將當前buffer中的內(nèi)容拷貝到目標buffer中或者將目標buffer中的內(nèi)容替換為我們想要的內(nèi)容等等。因為各種跨buffer的文本操作實在是太頻繁了所以Emacs提供很多有用的函數(shù)下面我列舉一些常用的函數(shù)append-to-buffer: 從當前buffer中提取START和END范圍內(nèi)的文本并追加到參數(shù)BUFFER所指定的緩沖區(qū)的光標位置copy-to-buffer: 從當前 buffer 中提取START和END范圍內(nèi)的文本并對參數(shù)中BUFFER所指定的緩沖區(qū)進行替換上述這些函數(shù)提取的內(nèi)容都帶有文本屬性如果我們只想提取文本本身可以使用buffer-substring-no-properties。查閱相關(guān)文檔我們發(fā)現(xiàn)buffer-substring-no-properties實際上對標的是buffer-substring都是提取當前buffer的文本而不涉及到改變buffer。在跨buffer的函數(shù)中只有insert-buffer-substring是使用底層C函數(shù)編寫的代碼而其他兩個都是依靠這個函數(shù)在lisp層面實現(xiàn)的。所以說關(guān)于跨buffer的文本操作我們只需要掌握基本的insert-buffer-substring其他的函數(shù)我們可以自己實現(xiàn)。這有點像數(shù)學(xué)上學(xué)的時候老師告訴我初中的幾何只有三條基本公理其他的定理和自己利用這三條推導(dǎo)出來。Emacs也是這樣只提供基本的功能其余高級的功能可以自己利用基本函數(shù)實現(xiàn)出來。但是也提供了這些高級函數(shù)的官方實現(xiàn)。練習(xí)今天我們來實現(xiàn)一個日志收集的功能。我們將當前用戶選中的行記錄到一個名為Log-Collection的buffer中該buffer平時不允許寫入只能通過調(diào)用特定的函數(shù)進行收集。如果用戶選擇并激活了一個區(qū)間則提取區(qū)間的內(nèi)容進行激活否則提取當前所在行的文本。(defunmy/collection-log()(interactive)(let((log-buffer(get-buffer-create*Log-Collection*))(cur-buf(current-buffer))(start)(end))(if(use-region-p);; 激活了選區(qū)則按照選取來決定范圍(progn(setqstart(region-beginning))(setqend(region-end)));; 未激活選取則按照光標所在行來決定范圍(progn(setqstart(line-beginning-position))(setqend(line-end-position))))(with-current-bufferlog-buffer(let((inhibit-read-onlyt))(goto-char(point-max))(insert-buffer-substringcur-buf start end)))))總結(jié)本節(jié)介紹的重點函數(shù)只有一個insert-buffer-substring因為功能導(dǎo)致它的參數(shù)比較割裂BUFFER是目標buffer、而START和END對應(yīng)著源buffer的位置。這也就意味著想要成功調(diào)用該函數(shù)無論如何都得使用with-current-buffer進行buffer的切換無法一步到位其余的函數(shù)我們可以自己實現(xiàn)所以就不在這里列舉了。