Skip to content

Commit eac0003

Browse files
dhylandspfalcon
authored andcommitted
cmd: Customize to work with MicroPython.
1 parent d71c6a3 commit eac0003

File tree

3 files changed

+39
-82
lines changed

3 files changed

+39
-82
lines changed

cmd/cmd.py

Lines changed: 18 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,25 @@
4040
`self.undoc_header' set the headers used for the help function's
4141
listings of documented functions, miscellaneous topics, and undocumented
4242
functions respectively.
43+
44+
----------------------------------------------------------------------------
45+
This is a copy of python's Cmd, but leaves out features that aren't relevant
46+
or can't currently be implemented for MicroPython.
47+
48+
One of the notable deviations is that since MicroPython strips doc strings,
49+
this means that that help by doc string feature doesn't work.
50+
51+
completions have also been stripped out.
4352
"""
4453

45-
import string, sys
54+
#import string, sys
55+
import sys # MiroPython doesn't yet have a string module
4656

4757
__all__ = ["Cmd"]
4858

4959
PROMPT = '(Cmd) '
50-
IDENTCHARS = string.ascii_letters + string.digits + '_'
60+
#IDENTCHARS = string.ascii_letters + string.digits + '_'
61+
IDENTCHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
5162

5263
class Cmd:
5364
"""A simple framework for writing line-oriented command interpreters.
@@ -73,13 +84,10 @@ class Cmd:
7384
nohelp = "*** No help on %s"
7485
use_rawinput = 1
7586

76-
def __init__(self, completekey='tab', stdin=None, stdout=None):
87+
def __init__(self, stdin=None, stdout=None):
7788
"""Instantiate a line-oriented interpreter framework.
7889
79-
The optional argument 'completekey' is the readline name of a
80-
completion key; it defaults to the Tab key. If completekey is
81-
not None and the readline module is available, command completion
82-
is done automatically. The optional arguments stdin and stdout
90+
The optional arguments stdin and stdout
8391
specify alternate input and output file objects; if not specified,
8492
sys.stdin and sys.stdout are used.
8593
@@ -93,7 +101,6 @@ def __init__(self, completekey='tab', stdin=None, stdout=None):
93101
else:
94102
self.stdout = sys.stdout
95103
self.cmdqueue = []
96-
self.completekey = completekey
97104

98105
def cmdloop(self, intro=None):
99106
"""Repeatedly issue a prompt, accept input, parse an initial prefix
@@ -103,14 +110,6 @@ def cmdloop(self, intro=None):
103110
"""
104111

105112
self.preloop()
106-
if self.use_rawinput and self.completekey:
107-
try:
108-
import readline
109-
self.old_completer = readline.get_completer()
110-
readline.set_completer(self.complete)
111-
readline.parse_and_bind(self.completekey+": complete")
112-
except ImportError:
113-
pass
114113
try:
115114
if intro is not None:
116115
self.intro = intro
@@ -139,13 +138,7 @@ def cmdloop(self, intro=None):
139138
stop = self.postcmd(stop, line)
140139
self.postloop()
141140
finally:
142-
if self.use_rawinput and self.completekey:
143-
try:
144-
import readline
145-
readline.set_completer(self.old_completer)
146-
except ImportError:
147-
pass
148-
141+
pass
149142

150143
def precmd(self, line):
151144
"""Hook method executed just before the command line is
@@ -235,74 +228,18 @@ def default(self, line):
235228
"""
236229
self.stdout.write('*** Unknown syntax: %s\n'%line)
237230

238-
def completedefault(self, *ignored):
239-
"""Method called to complete an input line when no command-specific
240-
complete_*() method is available.
241-
242-
By default, it returns an empty list.
243-
244-
"""
245-
return []
246-
247-
def completenames(self, text, *ignored):
248-
dotext = 'do_'+text
249-
return [a[3:] for a in self.get_names() if a.startswith(dotext)]
250-
251-
def complete(self, text, state):
252-
"""Return the next possible completion for 'text'.
253-
254-
If a command has not been entered, then complete against command list.
255-
Otherwise try to call complete_<command> to get list of completions.
256-
"""
257-
if state == 0:
258-
import readline
259-
origline = readline.get_line_buffer()
260-
line = origline.lstrip()
261-
stripped = len(origline) - len(line)
262-
begidx = readline.get_begidx() - stripped
263-
endidx = readline.get_endidx() - stripped
264-
if begidx>0:
265-
cmd, args, foo = self.parseline(line)
266-
if cmd == '':
267-
compfunc = self.completedefault
268-
else:
269-
try:
270-
compfunc = getattr(self, 'complete_' + cmd)
271-
except AttributeError:
272-
compfunc = self.completedefault
273-
else:
274-
compfunc = self.completenames
275-
self.completion_matches = compfunc(text, line, begidx, endidx)
276-
try:
277-
return self.completion_matches[state]
278-
except IndexError:
279-
return None
280-
281231
def get_names(self):
282232
# This method used to pull in base class attributes
283233
# at a time dir() didn't do it yet.
284234
return dir(self.__class__)
285235

286-
def complete_help(self, *args):
287-
commands = set(self.completenames(*args))
288-
topics = set(a[5:] for a in self.get_names()
289-
if a.startswith('help_' + args[0]))
290-
return list(commands | topics)
291-
292236
def do_help(self, arg):
293237
'List available commands with "help" or detailed help with "help cmd".'
294238
if arg:
295239
# XXX check arg syntax
296240
try:
297241
func = getattr(self, 'help_' + arg)
298242
except AttributeError:
299-
try:
300-
doc=getattr(self, 'do_' + arg).__doc__
301-
if doc:
302-
self.stdout.write("%s\n"%str(doc))
303-
return
304-
except AttributeError:
305-
pass
306243
self.stdout.write("%s\n"%str(self.nohelp % (arg,)))
307244
return
308245
func()
@@ -326,8 +263,6 @@ def do_help(self, arg):
326263
if cmd in help:
327264
cmds_doc.append(cmd)
328265
del help[cmd]
329-
elif getattr(self, name).__doc__:
330-
cmds_doc.append(cmd)
331266
else:
332267
cmds_undoc.append(cmd)
333268
self.stdout.write("%s\n"%str(self.doc_leader))
@@ -397,5 +332,6 @@ def columnize(self, list, displaywidth=80):
397332
while texts and not texts[-1]:
398333
del texts[-1]
399334
for col in range(len(texts)):
400-
texts[col] = texts[col].ljust(colwidths[col])
335+
#texts[col] = texts[col].ljust(colwidths[col])
336+
texts[col] = '%-*s' % (colwidths[col], texts[col])
401337
self.stdout.write("%s\n"%str(" ".join(texts)))

cmd/metadata.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
srctype = cpython
2+
type = module
3+
version = 0.0.1

cmd/setup.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import sys
2+
# Remove current dir from sys.path, otherwise setuptools will peek up our
3+
# module instead of system.
4+
sys.path.pop(0)
5+
from setuptools import setup
6+
7+
8+
setup(name='micropython-cmd',
9+
version='0.0.1',
10+
description='CPython cmd module ported to MicroPython',
11+
long_description='This is a module ported from CPython standard library to be compatible with\nMicroPython interpreter. Usually, this means applying small patches for\nfeatures not supported (yet, or at all) in MicroPython. Sometimes, heavier\nchanges are required. Note that CPython modules are written with availability\nof vast resources in mind, and may not work for MicroPython ports with\nlimited heap. If you are affected by such a case, please help reimplement\nthe module from scratch.',
12+
url='https://github.com/micropython/micropython/issues/405',
13+
author='CPython Developers',
14+
author_email='[email protected]',
15+
maintainer='MicroPython Developers',
16+
maintainer_email='[email protected]',
17+
license='Python',
18+
py_modules=['cmd'])

0 commit comments

Comments
 (0)