77-- luacheck: globals uah_color cwd_color lamb_color clean_color dirty_color conflict_color unknown_color
88-- luacheck: globals prompt_homeSymbol prompt_lambSymbol prompt_type prompt_useHomeSymbol prompt_useUserAtHost
99-- luacheck: globals prompt_singleLine prompt_includeVersionControl
10- -- luacheck: globals prompt_overrideGitStatusOptIn prompt_overrideSvnStatusOptIn
10+ -- luacheck: globals prompt_overrideGitStatusOptIn
1111-- luacheck: globals clink io.popenyield os.isdir settings.get
1212
1313-- At first, load the original clink.lua file
350350-- @return {false|mercurial branch information}
351351---
352352local function get_hg_branch ()
353- -- Return the branch information. The default is to get just the
354- -- branch name, but you could e.g. use the "hg-prompt" extension to
355- -- get more information, such as any applied mq patches. Here's an
356- -- example of that:
357- -- local cmd = "hg prompt \"{branch}{status}{|{patch}}{update}\""
358- local cmd = " hg branch 2>nul"
359- local file = io.popen (cmd )
353+ -- Return the branch information.
354+ local file = io.popen (" hg branch 2>nul" )
360355 if not file then
361356 return false
362357 end
@@ -424,12 +419,33 @@ local function get_git_status()
424419 return { status = is_status , conflict = conflict_found }
425420end
426421
422+ ---
423+ -- Get the status of working dir
424+ -- @return {bool}
425+ ---
426+ local function get_hg_status ()
427+ -- The default is to just use the branch name, but you could e.g. use the
428+ -- "hg-prompt" extension to get more information, such as any applied mq
429+ -- patches. Here's an example of that:
430+ -- "hg prompt \"{branch}{status}{|{patch}}{update}\""
431+ local pipe = io_popenyield (" hg status -amrd 2>&1" )
432+ if not pipe then
433+ return { error = true }
434+ end
435+
436+ local output = pipe :read (' *all' )
437+ pipe :close ()
438+
439+ local dirty = (output ~= nil and output ~= " " )
440+ return { clean = not dirty }
441+ end
442+
427443---
428444-- Get the status of working dir
429445-- @return {bool}
430446---
431447local function get_svn_status ()
432- local file = io_popenyield (" svn status -q" )
448+ local file = io_popenyield (" svn status -q 2>nul " )
433449 if not file then
434450 return { error = true }
435451 end
@@ -520,14 +536,6 @@ local function git_prompt_filter()
520536 return false
521537 end
522538
523- -- Colors for git status
524- local colors = {
525- clean = get_clean_color (),
526- dirty = get_dirty_color (),
527- conflict = get_conflict_color (),
528- nostatus = get_unknown_color ()
529- }
530-
531539 local git_dir = get_git_dir ()
532540 local color
533541 if git_dir then
@@ -547,18 +555,19 @@ local function git_prompt_filter()
547555 local gitConflict = gitInfo .conflict
548556
549557 if gitStatus == nil then
550- color = colors . nostatus
558+ color = get_unknown_color ()
551559 elseif gitStatus then
552- color = colors . clean
560+ color = get_clean_color ()
553561 else
554- color = colors . dirty
562+ color = get_dirty_color ()
555563 end
556564
557565 if gitConflict then
558- color = colors . conflict
566+ color = get_conflict_color ()
559567 end
560568
561- clink .prompt .value = gsub_plain (clink .prompt .value , " {git}" , " " .. color .. " (" .. branch .. " )" )
569+ local result = " " .. color .. " (" .. branch .. " )"
570+ clink .prompt .value = gsub_plain (clink .prompt .value , " {git}" , result )
562571 return false
563572 end
564573 end
@@ -568,6 +577,18 @@ local function git_prompt_filter()
568577 return false
569578end
570579
580+ local function get_hg_info_table ()
581+ local info = clink_promptcoroutine (function ()
582+ return get_hg_status () or {}
583+ end )
584+ if not info then
585+ info = cached_info .hg_info or {}
586+ else
587+ cached_info .hg_info = info
588+ end
589+ return info
590+ end
591+
571592local function hg_prompt_filter ()
572593
573594 -- Don't do any hg processing if the prompt doesn't want to show hg info.
@@ -577,33 +598,34 @@ local function hg_prompt_filter()
577598
578599 local hg_dir = get_hg_dir ()
579600 if hg_dir then
580- -- Colors for mercurial status
581- local colors = {
582- clean = get_clean_color (),
583- dirty = get_dirty_color (),
584- nostatus = get_unknown_color ()
585- }
586- local output = get_hg_branch ()
587-
588- -- strip the trailing newline from the branch name
589- local n = # output
590- while n > 0 and output :find (" ^%s" , n ) do n = n - 1 end
591- local branch = output :sub (1 , n )
601+ local output = get_hg_branch () or " "
602+
603+ -- strip the trailing spaces and newline from the branch name
604+ local branch = output :gsub (" %s+$" , " " )
592605
593606 if branch ~= nil and
594607 string.sub (branch ,1 ,7 ) ~= " abort: " and -- not an HG working copy
595608 (not string.find (branch , " is not recognized" )) then -- 'hg' not in path
596- local color = colors .clean
609+ -- If in a different repo or branch than last time, discard cached info
610+ if cached_info .hg_dir ~= hg_dir or cached_info .hg_branch ~= branch then
611+ cached_info .hg_info = nil
612+ cached_info .hg_dir = hg_dir
613+ cached_info .hg_branch = branch
614+ end
597615
598- local pipe = io.popen (" hg status -amrd 2>&1" )
599- if pipe then
600- output = pipe :read (' *all' )
601- pipe :close ()
602- if output ~= nil and output ~= " " then color = colors .dirty end
616+ local hgInfo = get_hg_info_table ()
617+
618+ local color
619+ if not hgInfo or hgInfo .error then
620+ color = get_unknown_color ()
621+ elseif hgInfo .clean then
622+ color = get_clean_color ()
623+ else
624+ color = get_dirty_color ()
603625 end
604626
605- local result = color .. " (" .. branch .. " )"
606- clink .prompt .value = gsub_plain (clink .prompt .value , " {hg}" , " " .. result )
627+ local result = " " .. color .. " (" .. branch .. " )"
628+ clink .prompt .value = gsub_plain (clink .prompt .value , " {hg}" , result )
607629 return false
608630 end
609631 end
@@ -612,20 +634,25 @@ local function hg_prompt_filter()
612634 clink .prompt .value = gsub_plain (clink .prompt .value , " {hg}" , " " )
613635end
614636
637+ local function get_svn_info_table ()
638+ local info = clink_promptcoroutine (function ()
639+ return get_svn_status () or {}
640+ end )
641+ if not info then
642+ info = cached_info .svn_info or {}
643+ else
644+ cached_info .svn_info = info
645+ end
646+ return info
647+ end
648+
615649local function svn_prompt_filter ()
616650
617651 -- Don't do any svn processing if the prompt doesn't want to show svn info.
618652 if not clink .prompt .value :find (" {svn}" ) then
619653 return false
620654 end
621655
622- -- Colors for svn status
623- local colors = {
624- clean = get_clean_color (),
625- dirty = get_dirty_color (),
626- nostatus = get_unknown_color ()
627- }
628-
629656 local svn_dir = get_svn_dir ()
630657 if svn_dir then
631658 -- if we're inside of svn repo then try to detect current branch
@@ -637,29 +664,16 @@ local function svn_prompt_filter()
637664 cached_info .svn_dir = svn_dir
638665 cached_info .svn_branch = branch
639666 end
640- -- Get the svn status using coroutine if available and option is enabled. Otherwise use a blocking call
641- local svnStatus
642- if clink .promptcoroutine and io .popenyield and settings .get (" prompt.async" ) and prompt_overrideSvnStatusOptIn then -- luacheck: no max line length
643- svnStatus = clink_promptcoroutine (function ()
644- return get_svn_status ()
645- end )
646- -- If the status result is pending, use the cached version instead, otherwise store it to the cache
647- if svnStatus == nil then
648- svnStatus = cached_info .svn_info
649- else
650- cached_info .svn_info = svnStatus
651- end
652- else
653- svnStatus = get_svn_status ()
654- end
667+
668+ local svnInfo = get_svn_info_table ()
655669
656670 local color
657- if not svnStatus or svnStatus .error then
658- color = colors . nostatus
659- elseif svnStatus .clean then
660- color = colors . clean
671+ if not svnInfo or svnInfo .error then
672+ color = get_unknown_color ()
673+ elseif svnInfo .clean then
674+ color = get_clean_color ()
661675 else
662- color = colors . dirty
676+ color = get_dirty_color ()
663677 end
664678
665679 clink .prompt .value = gsub_plain (clink .prompt .value , " {svn}" , " " .. color .. " (" .. branch .. " )" )
0 commit comments