;;; (load! "nimcoon")
;;; Non-interactive functions to respond to URL clicks
-(defun nimcoon-play-url (url)
- "Play given url in NimCoon"
+(defun nimcoon-play-url (url &rest args)
+ "Play given URL in NimCoon."
(start-process "nimcoon" nil "nimcoon" url))
;; Play all YouTube URLs in NimCoon
(("youtu\\.?be" . nimcoon-play-url)
("." . browse-url-default-browser))))
+(defun run-nimcoon(args query)
+ "Search by QUERY and play in NimCoon."
+ (call-process "nimcoon" nil 0 nil args query))
+
;;; Interactive functions
(defun nimcoon-feeling-lucky-music(query)
(interactive "sSearch query: ")
- (call-process "nimcoon" nil 0 nil "-m" "-l" (format "'%s'" query)))
+ (run-nimcoon "-ml" query))
(defun nimcoon-feeling-lucky-video(query)
(interactive "sSearch query: ")
- (call-process "nimcoon" nil 0 nil "-l" (format "'%s'" query)))
+ (run-nimcoon "-l" query))
(defun nimcoon-download-video(query)
(interactive "sSearch query: ")
- (call-process "nimcoon" nil 0 nil "-d" "-l" (format "'%s'" query)))
+ (run-nimcoon "-dl" query))
(defun nimcoon-download-music(query)
(interactive "sSearch query: ")
- (call-process "nimcoon" nil 0 nil "-d" "-l" "-m" (format "'%s'" query)))
+ (run-nimcoon "-dlm" query))
+
+;; Assumes only one process exists. Must capture the pid of the running NimCoon process and only kill it.
+(defun nimcoon-kill-background-processes()
+ "Kill NimCoon process running in the background. Useful for stopping background music."
+ (interactive)
+ (shell-command "kill `pgrep nimcoon` `pgrep mpv` `pgrep vlc`"))
+
+(defun nimcoon-search-video(query)
+ "Search for a video by QUERY."
+ (interactive "sSearch query: ")
+ (with-output-to-temp-buffer "*NimCoon search results*"
+ (call-process "nimcoon" nil "*NimCoon search results*" t "--non-interactive" query)
+ (with-current-buffer "*NimCoon search results*"
+ (org-mode))))
+
+(defun nimcoon-search-music(query)
+ "Search for a video by QUERY."
+ (interactive "sSearch query: ")
+ (with-output-to-temp-buffer "*NimCoon search results*"
+ (call-process "nimcoon" nil "*NimCoon search results*" t "--music" "--non-interactive" query)
+ (with-current-buffer "*NimCoon search results*"
+ (org-mode))))
;;; Keybindings
(map! :leader
(:prefix ("d" . "Download")
:desc "Video" "v" #'nimcoon-download-video
:desc "Music" "m" #'nimcoon-download-music)
+ (:prefix ("s" . "Search")
+ :desc "Video" "v" #'nimcoon-search-video
+ :desc "Music" "m" #'nimcoon-search-music)
+ :desc "Kill" "k" #'nimcoon-kill-process
:desc "Video" "v" #'nimcoon-feeling-lucky-video
:desc "Music" "m" #'nimcoon-feeling-lucky-music))
for index, (title, url) in searchResults:
styledEcho $index, ". ", styleBright, fgMagenta, title, "\n", resetStyle, fgCyan, " ", url, "\n"
-
func buildPlayerArgs(url: string, options: Table[string, bool], player: string): seq[string] =
let musicOnly = if options["musicOnly"]: "--no-video" else: ""
let fullScreen = if options["fullScreen"]: "--fullscreen" else: ""
if "--no-video" in args:
discard execShellCmd(&"{player} {args.join(\" \")}")
else:
- discard execProcess(player, args=args, options=processOptions)
+ discard startProcess(player, args=args, options=processOptions)
func buildMusicDownloadArgs(url: string): seq[string] =
proc parseArguments(): CommandLineOptions =
var
searchQuery = ""
- options = to_table({"musicOnly": false, "feelingLucky": false, "fullScreen": false, "download": false})
+ options = to_table({"musicOnly": false, "feelingLucky": false, "fullScreen": false, "download": false, "non-interactive": false})
for kind, key, value in getopt():
case kind
of "l", "lucky": options["feelingLucky"] = true
of "f", "full-screen": options["fullScreen"] = true
of "d", "download": options["download"] = true
+ of "n", "non-interactive": options["non-interactive"] = true
of cmdEnd: discard
+ if searchQuery == "":
+ stderr.writeLine "NimCoon doesn't permit browsing. You must provide a search query."
+ quit(1)
+
(searchQuery, options)
-proc isValidOptions*(options: Options): bool =
+proc isValidOptions(options: Options): bool =
# Check for invalid combinations of options
var invalidCombinations = [("musicOnly", "fullScreen"), ("download", "fullScreen")]
result = true
quit(0)
let searchResults = getSearchResults(searchQuery)
+ if options["non-interactive"]:
+ for index, (title, url) in searchResults:
+ echo title
+ echo url
+ echo ""
+ quit(0)
+
let numResults = min(limit, len(searchResults))
present(searchResults, options, (0, numResults-1), player)