9 votes

Séquence d'échappement pour supprimer le caractère suivant/suivant ?

Est-il possible, en plus de la suppression d'un caractère de tête à l'aide de la fonction \x08 pour supprimer également un caractère de fin de ligne ? Existe-t-il une séquence d'échappement qui permet de supprimer le caractère suivant au lieu du précédent ?

Je vois que delete est apparemment mappé à ASCII 127, qui est Hex 7F, mais le code suivant :

puts "a\x08b\x7fcd"

produit

bcd

Je m'attendais à ce que \x7f devrait supprimer le caractère 'c' qui le suit, mais il ne le fait pas.

8voto

Vous ne supprimez rien en fait avec \x08 vous ne faites qu'écraser le "a" par un "b".

Imaginez le très vieux temps où vous utilisiez un terminal papier télétype. Ce que vous voyiez sur le papier était un "a" imprimé, le télétype reculait d'un espace et imprimait un "b" par-dessus. Tous les codes ascii non imprimés ont été inventés pour contrôler le mouvement des terminaux télétype.

C'est exactement ce que fait la sortie ci-dessus, sauf que l'écran du terminal ne garde pas les pixels allumés pour le "a" précédent.

Le caractère "del" n'a pas cette signification particulière pour l'écran du terminal de base. Il peut avoir une signification pour un programme tel qu'un éditeur ou un shell, mais pour STDOUT, c'est juste un autre caractère ascii à imprimer.

La signification originale de "del" est d'ignorer ce caractère comme entrée, voir :

http://en.wikipedia.org/wiki/Delete_character

Il n'y a rien que je sache que vous puissiez mettre avant un caractère que STDOUT traitera comme un signal pour ne pas imprimer le caractère suivant. Cependant, si votre sortie est destinée à un programme d'émulation de terminal tel que xterm, vous pouvez faire beaucoup de choses en utilisant des codes d'échappement pour accomplir ce que vous voulez. Voir par exemple :

http://ascii-table.com/ansi-escape-sequences-vt-100.php

La bibliothèque "standard" permettant d'abstraire tous ces codes complexes est la suivante ncurses dont il existe quelques interfaces ruby. voir

Meilleure gemme pour travailler avec ncurses et ruby

2voto

Denis Points 34131

Le caractère de retour en arrière (charcode ?\x08 son alias ?\b et ses fréquentes ?\C-H (Ctrl+H)) n'est pas le même que le caractère de suppression (charcode ?\x7f c'est-à-dire ascii 127). La différence entre les deux est que le retour arrière déplace le curseur vers la gauche avant de l'effacer.

Notez que dans les deux cas, sur les plates-formes unix, la suppression correspond généralement à la séquence d'échappement kill, et que la dernière correspond à la suppression de la ligne à partir de la droite du curseur (c'est-à-dire comme le mappage Ctrl+K dans Terminal). En d'autres termes, ?\b est équivalent à "\e[D\e[K" (à gauche, tuer) et ?\x7f est équivalent à "\e[K" (tuer). Exemple de sortie dans IRB (Ruby 2.0.0, OSX) pour illustrer ceci :

>> print "abc\b"            # abc, backspace
ab=> nil
>> print "abc\e[D\b"        # abc, left, backspace
a=> nil
>> print "abc\x7f"          # abc, delete
abc=> nil
>> print "abc\e[D\x7f"      # abc, left, delete
ab=> nil
>> print "abc\e[D\e[D\x7f"  # abc, left, left, delete
a=> nil
>> print "abc\e[D\e[D\e[K"  # abc, left, left, kill
a=> nil

Le mot d'ordre dans ce qui précède est généralement . Si vous jouez avec getch dans un terminal, le comportement sera très différent de celui d'IRB. (Si ma mémoire est bonne, la touche delete déplace alors le caractère vers la gauche sans tuer la ligne, ou quelque chose de cet ordre).

Pour revenir à votre question après avoir clarifié ce point : à ma connaissance, il n'existe pas de séquence d'échappement pour tuer un seul caractère à la position du curseur ; il n'existe que des séquences pour tuer une ligne à gauche, à droite ou aux deux extrémités du curseur. La référence postée par Fred est très bonne si vous voulez vous plonger dans le sujet :

http://ascii-table.com/ansi-escape-sequences-vt-100.php

En tout cas, je suppose que tu joues avec getch ou quelque chose de cet ordre. Ce que vous voulez faire, pour supprimer un seul caractère, c'est maintenir un tampon et la position du curseur en même temps que vous imprimez des caractères sur la sortie standard. Cela vous permettra de faire correspondre ?\b o ?\x7f comme vous le souhaitez, en utilisant quelque chose comme :

def refresh
  rest = @buffer[@position..-1]
  @stdout.print "\e[K"
  @stdout.print rest, "\e[#{rest.length}D" if rest && !rest.empty?
  nil
end

Sinon, essayez les suspects habituels pour vous épargner les maux de tête : readline, ncurses, la gemme highline, etc.

2voto

mudasobwa Points 5530

Le principal problème ici est le suivant : la norme IO n'a pas de mémoire à court terme. Ce qui veut dire qu'il n'y a pas d'entité magique pour agir sur à venir des symboles. L'extrait de code suivant montre que "delete", même fourni avec un symbole méthode moderne n'a aucune idée des symboles du futur :

> puts "a#{`tput dch1`}b"
#  ab

Si vous avez vraiment besoin de "supprimer un symbole prospectif", je vous suggère d'utiliser ruby monkeypatch pour cela :

class String
  DEL = ''
  def postprocess
    self.gsub /#{DEL}./, ''
  end
end

puts "abc".postprocess
#  ac

En fait, ce n'est pas une réponse directe à votre question, mais cela peut donner une suggestion.

0voto

Doorknob Points 23912

Voici une approche alternative pour supprimer le caractère suivant :

class String
  alias_method :default_initialize, :initialize
  alias_method :default_plus, :+

  attr_accessor :delnext

  def initialize
    default_initialize
    @delnext = false
  end

  def +(x)
    str = String(x)
    str[0] = '' if @delnext
    @delnext = false
    default_plus str
  end
end

Maintenant, vous pouvez le faire :

s = 'test string'
s.delnext = true
s += 'test again'
s # => 'test stringest again'

De même, vous pouvez facilement mettre en œuvre delprev :

class String
  def delprev
    self[self.length - 1] = ''
    # self # uncomment if you want delprev to return the new string
  end
end

s = 'test string'
s.delprev
s # => 'test strin'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X