From 94c7243ba432a96be1541253013669b18eed713e Mon Sep 17 00:00:00 2001 From: Leo Liu Date: Sun, 12 Sep 2010 13:06:19 +0200 Subject: [PATCH] * lisp/net/rcirc.el (rcirc-server-commands, rcirc-client-commands) (rcirc-completion-start): New variables. (rcirc-nick-completions): Rename to rcirc-completions. (rcirc-nick-completion-start-offset): Delete. (rcirc-completion-at-point): New function for constructing completion data for both nicks and irc commands. Add to completion-at-point-functions in rcirc mode. (rcirc-complete): Rename from rcirc-nick-complete; use rcirc-completion-at-point. (defun-rcirc-command): Update rcirc-client-commands. Fixes: debbugs:6076 --- lisp/ChangeLog | 13 +++++++ lisp/net/rcirc.el | 113 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1088bf432c4..ddbc0b43eed 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,16 @@ +2010-09-12 Leo + + * net/rcirc.el (rcirc-server-commands, rcirc-client-commands) + (rcirc-completion-start): New variables. + (rcirc-nick-completions): Rename to rcirc-completions. + (rcirc-nick-completion-start-offset): Delete. + (rcirc-completion-at-point): New function for constructing + completion data for both nicks and irc commands. Add to + completion-at-point-functions in rcirc mode. + (rcirc-complete): Rename from rcirc-nick-complete; use + rcirc-completion-at-point. + (defun-rcirc-command): Update rcirc-client-commands. + 2010-09-11 Glenn Morris * emacs-lisp/bytecomp.el (byte-compile-file): Create .elc files diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 9af6057c20c..093892a1100 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -774,42 +774,64 @@ If SILENT is non-nil, do not print the message in any irc buffer." (setq rcirc-input-ring-index (1- rcirc-input-ring-index)) (insert (rcirc-prev-input-string -1)))) -(defvar rcirc-nick-completions nil) -(defvar rcirc-nick-completion-start-offset nil) - -(defun rcirc-complete-nick () - "Cycle through nick completions from list of nicks in channel." +(defvar rcirc-server-commands + '("/admin" "/away" "/connect" "/die" "/error" "/info" + "/invite" "/ison" "/join" "/kick" "/kill" "/links" + "/list" "/lusers" "/mode" "/motd" "/names" "/nick" + "/notice" "/oper" "/part" "/pass" "/ping" "/pong" + "/privmsg" "/quit" "/rehash" "/restart" "/service" "/servlist" + "/server" "/squery" "/squit" "/stats" "/summon" "/time" + "/topic" "/trace" "/user" "/userhost" "/users" "/version" + "/wallops" "/who" "/whois" "/whowas") + "A list of user commands by IRC server. +The value defaults to RFCs 1459 and 2812.") + +;; /me and /ctcp are not defined by `defun-rcirc-command'. +(defvar rcirc-client-commands '("/me" "/ctcp") + "A list of user commands defined by IRC client rcirc. +The list is updated automatically by `defun-rcirc-command'.") + +(defun rcirc-completion-at-point () + "Function used for `completion-at-point-functions' in `rcirc-mode'." + (let* ((beg (save-excursion + (if (re-search-backward " " rcirc-prompt-end-marker t) + (1+ (point)) + rcirc-prompt-end-marker))) + (table (if (and (= beg rcirc-prompt-end-marker) + (eq (char-after beg) ?/)) + (delete-dups + (nconc + (sort (copy-sequence rcirc-client-commands) 'string-lessp) + (sort (copy-sequence rcirc-server-commands) 'string-lessp))) + (rcirc-channel-nicks (rcirc-buffer-process) rcirc-target)))) + (list beg (point) table))) + +(defvar rcirc-completions nil) +(defvar rcirc-completion-start nil) + +(defun rcirc-complete () + "Cycle through completions from list of nicks in channel or IRC commands. +IRC command completion is performed only if '/' is the first input char." (interactive) (if (eq last-command this-command) - (setq rcirc-nick-completions - (append (cdr rcirc-nick-completions) - (list (car rcirc-nick-completions)))) - (setq rcirc-nick-completion-start-offset - (- (save-excursion - (if (re-search-backward " " rcirc-prompt-end-marker t) - (1+ (point)) - rcirc-prompt-end-marker)) - rcirc-prompt-end-marker)) - (setq rcirc-nick-completions - (let ((completion-ignore-case t)) - (all-completions - (buffer-substring - (+ rcirc-prompt-end-marker - rcirc-nick-completion-start-offset) - (point)) - (mapcar (lambda (x) (cons x nil)) - (rcirc-channel-nicks (rcirc-buffer-process) - rcirc-target)))))) - (let ((completion (car rcirc-nick-completions))) + (setq rcirc-completions + (append (cdr rcirc-completions) (list (car rcirc-completions)))) + (let ((completion-ignore-case t) + (table (rcirc-completion-at-point))) + (setq rcirc-completion-start (car table)) + (setq rcirc-completions + (all-completions (buffer-substring rcirc-completion-start + (cadr table)) + (nth 2 table))))) + (let ((completion (car rcirc-completions))) (when completion - (delete-region (+ rcirc-prompt-end-marker - rcirc-nick-completion-start-offset) - (point)) - (insert (concat completion - (if (= (+ rcirc-prompt-end-marker - rcirc-nick-completion-start-offset) - rcirc-prompt-end-marker) - ": ")))))) + (delete-region rcirc-completion-start (point)) + (insert + (concat completion + (cond + ((= (aref completion 0) ?/) " ") + ((= rcirc-completion-start rcirc-prompt-end-marker) ": ") + (t ""))))))) (defun set-rcirc-decode-coding-system (coding-system) "Set the decode coding system used in this channel." @@ -827,7 +849,7 @@ If SILENT is non-nil, do not print the message in any irc buffer." (define-key rcirc-mode-map (kbd "RET") 'rcirc-send-input) (define-key rcirc-mode-map (kbd "M-p") 'rcirc-insert-prev-input) (define-key rcirc-mode-map (kbd "M-n") 'rcirc-insert-next-input) -(define-key rcirc-mode-map (kbd "TAB") 'rcirc-complete-nick) +(define-key rcirc-mode-map (kbd "TAB") 'rcirc-complete) (define-key rcirc-mode-map (kbd "C-c C-b") 'rcirc-browse-url) (define-key rcirc-mode-map (kbd "C-c C-c") 'rcirc-edit-multiline) (define-key rcirc-mode-map (kbd "C-c C-j") 'rcirc-cmd-join) @@ -948,6 +970,9 @@ This number is independent of the number of lines in the buffer.") rcirc-buffer-alist)))) (rcirc-update-short-buffer-names)) + (add-hook 'completion-at-point-functions + 'rcirc-completion-at-point nil 'local) + (run-hooks 'rcirc-mode-hook)) (defun rcirc-update-prompt (&optional all) @@ -2004,16 +2029,18 @@ activity. Only run if the buffer is not visible and ;; containing the text following the /cmd. (defmacro defun-rcirc-command (command argument docstring interactive-form - &rest body) + &rest body) "Define a command." - `(defun ,(intern (concat "rcirc-cmd-" (symbol-name command))) - (,@argument &optional process target) - ,(concat docstring "\n\nNote: If PROCESS or TARGET are nil, the values given" - "\nby `rcirc-buffer-process' and `rcirc-target' will be used.") - ,interactive-form - (let ((process (or process (rcirc-buffer-process))) - (target (or target rcirc-target))) - ,@body))) + `(progn + (add-to-list 'rcirc-client-commands ,(concat "/" (symbol-name command))) + (defun ,(intern (concat "rcirc-cmd-" (symbol-name command))) + (,@argument &optional process target) + ,(concat docstring "\n\nNote: If PROCESS or TARGET are nil, the values given" + "\nby `rcirc-buffer-process' and `rcirc-target' will be used.") + ,interactive-form + (let ((process (or process (rcirc-buffer-process))) + (target (or target rcirc-target))) + ,@body)))) (defun-rcirc-command msg (message) "Send private MESSAGE to TARGET." -- 2.11.4.GIT