or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

completion.mdconfiguration.mdhistory.mdhooks.mdindex.mdline-editing.md

completion.mddocs/

0

# Tab Completion

1

2

Comprehensive tab completion system with customizable completion functions, delimiter configuration, and completion context access. These functions enable sophisticated autocompletion behavior for interactive command-line applications.

3

4

## Capabilities

5

6

### Completion Function Management

7

8

Functions for setting up and managing custom completion behavior, allowing applications to provide context-aware autocompletion.

9

10

```python { .api }

11

def set_completer(function=None):

12

"""

13

Set or remove the completer function.

14

15

Parameters:

16

- function (callable, optional): Completer function called as function(text, state)

17

for state in 0, 1, 2, ... until it returns None.

18

If None, removes current completer.

19

20

Returns:

21

None

22

"""

23

24

def get_completer():

25

"""

26

Return current completer function.

27

28

Returns:

29

callable or None: Current completer function, or None if no completer is set

30

"""

31

```

32

33

**Usage Example:**

34

35

```python

36

import readline

37

import os

38

import glob

39

40

def file_completer(text, state):

41

"""Simple file completion example"""

42

# Get all files/directories that start with text

43

matches = glob.glob(text + '*')

44

45

# Add trailing slash to directories

46

matches = [match + '/' if os.path.isdir(match) else match for match in matches]

47

48

# Return the match for this state, or None when exhausted

49

return matches[state] if state < len(matches) else None

50

51

# Set the completer

52

readline.set_completer(file_completer)

53

54

# Enable tab completion

55

readline.parse_and_bind('tab: complete')

56

57

# Check current completer

58

current_completer = readline.get_completer()

59

print(f"Current completer: {current_completer}")

60

61

# Remove completer

62

readline.set_completer(None)

63

```

64

65

### Advanced Completion Example

66

67

```python

68

import readline

69

import keyword

70

import builtins

71

72

class PythonCompleter:

73

def __init__(self):

74

self.matches = []

75

76

def complete(self, text, state):

77

"""Complete Python keywords, builtins, and local variables"""

78

if state == 0: # First call, generate matches

79

self.matches = []

80

81

# Add Python keywords

82

self.matches.extend([kw for kw in keyword.kwlist if kw.startswith(text)])

83

84

# Add built-in functions

85

self.matches.extend([name for name in dir(builtins) if name.startswith(text)])

86

87

# Add local variables (simplified)

88

import __main__

89

if hasattr(__main__, '__dict__'):

90

local_vars = [name for name in __main__.__dict__.keys()

91

if name.startswith(text) and not name.startswith('_')]

92

self.matches.extend(local_vars)

93

94

return self.matches[state] if state < len(self.matches) else None

95

96

# Set up Python completion

97

python_completer = PythonCompleter()

98

readline.set_completer(python_completer.complete)

99

```

100

101

### Completion Context Access

102

103

Functions for accessing information about the current completion attempt, enabling context-sensitive completion behavior.

104

105

```python { .api }

106

def get_completion_type():

107

"""

108

Get the type of completion being attempted.

109

110

Returns:

111

int: Completion type code indicating the kind of completion

112

"""

113

114

def get_begidx():

115

"""

116

Get the beginning index of the readline tab-completion scope.

117

118

Returns:

119

int: Starting index of text being completed within the line buffer

120

"""

121

122

def get_endidx():

123

"""

124

Get the ending index of the readline tab-completion scope.

125

126

Returns:

127

int: Ending index of text being completed within the line buffer

128

"""

129

```

130

131

**Usage Example:**

132

133

```python

134

import readline

135

136

def context_aware_completer(text, state):

137

"""Completer that uses completion context"""

138

if state == 0: # First call, analyze context

139

# Get completion boundaries

140

begidx = readline.get_begidx()

141

endidx = readline.get_endidx()

142

143

# Get the full line being edited

144

line_buffer = readline.get_line_buffer()

145

146

# Extract the word being completed and its context

147

before_cursor = line_buffer[:begidx]

148

completion_text = line_buffer[begidx:endidx]

149

150

print(f"\nCompletion context:")

151

print(f" Line: '{line_buffer}'")

152

print(f" Before cursor: '{before_cursor}'")

153

print(f" Completing: '{completion_text}'")

154

print(f" Indexes: {begidx}-{endidx}")

155

print(f" Completion type: {readline.get_completion_type()}")

156

157

# Simple completion for demonstration

158

options = ['hello', 'help', 'history', 'home']

159

matches = [opt for opt in options if opt.startswith(text)]

160

return matches[state] if state < len(matches) else None

161

162

readline.set_completer(context_aware_completer)

163

```

164

165

### Completion Delimiter Configuration

166

167

Functions for controlling which characters are treated as word boundaries during tab completion.

168

169

```python { .api }

170

def set_completer_delims(string):

171

"""

172

Set the readline word delimiters for tab-completion.

173

174

Parameters:

175

- string (str): Characters to treat as word delimiters

176

177

Returns:

178

None

179

"""

180

181

def get_completer_delims():

182

"""

183

Get the readline word delimiters for tab-completion.

184

185

Returns:

186

str: Current word delimiter characters

187

"""

188

```

189

190

**Usage Example:**

191

192

```python

193

import readline

194

195

# Check current delimiters

196

current_delims = readline.get_completer_delims()

197

print(f"Current delimiters: '{current_delims}'")

198

199

# Set custom delimiters (default is usually ' \t\n`@$><=;|&{(')

200

readline.set_completer_delims(' \t\n') # Only space, tab, and newline

201

202

# For file path completion, you might want to exclude '/' and '.'

203

readline.set_completer_delims(' \t\n=')

204

205

# For programming language completion, include more programming symbols

206

readline.set_completer_delims(' \t\n`@$><=;|&{()}[].,')

207

```

208

209

## Advanced Completion Patterns

210

211

### Command-Specific Completion

212

213

```python

214

import readline

215

import os

216

import subprocess

217

218

class CommandCompleter:

219

def __init__(self):

220

self.commands = {

221

'cd': self._complete_directories,

222

'ls': self._complete_files,

223

'python': self._complete_python_files,

224

'git': self._complete_git_commands,

225

}

226

227

def complete(self, text, state):

228

line_buffer = readline.get_line_buffer()

229

words = line_buffer.split()

230

231

if not words:

232

return None

233

234

command = words[0]

235

if command in self.commands:

236

return self.commands[command](text, state, words)

237

238

# Default file completion

239

return self._complete_files(text, state, words)

240

241

def _complete_directories(self, text, state, words):

242

"""Complete only directories for cd command"""

243

import glob

244

matches = [d for d in glob.glob(text + '*') if os.path.isdir(d)]

245

matches = [d + '/' for d in matches] # Add trailing slash

246

return matches[state] if state < len(matches) else None

247

248

def _complete_files(self, text, state, words):

249

"""Complete files and directories"""

250

import glob

251

matches = glob.glob(text + '*')

252

matches = [m + '/' if os.path.isdir(m) else m for m in matches]

253

return matches[state] if state < len(matches) else None

254

255

def _complete_python_files(self, text, state, words):

256

"""Complete .py files"""

257

import glob

258

matches = glob.glob(text + '*.py')

259

return matches[state] if state < len(matches) else None

260

261

def _complete_git_commands(self, text, state, words):

262

"""Complete git subcommands"""

263

if len(words) == 1: # Completing git subcommand

264

git_commands = ['add', 'commit', 'push', 'pull', 'status', 'log', 'diff', 'branch']

265

matches = [cmd for cmd in git_commands if cmd.startswith(text)]

266

return matches[state] if state < len(matches) else None

267

return None

268

269

# Set up command-specific completion

270

command_completer = CommandCompleter()

271

readline.set_completer(command_completer.complete)

272

```

273

274

### Multi-Level Completion

275

276

```python

277

import readline

278

279

class HierarchicalCompleter:

280

def __init__(self):

281

self.completions = {

282

'show': {

283

'interface': ['eth0', 'eth1', 'lo', 'wlan0'],

284

'route': ['default', 'table', 'all'],

285

'ip': ['route', 'addr', 'link'],

286

},

287

'set': {

288

'interface': ['eth0', 'eth1', 'wlan0'],

289

'route': ['add', 'del', 'change'],

290

}

291

}

292

293

def complete(self, text, state):

294

line_buffer = readline.get_line_buffer()

295

words = line_buffer.split()

296

297

if not words:

298

return None

299

300

# Navigate through completion hierarchy

301

current_level = self.completions

302

for word in words[:-1]: # All words except the one being completed

303

if word in current_level and isinstance(current_level[word], dict):

304

current_level = current_level[word]

305

else:

306

return None

307

308

# Get matches at current level

309

if isinstance(current_level, dict):

310

matches = [key for key in current_level.keys() if key.startswith(text)]

311

elif isinstance(current_level, list):

312

matches = [item for item in current_level if item.startswith(text)]

313

else:

314

matches = []

315

316

return matches[state] if state < len(matches) else None

317

318

# Set up hierarchical completion

319

hierarchical_completer = HierarchicalCompleter()

320

readline.set_completer(hierarchical_completer.complete)

321

```