1 from __future__
import absolute_import
, division
, print_function
, unicode_literals
4 from qtpy
import QtCore
5 from qtpy
.QtCore
import Signal
10 from ..cmd
import Command
13 AUTOCOMPLETE_PATHS
= 'cola.autocompletepaths'
14 AUTOTEMPLATE
= 'cola.autoloadcommittemplate'
15 BACKGROUND_EDITOR
= 'cola.backgroundeditor'
16 BLAME_VIEWER
= 'cola.blameviewer'
17 BLOCK_CURSOR
= 'cola.blockcursor'
18 BOLD_HEADERS
= 'cola.boldheaders'
19 CHECK_CONFLICTS
= 'cola.checkconflicts'
20 CHECK_PUBLISHED_COMMITS
= 'cola.checkpublishedcommits'
21 COMMENT_CHAR
= 'core.commentchar'
22 DIFFCONTEXT
= 'gui.diffcontext'
23 DIFFTOOL
= 'diff.tool'
24 DISPLAY_UNTRACKED
= 'gui.displayuntracked'
26 ENABLE_GRAVATAR
= 'cola.gravatar'
27 EXPANDTAB
= 'cola.expandtab'
28 FONTDIFF
= 'cola.fontdiff'
30 HISTORY_BROWSER
= 'gui.historybrowser'
31 ICON_THEME
= 'cola.icontheme'
32 LINEBREAK
= 'cola.linebreak'
33 MAXRECENT
= 'cola.maxrecent'
34 MERGE_DIFFSTAT
= 'merge.diffstat'
35 MERGE_KEEPBACKUP
= 'merge.keepbackup'
36 MERGE_SUMMARY
= 'merge.summary'
37 MERGE_VERBOSITY
= 'merge.verbosity'
38 MERGETOOL
= 'merge.tool'
39 MOUSE_ZOOM
= 'cola.mousezoom'
40 RESIZE_BROWSER_COLUMNS
= 'cola.resizebrowsercolumns'
41 SAFE_MODE
= 'cola.safemode'
42 SAVEWINDOWSETTINGS
= 'cola.savewindowsettings'
43 SHOW_PATH
= 'cola.showpath'
44 SORT_BOOKMARKS
= 'cola.sortbookmarks'
45 SPELL_CHECK
= 'cola.spellcheck'
46 STATUS_INDENT
= 'cola.statusindent'
47 STATUS_SHOW_TOTALS
= 'cola.statusshowtotals'
49 TABWIDTH
= 'cola.tabwidth'
50 TEXTWIDTH
= 'cola.textwidth'
51 USER_EMAIL
= 'user.email'
52 USER_NAME
= 'user.name'
55 class Defaults(object):
56 """Read-only class for holding defaults that get overridden"""
58 # These should match Git's defaults for git-defined values.
60 blame_viewer
= 'git gui blame'
63 check_conflicts
= True
64 check_published_commits
= True
66 display_untracked
= True
70 enable_gravatar
= True
72 history_browser
= 'gitk'
73 icon_theme
= 'default'
78 merge_keep_backup
= True
82 resize_browser_columns
= False
83 save_window_settings
= True
85 autocomplete_paths
= True
92 hidpi
= hidpi
.Option
.AUTO
94 status_show_totals
= False
97 def blame_viewer(context
):
98 """Return the configured "blame" viewer"""
99 default
= Defaults
.blame_viewer
100 return context
.cfg
.get(BLAME_VIEWER
, default
=default
)
103 def block_cursor(context
):
104 """Should we display a block cursor in diff editors?"""
105 return context
.cfg
.get(BLOCK_CURSOR
, default
=Defaults
.block_cursor
)
108 def bold_headers(context
):
109 """Should we bold the Status column headers?"""
110 return context
.cfg
.get(BOLD_HEADERS
, default
=Defaults
.bold_headers
)
113 def check_conflicts(context
):
114 """Should we check for merge conflict markers in unmerged files?"""
115 return context
.cfg
.get(CHECK_CONFLICTS
, default
=Defaults
.check_conflicts
)
118 def check_published_commits(context
):
119 """Should we check for published commits when amending?"""
120 return context
.cfg
.get(
121 CHECK_PUBLISHED_COMMITS
, default
=Defaults
.check_published_commits
125 def display_untracked(context
):
126 """Should we display untracked files?"""
127 return context
.cfg
.get(DISPLAY_UNTRACKED
, default
=Defaults
.display_untracked
)
131 """Return the configured editor"""
132 app
= context
.cfg
.get(EDITOR
, default
=fallback_editor())
133 return _remap_editor(app
)
136 def background_editor(context
):
137 """Return the configured non-blocking background editor"""
138 app
= context
.cfg
.get(BACKGROUND_EDITOR
, default
=editor(context
))
139 return _remap_editor(app
)
142 def fallback_editor():
143 """Return a fallback editor for cases where one is not configured
145 GIT_VISUAL and VISUAL are consulted before GIT_EDITOR and EDITOR to allow
146 configuring a visual editor for Git Cola using $GIT_VISUAL and an alternative
147 editor for the Git CLI.
155 for env
in editor_variables
:
156 env_editor
= core
.getenv(env
)
160 return Defaults
.editor
163 def _remap_editor(app
):
164 """Remap a configured editor into a visual editor name"""
165 # We do this for vim users because this configuration is convenient for new users.
168 'nvim': 'nvim-qt --nofork',
172 def comment_char(context
):
173 """Return the configured git commit comment character"""
174 return context
.cfg
.get(COMMENT_CHAR
, default
=Defaults
.comment_char
)
177 def enable_gravatar(context
):
178 """Is gravatar enabled?"""
179 return context
.cfg
.get(ENABLE_GRAVATAR
, default
=Defaults
.enable_gravatar
)
182 def default_history_browser():
183 """Return the default history browser (e.g. git-dag, gitk)"""
185 # On Windows, a sensible default is "python git-cola dag"
186 # which is different than `gitk` below, but is preferred
187 # because we don't have to guess paths.
188 git_cola
= sys
.argv
[0].replace('\\', '/')
189 python
= sys
.executable
.replace('\\', '/')
190 cwd
= core
.getcwd().replace('\\', '/')
191 argv
= [python
, git_cola
, 'dag', '--repo', cwd
]
192 argv
= core
.prep_for_subprocess(argv
)
193 default
= core
.list2cmdline(argv
)
195 # The `gitk` script can be launched as-is on unix
196 default
= Defaults
.history_browser
200 def history_browser(context
):
201 """Return the configured history browser"""
202 default
= default_history_browser()
203 return context
.cfg
.get(HISTORY_BROWSER
, default
=default
)
206 def linebreak(context
):
207 """Should we word-wrap lines in the commit message editor?"""
208 return context
.cfg
.get(LINEBREAK
, default
=Defaults
.linebreak
)
211 def maxrecent(context
):
212 """Return the configured maximum number of Recent Repositories"""
213 value
= Defaults
.maxrecent
215 value
= context
.cfg
.get(MAXRECENT
, default
=value
)
219 def mouse_zoom(context
):
220 """Should we zoom text when using Ctrl + MouseWheel scroll"""
221 return context
.cfg
.get(MOUSE_ZOOM
, default
=Defaults
.mouse_zoom
)
224 def spellcheck(context
):
225 """Should we spellcheck commit messages?"""
226 return context
.cfg
.get(SPELL_CHECK
, default
=Defaults
.spellcheck
)
229 def expandtab(context
):
230 """Should we expand tabs in commit messages?"""
231 return context
.cfg
.get(EXPANDTAB
, default
=Defaults
.expandtab
)
234 def sort_bookmarks(context
):
235 """Should we sort bookmarks by name?"""
236 return context
.cfg
.get(SORT_BOOKMARKS
, default
=Defaults
.sort_bookmarks
)
239 def tabwidth(context
):
240 """Return the configured tab width in the commit message editor"""
241 return context
.cfg
.get(TABWIDTH
, default
=Defaults
.tabwidth
)
244 def textwidth(context
):
245 """Return the configured text width for word wrapping commit messages"""
246 return context
.cfg
.get(TEXTWIDTH
, default
=Defaults
.textwidth
)
249 def status_indent(context
):
250 """Should we indent items in the status widget?"""
251 return context
.cfg
.get(STATUS_INDENT
, default
=Defaults
.status_indent
)
254 def status_show_totals(context
):
255 """Should we display count totals in the status widget headers?"""
256 return context
.cfg
.get(STATUS_SHOW_TOTALS
, default
=Defaults
.status_show_totals
)
259 class PreferencesModel(QtCore
.QObject
):
260 """Interact with repo-local and user-global git config preferences"""
262 config_updated
= Signal(str, str, object)
264 def __init__(self
, context
):
265 super(PreferencesModel
, self
).__init
__()
266 self
.context
= context
267 self
.config
= context
.cfg
269 def set_config(self
, source
, config
, value
):
270 """Set a configuration value"""
271 if source
== 'local':
272 self
.config
.set_repo(config
, value
)
274 self
.config
.set_user(config
, value
)
275 self
.config_updated
.emit(source
, config
, value
)
277 def get_config(self
, source
, config
):
278 """Get a configured value"""
279 if source
== 'local':
280 value
= self
.config
.get_repo(config
)
282 value
= self
.config
.get(config
)
286 class SetConfig(Command
):
287 """Store a gitconfig value"""
291 def __init__(self
, model
, source
, config
, value
):
295 self
.old_value
= None
299 """Modify the model and store the updated configuration"""
300 self
.old_value
= self
.model
.get_config(self
.source
, self
.config
)
301 self
.model
.set_config(self
.source
, self
.config
, self
.value
)
304 """Restore the configuration change to its original value"""
305 if self
.old_value
is None:
307 self
.model
.set_config(self
.source
, self
.config
, self
.old_value
)