Commit 7838a8ba authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'master' into ls-n

parents 76a38dcc 10ec25eb
......@@ -5,10 +5,6 @@ smoothly into topydo.
### General
* This Github page defaults to the **stable** branch which is for **bug fixes
only**. If you would like to add a new feature, make sure to make a Pull
Request on the `master` branch.
* Use descriptive commit messages. The post
[How to write a commit message](http://chris.beams.io/posts/git-commit/) by
Chris Beams has some good guidelines.
......
......@@ -43,6 +43,6 @@ Demo
[2]: https://github.com/ginatrapani/todo.txt-cli
[3]: https://github.com/bram85/todo.txt-tools
[4]: https://github.com/bram85/topydo/wiki
[5]: https://raw.githubusercontent.com/bram85/topydo/stable/doc/topydo.gif
[5]: https://raw.githubusercontent.com/bram85/topydo/master/doc/topydo.gif
[6]: https://github.com/jonathanslenders/python-prompt-toolkit
[7]: https://github.com/collective/icalendar
......@@ -45,24 +45,30 @@ class EditCommandTest(CommandTest):
self.todolist = TodoList(todos)
@mock.patch('topydo.commands.EditCommand._is_edited')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit1(self, mock_open_in_editor):
def test_edit01(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
""" Preserve dependencies after editing. """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Foo id:1')]
mock_is_edited.return_value = True
command = EditCommand(["1"], self.todolist, self.out, self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.todolist.print_todos(), u("Bar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a\nFoo id:1"))
@mock.patch('topydo.commands.EditCommand._is_edited')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit2(self, mock_open_in_editor, mock_todos_from_temp):
def test_edit02(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
""" Edit some todo. """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
mock_is_edited.return_value = True
command = EditCommand(["Bar"], self.todolist, self.out, self.error,
None)
......@@ -72,7 +78,7 @@ class EditCommandTest(CommandTest):
self.assertEqual(self.errors, "")
self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat"))
def test_edit3(self):
def test_edit03(self):
""" Throw an error after invalid todo number given as argument. """
command = EditCommand(["FooBar"], self.todolist, self.out, self.error,
None)
......@@ -81,7 +87,7 @@ class EditCommandTest(CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_edit4(self):
def test_edit04(self):
""" Throw an error with pointing invalid argument. """
command = EditCommand(["Bar", "5"], self.todolist, self.out,
self.error, None)
......@@ -90,22 +96,7 @@ class EditCommandTest(CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, "Invalid todo number given: 5.\n")
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit5(self, mock_open_in_editor, mock_todos_from_temp):
""" Don't let to delete todos acidentally while editing. """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Only one line')]
command = EditCommand(["1", "Bar"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, "Number of edited todos is not equal to number of supplied todo IDs.\n")
self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a"))
def test_edit6(self):
def test_edit05(self):
"""
Throw an error with invalid argument containing special characters.
"""
......@@ -117,12 +108,14 @@ class EditCommandTest(CommandTest):
self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
@mock.patch('topydo.commands.EditCommand._is_edited')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit7(self, mock_open_in_editor, mock_todos_from_temp):
def test_edit06(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
""" Edit todo with special characters. """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
mock_is_edited.return_value = True
command = EditCommand([u("Fo\u00f3B\u0105\u017a")], self.todolist,
self.out, self.error, None)
......@@ -133,13 +126,32 @@ class EditCommandTest(CommandTest):
self.assertEqual(self.todolist.print_todos(),
u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat"))
@mock.patch('topydo.commands.EditCommand._is_edited')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp):
def test_edit07(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
""" Don't perform write if tempfile is unchanged """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Only one line')]
mock_is_edited.return_value = False
command = EditCommand(["1", "Bar"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, "Editing aborted. Nothing to do.\n")
self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a"))
@mock.patch('topydo.commands.EditCommand._is_edited')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
""" Edit todos matching expression. """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat'),
Todo('Lazy Dog')]
mock_is_edited.return_value = True
command = EditCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
......@@ -147,8 +159,8 @@ class EditCommandTest(CommandTest):
expected = u("| 3| Lazy Cat\n| 4| Lazy Dog\n")
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, expected)
self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nFo\u00f3B\u0105\u017a\nLazy Cat\nLazy Dog"))
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
from test.TopydoTestCase import TopydoTest
from topydo.Commands import get_subcommand
from topydo.commands.AddCommand import AddCommand
from topydo.commands.DeleteCommand import DeleteCommand
from topydo.commands.ListCommand import ListCommand
from topydo.commands.ListProjectCommand import ListProjectCommand
from topydo.lib.Config import config
class GetSubcommandTest(TopydoTest):
def test_normal_cmd(self):
args = ["add"]
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, AddCommand))
def test_cmd_help(self):
args = ["help", "add"]
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, AddCommand))
self.assertEqual(final_args, ["help"])
def test_alias(self):
config("test/data/aliases.conf")
args = ["foo"]
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, DeleteCommand))
self.assertEqual(final_args, ["-f", "test"])
def test_default_cmd01(self):
args = ["bar"]
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, ListCommand))
self.assertEqual(final_args, ["bar"])
def test_default_cmd02(self):
args = []
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, ListCommand))
self.assertEqual(final_args, [])
def test_alias_default_cmd01(self):
config("test/data/aliases.conf", {('topydo', 'default_command'): 'foo'})
args = ["bar"]
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, DeleteCommand))
self.assertEqual(final_args, ["-f", "test", "bar"])
def test_alias_default_cmd02(self):
config("test/data/aliases.conf", {('topydo', 'default_command'): 'foo'})
args = []
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, DeleteCommand))
self.assertEqual(final_args, ["-f", "test"])
def test_wrong_alias(self):
config("test/data/aliases.conf")
args = ["baz"]
real_cmd, final_args = get_subcommand(args)
self.assertEqual(real_cmd, None)
if __name__ == '__main__':
unittest.main()
[aliases]
foo = rm -f test
baz = FooBar
......@@ -46,3 +46,14 @@ append_parent_contexts = 0
; context_color = magenta
; metadata_color = green
; link_color = light-cyan
[aliases]
;showall = ls -x
;lsproj = lsprj
;listprj = lsprj
;listproj = lsprj
;listproject = lsprj
;listprojects = lsprj
;listcon = lscon
;listcontext = lscon
;listcontexts = lscon
......@@ -35,15 +35,7 @@ _SUBCOMMAND_MAP = {
'exit': 'ExitCommand', # used for the prompt
'ls': 'ListCommand',
'lscon': 'ListContextCommand',
'listcon': 'ListContextCommand',
'listcontext': 'ListContextCommand',
'listcontexts': 'ListContextCommand',
'lsprj': 'ListProjectCommand',
'lsproj': 'ListProjectCommand',
'listprj': 'ListProjectCommand',
'listproj': 'ListProjectCommand',
'listproject': 'ListProjectCommand',
'listprojects': 'ListProjectCommand',
'postpone': 'PostponeCommand',
'pri': 'PriorityCommand',
'quit': 'ExitCommand',
......@@ -53,7 +45,6 @@ _SUBCOMMAND_MAP = {
'tag': 'TagCommand',
}
def get_subcommand(p_args):
"""
Retrieves the to-be executed Command and returns a tuple (Command, args).
......@@ -80,13 +71,31 @@ def get_subcommand(p_args):
__import__(modulename, globals(), locals(), [classname], 0)
return getattr(sys.modules[modulename], classname)
def resolve_alias(p_alias, p_args):
"""
Resolves a subcommand alias and returns a tuple (Command, args).
If alias resolves to non-existent command, main help message is
returned.
"""
real_subcommand, alias_args = alias_map[p_alias]
try:
result = import_subcommand(real_subcommand)
args = alias_args + p_args
return (result, args)
except KeyError:
return get_subcommand(['help'])
result = None
args = p_args
alias_map = config().aliases()
try:
subcommand = p_args[0]
if subcommand in _SUBCOMMAND_MAP:
if subcommand in alias_map:
result, args = resolve_alias(subcommand, args[1:])
elif subcommand in _SUBCOMMAND_MAP:
result = import_subcommand(subcommand)
args = args[1:]
elif subcommand == 'help':
......@@ -101,12 +110,16 @@ def get_subcommand(p_args):
pass
else:
p_command = config().default_command()
if p_command in _SUBCOMMAND_MAP:
if p_command in alias_map:
result, args = resolve_alias(p_command, args)
elif p_command in _SUBCOMMAND_MAP:
result = import_subcommand(p_command)
# leave args unchanged
except IndexError:
p_command = config().default_command()
if p_command in _SUBCOMMAND_MAP:
if p_command in alias_map:
result, args = resolve_alias(p_command, args)
elif p_command in _SUBCOMMAND_MAP:
result = import_subcommand(p_command)
return (result, args)
......@@ -101,12 +101,9 @@ except ConfigError as config_error:
error(str(config_error))
sys.exit(1)
from topydo.commands.ArchiveCommand import ArchiveCommand
from topydo.commands.SortCommand import SortCommand
from topydo.lib import TodoFile
from topydo.lib import TodoList
from topydo.lib import TodoListBase
from topydo.lib.ChangeSet import ChangeSet
from topydo.lib.Utils import escape_ansi
......@@ -178,6 +175,7 @@ class CLIApplicationBase(object):
self.backup.add_archive(archive)
if archive:
from topydo.commands.ArchiveCommand import ArchiveCommand
command = ArchiveCommand(self.todolist, archive)
command.execute()
......@@ -196,14 +194,21 @@ class CLIApplicationBase(object):
"""
return input
def is_read_only(self, p_command):
""" Returns True when the given command class is read-only. """
read_only_commands = tuple(cmd + 'Command' for cmd in ('Revert', ) +
READ_ONLY_COMMANDS)
return p_command.__module__.endswith(read_only_commands)
def _execute(self, p_command, p_args):
"""
Execute a subcommand with arguments. p_command is a class (not an
object).
"""
cmds_wo_backup = tuple(cmd + 'Command' for cmd in ('Revert', ) + READ_ONLY_COMMANDS)
if config().backup_count() > 0 and p_command and not p_command.__module__.endswith(cmds_wo_backup):
if config().backup_count() > 0 and p_command and not self.is_read_only(p_command):
call = [p_command.__module__.lower()[16:-7]] + p_args # strip "topydo.commands" and "Command"
from topydo.lib.ChangeSet import ChangeSet
self.backup = ChangeSet(self.todolist, p_call=call)
command = p_command(
......@@ -232,6 +237,7 @@ class CLIApplicationBase(object):
self._archive()
if config().keep_sorted():
from topydo.commands.SortCommand import SortCommand
self._execute(SortCommand, [])
if self.backup:
......
......@@ -99,15 +99,14 @@ class PromptApplication(CLIApplicationBase):
sys.exit(0)
mtime_after = _todotxt_mtime()
(subcommand, args) = get_subcommand(user_input)
if self.mtime != mtime_after:
# refuse to perform operations such as 'del' and 'do' if the
# todo.txt file has been changed in the background.
if not self.is_read_only(subcommand) and self.mtime != mtime_after:
error("WARNING: todo.txt file was modified by another application.\nTo prevent unintended changes, this operation was not executed.")
continue
(subcommand, args) = get_subcommand(user_input)
try:
if self._execute(subcommand, args) != False:
self._post_execute()
......
......@@ -30,7 +30,9 @@ from topydo.lib.RelativeDate import relative_date_to_date
def _subcommands(p_word_before_cursor):
""" Generator for subcommand name completion. """
subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if
sc_map = config().aliases()
sc_map.update(_SUBCOMMAND_MAP)
subcommands = [sc for sc in sorted(sc_map.keys()) if
sc.startswith(p_word_before_cursor)]
for command in subcommands:
yield Completion(command, -len(p_word_before_cursor))
......
......@@ -33,6 +33,11 @@ DEFAULT_EDITOR = 'vi'
# cannot use super() inside the class itself
BASE_TODOLIST = lambda tl: super(TodoList, tl)
def _get_file_mtime(p_file):
return os.stat(p_file.name).st_mtime
def _is_edited(p_orig_mtime, p_file):
return p_orig_mtime < _get_file_mtime(p_file)
class EditCommand(MultiCommand):
def __init__(self, p_args, p_todolist, p_output, p_error, p_input):
......@@ -105,10 +110,12 @@ class EditCommand(MultiCommand):
self.printer.add_filter(PrettyPrinterNumbers(self.todolist))
temp_todos = self._todos_to_temp()
orig_mtime = _get_file_mtime(temp_todos)
if not self._open_in_editor(temp_todos.name):
new_todos = self._todos_from_temp(temp_todos)
if len(new_todos) == len(self.todos):
if _is_edited(orig_mtime, temp_todos):
for todo in self.todos:
BASE_TODOLIST(self.todolist).delete(todo)
......@@ -116,8 +123,7 @@ class EditCommand(MultiCommand):
self.todolist.add_todo(todo)
self.out(self.printer.print_todo(todo))
else:
self.error('Number of edited todos is not equal to '
'number of supplied todo IDs.')
self.error('Editing aborted. Nothing to do.')
else:
self.error(self.usage())
......
......@@ -16,8 +16,6 @@
from topydo.lib.Config import config
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.IcalPrinter import IcalPrinter
from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.PrettyPrinter import pretty_printer_factory
from topydo.lib.PrettyPrinterFilter import (PrettyPrinterHideTagFilter,
PrettyPrinterIndentFilter)
......@@ -58,9 +56,11 @@ class ListCommand(ExpressionCommand):
self.sort_expression = value
elif opt == '-f':
if value == 'json':
from topydo.lib.JsonPrinter import JsonPrinter
self.printer = JsonPrinter()
elif value == 'ical':
if self._poke_icalendar():
from topydo.lib.IcalPrinter import IcalPrinter
self.printer = IcalPrinter(self.todolist)
else:
self.printer = None
......
......@@ -39,8 +39,7 @@ class SortCommand(Command):
sorter = Sorter(expression) # TODO: validate
sorted_todos = sorter.sort(self.todolist.todos())
self.todolist.erase()
self.todolist.add_todos(sorted_todos)
self.todolist.replace(sorted_todos)
def usage(self):
return """Synopsis: sort [expression]"""
......
......@@ -110,7 +110,7 @@ class ChangeSet(object):
self._write()
self.close()
def delete(self, p_timestamp=None):
def delete(self, p_timestamp=None, p_write=True):
""" Removes backup from the backup file. """
timestamp = p_timestamp or self.timestamp
index = self._get_index()
......@@ -119,6 +119,8 @@ class ChangeSet(object):
del self.backup_dict[timestamp]
index.remove(index[[change[0] for change in index].index(timestamp)])
self._save_index(index)
if p_write:
self._write()
except KeyError:
pass
......@@ -143,12 +145,15 @@ class ChangeSet(object):
"""
Removes oldest backups that exceed the limit configured in backup_count
option.
Does not write back to file system, make sure to call self._write()
afterwards.
"""
index = self._get_index()
backup_limit = config().backup_count() - 1
for changeset in index[backup_limit:]:
self.delete(changeset[0])
self.delete(changeset[0], p_write=False)
def get_backup(self, p_todolist):
"""
......
......@@ -16,9 +16,9 @@
import os
from six import iteritems
from six.moves import configparser
class ConfigError(Exception):
def __init__(self, p_text):
self.text = p_text
......@@ -42,6 +42,7 @@ class _Config:
"""
self.sections = [
'add',
'aliases',
'colorscheme',
'dep',
'ls',
......@@ -51,47 +52,71 @@ class _Config:
]
self.defaults = {
# topydo
'topydo': {
'default_command': 'ls',
'colors': '1',
'filename': 'todo.txt',
'archive_filename': 'done.txt',
'identifiers': 'linenumber',
'backup_count': '5',
},
# add
'add': {
'auto_creation_date': '1',
},
# ls
'ls': {
'hide_tags': 'id,p,ical',
'indent': 0,
'indent': '0',
'list_limit': '-1',
},
# tags
'tags': {
'tag_start': 't',
'tag_due': 'due',
'tag_star': 'star',
},
# sort
'sort': {
'keep_sorted': '0',
'sort_string': 'desc:importance,due,desc:priority',
'ignore_weekends': '1',
},
# dep
'dep': {
'append_parent_projects': '0',
'append_parent_contexts': '0',
},
# colorscheme
'colorscheme': {
'project_color': 'red',
'context_color': 'magenta',
'metadata_color': 'green',
'link_color': 'cyan',
'priority_colors': 'A:cyan,B:yellow,C:blue',
},
'aliases': {
'lsproj': 'lsprj',
'listprj': 'lsprj',
'listproj': 'lsprj',
'listproject': 'lsprj',
'listprojects': 'lsprj',
'listcon': 'lscon',
'listcontext': 'lscon',
'listcontexts': 'lscon',
},
}
self.config = {}
self.cp = configparser.ConfigParser(self.defaults)
self.cp = configparser.ConfigParser()
for section in self.defaults:
self.cp.add_section(section)
for option, value in iteritems(self.defaults[section]):
self.cp.set(section, option, value)
files = [
"/etc/topydo.conf",
......@@ -129,7 +154,7 @@ class _Config:
try:
return self.cp.getboolean('topydo', 'colors')
except ValueError:
return self.defaults['colors'] == '1'
return self.defaults['topydo']['colors'] == '1'
def todotxt(self):
return os.path.expanduser(self.cp.get('topydo', 'filename'))
......@@ -147,25 +172,25 @@ class _Config:
value = 0
return value
except ValueError:
return int(self.defaults['backup_count'])
return int(self.defaults['topydo']['backup_count'])
def list_limit(self):
try:
return self.cp.getint('ls', 'list_limit')
except ValueError:
return int(self.defaults['list_limit'])
return int(self.defaults['ls']['list_limit'])
def list_indent(self):
try:
return self.cp.getint('ls', 'indent')
except ValueError:
return int(self.defaults['indent'])
return int(self.defaults['ls']['indent'])
def keep_sorted(self):
try:
return self.cp.getboolean('sort', 'keep_sorted')
except ValueError:
return self.defaults['keep_sorted'] == '1'
return self.defaults['sort']['keep_sorted'] == '1'
def sort_string(self):
return self.cp.get('sort', 'sort_string')
......@@ -174,19 +199,19 @@ class _Config:
try:
return self.cp.getboolean('sort', 'ignore_weekends')
except ValueError:
return self.defaults['ignore_weekends'] == '1'
return self.defaults['sort']['ignore_weekends'] == '1'
def append_parent_projects(self):
try:
return self.cp.getboolean('dep', 'append_parent_projects')
except ValueError:
return self.defaults['append_parent_projects'] == '1'
return self.defaults['dep']['append_parent_projects'] == '1'
def append_parent_contexts(self):
try:
return self.cp.getboolean('dep', 'append_parent_contexts')
except ValueError:
return self.defaults['append_parent_contexts'] == '1'
return self.defaults['dep']['append_parent_contexts'] == '1'
def _get_tag(self, p_tag):
try:
......@@ -232,7 +257,7 @@ class _Config:
else:
pri_colors_dict = _str_to_dict(pri_colors_str)
except ValueError:
pri_colors_dict = _str_to_dict(self.defaults['priority_colors'])
pri_colors_dict = _str_to_dict(self.defaults['colorscheme']['priority_colors'])
return pri_colors_dict
......@@ -240,31 +265,47 @@ class _Config:
try:
return self.cp.get('colorscheme', 'project_color')
except ValueError:
return int(self.defaults['project_color'])
return int(self.defaults['colorscheme']['project_color'])
def context_color(self):
try:
return self.cp.get('colorscheme', 'context_color')
except ValueError:
return int(self.defaults['context_color'])
return int(self.defaults['colorscheme']['context_color'])
def metadata_color(self):
try:
return self.cp.get('colorscheme', 'metadata_color')
except ValueError:
return int(self.defaults['metadata_color'])
return int(self.defaults['colorscheme']['metadata_color'])
def link_color(self):
try:
return self.cp.get('colorscheme', 'link_color')
except ValueError:
return int(self.defaults['link_color'])
return int(self.defaults['colorscheme']['link_color'])
def auto_creation_date(self):
try:
return self.cp.getboolean('add', 'auto_creation_date')
except ValueError:
return self.defaults['auto_creation_date'] == '1'
return self.defaults['add']['auto_creation_date'] == '1'
def aliases(self):
"""
Returns dict with aliases names as keys and pairs of actual
subcommand and alias args as values.
"""
aliases = self.cp.items('aliases')
alias_dict = dict()
for alias, meaning in aliases:
meaning = meaning.split()
real_subcommand = meaning[0]
alias_args = meaning[1:]
alias_dict[alias] = (real_subcommand, alias_args)
return alias_dict
def config(p_path=None, p_overrides=None):
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment