3 from qtpy
import QtCore
4 from qtpy
.QtCore
import Signal
9 from ..cmd
import Command
12 AUTOCOMPLETE_PATHS
= 'cola.autocompletepaths'
13 AUTOTEMPLATE
= 'cola.autoloadcommittemplate'
14 BACKGROUND_EDITOR
= 'cola.backgroundeditor'
15 BLAME_VIEWER
= 'cola.blameviewer'
16 BLOCK_CURSOR
= 'cola.blockcursor'
17 BOLD_HEADERS
= 'cola.boldheaders'
18 CHECK_CONFLICTS
= 'cola.checkconflicts'
19 CHECK_PUBLISHED_COMMITS
= 'cola.checkpublishedcommits'
20 COMMENT_CHAR
= 'core.commentchar'
21 COMMIT_CLEANUP
= 'commit.cleanup'
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 INOTIFY
= 'cola.inotify'
33 LINEBREAK
= 'cola.linebreak'
34 LOGDATE
= 'cola.logdate'
35 MAXRECENT
= 'cola.maxrecent'
36 MERGE_DIFFSTAT
= 'merge.diffstat'
37 MERGE_KEEPBACKUP
= 'merge.keepbackup'
38 MERGE_SUMMARY
= 'merge.summary'
39 MERGE_VERBOSITY
= 'merge.verbosity'
40 MERGETOOL
= 'merge.tool'
41 MOUSE_ZOOM
= 'cola.mousezoom'
42 PATCHES_DIRECTORY
= 'cola.patchesdirectory'
43 REFRESH_ON_FOCUS
= 'cola.refreshonfocus'
44 RESIZE_BROWSER_COLUMNS
= 'cola.resizebrowsercolumns'
45 SAFE_MODE
= 'cola.safemode'
46 SAVEWINDOWSETTINGS
= 'cola.savewindowsettings'
47 SHOW_PATH
= 'cola.showpath'
48 SORT_BOOKMARKS
= 'cola.sortbookmarks'
49 SPELL_CHECK
= 'cola.spellcheck'
50 STATUS_INDENT
= 'cola.statusindent'
51 STATUS_SHOW_TOTALS
= 'cola.statusshowtotals'
53 TABWIDTH
= 'cola.tabwidth'
54 TEXTWIDTH
= 'cola.textwidth'
55 USER_EMAIL
= 'user.email'
56 USER_NAME
= 'user.name'
64 ISO_STRICT
= 'iso8601-strict'
73 """Return valid values for git config cola.logdate"""
79 DateFormat
.ISO_STRICT
,
88 def commit_cleanup_modes():
89 """Return valid values for the git config commit.cleanup"""
100 """Read-only class for holding defaults that get overridden"""
102 # These should match Git's defaults for git-defined values.
104 blame_viewer
= 'git gui blame'
107 check_conflicts
= True
108 check_published_commits
= True
110 commit_cleanup
= 'default'
111 display_untracked
= True
115 enable_gravatar
= True
117 history_browser
= 'gitk'
118 icon_theme
= 'default'
123 merge_diffstat
= True
124 merge_keep_backup
= True
128 refresh_on_focus
= False
129 resize_browser_columns
= False
130 save_window_settings
= True
132 autocomplete_paths
= True
134 sort_bookmarks
= True
139 hidpi
= hidpi
.Option
.AUTO
140 patches_directory
= 'patches'
141 status_indent
= False
142 status_show_totals
= False
143 logdate
= DateFormat
.DEFAULT
146 def blame_viewer(context
):
147 """Return the configured "blame" viewer"""
148 default
= Defaults
.blame_viewer
149 return context
.cfg
.get(BLAME_VIEWER
, default
=default
)
152 def block_cursor(context
):
153 """Should we display a block cursor in diff editors?"""
154 return context
.cfg
.get(BLOCK_CURSOR
, default
=Defaults
.block_cursor
)
157 def bold_headers(context
):
158 """Should we bold the Status column headers?"""
159 return context
.cfg
.get(BOLD_HEADERS
, default
=Defaults
.bold_headers
)
162 def check_conflicts(context
):
163 """Should we check for merge conflict markers in unmerged files?"""
164 return context
.cfg
.get(CHECK_CONFLICTS
, default
=Defaults
.check_conflicts
)
167 def check_published_commits(context
):
168 """Should we check for published commits when amending?"""
169 return context
.cfg
.get(
170 CHECK_PUBLISHED_COMMITS
, default
=Defaults
.check_published_commits
174 def display_untracked(context
):
175 """Should we display untracked files?"""
176 return context
.cfg
.get(DISPLAY_UNTRACKED
, default
=Defaults
.display_untracked
)
180 """Return the configured editor"""
181 app
= context
.cfg
.get(EDITOR
, default
=fallback_editor())
182 return _remap_editor(app
)
185 def background_editor(context
):
186 """Return the configured non-blocking background editor"""
187 app
= context
.cfg
.get(BACKGROUND_EDITOR
, default
=editor(context
))
188 return _remap_editor(app
)
191 def fallback_editor():
192 """Return a fallback editor for cases where one is not configured
194 GIT_VISUAL and VISUAL are consulted before GIT_EDITOR and EDITOR to allow
195 configuring a visual editor for Git Cola using $GIT_VISUAL and an alternative
196 editor for the Git CLI.
204 for env
in editor_variables
:
205 env_editor
= core
.getenv(env
)
209 return Defaults
.editor
212 def _remap_editor(app
):
213 """Remap a configured editor into a visual editor name"""
214 # We do this for vim users because this configuration is convenient for new users.
217 'nvim': 'nvim-qt --nofork',
221 def comment_char(context
):
222 """Return the configured git commit comment character"""
223 return context
.cfg
.get(COMMENT_CHAR
, default
=Defaults
.comment_char
)
226 def commit_cleanup(context
):
227 """Return the configured git commit cleanup mode"""
228 return context
.cfg
.get(COMMIT_CLEANUP
, default
=Defaults
.commit_cleanup
)
231 def enable_gravatar(context
):
232 """Is gravatar enabled?"""
233 return context
.cfg
.get(ENABLE_GRAVATAR
, default
=Defaults
.enable_gravatar
)
236 def default_history_browser():
237 """Return the default history browser (e.g. git-dag, gitk)"""
239 # On Windows, a sensible default is "python git-cola dag"
240 # which is different than `gitk` below, but is preferred
241 # because we don't have to guess paths.
242 git_cola
= sys
.argv
[0].replace('\\', '/')
243 python
= sys
.executable
.replace('\\', '/')
244 cwd
= core
.getcwd().replace('\\', '/')
245 argv
= [python
, git_cola
, 'dag', '--repo', cwd
]
246 argv
= core
.prep_for_subprocess(argv
)
247 default
= core
.list2cmdline(argv
)
249 # The `gitk` script can be launched as-is on unix
250 default
= Defaults
.history_browser
254 def history_browser(context
):
255 """Return the configured history browser"""
256 default
= default_history_browser()
257 return context
.cfg
.get(HISTORY_BROWSER
, default
=default
)
260 def linebreak(context
):
261 """Should we word-wrap lines in the commit message editor?"""
262 return context
.cfg
.get(LINEBREAK
, default
=Defaults
.linebreak
)
265 def logdate(context
):
266 """Return the configured log date format"""
267 return context
.cfg
.get(LOGDATE
, default
=Defaults
.logdate
)
270 def maxrecent(context
):
271 """Return the configured maximum number of Recent Repositories"""
272 value
= Defaults
.maxrecent
274 value
= context
.cfg
.get(MAXRECENT
, default
=value
)
278 def mouse_zoom(context
):
279 """Should we zoom text when using Ctrl + MouseWheel scroll"""
280 return context
.cfg
.get(MOUSE_ZOOM
, default
=Defaults
.mouse_zoom
)
283 def spellcheck(context
):
284 """Should we spellcheck commit messages?"""
285 return context
.cfg
.get(SPELL_CHECK
, default
=Defaults
.spellcheck
)
288 def expandtab(context
):
289 """Should we expand tabs in commit messages?"""
290 return context
.cfg
.get(EXPANDTAB
, default
=Defaults
.expandtab
)
293 def patches_directory(context
):
294 """Return the patches output directory"""
295 return context
.cfg
.get(PATCHES_DIRECTORY
, default
=Defaults
.patches_directory
)
298 def sort_bookmarks(context
):
299 """Should we sort bookmarks by name?"""
300 return context
.cfg
.get(SORT_BOOKMARKS
, default
=Defaults
.sort_bookmarks
)
303 def tabwidth(context
):
304 """Return the configured tab width in the commit message editor"""
305 return context
.cfg
.get(TABWIDTH
, default
=Defaults
.tabwidth
)
308 def textwidth(context
):
309 """Return the configured text width for word wrapping commit messages"""
310 return context
.cfg
.get(TEXTWIDTH
, default
=Defaults
.textwidth
)
313 def status_indent(context
):
314 """Should we indent items in the status widget?"""
315 return context
.cfg
.get(STATUS_INDENT
, default
=Defaults
.status_indent
)
318 def status_show_totals(context
):
319 """Should we display count totals in the status widget headers?"""
320 return context
.cfg
.get(STATUS_SHOW_TOTALS
, default
=Defaults
.status_show_totals
)
323 class PreferencesModel(QtCore
.QObject
):
324 """Interact with repo-local and user-global git config preferences"""
326 config_updated
= Signal(str, str, object)
328 def __init__(self
, context
):
330 self
.context
= context
331 self
.config
= context
.cfg
333 def set_config(self
, source
, config
, value
):
334 """Set a configuration value"""
335 if source
== 'local':
336 self
.config
.set_repo(config
, value
)
338 self
.config
.set_user(config
, value
)
339 self
.config_updated
.emit(source
, config
, value
)
341 def get_config(self
, source
, config
):
342 """Get a configured value"""
343 if source
== 'local':
344 value
= self
.config
.get_repo(config
)
346 value
= self
.config
.get(config
)
350 class SetConfig(Command
):
351 """Store a gitconfig value"""
355 def __init__(self
, model
, source
, config
, value
):
359 self
.old_value
= None
363 """Modify the model and store the updated configuration"""
364 self
.old_value
= self
.model
.get_config(self
.source
, self
.config
)
365 self
.model
.set_config(self
.source
, self
.config
, self
.value
)
368 """Restore the configuration change to its original value"""
369 if self
.old_value
is None:
371 self
.model
.set_config(self
.source
, self
.config
, self
.old_value
)