▌ Astronvim + Rvnimr + ranger + mpv 설정
※ 준비물 : Astronvim, Rnvimr(nvim plugin), ranger, mpv
※ 목적 : 파일을 빠르게 검색/조작하고, 설정 파일들을 빠르게 편집힌다. 마우스를 사용하지 않는다.
※ 1. Rnvimr + mpv 이용 ranger image 미리보기: (소리 주의)
🔎 설치
$ sudo pacman -S ranger, mpv $ yay -S astronvim python-pynvim ueberzugpp Rnvinr Git: https://github.com/kevinhwang91/rnvimr
😀 ~/.config/ranger/rc.conf
set preview_images true set preview_images_method mpv set preview_script ~/.config/ranger/scope.sh set use_preview_script true
😀 ~/.config/ranger/commands.py
## Image preivew With mpv
# The mpv image preview method allows ranger to control an external client for viewing media. The benefit of this approach is that both images and videos share a single, separate window.
import subprocess
import json
import atexit
import socket
from pathlib import Path
import logging
logger = logging.getLogger(__name__)
import traceback
from ranger.ext.img_display import ImageDisplayer, register_image_displayer
@register_image_displayer("mpv")
class MPVImageDisplayer(ImageDisplayer):
"""Implementation of ImageDisplayer using mpv, a general media viewer.
Opens media in a separate X window.
mpv 0.25+ needs to be installed for this to work.
"""
def _send_command(self, path, sock):
message = '{"command": ["raw","loadfile",%s]}\n' % json.dumps(path)
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(str(sock))
logger.info('-> ' + message)
s.send(message.encode())
message = s.recv(1024).decode()
logger.info('<- ' + message)
def _launch_mpv(self, path, sock):
proc = subprocess.Popen([
* os.environ.get("MPV", "mpv").split(),
"--no-config",
"--no-terminal",
"--force-window",
"--input-ipc-server=" + str(sock),
"--image-display-duration=inf",
"--loop-file=inf",
"--no-osc",
"--no-input-default-bindings",
"--keep-open",
"--idle",
"--ontop",
"--x11-name=mpsyt",
"--geometry=854x480+1067+0",
"--",
path,
])
@atexit.register
def cleanup():
proc.terminate()
sock.unlink()
def draw(self, path, start_x, start_y, width, height):
path = os.path.abspath(path)
cache = Path(os.environ.get("XDG_CACHE_HOME", "~/.cache")).expanduser()
cache = cache / "ranger"
cache.mkdir(exist_ok=True)
sock = cache / "mpv.sock"
try:
self._send_command(path, sock)
except (ConnectionRefusedError, FileNotFoundError):
logger.info('LAUNCHING ' + path)
self._launch_mpv(path, sock)
except Exception as e:
logger.exception(traceback.format_exc())
sys.exit(1)
logger.info('SUCCESS')
"--x11-name=mpsyt" : ranger 에서 띠우는 mvp 윈도우 창을 $ xprop 로 체크하면 class name, resource name 은 mpv, mpsyt가 된다.
wm에서 mpsyt class/resoruce 네임을 가지는 윈도우 창은 무시하도록 설정 한다.
ex) xmonad wm 인경우
😀 ~/.xmonad/xmonad.hs
, [ className =? "mpv" <&&> resource =? "mpsyt" --> doF W.focusDown ] -- 또는 "doIgnore"
"--geometry=854x480+1067+0" : 우측 상단 코너로 지정하였다. ( mpv의 --geometry 옵션 대신, wm 설정에 따로 설정해도 된다.)
ex) xmonad wm 인경우
😀 ~/.xmonad/xmonad.hs
myScratchPads :: [NamedScratchpad]
myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm -- one scratchpad
, NS "mixer" spawnMixer findMixer manageMixer -- and a second
, NS "video" spawnVideo findVideo manageVideo -- and a third
, NS "player" spawnPlayer findPlayer managePlayer -- and a 4th
, NS "mpd" spawnMpd findMpd manageMpd -- and a 5th
]
where
role = stringProperty "WM_WINDOW_ROLE"
spawnTerm = myTerminal ++ " -b 15 -name scratchpad -fn 'xft:Iosevka Nerd Font Mono:style=Regular:pixelsize=22,xft:NanumGothicCoding:pixelsize=22'" ++ " -fb 'xft:Iosevka Nerd Font Mono:style=Bold:pixelsize=22,xft:NanumGothicCoding:Bold:pixelsize=24'" -- launch my scratchpad terminal
findTerm = resource =? "scratchpad" -- its window will be named "scratchpad" (see above)
manageTerm = customFloating $ W.RationalRect l t w h -- and I'd like it* using the geometry below
where
-- reusing these variables is ok since they're confined to their own
-- where clauses
h = 0.75 --0.65 -- height, 65%
w = 0.75 --0.68 -- width, 68%
t = (1 - h)/2 -- centered top/bottom
l = (1 - w)/2 -- centered left/right
spawnMixer = "urxvt -name pulsemixer -e pulsemixer" -- launch my pulsemixer
findMixer = resource =? "pulsemixer" <||> title =? "pulsemixer" -- its window has a ClassName of "mixer"
manageMixer = customFloating $ W.RationalRect l t w h -- and I'd like it* using the geometry below:
where
h = 0.6 -- height, 60%
w = 0.6 -- width, 60%
t = (1 - h)/2 -- centered top/bottom
l = (1 - w)/2 -- centered left/right
-- mpsyt : "set playerargs --x11-name mpsyt"
spawnVideo = "mpv --x11-name mpsyt --ytdl-format best --no-resume-playback $(xclip -o)" -- launch mpv for youtube (resolusin 1280x720)
findVideo = resource =? "mpsyt" <&&> className =? "mpv" -- its window will be named "video" (see above)
manageVideo = ((customFloating $ W.RationalRect l t w h) <+> doF W.focusDown) -- and I'd like it* using the geometry below, then focus down, mpv no focus
where
-- reusing these variables is ok since they're confined to their own
-- where clauses
h = 0.29 --0.24 -- height, 24%
w = 0.29 --0.24 -- width, 24%
t = (1 - h) - (myBottomPanelHeight / myYResolution) -- bottom right edge: bottom xmobar height=16, y resoulution=1080
l = 1 - w -- right, left/right
spawnPlayer = "mpv --x11-name livetv --profile tv --no-resume-playback --playlist-pos 19 channels.m3u" -- launch mpv for livetv mpv
findPlayer = resource =? "livetv" <&&> className =? "mpv" -- its window will be named "player" (see above)
managePlayer = customFloating $ W.RationalRect l t w h -- and I'd like it* using the geometry below
where
-- reusing these variables is ok since they're confined to their own
-- where clauses
h = 0.29 --0.24 -- height, 24%
w = 0.29 --0.24 -- width, 24%
--t = 0 + (myTopPanelHeight / myYResolution) -- top right edge: top xmobar height=16, y resoulution=1080
--l = 1 - w -- right, left/right
t = (1 - h) - (myBottomPanelHeight / myYResolution) -- bottom right edge: bottom xmobar height=16, y resoulution=1080
l = 1 - w -- right, left/right
ranger에서 띠운 mpv 이미지 프리뷰는 ranger에서 이미지 파일인 아닌 곳으로 ranger 커서(포커스)가 이동 해도, 사라지지 않는다.
따라서, ranger 에서 띠운 mpv 윈도우 창 삭제 커맨드를 만들어서 keybinding 해 주었다
$ sudo pacmsn -S xbindkeys
😀 ~/.xbindkeysrc
"kill $(ps -ef | grep "x11-name=mpsyt" | head -n1 | awk '{printf $2}')"
shift+BackSpace
"Shift" + "BackSpace" 키룰 누르면 mpv 이미지를 종료한다.
위 xbindkeys 키바인딩 대신, wm 설정 파일에서 지정 하여도 된다.
※ (번외 1) 마법의 커맨드 : "야동": (소리 주의)
😀.zshrc:
야동 () { mpv $(tbitsearch $(dmenu -p "🔎 Search Jav Torrent 😀 Watch: " -fn "hack" -sb "#783e57" -nb "#312e37" <&-) -s seeders -j | jq '.[] | .magnet' | head -n1 | sed -e 's/"//g') --terminal=no >/dev/null }
mmm () { mpv --ytdl-format="(bestvideo[height<=?1080][fps<=?60][vcodec=av01.0.09M.08]/bestvideo[height<=?1080][fps<=?30][vcodec=av01.0.08M.08]/bestvideo[height<=?1080][fps<=?60][ext=mp4])+(bestaudio[acodec=opus]/bestaudio[acodec=vorbis]/bestaudio[acodec=aac]/bestaudio/bestaudio[ext=webm])/bestvideo+bestaudio/best[ext=mp4]/best" ytdl://ytsearch:"$@" }
1. 야동() 커맨드 실행시 필요한 프로그램:
$ sudo pacman -S dmenu npm mpv jq $ yay -S tbitsearch-git webtorrent-cli $ sudo npm install --global webtorrent-mpv-hook $ webtorrent-mpv-hook $ ln -s "/usr/lib/node_modules/webtorrent-mpv-hook/build/webtorrent.js" "/home/[유저명]/.config/mpv/scripts/webtorrent.js"
2. mmm() 커맨드 실행시 필요한 프로그램:
$ sudo pacman -S mpv yt-dlp (또는) $ yay -S mpv-git (또는) $ yay -S mpv-vapoursynth
* tbitsearch 프로그램은 bitsearch 사이트 검색기능을 가져온다.
영화, 드라마, 모든 토렌트 파일들을 query를 통해 magnet을 추출할 수 있지만, 야동 검색에 적합한것 같다. "품번" query를 넣어주면 정확한 야동 품번 마그넷을 추출해준다.
* mmm 은 youtube 검색을 지원하는 내장 mpv search 기능과 선호하는 youtube 코덱/해상도/FPS 등등의 설정을 지정하는 커맨드이다.
🔎 A. 영화 검색 : rofi > "jtm ssis-875 9"

😀 B. 영화 감상 : rofi > "jp juq-363" : 로컬 하드의 한글자막 + 토렝이 스트리밍 + 메타정보 (mpv는 토랭이영상 이전 보던 시점에서 이어보기 지원)
* 사용프로그램 : 다이나믹 윈도우 매니저(wm) + mpv + dunst
* 언제나 그렇듯, 로컬 하드에는 한글 자막과 한글 포스터만 모읍니다.

😀 B. 영화 감상 : 1배속 (소리주의) : 구드 1080p : 영상이 잘 안나오면.. 옆페 imgur 480p 영상으로 > Imgur 480p
😀 C. 총평 - 영화 한줄 요약 : "생겼다구요~ 동생이요!"
😀 (번외 2) : 제가 생각하는 최상의 레이아웃 세팅
* 워크스페이스(=윈도우에서 말하는 가상 데스크탑 (?)) : 9 개 설정
* 3:1 의 비율로 화면을 분할하는(물리 스크린을 가상 스크린으로 분할하는) 단축키와 화면분활 복원하는 단축키 설정
- 좌측 스크린(75%)은 작업 전용, 우측 스크린은(25%)은 미디어 전용
| 촤측 스크린 에는 6번 워크스페이스를 사용 : A. 주는 "BSP(Binary Space Partitioning) Layout, B. 부는 "PostionRestoreFloat Layout" 2개를 설정 사용 . C. fullscreen 토글 단축키
보통 "윈도우 + f" 를 fullscreen 토글 키롤 많이들 할당 합니다.(화면의 커서가 있는 웹브라우저에서 단축키를 누르면 4:3 비율로 가득찬 풀 스크린 웹서핑 모드로 전환
| 우측 스크린 에는 5번 워크스페이스를 사용 : Media 전용 워크스페이스로 사용합니다.
5번 워크스페이스는 세로로(위에서 부터 아래로) 75% 의 영역을 Vertical Tiled Layout 으로 지정,, 세로로 하단 25% 의 영역은 mpv 영상(주로 TV 와 유투브) 을 float 띠우기 위한 고정된 영역으로 미리 비워둡니다. 여기서 띠울 mpv는 titled stack에 포함되어 있지 않고, float stack 속해 잇기때문에.. mpv의 풀스크린 토글 단축키 "f" 키를 누르면... 우측 가상 스크린의 세로로 가득찬 풀 스크린 화면이 아닌,, 물리 모니터를 가득 채우는 1920x1080 해상도로 화면이 가득차게 됩니다.
* 작업 워크페이스와 미디어 워크스페이스를 분리 해 놓았기 때문에.. 작업하다가 "왼도우 + j" , "윈도우 + k" 키롤 창 이동을 해도. 미디어 쪽으로 포커스가 절대 가지 않습니다.
(오래전에 온갖 윈도우 매너저들 다 한번씩 잠깐 사용해 보고 "Layout 기반 최강의 윈도우 매니저" 란 이유로, xmonad 로 정작하였습니다. A. 단축키 기반 wm, B. Layout 기반 wm 을 사용하고자 하시는 분은 xmonad 를 강력히 추천합니다. )
* 이 세팅값을 거의 10년 동안 동일하게 사용해 오고 있습니다. 오래전에 1. urxvt 터미널 색상 테마, 2. tmux 색상 테마 3. vim 색상 테마, 4. gtk 앱 색생 테마 등등을 통일해 놓았는데, nvim으로 넘어 왓다니 색상 테마가 달라졋네요. Astronvim 색상 테마 값을 변경하는 방법을 모르겠습니다 ㅠ.ㅠ
🔎 사용한 App :
qutebrowser | ranger | w3m(=w3mimgdisplay) , python-ueberzug-git(or ueberzugpp) | mpv | yt-dlp | urxvt | tmux | tty-clock | pfetch | fzf | ripgrep | mpd | mpc | fmpc | ncmpcpp | feh , sxiv | ffmpeg | cava | playerctl | tbitsearch-git | webtorrent-cli | jq | dmenu , rofi | dunst | picom | vim | trayer | python | vapoursynth | lua | npm | postgresql | xmobar | xmonad | xmonad-contrib | ... | gtk app | qt app | ... etc
- 마법의 namedScratchPads 토글키 : "win + F9" 키 : 해당 단축키를 누르면 5번 워크스페이스에 하단 해당 영역에 mpv tv채널을 띠워주고, 이후 누를때마다 mpv 창이 visible/unvisible 해줍니다.
- 아래는 mpv 창 하나에 namedScratchPads(NSP)을 설정하고 단축키를 설정하는 xmonad 초간략 설정값입니다. compile 하고 실행하면 돌아갑니다.
"mod + F9" 키: "alt + F9" 키를 누르면... 유투브 3분휴지 최신영상을 띠워즈고. 금일 날짜 기준 310개의 영상의 Playlist를 생성해줍니다. (mpv는 유투브 연령제한으로 자동으로 통과합니다)
😀 ~/.xmonad.hs
import XMonad import qualified XMonad.StackSet as W --https://hackage.haskell.org/package/xmonad-0.15/docs/XMonad-StackSet.html#t:RationalRect import qualified Data.Map as M import XMonad.Util.NamedScratchpad --http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-NamedScratchpad.html import XMonad.ManageHook --https://hackage.haskell.org/package/xmonad-0.15/docs/XMonad-ManageHook.html import XMonad.Hooks.ManageHelpers -- Named ScratchPads myScratchPads :: [NamedScratchpad] myScratchPads = [ NS "livetv" spawnLivetv findLivetv manageLivetv -- and a 4th ] where role = stringProperty "WM_WINDOW_ROLE" --- (중략) --- spawnPlayer = "mpv --x11-name=livetv --no-resume-playback https://www.youtube.com/@3mtissue" -- launch mpv for Youtube 3분휴지 --spawnLivetv = "mpv --x11-name=livetv --profile=tv --playlist-start=8 --no-resume-playback TVChannels/my_tvheadend.m3u" -- launch mpv for livetv mpv findLivetv = resource =? "livetv" <&&> className =? "mpv" -- its window will be named "livetv" (see above) manageLivetv = customFloating $ W.RationalRect l t w h -- and I'd like it* using the geometry below where -- reusing these variables is ok since they're confined to their own -- where clauses h = 0.24 -- height, 24% w = 1 -- width, 100% t = (1 - h) - (16 / 1080) -- bottom right edge: bottom xmobar height=16, y resoulution=1080 l = 1 - w -- right, left/right ----------------------------------------------------------------------------}}} -- Key Binding {{{ ------------------------------------------------------------------------------- -- FOR MULTIMEDIA KEYS RUN: -- xev | grep -A2 --line-buffered '^KeyRelease' | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p' -- Then look in /usr/include/X11/XF86keysym.h and look for the name and code. -- -- Graphics.X11 keysym definitions: https://wiki.haskell.org/Xmonad/Key_codes -- /usr/include/X11/keysymdef.h -- Define keys to add keysToAdd x = [ -- rofi lanucher (modMask x, xK_p), spawn "rofi -show drun -show-icons") -- Close focused window ,((modMask x, xK_c), kill) -- Named Scratchpad key -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-NamedScratchpad.html ((modMask x, xK_F12), scratchTerm ) , ((modMask x, xK_F9 ), scratchLivetv ) ] where -- this simply means "find the scratchpad in myScratchPads that is -- named terminal and launch it" scratchTerm = namedScratchpadAction myScratchPads "terminal" scratchLivetv = namedScratchpadAction myScratchPads "livetv" -- Define keys to remove keysToRemove x = [ -- Unused dmenu binding (modMask x, xK_p) -- Unused gmrun binding , (modMask x .|. shiftMask, xK_p) -- Unused close window binding , (modMask x .|. shiftMask, xK_c) -- Unused xmonad recompile, restart logout binding , (modMask x, xK_q) , (modMask x .|. shiftMask, xK_q) ] -- Delete the keys combinations we want to remove strippedKeys x = foldr M.delete (keys def x) (keysToRemove x) -- Compose all my new key combinations. myKeys x = M.union (strippedKeys x) (M.fromList (keysToAdd x )) -- Define the workspace on application has to go to myManageHook :: ManageHook myManageHook = (composeAll . concat $ [ --[ className =? "mpv" --> doCenterFloat ] --doFloat [ className =? "mpv" <&&> resource =? "livetv" --> doSideFloat(SE) ] --, [ className =? "mpv" <&&> resource =? "livetv" --> doF (W.shift (myWorkspaces !! 4)) ] ]) <+> namedScratchpadManageHook myScratchPads <+> manageHook def -- Main main = do xmonad $ def { keys = myKeys , manageHook = myManageHook }
😀 XMonad WM : 극강의 미니멀. 간결하다. 공간의 낭비가 없다. 확장 라이브러리. 빠르다. 빠르다. 빠르다
기존에 vim을 오랫동안 사용 해 왓었는데. 리눅서당 게시글을 읽고 저도 astronvim 으로 넘어 왓씁니다.
astronvim 기본 설정을 그대로 사용하엿구요. Rnvimr(ranger nvim 플러그인) 만 별도 설치 하였습니다.
tmux -> nvim -> Rnvimr -> ranger 이미지 프리뷰에서 : w3m 이미지 프리뷰가 작동 하지 않습니다. ueberzug 이미지 프리뷰는 "레이아웃 포지션이" 엉뚱한 위치에 뜹니다.
그래서, ranger 이미지 프리뷰는 "mpv" 로 우측 상단 코너에 고정 하였습니다. (윈도우 매니저(wm)에서 nvim->ranger에서 띠우는 mpv는 "ignore (포커스 무시)" "focus down (포커스 자동 이전 단계로 이동) 설정" 이 필요 합니다.
** 환경
| OS : Arch
| wm : xmonad
| terminal : urxvt
| tmux
| astronvim + (Rnvimr Plugin) : astronvim 기본 내장 터미널 플러그인 (ToggleTerml : F7 키)
| ranger
| mpv
| (etc)
** 사용
| xmonad wm : NamedScratchpad 터미널 한개: "mod3" + "F12" 키 할당
제 사용 용도에선, 터미널 윈도우창 하나면, 충분 한 것 같습니다. 윈도우 창 한개로 빠르게 다 되어서 좋아요.
"Mod3" + "F12" 키 (=Scratchpad 메인 tmux 토글 터미널) --> astronvim -> Rnvimr -> ranger -> mpv, feh, 등등등 ...
오랫만에 데스크탑 설정/세팅 했는데 시간이 참 잘가네요.
감사합니다. 누군가에게는 도움이 되시길....



노래와 유투브를 편하게 시청하기 위한(???) 환경 구축인거 같습니다.
저번엔 너무 건전한거 같아서 다시 콤백해어유. "천녀유혼"은 최고의 중국 영화입니다. 왕조현 뿌잉 ^^
Astronvim 게시글 올려 주셔서. 덕분에 갈아탈 수 있었습니다. 감사합니다. !!
으아아아니 이것은??? 서극 감독의...
천...
아 아니지.. 이거 무슨 영화인가요? ㅋㅋㅋ 어려서 잘모르겠어요 ㅋㅋㅋㅋㅋ
여배우가 정말 역대급으로 아름답네요..
제가 궁금했던 정말 귀중하고 소중한 내용을 이렇게 친절하게 정성스럽게 올려주시다니!!!
성은이 망극하옵니다
그녀와의 미팅은 성공하셨나요? 도움이 되었다니 망극하옵니다.
저동네 넘버원 신작영화라 구런가.. 시드가 너무 빵빵한듯 하옵니다.
자동화가 멋집니다.