Why: The kill ring is fundamental to Emacs' copy/paste workflow
Implementation needed:
C-w (kill-region) - cut selectionM-w (kill-ring-save) - copy selectionC-y (yank) - pasteM-y (yank-pop) - cycle through kill ringC-k (kill-line) - kill from cursor to end of lineC++ API needed:
class KillRing {
std::vector<std::string> ring_;
size_t max_size_ = 60;
size_t yank_index_ = 0;
public:
void push(std::string text);
std::string yank();
std::string yank_pop();
};
Why: Emacs' selection system is mark-based, not mouse-based
Implementation needed:
C-SPC or C-@ (set-mark-command) - set markC-x C-x (exchange-point-and-mark) - swap cursor and markC-x h (mark-whole-buffer) - select allC++ API needed:
class Buffer {
std::optional<Position> mark_;
bool mark_active_ = false;
public:
void set_mark(Position pos);
void deactivate_mark();
std::optional<Range> get_region() const;
bool has_active_region() const;
};
Why: Need to work with multiple files efficiently
Implementation needed:
C-x b (switch-to-buffer) - switch buffer with promptC-x C-b (list-buffers) - show buffer listC-x k (kill-buffer) - close bufferLua API:
function list_buffers()
function switch_to_buffer(name)
function kill_buffer(name)
Why: Efficient navigation is key to productivity
Implementation needed:
M-f (forward-word) - move forward by wordM-b (backward-word) - move backward by wordC-v (scroll-up) - page downM-v (scroll-down) - page upM-< (beginning-of-buffer) - go to startM-> (end-of-buffer) - go to endM-g M-g or M-g g (goto-line) - jump to line numberC++ API needed:
void move_forward_word();
void move_backward_word();
void page_up();
void page_down();
void goto_beginning();
void goto_end();
void goto_line(size_t line);
Why: The Emacs way of searching
Implementation needed:
C-s (isearch-forward) - incremental searchC-r (isearch-backward) - reverse incremental searchC-s again to find nextC-g to cancel searchMode: Requires a search mode/state
M-d (kill-word) - delete word forwardM-DEL (backward-kill-word) - delete word backwardM-t (transpose-words) - swap wordsC-t (transpose-chars) - swap charactersM-u (upcase-word) - uppercase wordM-l (downcase-word) - lowercase wordM-c (capitalize-word) - capitalize wordC-x C-u (upcase-region) - uppercase selectionC-x C-l (downcase-region) - lowercase selectionM-; (comment-dwim) - comment or uncomment regionTAB - indent current lineC-j (newline-and-indent) - insert newline and indentM-q (fill-paragraph) - reflow text to column widthC-x r s (copy-to-register)C-x r i (insert-register)C-x r k (kill-rectangle)C-x r y (yank-rectangle)C-x r t (string-rectangle)C-x ( (start-kbd-macro)C-x ) (end-kbd-macro)C-x e (call-last-kbd-macro)C-u C-SPC - jump to previous markFocus on making the editor feel like Emacs:
Make working with multiple files practical:
Add the editing commands power users expect:
Refinements and quality of life:
Add to EditorCore:
class KillRing;
std::unique_ptr<KillRing> kill_ring_;
Add to Buffer:
std::optional<Position> mark_;
bool mark_active_;
Already have std::list<std::shared_ptr<Buffer>> buffers_ but need:
Add search state machine for incremental search
Add word boundary detection to Buffer:
Position find_word_boundary_forward(Position pos);
Position find_word_boundary_backward(Position pos);
Emacs Compatibility Score:
The goal is not 100% compatibility, but capturing the essential Emacs workflow and feeling.