aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml7
-rw-r--r--lisp/mastodon-auth.el7
-rw-r--r--lisp/mastodon-client.el32
-rw-r--r--lisp/mastodon-http.el13
-rw-r--r--lisp/mastodon-inspect.el16
-rw-r--r--lisp/mastodon-media.el27
-rw-r--r--lisp/mastodon-tl.el181
-rw-r--r--lisp/mastodon-toot.el55
-rw-r--r--lisp/mastodon.el39
-rw-r--r--test/mastodon-client-tests.el10
-rw-r--r--test/mastodon-media-tests.el20
-rw-r--r--test/mastodon-tl-tests.el18
12 files changed, 251 insertions, 174 deletions
diff --git a/.travis.yml b/.travis.yml
index c7e0516..5f5796c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,3 +13,10 @@ script:
- cask clean-elc
- cask exec ert-runner -l test/ert-helper.el test/*-tests.el
- cask emacs --batch -Q -l package-lint.el -f package-lint-batch-and-exit lisp/*.el
+notifications:
+ webhooks:
+ urls:
+ - "https://scalar.vector.im/api/neb/services/hooks/dHJhdmlzLWNpLyU0MGpvaG5zb24lM0FtYXRyaXgub3JnLyUyMVpSbGVnVEFCTHBTQmJ2c01tTiUzQW1hdHJpeC5vcmc"
+ on_success: always # always|never|change
+ on_failure: always
+ on_start: never
diff --git a/lisp/mastodon-auth.el b/lisp/mastodon-auth.el
index 013487c..ed756f8 100644
--- a/lisp/mastodon-auth.el
+++ b/lisp/mastodon-auth.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Homepage: https://github.com/jdenen/mastodon.el
;; Package-Requires: ((emacs "24.4"))
@@ -30,7 +30,10 @@
;;; Code:
(require 'plstore)
-(require 'mastodon-client nil t)
+
+(autoload 'mastodon-client "mastodon-client")
+(autoload 'mastodon-http--post "mastodon-http")
+(defvar mastodon-instance-url)
(defgroup mastodon-auth nil
"Authenticate with Mastodon."
diff --git a/lisp/mastodon-client.el b/lisp/mastodon-client.el
index f8e8a5c..cbb276b 100644
--- a/lisp/mastodon-client.el
+++ b/lisp/mastodon-client.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Homepage: https://github.com/jdenen/mastodon.el
;; Package-Requires: ((emacs "24.4"))
@@ -30,14 +30,16 @@
;;; Code:
(require 'plstore)
-(require 'mastodon-http nil t)
+(autoload 'mastodon-http--api "mastodon-http")
+(autoload 'mastodon-http--post "mastodon-http")
-(defgroup mastodon-client nil
- "Register your client with Mastodon."
- :prefix "mastodon-client-"
- :group 'mastodon)
-(defvar mastodon-client nil
+(defcustom mastodon-client--token-file (concat user-emacs-directory "mastodon.plstore")
+ "File path where Mastodon access tokens are stored."
+ :group 'mastodon
+ :type 'file)
+
+(defvar mastodon-client--client-details nil
"Client id and secret.")
(defun mastodon-client--register ()
@@ -62,11 +64,11 @@
(json-read-from-string json-string))))
(defun mastodon-client--token-file ()
- "Return `mastodon-token-file'."
- mastodon-token-file)
+ "Return `mastodon-client--token-file'."
+ mastodon-client--token-file)
(defun mastodon-client--store ()
- "Store client_id and client_secret in `mastodon-token-file'.
+ "Store client_id and client_secret in `mastodon-client--token-file'.
Make `mastodon-client--fetch' call to determine client values."
(let ((plstore (plstore-open (mastodon-client--token-file)))
@@ -77,19 +79,19 @@ Make `mastodon-client--fetch' call to determine client values."
client))
(defun mastodon-client--read ()
- "Retrieve client_id and client_secret from `mastodon-token-file'."
+ "Retrieve client_id and client_secret from `mastodon-client--token-file'."
(let* ((plstore (plstore-open (mastodon-client--token-file)))
(mastodon (plstore-get plstore "mastodon")))
(when mastodon
(delete "mastodon" mastodon))))
(defun mastodon-client ()
- "Return variable `mastodon-client' plist.
+ "Return variable `mastodon-client--client-details' plist.
-Read plist from `mastodon-token-file' if variable is nil.
+Read plist from `mastodon-client--token-file' if variable is nil.
Fetch and store plist if `mastodon-client--read' returns nil."
- (or mastodon-client
- (setq mastodon-client
+ (or mastodon-client--client-details
+ (setq mastodon-client--client-details
(or (mastodon-client--read)
(mastodon-client--store)))))
diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el
index dbbad4f..1e6e037 100644
--- a/lisp/mastodon-http.el
+++ b/lisp/mastodon-http.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Package-Requires: ((emacs "24.4"))
;; Homepage: https://github.com/jdenen/mastodon.el
@@ -30,15 +30,16 @@
;;; Code:
(require 'json)
+(defvar mastodon-instance-url)
+(defvar mastodon-auth--token)
+(autoload 'mastodon-auth--access-token "mastodon-auth")
-(defgroup mastodon-http nil
- "HTTP requests and responses for Mastodon."
- :prefix "mastodon-http-"
- :group 'mastodon)
+(defvar mastodon-http--api-version "v1")
(defun mastodon-http--api (endpoint)
"Return Mastondon API URL for ENDPOINT."
- (concat mastodon-instance-url "/api/" mastodon--api-version "/" endpoint))
+ (concat mastodon-instance-url "/api/"
+ mastodon-http--api-version "/" endpoint))
(defun mastodon-http--response ()
"Capture response buffer content as string."
diff --git a/lisp/mastodon-inspect.el b/lisp/mastodon-inspect.el
index c12273e..29368a9 100644
--- a/lisp/mastodon-inspect.el
+++ b/lisp/mastodon-inspect.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Package-Requires: ((emacs "24.4"))
;; Homepage: https://github.com/jdenen/mastodon.el
@@ -28,8 +28,12 @@
;; Some tools to help inspect / debug mastodon.el
;;; Code:
-
-(require 'mastodon-tl nil t)
+(autoload 'mastodon-http--api "mastodon-http")
+(autoload 'mastodon-http--get-json "mastodon-http")
+(autoload 'mastodon-media--inline-images "mastodon-media")
+(autoload 'mastodon-mode "mastodon")
+(autoload 'mastodon-tl--property "mastodon-tl")
+(autoload 'mastodon-tl--toot "mastodon-tl")
(defgroup mastodon-inspect nil
"Tools to help inspect toots."
@@ -67,8 +71,10 @@
(with-current-buffer buffer
(let ((toot (mastodon-inspect--download-single-toot toot-id )))
(mastodon-tl--toot toot)
- (replace-regexp "\n\n\n | " "\n | " nil (point-min) (point-max))
- (mastodon-media--inline-images)))
+ (goto-char (point-min))
+ (while (search-forward "\n\n\n | " nil t)
+ (replace-match "\n | "))
+ (mastodon-media--inline-images)))
(switch-to-buffer-other-window buffer)
(mastodon-mode)))
diff --git a/lisp/mastodon-media.el b/lisp/mastodon-media.el
index b3565d0..f5d67ca 100644
--- a/lisp/mastodon-media.el
+++ b/lisp/mastodon-media.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Homepage: https://github.com/jdenen/mastodon.el
;; Package-Requires: ((emacs "24.4"))
@@ -32,16 +32,20 @@
;; required by the server and client.
;;; Code:
-(require 'mastodon-http nil t)
-
(defgroup mastodon-media nil
"Inline Mastadon media."
:prefix "mastodon-media-"
:group 'mastodon)
-(defvar mastodon-media-show-avatars-p
- (image-type-available-p 'imagemagick)
- "A boolean value stating whether to show avatars in timelines.")
+(defcustom mastodon-media--avatar-height 30
+ "Height of the user avatar images (if shown)."
+ :group 'mastodon-media
+ :type 'integer)
+
+(defcustom mastodon-media--preview-max-height 250
+ "Max height of any media attachment preview to be shown."
+ :group 'mastodon-media
+ :type 'integer)
(defvar mastodon-media--generic-avatar-data
(base64-decode-string
@@ -121,14 +125,13 @@ BAIQCEAgAIEABAIsJVH58WqHw8FIgjUIQCAACAQgEIBAAAIBCAQgEIBAAAIBCAQgEAAEAhAIQCBA
fKRJkmVZjAQwh78A6vCRWJE8K+8AAAAASUVORK5CYII=")
"The PNG data for a generic 200x200 'broken image' view")
-(defun mastodon-media--process-image-response (status-plist marker image-options region-length image-url)
+(defun mastodon-media--process-image-response (status-plist marker image-options region-length)
"Callback function processing the url retrieve response for URL.
STATUS-PLIST is the usual plist of status events as per `url-retrieve'.
IMAGE-OPTIONS are the precomputed options to apply to the image.
MARKER is the marker to where the response should be visible.
REGION-LENGTH is the length of the region that should be replaced with the image.
-IMAGE-URL is the URL that was retrieved.
"
(let ((url-buffer (current-buffer))
(is-error-response-p (eq :error (car status-plist))))
@@ -164,12 +167,12 @@ MEDIA-TYPE is a symbol and either 'avatar or 'media-link."
(let ((image-options (when (image-type-available-p 'imagemagick)
(cond
((eq media-type 'avatar)
- `(:height ,mastodon-avatar-height))
+ `(:height ,mastodon-media--avatar-height))
((eq media-type 'media-link)
- `(:max-height ,mastodon-preview-max-height))))))
+ `(:max-height ,mastodon-media--preview-max-height))))))
(url-retrieve url
#'mastodon-media--process-image-response
- (list (copy-marker start) image-options region-length url))))
+ (list (copy-marker start) image-options region-length))))
(defun mastodon-media--select-next-media-line ()
"Find coordinates of the next media to load.
@@ -225,7 +228,7 @@ not been returned."
;; This is what a user will see on a non-graphical display
;; where not showing an avatar at all is preferable.
(let ((image-options (when (image-type-available-p 'imagemagick)
- `(:height ,mastodon-avatar-height))))
+ `(:height ,mastodon-media--avatar-height))))
(concat
(propertize " "
'media-url avatar-url
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index 42cb252..eeed6b5 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Homepage: https://github.com/jdenen/mastodon.el
;; Package-Requires: ((emacs "24.4"))
@@ -29,30 +29,48 @@
;;; Code:
-(require 'mastodon-http)
-(require 'mastodon-toot)
-(require 'mastodon-media)
+(require 'shr)
+(require 'thingatpt) ;; for word-at-point
(require 'time-date)
+(autoload 'mastodon-http--api "mastodon-http")
+(autoload 'mastodon-http--get-json "mastodon-http")
+(autoload 'mastodon-media--get-avatar-rendering "mastodon-media")
+(autoload 'mastodon-media--get-media-link-rendering "mastodon-media")
+(autoload 'mastodon-media--inline-images "mastodon-media")
+(autoload 'mastodon-mode "mastodon")
+(defvar mastodon-toot-timestamp-format)
+
(defgroup mastodon-tl nil
"Timelines in Mastodon."
:prefix "mastodon-tl-"
:group 'mastodon)
+(defvar mastodon-tl--buffer-spec nil
+ "A unique identifier and functions for each Mastodon buffer.")
+
+(defvar mastodon-tl--show-avatars-p
+ (image-type-available-p 'imagemagick)
+ "A boolean value stating whether to show avatars in timelines.")
+
+
(defun mastodon-tl--get-federated-timeline ()
"Opens federated timeline."
(interactive)
- (mastodon-tl--get "public"))
+ (mastodon-tl--init
+ "federated" "timelines/public" 'mastodon-tl--timeline))
(defun mastodon-tl--get-home-timeline ()
"Opens home timeline."
(interactive)
- (mastodon-tl--get "home"))
+ (mastodon-tl--init
+ "home" "timelines/home" 'mastodon-tl--timeline))
(defun mastodon-tl--get-local-timeline ()
"Opens local timeline."
(interactive)
- (mastodon-tl--get "public?local=true"))
+ (mastodon-tl--init
+ "local" "timelines/public?local=true" 'mastodon-tl--timeline))
(defun mastodon-tl--get-tag-timeline ()
"Prompts for tag and opens its timeline."
@@ -60,8 +78,8 @@
(let* ((word (or (word-at-point) ""))
(input (read-string (format "Tag(%s): " word)))
(tag (if (equal input "") word input)))
- (print tag)
- (mastodon-tl--get (concat "tag/" tag))))
+ (mastodon-tl--init
+ (concat "tag-" tag) (concat "timelines/tag/" tag) 'mastodon-tl--timeline)))
(defun mastodon-tl--goto-toot-pos (find-pos refresh &optional pos)
"Search for toot with FIND-POS.
@@ -90,11 +108,6 @@ Optionally start from POS."
(mastodon-tl--goto-toot-pos 'previous-single-property-change
'mastodon-tl--update))
-(defun mastodon-tl--timeline-name ()
- "Determine timeline from `buffer-name'."
- (replace-regexp-in-string "\*" ""
- (replace-regexp-in-string "mastodon-" "" (buffer-name))))
-
(defun mastodon-tl--remove-html (toot)
"Remove unrendered tags from TOOT."
(let* ((t1 (replace-regexp-in-string "<\/p>" "\n\n" toot))
@@ -108,13 +121,13 @@ Optionally start from POS."
(name (cdr (assoc 'display_name account)))
(avatar-url (cdr (assoc 'avatar account))))
(concat
- (when mastodon-media-show-avatars-p
+ (when mastodon-tl--show-avatars-p
(mastodon-media--get-avatar-rendering avatar-url))
(propertize name 'face 'mastodon-display-name-face)
(propertize (concat " (@"
- handle
- ")")
- 'face 'mastodon-handle-face))))
+ handle
+ ")")
+ 'face 'mastodon-handle-face))))
(defun mastodon-tl--byline-boosted (toot)
"Add byline for boosted data from TOOT."
@@ -143,10 +156,10 @@ Return value from boosted content if available."
(concat (propertize "\n | " 'face 'default)
(when boosted
(format "(%s) "
- (propertize "B" 'face 'mastodon-boost-fave-face)))
+ (propertize "B" 'face 'mastodon-boost-fave-face)))
(when faved
(format "(%s) "
- (propertize "F" 'face 'mastodon-boost-fave-face)))
+ (propertize "F" 'face 'mastodon-boost-fave-face)))
(mastodon-tl--byline-author toot)
(mastodon-tl--byline-boosted toot)
" "
@@ -184,12 +197,17 @@ also render the html"
(defun mastodon-tl--media (toot)
"Retrieve a media attachment link for TOOT if one exists."
- (let ((media-attachements (mastodon-tl--field 'media_attachments toot)))
- (mapconcat
- (lambda (media-attachement)
- (let ((preview-url (cdr (assoc 'preview_url media-attachement))))
- (mastodon-media--get-media-link-rendering preview-url)))
- media-attachements "")))
+ (let* ((media-attachements (mastodon-tl--field 'media_attachments toot))
+ (media-string (mapconcat
+ (lambda (media-attachement)
+ (let ((preview-url
+ (cdr (assoc 'preview_url media-attachement))))
+ (mastodon-media--get-media-link-rendering
+ preview-url)))
+ media-attachements "")))
+ (if (not (equal media-string ""))
+ (concat "\n" media-string ) "")))
+
(defun mastodon-tl--content (toot)
"Retrieve text content from TOOT."
@@ -206,33 +224,63 @@ also render the html"
(insert
(concat
(mastodon-tl--spoiler toot)
- (mastodon-tl--content toot)
+ ;; remove two trailing newlines
+ (substring (mastodon-tl--content toot) 0 -2)
(mastodon-tl--media toot)
+ "\n\n"
(mastodon-tl--byline toot)
"\n\n")))
(defun mastodon-tl--timeline (toots)
"Display each toot in TOOTS."
- (mapcar 'mastodon-tl--toot toots)
- (replace-regexp "\n\n\n | " "\n | " nil (point-min) (point-max))
+ (mapc 'mastodon-tl--toot toots)
+ (goto-char (point-min))
+ (while (search-forward "\n\n\n | " nil t)
+ (replace-match "\n | "))
(mastodon-media--inline-images))
-(defun mastodon-tl--more-json (timeline id)
- "Return JSON for TIMELINE before ID."
- (let ((url (mastodon-http--api (concat "timelines/"
- timeline
- "?max_id="
- (number-to-string id)))))
+(defun mastodon-tl--get-update-function (&optional buffer)
+ "Get the UPDATE-FUNCTION stored in `mastodon-tl--buffer-spec'"
+ (mastodon-tl--get-buffer-property 'update-function buffer))
+
+(defun mastodon-tl--get-endpoint (&optional buffer)
+ "Get the ENDPOINT stored in `mastodon-tl--buffer-spec'"
+ (mastodon-tl--get-buffer-property 'endpoint buffer))
+
+(defun mastodon-tl--buffer-name (&optional buffer)
+ "Get the BUFFER-NAME stored in `mastodon-tl--buffer-spec'"
+ (mastodon-tl--get-buffer-property 'buffer-name buffer ))
+
+(defun mastodon-tl--get-buffer-property (property &optional buffer)
+ "Get `MASTODON-TL--BUFFER-SPEC' in BUFFER or `CURRENT-BUFFER'"
+ (with-current-buffer (or buffer (current-buffer))
+ (if (plist-get mastodon-tl--buffer-spec property)
+ (plist-get mastodon-tl--buffer-spec property)
+ (error "mastodon-tl--buffer-spec is not defined for buffer %s"
+ (or buffer (current-buffer))))))
+
+(defun mastodon-tl--more-json (endpoint id)
+ "Return JSON for timeline ENDPOINT before ID."
+ (let* ((url (mastodon-http--api (concat
+ endpoint
+ (if (string-match-p "?" endpoint)
+ "&"
+ "?")
+ "max_id="
+ (number-to-string id)))))
(mastodon-http--get-json url)))
;; TODO
;; Look into the JSON returned here by Local
-(defun mastodon-tl--updated-json (timeline id)
- "Return JSON for TIMELINE since ID."
- (let ((url (mastodon-http--api (concat "timelines/"
- timeline
- "?since_id="
- (number-to-string id)))))
+(defun mastodon-tl--updated-json (endpoint id)
+ "Return JSON for timeline ENDPOINT since ID."
+ (let ((url (mastodon-http--api (concat
+ endpoint
+ (if (string-match-p "?" endpoint)
+ "&"
+ "?")
+ "since_id="
+ (number-to-string id)))))
(mastodon-http--get-json url)))
(defun mastodon-tl--property (prop &optional backward)
@@ -276,38 +324,47 @@ Move forward (down) the timeline unless BACKWARD is non-nil."
"Append older toots to timeline."
(interactive)
(let* ((point-before (point))
- (tl (mastodon-tl--timeline-name))
+ (endpoint (mastodon-tl--get-endpoint))
+ (update-function (mastodon-tl--get-update-function))
(id (mastodon-tl--oldest-id))
- (json (mastodon-tl--more-json tl id)))
+ (json (mastodon-tl--more-json endpoint id)))
(when json
- (with-current-buffer (current-buffer)
- (let ((inhibit-read-only t))
- (goto-char (point-max))
- (mastodon-tl--timeline json)
- (goto-char point-before)
- (mastodon-tl--goto-next-toot))))))
+ (let ((inhibit-read-only t))
+ (goto-char (point-max))
+ (funcall update-function json)
+ (goto-char point-before)))))
(defun mastodon-tl--update ()
"Update timeline with new toots."
(interactive)
- (let* ((tl (mastodon-tl--timeline-name))
+ (let* ((endpoint (mastodon-tl--get-endpoint))
+ (update-function (mastodon-tl--get-update-function))
(id (mastodon-tl--newest-id))
- (json (mastodon-tl--updated-json tl id)))
+ (json (mastodon-tl--updated-json endpoint id)))
(when json
- (with-current-buffer (current-buffer)
- (let ((inhibit-read-only t))
- (goto-char (point-min))
- (mastodon-tl--timeline json))))))
-
-(defun mastodon-tl--get (timeline)
- "Display TIMELINE in buffer."
- (let* ((url (mastodon-http--api (concat "timelines/" timeline)))
- (buffer (concat "*mastodon-" timeline "*"))
+ (let ((inhibit-read-only t))
+ (goto-char (point-min))
+ (funcall update-function json)))))
+
+
+(defun mastodon-tl--init (buffer-name endpoint update-function)
+ "Initialize BUFFER-NAME with timeline targeted by ENDPOINT.
+
+UPDATE-FUNCTION is used to recieve more toots."
+ (let* ((url (mastodon-http--api endpoint))
+ (buffer (concat "*mastodon-" buffer-name "*"))
(json (mastodon-http--get-json url)))
(with-output-to-temp-buffer buffer
(switch-to-buffer buffer)
- (mastodon-tl--timeline json))
- (mastodon-mode)))
+ (funcall update-function json))
+ (mastodon-mode)
+ (with-current-buffer buffer
+ (make-local-variable 'mastodon-tl--buffer-spec)
+ (setq mastodon-tl--buffer-spec
+ `(buffer-name ,buffer-name
+ endpoint ,endpoint update-function
+ ,update-function)))
+ buffer))
(provide 'mastodon-tl)
;;; mastodon-tl.el ends here
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index fc31a5b..7d33116 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Homepage: https://github.com/jdenen/mastodon.el
;; Package-Requires: ((emacs "24.4"))
@@ -29,16 +29,26 @@
;;; Code:
-(require 'mastodon-auth nil t)
-
-(defgroup mastodon-toot nil
- "Capture Mastodon toots."
- :prefix "mastodon-toot-"
- :group 'mastodon)
-
(defvar mastodon-toot--reply-to-id nil)
(defvar mastodon-toot--content-warning nil)
+(autoload 'mastodon-http--api "mastodon-http")
+(autoload 'mastodon-http--post "mastodon-http")
+(autoload 'mastodon-http--triage "mastodon-http")
+(autoload 'mastodon-tl--field "mastodon-tl")
+(autoload 'mastodon-tl--goto-next-toot "mastodon-tl")
+(autoload 'mastodon-tl--property "mastodon-tl")
+(autoload 'mastodon-toot "mastodon")
+
+(defvar mastodon-toot-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c C-c") #'mastodon-toot--send)
+ (define-key map (kbd "C-c C-k") #'mastodon-toot--cancel)
+ (define-key map (kbd "C-c C-w") #'mastodon-toot--toggle-warning)
+ map)
+ "Keymap for `mastodon-toot'.")
+
+
(defun mastodon-toot--action-success (marker &optional rm)
"Insert MARKER with 'success face in byline.
@@ -46,7 +56,10 @@ Remove MARKER if RM is non-nil."
(let ((inhibit-read-only t)
(bol (progn (move-beginning-of-line nil) (point)))
(eol (progn (move-end-of-line nil) (point))))
- (when rm (replace-regexp (format "(%s) " marker) "" nil bol eol))
+ (when rm
+ (goto-char bol)
+ (if (search-forward (format "(%s) " marker) eol t)
+ (replace-match "")))
(move-beginning-of-line nil)
(mastodon-tl--goto-next-toot)
(unless rm
@@ -153,28 +166,28 @@ Set `mastodon-toot--content-warning' to nil."
(mapcar (lambda (b)
(setf (car b) (vector prefix (car b)))
b)
- bindings)))
+ bindings)))
(defun mastodon-toot--format-kbind-command (cmd)
"Format CMD to be more readable.
e.g. mastodon-toot--send -> Send."
(let* ((str (symbol-name cmd))
- (re "--\\(.*\\)$")
- (str2 (save-match-data
- (string-match re str)
- (match-string 1 str))))
+ (re "--\\(.*\\)$")
+ (str2 (save-match-data
+ (string-match re str)
+ (match-string 1 str))))
(capitalize (replace-regexp-in-string "-" " " str2))))
(defun mastodon-toot--format-kbind (kbind)
"Format a single keybinding, KBIND, for display in documentation."
(let ((key (help-key-description (car kbind) nil))
- (command (mastodon-toot--format-kbind-command (cdr kbind))))
+ (command (mastodon-toot--format-kbind-command (cdr kbind))))
(format "\t%s - %s" key command)))
(defun mastodon-toot--format-kbinds (kbinds)
"Format a list keybindings, KBINDS, for display in documentation."
(mapconcat 'identity (cons "" (mapcar #'mastodon-toot--format-kbind kbinds))
- "\n"))
+ "\n"))
(defun mastodon-toot--make-mode-docs ()
"Create formatted documentation text for the mastodon-toot-mode."
@@ -204,21 +217,13 @@ If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
If REPLY-TO-USER is provided, inject their handle into the message.
If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
(let* ((buffer-exists (get-buffer "*new toot*"))
- (buffer (or buffer-exists (get-buffer-create "*new toot*"))))
+ (buffer (or buffer-exists (get-buffer-create "*new toot*"))))
(switch-to-buffer-other-window buffer)
(when (not buffer-exists)
(mastodon-toot--display-docs)
(mastodon-toot--setup-as-reply reply-to-user reply-to-id))
(mastodon-toot-mode t)))
-(defvar mastodon-toot-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-c C-c") #'mastodon-toot--send)
- (define-key map (kbd "C-c C-k") #'mastodon-toot--cancel)
- (define-key map (kbd "C-c C-w") #'mastodon-toot--toggle-warning)
- map)
- "Keymap for `mastodon-toot'.")
-
(define-minor-mode mastodon-toot-mode
"Minor mode to capture Mastodon toots."
:group 'mastodon-toot
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index b75c608..2bf5e84 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2017 Johnson Denen
;; Author: Johnson Denen <johnson.denen@gmail.com>
-;; Version: 0.6.3
+;; Version: 0.7.0
;; Package-Requires: ((emacs "24.4"))
;; Homepage: https://github.com/jdenen/mastodon.el
@@ -30,8 +30,20 @@
;; it is a labor of love.
;;; Code:
-
-(require 'mastodon-auth nil t)
+(declare-function discover-add-context-menu "discover")
+(declare-function emojify-mode "emojify")
+(autoload 'mastodon-tl--get-federated-timeline "mastodon-tl")
+(autoload 'mastodon-tl--get-home-timeline "mastodon-tl")
+(autoload 'mastodon-tl--get-local-timeline "mastodon-tl")
+(autoload 'mastodon-tl--get-tag-timeline "mastodon-tl")
+(autoload 'mastodon-tl--goto-next-toot "mastodon-tl")
+(autoload 'mastodon-tl--goto-prev-toot "mastodon-tl")
+(autoload 'mastodon-tl--thread "mastodon-tl")
+(autoload 'mastodon-tl--update "mastodon-tl")
+(autoload 'mastodon-toot--compose-buffer "mastodon-toot")
+(autoload 'mastodon-toot--reply "mastodon-toot")
+(autoload 'mastodon-toot--toggle-boost "mastodon-toot")
+(autoload 'mastodon-toot--toggle-favourite "mastodon-toot")
(defgroup mastodon nil
"Interface with Mastodon."
@@ -43,11 +55,6 @@
:group 'mastodon
:type 'string)
-(defcustom mastodon-token-file (concat user-emacs-directory "mastodon.plstore")
- "File path where Mastodon access tokens are stored."
- :group 'mastodon
- :type 'file)
-
(defcustom mastodon-toot-timestamp-format "%F %T"
"Format to use for timestamps.
@@ -57,22 +64,10 @@ Use. e.g. \"%c\" for your locale's date and time format."
:group 'mastodon
:type 'string)
-(defcustom mastodon-avatar-height 30
- "Height of the user avatar images (if shown)."
- :group 'mastodon
- :type 'integer)
-
-(defcustom mastodon-preview-max-height 250
- "Max height of any media attachment preview to be shown."
- :group 'mastodon
- :type 'integer)
-
(defvar mastodon-mode-map
(make-sparse-keymap)
"Keymap for `mastodon-mode'.")
-(defvar mastodon--api-version "v1")
-
(defcustom mastodon-mode-hook nil
"Hook run when entering Mastodon mode."
:type 'hook
@@ -103,8 +98,7 @@ Use. e.g. \"%c\" for your locale's date and time format."
(defun mastodon ()
"Connect Mastodon client to `mastodon-instance-url' instance."
(interactive)
- (require 'mastodon-tl nil t)
- (mastodon-tl--get "home"))
+ (mastodon-tl--get-home-timeline))
;;;###autoload
(defun mastodon-toot (&optional user reply-to-id)
@@ -113,7 +107,6 @@ Use. e.g. \"%c\" for your locale's date and time format."
If USER is non-nil, insert after @ symbol to begin new toot.
If REPLY-TO-ID is non-nil, attach new toot to a conversation."
(interactive)
- (require 'mastodon-toot nil t)
(mastodon-toot--compose-buffer user reply-to-id))
;;;###autoload
diff --git a/test/mastodon-client-tests.el b/test/mastodon-client-tests.el
index e1f92f8..c339efa 100644
--- a/test/mastodon-client-tests.el
+++ b/test/mastodon-client-tests.el
@@ -54,22 +54,22 @@
(ert-deftest client-1 ()
"Should return `mastondon-client' if non-nil."
- (let ((mastodon-client t))
+ (let ((mastodon-client--client-details t))
(should (eq (mastodon-client) t))))
(ert-deftest client-2 ()
"Should read from `mastodon-token-file' if available."
- (let ((mastodon-client nil))
+ (let ((mastodon-client--client-details nil))
(with-mock
(mock (mastodon-client--read) => '(:client_id "foo" :client_secret "bar"))
(should (equal (mastodon-client) '(:client_id "foo" :client_secret "bar")))
- (should (equal mastodon-client '(:client_id "foo" :client_secret "bar"))))))
+ (should (equal mastodon-client--client-details '(:client_id "foo" :client_secret "bar"))))))
(ert-deftest client-3 ()
"Should store client data in plstore if it can't be read."
- (let ((mastodon-client nil))
+ (let ((mastodon-client--client-details nil))
(with-mock
(mock (mastodon-client--read))
(mock (mastodon-client--store) => '(:client_id "foo" :client_secret "baz"))
(should (equal (mastodon-client) '(:client_id "foo" :client_secret "baz")))
- (should (equal mastodon-client '(:client_id "foo" :client_secret "baz"))))))
+ (should (equal mastodon-client--client-details '(:client_id "foo" :client_secret "baz"))))))
diff --git a/test/mastodon-media-tests.el b/test/mastodon-media-tests.el
index 9cd06b7..4bb89c7 100644
--- a/test/mastodon-media-tests.el
+++ b/test/mastodon-media-tests.el
@@ -6,7 +6,7 @@
(mock (image-type-available-p 'imagemagick) => t)
(mock (create-image * 'imagemagick t :height 123) => :mock-image)
- (let* ((mastodon-avatar-height 123)
+ (let* ((mastodon-media--avatar-height 123)
(result (mastodon-media--get-avatar-rendering "http://example.org/img.png"))
(result-no-properties (substring-no-properties result))
(properties (text-properties-at 0 result)))
@@ -21,7 +21,7 @@
(with-mock
(mock (create-image * nil t) => :mock-image)
- (let* ((mastodon-preview-max-height 123)
+ (let* ((mastodon-media--preview-max-height 123)
(result (mastodon-media--get-media-link-rendering "http://example.org/img.png"))
(result-no-properties (substring-no-properties result))
(properties (text-properties-at 0 result)))
@@ -34,7 +34,7 @@
(ert-deftest mastodon-media:load-image-from-url:avatar-with-imagemagic ()
"Should make the right call to url-retrieve."
(let ((url "http://example.org/image.png")
- (mastodon-avatar-height 123))
+ (mastodon-media--avatar-height 123))
(with-mock
(mock (image-type-available-p 'imagemagick) => t)
(mock (create-image * 'imagemagick t :height 123) => '(image foo))
@@ -42,7 +42,7 @@
(mock (url-retrieve
url
#'mastodon-media--process-image-response
- '(:my-marker (:height 123) 1 "http://example.org/image.png"))
+ '(:my-marker (:height 123) 1))
=> :called-as-expected)
(with-temp-buffer
@@ -62,7 +62,7 @@
(mock (url-retrieve
url
#'mastodon-media--process-image-response
- '(:my-marker () 1 "http://example.org/image.png"))
+ '(:my-marker () 1))
=> :called-as-expected)
(with-temp-buffer
@@ -82,13 +82,13 @@
(mock (url-retrieve
"http://example.org/image.png"
#'mastodon-media--process-image-response
- '(:my-marker (:max-height 321) 5 "http://example.org/image.png"))
+ '(:my-marker (:max-height 321) 5))
=> :called-as-expected)
(with-temp-buffer
(insert (concat "Start:"
(mastodon-media--get-media-link-rendering url)
":rest"))
- (let ((mastodon-preview-max-height 321))
+ (let ((mastodon-media--preview-max-height 321))
(should (eq :called-as-expected (mastodon-media--load-image-from-url url 'media-link 7 5))))))))
(ert-deftest mastodon-media:load-image-from-url:media-link-without-imagemagic ()
@@ -101,14 +101,14 @@
(mock (url-retrieve
"http://example.org/image.png"
#'mastodon-media--process-image-response
- '(:my-marker () 5 "http://example.org/image.png"))
+ '(:my-marker () 5))
=> :called-as-expected)
(with-temp-buffer
(insert (concat "Start:"
(mastodon-media--get-avatar-rendering url)
":rest"))
- (let ((mastodon-preview-max-height 321))
+ (let ((mastodon-media--preview-max-height 321))
(should (eq :called-as-expected (mastodon-media--load-image-from-url url 'media-link 7 5))))))))
(ert-deftest mastodon-media:process-image-response ()
@@ -134,7 +134,7 @@
(mock (create-image "fake\nimage\ndata" 'imagemagick t ':image :option) => :fake-image)
- (mastodon-media--process-image-response () used-marker '(:image :option) 1 "the-url")
+ (mastodon-media--process-image-response () used-marker '(:image :option) 1)
;; the used marker has been unset:
(should (null (marker-position used-marker)))
diff --git a/test/mastodon-tl-tests.el b/test/mastodon-tl-tests.el
index a91d6d5..8c706f5 100644
--- a/test/mastodon-tl-tests.el
+++ b/test/mastodon-tl-tests.el
@@ -101,11 +101,11 @@
(let ((mastodon-instance-url "https://instance.url"))
(with-mock
(mock (mastodon-http--get-json "https://instance.url/api/v1/timelines/foo?max_id=12345"))
- (mastodon-tl--more-json "foo" 12345))))
+ (mastodon-tl--more-json "timelines/foo" 12345))))
(ert-deftest mastodon-tl--byline-regular ()
"Should format the regular toot correctly."
- (let ((mastodon-media-show-avatars-p nil)
+ (let ((mastodon-tl--show-avatars-p nil)
(timestamp (cdr (assoc 'created_at mastodon-tl-test-base-toot))))
(with-mock
(mock (date-to-time timestamp) => '(22782 21551))
@@ -119,7 +119,7 @@
(ert-deftest mastodon-tl--byline-regular-with-avatar ()
"Should format the regular toot correctly."
- (let ((mastodon-media-show-avatars-p t)
+ (let ((mastodon-tl--show-avatars-p t)
(timestamp (cdr (assoc 'created_at mastodon-tl-test-base-toot))))
(with-mock
(stub create-image => '(image "fake data"))
@@ -134,7 +134,7 @@
(ert-deftest mastodon-tl--byline-boosted ()
"Should format the boosted toot correctly."
- (let* ((mastodon-media-show-avatars-p nil)
+ (let* ((mastodon-tl--show-avatars-p nil)
(toot (cons '(reblogged . t) mastodon-tl-test-base-toot))
(timestamp (cdr (assoc 'created_at toot))))
(with-mock
@@ -148,7 +148,7 @@
(ert-deftest mastodon-tl--byline-favorited ()
"Should format the favourited toot correctly."
- (let* ((mastodon-media-show-avatars-p nil)
+ (let* ((mastodon-tl--show-avatars-p nil)
(toot (cons '(favourited . t) mastodon-tl-test-base-toot))
(timestamp (cdr (assoc 'created_at toot))))
(with-mock
@@ -163,7 +163,7 @@
(ert-deftest mastodon-tl--byline-boosted/favorited ()
"Should format the boosted & favourited toot correctly."
- (let* ((mastodon-media-show-avatars-p nil)
+ (let* ((mastodon-tl--show-avatars-p nil)
(toot `((favourited . t) (reblogged . t) ,@mastodon-tl-test-base-toot))
(timestamp (cdr (assoc 'created_at toot))))
(with-mock
@@ -177,7 +177,7 @@
(ert-deftest mastodon-tl--byline-reblogged ()
"Should format the reblogged toot correctly."
- (let* ((mastodon-media-show-avatars-p nil)
+ (let* ((mastodon-tl--show-avatars-p nil)
(toot mastodon-tl-test-base-boosted-toot)
(original-toot (cdr (assoc 'reblog mastodon-tl-test-base-boosted-toot)))
(timestamp (cdr (assoc 'created_at toot)))
@@ -197,7 +197,7 @@
(ert-deftest mastodon-tl--byline-reblogged-with-avatars ()
"Should format the reblogged toot correctly."
- (let* ((mastodon-media-show-avatars-p t)
+ (let* ((mastodon-tl--show-avatars-p t)
(toot mastodon-tl-test-base-boosted-toot)
(original-toot (cdr (assoc 'reblog mastodon-tl-test-base-boosted-toot)))
(timestamp (cdr (assoc 'created_at toot)))
@@ -218,7 +218,7 @@
(ert-deftest mastodon-tl--byline-reblogged-boosted/favorited ()
"Should format the reblogged toot that was also boosted & favoritedcorrectly."
- (let* ((mastodon-media-show-avatars-p nil)
+ (let* ((mastodon-tl--show-avatars-p nil)
(toot `((favourited . t) (reblogged . t) ,@mastodon-tl-test-base-boosted-toot))
(original-toot (cdr (assoc 'reblog mastodon-tl-test-base-boosted-toot)))
(timestamp (cdr (assoc 'created_at toot)))