2009-06-15 7 views
12

En mi .zshrc, utilizo el siguiente fragmento para integrar el portapapeles del shell y mi portapapeles primario X11. Gracias a esta integración, puedo cortar y pegar texto desde y hacia emacs, firefox y la terminal sin tener que usar el mouse.Integrar el kill-ring de readline y el portapapeles X11

kill-line() { zle .kill-line ; echo -n $CUTBUFFER | xclip -i } 
zle -N kill-line # bound on C-k 

yank() { LBUFFER=$LBUFFER$(xclip -o) } 
zle -N yank # bound on C-y 

Nota: Yo uso este truco en Mac OS X, así (con pbcopy/pbpaste en lugar de xclip) y gracias a Synergy mis dos equipos comparten un único portapapeles. Ordenado. Pero no funciona con readline. Y me encuentro usando readline con bastante frecuencia, por ejemplo en (i) python, en gdb, en ncftp ...

Así que aquí viene mi pregunta: hay una manera de integrar el portapapeles de readline con el-resto-de -el mundo ?

Por supuesto, estoy pensando en algunos .inputrc wizardry aquí, pero cualquier idea/ideas sería bienvenida.

+0

No estoy seguro de lo que realmente quiero aquí, pero encontré otra herramienta como xclip XSEL - http://www.vergenet.net/~conrad/software/xsel/ que parece más poderoso – jitter

+0

Gracias por compartir. En realidad, lo que busco es una forma de llamar automáticamente a un programa como XSEL desde los programas de lectura (por ejemplo, bash) cuando presiono Ctrl-K/Ctrl-Y. Supongo que esto se reduce a un comando de shell vinculante para leer combinaciones de teclas ... – Gyom

+0

Te sugiero que cambies tu 'echo -n' a' print -rn --' (o 'printf% s') por encima de –

Respuesta

5

Personalmente, ejecuto todo dentro de GNU screen. Esto me da una gran cantidad de funcionalidades en todos los programas basados ​​en terminales, no solo en los basados ​​en línea de lectura. Tiene sus propios búferes de pegado, que se comparten entre todas las pantallas en su sesión actual, y puede leer/escribir un archivo de intercambio (configurable con bufferfile).

  • Una selección pantalla está hecha con Ctrl + A, [, < movimiento >, Espacio, < movimiento >;
  • copiado al buffer de pegar con Ingrese;
  • pegado con Ctrl + A, ];
  • sustituye por el contenido del archivo de intercambio con Ctrl + A, <;
  • y escrita a cabo en el fichero de intercambio con Ctrl +Un, >.

Entonces todo lo que necesita son pequeños ayudantes para sincronizar /tmp/screen-exchange y la selección X. Algo tan simple como esto funcionaría.

# ~/.screenrc (or entered at C-a : command prompt) 
bind '{' exec sh -c 'xclip -o>~/.screen_exchange' 
bind '}' exec sh -c 'xclip -i ~/.screen_exchange' 

Por supuesto algunas fijaciones y macros más agradables harían la vida más fácil (esto requiere C-a { C-a < C-a ] X para pegar la selección al terminal), pero es totalmente suya.

11

Bash 4.0 introduce algunas nuevas funcionalidades:

NEWS

El comando asignado a una secuencia de teclas con ` bind -x 'ahora establece dos nuevos variables en el entorno del comando ejecutado: READLINE_LINE_BUFFER y READLINE_POINT. El comando puede cambiar la línea de lectura actual y la posición del cursor al modificar READLINE_LINE_BUFFER y READLINE_POINT, respectivamente.

El archivo NEWS parece ser inexacto; READLINE_LINE (no _BUFFER) es lo que está documentado en otro lugar y realmente funciona.

A continuación se simulará el comportamiento de Bash existente Ctrl + (T | K | Y), sino que afecta a la selección X, aunque yo uso Meta/Esc porque yo no' Me gusta sobrescribir la funcionalidad existente.

_xdiscard() { 
    echo -n "${READLINE_LINE:0:$READLINE_POINT}" | xclip 
    READLINE_LINE="${READLINE_LINE:$READLINE_POINT}" 
    READLINE_POINT=0 
} 
_xkill() { 
    echo -n "${READLINE_LINE:$READLINE_POINT}" | xclip 
    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}" 
} 
_xyank() { 
    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$(xclip -o)${READLINE_LINE:$READLINE_POINT}" 
} 
bind -m emacs -x '"\eu": _xdiscard' 
bind -m emacs -x '"\ek": _xkill' 
bind -m emacs -x '"\ey": _xyank' 

todavía me gusta screen más, pero esto mejor responda a su pregunta —, siempre y cuando la única aplicación readline lo que importa es Bash.

+0

gracias; este es de hecho el tipo de cosas que quería.Lamentablemente, estoy usando zsh como shell, así que cuando uso readline suele ser con otros programas que bash :-) Supongo que tendré que acostumbrarme a la pantalla. – Gyom

+1

esto no funciona para mí bajo bash 4.2.37. Esas variables en realidad no contienen ningún valor. – Forethinker

4

me gustaría proponer la siguiente función _xyank() basado en la respuesta de ephemient:

_xyank() { 
    CLIP=$(xclip -o) 
    COUNT=$(echo -n "$CLIP" | wc -c) 
    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}${CLIP}${READLINE_LINE:$READLINE_POINT}" 
    READLINE_POINT=$(($READLINE_POINT + $COUNT)) 
} 

Lo que esto hace es mover el cursor hasta el final del texto pegado, lo que es más consistente con otros elementos de construcción en comandos.

+0

gracias también, pero de nuevo, mi pregunta era para aplicaciones de lectura no bash :-) – Gyom

0

Cuando escribí here, encontré que puede ser mejor tener combinaciones de teclas separadas para llenar el X Portapapeles, esto es porque a menudo uso "matar" para la manipulación de texto en Readline, y no quiero que esto se borre el portapapeles cada vez.

Cuando Readline obtiene la capacidad de tener combinaciones de teclas que desencadenen interacciones con X, recomiendo enlazar^Xw y^Xy para copiar y pegar.

Sé que esto no proporciona una solución a su pregunta, pero no tengo suficientes representantes para decirlo en un comentario.

En cuanto a extender Readline con la capacidad de unirse a los comandos de teclas, lo traje para arriba en la lista de correo Readline, vamos a ver qué dice Chet:

https://lists.gnu.org/archive/html/bug-readline/2016-05/msg00002.html

Cuestiones relacionadas