listpager 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d4f836e524e3a80691d2a2a0212b3e447d683c7
4
- data.tar.gz: 4d68a1eee960c026cfbcbaa24b3b9f7378218e26
3
+ metadata.gz: 1cb09a07756c07b56bc85e800cc44c160c164c0e
4
+ data.tar.gz: ccfa85c999c3b235699461e3ef78dd9e428c9a16
5
5
  SHA512:
6
- metadata.gz: c2942ab1c84e13c509b4958b6002604f81c3ee7ee8708eeb3a6e6dce0e0286ff2df89b5a3d60463535d4c7941b0052c4755519452b394d3bf87095c3ef101d29
7
- data.tar.gz: 8789bc607ee28fdf54d6018144c18df4583e61fd4c250739f46e7209e25cf638371e5ec7cb1f5ffca89f8b79df0aff660d926da9112fb0a8bea78a6b1b088f3f
6
+ metadata.gz: 7d83d8ee3ed4476a2e19e1b11a75a5233d8bd215994481a559a455bc055903355b1baa6b9f83d2d8cfe2d82d48a5e21b0e435b016d50cb7e3148da704ba3acc2
7
+ data.tar.gz: 218bbe3375248ba86926f6a9244e2457acbd93e77c747c2bcf2498ee513a11dbcd686381aa95d006e0eff617dad24876c6096351b04a5d54848d60708123bb65
data/README.md CHANGED
@@ -28,9 +28,7 @@ listpager.sync = true
28
28
  listpager.puts "Item #{i}"
29
29
  end
30
30
 
31
- # Enter command mode.
32
- listpager.puts "%%"
33
- listpager.puts "select 35"
31
+ listpager.puts "%set-selected 35"
34
32
  ```
35
33
 
36
34
  If you want to play with the protocol, it's easiest to use two terminals and
@@ -48,28 +46,20 @@ And a "client", like:
48
46
  socat TCP:localhost:4500 -
49
47
  ```
50
48
 
51
- Add some items on your keyboard, then enter `%%` to enter command mode. Another
52
- `%%` will put you back in command mode. If you need a literal `%%` list item,
53
- escape it with `\%%`. If you need a literal `\\%%`, you're out of luck, because
54
- complete escaping isn't available yet.
49
+ Add some items on your keyboard, then enter some commands, prefixed by `%`. If
50
+ you need an item that starts with a liter `%`, start it with `%%`.
55
51
 
56
52
  There are a lot of obvious things the protocol could do, that it doesn't
57
- currently. It's way low-hanging fruit for any contributors (`clear`, `rename`,
58
- `move`, etc.)
53
+ currently. It's way low-hanging fruit for any contributors.
59
54
 
60
55
  ## Protocol
61
56
  listpager reads each item from stdin, and it becomes a list item. As the user
62
57
  arrows through the list, it outputs messages like:
63
58
 
64
- `select 21 apples` where `21` is the index into the list, and `abacate` is the
65
- caption. Any other keys pressed on an item are written out like
59
+ `is-selected 21 apples` where `21` is the index into the list, and `apples` is
60
+ the caption. Any other keys pressed on an item are written out like
66
61
  `keypress enter apples`.
67
62
 
68
- listpager stops considering input bulk list items once it sees: `%%`, where it
69
- enters command mode. Currently, command mode does nothing, but in the future,
70
- it will allow the calling program to instruct listpager to select certain items,
71
- ask for statuses, manipulate the list, add badges, change captions, etc.
72
-
73
63
 
74
64
  ## Dependencies and Installation
75
65
  Install listpager with `gem install listpager`. It has few dependencies:
@@ -83,7 +73,7 @@ sudo apt install libncursesw5-dev
83
73
 
84
74
  ## Implementation Notes
85
75
  curses is terrible but portable. 'curses' doesn't expose enough to be useful,
86
- 'ncurses-ruby' is about as good as you'll do in Ruby.
76
+ 'ncursesw' is about as good as you'll do in Ruby.
87
77
 
88
78
 
89
79
  ## Upcoming Features
@@ -96,6 +86,7 @@ be more functional, I'd like to add a few features:
96
86
  * Mouse support, with scroll wheels.
97
87
  * Checkboxes
98
88
  * Extend command mode
89
+ * `Listpager::Client`
99
90
 
100
91
 
101
92
  ## Contributing
@@ -11,11 +11,13 @@ module Listpager
11
11
  attr_reader :tty
12
12
  attr_reader :self_pipe
13
13
  attr_reader :list
14
- attr_reader :mode
14
+
15
+ attr_reader :locked
15
16
 
16
17
  def initialize
17
18
  @tty = File.open('/dev/tty', 'r+')
18
19
  @self_pipe = IO.pipe
20
+ @locked = false
19
21
 
20
22
  [@tty, *self_pipe].each do |io|
21
23
  io.sync = true
@@ -24,8 +26,35 @@ module Listpager
24
26
  initialize_curses
25
27
 
26
28
  @list = List.new(Ncurses.stdscr)
27
- @mode = :append
29
+ connect_list
30
+
28
31
  @buffer = ''
32
+ @locked_buffer = []
33
+ end
34
+
35
+ def key_name(v)
36
+ @m ||= {
37
+ 27 => 'esc',
38
+ 10 => 'enter',
39
+ 260 => 'left',
40
+ 261 => 'right',
41
+ 127 => 'backspace',
42
+ 330 => 'delete',
43
+ ' ' => 'space',
44
+ }
45
+ @m[v] || (v < 255 && v.chr.match(/[[:print:]]/) ? v.chr : "\##{v}")
46
+ end
47
+
48
+ def connect_list
49
+ cterm = self
50
+ list.define_singleton_method :on_select_change do
51
+ cterm.cmd!('is-selected', selected, selected_value, observe_lock: true)
52
+ end
53
+
54
+ list.define_singleton_method :on_key_press do |k|
55
+ cterm.cmd!('key-pressed', cterm.key_name(k),
56
+ selected, selected_value, observe_lock: true)
57
+ end
29
58
  end
30
59
 
31
60
  def initialize_curses
@@ -50,45 +79,77 @@ module Listpager
50
79
  @tty.close
51
80
  end
52
81
 
53
- def append_mode?
54
- @mode == :append
82
+ def line!(line, observe_lock: false)
83
+ if observe_lock && @locked
84
+ @locked_buffer.push(line)
85
+ else
86
+ $stdout.puts line
87
+ $stdout.flush
88
+ end
89
+ end
90
+
91
+ def cmd!(*args, observe_lock: false)
92
+ line!('%' + Shellwords.join(args.map(&:to_s)),
93
+ observe_lock: observe_lock)
55
94
  end
56
95
 
57
96
  def process_command(argv)
58
97
  cmd, *args = argv
59
98
  case cmd
60
- when 'append-mode', '%'
61
- @mode = :append
62
- when 'title'
63
- @list.title = args[0]
99
+ # TODO: This to be refactored into CommandProcessor
100
+ when 'quit'
101
+ raise Interrupt
102
+
64
103
  when 'clear'
65
- @list.values = []
66
- @list.selected = 0
104
+ list.values = []
105
+ list.selected = 0
106
+ list.dirty!
107
+
108
+ when 'append'
109
+ list.values.push(args.fetch(0))
67
110
  list.dirty!
111
+
112
+ when 'lock'
113
+ @locked = true
114
+ cmd! 'lock'
115
+
116
+ when 'unlock'
117
+ @locked = false
118
+ cmd! 'unlock'
119
+ @locked_buffer.each do |line|
120
+ line!(line)
121
+ end
122
+ @locked_buffer = []
123
+
124
+ when 'get-title'
125
+ cmd! 'title-is', @list.title
126
+ when 'set-title'
127
+ @list.title = args[0]
128
+ cmd! 'title-is', @list.title
129
+
68
130
  when 'get-selected'
69
- list.selection_changed
70
- when 'select'
131
+ cmd! 'selected-is', list.selected, list.selected_value
132
+ when 'set-selected'
71
133
  list.selected = args.fetch(0).to_i
134
+ cmd! 'seleted-is', list.selected, list.selected_value
135
+
72
136
  when 'get-item'
73
- puts ["item", args.fetch(0), list.values[args.fetch(0).to_i]].join ' '
74
- when 'quit'
75
- raise Interrupt
137
+ cmd! 'item-is', args.fetch(0), list.values[args.fetch(0).to_i]
138
+ when 'set-item'
139
+ cmd! 'item-is'
76
140
  end
77
141
  end
78
142
 
79
143
  def process_line(line)
80
- if append_mode?
81
- if line == '%%'
82
- @mode = :command
83
- elsif line[0] == '%'
84
- cmd = Shellwords.split(line[1..-1])
85
- process_command(cmd)
86
- else
87
- list.values.push(line)
88
- list.dirty!
89
- end
144
+ if line[0] == '%' && line[1] != '%'
145
+ cmd = Shellwords.split(line[1..-1])
146
+ process_command(cmd)
90
147
  else
91
- process_command(Shellwords.split(line))
148
+ if line[0] == '%'
149
+ line = line[1..-1]
150
+ end
151
+ list.values.push(line)
152
+ list.dirty!
92
153
  end
93
154
  end
94
155
 
@@ -14,11 +14,9 @@ module Listpager
14
14
  BLANK_SPACE = ' '
15
15
 
16
16
  def on_select_change
17
- puts "select #{selected} #{values[selected]}"
18
17
  end
19
18
 
20
19
  def on_key_press(k)
21
- puts "keypress #{key_name(k)} #{selected} #{values[selected]}"
22
20
  end
23
21
 
24
22
  attr_reader :window
@@ -72,25 +70,18 @@ module Listpager
72
70
 
73
71
  if v != @selected
74
72
  dirty!
73
+ @selected = v
75
74
  on_select_change
76
75
  end
77
76
 
78
- return (@selected = v)
77
+ return @selected
79
78
  end
80
79
 
81
- def key_name(v)
82
- @m ||= {
83
- 27 => 'esc',
84
- 10 => 'enter',
85
- 260 => 'left',
86
- 261 => 'right',
87
- 127 => 'backspace',
88
- 330 => 'delete',
89
- ' ' => 'space',
90
- }
91
- @m[v] || (v < 255 && v.chr.match(/[[:print:]]/) ? v.chr : "\##{v}")
80
+ def selected_value
81
+ values[selected]
92
82
  end
93
83
 
84
+
94
85
  def key_input(value)
95
86
  maxx, maxy = getmaxxy
96
87
 
@@ -1,3 +1,3 @@
1
1
  module Listpager
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: listpager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Owens