<commit_before>;;; -*- lexical-binding: t; -*-
(require 'ar-vsetq)

(require 'ar-string)
(require 's)

(defun ar/open-youtube-url (url)
  "Download and open youtube URL."
  ;; Check for URLs like:
  ;; https://www.youtube.com/watch?v=rzQEIRRJ2T0
  ;; https://youtu.be/rzQEIRRJ2T0
  (setq url (s-trim url))
  (assert (string-match-p "^http[s]?://\\(www\\.\\)?\\(\\(youtube.com\\)\\|\\(youtu.be\\)\\|\\(soundcloud.com\\)\\|\\(redditmedia.com\\)\\)" url)
          nil "Not a downloadable URL: %s" url)
  (message "Downloading: %s" url)
  (async-start
   `(lambda ()
      (shell-command-to-string
       (format "youtube-dl --newline -o \"~/Downloads/%%(title)s.%%(ext)s\" %s" ,url)))
   `(lambda (output)
      (if (string-match-p "ERROR:" output)
          (message "%s" output)
        (message "Downloaded: %s" ,url)))))

(defun ar/open-youtube-clipboard-url ()
  "Open youtube video from url in clipboard."
  (interactive)
  (ar/open-youtube-url (current-kill 0)))

(defun ar/open-youtube-clipboard-from-page-url ()
  "Open youtube video from page url in clipboard."
  (interactive)
  (require 'ar-url)
  (require 'dash)
  (let ((youtube-urls (-union
                       ;; Look for iframe.
                       (-filter (lambda (iframe-url)
                                  (string-match "\\(youtube.com\\)\\|\\(youtu.be\\)\\|\\(redditmedia.com\\)" iframe-url))
                                (ar/url-fetch-iframe-srcs (current-kill 0)))
                       ;; Look for links.
                       (-map (lambda (anchor)
                               (let-alist anchor
                                 .url))
                             (-filter (lambda (anchor)
                                        (let-alist anchor
                                          (string-match "youtube" .url)))
                                      (ar/url-fetch-anchor-elements (current-kill 0)))))))
    (assert (> (length youtube-urls) 0) nil "No youtube links found")
    (if (= (length youtube-urls) 1)
        (ar/open-youtube-url (nth 0 youtube-urls))
      (ar/open-youtube-url (completing-read "choose:" youtube-urls)))))

(use-package elfeed :ensure t
  :commands elfeed
  :hook ((elfeed-search-mode . ar/elfeed-set-style))
  :bind (:map elfeed-search-mode-map
              ("R" . ar/elfeed-mark-all-as-read)
              ("d" . elfeed-search-untag-all-unread)
              ("v" . ar/elfeed-mark-visible-as-read)
              ("<tab>" . ar/elfeed-completing-filter))
  :init
  (defun ar/elfeed-set-style ()
    ;; Separate elfeed lines for readability.
    (ar/vsetq line-spacing 25))

  (defun ar/elfeed-mark-all-as-read ()
    "Mark all entries in search as read."
    (interactive)
    (mark-whole-buffer)
    (elfeed-search-untag-all-unread))

  (defun ar/elfeed-filter-results-count (search-filter)
    "Count results for SEARCH-FILTER."
    (let* ((filter (elfeed-search-parse-filter search-filter))
           (head (list nil))
           (tail head)
           (count 0))
      (let ((lexical-binding t)
            (func (byte-compile (elfeed-search-compile-filter filter))))
        (with-elfeed-db-visit (entry feed)
          (when (funcall func entry feed count)
            (setf (cdr tail) (list entry)
                  tail (cdr tail)
                  count (1+ count)))))
      count))

  (defun ar/elfeed-completing-filter ()
    "Completing filter."
    (interactive)
    (let ((categories (-filter
                       (lambda (item)
                         (> (ar/elfeed-filter-results-count (cdr item))
                            0))
                       '(("[All]" . "@6-months-ago +unread")
                         ("Art" . "@6-months-ago +unread +art")
                         ("BBC" . "@6-months-ago +unread +bbc")
                         ("Dev" . "@6-months-ago +unread +dev")
                         ("Emacs" . "@6-months-ago +unread +emacs")
                         ("Health" . "@6-months-ago +unread +health")
                         ("Hacker News" . "@6-months-ago +unread +hackernews")
                         ("iOS" . "@6-months-ago +unread +ios")
                         ("Money" . "@6-months-ago +unread +money")
                         ("Product Hunt" . "@6-months-ago +unread +ProductHunt")
                         ("Travel" . "@6-months-ago +unread +travel")))))
      (if (> (length categories) 0)
          (progn
            (ar/elfeed-view-filtered (cdr (assoc (completing-read "Categories: " categories)
                                                 categories)))
            (goto-char (window-start)))
        (message "All caught up \\o/"))))

  :config
  (defun ar/elfeed-mark-visible-as-read ()
    (interactive)
    (when (yes-or-no-p "Mark page as read?")
      (set-mark (window-start))
      (goto-char (window-end-visible))
      (activate-mark)
      (elfeed-search-untag-all-unread)
      (elfeed-search-update--force)
      (deactivate-mark)
      (goto-char (window-start))))

  ;; Going back to defaults for a little while.
  ;; (use-package elfeed-goodies :ensure t
  ;;   :after elfeed
  ;;   :config
  ;;   (ar/vsetq elfeed-goodies/entry-pane-position 'bottom)
  ;;   (ar/vsetq elfeed-goodies/feed-source-column-width 30)
  ;;   (ar/vsetq elfeed-goodies/tag-column-width 35)
  ;;   (elfeed-goodies/setup))

  (defun ar/elfeed-open-youtube-video ()
    (interactive)
    (let ((link (elfeed-entry-link elfeed-show-entry)))
      (when link
        (ar/open-youtube-url link))))

  (defun ar/elfeed-search-print-entry (entry)
    "My preferred format for displaying each elfeed search result ENTRY.
Based on `elfeed-search-print-entry--default'."
    (let* ((date (elfeed-search-format-date (elfeed-entry-date entry)))
           ;; Decode HTML entities (ie. &amp;)
           ;; (title (ar/string-decode-html-entities (or (elfeed-meta entry :title) (elfeed-entry-title entry) "")))
           (title (or (elfeed-meta entry :title) (elfeed-entry-title entry) ""))
           (title-faces (elfeed-search--faces (elfeed-entry-tags entry)))
           (feed (elfeed-entry-feed entry))
           (feed-title
            (when feed
              (or (elfeed-meta feed :title) (elfeed-feed-title feed))))
           (tags (mapcar #'symbol-name (elfeed-entry-tags entry)))
           (tags-str (mapconcat
                      (lambda (s) (propertize s 'face 'elfeed-search-tag-face))
                      tags ","))
           (title-width (- (window-width) 10 elfeed-search-trailing-width))
           (title-column (elfeed-format-column
                          title (elfeed-clamp
                                 elfeed-search-title-min-width
                                 title-width
                                 elfeed-search-title-max-width)
                          :left)))
      (insert (propertize date 'face 'elfeed-search-date-face) " ")
      (insert (propertize title-column 'face title-faces 'kbd-help title) " ")
      (when feed-title
        (insert (propertize feed-title 'face 'elfeed-search-feed-face) " "))
      (when tags
        (insert "(" tags-str ")"))))

  (ar/vsetq elfeed-search-print-entry-function #'ar/elfeed-search-print-entry)

  (ar/vsetq elfeed-feeds
            '(
              ("http://1w6.org/rss.xml" blog emacs draketo)
              ("http://200ok.ch/atom.xml" blog emacs 200ok)
              ("http://akkartik.name/feeds.xml" blog dev)
              ("http://amitp.blogspot.com/feeds/posts/default" blog emacs AmitPatel)
              ("http://beard.institute/index.xml" blog emacs BeardInstitute)
              ("http://ben-evans.com/benedictevans?format=RSS" blog dev Ben-Evans)
              ("http://blog.abhixec.com/index.xml" blog emacs RandomMusings)
              ("http://blog.davep.org/feed.xml" blog emacs davep)
              ("http://blog.josephholsten.com/feed.xml" blog hammerspoon dev Libera-Ideoj)
              ("http://blog.nawaz.org/feeds/all.atom.xml" blog dev )
              ("http://buddhistinspiration.blogspot.com/feeds/posts/default" blog mindful BuddistInspiration)
              ("http://cestlaz.github.io/rss.xml" blog emacs Zamansky)
              ("http://cmsj.net/feed.xml" blog hammerspoon dev Chris-Jones)
              ("http://dangrover.com/feed.xml" blog dangrover emacs )
              ("http://dividendlife.com/feed" blog money DividendLife)
              ("http://earlyretirementinuk.blogspot.com/feeds/posts/default" blog money EarlyRetirementUK)
              ("http://emacslife.blogspot.com/feeds/posts/default" blog emacs emacslife)
              ("http://emacslisp.com/?feed=rss2" blog emacs WUDI)
              ("http://emacsninja.com/atom.xml" blog emacs EmacsNinja)
              ("http://emacsredux.com/atom.xml" blog emacs emacs-redux)
              ("http://emacsworld.blogspot.com/feeds/posts/default?alt=rss" blog emacs EmacsWorld)
              ("http://evgeni.io/categories/posts/index.xml" blog emacs Evgeni)
              ("http://feeds.bbci.co.uk/news/uk/rss.xml?edition=uk" news BBCUK bbc)
              ("http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk" news BBCWorld bbc)<commit_msg>Adding feed<commit_after>;;; -*- lexical-binding: t; -*-
(require 'ar-vsetq)

(require 'ar-string)
(require 's)

(defun ar/open-youtube-url (url)
  "Download and open youtube URL."
  ;; Check for URLs like:
  ;; https://www.youtube.com/watch?v=rzQEIRRJ2T0
  ;; https://youtu.be/rzQEIRRJ2T0
  (setq url (s-trim url))
  (assert (string-match-p "^http[s]?://\\(www\\.\\)?\\(\\(youtube.com\\)\\|\\(youtu.be\\)\\|\\(soundcloud.com\\)\\|\\(redditmedia.com\\)\\)" url)
          nil "Not a downloadable URL: %s" url)
  (message "Downloading: %s" url)
  (async-start
   `(lambda ()
      (shell-command-to-string
       (format "youtube-dl --newline -o \"~/Downloads/%%(title)s.%%(ext)s\" %s" ,url)))
   `(lambda (output)
      (if (string-match-p "ERROR:" output)
          (message "%s" output)
        (message "Downloaded: %s" ,url)))))

(defun ar/open-youtube-clipboard-url ()
  "Open youtube video from url in clipboard."
  (interactive)
  (ar/open-youtube-url (current-kill 0)))

(defun ar/open-youtube-clipboard-from-page-url ()
  "Open youtube video from page url in clipboard."
  (interactive)
  (require 'ar-url)
  (require 'dash)
  (let ((youtube-urls (-union
                       ;; Look for iframe.
                       (-filter (lambda (iframe-url)
                                  (string-match "\\(youtube.com\\)\\|\\(youtu.be\\)\\|\\(redditmedia.com\\)" iframe-url))
                                (ar/url-fetch-iframe-srcs (current-kill 0)))
                       ;; Look for links.
                       (-map (lambda (anchor)
                               (let-alist anchor
                                 .url))
                             (-filter (lambda (anchor)
                                        (let-alist anchor
                                          (string-match "youtube" .url)))
                                      (ar/url-fetch-anchor-elements (current-kill 0)))))))
    (assert (> (length youtube-urls) 0) nil "No youtube links found")
    (if (= (length youtube-urls) 1)
        (ar/open-youtube-url (nth 0 youtube-urls))
      (ar/open-youtube-url (completing-read "choose:" youtube-urls)))))

(use-package elfeed :ensure t
  :commands elfeed
  :hook ((elfeed-search-mode . ar/elfeed-set-style))
  :bind (:map elfeed-search-mode-map
              ("R" . ar/elfeed-mark-all-as-read)
              ("d" . elfeed-search-untag-all-unread)
              ("v" . ar/elfeed-mark-visible-as-read)
              ("<tab>" . ar/elfeed-completing-filter))
  :init
  (defun ar/elfeed-set-style ()
    ;; Separate elfeed lines for readability.
    (ar/vsetq line-spacing 25))

  (defun ar/elfeed-mark-all-as-read ()
    "Mark all entries in search as read."
    (interactive)
    (mark-whole-buffer)
    (elfeed-search-untag-all-unread))

  (defun ar/elfeed-filter-results-count (search-filter)
    "Count results for SEARCH-FILTER."
    (let* ((filter (elfeed-search-parse-filter search-filter))
           (head (list nil))
           (tail head)
           (count 0))
      (let ((lexical-binding t)
            (func (byte-compile (elfeed-search-compile-filter filter))))
        (with-elfeed-db-visit (entry feed)
          (when (funcall func entry feed count)
            (setf (cdr tail) (list entry)
                  tail (cdr tail)
                  count (1+ count)))))
      count))

  (defun ar/elfeed-completing-filter ()
    "Completing filter."
    (interactive)
    (let ((categories (-filter
                       (lambda (item)
                         (> (ar/elfeed-filter-results-count (cdr item))
                            0))
                       '(("[All]" . "@6-months-ago +unread")
                         ("Art" . "@6-months-ago +unread +art")
                         ("BBC" . "@6-months-ago +unread +bbc")
                         ("Dev" . "@6-months-ago +unread +dev")
                         ("Emacs" . "@6-months-ago +unread +emacs")
                         ("Health" . "@6-months-ago +unread +health")
                         ("Hacker News" . "@6-months-ago +unread +hackernews")
                         ("iOS" . "@6-months-ago +unread +ios")
                         ("Money" . "@6-months-ago +unread +money")
                         ("Product Hunt" . "@6-months-ago +unread +ProductHunt")
                         ("Travel" . "@6-months-ago +unread +travel")))))
      (if (> (length categories) 0)
          (progn
            (ar/elfeed-view-filtered (cdr (assoc (completing-read "Categories: " categories)
                                                 categories)))
            (goto-char (window-start)))
        (message "All caught up \\o/"))))

  :config
  (defun ar/elfeed-mark-visible-as-read ()
    (interactive)
    (when (yes-or-no-p "Mark page as read?")
      (set-mark (window-start))
      (goto-char (window-end-visible))
      (activate-mark)
      (elfeed-search-untag-all-unread)
      (elfeed-search-update--force)
      (deactivate-mark)
      (goto-char (window-start))))

  ;; Going back to defaults for a little while.
  ;; (use-package elfeed-goodies :ensure t
  ;;   :after elfeed
  ;;   :config
  ;;   (ar/vsetq elfeed-goodies/entry-pane-position 'bottom)
  ;;   (ar/vsetq elfeed-goodies/feed-source-column-width 30)
  ;;   (ar/vsetq elfeed-goodies/tag-column-width 35)
  ;;   (elfeed-goodies/setup))

  (defun ar/elfeed-open-youtube-video ()
    (interactive)
    (let ((link (elfeed-entry-link elfeed-show-entry)))
      (when link
        (ar/open-youtube-url link))))

  (defun ar/elfeed-search-print-entry (entry)
    "My preferred format for displaying each elfeed search result ENTRY.
Based on `elfeed-search-print-entry--default'."
    (let* ((date (elfeed-search-format-date (elfeed-entry-date entry)))
           ;; Decode HTML entities (ie. &amp;)
           ;; (title (ar/string-decode-html-entities (or (elfeed-meta entry :title) (elfeed-entry-title entry) "")))
           (title (or (elfeed-meta entry :title) (elfeed-entry-title entry) ""))
           (title-faces (elfeed-search--faces (elfeed-entry-tags entry)))
           (feed (elfeed-entry-feed entry))
           (feed-title
            (when feed
              (or (elfeed-meta feed :title) (elfeed-feed-title feed))))
           (tags (mapcar #'symbol-name (elfeed-entry-tags entry)))
           (tags-str (mapconcat
                      (lambda (s) (propertize s 'face 'elfeed-search-tag-face))
                      tags ","))
           (title-width (- (window-width) 10 elfeed-search-trailing-width))
           (title-column (elfeed-format-column
                          title (elfeed-clamp
                                 elfeed-search-title-min-width
                                 title-width
                                 elfeed-search-title-max-width)
                          :left)))
      (insert (propertize date 'face 'elfeed-search-date-face) " ")
      (insert (propertize title-column 'face title-faces 'kbd-help title) " ")
      (when feed-title
        (insert (propertize feed-title 'face 'elfeed-search-feed-face) " "))
      (when tags
        (insert "(" tags-str ")"))))

  (ar/vsetq elfeed-search-print-entry-function #'ar/elfeed-search-print-entry)

  (ar/vsetq elfeed-feeds
            '(
              ("http://1w6.org/rss.xml" blog emacs draketo)
              ("https://blog.davep.dev/rss.xml" blog emacs davepdev)
              ("http://200ok.ch/atom.xml" blog emacs 200ok)
              ("http://akkartik.name/feeds.xml" blog dev)
              ("http://amitp.blogspot.com/feeds/posts/default" blog emacs AmitPatel)
              ("http://beard.institute/index.xml" blog emacs BeardInstitute)
              ("http://ben-evans.com/benedictevans?format=RSS" blog dev Ben-Evans)
              ("http://blog.abhixec.com/index.xml" blog emacs RandomMusings)
              ("http://blog.davep.org/feed.xml" blog emacs davep)
              ("http://blog.josephholsten.com/feed.xml" blog hammerspoon dev Libera-Ideoj)
              ("http://blog.nawaz.org/feeds/all.atom.xml" blog dev )
              ("http://buddhistinspiration.blogspot.com/feeds/posts/default" blog mindful BuddistInspiration)
              ("http://cestlaz.github.io/rss.xml" blog emacs Zamansky)
              ("http://cmsj.net/feed.xml" blog hammerspoon dev Chris-Jones)
              ("http://dangrover.com/feed.xml" blog dangrover emacs )
              ("http://dividendlife.com/feed" blog money DividendLife)
              ("http://earlyretirementinuk.blogspot.com/feeds/posts/default" blog money EarlyRetirementUK)
              ("http://emacslife.blogspot.com/feeds/posts/default" blog emacs emacslife)
              ("http://emacslisp.com/?feed=rss2" blog emacs WUDI)
              ("http://emacsninja.com/atom.xml" blog emacs EmacsNinja)
              ("http://emacsredux.com/atom.xml" blog emacs emacs-redux)
              ("http://emacsworld.blogspot.com/feeds/posts/default?alt=rss" blog emacs EmacsWorld)
              ("http://evgeni.io/categories/posts/index.xml" blog emacs Evgeni)
              ("http://feeds.bbci.co.uk/news/uk/rss.xml?edition=uk" news BBCUK bbc)
              ("http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk" news BBCWorld bbc)
{'fraction_non_alphanumeric': 0.1567478784560635, 'fraction_numerical': 0.004598959759102108, 'mean_word_length': 1.8266790467347571, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 5, 'lorem ipsum': 0, 'www.': 4, 'xml': 33}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '635509', 'n_tokens_mistral': 6039, 'n_tokens_neox': 5756, 'n_words': 1162}