mirror of
https://github.com/alexpasmantier/television.git
synced 2025-07-29 14:21:43 +00:00
1 line
11 KiB
JavaScript
1 line
11 KiB
JavaScript
"use strict";(self.webpackChunktelevision_website=self.webpackChunktelevision_website||[]).push([[1885],{8366:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>h,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"Users/shell-integration","title":"Shell Integration","description":"Television can integrate with your shell to provide smart autocompletion based on the commands you start typing.","source":"@site/../docs/01-Users/05-shell-integration.md","sourceDirName":"01-Users","slug":"/Users/shell-integration","permalink":"/television/docs/Users/shell-integration","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":5,"frontMatter":{},"sidebar":"docSidebar","previous":{"title":"Keybindings","permalink":"/television/docs/Users/keybindings"},"next":{"title":"Search Patterns","permalink":"/television/docs/Users/search-patterns"}}');var t=i(3420),l=i(5404);const r={},h="Shell Integration",o={},a=[{value:"Keybindings",id:"keybindings",level:2},{value:"Enabling shell integration",id:"enabling-shell-integration",level:2},{value:"Zsh",id:"zsh",level:3},{value:"Bash",id:"bash",level:3},{value:"Fish",id:"fish",level:3},{value:"Nushell",id:"nushell",level:3},{value:"Configuring autocompletion",id:"configuring-autocompletion",level:2},{value:"Customizing shell integration scripts",id:"customizing-shell-integration-scripts",level:2},{value:"Setting up the files",id:"setting-up-the-files",level:3},{value:"Zsh",id:"zsh-1",level:4},{value:"Bash",id:"bash-1",level:4},{value:"Fish",id:"fish-1",level:4},{value:"Recipes",id:"recipes",level:3},{value:"Automatically executing selection",id:"automatically-executing-selection",level:4},{value:"Open history channel with the most up to date version of the history file",id:"open-history-channel-with-the-most-up-to-date-version-of-the-history-file",level:4}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"shell-integration",children:"Shell Integration"})}),"\n",(0,t.jsx)(n.p,{children:"Television can integrate with your shell to provide smart autocompletion based on the commands you start typing."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:"https://github.com/user-attachments/assets/6292db26-8fcf-4874-ac9d-c9baedc70ff1",alt:"tv-shell-integration"})}),"\n",(0,t.jsx)(n.h2,{id:"keybindings",children:"Keybindings"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)("kbd",{children:"Ctrl"}),"-",(0,t.jsx)("kbd",{children:"R"}),": shell history"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)("kbd",{children:"Ctrl"}),"-",(0,t.jsx)("kbd",{children:"T"}),": smart autocompletion for the current prompt command"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"enabling-shell-integration",children:"Enabling shell integration"}),"\n",(0,t.jsx)(n.h3,{id:"zsh",children:"Zsh"}),"\n",(0,t.jsx)(n.p,{children:"To enable shell integration for zsh, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"echo 'eval \"$(tv init zsh)\"' >> ~/.zshrc\n"})}),"\n",(0,t.jsx)(n.p,{children:"And then restart your shell or run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source ~/.zshrc\n"})}),"\n",(0,t.jsx)(n.h3,{id:"bash",children:"Bash"}),"\n",(0,t.jsx)(n.p,{children:"To enable shell integration for bash, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"echo 'eval \"$(tv init bash)\"' >> ~/.bashrc\n"})}),"\n",(0,t.jsx)(n.p,{children:"And then restart your shell or run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source ~/.bashrc\n"})}),"\n",(0,t.jsx)(n.h3,{id:"fish",children:"Fish"}),"\n",(0,t.jsx)(n.p,{children:"To enable shell integration for fish, add:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"tv init fish | source\n"})}),"\n",(0,t.jsxs)(n.p,{children:["to your ",(0,t.jsx)(n.code,{children:"is-interactive"})," block in your ",(0,t.jsx)(n.code,{children:"~/.config/fish/config.fish"})," file and then restart your shell."]}),"\n",(0,t.jsx)(n.h3,{id:"nushell",children:"Nushell"}),"\n",(0,t.jsxs)(n.p,{children:["To enable shell integration for nu, add this to your ",(0,t.jsx)(n.code,{children:"~/.config/nushell/config.nu"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-nu",children:'mkdir ($nu.data-dir | path join "vendor/autoload")\ntv init nu | save -f ($nu.data-dir | path join "vendor/autoload/tv.nu")\n'})}),"\n",(0,t.jsx)(n.h2,{id:"configuring-autocompletion",children:"Configuring autocompletion"}),"\n",(0,t.jsxs)(n.p,{children:["Shell integration works by setting a dedicated shell keybinding that launches ",(0,t.jsx)(n.code,{children:"tv"})," with the current prompt buffer so that ",(0,t.jsx)(n.code,{children:"tv"})," may guess which channel (builtin or cable) is the most appropriate."]}),"\n",(0,t.jsxs)(n.p,{children:["Which channel gets effectively chosen for different commands can be tweaked in the ",(0,t.jsx)(n.code,{children:"shell_integration"})," section of the ",(0,t.jsx)(n.a,{href:"https://github.com/alexpasmantier/television/wiki/Configuration-file",children:"configuration file"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-toml",children:'[shell_integration.channel_triggers]\n"env" = ["export", "unset"]\n"dirs" = ["cd", "ls", "rmdir"]\n"files" = ["mv", "cp", "vim"]\n'})}),"\n",(0,t.jsx)(n.p,{children:"Each key is a channel name and each value is a set of commands that should trigger that channel."}),"\n",(0,t.jsxs)(n.p,{children:["Example: say you want the following prompts to trigger the following channels when pressing ",(0,t.jsx)("kbd",{children:"CTRL-T"}),"`:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"git checkout"})," should trigger the ",(0,t.jsx)(n.code,{children:"git-branches"})," channel"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"ls"})," should trigger the ",(0,t.jsx)(n.code,{children:"dirs"})," channel"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"cat"})," and ",(0,t.jsx)(n.code,{children:"nano"})," should trigger the ",(0,t.jsx)(n.code,{children:"files"})," channel"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You would add the following to your configuration file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-toml",children:'[shell_integration.channel_triggers]\n"git-branches" = ["git checkout"]\n"dirs" = ["ls"]\n"files" = ["cat", "nano"]\n'})}),"\n",(0,t.jsx)(n.h2,{id:"customizing-shell-integration-scripts",children:"Customizing shell integration scripts"}),"\n",(0,t.jsx)(n.h3,{id:"setting-up-the-files",children:"Setting up the files"}),"\n",(0,t.jsx)(n.p,{children:"To customize the default behavior of the shell integration scripts you can save them locally and source that file instead:"}),"\n",(0,t.jsx)(n.p,{children:"Run the following command to make sure the destination directory exists, you can also store them wherever you like"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"mkdir -p ~/.config/television/shell\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.em,{children:"Note:"})," Remember to remove the line added in ",(0,t.jsx)(n.a,{href:"https://github.com/alexpasmantier/television/wiki/Shell-Autocompletion#enabling-shell-integration",children:"Enabling Shell Integration"})," to avoid sourcing the file twice."]}),"\n",(0,t.jsx)(n.h4,{id:"zsh-1",children:"Zsh"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"tv init zsh > ~/.config/television/shell/integration.zsh\necho 'source $HOME/.config/television/shell/integration.zsh' >> ~/.zshrc\n"})}),"\n",(0,t.jsx)(n.h4,{id:"bash-1",children:"Bash"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"tv init bash > ~/.config/television/shell/integration.bash\necho 'source $HOME/.config/television/shell/integration.bash' >> ~/.bashrc\n"})}),"\n",(0,t.jsx)(n.h4,{id:"fish-1",children:"Fish"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"tv init fish > ~/.config/television/shell/integration.fish\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then add to your ",(0,t.jsx)(n.code,{children:"is-interactive"})," block in your ",(0,t.jsx)(n.code,{children:"~/.config/fish/config.fish"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-fish",children:"source $HOME/.config/television/shell/integration.fish\n"})}),"\n",(0,t.jsx)(n.p,{children:"For all shells you'll have to restart it (or similar) to integrate the changes."}),"\n",(0,t.jsx)(n.h3,{id:"recipes",children:"Recipes"}),"\n",(0,t.jsx)(n.h4,{id:"automatically-executing-selection",children:"Automatically executing selection"}),"\n",(0,t.jsxs)(n.p,{children:["Edit the ",(0,t.jsx)(n.code,{children:"~/.config/television/shell/integration.zsh"})," file and add the following:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-zsh",children:'_tv_search() {\n emulate -L zsh\n zle -I\n\n local current_prompt\n current_prompt=$LBUFFER\n\n local output\n\n output=$(tv --autocomplete-prompt "$current_prompt" $*)\n\n zle reset-prompt\n\n if [[ -n $output ]]; then\n RBUFFER=""\n LBUFFER=$current_prompt$output\n\n # uncomment this to automatically accept the line\n # (i.e. run the command without having to press enter twice)\n # zle accept-line\n fi\n}\n\n\nzle -N tv-search _tv_search\n\n\nbindkey \'^T\' tv-search\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Note: Uncommenting ",(0,t.jsx)(n.code,{children:"zle accept-line"})," below will automatically execute the command when accepting a suggestion"]}),"\n",(0,t.jsx)(n.h4,{id:"open-history-channel-with-the-most-up-to-date-version-of-the-history-file",children:"Open history channel with the most up to date version of the history file"}),"\n",(0,t.jsxs)(n.p,{children:["Edit the ",(0,t.jsx)(n.code,{children:"~/.config/television/shell/integration.bash"})," file and replace the ",(0,t.jsx)(n.code,{children:"tv_shell_history"})," function with the following (or rename to keep the default implementation):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'function tv_shell_history() {\n local current_prompt="${READLINE_LINE:0:$READLINE_POINT}"\n\n local output=$(history -n && history -a && tv bash-history --input "$current_prompt")\n\n if [[ -n $output ]]; then\n READLINE_LINE=$output\n READLINE_POINT=${#READLINE_LINE}\n fi\n}\n# history -n to read the current file, in case other sessions wrote some commands\n# history -a to commit the current one\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"WARNING:"})," committing the current history to file could have unintended consequences as a default, for example if the user was planning to run ",(0,t.jsx)(n.code,{children:"history -c"})," to clear the current session (perhaps some commands have sensitive information)"]})]})}function d(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}}}]); |