precedences 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +6 -0
- data/CHANGELOG +43 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +43 -0
- data/Manual/Manuel-fr.md +170 -0
- data/Manual/Manuel-fr.pdf +0 -0
- data/README.md +90 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/precedences/exposed.rb +16 -0
- data/lib/precedences/precedence.rb +330 -0
- data/lib/precedences/version.rb +3 -0
- data/lib/precedences.rb +9 -0
- data/precedences.gemspec +32 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7a84c172e64b8c245d28b5b61fc6971242e5e4754ebe5de552a4b6af27b33014
|
4
|
+
data.tar.gz: 5e43bfe49c64c21b8ab134330f922bc4820dd66c9eceec6b45f36245d208467b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5a0600fae85efe979be58a31250bd0d983b9163305e2e2ba5c3dba9d39ab91ca5cb5203360ec7540ce9d3a50313ddab67d684bf05cbb8a2b4ccefd86007872d0
|
7
|
+
data.tar.gz: ee8ca855b132b278b78b4d84e3933821a4e6e0094069b7f1855af81c5938a0b73fcac6ccd20d42be0380f54637bb9430981ffec2097d5fccbdb9f6d094bb9bc7
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# 1.4.1
|
2
|
+
|
3
|
+
- option :filter à true pour le TTY::select
|
4
|
+
|
5
|
+
# 1.4.0
|
6
|
+
|
7
|
+
- On peut appeler `set_precedence` avec un fichier pour une utilisation sans pré-traitement.
|
8
|
+
|
9
|
+
# 1.3.2
|
10
|
+
|
11
|
+
- Traitement plus fin du nom du fichier enregistrant les précédences
|
12
|
+
|
13
|
+
# 1.3.1
|
14
|
+
|
15
|
+
- correction du bug sur le check des choices (on prend le premier
|
16
|
+
au lieu du deuxième qui pourrait ne pas exister)
|
17
|
+
|
18
|
+
# 1.3.0
|
19
|
+
|
20
|
+
- Possibilité de faire Control-C pour interrompre (annuler)
|
21
|
+
- Cancel en orange
|
22
|
+
|
23
|
+
# 1.2.0
|
24
|
+
|
25
|
+
- Ajout d'un menu Cancel/Renoncer à la demande.
|
26
|
+
|
27
|
+
# 1.1.1
|
28
|
+
|
29
|
+
- Quelques corrections
|
30
|
+
|
31
|
+
# 1.1.0
|
32
|
+
|
33
|
+
- Option :precedences_per_index pour pouvoir utiliser n'importe
|
34
|
+
quel type de value, mais un enregistrement des précédences par
|
35
|
+
index.
|
36
|
+
|
37
|
+
# 1.0.1
|
38
|
+
|
39
|
+
- :value of a choice can be nil.
|
40
|
+
|
41
|
+
# 1.0.0
|
42
|
+
|
43
|
+
- First operational release.
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
precedences (1.4.1)
|
5
|
+
clir (>= 0.16)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
clir (0.22.1)
|
11
|
+
json
|
12
|
+
tty-prompt
|
13
|
+
json (2.6.3)
|
14
|
+
minitest (5.20.0)
|
15
|
+
minitest-color (0.0.2)
|
16
|
+
minitest (~> 5)
|
17
|
+
pastel (0.8.0)
|
18
|
+
tty-color (~> 0.5)
|
19
|
+
rake (12.3.3)
|
20
|
+
tty-color (0.6.0)
|
21
|
+
tty-cursor (0.7.1)
|
22
|
+
tty-prompt (0.23.1)
|
23
|
+
pastel (~> 0.8)
|
24
|
+
tty-reader (~> 0.8)
|
25
|
+
tty-reader (0.9.0)
|
26
|
+
tty-cursor (~> 0.7)
|
27
|
+
tty-screen (~> 0.8)
|
28
|
+
wisper (~> 2.0)
|
29
|
+
tty-screen (0.8.1)
|
30
|
+
wisper (2.0.1)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
clir (>= 0.16)
|
37
|
+
minitest (~> 5.0)
|
38
|
+
minitest-color
|
39
|
+
precedences!
|
40
|
+
rake (~> 12.0)
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
2.1.4
|
data/Manual/Manuel-fr.md
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# Precedences
|
2
|
+
|
3
|
+
Gestion de précédences dans les listes de choix pour `Tty-Prompt#select`.
|
4
|
+
|
5
|
+
Deux modes d'utilisation sont possibles.
|
6
|
+
|
7
|
+
Le plus simple, par block :
|
8
|
+
|
9
|
+
~~~ruby
|
10
|
+
require 'precedences'
|
11
|
+
|
12
|
+
#
|
13
|
+
# Tty-prompt#select choices
|
14
|
+
#
|
15
|
+
choices = [
|
16
|
+
{name:"Choix premier", value: :first},
|
17
|
+
{name:"Deuxième choix", value: :second}
|
18
|
+
]
|
19
|
+
|
20
|
+
#
|
21
|
+
# Fichier où les précédences seront enregistrées
|
22
|
+
#
|
23
|
+
precfile = File.join(__dir__, '.precedences')
|
24
|
+
|
25
|
+
choix = precedencize(choices, precfile) do |q|
|
26
|
+
q.question "Choisir la valeur :"
|
27
|
+
end
|
28
|
+
|
29
|
+
~~~
|
30
|
+
|
31
|
+
`choix` contiendra la valeur choisie, soit `:first` soit `:second`.
|
32
|
+
|
33
|
+
Le second mode d'utilisation fonctionne sans bloc, avec les valeurs par défaut :
|
34
|
+
|
35
|
+
~~~ruby
|
36
|
+
require 'precedences'
|
37
|
+
|
38
|
+
##
|
39
|
+
# On définit choices et prefile de la même façon
|
40
|
+
# puis…
|
41
|
+
|
42
|
+
choices = precedencize(choices, precfile)
|
43
|
+
|
44
|
+
choix = Q.select("Choisir parmi : ", choices)
|
45
|
+
#
|
46
|
+
# Pour enregistrer cette précédence (ne pas l'oublier !)
|
47
|
+
#
|
48
|
+
set_precedence(choix)
|
49
|
+
|
50
|
+
# ...
|
51
|
+
~~~
|
52
|
+
|
53
|
+
On peut même considérer un troisième bloc qui utilise juste la méthode `set_precedence(choix, fichier)` quand le traitement du choix se fait ailleurs. Typiquement, on l’utilise quand la valeur peut être transmise directement au script, par exemple en ligne de commande.
|
54
|
+
|
55
|
+
~~~ruby
|
56
|
+
require 'precedences'
|
57
|
+
|
58
|
+
choix = ARGV[0] || demande_la_valeur_du_choix || return
|
59
|
+
|
60
|
+
set_precedence(choix, "<file/to/precedences_file>")
|
61
|
+
~~~
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
## Valeurs possibles
|
66
|
+
|
67
|
+
Dans l'utilisation normale, l'attribut `:value` des choices doit obligatoirement être de type `String`, `Symbol` ou `Numeric`, mais avec l’option `precedences_per_index`, il est possible d’utiliser n’importe quelle valeur (note : l’ordre est alors mémorisé par index — ce qui signifie qu’il ne faut pas modifier la liste en cours de route).
|
68
|
+
|
69
|
+
Par exemple :
|
70
|
+
|
71
|
+
~~~ruby
|
72
|
+
require 'precedences'
|
73
|
+
|
74
|
+
#
|
75
|
+
# Des choix avec des valeurs spéciales
|
76
|
+
#
|
77
|
+
choices = [
|
78
|
+
{name:"La classe Integer" , value: Integer},
|
79
|
+
{name:"La classe Array" , value: Array},
|
80
|
+
{name:"La classe Hash" , value: Hash},
|
81
|
+
]
|
82
|
+
|
83
|
+
choix = precedencize(choices, file) do |q|
|
84
|
+
q.question "Choisis une classe"
|
85
|
+
q.precedences_per_index # <=== option pour que ça passe
|
86
|
+
end
|
87
|
+
~~~
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
## Options possibles
|
92
|
+
|
93
|
+
En mode block, on peut définir plusieurs choses :
|
94
|
+
|
95
|
+
~~~ruby
|
96
|
+
require 'precedences'
|
97
|
+
|
98
|
+
choix = precedencize(choices, precfile) do |q|
|
99
|
+
#
|
100
|
+
# La question
|
101
|
+
#
|
102
|
+
q.question = "Ma question"
|
103
|
+
# ou
|
104
|
+
q.question "Ma question"
|
105
|
+
|
106
|
+
#
|
107
|
+
# Le nombre de menus affichés
|
108
|
+
# (noter que par défaut, tous les menus sont affichés, contrairement
|
109
|
+
# à tty-prompt qui les limite toujours)
|
110
|
+
#
|
111
|
+
q.per_page 5
|
112
|
+
# ou q.per_page = 5
|
113
|
+
|
114
|
+
#
|
115
|
+
# L'affichage ou non de l'aide (:never par défaut)
|
116
|
+
#
|
117
|
+
q.show_help = :always
|
118
|
+
# ou
|
119
|
+
q.show_help :start
|
120
|
+
|
121
|
+
#
|
122
|
+
# Le message d'aide à afficher
|
123
|
+
#
|
124
|
+
q.help = "Mon message d'aide"
|
125
|
+
# ou
|
126
|
+
q.help "Message d'aide"
|
127
|
+
|
128
|
+
#
|
129
|
+
# La valeur sélectionnée par défaut (lorsqu'il faut passer
|
130
|
+
# outre l'ordre de précédence par exemple)
|
131
|
+
# Cette valeur peut être passée par…
|
132
|
+
#
|
133
|
+
# Par index 1-based explicite
|
134
|
+
q.default = 4
|
135
|
+
# ou q.default 4
|
136
|
+
#
|
137
|
+
# Par valeur du :value
|
138
|
+
q.default = :second
|
139
|
+
# ou q.default :second
|
140
|
+
#
|
141
|
+
# Par extrait du name (ou name exact)
|
142
|
+
q.default = "premier"
|
143
|
+
# ou q.default "premier"
|
144
|
+
# => Sélectionnera le choix "Choix premier"
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
~~~
|
149
|
+
|
150
|
+
#### Ajouter un menu “Renoncer”
|
151
|
+
|
152
|
+
~~~ruby
|
153
|
+
choix = precedencize(choices, file) do |q|
|
154
|
+
q.add_choice_cancel(:up, {value: :cancel, name: "Renoncer"})
|
155
|
+
end
|
156
|
+
~~~
|
157
|
+
|
158
|
+
Si on doit utiliser les valeurs par défaut que sont :
|
159
|
+
|
160
|
+
* `:name` est “Cancel”
|
161
|
+
* `:value` est `nil`
|
162
|
+
* position est `:down` alors on peut faire simplement
|
163
|
+
|
164
|
+
~~~ruby
|
165
|
+
choix = precedencize(choices, file) do |q|
|
166
|
+
q.add_choice_cancel
|
167
|
+
end
|
168
|
+
~~~
|
169
|
+
|
170
|
+
> 😃 Noter qu’on peut en fait se servir de ce menu pour ajouter n’importe quel autre menu que “Renoncer”.
|
Binary file
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Precedences
|
2
|
+
|
3
|
+
Deal with order of items in a select list of TTY-Prompt, applying the "last is the first" principle. Hence, last choice in the list will always be the first in the future.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'precedences'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install precedences
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
~~~ruby
|
24
|
+
require 'precedences'
|
25
|
+
|
26
|
+
choices = [
|
27
|
+
{name:"First choix", value: :first},
|
28
|
+
{name:"Second choix", value: :second},
|
29
|
+
{name:"Third choix", value: :third},
|
30
|
+
]
|
31
|
+
|
32
|
+
myfile = File.join(__dir__, 'my.precedences')
|
33
|
+
|
34
|
+
choix = precedencize(choices, myfile) do |q|
|
35
|
+
q.question "Choose a item among:"
|
36
|
+
end
|
37
|
+
|
38
|
+
~~~
|
39
|
+
|
40
|
+
With the code above, the first time, the list will display:
|
41
|
+
|
42
|
+
~~~
|
43
|
+
> First choix
|
44
|
+
Second choix
|
45
|
+
Third choix
|
46
|
+
~~~
|
47
|
+
|
48
|
+
I choose "Second choix":
|
49
|
+
|
50
|
+
~~~
|
51
|
+
First choix
|
52
|
+
> Second choix
|
53
|
+
Third choix
|
54
|
+
~~~
|
55
|
+
|
56
|
+
The next time I use the command, the list will display:
|
57
|
+
|
58
|
+
~~~
|
59
|
+
> Second choix
|
60
|
+
First choix
|
61
|
+
Third choix
|
62
|
+
~~~
|
63
|
+
|
64
|
+
Then I choose "Third choix":
|
65
|
+
|
66
|
+
~~~
|
67
|
+
Second choix
|
68
|
+
First choix
|
69
|
+
> Third choix
|
70
|
+
~~~
|
71
|
+
|
72
|
+
The next time I use the command, the list displayed should be:
|
73
|
+
|
74
|
+
~~~
|
75
|
+
> Third choix
|
76
|
+
Second choix
|
77
|
+
First choix
|
78
|
+
~~~
|
79
|
+
|
80
|
+
|
81
|
+
## Development
|
82
|
+
|
83
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
84
|
+
|
85
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
86
|
+
|
87
|
+
## Contributing
|
88
|
+
|
89
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/precedences.
|
90
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "precedences"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
def precedencize(choices, filename, &block)
|
4
|
+
prec = Clir::Precedence.new(filename)
|
5
|
+
Clir::Precedence.current = prec
|
6
|
+
return prec.sort(choices, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_precedence(choix, filename = nil)
|
10
|
+
prec = if filename.nil?
|
11
|
+
Clir::Precedence.current
|
12
|
+
else
|
13
|
+
Clir::Precedence.new(filename)
|
14
|
+
end
|
15
|
+
prec.send(:set_precedences_ids, choix)
|
16
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
module Clir
|
2
|
+
class Precedence
|
3
|
+
|
4
|
+
################### CLASSE ###################
|
5
|
+
class << self
|
6
|
+
|
7
|
+
attr_accessor :current
|
8
|
+
|
9
|
+
end #/<< self
|
10
|
+
################### INSTANCE ###################
|
11
|
+
|
12
|
+
attr_reader :filepath
|
13
|
+
|
14
|
+
def initialize(filepath)
|
15
|
+
@filepath = filepath
|
16
|
+
filepath_validize_or_raises
|
17
|
+
# --- Default values ---
|
18
|
+
@question = "Choose:"
|
19
|
+
@show_help = nil
|
20
|
+
@help = ''
|
21
|
+
@per_page = nil
|
22
|
+
@default = 1
|
23
|
+
@precedences_per_index = false
|
24
|
+
@add_choice_cancel = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def sort(choices_ini, &block)
|
28
|
+
|
29
|
+
#
|
30
|
+
# On doit évaluer le bloc ici car certaines valeurs peuvent
|
31
|
+
# modifier le comportement de la suite.
|
32
|
+
# Par exemple, si @precedences_per_index a été mis à true,
|
33
|
+
# on peut permettre n'importe quel type de :value dans les
|
34
|
+
# hash
|
35
|
+
if block_given?
|
36
|
+
block.call(self)
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# List of choices must be valid
|
41
|
+
#
|
42
|
+
choices_valid_or_raises(choices_ini)
|
43
|
+
|
44
|
+
#
|
45
|
+
# Use a clone rather than original list to leave the initial
|
46
|
+
# list of choices alone.
|
47
|
+
#
|
48
|
+
choices = choices_ini.dup
|
49
|
+
|
50
|
+
#
|
51
|
+
# Sort the list of choices
|
52
|
+
# (and treate other choices — add cancel, etc.)
|
53
|
+
#
|
54
|
+
choices = prepare_choices(choices)
|
55
|
+
|
56
|
+
if block_given?
|
57
|
+
#
|
58
|
+
# Tty-select options
|
59
|
+
#
|
60
|
+
options = define_tty_options(choices)
|
61
|
+
#
|
62
|
+
# On procède au choix
|
63
|
+
#
|
64
|
+
begin
|
65
|
+
choix = Q.select(question.jaune, choices, **options)
|
66
|
+
rescue TTY::Reader::InputInterrupt
|
67
|
+
# Annulation par ^C
|
68
|
+
return nil
|
69
|
+
end
|
70
|
+
#
|
71
|
+
# On enregistre ce choix (sauf si null ou :cancel)
|
72
|
+
#
|
73
|
+
set_precedence(choix) unless choix.nil? || choix == :cancel
|
74
|
+
#
|
75
|
+
# On retourne le choix
|
76
|
+
#
|
77
|
+
return choix
|
78
|
+
else
|
79
|
+
#
|
80
|
+
# Sinon, sans block, on renvoie la liste classée
|
81
|
+
#
|
82
|
+
return choices
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# --- Predicate Methods ---
|
87
|
+
|
88
|
+
def precedences_per_index?
|
89
|
+
@precedences_per_index === true
|
90
|
+
end
|
91
|
+
|
92
|
+
def add_choice_cancel?
|
93
|
+
not(@add_choice_cancel.nil?)
|
94
|
+
end
|
95
|
+
|
96
|
+
# --- Tty prompt Methods ---
|
97
|
+
|
98
|
+
def question(quest = nil)
|
99
|
+
@question = quest unless quest.nil?
|
100
|
+
return @question
|
101
|
+
end
|
102
|
+
def question=(quest) ; question(quest) end
|
103
|
+
|
104
|
+
def per_page(value = nil)
|
105
|
+
@per_page = value unless value.nil?
|
106
|
+
return @per_page
|
107
|
+
end
|
108
|
+
def per_page=(value); per_page(value) end
|
109
|
+
|
110
|
+
def show_help(value = nil)
|
111
|
+
@show_help = value unless value === nil
|
112
|
+
return @show_help
|
113
|
+
end
|
114
|
+
def show_help=(value) ; show_help(value) end
|
115
|
+
|
116
|
+
def default(value = nil)
|
117
|
+
@default = value unless value.nil?
|
118
|
+
return @default
|
119
|
+
end
|
120
|
+
def default=(value) ; default(value) end
|
121
|
+
|
122
|
+
def help(value = nil)
|
123
|
+
@help = value unless value.nil?
|
124
|
+
return @help
|
125
|
+
end
|
126
|
+
def help=(value) ; help(value) end
|
127
|
+
|
128
|
+
def precedences_per_index(value = nil)
|
129
|
+
if value === false
|
130
|
+
@precedences_per_index = false
|
131
|
+
else
|
132
|
+
@precedences_per_index = true
|
133
|
+
end
|
134
|
+
return @precedences_per_index
|
135
|
+
end
|
136
|
+
def precedences_per_index=(value) ; precedences_per_index(value) end
|
137
|
+
|
138
|
+
##
|
139
|
+
# To add the cancel choice
|
140
|
+
#
|
141
|
+
def add_choice_cancel(where = :down, **params)
|
142
|
+
if where.is_a?(Hash)
|
143
|
+
params = where
|
144
|
+
where = nil
|
145
|
+
else
|
146
|
+
params ||= {}
|
147
|
+
end
|
148
|
+
params ||= {}
|
149
|
+
default_params = {value: nil, name: "Cancel", position: :down}
|
150
|
+
params = default_params.merge(params)
|
151
|
+
params.merge!(position: where.to_s.downcase.to_sym) unless where.nil?
|
152
|
+
params.merge!(name: params[:name].orange)
|
153
|
+
@add_choice_cancel = params
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
##
|
159
|
+
# = main =
|
160
|
+
#
|
161
|
+
def prepare_choices(choices)
|
162
|
+
#
|
163
|
+
# Classement des choix par précédence
|
164
|
+
#
|
165
|
+
choices = sort_items(choices)
|
166
|
+
#
|
167
|
+
# Faut-il ajouter un choix cancel ?
|
168
|
+
#
|
169
|
+
if add_choice_cancel?
|
170
|
+
add_method = (@add_choice_cancel[:position] == :down) ? :push : :unshift
|
171
|
+
choices.send(add_method, @add_choice_cancel)
|
172
|
+
end
|
173
|
+
#
|
174
|
+
# On retourne les choix préparés
|
175
|
+
#
|
176
|
+
return choices
|
177
|
+
end
|
178
|
+
#
|
179
|
+
# Main method whose sort items
|
180
|
+
#
|
181
|
+
# @api private
|
182
|
+
def sort_items(choices)
|
183
|
+
return choices unless File.exist?(filepath)
|
184
|
+
prec_ids = get_precedences_ids
|
185
|
+
if precedences_per_index?
|
186
|
+
choices_copy = choices.dup
|
187
|
+
choices = prec_ids.map do |id|
|
188
|
+
item = choices_copy[id.to_i - 1]
|
189
|
+
choices_copy[id.to_i - 1] = nil
|
190
|
+
item
|
191
|
+
end
|
192
|
+
# On ajoute les choix restants
|
193
|
+
choices += choices_copy.compact
|
194
|
+
else
|
195
|
+
#
|
196
|
+
# Cas normal
|
197
|
+
#
|
198
|
+
choices.sort!{|a, b|
|
199
|
+
(prec_ids.index(a[:value].to_s)||10000) <=> (prec_ids.index(b[:value].to_s)||10000)
|
200
|
+
}
|
201
|
+
end
|
202
|
+
return choices
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# Define default tty-options (last parameter of select)
|
207
|
+
#
|
208
|
+
def define_tty_options(choices)
|
209
|
+
{
|
210
|
+
per_page: self.per_page || choices.count,
|
211
|
+
show_help: self.show_help ? :always : :never,
|
212
|
+
echo: nil,
|
213
|
+
help: self.help,
|
214
|
+
default: get_default_value_index(choices),
|
215
|
+
filter: true,
|
216
|
+
}
|
217
|
+
end
|
218
|
+
|
219
|
+
# Save the values order in filepath file
|
220
|
+
#
|
221
|
+
# @api private
|
222
|
+
def set_precedences_ids(value)
|
223
|
+
if precedences_per_index?
|
224
|
+
#
|
225
|
+
# Mémorisation des choix par index
|
226
|
+
# (:value de n'importe quel type, mais la liste original
|
227
|
+
# ne peut pas être changée)
|
228
|
+
#
|
229
|
+
@choices_ini.each_with_index do |choice, idx|
|
230
|
+
value = (idx + 1).to_s and break if choice[:value] == value
|
231
|
+
end
|
232
|
+
else
|
233
|
+
#
|
234
|
+
# Mémorisation des choix par valeur
|
235
|
+
# (plus fiable, la liste peut être changée)
|
236
|
+
#
|
237
|
+
value = value.to_s
|
238
|
+
end
|
239
|
+
pids = get_precedences_ids
|
240
|
+
pids.delete(value)
|
241
|
+
pids.unshift(value)
|
242
|
+
File.write(filepath, pids.join("\n"))
|
243
|
+
end
|
244
|
+
|
245
|
+
# Get the values sorted if filepath exists.
|
246
|
+
#
|
247
|
+
# @api private
|
248
|
+
def get_precedences_ids
|
249
|
+
@get_precedences_ids ||= begin
|
250
|
+
File.exist?(filepath) ? File.read(filepath).split("\n") : []
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# Check if given filepath (for saving order of choices) is valid.
|
256
|
+
# Raise an argument error otherwise.
|
257
|
+
# If it's a folder, set to .precedences file
|
258
|
+
#
|
259
|
+
# @api private
|
260
|
+
def filepath_validize_or_raises
|
261
|
+
File.exist?(File.dirname(filepath)) || raise(ArgumentError.new("Precedences incorrect file: its folder should exist."))
|
262
|
+
if File.exist?(filepath) && File.directory?(filepath)
|
263
|
+
@filepath = File.join(filepath, '.precedences')
|
264
|
+
elsif File.extname(filepath).empty? && !File.basename(filepath).start_with?('.')
|
265
|
+
@filepath = "#{filepath}.precedences"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
##
|
270
|
+
# Check if given choices are valid. Raise an ArgumentError otherwise
|
271
|
+
#
|
272
|
+
# @api private
|
273
|
+
def choices_valid_or_raises(choices)
|
274
|
+
#
|
275
|
+
# On en aura besoin
|
276
|
+
#
|
277
|
+
@choices_ini = choices.dup.freeze
|
278
|
+
|
279
|
+
choices.is_a?(Array) || raise(ArgumentError.new('Bad choices. Should be an Array.'))
|
280
|
+
choices.empty? && raise(ArgumentError.new("Bad choices. Shouldn't be empty." ))
|
281
|
+
choices[0].is_a?(Hash) || raise(ArgumentError.new('Bad choices. Should be an Array of Hash(s).'))
|
282
|
+
#
|
283
|
+
# To check unicity of values
|
284
|
+
#
|
285
|
+
cvalues = {}
|
286
|
+
#
|
287
|
+
# Check every choice
|
288
|
+
#
|
289
|
+
choices.each do |choice|
|
290
|
+
choice.key?(:name) || raise(ArgumentError.new("Bad choices. Every choice should define :name attribute."))
|
291
|
+
choice.key?(:value) || raise(ArgumentError.new("Bad choices. Every choice should define :value attribute."))
|
292
|
+
case choice[:value]
|
293
|
+
when Symbol, String, Numeric, NilClass then
|
294
|
+
val = choice[:value].to_s
|
295
|
+
if cvalues.key?(val)
|
296
|
+
raise ArgumentError.new("Bad choices. Value collision: #{choice[:value].inspect} and #{cvalues[val].inspect} are the same, for precedences.")
|
297
|
+
else
|
298
|
+
cvalues.merge!(val => choice[:value])
|
299
|
+
end
|
300
|
+
else
|
301
|
+
if precedences_per_index?
|
302
|
+
# ok, :value peut avoir n'importe quelle valeur
|
303
|
+
else
|
304
|
+
raise(ArgumentError.new("Bad choices. Attribute :value of choice should only be a String, a Symbol, a Numeric or NilClass. #{choice[:value]} is a #{choice[:value].class}. Add option q.precedences_per_index in block if init never changes."))
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
##
|
311
|
+
# @return index (1-based) of default value if defined (even it's a
|
312
|
+
# bit silly with precedences…)
|
313
|
+
#
|
314
|
+
def get_default_value_index(choices)
|
315
|
+
return default if default.is_a?(Integer) && default > 0
|
316
|
+
#
|
317
|
+
# On recherche la valeur dans les choix (:name or :value)
|
318
|
+
#
|
319
|
+
choices.each_with_index do |choice, idx|
|
320
|
+
the_index = idx + 1
|
321
|
+
return the_index if choice[:value] == default
|
322
|
+
return the_index if choice[:name].match?(/#{default}/)
|
323
|
+
end
|
324
|
+
#
|
325
|
+
# Si on n'a rien trouvé, on s'en retourne avec le premier
|
326
|
+
#
|
327
|
+
return 1
|
328
|
+
end
|
329
|
+
end #/class Precedence
|
330
|
+
end #/module Clir
|
data/lib/precedences.rb
ADDED
data/precedences.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'lib/precedences/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "precedences"
|
5
|
+
s.version = Precedences::VERSION
|
6
|
+
s.authors = ["PhilippePerret"]
|
7
|
+
s.email = ["philippe.perret@yahoo.fr"]
|
8
|
+
|
9
|
+
s.summary = %q{Sort list with "the last is the first" principle}
|
10
|
+
s.description = %q{Tty-prompt extension to sort a list of choices along the "last is firts" principle.}
|
11
|
+
s.homepage = "https://rubygems.org/gems/precedences"
|
12
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
13
|
+
|
14
|
+
s.add_dependency 'clir', '>= 0.16'
|
15
|
+
s.add_development_dependency 'minitest'
|
16
|
+
s.add_development_dependency 'minitest-color'
|
17
|
+
|
18
|
+
s.metadata["allowed_push_host"] = "https://rubygems.org"
|
19
|
+
|
20
|
+
s.metadata["homepage_uri"] = s.homepage
|
21
|
+
s.metadata["source_code_uri"] = "https://github.com/PhilippePerret/precedences"
|
22
|
+
s.metadata["changelog_uri"] = "https://github.com/PhilippePerret/precedences/CHANGELOG"
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
26
|
+
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
27
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|features)/}) }
|
28
|
+
end
|
29
|
+
s.bindir = "exe"
|
30
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: precedences
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.4.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- PhilippePerret
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-09-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: clir
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.16'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest-color
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Tty-prompt extension to sort a list of choices along the "last is firts"
|
56
|
+
principle.
|
57
|
+
email:
|
58
|
+
- philippe.perret@yahoo.fr
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".travis.yml"
|
65
|
+
- CHANGELOG
|
66
|
+
- Gemfile
|
67
|
+
- Gemfile.lock
|
68
|
+
- Manual/Manuel-fr.md
|
69
|
+
- Manual/Manuel-fr.pdf
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- bin/console
|
73
|
+
- bin/setup
|
74
|
+
- lib/precedences.rb
|
75
|
+
- lib/precedences/exposed.rb
|
76
|
+
- lib/precedences/precedence.rb
|
77
|
+
- lib/precedences/version.rb
|
78
|
+
- precedences.gemspec
|
79
|
+
homepage: https://rubygems.org/gems/precedences
|
80
|
+
licenses: []
|
81
|
+
metadata:
|
82
|
+
allowed_push_host: https://rubygems.org
|
83
|
+
homepage_uri: https://rubygems.org/gems/precedences
|
84
|
+
source_code_uri: https://github.com/PhilippePerret/precedences
|
85
|
+
changelog_uri: https://github.com/PhilippePerret/precedences/CHANGELOG
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 2.3.0
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubygems_version: 3.1.6
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Sort list with "the last is the first" principle
|
105
|
+
test_files: []
|