diff options
-rw-r--r-- | README.org | 141 | ||||
-rw-r--r-- | lisp/mastodon-discover.el | 10 | ||||
-rw-r--r-- | lisp/mastodon-tl.el | 13 | ||||
-rw-r--r-- | lisp/mastodon-toot.el | 20 | ||||
-rw-r--r-- | lisp/mastodon.el | 19 |
5 files changed, 119 insertions, 84 deletions
@@ -1,5 +1,3 @@ -#+OPTIONS: toc:nil - @@html: <a href="https://melpa.org/#/mastodon"><img alt="MELPA" src="https://melpa.org/packages/mastodon-badge.svg"/></a>@@ @@html: <a href="https://ci.codeberg.org/martianh/mastodon.el"><img alt="Build Status" src="https://ci.codeberg.org/api/badges/martianh/mastodon.el/status.svg"></a>@@ @@ -109,69 +107,70 @@ not contain =:client_id= and =:client_secret=. **** Keybindings -|----------------+-----------------------------------------------------------------------| -| Key | Action | -|----------------+-----------------------------------------------------------------------| -| | *Help* | -| =?= | Open context menu if =discover= is available | -|----------------+-----------------------------------------------------------------------| -| | *Timeline actions* | -| =n= | Go to next item (toot, notification) | -| =p= | Go to previous item (toot, notification) | -| =M-n=/=<tab>= | Go to the next interesting thing that has an action | -| =M-p=/=<S-tab>= | Go to the previous interesting thing that has an action | -| =F= | Open federated timeline | -| =H= | Open home timeline | -| =L= | Open local timeline | -| =N= | Open notifications timeline | -| =@= | Open mentions-only notifications timeline | -| =u= | Update current timeline | -| =T= | Open thread for toot under =point= | -| =#= | Prompt for tag and open its timeline | -| =A= | Open author profile of toot under =point= | -| =P= | Open profile of user attached to toot under =point= | -| =O= | View own profile | -| =U= | update your profile bio note | -|----------------+-----------------------------------------------------------------------| -| | *Other views* | -| =S= | search (posts, users, tags) (NB: only posts you have interacted with) | -| =I=, =c=, =d= | view, create, and delete filters | -| =R=, =a=, =j= | view/accept/reject follow requests | -| =G= | view follow suggestions | -| =V= | view your favourited toots | -| =K= | view bookmarked toots | -| =X= | view/edit/create/delete lists | -|----------------+-----------------------------------------------------------------------| -| | *Toot actions* | -| =t= | Compose a new toot | -| =c= | Toggle content warning content | -| =b= | Boost toot under =point= | -| =f= | Favourite toot under =point= | -| =k= | toggle bookmark of toot at point | -| =r= | Reply to toot under =point= | -| =v= | Vote on poll at point | -| =C= | copy url of toot at point | -| =C-RET= | play video/gif at point (requires =mpv=) | -| =e= | edit your toot at point | -| =E= | view edits of toot at point | -| =i= | (un)pin your toot at point | -| =d= | delete your toot at point, and reload current timeline | -| =D= | delete and redraft toot at point, preserving reply/CW/visibility | -| (=S-C-=) =W=, =M=, =B= | (un)follow, (un)mute, (un)block author of toot at point | -|----------------+-----------------------------------------------------------------------| -| | *Profile view* | +|----------------+---------------------------------------------------------------------------| +| Key | Action | +|----------------+---------------------------------------------------------------------------| +| | *Help* | +| =?= | Open context menu if =discover= is available | +|----------------+---------------------------------------------------------------------------| +| | *Timeline actions* | +| =n= | Go to next item (toot, notification) | +| =p= | Go to previous item (toot, notification) | +| =M-n=/=<tab>= | Go to the next interesting thing that has an action | +| =M-p=/=<S-tab>= | Go to the previous interesting thing that has an action | +| =F= | Open federated timeline | +| =H= | Open home timeline | +| =L= | Open local timeline | +| =N= | Open notifications timeline | +| =@= | Open mentions-only notifications timeline | +| =u= | Update current timeline | +| =T= | Open thread for toot under =point= | +| =#= | Prompt for tag and open its timeline | +| =A= | Open author profile of toot under =point= | +| =P= | Open profile of user attached to toot under =point= | +| =O= | View own profile | +| =U= | update your profile bio note | +|----------------+---------------------------------------------------------------------------| +| | *Other views* | +| =S= | search (posts, users, tags) (NB: only posts you have interacted with) | +| =I=, =c=, =d= | view, create, and delete filters | +| =R=, =a=, =j= | view/accept/reject follow requests | +| =G= | view follow suggestions | +| =V= | view your favourited toots | +| =K= | view bookmarked toots | +| =X= | view/edit/create/delete lists | +| =s= | view your scheduled toots | +|----------------+---------------------------------------------------------------------------| +| | *Toot actions* | +| =t= | Compose a new toot | +| =c= | Toggle content warning content | +| =b= | Boost toot under =point= | +| =f= | Favourite toot under =point= | +| =k= | toggle bookmark of toot at point | +| =r= | Reply to toot under =point= | +| =v= | Vote on poll at point | +| =C= | copy url of toot at point | +| =C-RET= | play video/gif at point (requires =mpv=) | +| =e= | edit your toot at point | +| =E= | view edits of toot at point | +| =i= | (un)pin your toot at point | +| =d= | delete your toot at point, and reload current timeline | +| =D= | delete and redraft toot at point, preserving reply/CW/visibility | +| (=S-C-=) =W=, =M=, =B= | (un)follow, (un)mute, (un)block author of toot at point | +|----------------+---------------------------------------------------------------------------| +| | *Profile view* | | =C-c C-c= | cycle between statuses, followers, following, and statuses without boosts | -| | =mastodon-profile--account-account-to-list= (see lists view) | -|----------------+-----------------------------------------------------------------------| -| | *Notifications view* | -| =a=, =j= | accept/reject follow request | -| =c= | clear notification at point | -| | see =mastodon-notifications--get-*= functions for filtered views | -|----------------+-----------------------------------------------------------------------| -| | *Quitting* | -| =q= | Quit mastodon buffer, leave window open | -| =Q= | Quit mastodon buffer and kill window | -|----------------+-----------------------------------------------------------------------| +| | =mastodon-profile--account-account-to-list= (see lists view) | +|----------------+---------------------------------------------------------------------------| +| | *Notifications view* | +| =a=, =j= | accept/reject follow request | +| =c= | clear notification at point | +| | see =mastodon-notifications--get-*= functions for filtered views | +|----------------+---------------------------------------------------------------------------| +| | *Quitting* | +| =q= | Quit mastodon buffer, leave window open | +| =Q= | Quit mastodon buffer and kill window | +|----------------+---------------------------------------------------------------------------| **** Toot byline legend @@ -217,7 +216,7 @@ You can download and use your instance's custom emoji | =C-c C-l= | Set toot language | |---------+----------------------------------| -**** draft toots +**** Draft toots - Compose buffer text is saved as you type, kept in =mastodon-toot-current-toot-text=. - =mastodon-toot--save-draft=: save the current toot as a draft. @@ -303,7 +302,7 @@ view a timeline with one of the commands that begin with *** Translating toots -You can translate toots with =mastodon-toot--translate-toot-text=. At the moment +You can translate toots with =mastodon-toot--translate-toot-text= (=a= in a timeline). At the moment this requires [[https://codeberg.org/martianh/lingva.el][lingva.el]], a little interface I wrote to https://lingva.ml, to be installed to work. @@ -336,7 +335,7 @@ Optional dependencies: - =mpv= and =mpv.el= for viewing videos and gifs - =lingva.el= for translating toots -** Network compatibility. +** Network compatibility =mastodon.el= should work with ActivityPub servers that implement the Mastodon API. @@ -367,23 +366,23 @@ PRs, issues, feature requests, and general feedback are very welcome! 3. Run the tests and ensure that your code doesn't break any of them. 4. Create a pull request referencing the issue created in step 1. -*** coding style +*** Coding style - This library uses an unconvential double dash (=--=) between file namespaces and function names, which contradicts normal Elisp style. This needs to be respected until the whole library is changed. - Use =aggressive-indent-mode= or similar to keep your code indented. - Single spaces end sentences in docstrings. - There's no need for a blank line after the first docstring line (one is added automatically when documentation is displayed). -** Supporting mastodon.el +** Supporting =mastodon.el= If you'd like to support continued development of =mastodon.el=, I accept -donations via paypal: https://paypal.me/martianh. If you would +donations via paypal: [[https://paypal.me/martianh][paypal.me/martianh]]. If you would prefer a different payment method, write to me at that address and I can provide IBAN or other details. I don't have a tech worker's income, so even a small tip would help out. -** Contributors: +** Contributors =mastodon.el= is the work of a number of people. diff --git a/lisp/mastodon-discover.el b/lisp/mastodon-discover.el index 1b960e5..b3819ed 100644 --- a/lisp/mastodon-discover.el +++ b/lisp/mastodon-discover.el @@ -66,9 +66,11 @@ ("C" "Copy toot URL" mastodon-toot--copy-toot-url) ("d" "Delete (your) toot" mastodon-toot--delete-toot) ("D" "Delete and redraft (your) toot" mastodon-toot--delete-toot) + ("e" "Edit (your) toot" mastodon-toot--edit-toot-at-point) + ("E" "View edits of (your) toot" mastodon-toot--view-toot-edits) ("i" "Pin/Unpin (your) toot" mastodon-toot--pin-toot-toggle) ("P" "View user profile" mastodon-profile--show-user) - ("s" "Translate toot at point" mastodon-toot--translate-toot-text) + ("a" "Translate toot at point" mastodon-toot--translate-toot-text) ("T" "View thread" mastodon-tl--thread) ("v" "Vote on poll" mastodon-tl--poll-vote)) ("Views" @@ -78,6 +80,7 @@ ("H" "Home" mastodon-tl--get-home-timeline) ("L" "Local" mastodon-tl--get-local-timeline) ("N" "Notifications" mastodon-notifications-get) + ("@" "Notifications with mentions" mastodon-notifications--get-mentions) ("u" "Update timeline" mastodon-tl--update) ("S" "Search" mastodon-search--search-query) ("O" "Jump to your profile" mastodon-profile--my-profile) @@ -86,7 +89,10 @@ ("V" "View favourites" mastodon-profile--view-favourites) ("R" "View follow requests" mastodon-profile--view-follow-requests) ("G" "View follow suggestions" mastodon-tl--get-follow-suggestions) - ("I" "View filters" mastodon-tl--view-filters)) + ("I" "View filters" mastodon-tl--view-filters) + ("X" "View lists" mastodon-tl--view-lists) + ("s" "View scheduled toots" mastodon-tl--view-scheduled-toots) + (";" "View instance description" mastodon-tl--view-instance-description)) ("Users" ("W" "Follow" mastodon-tl--follow-user) ("C-S-W" "Unfollow" mastodon-tl--unfollow-user) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 99eda44..ae39887 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1431,7 +1431,10 @@ Should work in all mastodon buffers." (let ((endpoint-fun (mastodon-tl--get-endpoint nil :no-error)) (buffer-name-fun (mastodon-tl--buffer-name nil :no-error))) (cond (mastodon-toot-mode - 'compose-toot) + ;; composing/editing: + (if (string= "*edit toot*" (buffer-name)) + 'edit-toot + 'new-toot)) ;; main timelines: ((string= "timelines/home" endpoint-fun) 'home) @@ -1451,6 +1454,8 @@ Should work in all mastodon buffers." ;; threads: ((string-suffix-p "context" endpoint-fun) 'thread) + ((string-prefix-p "statuses" endpoint-fun) + 'single-status) ;; profiles: ((string-prefix-p "accounts" endpoint-fun) (cond @@ -1488,7 +1493,9 @@ Should work in all mastodon buffers." 'scheduled-statuses) ;; instance description ((string= "instance" endpoint-fun) - 'instance-description)))) + 'instance-description) + ((string= "*mastodon-toot-edits*" buffer-name-fun) + 'toot-edits)))) (defun mastodon-tl--has-toots-p () "Return non-nil if the current buffer contains toots. @@ -1907,7 +1914,7 @@ a: add account to this list, r: remove account from this list" "Return the list of followers of the logged in account." (let* ((id (mastodon-auth--get-account-id)) (url (mastodon-http--api (format "accounts/%s/following" id)))) - (mastodon-http--get-json url))) + (mastodon-http--get-json url '(("limit" . "80"))))) ; max 80 accounts (defun mastodon-tl--add-account-to-list-at-point () "Prompt for account and add to list at point." diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 177cfdc..0d4f9e2 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -793,9 +793,9 @@ instance to edit a toot." (toot-language (alist-get 'language toot)) (reply-id (alist-get 'in_reply_to_id toot))) (when (y-or-n-p "Edit this toot? ") - (mastodon-toot--compose-buffer) + (mastodon-toot--compose-buffer nil reply-id nil content :edit) (goto-char (point-max)) - (insert content) + ;; (insert content) ;; adopt reply-to-id, visibility, CW, and language: (mastodon-toot--set-toot-properties reply-id toot-visibility source-cw toot-language) @@ -815,7 +815,8 @@ instance to edit a toot." (defun mastodon-toot--view-toot-edits () "View editing history of the toot at point in a popup buffer." (interactive) - (let ((history (mastodon-tl--property 'edit-history))) + (let ((id (mastodon-tl--property 'base-toot-id)) + (history (mastodon-tl--property 'edit-history))) (with-current-buffer (get-buffer-create "*mastodon-toot-edits*") (let ((inhibit-read-only t)) (special-mode) @@ -836,7 +837,10 @@ instance to edit a toot." (format "Edits to toot by %s:" (alist-get 'username (alist-get 'account (car history)))) - 'face font-lock-comment-face)))))) + 'face font-lock-comment-face)) + (mastodon-tl--set-buffer-spec (buffer-name (current-buffer)) + (format "statuses/%s/history" id) + nil))))) (defun mastodon-toot--insert-toot-iter (it) "Insert iteration IT of toot." @@ -1539,15 +1543,17 @@ Added to `after-change-functions'." ;; NB: now that we have toot drafts, to ensure offline composing remains ;; possible, avoid any direct requests here: (defun mastodon-toot--compose-buffer (&optional reply-to-user - reply-to-id reply-json initial-text) + reply-to-id reply-json initial-text + edit) "Create a new buffer to capture text for a new toot. 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. REPLY-JSON is the full JSON of the toot being replied to. INITIAL-TEXT is used by `mastodon-toot-insert-draft-toot' to add a draft into the buffer." - (let* ((buffer-exists (get-buffer "*new toot*")) - (buffer (or buffer-exists (get-buffer-create "*new toot*"))) + (let* ((buffer-name (if edit "*edit toot*" "*new toot*")) + (buffer-exists (get-buffer buffer-name)) + (buffer (or buffer-exists (get-buffer-create buffer-name))) (inhibit-read-only t) (reply-text (alist-get 'content reply-json)) (previous-window-config (list (current-window-configuration) diff --git a/lisp/mastodon.el b/lisp/mastodon.el index cd7dd8e..1c3136c 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -203,7 +203,10 @@ Use. e.g. \"%c\" for your locale's date and time format." (define-key map (kbd "e") #'mastodon-toot--edit-toot-at-point) (define-key map (kbd "E") #'mastodon-toot--view-toot-edits) (when (require 'lingva nil :no-error) - (define-key map (kbd "s") #'mastodon-toot--translate-toot-text)) + (define-key map (kbd "a") #'mastodon-toot--translate-toot-text)) + (define-key map (kbd "s") #'mastodon-tl--view-scheduled-toots) + (define-key map (kbd "M-C-q") #'mastodon-kill-all-buffers) + (define-key map (kbd ";") #'mastodon-tl--view-instance-description) map) "Keymap for `mastodon-mode'.") @@ -345,6 +348,20 @@ not, just browse the URL in the normal fashion." (string-match "^/[[:alpha:]]+$" query) (string-match "^/u/[[:alpha:]]+$" query))))) +(defun mastodon-live-buffers () + "Return a list of open mastodon buffers. +Calls `mastodon-tl--get-buffer-type', which see." + (cl-loop for x in (buffer-list) + when (with-current-buffer x (mastodon-tl--get-buffer-type)) + collect (get-buffer x))) + +(defun mastodon-kill-all-buffers () + "Kill any and all open mastodon buffers, hopefully." + (interactive) + (let ((mastodon-buffers (mastodon-live-buffers))) + (cl-loop for x in mastodon-buffers + do (kill-buffer x)))) + ;;;###autoload (add-hook 'mastodon-mode-hook (lambda () (when (require 'emojify nil :noerror) |