vim-eof-comment 0.4.2__tar.gz → 0.5.0__tar.gz

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.
Files changed (63) hide show
  1. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/PKG-INFO +2 -1
  2. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/Pipfile +2 -2
  3. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/pyproject.toml +3 -1
  4. vim_eof_comment-0.5.0/version.txt +1 -0
  5. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/args/completion.py +1 -1
  6. vim_eof_comment-0.5.0/vim_eof_comment/args/completion.pyi +34 -0
  7. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/comments/generator.py +8 -2
  8. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/comments/generator.pyi +20 -1
  9. vim_eof_comment-0.4.2/vim_eof_comment/version.py → vim_eof_comment-0.5.0/vim_eof_comment/types.py +194 -90
  10. vim_eof_comment-0.5.0/vim_eof_comment/types.pyi +292 -0
  11. vim_eof_comment-0.5.0/vim_eof_comment/version.py +105 -0
  12. vim_eof_comment-0.5.0/vim_eof_comment/version.pyi +24 -0
  13. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment.egg-info/PKG-INFO +2 -1
  14. vim_eof_comment-0.4.2/version.txt +0 -1
  15. vim_eof_comment-0.4.2/vim_eof_comment/args/completion.pyi +0 -18
  16. vim_eof_comment-0.4.2/vim_eof_comment/types.py +0 -192
  17. vim_eof_comment-0.4.2/vim_eof_comment/types.pyi +0 -157
  18. vim_eof_comment-0.4.2/vim_eof_comment/version.pyi +0 -144
  19. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.flake8 +0 -0
  20. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.gitattributes +0 -0
  21. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.github/CODEOWNERS +0 -0
  22. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.github/workflows/flake8-lint.yml +0 -0
  23. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.github/workflows/mypy-lint.yml +0 -0
  24. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.github/workflows/release.yml +0 -0
  25. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.github/workflows/vim-eof-comment.yml +0 -0
  26. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/.pre-commit-config.yaml +0 -0
  27. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/CHANGELOG.md +0 -0
  28. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/LICENSE +0 -0
  29. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/Makefile +0 -0
  30. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/README.md +0 -0
  31. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/docs/Makefile +0 -0
  32. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/docs/make.bat +0 -0
  33. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/docs/source/conf.py +0 -0
  34. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/docs/source/functions.rst +0 -0
  35. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/docs/source/index.rst +0 -0
  36. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/docs/source/installation.rst +0 -0
  37. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/requirements.txt +0 -0
  38. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/setup.cfg +0 -0
  39. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/taplo.toml +0 -0
  40. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/__init__.py +0 -0
  41. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/__init__.pyi +0 -0
  42. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/__main__.py +0 -0
  43. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/args/__init__.py +0 -0
  44. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/args/__init__.pyi +0 -0
  45. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/args/parsing.py +0 -0
  46. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/args/parsing.pyi +0 -0
  47. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/comments/__init__.py +0 -0
  48. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/comments/__init__.pyi +0 -0
  49. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/comments/filetypes.json +0 -0
  50. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/eof.py +0 -0
  51. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/eof.pyi +0 -0
  52. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/file.py +0 -0
  53. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/file.pyi +0 -0
  54. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/py.typed +0 -0
  55. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/regex.py +0 -0
  56. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/regex.pyi +0 -0
  57. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/util.py +0 -0
  58. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment/util.pyi +0 -0
  59. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment.egg-info/SOURCES.txt +0 -0
  60. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment.egg-info/dependency_links.txt +0 -0
  61. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment.egg-info/entry_points.txt +0 -0
  62. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment.egg-info/requires.txt +0 -0
  63. {vim_eof_comment-0.4.2 → vim_eof_comment-0.5.0}/vim_eof_comment.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vim-eof-comment
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: Adds Vim EOF modeline comments for given filetypes in given directories
5
5
  Author-email: Guennadi Maximov C <g.maxc.fox@protonmail.com>
6
6
  Maintainer-email: Guennadi Maximov C <g.maxc.fox@protonmail.com>
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
20
20
  Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
23
24
  Classifier: Programming Language :: Python
24
25
  Classifier: Topic :: Text Processing :: Filters
25
26
  Classifier: Topic :: Utilities
@@ -14,7 +14,6 @@ setuptools = "*"
14
14
  wheel = "*"
15
15
  pynvim = "*"
16
16
  build = "*"
17
- pip = "*"
18
17
  twine = "*"
19
18
  pypi-attestations = "*"
20
19
  pre-commit = "*"
@@ -28,6 +27,7 @@ renku-sphinx-theme = "*"
28
27
  sphinxawesome-theme = "*"
29
28
  numpydoc = "*"
30
29
  vim-eof-comment = "*"
30
+ pip = "*"
31
31
 
32
32
  [scripts]
33
33
  lint = "flake8 --statistics --show-source --color always --max-line-length 100 --docstring-convention numpy --ignore=D401 ."
@@ -39,4 +39,4 @@ install = "python3 -m pip install"
39
39
  stubs = "stubgen -p vim_eof_comment -o ."
40
40
 
41
41
  [requires]
42
- python_version = "3.13"
42
+ python_version = "3.14"
@@ -16,6 +16,7 @@ classifiers = [
16
16
  "Programming Language :: Python :: 3.11",
17
17
  "Programming Language :: Python :: 3.12",
18
18
  "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
19
20
  "Programming Language :: Python",
20
21
  "Topic :: Text Processing :: Filters",
21
22
  "Topic :: Utilities",
@@ -39,7 +40,7 @@ maintainers = [{ name = "Guennadi Maximov C", email = "g.maxc.fox@protonmail.com
39
40
  name = "vim-eof-comment"
40
41
  readme = "README.md"
41
42
  requires-python = ">=3.10"
42
- version = "0.4.2"
43
+ version = "0.5.0"
43
44
 
44
45
  [project.scripts]
45
46
  vim-eof-comment = "vim_eof_comment.eof:main"
@@ -62,6 +63,7 @@ exclude = [
62
63
  '__dict__$',
63
64
  '__eq__$',
64
65
  '__init__$',
66
+ '__ne__$',
65
67
  '__repr__$',
66
68
  '__str__$',
67
69
  ]
@@ -0,0 +1 @@
1
+ 0.5.0
@@ -5,7 +5,7 @@ Argument parsing completion utilities for ``vim-eof-comment``.
5
5
 
6
6
  Copyright (c) 2025 Guennadi Maximov C. All Rights Reserved.
7
7
  """
8
- __all__ = ["complete_parser"]
8
+ __all__ = ["complete_parser", "complete_validator"]
9
9
 
10
10
  from argparse import ArgumentParser
11
11
  from typing import List, NoReturn
@@ -0,0 +1,34 @@
1
+ from argparse import ArgumentParser
2
+ from typing import NoReturn
3
+
4
+ __all__ = ['complete_parser', 'complete_validator']
5
+
6
+ def complete_validator(completion_candidate: list[str], current_input: str) -> bool:
7
+ """
8
+ Complete non-prefix substring matches.
9
+
10
+ Parameters
11
+ ----------
12
+ completion_candidate : List[str]
13
+ All the completion candidates.
14
+ current_input : str
15
+ The current input string.
16
+
17
+ Returns
18
+ -------
19
+ bool
20
+ Whether the current input fits the completion candidates pool.
21
+ """
22
+ def complete_parser(parser: ArgumentParser, **kwargs) -> NoReturn:
23
+ """
24
+ Complete the script argument parser.
25
+
26
+ Parameters
27
+ ----------
28
+ parser : argparse.ArgumentParser
29
+ The ``ArgumentParser`` object.
30
+ **kwargs
31
+ Extra parameters to be passed to ``argcomplete.autocomplete()``.
32
+ """
33
+
34
+ # vim: set ts=4 sts=4 sw=4 et ai si sta:
@@ -5,7 +5,13 @@ Per-filetype modeline comment class.
5
5
 
6
6
  Copyright (c) 2025 Guennadi Maximov C. All Rights Reserved.
7
7
  """
8
- __all__ = ["Comments", "export_json", "import_json", "list_filetypes"]
8
+ __all__ = [
9
+ "Comments",
10
+ "export_json",
11
+ "generate_list_items",
12
+ "import_json",
13
+ "list_filetypes",
14
+ ]
9
15
 
10
16
  import json
11
17
  import os
@@ -22,7 +28,6 @@ from ..util import die
22
28
  COMMENT_STR: str = "vim: set ts={ts} sts={sts} sw={sw} {et} ai si sta:"
23
29
 
24
30
  _JSON_FILE: str = realpath("./vim_eof_comment/comments/filetypes.json")
25
-
26
31
  _BLUE: int = Fore.BLUE
27
32
  _YELLOW: int = Fore.YELLOW
28
33
  _CYAN: int = Fore.CYAN
@@ -88,6 +93,7 @@ class Comments():
88
93
  __is_available(lang)
89
94
  __fill_langs(langs)
90
95
  get_defaults()
96
+ get_ft()
91
97
  """
92
98
 
93
99
  __DEFAULT: Dict[str, IndentMap] = _DEFAULT.copy()
@@ -2,7 +2,7 @@ from typing import Iterator, NoReturn
2
2
 
3
3
  from ..types import IndentMap
4
4
 
5
- __all__ = ['Comments', 'export_json', 'import_json', 'list_filetypes']
5
+ __all__ = ['Comments', 'export_json', 'generate_list_items', 'import_json', 'list_filetypes']
6
6
 
7
7
  def import_json() -> tuple[dict[str, str], dict[str, IndentMap]]:
8
8
  """
@@ -41,6 +41,7 @@ class Comments:
41
41
  __is_available(lang)
42
42
  __fill_langs(langs)
43
43
  get_defaults()
44
+ get_ft()
44
45
  """
45
46
  __DEFAULT: dict[str, IndentMap]
46
47
  __formats: dict[str, str]
@@ -113,6 +114,24 @@ class Comments:
113
114
  Either the file extension string, or if not available then ``None``.
114
115
  """
115
116
 
117
+ def generate_list_items(ft: str, level: int, expandtab: str) -> str:
118
+ '''
119
+ Generate a colored string for filetypes listing.
120
+
121
+ Parameters
122
+ ----------
123
+ ft : str
124
+ The filetype item in question.
125
+ level : int
126
+ Indent size.
127
+ expandtab : str
128
+ Either ``"Yes"`` or ``"No"``.
129
+
130
+ Returns
131
+ -------
132
+ str
133
+ The generated string.
134
+ '''
116
135
  def list_filetypes() -> NoReturn:
117
136
  """List all available filetypes."""
118
137
  def export_json() -> NoReturn:
@@ -1,15 +1,26 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Copyright (c) 2025 Guennadi Maximov C. All Rights Reserved.
3
3
  """
4
- Custom vim-eof-comment versioning objects.
4
+ Custom vim-eof-comment ``TypedDict`` objects.
5
5
 
6
6
  Copyright (c) 2025 Guennadi Maximov C. All Rights Reserved.
7
7
  """
8
- __all__ = ["VersionInfo", "list_versions", "version_info", "version_print", "__version__"]
8
+ __all__ = [
9
+ "BatchPairDict",
10
+ "BatchPathDict",
11
+ "CommentMap",
12
+ "EOFCommentSearch",
13
+ "IOWrapperBool",
14
+ "IndentHandler",
15
+ "IndentMap",
16
+ "LineBool",
17
+ "ParserSpec",
18
+ "VersionInfo",
19
+ ]
9
20
 
10
- from typing import List, NoReturn, Tuple
21
+ from typing import Any, Dict, List, TextIO, Tuple, TypedDict
11
22
 
12
- from .util import die
23
+ import argcomplete
13
24
 
14
25
 
15
26
  class VersionInfo():
@@ -134,8 +145,23 @@ class VersionInfo():
134
145
  b: VersionInfo = b
135
146
  return self.major == b.major and self.minor == b.minor and self.patch == b.patch
136
147
 
148
+ def get_current_version(self) -> Tuple[int, int, int]:
149
+ """
150
+ Get a tuple representing the current version.
151
+
152
+ Returns
153
+ -------
154
+ major : int
155
+ Major component.
156
+ minor : int
157
+ Minor component.
158
+ patch : int
159
+ Patch component.
160
+ """
161
+ return (self.major, self. minor, self.patch)
162
+
137
163
  def get_all_versions(self) -> str:
138
- r"""
164
+ """
139
165
  Retrieve all versions as a string.
140
166
 
141
167
  Returns
@@ -163,93 +189,171 @@ class VersionInfo():
163
189
  return result
164
190
 
165
191
 
166
- version_info = VersionInfo([
167
- (0, 1, 1),
168
- (0, 1, 2),
169
- (0, 1, 3),
170
- (0, 1, 4),
171
- (0, 1, 5),
172
- (0, 1, 6),
173
- (0, 1, 7),
174
- (0, 1, 8),
175
- (0, 1, 9),
176
- (0, 1, 10),
177
- (0, 1, 11),
178
- (0, 1, 12),
179
- (0, 1, 13),
180
- (0, 1, 14),
181
- (0, 1, 15),
182
- (0, 1, 16),
183
- (0, 1, 17),
184
- (0, 1, 18),
185
- (0, 1, 19),
186
- (0, 1, 20),
187
- (0, 1, 21),
188
- (0, 1, 22),
189
- (0, 1, 23),
190
- (0, 1, 24),
191
- (0, 1, 25),
192
- (0, 1, 26),
193
- (0, 1, 27),
194
- (0, 1, 28),
195
- (0, 1, 29),
196
- (0, 1, 30),
197
- (0, 1, 31),
198
- (0, 1, 32),
199
- (0, 1, 33),
200
- (0, 1, 34),
201
- (0, 1, 35),
202
- (0, 1, 36),
203
- (0, 1, 37),
204
- (0, 1, 38),
205
- (0, 2, 0),
206
- (0, 2, 1),
207
- (0, 2, 2),
208
- (0, 2, 3),
209
- (0, 3, 0),
210
- (0, 3, 1),
211
- (0, 3, 2),
212
- (0, 3, 3),
213
- (0, 3, 4),
214
- (0, 3, 5),
215
- (0, 3, 6),
216
- (0, 3, 7),
217
- (0, 3, 8),
218
- (0, 3, 9),
219
- (0, 3, 10),
220
- (0, 3, 11),
221
- (0, 3, 12),
222
- (0, 3, 13),
223
- (0, 3, 14),
224
- (0, 3, 15),
225
- (0, 3, 16),
226
- (0, 3, 17),
227
- (0, 3, 18),
228
- (0, 3, 19),
229
- (0, 3, 20),
230
- (0, 3, 21),
231
- (0, 4, 0),
232
- (0, 4, 1),
233
- (0, 4, 2),
234
- ])
235
-
236
- __version__: str = str(version_info)
237
-
238
-
239
- def list_versions() -> NoReturn:
240
- """List all versions."""
241
- die(version_info.get_all_versions(), code=0)
242
-
243
-
244
- def version_print(version: str) -> NoReturn:
245
- """
246
- Print project version, then exit.
192
+ class ParserSpec(TypedDict):
193
+ """
194
+ Stores the spec for ``argparse`` operations in a constant value.
247
195
 
248
- Parameters
196
+ This is a ``TypedDict``-like object.
197
+
198
+ Attributes
199
+ ----------
200
+ opts : List[str]
201
+ A list containing all the relevant iterations of the same option.
202
+ kwargs : Dict[str, Any]
203
+ Extra arguments for ``argparse.ArgumentParser``.
204
+ completer : argcomplete.DirectoriesCompleter
205
+ An ``argcomplete`` completer object.
206
+ """
207
+
208
+ opts: List[str]
209
+ kwargs: Dict[str, Any]
210
+ completer: argcomplete.DirectoriesCompleter
211
+
212
+
213
+ class CommentMap(TypedDict):
214
+ """
215
+ Stores a dict with a ``level`` key.
216
+
217
+ This is a ``TypedDict``-like object.
218
+
219
+ Attributes
220
+ ----------
221
+ level : int
222
+ The indentation level.
223
+ """
224
+
225
+ level: int
226
+
227
+
228
+ class IndentMap(TypedDict):
229
+ """
230
+ A dict containing ``level`` and ``expandtab`` as keys.
231
+
232
+ This is a ``TypedDict``-like object.
233
+
234
+ Attributes
235
+ ----------
236
+ level : int
237
+ The indent level.
238
+ expandtab : bool
239
+ Whether to expand tabs or not.
240
+ """
241
+
242
+ level: int
243
+ expandtab: bool
244
+
245
+
246
+ class IndentHandler(TypedDict):
247
+ """
248
+ A dict containing ``ft_ext``, ``level`` and ``expandtab`` as keys.
249
+
250
+ This is a ``TypedDict``-like object.
251
+
252
+ Attributes
253
+ ----------
254
+ ft_ext : str
255
+ The file-extension/file-type.
256
+ level : str
257
+ The string representation of the indent level.
258
+ expandtab : bool
259
+ Whether to expand tabs or not.
260
+ """
261
+
262
+ ft_ext: str
263
+ level: str
264
+ expandtab: bool
265
+
266
+
267
+ class IOWrapperBool(TypedDict):
268
+ """
269
+ A dict containing ``file`` and ``had_nwl`` as keys.
270
+
271
+ This is a ``TypedDict``-like object.
272
+
273
+ Attributes
274
+ ----------
275
+ file : TextIO
276
+ The opened file as a ``TextIO`` wrapper.
277
+ had_nwl : bool
278
+ Whether the file has a newline or not.
279
+ """
280
+
281
+ file: TextIO
282
+ had_nwl: bool
283
+
284
+
285
+ class LineBool(TypedDict):
286
+ """
287
+ A dict containing ``line`` and ``had_nwl`` as keys.
288
+
289
+ This is a ``TypedDict``-like object.
290
+
291
+ Attributes
292
+ ----------
293
+ line : str
294
+ The last line of the target file.
295
+ had_nwl : bool
296
+ Whether the file has a newline or not.
297
+ """
298
+
299
+ line: str
300
+ had_nwl: bool
301
+
302
+
303
+ class BatchPathDict(TypedDict):
304
+ """
305
+ A dict containing ``file`` and ``ft_ext`` as keys.
306
+
307
+ This is a ``TypedDict``-like object.
308
+
309
+ Attributes
310
+ ----------
311
+ file : TextIO
312
+ The opened file as a ``TextIO`` wrapper.
313
+ ft_ext : str
314
+ The file-type/file-extension.
315
+ """
316
+
317
+ file: TextIO
318
+ ft_ext: str
319
+
320
+
321
+ class BatchPairDict(TypedDict):
322
+ """
323
+ A dict containing ``fpath`` and ``ft_ext`` as keys.
324
+
325
+ This is a ``TypedDict``-like object.
326
+
327
+ Attributes
249
328
  ----------
250
- version : str
251
- The version string.
329
+ fpath : str
330
+ The target file's path.
331
+ ft_ext : str
332
+ The file-type/file-extension.
252
333
  """
253
- die(f"vim-eof-comment-{version}", code=0)
334
+
335
+ fpath: str
336
+ ft_ext: str
337
+
338
+
339
+ class EOFCommentSearch(TypedDict):
340
+ """
341
+ A dict containing ``state``, ``lang`` and ``match`` as keys.
342
+
343
+ This is a ``TypedDict``-like object.
344
+
345
+ Attributes
346
+ ----------
347
+ state : IOWrapperBool
348
+ The target ``IOWrapperBool`` object.
349
+ lang : str
350
+ The file language.
351
+ match : bool
352
+ Whether it has a variation of an EOF comment at the end.
353
+ """
354
+
355
+ state: IOWrapperBool
356
+ lang: str
357
+ match: bool
254
358
 
255
359
  # vim: set ts=4 sts=4 sw=4 et ai si sta: