GNU Emacs là trình soạn thảo văn bản
GNU Emacs không là trình xử lý từ WYSIWYG (thấy gì được nấy).
Thực ra Emacs là tên của một họ các trình soạn thảo văn bản. Emacs nguyên thuỷ được viết bằng ngôn ngữ lập trình của trình soạn thảo văn bản TECO, và chạy trên DEC PDP-10 và -11.
Emacs đầu tiên cho các máy Unix là Gosling Emacs, sau này được thương mại hoá với tên Unipress Emacs. GNU Emacs được viết bởi Richard Stallman, tác giả chính của TECO Emacs nguyên thuỷ.
Yêu cầu chính để một trình soạn thảo văn bản được gọi là "emacs" là nó có thể được mở rộng đầy đủ với một ngôn ngữ lập trình thực, không đơn thuần là một ngôn ngữ macro. Đối với GNU Emacs, ngôn ngữ này là Lisp.
Bài viết này hiện dựa gần như hoàn toàn trên bản "A Tutorial Introduction to GNU Emacs" (http://www.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html) bởi Keith Waclena - nhưng có thể được bổ sung và mở rộng sau này. Bản mới nhất của tài liệu này có ở http://labang.sourceforge.net.
Mỗi lệnh có một tên dài, như kill-line, delete-backward-char, hay self-insert-command. Các lệnh này được liên kết (bind) với một gõ phím để thuận tiện khi soạn thảo. Mỗi cặp gõ phím và lệnh được gọi là liên kết phím (key binding), hoặc gọi tắt là liên kết (binding).
Bộ các liên kết tạo thành bộ lệnh Emacs. Tuy nhiên, chúng có thể được mở rộng và được thay đổi tuỳ thích.
self-insert-command để được điền vào văn bản khi được gõ.
Lệnh tiền tố (prefix command) là một gõ phím đợi một kí tự khác được gõ, tạo thành một cặp gõ phím liên kết với một lệnh. Lệnh tiền tố thường nhóm các lệnh có liên hệ với nhau.
Các lệnh tiền tố tiêu chuẩn là:
Một lệnh của lệnh tiền tố cũng có thể liên kết với một lệnh tiền tố khác.
Đối với một người dùng cụ thể, có những lệnh hiếm khi được dùng, và khi cần có thể tra tên dài của lệnh đó (bằng cách dùng Info, hệ thống giúp đỡ trực tuyến của Emacs) và gõ nó trực tiếp.
Có một lệnh của Emacs có thể được dùng để thi hành lệnh khác bằng cách gõ tên dài của nó: M-x.
Người dùng không cần phải nhớ tất cả các lệnh mà chỉ cần học các lệnh cơ bản và một số lệnh nâng cao phù hợp với nhu cầu của mình.
find-file. Nhắc nhập tên tập tin và đọc tập tin vào bộ đệm cho để biên tập. Nếu tập tin đang được biên tập trong một bộ đệm nào đó, nó chỉ chuyển sang bộ đệm đó mà không đọc tập tin.
save-buffer. Lưu tập tin, hay chính xác hơn là viết bộ đệm hiện tại lên đĩa.
save-some-buffers. Lưu tất cả các bộ đệm đang viếng thăm tập tin, truy vấn từng cái và đưa ra một số tuỳ chọn cho mỗi cái (lưu, không lưu, nhìn qua trước rồi có thể lưu nó, v.v).
switch-to-buffer. Nhắc nhập tên bộ đệm và chuyển bộ đệm của cửa sổ hiện tại sang bộ đệm đó. Tạo bộ đệm rỗng mới nếu tên mới được nhập vào.
list-buffers. Xuất hiện cửa sổ mới liệt kê tất cả bộ đệm với tên, đã thay đổi hay không, kích thước theo byte, chế độ chính và tập tin mà bộ đệm đang viếng thăm.
kill-buffer. Nhắc nhập tên bộ đệm và dỡ bỏ toàn bộ cấu trúc dữ liệu cho bộ đệm đó khỏi Emacs. Nếu bộ đệm đã thay đổi bạn sẽ có cơ hội lưu nó. Lệnh này không xoá tập tin liên hệ, nếu có.
vc-toggle-read-only. Đặt thuộc tính chỉ-đọc hoặc đặt thuộc tính đọc-viết nếu nó đang là chỉ-đọc.
scroll-up. Cuộn tới (về cuối tập tin) một màn hình. Theo mặc định, Emacs chừa 2 hàng từ màn hình trước.
scroll-down. Như C-v, nhưng cuộn ngược.
other-window. Chuyển sang cửa sổ khác. Lặp đi lặp lại lệnh này sẽ di chuyển qua tất cả các cửa sổ, từ trái sang phải và trên xuống dưới.
delete-other-windows. Xoá tất cả các cửa sổ khác, trừ cửa sổ hiện tại. Lệnh này không xoá các bộ đệm và tập tin liên hệ với cửa sổ bị xoá.
delete-window. Xoá cửa sổ hiện tại, thay đổi kích thước các cửa sổ khác cho thích hợp.
split-window-vertically. Chia cửa sổ hiện tại thành hai, theo chiều dọc. Lệnh này tạo một cửa sổ mới, nhưng không tạo bộ đệm mới: cùng một bộ đệm sẽ được xem trong 2 cửa sổ. Điều này giúp xem các phần khác nhau của bộ đệm đồng thời.
split-window-horizontally. Tương tự như C-x 2 nhưng chia cửa sổ theo chiều ngang.
scroll-other-window. Tương tự như C-v, nhưng cuộn các cửa sổ kế tiếp (là cửa sổ mà lệnh C-o sẽ chuyển sang).
emacs
sau đó dùng các lệnh tập tin để đọc tập tin cần biên tập. Thay vào đó, bạn cũng có thể khởi động Emacs với một (hoặc nhiều) tập tin ban đầu:
emacs foo.bar
Để thoát Emacs, dùng lệnh C-x C-c (liên kết với save-buffers-kill-emacs). Nó sẽ đề nghị bạn lưu tất cả bộ đệm và rồi thoát.
Bạn cũng có thể hoãn Emacs (theo nghĩa Unix là dừng nó và đặt vào hậu trường) bằng C-x C-z (liên kết với suspend-emacs). Khởi động lại Emacs tuỳ theo shell, nhưng thông thường dựa trên lệnh fg.
self-insert-command.
Tiểu bộ đệm cũng được gọi là vùng phản hồi (echo area), vì Emacs hiển thị các gõ phím ở đây nếu bạn gõ thật chậm. Thí dụ gõ phím đa kí tự (multi-character keystroke) (như ESC q) với khoảng dừng dài giữa các lần gõ.
C-g
(liên kết với keyboard-quit) dùng để ngắt ngang công việc Emacs đang làm (chẳng hạn như đang hỏi bạn gì đó mà bạn không hiểu), và nó cũng bỏ ngang một phần chuỗi phím vừa được gõ (ví dụ nếu bạn bất cẩn gõ C-x). C-g là kí tự ASCII BEL, do đó khi bạn gõ chuông sẽ kêu.
Vì Emacs có khả năng đệ quy đầy đủ nên đôi khi cần phải gõ C-g vài lần để thoát khỏi chuỗi lệnh đệ quy. Cũng vậy, nếu Emacs thật sự bị treo, có thể gõ nhanh 3 lần C-g để bỏ ngang cái đang làm treo.
command-apropos. Nhắc nhập từ khoá và sau đó liệt kê tất cả các lệnh mang từ khoá đó trong tên dài.
describe-key. Nhắc nhập một gõ phím, và miêu tả lệnh liên kết với phím đó, nếu có.
info. Gọi trình đọc tài liệu siêu văn bản Info.
describe-mode. Miêu tả chế độ chính hiện tại và các liên kết phím (key binding) cụ thể của nó.
finder-by-keyword. Chạy trình duyệt hướng chủ đề tương tác (interactive subject-oriented browser) của các gói Emacs.
help-with-tutorial. Chạy tài liệu hướng dẫn sử dụng Emacs. Rất có ích cho người mới bắt đầu.
undo, bằng cách gõ C-_ (control thanh dưới). C-_ là một kí tự ASCII hợp lệ, nhưng một vài bàn phím không phát sinh được kí tự này, khi đó có thể dùng C-x u.
Emacs có thể undo không giới hạn số lần thay đổi trước, và nó cũng có khả năng redo những gì đã bị undo.
Có một loại đối số thường được chấp nhận đến nỗi có cách đặc biệt để cung cấp nó: đối số số (numeric argument). Nhiều lệnh hiểu đối số số là một yêu cầu lặp lại bấy nhiêu lần. Thí dụ, lệnh delete-char (liên kết với C-d), thông thường xoá một kí tự bên phải con trỏ, sẽ xoá N kí tự nếu được cho đối số số là N. Nó cũng làm việc với các lệnh tự điên vào.
Để cung cấp đối số số, thí dụ 12, cho một lệnh, gõ C-u 12 trước khi gõ lệnh. Nếu gõ chậm rãi, bạn sẽ thấy:
C-u 1 2-ở vùng phản hồi. Sau đó gõ C-d và như vậy bạn đã cho lệnh
delete-char đối số 12. Dấu gạch ngang dẫn đầu biểu thị đối số âm; dấu gạch ngang duy nhất (không có con số theo sau) biểu thị đối số -1. Bỏ ngang một đối số số vừa gõ bằng C-g.
Vì người ta thường không quan tâm precisely chính xác bao nhiêu lần một lệnh được lặp lại, có cách nhanh để lấy đối số số với các biên độ khác nhau. C-u một mình, không có chữ số nào theo sau, tương ứng với đối số số là 4. Lần C-u tiếp theo sẽ nhân nó lên 4, được đối số số 16. Lần C-u tiếp nữa sẽ nhân thêm 4, được đối số số 64, v.v. Vì vậy C-u được gọi là universal-argument (đối số phổ quát).
Tuỳ theo lệnh, đối số số không nhất thiết được hiểu là số lần lặp lại, mà có thể bị bỏ qua hoặc được hiểu là Boolean (sự có mặt của đối số -- bất cứ đối số nào -- và ngược lại là sự vắng mặt của nó), v.v.
quoted-insert, liên kết với C-q. C-q có tác dụng như lệnh tiền tố, nhưng kí tự kế tiếp sẽ được điền vào bộ đệm thay vì thi hành như một lệnh. Thí dụ C-q ESC sẽ điền một Escape.
C-q cũng có thể dùng nhập kí tự bằng cách gõ C-q và theo sau với mã ASCII ở dạng chữ 3 số bát phân.
forward-char. Di chuyển tới (về phải) một kí tự.
backward-char. Di chuyển lùi (về trái) một kí tự.
forward-word. Di chuyển tới một từ.
backward-word. Di chuyển lùi một từ.
next-line. Di chuyển xuống dòng kế tiếp.
previous-line. Di chuyển lên dòng trước.
beginning-of-line. Di chuyển đến đầu dòng hiện tại.
end-of-line. Di chuyển đến cuối dòng hiện tại.
backward-sentence. Di chuyển đến đầu câu hiện tại.
forward-sentence. Di chuyển đến cuối câu hiện tại.
backward-paragraph. Di chuyển đến đầu đoạn hiện tại.
forward-paragraph. Di chuyển đến cuối đoạn hiện tại.
backward-page. Di chuyển đến đầu trang hiện tại.
forward-page. Di chuyển đến cuối trang hiện tại.
beginning-of-buffer. Di chuyển đến đầu bộ đệm.
end-of-buffer. Di chuyển đến cuối bộ đệm.
Ngoài ra, trong hầu hết các chế độ ngôn ngữ lập trình, các chuỗi đặt trong dấu nháy (quoted string) cũng được xem là sexps (có thể là dấu nháy đơn hay nháy kép).
backward-sexp. Di chuyển lùi đến sexp kế tiếp. Nếu con trỏ ở ngay bên phải của dấu ngoặc trái, C-M-b sẽ bíp, vì không có sexp ở phía trái để di chuyển đến: bạn phải di chuyển lên.
forward-sexp. Di chuyển tới sexp kế tiếp. Tương tự như trên nếu con trỏ nằm ngay bên trái của dấu ngoặc phải.
backward-up-list. Di chuyển lùi lên một cấp dấu ngoặc. Nói cách khác, di chuyển sang dấu ngoặc trái của dấu ngoặc đang chứa con trỏ, bỏ qua các sexp trong các cặp dấu ngoặc.
down-list. Di chuyển xuống một cấp dấu ngoặc. Nói cách khác, di chuyển sang bên phải của dấu ngoặc trái kế tiếp, bỏ qua các sexp trong các cặp dấu ngoặc.
beginning-of-defun. Di chuyển đến đầu của defun hiện tại.
end-of-defun. Di chuyển đến cuối của defun hiện tại.
Văn bản bị kill được lưu ở vòng kill (kill ring). Vòng kill giữ N kill cuối, mặc định N là 30, nhưng có thể thay đổi bằng cách thay giá trị cho biến kill-ring-max. Vòng kill đóng vai trò như một fifo khi bạn kill một cái gì đó (sau lần kill thứ 30, kill số 1 sẽ biến mất), nhưng như một cái vòng khi bạn yank chúng trở lại (có thể yank vòng quanh một cách tuần hoàn).
delete-char. Xoá kí tự bên phải (hoặc dưới, nếu con trỏ là khối chứa một kí tự) con trỏ.
delete-backward-char. Xoá kí tự bên trái con trỏ.
kill-word. Kill đến cuối từ phía bên phải con trỏ (tới).
backward-kill-word. Kill đến đâu từ phía bên trái con trỏ (lui).
kill-line. Kill đến cuối dòng hiện tại, không bao gồm kí tự xuống dòng (newline). Vì vậy nếu từ đầu dòng, cần 2 lần C-k để kill toàn bộ dòng và đóng khoảng trắng.
kill-line. Xoá đến đầu dòng hiện tại, không bao gồm newline.
kill-line. Xoá đến đầu của -n dòng trước.
kill-sentence. Kill đến cuối câu hiện tại, bao gồm các newline có trong câu.
kill-sentence. Kill đến đầu câu hiện tại, bao gồm các newline có trong câu.
forward-kill-paragraph và backward-kill-paragraph, nhưng theo mặc định chúng không liên kết với phím nào.
kill-buffer không kill tất cả văn bản trong bộ đệm, nhưng kill toàn bộ cấu trúc dữ liệu bộ đệm: xem Đánh dấu và vùng.
kill-sexp. Kill sexp sau con trỏ.
kill-sexp. Kill sexp trước con trỏ.
backward-kill-sexp, nhưng theo mặc định không liên kết với phím nào.
C-y (yank) lấy (yank) văn bản bị kill gần đây nhất.
M-y (yank-pop) di chuyển sang các văn bản ở các lần kill trước bằng cách thế văn bảng vừa được yank bằng văn bản ở lần kill trước nó. Các lần M-y tiếp theo sẽ di chuyển quanh vòng kill.
Vì Emacs chỉ có một vòng kill (chứ không phải một vòng cho mỗi bộ đệm), bạn có thể kill trong bộ đệm này và yank ở bộ đệm khác.
Xem thêm các lệnh sao chép và di chuyển các vùng văn bản ngẫu nhiên (không phải là đối tượng văn bản - textual object) tại Đánh dấu và vùng.
isearch-forward): tìm kiếm luỹ tiến (incremental search): Emacs tìm kiếm tích luỹ số từ trong chuỗi bạn gõ vào. Để dùng việc tìm kiếm, gõ RET hoặc một lệnh nào khác. Lặp lại C-s để nhảy tới kết quả phù hợp kế tiếp; để nhảy ngược lại, gõ C-r; gõ DEL để xoá và thay đổi chuỗi đang tìm kiếm.
C-r(isearch-backward): tìm kiếm theo chiều lui. (Dùng C-r để tìm kết quả phù hợp kế tiếp và C-s để đổi chiều tìm kiếm.)
Tìm kiếm không luỹ tiến: C-s RET text RET, trong đó text là văn bản cần tìm.
Tìm kiếm theo từ (word search): C-s RET C-w word word word RET tìm kiếm một chuỗi gồm một hoặc nhiều từ, bất kể chúng được phân cách như thế nào (bằng chữ số hay kết hợp kí tự xuống dòng và khoảng trắng).
Emacs cũng có thể tìm kiếm (không) luỹ tiến với biểu thức chính quy (regular expressions).
query-replace (M-%): nhắc bạn nhập văn bản thay thế, và văn bản để thay thế cho nó, và rồi tìm và thay trong bộ đệm hiện tại. query-replace có tính tương tác: ở mỗi lần phù hợp, bạn được nhắc để quyết định sẽ làm gì với các tuỳ chọn sau:
query-replace mà không thực hiện thay thế.
query-replace.
query-replace.
Có một số lệnh thay thế khác nên xem qua, gồm replace-string (thay thế không điều kiện đơn giản), replace-regexp và query-replace-regexp (dùng biểu thức thường quy), và tags-query-replace (thay thế tất cả identifiers trong một bộ tập tin mã nguồn).
query-replace và các lệnh thay thế khác theo mặc định khéo về chữ hoa-thường. Thí dụ nếu bạn đang thay thế foo bằng bar, nếu Emacs tìm thấy Foo, nó sẽ thay bằng Bar; nếu tìm thấy FOO, nó sẽ thay bằng BAR, v.v.
Vùng là văn bản nằm giữa điểm (point) và dấu (mark). Điểm thực ra là thuật ngữ Emacs gọi con trỏ. Còn dấu được thiết lập bằng lệnh C-@ (set-mark-command). Lệnh này thiết lập dấu ngay tại điểm đang đứng, và sau đó có thể di chuyển điểm để được vùng.
Mỗi bộ đệm có một điểm và dấu riêng biệt, nên có một vùng riêng biệt. (Cũng có thể không có dấu trong bộ đệm, và vì vậy không có vùng).
Vùng hoàn toàn như nhau bất kể điểm đến trước hay dấu đến trước.
Thông thường vùng không nhìn thấy (nhưng xem C-x C-x). Tuy nhiên nếu bạn chạy Emacs dưới hệ thống cửa sổ (windowing system), bạn có thể thi hành lệnh M-x transient-mark-mode để làm cho (bật/tắt) vùng thấy được.
Nhiều lệnh di chuyển điểm đi một khoảng cách (như M-< và C-s) và dấu được thiết lập tại vị trí mà chúng bắt đầu di chuyển từ đó. Bạn sẽ thấy "Mark set" ở vùng phản hồi khi điều này xảy ra.
Khi dùng Emacs dưới hệ thống cửa sổ như X, chuột có thể được dùng để quét vùng.
Có một số lệnh đặc biệt dùng để xác định vùng.
mark-word. Thiết lập vùng chứa từ kế tiếp, hoặc từ điểm đến cuối từ hiện tại, nếu đang ở giữa từ.
mark-paragraph. Thiết lập vùng chứa đoạn hiện tại.
mark-sexp. Thiết lập vùng chứa cùng sexp mà lệnh C-M-f sẽ di chuyển tới.
mark-defun. Thiết lập vùng chứa defun hiện tại.
mark-page. Thiết lập vùng chứa trang hiện tại.
mark-whole-buffer. Thiết lập vùng chứa toàn bộ bộ đệm.
exchange-point-and-mark. Tráo đổi điểm và vùng. Lặp lại nhanh lệnh này sẽ giúp dễ thấy phạm vi của vùng.
kill-region. Kill vùng. Khi đó nó sẽ vào vòng kill.
kill-ring-save. Lưu vùng hiện tại vào vòng kill mà không lấy bỏ khỏi bộ đệm. Điều này tương đương với gõ C-w C-y.
indent-rigidly. Canh lề cứng vùng bởi số kí tự (cột) được cung cấp làm đối số số (mặc định là 1 cột).
downcase-region. Chuyển toàn bộ văn bản trong vùng thành chữ thường. Theo mặc định lệnh này bị bất hoạt.
upcase-region. Chuyển toàn bộ văn bản trong vùng thành chữ hoa. Theo mặc định lệnh này bị bất hoạt.
fill-region. Điền, nghĩa là canh thẳng lề với bờ phải không đều, tất cả các đoạn trong vùng.
GNU Emacs Manual (mirror 1: dạng Info Nodes)