vim r! en position de curseur

17

avec vim, si j'utilise

:r!date

vim insère la date dans la ligne suivante, comme avec

:r!pwd

comment puis-je insérer la commande de sortie sous la position du curseur et non dans une nouvelle ligne?

Juan Pablo
la source
1
vi.stackexchange.com/questions/862/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Réponses:

16

Avec " :read" Vim insérera toujours la sortie sur une nouvelle ligne. La solution n'est malheureusement pas simple.

Vous pouvez insérer la sortie d'une commande à la position actuelle du curseur lorsque vous êtes en mode insertion en appuyant sur ControlRpuis en tapant =system('command')Enter. Malheureusement, si la sortie de la commande a une nouvelle ligne de fin (comme la plupart le seront) qui sera également insérée, votre ligne sera interrompue.

Cela peut être résolu en ajoutant un substitute()appel pour supprimer les sauts de ligne, mais cela rend la commande plus problématique qu'il ne vaut la peine de taper à la main.

La solution ultime est de créer une sorte de mappage, mais cela devient encore plus complexe en raison de la façon dont Vim gère ce qu'il appelle "taper à l'avance"; alors que vous pouvez faire quelque chose comme:

:nmap \e i<c-r>=substitute(system('date'),'[\r\n]*$','','')<cr><esc>

Lorsque la commande est "câblée" dans le mappage, vous ne pouvez pas faire quelque chose comme:

:nmap \e i<c-r>=substitute(system(input('Command: ')),'[\r\n]*$','','')<cr><esc>

Où vous essayez d'inviter l'utilisateur à exécuter la commande, car Vim sera simplement confus, émettra un bip et passera en mode insertion.

Vous devez donc demander que la commande s'exécute en premier, la stocker dans une variable, puis insérer la sortie traitée. À ce stade, une fonction d'assistance est probablement nécessaire pour empêcher le mappage lui-même de devenir gênant, donc nous nous retrouvons avec quelque chose comme ceci:

function InlineCommand()
    let l:cmd = input('Command: ')
    let l:output = system(l:cmd)
    let l:output = substitute(l:output, '[\r\n]*$', '', '')
    execute 'normal i' . l:output
endfunction

nmap <silent> \e :call InlineCommand()<CR>

Notez que nmapcrée des mappages qui ne s'exécutent que lorsqu'ils sont tapés en mode normal.

Soit dit en passant, si vous ne souhaitez insérer que la date ou le répertoire de travail actuel, la réponse initiale que j'ai donnée est faisable. Entrez simplement en mode insertion et tapez ControlR=strftime('%c')Enterou ControlR=getcwd()Enter.

Heptite
la source
Serait-il possible de chaîner des commandes pour résoudre ce problème. : r! date | : - | J or i \ n \ n ^ [-:.! Date \ n -JJ
Alexx Roche
4

Si vous le souhaitez dans la ligne actuelle, essayez simplement, mais gardez à l'esprit que l'ancien contenu de la ligne sera effacé:

:.!date

Si vous voulez la position exacte du curseur, vous pouvez:

:let a=system("date") | let b=substitute(a,"[\r\n]*$","","g") | exec 'normal i'.b

Pour faire court: vous devez remplacer car vous voulez vous débarrasser de ^ @ (caractères nuls) que vous pouvez également remplacer par .s / \% x00 // g. Il s'agit d'une version plus courte avec moins de tuyaux:

:exec 'normal i'.substitute(system("date"),"[\n]*$","","")

Et vous pouvez également définir des balises si vous souhaitez remplacer en différents points sur la même ligne:

Compte tenu de cette ligne 1:

1 Date: <datehere> and also <datehere>

Exécuter:

:let a=system("date") | exec ".s/<datehere>/".a."/g" | .s/\%x00//g

Après remplacement:

1 Date: jue ago 9 02:34:52 ART 2012 and also jue ago 9 02:34:52 ART 2012

Testé sur Vim 7.2

Crisboot
la source
1

Vous pouvez ajouter ce genre de chose dans votre .vimrc:

" Insert the date in YYYY-MM-DD format inline just before cursor position (normal mode)
nnoremap <Leader>di me:r !date +\%F<CR>A <Esc>0D`ePJx
  • me marque la position actuelle.
  • :r !date +\%F<CR>met la date sur la ligne suivante au format AAAA-MM-JJ (vous pouvez changer cela comme bon vous semble, échappez simplement à chacun %avec \).
  • A <Esc> ajoute un espace à la fin de la sortie de date.
  • 0Dsupprime la date, `evous ramène à la position marquée et PJxplace la date avant le curseur, joint les lignes (pour se débarrasser de la vide ci-dessous) et tue l'espace de fin. Modifiez le mappage comme bon vous semble.

Si vous voulez le faire en mode insertion, j'ai lu ce bijou aujourd'hui sur https://vimways.org/2018/the-mapping-business/

inoremap <C-g><C-t> <C-r>=strftime("%F")<CR>

Vous pouvez modifier la sortie de date en fonction de vos besoins ( man datepeut vous aider à ce sujet).

Tristan Chase
la source
0

En mode normal (mode d'échappement / bip) coller dans

:exec 'normal i'.system("date \| tr '\n' ' '")

pour obtenir la date insérée à la position actuelle. Si vous copiez cette ligne avec un retour chariot, Shift + Insert devient votre commande DateTime-Here.

De plus, vous pouvez lier F12 à une commande avec

:inoremap <F12> <C-r>=system("date \| tr '\n' ' '")<CR>

vous pouvez ensuite insérer la date avec la touche de fonction-12 lorsque le mode d'insertion est actif. j'utilise

:inoremap DHRE <C-r>=system("date \| tr '\n' ' '")<CR>

(J'ai changé de DHERE après avoir découvert que le collage ADHERE s'est déclenché) parce que j'utilise déjà F12 pour d'autres choses.

j'utilise

grep -iE "dhere" /usr/share/dict/words

pour vérifier les conflits évidents avec les mots existants, ce qui suggère que vous êtes relativement sûr à utiliser:

:inoremap PWD <C-r>=system("pwd \| tr '\n' ' '")<CR>

(sauf si vous rédigez certains documents.)

Alexx Roche
la source