Update all my elpa files
This commit is contained in:
39
elpa/weechat-20180513.310/weechat-autoloads.el
Normal file
39
elpa/weechat-20180513.310/weechat-autoloads.el
Normal file
@@ -0,0 +1,39 @@
|
||||
;;; weechat-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||
|
||||
;;;### (autoloads nil "weechat" "weechat.el" (23293 60625 349674
|
||||
;;;;;; 451000))
|
||||
;;; Generated autoloads from weechat.el
|
||||
|
||||
(autoload 'weechat-connect "weechat" "\
|
||||
Connect to WeeChat.
|
||||
|
||||
HOST is the relay host, `weechat-host-default' by default.
|
||||
PORT is the port where the relay listens, `weechat-port-default' by default.
|
||||
PASSWORD is either a string, a function or nil.
|
||||
MODE is null or 'plain for a plain socket, t or 'ssl for a TLS socket;
|
||||
a string denotes a command to run. You can use %h and %p to interpolate host
|
||||
and port number respectively.
|
||||
|
||||
\(fn &optional HOST PORT PASSWORD MODE FORCE-DISCONNECT)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil nil ("weechat-button.el" "weechat-cmd.el" "weechat-color.el"
|
||||
;;;;;; "weechat-complete.el" "weechat-core.el" "weechat-corrector.el"
|
||||
;;;;;; "weechat-image.el" "weechat-latex.el" "weechat-notifications.el"
|
||||
;;;;;; "weechat-pkg.el" "weechat-read-marker.el" "weechat-relay.el"
|
||||
;;;;;; "weechat-sauron.el" "weechat-secrets.el" "weechat-smiley.el"
|
||||
;;;;;; "weechat-speedbar.el" "weechat-spelling.el" "weechat-tracking.el")
|
||||
;;;;;; (23293 60627 145855 345000))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; weechat-autoloads.el ends here
|
||||
348
elpa/weechat-20180513.310/weechat-button.el
Normal file
348
elpa/weechat-20180513.310/weechat-button.el
Normal file
@@ -0,0 +1,348 @@
|
||||
;;; weechat-button --- Add buttons to text ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; This code is heavily inspired by erc-button.el!
|
||||
|
||||
;;; Code:
|
||||
;;
|
||||
|
||||
(require 'weechat)
|
||||
(require 'button)
|
||||
(require 's)
|
||||
|
||||
;;; Customize
|
||||
|
||||
(defgroup weechat-button nil
|
||||
"WeeChat button interface (URLification)."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-button"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-button-url-regexp
|
||||
(concat "\\(www\\.\\|\\(s?https?\\|"
|
||||
"ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\)"
|
||||
"\\(//[-[:alnum:]_.]+:[0-9]*\\)?"
|
||||
"[-[:alnum:]_=!?#$@~`%&*+\\/:;.,()]+[-[:alnum:]_=#$@~`%&*+\\/()]")
|
||||
"Regexp to match URLs.
|
||||
Copied from erc-button.el."
|
||||
:type 'regexp
|
||||
:group 'weechat-button)
|
||||
|
||||
(defcustom weechat-button-default-log-buffer "*WeeChat URL Log*"
|
||||
"Buffer name for URL log.
|
||||
Valid values include a string describing a buffer name or nil to
|
||||
disable url logging (except when an explicit buffer name is
|
||||
defined in `weechat-button-list')"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "No Log" nil)
|
||||
(string :tag "Buffer Name")))
|
||||
|
||||
(defcustom weechat-button-buttonize-url t
|
||||
"Buttonize url links?"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
(defcustom weechat-button-buttonize-channels t
|
||||
"Buttonize channel links?"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
(defcustom weechat-button-buttonize-symbols t
|
||||
"Buttonize symbol links?"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
(defcustom weechat-button-buttonize-emails nil
|
||||
"Buttonize e-mail link?"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
(defcustom weechat-button-buttonize-man nil
|
||||
"Buttonize manpage links?
|
||||
Format is man(1)."
|
||||
:group 'weechat-button
|
||||
:type 'boolen)
|
||||
|
||||
(defcustom weechat-button-buttonize-info '("#emacs" "#weechat\\.el")
|
||||
"Buttonize info links?
|
||||
Format is (info \"link\")."
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
(defcustom weechat-button-rfc-url "http://www.faqs.org/rfcs/rfc%s.html"
|
||||
"URL used to browse rfc references.
|
||||
%s is replaced by the number."
|
||||
:group 'weechat-button
|
||||
:type 'string)
|
||||
|
||||
(defcustom weechat-button-buttonize-rfc nil
|
||||
"Buttonize rfc links?"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
; temporarily disabled due to performance problems
|
||||
(defcustom weechat-button-buttonize-nicks nil
|
||||
"Buttonize nicknames?"
|
||||
:group 'weechat-button
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Always" t)
|
||||
(repeat :tag "If regular expression matches buffer name" regexp)))
|
||||
|
||||
(defcustom weechat-button-list
|
||||
'((weechat-button-url-regexp 0 weechat-button-buttonize-url t "Browse URL"
|
||||
browse-url 0)
|
||||
("#[-#+_.[:alnum:]]+" 0 weechat-button-buttonize-channels nil "Join Channel"
|
||||
weechat-join 0)
|
||||
("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]\\{2,4\\}\\b" 0 weechat-button-buttonize-emails nil
|
||||
"email" weechat-button--mailto 0)
|
||||
("[`]\\([-_.[:alnum:]]+\\)[']" 1 weechat-button-buttonize-symbols nil "Describe Symbol"
|
||||
weechat-button--describe-symbol 1)
|
||||
("[[:alpha:][:alnum:]]+([1-9])" 0 weechat-button-buttonize-man nil "Manpage" man 0)
|
||||
("(info \"\\(([[:alnum:]]+) .+?\\)\"" 1 weechat-button-buttonize-info nil "info"
|
||||
info 1)
|
||||
("\\brfc[#: ]?\\([0-9]+\\)" 0 weechat-button-buttonize-rfc nil "RFC"
|
||||
weechat-button--rfc 1))
|
||||
"List of potential buttons in WeeChat chat buffers.
|
||||
Each entry has the form (REGEXP BUTTON-MATCH BUTTONIZE? LOG HELP-ECHO ACTION
|
||||
DATA-MATCH...), where
|
||||
|
||||
REGEXP is a string or variable containing a regular expression to match buttons.
|
||||
|
||||
BUTTON-MATCH is the number of the regexp grouping which represents the actual
|
||||
button.
|
||||
|
||||
BUTTONIZE? determines if button should be buttonized.
|
||||
See `weechat-button--buttonize?' for exact usage.
|
||||
|
||||
LOG decides if `weechat-button-log-functions' gets called.
|
||||
|
||||
HELP-ECHO is the `help-echo' property of the button.
|
||||
See Info node `(elisp) Button Properties'.
|
||||
|
||||
ACTION the function to call when the button is selected.
|
||||
|
||||
DATA-MATCH... numbers of the regexp groupings whose text will be passed to
|
||||
ACTION.
|
||||
|
||||
This is similar (but not identical) to `erc-button-alist' in ERC."
|
||||
:group 'weechat-button
|
||||
:type '(repeat :tag "Buttons"
|
||||
(list (choice :tag "Matches"
|
||||
regexp
|
||||
(variable :tag "Variable containing regexp"))
|
||||
(integer :tag "Number of the regexp section that matches")
|
||||
(choice :tag "When to buttonize"
|
||||
(const :tag "Always" t)
|
||||
(const :tag "Never" nil)
|
||||
(repeat :tag "If regular expression matches buffer name"
|
||||
regexp)
|
||||
(symbol :tag "Variable name"))
|
||||
(choice :tag "Log match"
|
||||
(const :tag "To default buffer" t)
|
||||
(const :tag "Never" nil)
|
||||
(string :tag "To buffer name"))
|
||||
(string :tag "Help echo text")
|
||||
(function :tag "Call this function when button is pressed")
|
||||
(repeat :tag "Sections of regexp to send to the function"
|
||||
:inline t
|
||||
(integer :tag "Regexp section number")))))
|
||||
(put 'weechat-button-list 'risky-local-variable t)
|
||||
|
||||
(defvar weechat-button-log-functions nil
|
||||
"List of function to run when a button should be logged.
|
||||
|
||||
This hook only runs when `LOG' is set to t for the particular
|
||||
button type.
|
||||
|
||||
Functions in list must have two arguments: The button data (the
|
||||
match string) and a plist describing the button properties.
|
||||
|
||||
The functions in this list will be called with
|
||||
`weechat-narrow-to-line' active.")
|
||||
|
||||
;;; Internal functions
|
||||
|
||||
(defun weechat-button--handler (button)
|
||||
"Handle BUTTON actions.
|
||||
The function in property `weechat-function' gets called with `weechat-data'."
|
||||
(let ((function (button-get button 'weechat-function))
|
||||
(data (button-get button 'weechat-data)))
|
||||
(when function
|
||||
(apply function data))))
|
||||
|
||||
(defun weechat-button--log-to-buffer (button-data button-properties)
|
||||
(when (and weechat-button-default-log-buffer)
|
||||
(let ((weechat-buffer-name (buffer-name)))
|
||||
(with-current-buffer (get-buffer-create
|
||||
weechat-button-default-log-buffer)
|
||||
(goto-char (point-max))
|
||||
(unless (bolp)
|
||||
(insert "\n"))
|
||||
(insert weechat-buffer-name "\t")
|
||||
(apply #'insert-button button-data button-properties)
|
||||
(insert "\n")))))
|
||||
|
||||
(add-hook 'weechat-button-log-functions 'weechat-button--log-to-buffer)
|
||||
|
||||
(defun weechat-button--buttonize? (buttonize?)
|
||||
"Return non-nil if BUTTONIZE? says so.
|
||||
Return non-nil if BUTTONIZE?:
|
||||
- is t,
|
||||
- is a list of strings and one of the strings matches the channel name,
|
||||
- is a variable then apply the rules to the value of the variable."
|
||||
(when (and (symbolp buttonize?) (boundp buttonize?))
|
||||
(setq buttonize? (symbol-value buttonize?)))
|
||||
(cond
|
||||
((listp buttonize?)
|
||||
(let ((name (buffer-name)) ret)
|
||||
(dolist (i buttonize? ret)
|
||||
(when (s-matches? i name)
|
||||
(setq ret t)))))
|
||||
(t t)))
|
||||
|
||||
(defvar weechat-button-log-buffer-last-log nil)
|
||||
(defun weechat-button--add-do (entry &optional text-buttons)
|
||||
"Handle each button ENTRY.
|
||||
If TEXT-BUTTONS is non-nil then use `make-text-button instead of `make-button'."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(cl-destructuring-bind
|
||||
(regexp-entry button-match buttonize?
|
||||
log help-echo action &rest data-match) entry
|
||||
(let* ((regexp (or (and (stringp regexp-entry) regexp-entry)
|
||||
(and (boundp regexp-entry) (symbol-value regexp-entry))))
|
||||
(line-date (weechat-line-date))
|
||||
(run-hooks?
|
||||
(and line-date
|
||||
(or (null weechat-button-log-buffer-last-log)
|
||||
(time-less-p weechat-button-log-buffer-last-log
|
||||
line-date))))
|
||||
(button-fn (if text-buttons
|
||||
#'make-text-button
|
||||
#'make-button)))
|
||||
(when regexp
|
||||
(while (re-search-forward regexp nil t)
|
||||
(let ((start (match-beginning button-match))
|
||||
(end (match-end button-match))
|
||||
(button-data-no-properties
|
||||
(match-string-no-properties button-match))
|
||||
(data (mapcar #'match-string data-match)))
|
||||
(when (and (weechat-button--buttonize? buttonize?)
|
||||
;; Don't overlap buttons
|
||||
;; Handles text-buttons and overlay-buttons
|
||||
(cl-every (lambda (o)
|
||||
(null (overlay-get o 'button)))
|
||||
(overlays-in start end))
|
||||
(not (text-property-not-all start end 'button nil)))
|
||||
(let ((properties (list 'action #'weechat-button--handler
|
||||
'help-echo help-echo
|
||||
'follow-link t
|
||||
'weechat-function action
|
||||
'weechat-data data)))
|
||||
(when (and log
|
||||
run-hooks?)
|
||||
;; Hack: Rebind `weechat-button-default-log-buffer'
|
||||
;; to the value supplied by the button type in
|
||||
;; `weechat-button-list'
|
||||
(let ((weechat-button-default-log-buffer
|
||||
(if (or (stringp log) (bufferp log))
|
||||
log
|
||||
weechat-button-default-log-buffer)))
|
||||
(run-hook-with-args 'weechat-button-log-functions
|
||||
button-data-no-properties
|
||||
properties))
|
||||
(setq weechat-button-log-buffer-last-log line-date))
|
||||
(apply button-fn start end properties))))))))))
|
||||
|
||||
(defun weechat-button--add ()
|
||||
"Add text buttons to text in buffer."
|
||||
(dolist (i weechat-button-list)
|
||||
(weechat-button--add-do i))
|
||||
(when weechat-button-buttonize-nicks
|
||||
(weechat-button--add-nickname-buttons)))
|
||||
|
||||
(defvar weechat-user-list) ;; See weechat.el
|
||||
|
||||
(defun weechat-button--add-nickname-buttons ()
|
||||
"Add nick name buttons."
|
||||
(dolist (nick weechat-user-list)
|
||||
(unless (s-blank? nick)
|
||||
(weechat-button--add-do (list (concat "\\b" (regexp-quote nick) "\\b")
|
||||
0 t 0 "Nick Action"
|
||||
#'weechat-nick-action
|
||||
0)
|
||||
'text-button))))
|
||||
|
||||
;;; Callback functions
|
||||
|
||||
;; This function is copied from `erc-button-describe-symbol'
|
||||
(defun weechat-button--describe-symbol (symbol-name)
|
||||
"Describe SYMBOL-NAME.
|
||||
Use `describe-function' for functions, `describe-variable' for variables,
|
||||
and `apropos' for other symbols."
|
||||
(let ((symbol (intern-soft symbol-name)))
|
||||
(cond ((and symbol (fboundp symbol))
|
||||
(describe-function symbol))
|
||||
((and symbol (boundp symbol))
|
||||
(describe-variable symbol))
|
||||
(t (apropos symbol-name)))))
|
||||
|
||||
(defun weechat-button--mailto (email)
|
||||
"Call `browse-url' on email with \"mailto:\" prepend."
|
||||
(browse-url (concat "mailto:" email)))
|
||||
|
||||
(defun weechat-button--rfc (rfc)
|
||||
"Call `browse-url' on RFC using `weechat-button-rfc-url'."
|
||||
(browse-url (format weechat-button-rfc-url rfc)))
|
||||
|
||||
;;; Module load/unload
|
||||
|
||||
;;; This is done automatically by `load-library' or `require'.
|
||||
;;; Unloading is taken care of, because hooks added via `add-hook'
|
||||
;;; will be removed automatically by `unload-feature'.
|
||||
|
||||
;;; If you need special cleanup code, use define a function named
|
||||
;;; `FEATURE-unload-function'. This function will be called by emacs
|
||||
;;; right before unloading the feature. Check the docstring of
|
||||
;;; `unload-feature' for details.
|
||||
|
||||
(add-hook 'weechat-insert-modify-hook #'weechat-button--add)
|
||||
|
||||
(provide 'weechat-button)
|
||||
|
||||
;;; weechat-button.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-button.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-button.elc
Normal file
Binary file not shown.
79
elpa/weechat-20180513.310/weechat-cmd.el
Normal file
79
elpa/weechat-20180513.310/weechat-cmd.el
Normal file
@@ -0,0 +1,79 @@
|
||||
;;; weechat-cmd.el --- Define local weechat commands in elisp
|
||||
|
||||
;; Copyright (C) 2013 Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; This modules allows the user to write Emacs Lisp functions which
|
||||
;; are callable in weechat buffers via normal irc /command syntax.
|
||||
;;
|
||||
;; Function names must start with `weechat-cmd-function-prefix' and
|
||||
;; take one argument, the input of the user.
|
||||
;;
|
||||
;; They might return either a string or nil. In case of string the
|
||||
;; value will be sent to the server. If the return value is nil, the
|
||||
;; command will be discarded. This is useful if you want to execute
|
||||
;; local code but not send anything to the server.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 's)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defconst weechat-cmd-function-prefix "weechat-command-")
|
||||
|
||||
(defcustom weechat-cmd-prefix "/"
|
||||
"Prefix used for cmd commands."
|
||||
:type 'string
|
||||
:group 'weechat-cmd)
|
||||
|
||||
(defun weechat-cmd-find-cmds ()
|
||||
(let (ret)
|
||||
(mapatoms
|
||||
(lambda (x)
|
||||
(when (s-prefix? weechat-cmd-function-prefix (symbol-name x))
|
||||
(setq ret (cons x ret)))))
|
||||
ret))
|
||||
|
||||
(defun weechat-cmd-apply (input)
|
||||
(if (s-prefix? weechat-cmd-prefix input)
|
||||
(let* ((command (car
|
||||
(s-split-words
|
||||
(s-chop-prefix
|
||||
weechat-cmd-prefix
|
||||
input))))
|
||||
(sym (intern-soft (concat weechat-cmd-function-prefix
|
||||
command)))
|
||||
(fn (when (fboundp sym)
|
||||
(symbol-function sym))))
|
||||
(if (functionp fn)
|
||||
(funcall fn input)
|
||||
input))
|
||||
input))
|
||||
|
||||
(add-hook 'weechat-message-filter-functions #'weechat-cmd-apply)
|
||||
|
||||
(provide 'weechat-cmd)
|
||||
|
||||
;;; weechat-cmd.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-cmd.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-cmd.elc
Normal file
Binary file not shown.
379
elpa/weechat-20180513.310/weechat-color.el
Normal file
379
elpa/weechat-20180513.310/weechat-color.el
Normal file
@@ -0,0 +1,379 @@
|
||||
;;; weechat-color --- Color handling for WeeChat ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Moritz Ulrich, Rüdiger Sonderfeld
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; WeeChat comes with its own (ridiculously complicated) set of color codes.
|
||||
;; See URL `http://www.weechat.org/files/doc/devel/weechat_dev.en.html#color_codes_in_strings'
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat-core)
|
||||
(require 'rx)
|
||||
(require 's)
|
||||
|
||||
(defgroup weechat-faces nil
|
||||
"WeeChat Faces and Color settings"
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-"
|
||||
:group 'weechat)
|
||||
|
||||
(defface weechat-nick-self-face '((t :weight bold :foreground "brown"))
|
||||
"Face for your own nick."
|
||||
:group 'weechat-faces)
|
||||
|
||||
(defface weechat-time-face '((t :inherit default))
|
||||
"Weechat face used for timestamps."
|
||||
:group 'weechat-faces)
|
||||
|
||||
(defface weechat-prompt-face '((t :inherit minibuffer-prompt))
|
||||
"Weechat face used for the prompt."
|
||||
:group 'weechat-faces)
|
||||
|
||||
(defface weechat-highlight-face
|
||||
'((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
|
||||
(((class grayscale) (background dark)) :foreground "DimGray" :weight bold)
|
||||
(((class color) (min-colors 88) (background light)) :foreground "Purple")
|
||||
(((class color) (min-colors 88) (background dark)) :foreground "Cyan1")
|
||||
(((class color) (min-colors 16) (background light)) :foreground "Purple")
|
||||
(((class color) (min-colors 16) (background dark)) :foreground "Cyan")
|
||||
(((class color) (min-colors 8)) :foreground "cyan" :weight bold)
|
||||
(t :weight bold)) ;; Stolen from rcirc.el!
|
||||
"Weechat face for highlighted lines."
|
||||
:group 'weechat-faces)
|
||||
|
||||
(defface weechat-error-face '((t :inherit error))
|
||||
"Weechat face used to display errors."
|
||||
:group 'weechat-faces)
|
||||
|
||||
(defcustom weechat-strip-formatting nil
|
||||
"Remove every kind of formatting or color from messages.
|
||||
This will look very bland!"
|
||||
:type 'boolean
|
||||
:group 'weechat-faces)
|
||||
|
||||
(defvar weechat-formatting-regex
|
||||
(let* ((attr `(in "*!/_|")) ;NOTE: is not documented
|
||||
(std `(= 2 digit))
|
||||
(astd `(seq ,attr (= 2 digit)))
|
||||
(ext `(seq "@" (= 5 digit)))
|
||||
(aext `(seq "@" ,attr (= 5 digit))))
|
||||
(rx-form
|
||||
`(or (seq ""
|
||||
(or ,std
|
||||
,ext
|
||||
(seq "F" (or ,std ,astd ,ext ,aext))
|
||||
(seq "B" (or ,std ,ext))
|
||||
(seq "*" (or ,std
|
||||
,astd
|
||||
,ext
|
||||
,aext
|
||||
(seq (or ,std ,astd ,ext ,aext)
|
||||
","
|
||||
(or ,std ,astd ,ext ,aext))))
|
||||
(seq "b" (in "FDB_-#il"))
|
||||
""))
|
||||
(seq "" ,attr)
|
||||
(seq "" ,attr)
|
||||
""))))
|
||||
|
||||
(defun weechat-strip-formatting (string)
|
||||
"Strip weechat color codes from STRING."
|
||||
(if (stringp string)
|
||||
(replace-regexp-in-string weechat-formatting-regex "" string)
|
||||
string))
|
||||
|
||||
(defcustom weechat-color-list '(unspecified "black" "dark gray" "dark red" "red"
|
||||
"dark green" "light green" "brown"
|
||||
"yellow" "dark blue" "light blue"
|
||||
"dark magenta" "magenta" "dark cyan"
|
||||
"light cyan" "gray" "white")
|
||||
"Mapping of Weechat colors.
|
||||
|
||||
Do NOT remove or add new elements to the list. Only change the values.
|
||||
See URL `http://www.weechat.org/files/doc/devel/weechat_dev.en.html#color_codes_in_strings'."
|
||||
:type '(repeat (choice (const :tag "Unspecified" unspecified)
|
||||
(const :tag "Color" color)))
|
||||
:group 'weechat)
|
||||
|
||||
(defvar weechat-color-attributes-alist '((?* . (:weight bold)) (?\1 . (:weight bold)) ; bold
|
||||
(?! . (:inverse-video t)) (?\2 . (:inverse-video t)) ; reverse??
|
||||
(?/ . (:slant italic)) (?\3 . (:slant italic)) ; italic
|
||||
(?_ . (:underline t)) (?\4 . (:underline t)) ; underline
|
||||
(?| . keep)) ; keep
|
||||
"Map color attribute specifiers to Emacs face property.")
|
||||
|
||||
|
||||
(defvar weechat-terminal-colors
|
||||
(concat
|
||||
"000000cd000000cd00cdcd000000cdcd00cd00cdcde5e5e5"
|
||||
"4d4d4dff000000ff00ffff000000ffff00ff00ffffffffff"
|
||||
"00000000002a0000550000800000aa0000d4002a00002a2a"
|
||||
"002a55002a80002aaa002ad400550000552a005555005580"
|
||||
"0055aa0055d400800000802a0080550080800080aa0080d4"
|
||||
"00aa0000aa2a00aa5500aa8000aaaa00aad400d40000d42a"
|
||||
"00d45500d48000d4aa00d4d42a00002a002a2a00552a0080"
|
||||
"2a00aa2a00d42a2a002a2a2a2a2a552a2a802a2aaa2a2ad4"
|
||||
"2a55002a552a2a55552a55802a55aa2a55d42a80002a802a"
|
||||
"2a80552a80802a80aa2a80d42aaa002aaa2a2aaa552aaa80"
|
||||
"2aaaaa2aaad42ad4002ad42a2ad4552ad4802ad4aa2ad4d4"
|
||||
"55000055002a5500555500805500aa5500d4552a00552a2a"
|
||||
"552a55552a80552aaa552ad455550055552a555555555580"
|
||||
"5555aa5555d455800055802a5580555580805580aa5580d4"
|
||||
"55aa0055aa2a55aa5555aa8055aaaa55aad455d40055d42a"
|
||||
"55d45555d48055d4aa55d4d480000080002a800055800080"
|
||||
"8000aa8000d4802a00802a2a802a55802a80802aaa802ad4"
|
||||
"80550080552a8055558055808055aa8055d480800080802a"
|
||||
"8080558080808080aa8080d480aa0080aa2a80aa5580aa80"
|
||||
"80aaaa80aad480d40080d42a80d45580d48080d4aa80d4d4"
|
||||
"aa0000aa002aaa0055aa0080aa00aaaa00d4aa2a00aa2a2a"
|
||||
"aa2a55aa2a80aa2aaaaa2ad4aa5500aa552aaa5555aa5580"
|
||||
"aa55aaaa55d4aa8000aa802aaa8055aa8080aa80aaaa80d4"
|
||||
"aaaa00aaaa2aaaaa55aaaa80aaaaaaaaaad4aad400aad42a"
|
||||
"aad455aad480aad4aaaad4d4d40000d4002ad40055d40080"
|
||||
"d400aad400d4d42a00d42a2ad42a55d42a80d42aaad42ad4"
|
||||
"d45500d4552ad45555d45580d455aad455d4d48000d4802a"
|
||||
"d48055d48080d480aad480d4d4aa00d4aa2ad4aa55d4aa80"
|
||||
"d4aaaad4aad4d4d400d4d42ad4d455d4d480d4d4aad4d4d4"
|
||||
"0808081212121c1c1c2626263030303a3a3a4444444e4e4e"
|
||||
"5858586262626c6c6c7676768080808a8a8a9494949e9e9e"
|
||||
"a8a8a8b2b2b2bcbcbcc6c6c6d0d0d0dadadae4e4e4eeeeee"))
|
||||
|
||||
(defun weechat--match-color-code (what str i)
|
||||
"Match std, ext, attr WHAT on STR at position I.
|
||||
This is internal and used by `weechat-handle-color-codes'."
|
||||
(when (symbolp what)
|
||||
(cl-case what
|
||||
((std)
|
||||
(let ((std (substring str i (+ i 2))))
|
||||
(when (s-matches? "^[0-9]+$" std)
|
||||
(list 'std (+ i 2) (string-to-number std)))))
|
||||
((ext)
|
||||
(when (= (aref str i) ?@)
|
||||
(let ((std (substring str (1+ i) (+ i 6))))
|
||||
(when (s-matches? "^[0-9]+$" std)
|
||||
(list 'ext (+ i 6) (string-to-number std))))))
|
||||
((attr)
|
||||
(let* ((a (aref str i))
|
||||
(x (cdr (assq a weechat-color-attributes-alist))))
|
||||
(when x
|
||||
(list 'attr (1+ i) x))))
|
||||
(t (error "Unknown parameter %s" what)))))
|
||||
|
||||
(defun weechat--color-keep-attributes (old-face)
|
||||
"Remove color settings from OLD-FACE but keep the attributes."
|
||||
(cl-delete-if (lambda (x)
|
||||
(memq (car x) '(:foreground :background)))
|
||||
old-face))
|
||||
|
||||
(defun weechat--rgb-color (index)
|
||||
(let* ((colors (substring weechat-terminal-colors (* index 6)))
|
||||
(r (* 0.85 (string-to-number (substring colors 0 2) 16)))
|
||||
(g (* 0.85 (string-to-number (substring colors 2 4) 16)))
|
||||
(b (* 0.85 (string-to-number (substring colors 4 6) 16))))
|
||||
(format "#%02x%02x%02x" r g b)))
|
||||
|
||||
(defun weechat--color-handle-F (str i old-face)
|
||||
"Handle ?F (A)STD|(A)EXT color code in STR at I with OLD-FACE.
|
||||
This is an internal function of `weechat-handle-color-codes'."
|
||||
(let (match-data
|
||||
face
|
||||
(j (1+ i)))
|
||||
(while (setq match-data (weechat--match-color-code 'attr str j)) ;; (A)
|
||||
(if (eq (cl-third match-data) 'keep)
|
||||
(setq face (weechat--color-keep-attributes old-face))
|
||||
(setq face (append (list (cl-third match-data)) face)))
|
||||
(setq j (cl-second match-data)))
|
||||
(setq match-data (weechat--match-color-code 'std str j))
|
||||
(if match-data
|
||||
(setq face (append (list (list :foreground (nth (cl-third match-data)
|
||||
weechat-color-list)))
|
||||
face)) ;; TODO set attribute instead of simply append
|
||||
(setq match-data (weechat--match-color-code 'ext str j))
|
||||
(if match-data
|
||||
(setq face (list (list :foreground (weechat--rgb-color (cl-third match-data)))))
|
||||
(weechat-relay-log (format "Broken color code (in ?F '%s' %s)" str i)
|
||||
:warn)))
|
||||
(if match-data
|
||||
(cl-values (cl-second match-data)
|
||||
face)
|
||||
(cl-values j face))))
|
||||
|
||||
(defvar weechat-color-options-list
|
||||
'(("weechat.color.separator" . "blue") ;; KEEP THE ORDER!
|
||||
("weechat.color.chat" . default)
|
||||
("weechat.color.chat_time" . weechat-time-face)
|
||||
("weechat.color.chat_time_delimiters" . weechat-time-face)
|
||||
("weechat.color.chat_prefix_error" . "yellow")
|
||||
("weechat.color.chat_prefix_network" . "magenta")
|
||||
("weechat.color.chat_prefix_action" . "white")
|
||||
("weechat.color.chat_prefix_join" . "light green")
|
||||
("weechat.color.chat_prefix_quit" . "orange red") ;; light red
|
||||
("weechat.color.chat_prefix_more" . "medium violet red") ;; light magenta
|
||||
("weechat.color.chat_prefix_suffix" . "green")
|
||||
("weechat.color.chat_buffer" . "white")
|
||||
("weechat.color.chat_server" . "brown")
|
||||
("weechat.color.chat_channel" . "white")
|
||||
("weechat.color.chat_nick" . "light cyan")
|
||||
("weechat.color.chat_nick_self" . weechat-nick-self-face)
|
||||
("weechat.color.chat_nick_other" . "cyan")
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
(nil . default)
|
||||
("weechat.color.chat_host" . "cyan")
|
||||
("weechat.color.chat_delimiters" . "green")
|
||||
("weechat.color.chat_highlight" . weechat-highlight-face)
|
||||
("weechat.color.chat_read_marker" . "magenta")
|
||||
("weechat.color.chat_text_found" . "yellow")
|
||||
("weechat.color.chat_value" . "cyan")
|
||||
("weechat.color.chat_prefix_buffer")
|
||||
("weechat.color.chat_tags" . "red")
|
||||
("weechat.color.chat_inactive_window" . "dark grey")
|
||||
("weechat.color.chat_inactive_buffer" . "dark grey")
|
||||
("weechat.color.chat_prefix_buffer_inactive_buffer" . "dark grey")
|
||||
("weechat.color.chat_nick_offline" . "dark grey")
|
||||
("weechat.color.chat_nick_offline_highlight" . default))
|
||||
"List of color options for \x19XX.")
|
||||
;; TODO every option here should probably be a face!
|
||||
|
||||
(defun weechat--color-std-to-theme (num)
|
||||
"Turn color code in NUM using option into face."
|
||||
(if (or (not (integerp num))
|
||||
(> num (length weechat-color-options-list)))
|
||||
'default
|
||||
(let ((face (cdr (nth num weechat-color-options-list))))
|
||||
(if (stringp face) ;; color value
|
||||
(list (list :foreground face ))
|
||||
face))))
|
||||
|
||||
(defun weechat-handle-color-codes (str)
|
||||
"Convert the Weechat color codes in STR to properties.
|
||||
EXT colors are currently not supported. Any color codes left are stripped.
|
||||
|
||||
Be aware that Weechat does not use mIRC color codes.
|
||||
See URL `http://www.weechat.org/files/doc/devel/weechat_dev.en.html#color_codes_in_strings'."
|
||||
(let ((i 0)
|
||||
face
|
||||
(ret "")
|
||||
(len (length str)))
|
||||
(while (< i len)
|
||||
(cl-case (aref str i)
|
||||
((?\x19) ;; STD|EXT|?F((A)STD|(A)EXT)|?B(STD|EXT)|?\x1C|?*...|?b...
|
||||
(let ((old-face face)
|
||||
(next (aref str (1+ i))))
|
||||
(setq face nil)
|
||||
(setq i (1+ i))
|
||||
(cond
|
||||
((and (<= ?0 next) (<= next ?9)) ;; STD
|
||||
(let ((match-data (weechat--match-color-code 'std str i)))
|
||||
(when match-data
|
||||
(setq face (weechat--color-std-to-theme (cl-third match-data)))
|
||||
(setq i (cl-second match-data)))))
|
||||
((= next ?@) ;; EXT
|
||||
(let ((match-data (weechat--match-color-code 'ext str i)))
|
||||
(when match-data
|
||||
;; TODO
|
||||
(setq i (cl-second match-data)))))
|
||||
((= next ?F) ;; ?F(A)STD|?F(A)EXT
|
||||
(cl-multiple-value-setq (i face) (weechat--color-handle-F str i old-face)))
|
||||
((= next ?B) ;; ?BSTD|?BEXT
|
||||
(let ((match-data (weechat--match-color-code 'std str i)))
|
||||
(if match-data
|
||||
(setq face (list (list :background (nth (cl-third match-data)
|
||||
weechat-color-list))))
|
||||
(setq match-data (weechat--match-color-code 'ext str i))
|
||||
(if match-data
|
||||
t ;; TODO ext
|
||||
(weechat-relay-log (format "Broken color code (in ?B '%s' %s)" str i)
|
||||
:warn)))
|
||||
(setq i (if match-data
|
||||
(cl-second match-data)
|
||||
(1+ i)))))
|
||||
((= next ?*) ;; (A)STD | (A)EXT | (A)STD ?, (A)STD | ...
|
||||
(cl-multiple-value-setq (i face) (weechat--color-handle-F str i old-face))
|
||||
(if (= (aref str i) ?,)
|
||||
(let* ((i (1+ i))
|
||||
(match-data (weechat--match-color-code 'std str i)))
|
||||
(if match-data
|
||||
(setq face (append (list (list :background (nth (cl-third match-data)
|
||||
weechat-color-list)))
|
||||
face))
|
||||
(setq match-data (weechat--match-color-code 'ext str i))
|
||||
(if match-data
|
||||
t ;; TODO ext
|
||||
(weechat-relay-log (format "Broken color code (in ?* '%s' %s)" str i)
|
||||
:warn)))
|
||||
(setq i (if match-data
|
||||
(cl-second match-data)
|
||||
(1+ i))))))
|
||||
((= next ?b) 'b) ;; ignore for now
|
||||
((= next ?\x1C) ;; Clear color, leave attributes
|
||||
(setq face (weechat--color-keep-attributes old-face))))))
|
||||
|
||||
((?\x1A) ;; Set ATTR
|
||||
(let ((match-data (weechat--match-color-code 'attr str (1+ i))))
|
||||
(if (not match-data)
|
||||
(progn
|
||||
(weechat-relay-log (format "Broken color code (in ?\\x1A '%s' %s)" str i)
|
||||
:warn)
|
||||
(setq i (1+ i)))
|
||||
(if (eq (cl-third match-data) 'keep)
|
||||
(setq face (weechat--color-keep-attributes face))
|
||||
(setq face (list (cl-third match-data))))
|
||||
(setq i (cl-second match-data)))))
|
||||
|
||||
((?\x1B) ;; Delete ATTR
|
||||
(let ((match-data (weechat--match-color-code 'attr str (1+ i)))
|
||||
(old-face (copy-sequence face)))
|
||||
(if (not match-data)
|
||||
(progn
|
||||
(weechat-relay-log (format "Broken color code (in ?\\x1B '%s' %s)" str i)
|
||||
:warn)
|
||||
(setq i (1+ i)))
|
||||
(if (eq (cl-third match-data) 'keep)
|
||||
(setq face nil) ;; TODO Does keep here means delete all or keep all?
|
||||
(setq face (delq (cl-third match-data) old-face)))
|
||||
(setq i (cl-second match-data)))))
|
||||
|
||||
((?\x1C) (setq i (1+ i) face nil))) ;; reset face
|
||||
|
||||
(let ((r (string-match-p "\\(\x19\\|\x1A\\|\x1B\\|\x1C\\)" str i)))
|
||||
(if r
|
||||
(setq ret (concat ret
|
||||
(propertize (substring str i r) 'face (or face 'default)))
|
||||
i r)
|
||||
(setq ret (concat ret (propertize (substring str i) 'face (or face 'default)))
|
||||
i len)))) ;; STOP
|
||||
ret))
|
||||
|
||||
(provide 'weechat-color)
|
||||
|
||||
;;; weechat-color.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-color.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-color.elc
Normal file
Binary file not shown.
188
elpa/weechat-20180513.310/weechat-complete.el
Normal file
188
elpa/weechat-20180513.310/weechat-complete.el
Normal file
@@ -0,0 +1,188 @@
|
||||
;;; weechat-complete --- completions for weechat.el. ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld
|
||||
|
||||
;; Parts copied from `erc-pcomplete.el' are
|
||||
;; Copyright (C) 2002-2004, 2006-2013 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Martin Yrjölä <martin.yrjola@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Completions for weechat.el. Parts of the code are copied from
|
||||
;; `erc-pcomplete.el'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 'pcomplete)
|
||||
(require 's)
|
||||
|
||||
(defvar weechat-user-list)
|
||||
(defvar weechat-prompt-end-marker)
|
||||
|
||||
(defcustom weechat-complete-nick-prefix-and-postfix-alist nil
|
||||
"Alist of nick prefixes and postfixes to use for certain
|
||||
buffers Each element looks like (BUFFER-NAME-REGEXP
|
||||
. (NICK-PREFIX . NICK-POSTFIX). If BUFFER-NAME-REGEXP matches the
|
||||
current buffer, then NICK-PREFIX is pushed to the beginning of
|
||||
each nick in `weechat-user-list' and NICK-POSTFIX is appended to
|
||||
them. One common use case is that a messaging service provides an
|
||||
IRC server (e.g. Flowdock and Gitter), but the mentions have to
|
||||
be prefixed with '@' to be highlighted in the other clients."
|
||||
:type '(alist :key-type regexp :value-type (cons string string))
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-complete-nick-postfix ":"
|
||||
"Postfix to nick completions at the beginning of the prompt.
|
||||
Can be overriden by `weechat-complete-nick-prefix-and-postfix-alist'"
|
||||
:type 'string
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-complete-nick-ignore-self t
|
||||
"Wether to ignore yourself when completing at the begginning of
|
||||
the input line
|
||||
|
||||
Make sure to rebuild each buffer after changing this variable."
|
||||
:type 'boolean
|
||||
:group 'weechat)
|
||||
|
||||
(defun weechat-pcompletions-at-point ()
|
||||
"WeeChat completion data from pcomplete.
|
||||
for use on `completion-at-point-function'.
|
||||
|
||||
Copied from `erc-pcompletions-at-point'."
|
||||
(when (and (eq major-mode 'weechat-mode)
|
||||
(>= (point) weechat-prompt-end-marker))
|
||||
(or (let ((pcomplete-default-completion-function #'ignore))
|
||||
(pcomplete-completions-at-point))
|
||||
(let ((c (pcomplete-completions-at-point)))
|
||||
(if c (nconc c '(:exclusive no)))))))
|
||||
|
||||
(defun pcomplete-weechat-setup ()
|
||||
"Setup pcomplete for `weechat-mode'."
|
||||
(set (make-local-variable 'pcomplete-ignore-case) t)
|
||||
(set (make-local-variable 'pcomplete-use-paring) nil)
|
||||
(set (make-local-variable 'pcomplete-parse-arguments-function)
|
||||
#'pcomplete-weechat-parse-arguments)
|
||||
(set (make-local-variable 'pcomplete-command-completion-function)
|
||||
#'pcomplete/weechat/complete-command)
|
||||
(set (make-local-variable 'pcomplete-command-name-function)
|
||||
#'pcomplete-weechat-command-name)
|
||||
(set (make-local-variable 'pcomplete-default-completion-function)
|
||||
(lambda () (pcomplete-here (pcomplete-weechat-nicks)))))
|
||||
|
||||
(defun pcomplete-weechat-parse-arguments ()
|
||||
"Return a list of parsed whitespace-separated arguments.
|
||||
These are the words from the beginning of the line after the prompt
|
||||
up to where point is right now.
|
||||
|
||||
Copied from `pcomplete-erc-parse-arguments'."
|
||||
(let* ((start weechat-prompt-end-marker)
|
||||
(end (point))
|
||||
args beginnings)
|
||||
(save-excursion
|
||||
(when (< (skip-chars-backward " \t\n" start) 0)
|
||||
(setq args '("")
|
||||
beginnings (list end)))
|
||||
(setq end (point))
|
||||
(while (< (skip-chars-backward "^ \t\n" start) 0)
|
||||
(setq beginnings (cons (point) beginnings)
|
||||
args (cons (buffer-substring-no-properties
|
||||
(point) end)
|
||||
args))
|
||||
(skip-chars-backward " \t\n" start)
|
||||
(setq end (point))))
|
||||
(cons args beginnings)))
|
||||
|
||||
(defun pcomplete-weechat-command-name ()
|
||||
"Return the command name of the first argument.
|
||||
Copied from `pcomplete-erc-command-name'."
|
||||
(if (eq (aref (pcomplete-arg 'first) 0) ?/)
|
||||
(upcase (substring (pcomplete-arg 'first) 1))
|
||||
"SAY"))
|
||||
|
||||
(defun pcomplete/weechat/complete-command ()
|
||||
"Complete the initial command argument."
|
||||
(pcomplete-here
|
||||
(append
|
||||
(pcomplete-weechat-commands)
|
||||
(pcomplete-weechat-nicks weechat-complete-nick-postfix weechat-complete-nick-ignore-self))))
|
||||
|
||||
(defun pcomplete/weechat-mode/WHOIS ()
|
||||
(pcomplete-here (pcomplete-weechat-all-nicks)))
|
||||
|
||||
(defun pcomplete/weechat-mode/QUERY ()
|
||||
(pcomplete-here (pcomplete-weechat-all-nicks)))
|
||||
|
||||
(defun pcomplete/weechat-mode/SAY ()
|
||||
(while (pcomplete-here (pcomplete-weechat-nicks))))
|
||||
|
||||
(defun pcomplete-weechat-commands ()
|
||||
"Return a list of user commands."
|
||||
'("/NICK" "/JOIN" "/PART" "/WHOIS" "/QUERY")) ;; TODO
|
||||
|
||||
(defun pcomplete-weechat-nicks (&optional postfix ignore-self)
|
||||
"Return a list of nicks in the current channel.
|
||||
POSTFIX is an optional string to append to the nickname.
|
||||
If IGNORE-SELF is non-nil the users nick is ignored."
|
||||
(let* ((users weechat-user-list)
|
||||
(prefix-and-postfix
|
||||
(weechat-complete-nick-prefix-and-postfix-for-current-buffer))
|
||||
(nick-prefix (car prefix-and-postfix))
|
||||
(nick-postfix (if prefix-and-postfix
|
||||
(cdr prefix-and-postfix)
|
||||
postfix)))
|
||||
(when ignore-self
|
||||
(setq users (delete (weechat-get-local-var "nick") users)))
|
||||
(mapcar (lambda (nick)
|
||||
(concat
|
||||
nick-prefix
|
||||
nick
|
||||
nick-postfix)) users)))
|
||||
|
||||
(defun weechat-complete-nick-prefix-and-postfix-for-current-buffer ()
|
||||
"Returns the nick-prefix-and-postfix for the current buffer.
|
||||
The format is (nick-prefix . nick-postfix)."
|
||||
(let ((found-nick-prefix-and-postfix nil))
|
||||
(mapc (lambda (element)
|
||||
(let ((buffer-name-regexp (car element))
|
||||
(nick-prefix-and-postfix (cdr element)))
|
||||
(when (string-match buffer-name-regexp (buffer-name))
|
||||
(setq found-nick-prefix-and-postfix nick-prefix-and-postfix))))
|
||||
weechat-complete-nick-prefix-and-postfix-alist)
|
||||
found-nick-prefix-and-postfix))
|
||||
|
||||
(defun pcomplete-weechat-all-nicks ()
|
||||
"Return nick list of all weechat buffers."
|
||||
(let (result)
|
||||
(weechat-do-buffers
|
||||
(setq result (cl-union weechat-user-list result :test #'s-equals?)))
|
||||
result))
|
||||
|
||||
(weechat-do-buffers (pcomplete-weechat-setup))
|
||||
(add-hook 'weechat-mode-hook #'pcomplete-weechat-setup)
|
||||
(add-hook 'completion-at-point-functions #'weechat-pcompletions-at-point)
|
||||
|
||||
(provide 'weechat-complete)
|
||||
|
||||
;;; weechat-complete.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-complete.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-complete.elc
Normal file
Binary file not shown.
101
elpa/weechat-20180513.310/weechat-core.el
Normal file
101
elpa/weechat-20180513.310/weechat-core.el
Normal file
@@ -0,0 +1,101 @@
|
||||
;;; weechat-core --- Basic stuff for weechat.el ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Moritz Ulrich
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This package provides a way to chat via WeeChat's relay protocol in
|
||||
;; Emacs.
|
||||
|
||||
;; Please see README.org on how to use it.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 's)
|
||||
|
||||
(defgroup weechat nil
|
||||
"WeeChat based IRC client for Emacs."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-"
|
||||
:group 'applications)
|
||||
|
||||
(defgroup weechat-relay nil
|
||||
"WeeChat Relay Settings."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-relay"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-relay-log-buffer-name "*weechat-relay-log*"
|
||||
"Buffer name to use as debug log.
|
||||
Set to nil to disable logging."
|
||||
:type 'string
|
||||
:group 'weechat-relay)
|
||||
|
||||
(defcustom weechat-relay-log-level :info
|
||||
"Minimum log level.
|
||||
Might be one of :debug, :info, :warn, :error or nil."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(const :tag "Error" :error)
|
||||
(const :tag "Warnings" :warn)
|
||||
(const :tag "Info" :info)
|
||||
(const :tag "Debug" :debug))
|
||||
:group 'weechat-relay)
|
||||
|
||||
(defun weechat-relay-log (text &optional level)
|
||||
"Log `TEXT' to `weechat-relay-log-buffer-name' if enabled.
|
||||
`LEVEL' might be one of :debug :info :warn :error. Defaults
|
||||
to :info"
|
||||
(let ((log-level-alist '((:debug . 0)
|
||||
(:info . 1)
|
||||
(:warn . 2)
|
||||
(:error . 3))))
|
||||
(when (and (>= (assoc-default (or level :info) log-level-alist)
|
||||
(assoc-default weechat-relay-log-level log-level-alist))
|
||||
weechat-relay-log-level
|
||||
weechat-relay-log-buffer-name)
|
||||
(with-current-buffer (get-buffer-create weechat-relay-log-buffer-name)
|
||||
(let ((old-point (point)))
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-max))
|
||||
(insert (s-trim text))
|
||||
(newline)))
|
||||
(goto-char old-point))))))
|
||||
|
||||
(defun weechat-warn (message &rest args)
|
||||
"Display MESSAGE with `warn' and log it to `weechat-relay-log-buffer-name'."
|
||||
(let ((str (apply 'format message args)))
|
||||
(weechat-relay-log str :warn)
|
||||
(display-warning 'weechat str)))
|
||||
|
||||
(defun weechat-message (format-string &rest args)
|
||||
"Log MESSAGE with log-level :info and call `message'."
|
||||
(let ((text (apply 'format format-string args)))
|
||||
(weechat-relay-log text :info)
|
||||
(message text)))
|
||||
|
||||
(provide 'weechat-core)
|
||||
|
||||
;;; weechat-core.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-core.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-core.elc
Normal file
Binary file not shown.
118
elpa/weechat-20180513.310/weechat-corrector.el
Normal file
118
elpa/weechat-20180513.310/weechat-corrector.el
Normal file
@@ -0,0 +1,118 @@
|
||||
;;; weechat-corrector.el --- Fix your messages using s/foo/bar/ syntax
|
||||
|
||||
;; Copyright (C) 2013 Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; This module implements support to fix your own messages via the
|
||||
;; s/foo/bar/ syntax.
|
||||
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 's)
|
||||
|
||||
(defgroup weechat-corrector nil
|
||||
"This module implements support to fix your own messages via the s/foo/bar/ syntax."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-corrector"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-corrector-search-limit 5
|
||||
"How many previous lines to check for corrections."
|
||||
:type 'integer
|
||||
:group 'weechat-corrector)
|
||||
|
||||
(defcustom weechat-corrector-replace-limit 1
|
||||
"Limit to N replacements."
|
||||
:type 'integer
|
||||
:group 'weechat-corrector)
|
||||
|
||||
(defcustom weechat-corrector-correct-other nil
|
||||
"Whether to apply corrections by other people.
|
||||
|
||||
Warning: Setting this to non-nil MIGHT be a security problem as untrusted
|
||||
regular expression will be interpreted by `re-search-forward'."
|
||||
:type 'boolean
|
||||
:group 'weechat-corrector)
|
||||
|
||||
(defcustom weechat-corrector-support-plain-parentheses nil
|
||||
"If non-nil, s/a(.)c/\1/ will replace 'abc' with 'b'.
|
||||
|
||||
If nil, parentheses must be quotedL s/a\(.\)c/\1/."
|
||||
:type 'boolean
|
||||
:group 'weechat-corrector)
|
||||
|
||||
(defface weechat-corrector-corrected-face '((t :inherit default))
|
||||
"Face used to highlight corrected text."
|
||||
:group 'weechat-corrector)
|
||||
|
||||
(defun weechat-corrector-quote-parentheses (re)
|
||||
(if weechat-corrector-support-plain-parentheses
|
||||
(weechat->>
|
||||
re
|
||||
(s-replace "(" "\\(")
|
||||
(s-replace ")" "\\)"))
|
||||
re))
|
||||
|
||||
(defvar weechat-corrector-regex "s/\\(.+\\)/\\(.*\\)/")
|
||||
(defun weechat-corrector-apply ()
|
||||
(let ((nick (weechat-line-nick))
|
||||
(line (weechat-line-text)))
|
||||
(when (and (or weechat-corrector-correct-other
|
||||
(string= (weechat-line-nick)
|
||||
(weechat-get-local-var "nick")))
|
||||
line
|
||||
(stringp line))
|
||||
(let* ((text-start (weechat-line-text-start))
|
||||
(match (s-match weechat-corrector-regex line)))
|
||||
(when (>= (length match) 3)
|
||||
(let ((re (weechat-corrector-quote-parentheses
|
||||
(cadr match)))
|
||||
(rp (caddr match)))
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-at-bol))
|
||||
(let ((count 0))
|
||||
(dotimes (i weechat-corrector-search-limit)
|
||||
(when (< count weechat-corrector-replace-limit)
|
||||
(save-restriction
|
||||
(let ((line-move-visual nil))
|
||||
(forward-line -1))
|
||||
(weechat-narrow-to-line)
|
||||
(goto-char (weechat-line-text-start))
|
||||
(when (and (string= nick (weechat-line-nick))
|
||||
(re-search-forward re nil t))
|
||||
(replace-match rp)
|
||||
;; Add `weechat-corrector-corrected-face'
|
||||
(add-text-properties (match-beginning 0) (match-end 0)
|
||||
'(face weechat-corrector-corrected-face))
|
||||
(setq count (1+ count)))))))))))))))
|
||||
|
||||
(add-hook 'weechat-insert-modify-hook 'weechat-corrector-apply)
|
||||
|
||||
(provide 'weechat-corrector)
|
||||
|
||||
;;; weechat-corrector.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-corrector.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-corrector.elc
Normal file
Binary file not shown.
338
elpa/weechat-20180513.310/weechat-image.el
Normal file
338
elpa/weechat-20180513.310/weechat-image.el
Normal file
@@ -0,0 +1,338 @@
|
||||
;;; weechat-image --- Image preview ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; TODO: resize, make buffer more beautiful, test test test
|
||||
|
||||
;;; Code:
|
||||
;;
|
||||
|
||||
(require 'weechat)
|
||||
|
||||
;;; Customize:
|
||||
;;
|
||||
|
||||
(defgroup weechat-image nil
|
||||
"Image previews for WeeChat."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-image"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-image-url-regex "\\.\\(png\\|jpe?g\\|gif\\|svg\\)"
|
||||
"Regexp to match image URLs.
|
||||
This gets called on a URL matched with `thing-at-point' and `url'."
|
||||
:type 'regexp
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-url-blacklist-regex "/\\(Datei\\|File\\):"
|
||||
"Blacklist for image URLs.
|
||||
E.g., for Wikipedia links starting with File:. They do not link directly to the image."
|
||||
:type 'regexp
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-display-func #'weechat-image-insert-inline
|
||||
"Function to call to insert image.
|
||||
The Function should accept the following parameter (URL IMAGE BUFFER MARKER)."
|
||||
:type '(choice (const :tag "Inline" weechat-image-insert-inline)
|
||||
(const :tag "Other Buffer" weechat-image-insert-other-buffer)
|
||||
(function :tag "Call function"))
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-buffer "*WeeChat Image Buffer*"
|
||||
"Buffer used if `weechat-image-display-func' is set to ``Other Buffer''."
|
||||
:type 'string
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-use-imagemagick (fboundp 'imagemagick-types)
|
||||
;; TODO is there a better way to identify if emacs has imagemagick support?
|
||||
"Use ImageMagick to load images."
|
||||
:type 'boolean
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-size-limit (* 1024 1024) ;; 1M
|
||||
"Size limit for images."
|
||||
:type '(choice (const :tag "No limit" nil)
|
||||
(integer :tag "Size limit in bytes"))
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-max-width (/ (frame-pixel-width nil) 2)
|
||||
"Max image width.
|
||||
If `weechate-image-size' is non-nil the image is resized. Be aware that
|
||||
`weechat-image-size-limit' is checked before."
|
||||
:type '(choice (const :tag "No limit" nil)
|
||||
(integer :tag "Max width in pixel"))
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-max-height nil
|
||||
"Max image height.
|
||||
If `weechate-image-size' is non-nil the image is resized. Be aware that
|
||||
`weechat-image-size-limit' is checked before."
|
||||
:type '(choice (const :tag "No limit" nil)
|
||||
(integer :tag "Max height in pixel"))
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-resize weechat-image-use-imagemagick
|
||||
"Resize image if it's larger than `weechat-image-max-width' and
|
||||
`weechat-image-max-height'. This only works if imagemagick is used.
|
||||
See `weechat-image-use-imagemagick'."
|
||||
:type 'boolean
|
||||
:group 'weechat-image)
|
||||
|
||||
(defcustom weechat-image-time-format "%Y-%m-%dT%T%z" ;; ISO 8601
|
||||
"Timestamp format used in `weechat-image-buffer'.
|
||||
See `format-time-string'."
|
||||
:type 'string
|
||||
:group 'weechat-image)
|
||||
|
||||
(defun weechat-image--remove (button)
|
||||
"Remove image associated with BUTTON."
|
||||
(let ((start (button-get button 'weechat-image-begin))
|
||||
(end (button-get button 'weechat-image-end)))
|
||||
(remove-images start end)
|
||||
(delete-region (1- (overlay-start button)) (overlay-end button))
|
||||
(delete-overlay button)
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(narrow-to-region (line-beginning-position) (line-end-position))
|
||||
(let ((inhibit-read-only t))
|
||||
(weechat-image--add-preview-button))))))
|
||||
|
||||
(defun weechat-image-insert-inline (url image buffer marker)
|
||||
"Insert IMAGE after MARKER in buffer."
|
||||
(with-current-buffer buffer
|
||||
(goto-char marker)
|
||||
(let ((button (button-at marker)))
|
||||
(delete-region (overlay-start button) (overlay-end button))
|
||||
(delete-overlay button))
|
||||
(let ((button-start (point)) button-end image-start)
|
||||
(insert "[-]")
|
||||
(setq button-end (point))
|
||||
(end-of-line)
|
||||
(setq image-start (point))
|
||||
(put-image image image-start)
|
||||
(make-button button-start button-end
|
||||
'action #'weechat-image--remove
|
||||
'help-wecho "Remove Preview"
|
||||
'follow-link t
|
||||
'weechat-image-begin image-start
|
||||
'weechat-image-end (point))))
|
||||
(message "Inserted inline %s %s %s" url buffer marker))
|
||||
|
||||
(defun weechat-image-view-next ()
|
||||
"Go to next image."
|
||||
(interactive)
|
||||
(search-forward "URL:" nil t))
|
||||
|
||||
(defun weechat-image-view-previous ()
|
||||
"Go to previous image."
|
||||
(interactive)
|
||||
(search-backward "URL:" nil t))
|
||||
|
||||
(defun weechat-image-view-remove-entry ()
|
||||
"Remove current entry."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(let ((beg
|
||||
(if (looking-at "^URL:")
|
||||
(point)
|
||||
(search-backward "URL:" nil t)))
|
||||
(end (progn
|
||||
(end-of-line)
|
||||
(search-forward "URL:" nil t))))
|
||||
(if end
|
||||
(setq end (- end 4))
|
||||
(setq end (point-max)))
|
||||
(let ((inhibit-read-only t))
|
||||
(remove-images beg end)
|
||||
(delete-region beg end)))))
|
||||
|
||||
(defun weechat-image-view-clear ()
|
||||
"Clear image view buffer."
|
||||
(interactive)
|
||||
(when (and (called-interactively-p 'interactive)
|
||||
(y-or-n-p "Clear buffer? "))
|
||||
(let ((inhibit-read-only t))
|
||||
(remove-images (point-min) (point-max))
|
||||
(erase-buffer))))
|
||||
|
||||
(defvar weechat-image-view-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "p" #'weechat-image-view-previous)
|
||||
(define-key map "n" #'weechat-image-view-next)
|
||||
(define-key map "c" #'weechat-image-view-clear)
|
||||
(define-key map "k" #'weechat-image-view-remove-entry)
|
||||
map)
|
||||
"Keymap for `weechat-image-view-mode'.")
|
||||
|
||||
(easy-menu-define weechat-image-view-mode-menu weechat-image-view-mode-map
|
||||
"WeeChat Image"
|
||||
'("WeeChatImage"
|
||||
["Previous Image" weechat-image-view-previous t]
|
||||
["Next Image" weechat-image-view-next t]
|
||||
["Remove Image" weechat-image-view-remove-entry t]
|
||||
["Clear Buffer" weechat-image-view-clear t]))
|
||||
|
||||
(define-derived-mode weechat-image-view-mode special-mode "WeechatImage"
|
||||
"Mode for the weechat-image viewer
|
||||
|
||||
\{weechat-image-view-mode-map}"
|
||||
:group 'weechat-image)
|
||||
|
||||
(defun weechat-image-insert-other-buffer (url image buffer marker)
|
||||
"Insert IMAGE into `weechat-image-buffer'."
|
||||
(with-current-buffer (get-buffer-create weechat-image-buffer)
|
||||
(weechat-image-view-mode)
|
||||
(goto-char (point-max))
|
||||
(let ((inhibit-read-only t))
|
||||
(unless (bolp)
|
||||
(insert "\n"))
|
||||
(insert "URL: ")
|
||||
(insert-button url
|
||||
'action (lambda (button)
|
||||
(browse-url (button-get button 'weechat-image-url)))
|
||||
'help-echo "Browse URL"
|
||||
'follow-link t
|
||||
'weechat-image-url url)
|
||||
(insert "\n")
|
||||
(let ((channel-name (buffer-name buffer)))
|
||||
(insert "Channel: ")
|
||||
(insert-button channel-name
|
||||
'action (lambda (button)
|
||||
(let ((buf (button-get button 'weechat-image-buffer))
|
||||
(mark (button-get button 'weechat-image-marker)))
|
||||
(when (buffer-live-p buf)
|
||||
(switch-to-buffer buf)
|
||||
(with-current-buffer buf
|
||||
(goto-char mark)))))
|
||||
'help-echo "Goto buffer"
|
||||
'follow-link t
|
||||
'weechat-image-buffer buffer
|
||||
'weechat-image-marker marker)
|
||||
(insert "\n"))
|
||||
(let (nick date)
|
||||
(with-current-buffer buffer
|
||||
(goto-char marker)
|
||||
(beginning-of-line)
|
||||
(setq nick (get-text-property (point) 'weechat-nick))
|
||||
(setq date (get-text-property (point) 'weechat-date)))
|
||||
(when date
|
||||
(insert "Date: " (format-time-string weechat-image-time-format date) "\n"))
|
||||
(when nick
|
||||
(insert "By: ")
|
||||
(insert-button nick
|
||||
'action (lambda (button)
|
||||
(let ((buf (button-get button 'weechat-image-buffer))
|
||||
(nick (button-get button 'weechat-image-nick)))
|
||||
(with-current-buffer buf
|
||||
(weechat-nick-action nick))))
|
||||
'help-echo "Nick Actions"
|
||||
'follow-link t
|
||||
'weechat-image-buffer buffer
|
||||
'weechat-image-nick nick)
|
||||
(insert "\n")))
|
||||
(put-image image (point))
|
||||
(insert "\n")))
|
||||
(message "Added new image to %s" weechat-image-buffer)
|
||||
(switch-to-buffer weechat-image-buffer))
|
||||
|
||||
(defun weechat-image-resize (image what px)
|
||||
"Resize IMAGE.
|
||||
WHAT should be either `:width' or `:height' and PX is the new size in pixel.
|
||||
This function is a no-op if `weechat-image-use-imagemagick' is nil."
|
||||
(if weechat-image-use-imagemagick
|
||||
(or (create-image (plist-get (cdr image) :data) 'imagemagick t
|
||||
what px)
|
||||
image)
|
||||
image))
|
||||
|
||||
(defun weechat-image--get-image (_status url buffer marker)
|
||||
(goto-char (point-min))
|
||||
(unless (looking-at "^HTTP/.+ 200 OK$")
|
||||
(kill-buffer)
|
||||
(error "Error while fetching image `%s'" url))
|
||||
(unless (search-forward "\n\n" nil t)
|
||||
(kill-buffer)
|
||||
(error "Error while fetching image `%s'. Malformed http reply" url))
|
||||
(when (and weechat-image-size-limit
|
||||
(> (- (point-max) (point)) weechat-image-size-limit))
|
||||
(kill-buffer)
|
||||
(error "Image %s is too large (%s bytes)" url (- (point-max) (point))))
|
||||
(let* ((image (create-image (buffer-substring (point) (point-max))
|
||||
(if weechat-image-use-imagemagick
|
||||
'imagemagick
|
||||
nil)
|
||||
t))
|
||||
(size (image-size image 'pixels)))
|
||||
(unless image
|
||||
(kill-buffer)
|
||||
(error "Image type not supported or not an image."))
|
||||
(when (and weechat-image-max-width
|
||||
(> (car size) weechat-image-max-width))
|
||||
(if weechat-image-resize
|
||||
(setq image (weechat-image-resize image :width weechat-image-max-width))
|
||||
(kill-buffer)
|
||||
(error "Image %s is too wide (%s px)" url (car size))))
|
||||
(when (and weechat-image-max-height
|
||||
(> (cdr size) weechat-image-max-height))
|
||||
(if weechat-image-resize
|
||||
(setq image (weechat-image-resize image :height weechat-image-max-width))
|
||||
(kill-buffer)
|
||||
(error "Image %s is too heigh (%s px)" url (cdr size))))
|
||||
(kill-buffer)
|
||||
(funcall weechat-image-display-func url image buffer marker)))
|
||||
|
||||
(defun weechat-image--do-preview (button)
|
||||
(let ((url (button-get button 'weechat-image-url))
|
||||
(buffer (button-get button 'weechat-image-buffer))
|
||||
(marker (button-get button 'weechat-image-marker)))
|
||||
(url-queue-retrieve url
|
||||
#'weechat-image--get-image
|
||||
(list url buffer marker))))
|
||||
|
||||
(defun weechat-image--add-preview-button ()
|
||||
"Add preview buttons after image urls."
|
||||
(goto-char (point-min))
|
||||
(search-forward "http" nil t)
|
||||
(let ((url (thing-at-point 'url)))
|
||||
(when (and url
|
||||
(s-matches? weechat-image-url-regex url)
|
||||
(not (s-matches? weechat-image-url-blacklist-regex url)))
|
||||
(end-of-thing 'url)
|
||||
(insert " ")
|
||||
(insert-button "[+]"
|
||||
'action #'weechat-image--do-preview
|
||||
'help-echo "Preview Image"
|
||||
'follow-link t
|
||||
'weechat-image-marker (point)
|
||||
'weechat-image-buffer (current-buffer)
|
||||
'weechat-image-url url)
|
||||
(unless (or (eolp) (looking-at "[[:space:]]"))
|
||||
(insert " ")))))
|
||||
|
||||
(add-hook 'weechat-insert-modify-hook #'weechat-image--add-preview-button)
|
||||
|
||||
(provide 'weechat-image)
|
||||
|
||||
;;; weechat-image.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-image.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-image.elc
Normal file
Binary file not shown.
186
elpa/weechat-20180513.310/weechat-latex.el
Normal file
186
elpa/weechat-20180513.310/weechat-latex.el
Normal file
@@ -0,0 +1,186 @@
|
||||
;;; weechat-latex --- Add LateX preview -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; The LaTeX preview is based on `org-mode's `org-format-latex'
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 'org)
|
||||
|
||||
(defgroup weechat-latex nil
|
||||
"WeeChat LaTeX preview."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-latex"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-latex-temp-file-prefix "weechat-latex"
|
||||
"Prefix for temporary files."
|
||||
:type 'string
|
||||
:group 'weechat-latex)
|
||||
|
||||
(defcustom weechat-latex-temp-directory-prefix "weechat-latex"
|
||||
"Prefix for temporary directory."
|
||||
:type 'string
|
||||
:group 'weechat-latex)
|
||||
|
||||
(defcustom weechat-latex-image-program org-latex-create-formula-image-program
|
||||
"Program to convert LaTeX fragments.
|
||||
See `org-latex-create-formula-image-program'"
|
||||
:type '(choice
|
||||
(const :tag "dvipng" dvipng)
|
||||
(const :tag "imagemagick" imagemagick))
|
||||
:group 'weechat-latex)
|
||||
|
||||
(defvar weechat-latex-temp-dir nil
|
||||
"The temporary directory used for preview images.")
|
||||
|
||||
(defun weechat-latex--create-preview (at)
|
||||
"Wrapper for `org-format-latex'.
|
||||
The parameter AT should be nil or in (TYPE . POINT) format. With TYPE being a
|
||||
string showing the matched LaTeX statement (e.g., ``$'') and POINT being the
|
||||
POINT to replace. If AT is nil replace statements everywhere."
|
||||
(org-format-latex weechat-latex-temp-file-prefix
|
||||
weechat-latex-temp-dir
|
||||
'overlays
|
||||
"Creating images...%s"
|
||||
at 'forbuffer
|
||||
weechat-latex-image-program))
|
||||
|
||||
(defun weechat-latex--set-temp-dir ()
|
||||
"Set `weechat-latex-temp-dir' unless it is already set."
|
||||
(unless weechat-latex-temp-dir
|
||||
(setq weechat-latex-temp-dir
|
||||
(make-temp-file weechat-latex-temp-directory-prefix
|
||||
'directory))))
|
||||
|
||||
(defun weechat-latex-preview ()
|
||||
"Preview LaTeX fragments."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(let ((inhibit-read-only t))
|
||||
(weechat-latex--set-temp-dir)
|
||||
(org-remove-latex-fragment-image-overlays)
|
||||
(weechat-latex--create-preview nil))))
|
||||
|
||||
(defun weechat-latex-preview-region (beg end)
|
||||
"Preview LaTeX fragments in region."
|
||||
(interactive "r")
|
||||
(let* ((math-regex (assoc "$" org-latex-regexps))
|
||||
(regex (nth 1 math-regex))
|
||||
(n (nth 2 math-regex))
|
||||
matches)
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(while (re-search-forward regex end t)
|
||||
(setq matches (cons (cons "$" (match-beginning n)) matches)))
|
||||
(let ((inhibit-read-only t))
|
||||
(weechat-latex--set-temp-dir)
|
||||
(dolist (i matches)
|
||||
(weechat-latex--create-preview i))))))
|
||||
|
||||
(defvar weechat-prompt-start-marker) ;; See weechat.el
|
||||
(defun weechat-latex-preview-line ()
|
||||
"Preview LaTeX fragments in line."
|
||||
(interactive)
|
||||
(weechat-latex-preview-region (point-at-bol)
|
||||
(min (point-at-eol)
|
||||
weechat-prompt-start-marker)))
|
||||
|
||||
(defun weechat-latex-remove ()
|
||||
"Remove LaTeX preview images."
|
||||
(interactive)
|
||||
(let ((inhibit-read-only t))
|
||||
(org-remove-latex-fragment-image-overlays)))
|
||||
|
||||
(defun weechat-latex-is-active? ()
|
||||
"Are LaTeX Previews currently displayed?"
|
||||
org-latex-fragment-image-overlays)
|
||||
|
||||
(defun weechat-latex-toggle ()
|
||||
"Toggle display of LaTeX preview."
|
||||
(interactive)
|
||||
(if (weechat-latex-is-active?)
|
||||
(weechat-latex-remove)
|
||||
(weechat-latex-preview)))
|
||||
|
||||
;;; auto mode
|
||||
|
||||
(defun weechat-latex--do-auto-mode ()
|
||||
"Hook for auto LaTeX preview."
|
||||
(weechat-latex-preview-region (point-min) (point-max)))
|
||||
|
||||
(defun weechat-latex-is-auto-mode-active? ()
|
||||
"Is auto LaTeX preview active?"
|
||||
(memq #'weechat-latex--do-auto-mode weechat-insert-modify-hook))
|
||||
|
||||
(defcustom weechat-latex-auto-mode-line-string " LaTeX-Preview"
|
||||
"String displayed in mode line when `weechat-latex-auto-mode' is active."
|
||||
:type 'string
|
||||
:group 'weechat-latex)
|
||||
|
||||
(defcustom weechat-latex-auto-mode-preview-all t
|
||||
"Show preview for existing LaTeX fragmetns if auto mode is activated?"
|
||||
:type 'boolean
|
||||
:group 'weechat-latex)
|
||||
|
||||
(define-minor-mode weechat-latex-auto-mode
|
||||
"Automatically display LaTeX preview."
|
||||
:lighter weechat-latex-auto-mode-line-string
|
||||
:group 'weechat-latex
|
||||
(if weechat-latex-auto-mode
|
||||
(progn
|
||||
(when weechat-latex-auto-mode-preview-all
|
||||
(weechat-latex-preview))
|
||||
(add-hook 'weechat-insert-modify-hook #'weechat-latex--do-auto-mode))
|
||||
(remove-hook 'weechat-insert-modify-hook #'weechat-latex--do-auto-mode)))
|
||||
|
||||
;;; module
|
||||
|
||||
(easy-menu-add-item weechat-mode-menu nil
|
||||
["LaTeX Preview" weechat-latex-toggle
|
||||
:style toggle
|
||||
:selected (weechat-latex-is-active?)
|
||||
:help "If selected show LaTeX preview for existing buffer."]
|
||||
"Toggle Hidden Lines")
|
||||
|
||||
(easy-menu-add-item weechat-mode-menu nil
|
||||
["LaTeX Auto Preview" weechat-latex-auto-mode
|
||||
:style toggle
|
||||
:selected (weechat-latex-is-auto-mode-active?)
|
||||
:help "If selected automatically show LaTeX preview for new messages."]
|
||||
"Toggle Hidden Lines")
|
||||
|
||||
(defun weechat-latex-unload-function ()
|
||||
"Cleanup WeeChat LaTex module."
|
||||
(weechat-latex-auto-mode -1)
|
||||
(weechat-latex-remove)
|
||||
(easy-menu-remove-item weechat-mode-menu nil "LaTeX Preview")
|
||||
(easy-menu-remove-item weechat-mode-menu nil "LaTeX Auto Preview"))
|
||||
|
||||
(provide 'weechat-latex)
|
||||
|
||||
;;; weechat-latex.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-latex.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-latex.elc
Normal file
Binary file not shown.
119
elpa/weechat-20180513.310/weechat-notifications.el
Normal file
119
elpa/weechat-20180513.310/weechat-notifications.el
Normal file
@@ -0,0 +1,119 @@
|
||||
;;; weechat-notifications --- notifications.el based notifications. ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Notifications based on notifications.el. Shipped with Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 'notifications)
|
||||
(require 'xml) ;; For `xml-escape-string'
|
||||
|
||||
(defgroup weechat-notifications nil
|
||||
"Notifications based on notifications.el."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-notifications-"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-notifications-icon #'weechat-notifications-icon-function
|
||||
"Icon used in notifications.
|
||||
Either nil, a file-name, or a function which is called with (SENDER BUFFER-PTR)."
|
||||
:type '(choice (const :tag "No icon" nil)
|
||||
(file :tag "Icon file")
|
||||
(function :tag "Icon function"))
|
||||
:group 'weechat-notifications)
|
||||
|
||||
(defcustom weechat-notifications-sound t
|
||||
"Sound to use for notifications:
|
||||
- nil: No sound
|
||||
- t: default message-new-instant sound
|
||||
- string: file name of a sound file."
|
||||
:type '(choice (const :tag "No sound" nil)
|
||||
(const :tag "Default system sound" t)
|
||||
(file :tag "Sound file"))
|
||||
:group 'weechat-notifications)
|
||||
|
||||
(defun weechat-notifications-icon-function (_sender _buffer-ptr)
|
||||
"Default icon."
|
||||
(when (boundp 'notifications-application-icon)
|
||||
notifications-application-icon))
|
||||
|
||||
(defvar weechat--notifications-id-to-msg nil
|
||||
"Map notification ids to buffer-ptrs.")
|
||||
|
||||
(defun weechat--notifications-action (id key)
|
||||
"Handle notifcations.el actions.
|
||||
See `weechat-notifications-handler'.
|
||||
|
||||
Supported actions:
|
||||
- read: switch to buffer."
|
||||
(when (string= key "view")
|
||||
(let* ((buffer-ptr (cdr (assoc id weechat--notifications-id-to-msg))))
|
||||
(when buffer-ptr
|
||||
(weechat-switch-buffer buffer-ptr)))))
|
||||
|
||||
(defun weechat-notifications-handler (type &optional sender text _date buffer-ptr)
|
||||
"Notification handler using notifications.el."
|
||||
(let ((notifications-id
|
||||
(notifications-notify
|
||||
:title (xml-escape-string
|
||||
(or (cl-case type
|
||||
(:highlight
|
||||
(concat "Weechat.el: Message from <"
|
||||
(weechat-strip-formatting sender)
|
||||
">"))
|
||||
(:query
|
||||
(concat "Weechat.el: Query from <"
|
||||
(weechat-strip-formatting sender)
|
||||
">"))
|
||||
(:disconnect "Disconnected from WeeChat"))
|
||||
""))
|
||||
:body (when text (xml-escape-string text))
|
||||
:category "im.received"
|
||||
:actions '("view" "View")
|
||||
:on-action #'weechat--notifications-action
|
||||
:app-icon (cl-typecase weechat-notifications-icon
|
||||
(string weechat-notifications-icon)
|
||||
(function (funcall weechat-notifications-icon
|
||||
sender buffer-ptr)))
|
||||
:app-name "WeeChat.el"
|
||||
:sound-name (when (and weechat-notifications-sound
|
||||
(not (stringp weechat-notifications-sound)))
|
||||
"message-new-instant")
|
||||
:sound-file (when (stringp weechat-notifications-sound)
|
||||
weechat-notifications-sound)
|
||||
:replaces-id (caar weechat--notifications-id-to-msg))))
|
||||
(when notifications-id
|
||||
(setq weechat--notifications-id-to-msg
|
||||
(append (list (cons notifications-id buffer-ptr))
|
||||
weechat--notifications-id-to-msg)))))
|
||||
|
||||
(add-hook 'weechat-notification-handler-functions
|
||||
#'weechat-notifications-handler)
|
||||
|
||||
(provide 'weechat-notifications)
|
||||
|
||||
;;; weechat-notifications.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-notifications.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-notifications.elc
Normal file
Binary file not shown.
8
elpa/weechat-20180513.310/weechat-pkg.el
Normal file
8
elpa/weechat-20180513.310/weechat-pkg.el
Normal file
@@ -0,0 +1,8 @@
|
||||
(define-package "weechat" "20180513.310" "Chat via WeeChat's relay protocol in Emacs"
|
||||
'((s "1.3.1")
|
||||
(cl-lib "0.2")
|
||||
(emacs "24")
|
||||
(tracking "1.2")))
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
143
elpa/weechat-20180513.310/weechat-read-marker.el
Normal file
143
elpa/weechat-20180513.310/weechat-read-marker.el
Normal file
@@ -0,0 +1,143 @@
|
||||
;;; weechat-read-marker.el --- read marker for WeeChat -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2015 Hans-Peter Deifel
|
||||
|
||||
;; Author: Hans-Peter Deifel <hpd@hpdeifel.de>
|
||||
;; Created: 22 Jun 2015
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License as
|
||||
;; published by the Free Software Foundation; either version 2, or (at
|
||||
;; your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful, but
|
||||
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;; General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Draw a thin red line between the read and unread lines in a buffer.
|
||||
|
||||
;;; See `M-x customize-group weechat-read-marker' for configuration options.
|
||||
|
||||
;;; If anything goes wrong, the read marker can be manually reset with
|
||||
;;; `weechat-read-marker-reset'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
|
||||
(defgroup weechat-read-marker nil
|
||||
"Read marker for WeeChat"
|
||||
:prefix "weechat-read-marker"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-read-marker-char ?─
|
||||
"Character used to render the read marker."
|
||||
:type 'character
|
||||
:group 'weechat-read-marker)
|
||||
|
||||
(defface weechat-read-marker
|
||||
'((t :foreground "brown"))
|
||||
"Face used to colorize the read marker."
|
||||
:group 'weechat-read-marker)
|
||||
|
||||
(defcustom weechat-read-marker-always-show nil
|
||||
"Always show read marker, even if it is after last buffer line.
|
||||
|
||||
A value of t means that the read marker is displayed directly
|
||||
over the prompt, if there are no unread lines. With nil, the
|
||||
marker is simply not displayed in this case."
|
||||
:type 'boolean
|
||||
:group 'weechat-read-marker)
|
||||
|
||||
(defvar-local weechat-read-marker-overlay nil
|
||||
"The overlay used to draw the read marker.
|
||||
|
||||
Will be nil initially and if the buffer has no unread lines when
|
||||
`weechat-read-marker-always-show` is not set.")
|
||||
|
||||
(defvar-local weechat-read-marker-stale t
|
||||
"Whether the read marker position is outdated.
|
||||
|
||||
This will be set if the buffer is visited, to indicate that the
|
||||
unread lines are now read.")
|
||||
|
||||
(defun weechat-read-marker--set-overlay ()
|
||||
"Update the `after-string' property on an already existing overlay."
|
||||
(let* ((width (- (window-width) 1))
|
||||
(line (make-string width weechat-read-marker-char)))
|
||||
(overlay-put weechat-read-marker-overlay 'after-string
|
||||
(concat "\n" (propertize line 'face 'weechat-read-marker)))))
|
||||
|
||||
(defun weechat-read-marker--move-overlay ()
|
||||
"Update the read marker in the current buffer."
|
||||
(if weechat-read-marker-overlay
|
||||
(move-overlay weechat-read-marker-overlay (point-at-bol) (point-at-eol))
|
||||
(setq weechat-read-marker-overlay
|
||||
(make-overlay (point-at-bol) (point-at-eol) nil t nil))
|
||||
;; Delete overlay if text is deleted. This is needed to get rid of the
|
||||
;; overlay, when the buffer is reset.
|
||||
(overlay-put weechat-read-marker-overlay 'evaporate t))
|
||||
|
||||
(weechat-read-marker--set-overlay))
|
||||
|
||||
(defun weechat-read-marker-handle-visited ()
|
||||
"Reset read marker after a buffer is being visited."
|
||||
(if weechat-read-marker-stale
|
||||
;; we haven't had any new lines. Reset overlay
|
||||
(when weechat-read-marker-overlay
|
||||
(if weechat-read-marker-always-show
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(forward-line -1)
|
||||
(weechat-read-marker--move-overlay))
|
||||
(delete-overlay weechat-read-marker-overlay)
|
||||
(setq weechat-read-marker-overlay nil)))
|
||||
;; otherwise, set the read marker to be stale
|
||||
(setq weechat-read-marker-stale t)
|
||||
;; and also recompute the overlay string, since the window-width could have
|
||||
;; changed
|
||||
(when weechat-read-marker-overlay
|
||||
(weechat-read-marker--set-overlay))))
|
||||
|
||||
(defun weechat-read-marker-handle-background ()
|
||||
"Move read-marker in case it is stale."
|
||||
(when weechat-read-marker-stale
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(unless (< (line-number-at-pos) 3)
|
||||
(forward-line -2)
|
||||
(weechat-read-marker--move-overlay)
|
||||
(setq weechat-read-marker-stale nil)))))
|
||||
|
||||
(defun weechat-read-marker-reset ()
|
||||
"Manually reset the read marker in the current buffer."
|
||||
(interactive "")
|
||||
(when weechat-read-marker-overlay
|
||||
;; Always delete (and possibly) recreate overlay in case anything went wrong
|
||||
;; and the users used this command to reset things.
|
||||
(delete-overlay weechat-read-marker-overlay)
|
||||
(if weechat-read-marker-always-show
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(forward-line -1)
|
||||
(weechat-read-marker--set-overlay))
|
||||
(setq weechat-read-marker-overlay nil)))
|
||||
(setq weechat-read-marker-stale t))
|
||||
|
||||
|
||||
(add-hook 'weechat-buffer-background-message-hook
|
||||
'weechat-read-marker-handle-background)
|
||||
(add-hook 'weechat-buffer-visited-hook
|
||||
'weechat-read-marker-handle-visited)
|
||||
|
||||
(provide 'weechat-read-marker)
|
||||
|
||||
;;; weechat-read-marker.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-read-marker.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-read-marker.elc
Normal file
Binary file not shown.
632
elpa/weechat-20180513.310/weechat-relay.el
Normal file
632
elpa/weechat-20180513.310/weechat-relay.el
Normal file
@@ -0,0 +1,632 @@
|
||||
;;; weechat-relay --- Implementation of Weechat's relay protocol ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Moritz Ulrich
|
||||
|
||||
;; Author: Moritz Ulrich (moritz@tarn-vedra.de)
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file implements low-level code used by weechat.el to connect
|
||||
;; to remote WeeChat instances using the relay protocol:
|
||||
|
||||
;; http://www.weechat.org/files/doc/devel/weechat_relay_protocol.en.html
|
||||
|
||||
(require 'weechat-core)
|
||||
|
||||
(require 'bindat)
|
||||
(require 'format-spec)
|
||||
(require 's)
|
||||
(require 'pp)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defcustom weechat-relay-buffer-name "*weechat-relay*"
|
||||
"Buffer holding the connection to the host weechat instance."
|
||||
:type 'string
|
||||
:group 'weechat-relay)
|
||||
|
||||
(defcustom weechat-relay-message-function nil
|
||||
"Function to call when receiving a new weechat message."
|
||||
:type '(choice (const :tag "Off" nil)
|
||||
(function :tag "Callback Function"))
|
||||
:group 'weechat-relay)
|
||||
|
||||
(defvar weechat-relay-ignored-message-ids '("_nicklist")
|
||||
"IDs to ignore.")
|
||||
|
||||
(defcustom weechat-relay-disconnect-hook nil
|
||||
"Hook run when the relay disconnects.
|
||||
It will NOT run when the user disconnects via
|
||||
`weechat-disconnect'."
|
||||
:type 'hook
|
||||
:group 'weechat-relay)
|
||||
|
||||
(defcustom weechat-relay-connect-hook nil
|
||||
"Hook run when the relay connects.
|
||||
Note: This DOES NOT mean the client can is already authenticated
|
||||
to the relay server."
|
||||
:type 'hook
|
||||
:group 'weechat-relay)
|
||||
|
||||
(defcustom weechat-relay-ping-idle-seconds 60
|
||||
"Idle time in seconds after weechat.el will ping the server."
|
||||
:type '(choice integer
|
||||
(const nil))
|
||||
:group 'weechat-relay)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defvar weechat--relay-id-callback-hash (make-hash-table :test 'equal)
|
||||
"Alist mapping from ids to functions.
|
||||
Incoming message-ids will be searched in this alist and the
|
||||
corresponding function will be called.")
|
||||
|
||||
(defun weechat--relay-send-message (text &optional id)
|
||||
"Send message TEXT with optional ID.
|
||||
Trim TEXT prior to sending it."
|
||||
(let ((msg (concat (when id (format "(%s) " id)) (s-trim text) "\n")))
|
||||
(weechat-relay-log (format "Sending msg: '%s'" (s-trim msg))
|
||||
:debug)
|
||||
(let ((process (get-buffer-process weechat-relay-buffer-name)))
|
||||
(if process
|
||||
(send-string process msg)
|
||||
(weechat-warn "`get-buffer-process' returned nil for `weechat-relay-buffer-name'")))))
|
||||
|
||||
(defun weechat-relay-authenticate (password &optional compression)
|
||||
"Authenticate to weechat with PASSWORD.
|
||||
|
||||
PASSWORD can be a string, a function or nil.
|
||||
|
||||
If COMPRESSION is non-nil, enable compression on this connection.
|
||||
Currently unsupported."
|
||||
(cl-assert (or (null password)
|
||||
(stringp password)
|
||||
(functionp password)))
|
||||
(let ((pass (if (functionp password)
|
||||
(funcall password)
|
||||
password)))
|
||||
(when (stringp pass)
|
||||
(setq pass (if (s-blank? (s-trim pass))
|
||||
nil
|
||||
(s-trim pass))))
|
||||
(weechat--relay-send-message
|
||||
(concat "init "
|
||||
(s-join ","
|
||||
(cl-remove-if #'s-blank?
|
||||
(list
|
||||
(when pass (format "password=%s" (s-trim pass)))
|
||||
(format "compression=%s" (if compression "zlib" "off")))))
|
||||
"\n"))))
|
||||
|
||||
(defun weechat--relay-bindat-unsigned-to-signed (num bytes)
|
||||
"Convert an unsigned int NUM to signed int.
|
||||
NUM is in two-complement representation with BYTES bytes.
|
||||
Useful because bindat does not support signed numbers."
|
||||
(if (> num (- (expt 2 (- (* 8 bytes) 1)) 1))
|
||||
(- num (expt 2 (* 8 bytes)))
|
||||
num))
|
||||
|
||||
(defun weechat--relay-unpack-int (data)
|
||||
"Unpack a four-byte signed integer from unibyte string DATA.
|
||||
Return the value and number of bytes consumed."
|
||||
(cl-values
|
||||
(weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field
|
||||
(bindat-unpack '((val u32)) data)
|
||||
'val)
|
||||
4)
|
||||
4))
|
||||
|
||||
(defconst weechat--relay-lon-spec
|
||||
'((len u8)
|
||||
(val str (eval (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field struct 'len)
|
||||
1)))))
|
||||
|
||||
(defun weechat--relay-unpack-lon (data)
|
||||
(let ((obj (bindat-unpack weechat--relay-lon-spec data)))
|
||||
(cl-values (string-to-number (decode-coding-string (bindat-get-field obj 'val) 'utf-8))
|
||||
(bindat-length weechat--relay-lon-spec obj))))
|
||||
|
||||
(defun weechat--relay-unpack-chr (data)
|
||||
"Unpack a one byte char from unibyte string DATA.
|
||||
Returns value and bytes consumed."
|
||||
(cl-values
|
||||
(bindat-get-field
|
||||
(bindat-unpack '((val u8)) data)
|
||||
'val)
|
||||
1))
|
||||
|
||||
(defconst weechat--relay-str-spec
|
||||
'((len u32)
|
||||
(val str (eval (let ((len (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field struct 'len)
|
||||
4)))
|
||||
;; Hack for signed/unsigned problems
|
||||
(if (<= len 0) 0 len))))))
|
||||
|
||||
(defun weechat--relay-unpack-str (data)
|
||||
"Unpacks a weechat-relay-string from unibyte string DATA.
|
||||
Optional second return value contains length of parsed data."
|
||||
(let ((obj (bindat-unpack weechat--relay-str-spec data)))
|
||||
(cl-values (decode-coding-string (bindat-get-field obj 'val) 'utf-8)
|
||||
(bindat-length weechat--relay-str-spec obj))))
|
||||
|
||||
(defconst weechat--relay-buf-spec
|
||||
'((len u32)
|
||||
(val vec (eval (let ((len (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field struct 'len)
|
||||
4)))
|
||||
;; Hack for signed/unsigned problems
|
||||
(if (<= len 0) 0 len))))))
|
||||
|
||||
(defun weechat--relay-unpack-buf (data)
|
||||
(let ((obj (bindat-unpack weechat--relay-buf-spec data)))
|
||||
(cl-values (bindat-get-field obj 'val)
|
||||
(bindat-length weechat--relay-buf-spec obj))))
|
||||
|
||||
(defconst weechat--relay-ptr-spec
|
||||
'((len u8)
|
||||
(val str (eval (let ((len (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field struct 'len)
|
||||
1)))
|
||||
;; Hack for signed/unsigned problems
|
||||
(if (<= len 0) 0 len))))))
|
||||
|
||||
(defun weechat--relay-unpack-ptr (data)
|
||||
"Unpack a string encoded in weechat's binary representation.
|
||||
DATA must be an unibyte string. Return string-value and number
|
||||
of bytes consumed."
|
||||
(let ((obj (bindat-unpack weechat--relay-ptr-spec data)))
|
||||
(cl-values (unless (string= "0" (bindat-get-field obj 'val))
|
||||
(concat "0x" (bindat-get-field obj 'val)))
|
||||
(bindat-length weechat--relay-ptr-spec obj))))
|
||||
|
||||
(defconst weechat--relay-tim-spec
|
||||
'((len u8)
|
||||
(val str (eval (let ((len (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field struct 'len)
|
||||
1)))
|
||||
;; Hack for signed/unsigned problems
|
||||
(if (<= len 0) 0 len))))))
|
||||
|
||||
(defun weechat--relay-unpack-tim (data)
|
||||
(let ((obj (bindat-unpack weechat--relay-tim-spec data)))
|
||||
(cl-values (let ((val (string-to-number
|
||||
(bindat-get-field obj 'val))))
|
||||
(unless (zerop val)
|
||||
(seconds-to-time val)))
|
||||
(bindat-length weechat--relay-tim-spec obj))))
|
||||
|
||||
(defconst weechat--relay-htb-spec
|
||||
'((key-type str 3)
|
||||
(val-type str 3)
|
||||
(count u32)))
|
||||
|
||||
(defun weechat--relay-unpack-htb (data)
|
||||
(let* ((obj (bindat-unpack weechat--relay-htb-spec data))
|
||||
(count (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field obj 'count)
|
||||
4))
|
||||
(key-type (bindat-get-field obj 'key-type))
|
||||
(val-type (bindat-get-field obj 'val-type))
|
||||
(key-fn (symbol-function (intern (concat "weechat--relay-unpack-" key-type))))
|
||||
(val-fn (symbol-function (intern (concat "weechat--relay-unpack-" val-type))))
|
||||
(offset (bindat-length weechat--relay-htb-spec obj))
|
||||
(acc ()))
|
||||
(dotimes (_ count)
|
||||
(cl-multiple-value-bind (key key-len) (funcall key-fn (substring data offset))
|
||||
(cl-multiple-value-bind (val val-len) (funcall val-fn (substring data (+ offset key-len)))
|
||||
(setq acc (cons (cons key val) acc))
|
||||
(setq offset (+ offset key-len val-len)))))
|
||||
(cl-values acc
|
||||
offset)))
|
||||
|
||||
(defconst weechat--relay-arr-spec
|
||||
'((type str 3)
|
||||
(count u32)))
|
||||
|
||||
(defun weechat--relay-unpack-arr (data)
|
||||
(let* ((obj (bindat-unpack weechat--relay-arr-spec data))
|
||||
(count (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field obj 'count)
|
||||
4))
|
||||
(type (bindat-get-field obj 'type))
|
||||
(unpack-fn (symbol-function (intern (concat "weechat--relay-unpack-" type))))
|
||||
(offset (bindat-length weechat--relay-arr-spec obj))
|
||||
(acc ()))
|
||||
(dotimes (_ count)
|
||||
(cl-multiple-value-bind (val val-len) (funcall unpack-fn (substring data offset))
|
||||
(setq acc (append acc (list val)))
|
||||
(setq offset (+ offset val-len))))
|
||||
(cl-values acc offset)))
|
||||
|
||||
(defalias 'weechat--relay-parse-chr 'weechat--relay-unpack-chr)
|
||||
(defalias 'weechat--relay-parse-int 'weechat--relay-unpack-int)
|
||||
(defalias 'weechat--relay-parse-lon 'weechat--relay-unpack-lon)
|
||||
(defalias 'weechat--relay-parse-str 'weechat--relay-unpack-str)
|
||||
(defalias 'weechat--relay-parse-buf 'weechat--relay-unpack-buf)
|
||||
(defalias 'weechat--relay-parse-ptr 'weechat--relay-unpack-ptr)
|
||||
(defalias 'weechat--relay-parse-tim 'weechat--relay-unpack-tim)
|
||||
(defalias 'weechat--relay-parse-arr 'weechat--relay-unpack-arr)
|
||||
|
||||
(defun weechat--relay-parse-inf (data)
|
||||
(cl-multiple-value-bind (name len) (weechat--relay-unpack-str data)
|
||||
(cl-multiple-value-bind (value len*) (weechat--relay-unpack-str (substring data len))
|
||||
(cl-values (cons name value)
|
||||
(+ len len*)))))
|
||||
|
||||
(defconst weechat--relay-inl-item-spec
|
||||
'((name struct weechat--relay-str-spec)
|
||||
(type str 3)))
|
||||
|
||||
(defun weechat--relay-parse-inl-item (data)
|
||||
(let* ((count (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field
|
||||
(bindat-unpack '((len u32)) data) 'len)
|
||||
4))
|
||||
(offset 4)
|
||||
(acc ()))
|
||||
(while (< (length acc) count)
|
||||
(let* ((obj (bindat-unpack weechat--relay-inl-item-spec
|
||||
(substring data offset)))
|
||||
(fun (symbol-function (intern (concat "weechat--relay-unpack-"
|
||||
(bindat-get-field obj 'type))))))
|
||||
(setq offset (+ offset (bindat-length weechat--relay-inl-item-spec obj)))
|
||||
(cl-multiple-value-bind (value offset*) (funcall fun (substring data offset))
|
||||
(setq offset (+ offset offset*))
|
||||
(setq acc (cons
|
||||
(cons (bindat-get-field obj 'name 'val) value)
|
||||
acc)))))
|
||||
(cl-values acc
|
||||
offset)))
|
||||
|
||||
(defconst weechat--relay-inl-spec
|
||||
'((name struct weechat--relay-str-spec)
|
||||
(count u32)))
|
||||
|
||||
(defun weechat--relay-parse-inl (data)
|
||||
(let* ((obj (bindat-unpack weechat--relay-inl-spec data))
|
||||
(acc ())
|
||||
(count (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field obj 'count)
|
||||
4))
|
||||
(offset (bindat-length weechat--relay-inl-spec obj)))
|
||||
(dotimes (_ count)
|
||||
(cl-multiple-value-bind (item offset*) (weechat--relay-parse-inl-item (substring data offset))
|
||||
(setq acc (cons item acc))
|
||||
(setq offset (+ offset offset*))))
|
||||
(cl-values acc
|
||||
offset)))
|
||||
|
||||
(defun weechat--relay-parse-hda-item (h-path-length name-type-alist data)
|
||||
(let ((p-path ())
|
||||
(offset 0)
|
||||
(result ()))
|
||||
(dotimes (_ h-path-length)
|
||||
(cl-multiple-value-bind (el offset*) (weechat--relay-unpack-ptr (substring data offset))
|
||||
(setq p-path (cons el p-path))
|
||||
(setq offset (+ offset offset*))))
|
||||
(dolist (name-type name-type-alist)
|
||||
(let ((fun (symbol-function (intern (concat "weechat--relay-unpack-" (cdr name-type))))))
|
||||
(cl-multiple-value-bind (obj offset*) (funcall fun (substring data offset))
|
||||
(setq result (cons (cons (car name-type) obj) result))
|
||||
(setq offset (+ offset offset*)))))
|
||||
(cl-values (cons (reverse p-path) result)
|
||||
offset)))
|
||||
|
||||
(defconst weechat--relay-hdh-spec
|
||||
'((h-path struct weechat--relay-str-spec)
|
||||
(keys struct weechat--relay-str-spec)
|
||||
(count u32)))
|
||||
|
||||
;;; from http://lists.gnu.org/archive/html/help-gnu-emacs/2009-06/msg00764.html
|
||||
(defun weechat--partition-list (list length)
|
||||
(cl-loop while list
|
||||
collect (cl-subseq list 0 length)
|
||||
do (setf list (nthcdr length list))))
|
||||
|
||||
(defun weechat--hda-split-keys-string (str)
|
||||
(mapcar (lambda (x)
|
||||
(cons (car x)
|
||||
(cadr x)))
|
||||
(weechat--partition-list (split-string str "[:,]") 2)))
|
||||
|
||||
(defun weechat--relay-parse-hda (data)
|
||||
(let* ((obj (bindat-unpack weechat--relay-hdh-spec data))
|
||||
(count (weechat--relay-bindat-unsigned-to-signed
|
||||
(bindat-get-field obj 'count)
|
||||
4))
|
||||
(name-type-alist (weechat--hda-split-keys-string
|
||||
(bindat-get-field obj 'keys 'val)))
|
||||
(h-path-length (length (split-string (bindat-get-field obj 'h-path 'val) "[/]")))
|
||||
(offset (+ (bindat-length weechat--relay-hdh-spec obj)))
|
||||
(acc ()))
|
||||
(dotimes (_ count)
|
||||
(cl-multiple-value-bind (obj offset*) (weechat--relay-parse-hda-item
|
||||
h-path-length name-type-alist (substring data offset))
|
||||
(setq acc (cons obj acc))
|
||||
(setq offset (+ offset offset*))))
|
||||
(let ((h-path (bindat-get-field obj 'h-path 'val)))
|
||||
(cl-values (list h-path acc)
|
||||
offset))))
|
||||
|
||||
(defconst weechat--relay-message-spec
|
||||
'((length u32)
|
||||
(compression u8)
|
||||
(id struct weechat--relay-str-spec)
|
||||
(data vec (eval (let ((l (- (bindat-get-field struct 'length)
|
||||
4 ;length
|
||||
1 ;compression
|
||||
(+ 4 (length (bindat-get-field struct 'id 'val))))))
|
||||
l)))))
|
||||
|
||||
(defun weechat--unpack-message-contents (data)
|
||||
(let* ((type (substring data 0 3))
|
||||
(fun (symbol-function (intern (concat "weechat--relay-parse-" type)))))
|
||||
(cl-multiple-value-bind (obj len) (funcall fun (string-make-unibyte (substring data 3)))
|
||||
(cl-values obj
|
||||
(+ len 3)))))
|
||||
|
||||
(defun weechat-unpack-message (message-data)
|
||||
"Unpack weechat relay message in MESSAGE-DATA.
|
||||
Return a list: (id data)."
|
||||
(let* ((msg (bindat-unpack weechat--relay-message-spec message-data))
|
||||
(data (concat (bindat-get-field msg 'data)))
|
||||
(msg-id (bindat-get-field msg 'id 'val))
|
||||
(ignore-msg (member msg-id weechat-relay-ignored-message-ids))
|
||||
(offset 0)
|
||||
(acc ()))
|
||||
;; Only no-compression is supported atm
|
||||
(unless (= 0 (bindat-get-field msg 'compression))
|
||||
(error "Compression not supported"))
|
||||
(unless ignore-msg
|
||||
(while (< offset (length data))
|
||||
(cl-multiple-value-bind (obj offset*) (weechat--unpack-message-contents
|
||||
(substring data offset))
|
||||
(setq offset (+ offset offset*))
|
||||
(setq acc (cons obj acc)))))
|
||||
(cl-values (cons msg-id (if ignore-msg '(ignored) (reverse acc)))
|
||||
(bindat-get-field msg 'length))))
|
||||
|
||||
(defun weechat--message-available-p ()
|
||||
"Check if a weechat relay message available in current buffer."
|
||||
(and (> (buffer-size) 5)
|
||||
(>= (buffer-size)
|
||||
(bindat-get-field
|
||||
(bindat-unpack '((len u32))
|
||||
(buffer-string))
|
||||
'len))))
|
||||
|
||||
(defun weechat--relay-parse-new-message ()
|
||||
(when (weechat--message-available-p)
|
||||
(cl-multiple-value-bind (ret len) (weechat-unpack-message
|
||||
(buffer-string))
|
||||
(weechat-relay-log (format "Consumed %d bytes" len) :debug)
|
||||
(let ((inhibit-read-only t))
|
||||
(delete-region (point-min) (+ (point-min) len)))
|
||||
ret)))
|
||||
|
||||
(defun weechat-relay-get-id-callback (id)
|
||||
(gethash id weechat--relay-id-callback-hash))
|
||||
|
||||
(defun weechat-relay-remove-id-callback (id)
|
||||
(let ((fun (weechat-relay-get-id-callback id)))
|
||||
(remhash id weechat--relay-id-callback-hash)
|
||||
fun))
|
||||
|
||||
(defun weechat-relay-add-id-callback (id function &optional one-shot force)
|
||||
(unless id
|
||||
(error "ID must not be nil"))
|
||||
(when (weechat-relay-get-id-callback id)
|
||||
(unless force
|
||||
(error "ID '%s' is already in `weechat--relay-id-callback-hash'" id))
|
||||
(weechat-relay-remove-id-callback id))
|
||||
(let ((function* (if one-shot
|
||||
(lambda (x)
|
||||
(funcall function x)
|
||||
(weechat-relay-remove-id-callback id))
|
||||
function)))
|
||||
(puthash id function* weechat--relay-id-callback-hash)))
|
||||
|
||||
(defun weechat-relay-send-command (command &optional callback)
|
||||
"Send COMMAND to relay and call CALLBACK with reply.
|
||||
CALLBACK takes one argument (the response data) which is a list."
|
||||
(let ((id (symbol-name (cl-gensym))))
|
||||
(when (functionp callback)
|
||||
(weechat-relay-add-id-callback id callback 'one-shot))
|
||||
(weechat--relay-send-message command id)))
|
||||
|
||||
(defvar weechat-relay-last-receive nil
|
||||
"Stores the time when the last message was received.")
|
||||
|
||||
|
||||
(defun weechat--relay-send-ping (&optional pong-callback)
|
||||
(weechat-relay-send-command "info version" pong-callback))
|
||||
|
||||
;;; TODO: Move this functionality to weechat.el
|
||||
(defvar weechat--relay-ping-timer nil)
|
||||
(defun weechat--relay-stop-ping-timer ()
|
||||
(when (timerp weechat--relay-ping-timer)
|
||||
(cancel-timer weechat--relay-ping-timer)
|
||||
(setq weechat--relay-ping-timer nil)))
|
||||
|
||||
(defun weechat--relay-start-ping-timer ()
|
||||
(weechat--relay-stop-ping-timer)
|
||||
(setq weechat--relay-ping-timer
|
||||
(run-with-timer 0
|
||||
(/ weechat-relay-ping-idle-seconds 2)
|
||||
(lambda ()
|
||||
(if (weechat-relay-connected-p)
|
||||
(when (>= (float-time (time-since weechat-relay-last-receive))
|
||||
weechat-relay-ping-idle-seconds)
|
||||
(weechat--relay-send-ping))
|
||||
;; Stop the ping timer if we aren't connected
|
||||
(weechat--relay-stop-ping-timer))))))
|
||||
|
||||
(defun weechat--relay-process-filter (proc string)
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(weechat-relay-log (format "Received %d bytes" (length string)) :debug)
|
||||
;; Insert the text, advancing the process marker.
|
||||
(goto-char (point-max))
|
||||
(let ((inhibit-read-only t))
|
||||
(insert (string-make-unibyte string)))
|
||||
(let ((inhibit-redisplay t))
|
||||
(while (weechat--message-available-p)
|
||||
(let* ((data (weechat--relay-parse-new-message))
|
||||
(id (weechat--message-id data)))
|
||||
(setq weechat-relay-last-receive (current-time))
|
||||
;; If buffer is available, log message.
|
||||
(when (eq weechat-relay-log-level :debug)
|
||||
(weechat-relay-log (pp-to-string data) :debug))
|
||||
;; Call `weechat-relay-message-function'
|
||||
(when (functionp weechat-relay-message-function)
|
||||
(funcall weechat-relay-message-function data))
|
||||
;; Call callback from `weechat--relay-id-callback-hash'
|
||||
(if (functionp (weechat-relay-get-id-callback id))
|
||||
(funcall (weechat-relay-get-id-callback id)
|
||||
(weechat--message-data data))))))))
|
||||
|
||||
(defvar weechat--relay-connected-callback)
|
||||
|
||||
(defun weechat--relay-handle-process-status (status)
|
||||
(weechat-relay-log (format "Received status event: %s\n" status))
|
||||
(cl-case status
|
||||
((closed exit) (run-hooks 'weechat-relay-disconnect-hook))
|
||||
(failed (error "Failed to connect to weechat relay")
|
||||
(weechat-relay-disconnect))))
|
||||
|
||||
(defun weechat--relay-process-sentinel (proc _)
|
||||
(weechat--relay-handle-process-status (process-status proc)))
|
||||
|
||||
(defun weechat--relay-open-socket (name buffer host service)
|
||||
(make-network-process :name name
|
||||
:buffer buffer
|
||||
:host host
|
||||
:service service
|
||||
:coding 'binary
|
||||
:keepalive t
|
||||
:noquery t))
|
||||
|
||||
(defun weechat--relay-plain-socket (bname host port)
|
||||
(weechat-relay-log (format "PLAIN %s:%d" host port) :info)
|
||||
(weechat--relay-open-socket "weechat-relay" bname host port))
|
||||
|
||||
(defun weechat--relay-tls-socket (bname host port)
|
||||
(weechat-relay-log (format "TLS %s:%d" host port) :info)
|
||||
(require 'gnutls)
|
||||
(open-network-stream "weechat-relay-tls"
|
||||
bname
|
||||
host
|
||||
port
|
||||
:type 'tls
|
||||
:coding 'binary))
|
||||
|
||||
(defun weechat--relay-from-command (cmdspec)
|
||||
(lambda (bname host port)
|
||||
(let ((cmd (format-spec cmdspec (format-spec-make
|
||||
?h host
|
||||
?p port))))
|
||||
(weechat-relay-log (format "COMMAND %s:%s: `%s'" host port cmd))
|
||||
(let ((process-connection-type nil)) ; Use a pipe.
|
||||
(start-process-shell-command "weechat-relay-cmd" bname cmd)))))
|
||||
|
||||
(defun weechat-relay-connect (host port mode &optional callback)
|
||||
"Open a new weechat relay connection to HOST at PORT.
|
||||
|
||||
Argument MODE Null or 'plain for a plain socket, t or 'ssl for a TLS socket;
|
||||
a string denotes a command to run. You can use %h and %p to interpolate host
|
||||
and port number respectively.
|
||||
|
||||
Optional argument CALLBACK Called after initialization is finished."
|
||||
;; Clean relay buffer to start with clean state
|
||||
(with-current-buffer (get-buffer-create weechat-relay-buffer-name)
|
||||
(let ((inhibit-read-only t))
|
||||
(delete-region (point-min) (point-max))))
|
||||
(let* ((pfun (cond
|
||||
((or (null mode) (eq mode 'plain)) #'weechat--relay-plain-socket)
|
||||
((or (eq mode t) (eq mode 'ssl)) #'weechat--relay-tls-socket)
|
||||
((stringp mode) (weechat--relay-from-command mode))))
|
||||
(process
|
||||
(funcall pfun weechat-relay-buffer-name host port)))
|
||||
(set-process-sentinel process #'weechat--relay-process-sentinel)
|
||||
(set-process-coding-system process 'binary)
|
||||
(set-process-filter process #'weechat--relay-process-filter)
|
||||
(with-current-buffer (get-buffer weechat-relay-buffer-name)
|
||||
(setq buffer-read-only t)
|
||||
(set-buffer-multibyte nil)
|
||||
(buffer-disable-undo)))
|
||||
|
||||
(with-current-buffer (get-buffer-create
|
||||
weechat-relay-log-buffer-name)
|
||||
(buffer-disable-undo))
|
||||
(when (functionp callback)
|
||||
(funcall callback))
|
||||
(run-hooks 'weechat-relay-connect-hook))
|
||||
|
||||
(defun weechat-relay-connected-p ()
|
||||
(and (get-buffer weechat-relay-buffer-name)
|
||||
(get-buffer-process weechat-relay-buffer-name)
|
||||
(process-live-p (get-buffer-process weechat-relay-buffer-name))
|
||||
t))
|
||||
|
||||
(defun weechat-relay-disconnect ()
|
||||
"Disconnect current weechat relay connection and close all buffers."
|
||||
(when (weechat-relay-connected-p)
|
||||
(weechat--relay-send-message "quit")
|
||||
(with-current-buffer weechat-relay-buffer-name
|
||||
(let ((proc (get-buffer-process (current-buffer))))
|
||||
;; When disconnecting interactively (e.g. when this function
|
||||
;; is called), prevent running any disconnect hooks.
|
||||
(set-process-sentinel proc nil)
|
||||
(delete-process proc)
|
||||
;; Stop the ping timer
|
||||
(weechat--relay-stop-ping-timer))
|
||||
(kill-buffer))
|
||||
(when (get-buffer weechat-relay-log-buffer-name)
|
||||
(kill-buffer weechat-relay-log-buffer-name))))
|
||||
|
||||
(defun weechat--message-id (message)
|
||||
(car message))
|
||||
|
||||
(defun weechat--message-data (message)
|
||||
"Return a list with data in MESSAGE."
|
||||
(cdr message))
|
||||
|
||||
(defun weechat--hdata-path (hdata)
|
||||
(car hdata))
|
||||
|
||||
(defun weechat--hdata-values (hdata)
|
||||
(cadr hdata))
|
||||
|
||||
(defun weechat--hdata-value-pointer-path (value)
|
||||
(car value))
|
||||
|
||||
(defun weechat--hdata-value-alist (value)
|
||||
(cdr value))
|
||||
|
||||
(defun weechat-unload-function ()
|
||||
(ad-disable-advice 'open-gnutls-stream 'around 'weechat-verifying))
|
||||
|
||||
(provide 'weechat-relay)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; weechat-relay.el ends here
|
||||
|
||||
BIN
elpa/weechat-20180513.310/weechat-relay.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-relay.elc
Normal file
Binary file not shown.
65
elpa/weechat-20180513.310/weechat-sauron.el
Normal file
65
elpa/weechat-20180513.310/weechat-sauron.el
Normal file
@@ -0,0 +1,65 @@
|
||||
;;; weechat-sauron --- Sauron Notifications ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Moritz Ulrich
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Notifications using Sauron https://github.com/djcb/sauron
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(if (require 'sauron nil 'noerr)
|
||||
(progn
|
||||
(defun weechat-sauron-handler (type &optional sender text _date buffer-ptr)
|
||||
(setq text (if text (weechat-strip-formatting text)))
|
||||
(setq sender (if sender (weechat-strip-formatting sender)))
|
||||
(let ((jump-position (point-max-marker)))
|
||||
(sauron-add-event 'weechat 3
|
||||
(cl-case type
|
||||
(:highlight
|
||||
(format "%s in %s: %S"
|
||||
sender
|
||||
(weechat-buffer-name buffer-ptr)
|
||||
text))
|
||||
(:query
|
||||
(format "Query from %s: %S"
|
||||
sender
|
||||
text))
|
||||
(:disconnect
|
||||
"Disconnected from WeeChat"))
|
||||
(lambda ()
|
||||
(when (fboundp 'sauron-switch-to-marker-or-buffer)
|
||||
(sauron-switch-to-marker-or-buffer jump-position)))
|
||||
;; Flood protection based on sender
|
||||
(when sender
|
||||
(list :sender sender)))))
|
||||
|
||||
(add-hook 'weechat-notification-handler-functions
|
||||
'weechat-sauron-handler))
|
||||
(weechat-warn "Error while loading weechat-sauron. Sauron notifications are disabled."))
|
||||
|
||||
|
||||
(provide 'weechat-sauron)
|
||||
|
||||
;;; weechat-sauron.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-sauron.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-sauron.elc
Normal file
Binary file not shown.
97
elpa/weechat-20180513.310/weechat-secrets.el
Normal file
97
elpa/weechat-20180513.310/weechat-secrets.el
Normal file
@@ -0,0 +1,97 @@
|
||||
;;; weechat --- Support secrets.el -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; secrets.el support for weechat.el
|
||||
|
||||
;; Load this file and then set `weechat-password-callback' to
|
||||
;; `weechat-secrets-get-password'. You can use
|
||||
;; `weechat-secrets-create' to create new entries and
|
||||
;; `weechat-secrets-delete' to delete them.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 'secrets)
|
||||
|
||||
(defgroup weechat-secrets nil
|
||||
"Secrets.el support for WeeChat."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-secrets"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-secrets-collection "weechat.el"
|
||||
"Collection name."
|
||||
:type 'string
|
||||
:group 'weechat-secrets)
|
||||
|
||||
(defun weechat-secrets--to-item (host port)
|
||||
"Convert HOST and PORT to an item name."
|
||||
(format "%s:%s" host port))
|
||||
|
||||
(defun weechat-secrets-create (host port &optional password)
|
||||
"Associate HOST and PORT with PASSWORD.
|
||||
A collection named after `weechat-secrets-collection' is created if required."
|
||||
(interactive
|
||||
(list
|
||||
(read-string
|
||||
(format "Host for password (default '%s'): " weechat-host-default)
|
||||
nil nil weechat-host-default)
|
||||
(read-number "Port for password: " weechat-port-default)))
|
||||
(unless secrets-enabled
|
||||
(error "Secrets.el-API not available."))
|
||||
(unless (member weechat-secrets-collection (secrets-list-collections))
|
||||
(secrets-create-collection weechat-secrets-collection))
|
||||
(unless password
|
||||
(setq password (read-passwd "Password: " 'confirm)))
|
||||
(secrets-create-item weechat-secrets-collection
|
||||
(weechat-secrets--to-item host port) password
|
||||
:host host :port (number-to-string port))
|
||||
(clear-string password))
|
||||
|
||||
(defun weechat-secrets-delete (host port &optional allow-empty-collection)
|
||||
"Delete HOST and PORT entry.
|
||||
Unless ALLOW-EMPTY-COLLECTION is non-nil then the collection is removed
|
||||
if it is empty."
|
||||
(interactive
|
||||
(list
|
||||
(read-string
|
||||
(format "Host for password (default '%s'): " weechat-host-default)
|
||||
nil nil weechat-host-default)
|
||||
(read-number "Port for password: " weechat-port-default)))
|
||||
(let ((item (weechat-secrets--to-item host port)))
|
||||
(secrets-delete-item weechat-secrets-collection item)
|
||||
(unless (and allow-empty-collection
|
||||
(null (secrets-list-items weechat-secrets-collection)))
|
||||
(secrets-delete-collection weechat-secrets-collection))))
|
||||
|
||||
(defun weechat-secrets-get-password (host port)
|
||||
"Get password for HOST and PORT."
|
||||
(secrets-get-secret weechat-secrets-collection
|
||||
(weechat-secrets--to-item host port)))
|
||||
|
||||
(provide 'weechat-secrets)
|
||||
|
||||
;;; weechat-secrets.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-secrets.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-secrets.elc
Normal file
Binary file not shown.
86
elpa/weechat-20180513.310/weechat-smiley.el
Normal file
86
elpa/weechat-20180513.310/weechat-smiley.el
Normal file
@@ -0,0 +1,86 @@
|
||||
;;; weechat-smiley --- Display smiley faces ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; This module uses `smiley-region' from Gnus smiley.el.
|
||||
|
||||
;; To support short smileys (without nose) use:
|
||||
;;
|
||||
;; (setq smiley-regexp-alist
|
||||
;; '(("\\(;-?)\\)\\W" 1 "blink")
|
||||
;; ("[^;]\\(;)\\)\\W" 1 "blink")
|
||||
;; ("\\(:-?]\\)\\W" 1 "forced")
|
||||
;; ("\\(8-?)\\)\\W" 1 "braindamaged")
|
||||
;; ("\\(:-?|\\)\\W" 1 "indifferent")
|
||||
;; ("\\(:-?[/\\]\\)\\W" 1 "wry")
|
||||
;; ("\\(:-?(\\)\\W" 1 "sad")
|
||||
;; ("\\(X-?)\\)\\W" 1 "dead")
|
||||
;; ("\\(:-?{\\)\\W" 1 "frown")
|
||||
;; ("\\(>:-?)\\)\\W" 1 "evil")
|
||||
;; ("\\(;-?(\\)\\W" 1 "cry")
|
||||
;; ("\\(:-?D\\)\\W" 1 "grin")
|
||||
;; ;; "smile" must be come after "evil"
|
||||
;; ("\\(\\^?:-?)\\)\\W" 1 "smile")))
|
||||
|
||||
;; It might be necessary to run
|
||||
;;
|
||||
;; (setq smiley-cached-regexp-alist nil)
|
||||
;; (smiley-update-cache)
|
||||
;;
|
||||
;; To make it work when smiley is already loaded.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'smiley)
|
||||
(require 'weechat)
|
||||
|
||||
(defun weechat-smiley-buffer ()
|
||||
"Smiley the region."
|
||||
(let ((inhibit-read-only t))
|
||||
(smiley-buffer)))
|
||||
|
||||
(defun weechat-smiley--do ()
|
||||
"Hook for weechat."
|
||||
(save-excursion
|
||||
(let ((inhibit-read-only t))
|
||||
(smiley-region (+ (point-min) weechat-text-column) (point-max)))))
|
||||
|
||||
(weechat-do-buffers (weechat-smiley-buffer))
|
||||
(add-hook 'weechat-insert-modify-hook #'weechat-smiley--do)
|
||||
|
||||
(defun weechat-smiley-unload-function ()
|
||||
"Remove smileys from buffer."
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let ((inhibit-read-only t))
|
||||
(weechat-do-buffers
|
||||
;; smiley-toggle-buffer is broken somewhere in
|
||||
;; `gnus-with-article-buffer'. Remove smileys directly.
|
||||
(smiley-region (point-min) (point-max))
|
||||
(gnus-delete-images 'smiley)))))
|
||||
|
||||
(provide 'weechat-smiley)
|
||||
|
||||
;;; weechat-smiley.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-smiley.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-smiley.elc
Normal file
Binary file not shown.
268
elpa/weechat-20180513.310/weechat-speedbar.el
Normal file
268
elpa/weechat-20180513.310/weechat-speedbar.el
Normal file
@@ -0,0 +1,268 @@
|
||||
;;; weechat --- Chat via Weechat's relay protocol in Emacs ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Keywords: irc
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This code is inspired by erc-speedbar.el
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 'speedbar)
|
||||
|
||||
(defvar weechat-speedbar-key-map
|
||||
(let ((map (speedbar-make-specialized-keymap)))
|
||||
(define-key map "e" 'speedbar-edit-line)
|
||||
(define-key map "\C-m" 'speedbar-edit-line)
|
||||
(define-key map "+" 'speedbar-expand-line)
|
||||
(define-key map "=" 'speedbar-expand-line)
|
||||
(define-key map "-" 'speedbar-contract-line)
|
||||
map)
|
||||
"Weechat Speedbar Key Map")
|
||||
|
||||
(defvar weechat-speedbar-menu-items
|
||||
'(["Go to buffer" speedbar-edit-line t]
|
||||
["Expand Node" speedbat-expand-line
|
||||
(save-excursion (beginning-of-line)
|
||||
(looking-at "[0-9]+: *.\\+. "))]
|
||||
["Contract Node" speedbar-contract-line
|
||||
(save-excursion (beginning-of-line)
|
||||
(looking-at "[0-9]+: *.-. "))])
|
||||
"Weechat Speedbar Menu Items")
|
||||
|
||||
(defun weechat-speedbar--goto-buffer (_text buffer _indent)
|
||||
(let ((buf (get-buffer buffer)))
|
||||
(speedbar-set-timer dframe-update-speed)
|
||||
(if (buffer-live-p buf)
|
||||
(switch-to-buffer buf)
|
||||
(when (y-or-n-p (format "Monitor buffer '%s'? " buffer))
|
||||
(weechat-monitor-buffer (weechat--find-buffer buffer) 'show)))))
|
||||
|
||||
(defvar weechat--buffer-hashes) ;; See weechat.el
|
||||
|
||||
(defun weechat-speedbar--buttons (_directory depth)
|
||||
"Create buttons for speedbar in BUFFER."
|
||||
(erase-buffer)
|
||||
(maphash
|
||||
#'(lambda (_k v)
|
||||
(let* ((local-vars (gethash "local_variables" v))
|
||||
(type (cdr (assoc-string "type" local-vars)))
|
||||
(name (cdr (assoc-string "name" local-vars)))
|
||||
(server (cdr (assoc-string "server" local-vars))))
|
||||
(when (string= type "server")
|
||||
(speedbar-with-writable
|
||||
(speedbar-make-tag-line
|
||||
'bracket ?+
|
||||
#'weechat-speedbar--expand-server server
|
||||
server
|
||||
#'weechat-speedbar--goto-buffer name
|
||||
nil depth)))))
|
||||
weechat--buffer-hashes))
|
||||
|
||||
(defun weechat-speedbar--expand-server (text server indent)
|
||||
(cond ((string-match "+" text) ; expand node
|
||||
(speedbar-change-expand-button-char ?-)
|
||||
(speedbar-reset-scanners)
|
||||
(speedbar-with-writable
|
||||
(save-excursion
|
||||
(forward-line 1)
|
||||
(weechat-speedbar--channel-buttons nil (1+ indent) server))))
|
||||
((string-match "-" text) ; contract node
|
||||
(speedbar-change-expand-button-char ?+)
|
||||
(speedbar-delete-subblock indent))
|
||||
(t (error "Not sure what do do!")))
|
||||
(speedbar-center-buffer-smartly))
|
||||
|
||||
(defun weechat-speedbar--channel-buttons (_directory depth for-server)
|
||||
(maphash
|
||||
#'(lambda (_k v)
|
||||
(let* ((local-vars (gethash "local_variables" v))
|
||||
(type (cdr (assoc-string "type" local-vars)))
|
||||
(name (cdr (assoc-string "name" local-vars)))
|
||||
(channel (cdr (assoc-string "channel" local-vars)))
|
||||
(server (cdr (assoc-string "server" local-vars))))
|
||||
(when (string= server for-server)
|
||||
(cond
|
||||
((string= type "channel")
|
||||
(speedbar-with-writable
|
||||
(speedbar-make-tag-line
|
||||
'bracket ?+
|
||||
#'weechat-speedbar--expand-channel name
|
||||
channel
|
||||
#'weechat-speedbar--goto-buffer name
|
||||
nil depth)))
|
||||
((string= type "private")
|
||||
(speedbar-with-writable
|
||||
(speedbar-with-writable
|
||||
(speedbar-make-tag-line ;; TODO org-contacts/gravatar/bbdb?
|
||||
nil nil
|
||||
nil nil ;; TODO expand for whois?
|
||||
channel
|
||||
#'weechat-speedbar--goto-buffer name
|
||||
nil depth))))))))
|
||||
weechat--buffer-hashes))
|
||||
|
||||
(defun weechat-speedbar--expand-channel (text name indent)
|
||||
(cond ((string-match "+" text) ; expand node
|
||||
(speedbar-change-expand-button-char ?-)
|
||||
(speedbar-reset-scanners)
|
||||
(speedbar-with-writable
|
||||
(save-excursion
|
||||
(forward-line 1)
|
||||
(weechat-speedbar--user-buttons nil (1+ indent) name))))
|
||||
((string-match "-" text) ; contract node
|
||||
(speedbar-change-expand-button-char ?+)
|
||||
(speedbar-delete-subblock indent))
|
||||
(t (error "Not sure what do do!")))
|
||||
(speedbar-center-buffer-smartly))
|
||||
|
||||
(defvar weechat-user-list) ;; See weechat.el
|
||||
(defun weechat-speedbar--user-buttons (_directory depth name)
|
||||
(let ((buffer (get-buffer name))
|
||||
nick-list
|
||||
topic)
|
||||
(if (not (buffer-live-p buffer))
|
||||
(speedbar-with-writable
|
||||
(speedbar-make-tag-line
|
||||
'angle ?i
|
||||
nil nil
|
||||
"Not Monitored!"
|
||||
#'weechat-speedbar--goto-buffer name
|
||||
nil depth))
|
||||
(with-current-buffer buffer
|
||||
(setq nick-list weechat-user-list)
|
||||
(setq topic weechat-topic))
|
||||
(when topic
|
||||
(speedbar-with-writable
|
||||
(speedbar-make-tag-line
|
||||
'angle ?i
|
||||
nil nil
|
||||
(concat "Topic: " topic)
|
||||
nil nil
|
||||
nil depth)))
|
||||
(dolist (nick nick-list)
|
||||
(speedbar-with-writable
|
||||
(speedbar-make-tag-line ;; TODO org-contacts/gravatar/bbdb?
|
||||
nil nil
|
||||
nil nil ;; TODO expand for whois?
|
||||
nick
|
||||
#'weechat-speedbar--user-action nick
|
||||
nil depth))))))
|
||||
|
||||
(defun weechat-speedbar--user-action (_text nick _indent)
|
||||
(weechat-nick-action nick))
|
||||
|
||||
(defun weechat-speedbar-item-info ()
|
||||
"Display information about the current line."
|
||||
(let ((data (speedbar-line-token)))
|
||||
(message "item-info: %s" data)))
|
||||
|
||||
(defvar weechat-speedbar--to-do-point t
|
||||
"Local variable maintaining the current modified check position.")
|
||||
|
||||
(defcustom weechat-speedbar-highlight-indicator "<i>"
|
||||
"Indicator used for highlight events."
|
||||
:type 'string
|
||||
:group 'weechat-speedbar)
|
||||
|
||||
(defcustom weechat-speedbar-modified-indicator "<M>"
|
||||
"Indicator used for normal message events."
|
||||
:type 'string
|
||||
:group 'weechat-speedbar)
|
||||
|
||||
(defun weechat-speedbar--add-indicator (indicator)
|
||||
"Add INDICATOR to current line.
|
||||
This is similar to `speedbar-add-indicator' but supports weechat-speedbar
|
||||
indicators."
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(end-of-line)
|
||||
(when (re-search-backward (concat "\\("
|
||||
(regexp-quote weechat-speedbar-highlight-indicator)
|
||||
"\\|"
|
||||
(regexp-quote weechat-speedbar-modified-indicator)
|
||||
"\\)+")
|
||||
(line-beginning-position) t)
|
||||
(delete-region (match-beginning 0) (match-end 0)))
|
||||
(end-of-line)
|
||||
(when (not (string= " " indicator))
|
||||
(let ((start (point)))
|
||||
(speedbar-with-writable
|
||||
(insert indicator)
|
||||
(speedbar-insert-image-button-maybe start (length indicator)))))))
|
||||
|
||||
(defun weechat-speedbar--check-modified ()
|
||||
"Scan all the channels and check if they are modified."
|
||||
(save-excursion
|
||||
(when speedbar-buffer
|
||||
(set-buffer speedbar-buffer))
|
||||
(when (eq weechat-speedbar--to-do-point t)
|
||||
(setq weechat-speedbar--to-do-point 0))
|
||||
(if (not (numberp weechat-speedbar--to-do-point))
|
||||
t
|
||||
(goto-char weechat-speedbar--to-do-point)
|
||||
(while (and (not (input-pending-p))
|
||||
(re-search-forward "^1: \\(\\[[+-]\\]\\|>\\) " nil t))
|
||||
(setq weechat-speedbar--to-do-point (point))
|
||||
(let* ((buffer-name (get-text-property (point) 'speedbar-token))
|
||||
(buffer-ptr (weechat--find-buffer buffer-name)))
|
||||
(weechat-speedbar--add-indicator
|
||||
(if buffer-ptr
|
||||
(let ((hash (weechat-buffer-hash buffer-ptr)))
|
||||
(cond
|
||||
((gethash :background-highlight hash)
|
||||
weechat-speedbar-highlight-indicator)
|
||||
((gethash :background-message hash)
|
||||
weechat-speedbar-modified-indicator)
|
||||
(t " ")))
|
||||
" "))))
|
||||
(if (input-pending-p)
|
||||
nil ; we are incomplete
|
||||
(setq weechat-speedbar--to-do-point nil) ; done
|
||||
t))))
|
||||
|
||||
(defun weechat-speedbar-install-variables ()
|
||||
"Install WeeChat speedbar variables."
|
||||
(speedbar-add-expansion-list '("WeeChat"
|
||||
weechat-speedbar-menu-items
|
||||
weechat-speedbar-key-map
|
||||
weechat-speedbar--buttons))
|
||||
(add-to-list 'speedbar-stealthy-function-list
|
||||
'("WeeChat" weechat-speedbar--check-modified))
|
||||
(add-hook 'speedbar-scanner-reset-hook
|
||||
(lambda ()
|
||||
(setq weechat-speedbar--to-do-point t)))
|
||||
(speedbar-add-mode-functions-list
|
||||
'("WeeChat" (speedbar-item-info . weechat-speedbar-item-info))))
|
||||
|
||||
(if (featurep 'speedbar)
|
||||
(weechat-speedbar-install-variables)
|
||||
(add-hook 'speedbar-load-hook #'weechat-speedbar-install-variables))
|
||||
|
||||
(defun weechat-speedbar-unload-function ()
|
||||
;; TODO
|
||||
)
|
||||
|
||||
(provide 'weechat-speedbar)
|
||||
|
||||
;;; weechat-speedbar.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-speedbar.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-speedbar.elc
Normal file
Binary file not shown.
89
elpa/weechat-20180513.310/weechat-spelling.el
Normal file
89
elpa/weechat-20180513.310/weechat-spelling.el
Normal file
@@ -0,0 +1,89 @@
|
||||
;;; weechat-spelling.el --- FlySpell support for WeeChat. -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
|
||||
;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'weechat)
|
||||
(require 'flyspell)
|
||||
(require 's)
|
||||
|
||||
(defgroup weechat-spelling nil
|
||||
"FlySpell support for WeeChat."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-spelling"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-spelling-dictionaries nil
|
||||
"An alist mapping buffer names to dictionaries.
|
||||
The format of each entry is (CHANNEL . DICTIONARY). Where CHANNEL is a regexp
|
||||
matching the buffer name (\"Server.Channel\") and DICTIONARY is the name of an
|
||||
`ispell' dictionary.
|
||||
|
||||
See `ispell-valid-dictionary-list' for a list of valid dictionaries."
|
||||
:type '(choice
|
||||
(const :tag "Default dictionary" nil)
|
||||
(repeat (cons (string :tag "Server.Channel Regex")
|
||||
(string :tag "Dictionary"))))
|
||||
:group 'weechat-spelling)
|
||||
|
||||
(defun weechat-spelling-init (&optional buffer)
|
||||
"Initialize spelling in BUFFER or `current-buffer'."
|
||||
(with-current-buffer (or buffer (current-buffer))
|
||||
(dolist (entry weechat-spelling-dictionaries)
|
||||
(when (s-matches? (car entry) (buffer-name))
|
||||
(setq ispell-local-dictionary (cdr entry))))
|
||||
(setq flyspell-generic-check-word-predicate #'weechat-mode-flyspell-verify)
|
||||
(flyspell-mode 1)))
|
||||
|
||||
(defvar weechat-prompt-end-marker) ;; See weechat.el
|
||||
(defvar weechat-user-list) ;; See weechat.el
|
||||
|
||||
(defun weechat-mode-flyspell-verify ()
|
||||
"Function used for `flyspell-generic-check-word-predicate' in `weechat-mode'."
|
||||
(not (or
|
||||
;; Spell-check only input line
|
||||
(< (point) weechat-prompt-end-marker)
|
||||
(let ((word-data (flyspell-get-word)))
|
||||
(or
|
||||
;; Don't spell-check nick names
|
||||
(member (car word-data) weechat-user-list)
|
||||
;; Don't spell-check words starting with a /
|
||||
(eq (char-before (cadr word-data)) ?/))))))
|
||||
|
||||
(put 'weechat-mode
|
||||
'flyspell-mode-predicate
|
||||
#'weechat-mode-flyspell-verify)
|
||||
|
||||
(weechat-do-buffers (weechat-spelling-init))
|
||||
(add-hook 'weechat-mode-hook #'weechat-spelling-init)
|
||||
|
||||
(defun weechat-spelling-unload-function ()
|
||||
(weechat-do-buffers (flyspell-mode -1))
|
||||
nil)
|
||||
|
||||
(provide 'weechat-spelling)
|
||||
|
||||
;;; weechat-spelling.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-spelling.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-spelling.elc
Normal file
Binary file not shown.
107
elpa/weechat-20180513.310/weechat-tracking.el
Normal file
107
elpa/weechat-20180513.310/weechat-tracking.el
Normal file
@@ -0,0 +1,107 @@
|
||||
;;; weechat-tracking --- Tracking support for weechat.el ;; -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2013 Rüdiger Sonderfeld
|
||||
|
||||
;; Author: Moritz Ulrich <moritz@tarn-vedra.de>
|
||||
;; Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||
;; Aristid Breitkreuz <aristidb@gmail.com>
|
||||
;; Keywords: irc chat network weechat
|
||||
;; URL: https://github.com/the-kenny/weechat.el
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This module provides tracking support, similar to erc-track, for weechat.el.
|
||||
;; It requires the tracking library
|
||||
;; https://github.com/jorgenschaefer/circe/wiki/Tracking
|
||||
;; It should be available from marmalade or el-get.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'tracking)
|
||||
(require 'cl-lib)
|
||||
|
||||
(require 'weechat)
|
||||
|
||||
(defgroup weechat-tracking nil
|
||||
"Tracking support for Weechat.el."
|
||||
:link '(url-link "https://github.com/the-kenny/weechat.el")
|
||||
:prefix "weechat-tracking-"
|
||||
:group 'weechat)
|
||||
|
||||
(defcustom weechat-tracking-types '(:highlight)
|
||||
"A list of message types which should show up in tracking.
|
||||
|
||||
List elements can either be one of :highlight or :message, or a
|
||||
cons-cell like (regex . level). The former will be applied to all
|
||||
buffers while the latter will apply to all buffers whose namesn
|
||||
matches `regex'.
|
||||
|
||||
Supported values are :message and :highlight."
|
||||
:type '(repeat (choice
|
||||
symbol
|
||||
(cons string symbol)))
|
||||
:group 'weechat-tracking)
|
||||
|
||||
(defcustom weechat-tracking-faces-priorities '(weechat-highlight-face)
|
||||
"A list of faces which should show up in the tracking.
|
||||
The first face is kept if the new message has only lower faces,
|
||||
or faces that don't show up at all."
|
||||
:type '(repeat face)
|
||||
:group 'weechat-tracking)
|
||||
|
||||
(defun weechat-tracking-setup ()
|
||||
"Set up tracking in weechat buffer."
|
||||
(set (make-local-variable 'tracking-faces-priorities) weechat-tracking-faces-priorities))
|
||||
|
||||
(defun weechat-tracking-show-buffer? (message-type &optional buffer)
|
||||
(or (cl-find message-type weechat-tracking-types)
|
||||
(cl-some (lambda (c)
|
||||
(and (consp c)
|
||||
(s-matches? (car c) (buffer-name buffer))
|
||||
(eq message-type (cdr c))))
|
||||
weechat-tracking-types)))
|
||||
|
||||
(defun weechat-tracking-handle-highlight ()
|
||||
(when (weechat-tracking-show-buffer? :highlight (current-buffer))
|
||||
(tracking-add-buffer (current-buffer) '(weechat-highlight-face))))
|
||||
|
||||
(defun weechat-tracking-handle-message ()
|
||||
(when (weechat-tracking-show-buffer? :message (current-buffer))
|
||||
(tracking-add-buffer (current-buffer))))
|
||||
|
||||
(defun weechat-tracking-handle-reset ()
|
||||
(tracking-remove-buffer (current-buffer)))
|
||||
|
||||
(defun weechat-tracking-clear-buffers ()
|
||||
(interactive)
|
||||
(mapcar #'tracking-remove-buffer (weechat-buffer-list)))
|
||||
|
||||
(weechat-do-buffers (weechat-tracking-setup))
|
||||
(add-hook 'weechat-mode-hook #'weechat-tracking-setup)
|
||||
|
||||
(add-hook 'weechat-buffer-background-message-hook
|
||||
'weechat-tracking-handle-message)
|
||||
(add-hook 'weechat-buffer-background-highlight-hook
|
||||
'weechat-tracking-handle-highlight)
|
||||
(add-hook 'weechat-buffer-visited-hook
|
||||
'weechat-tracking-handle-reset)
|
||||
|
||||
(tracking-mode 1)
|
||||
|
||||
(provide 'weechat-tracking)
|
||||
|
||||
;;; weechat-tracking.el ends here
|
||||
BIN
elpa/weechat-20180513.310/weechat-tracking.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat-tracking.elc
Normal file
Binary file not shown.
1807
elpa/weechat-20180513.310/weechat.el
Normal file
1807
elpa/weechat-20180513.310/weechat.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
elpa/weechat-20180513.310/weechat.elc
Normal file
BIN
elpa/weechat-20180513.310/weechat.elc
Normal file
Binary file not shown.
Reference in New Issue
Block a user