
    Jeۏ                        d Z ddlZddlZddlZddlmZ ddlZddlm	Z	 ddl
mZ ddlmZmZ ddlmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZmZ ddlmZmZmZm Z  ddl!m"Z"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z: ddl;m<Z<m=Z=m>Z>  ej~                  e@      ZA G d d      ZB G d d      ZC G d d      ZDe> G d de             ZEy)z
Projects Plugin

It handles closing, opening and switching among projetcs and also
updating the file tree explorer associated with a project
    N)OrderedDict)getexistingdirectory)SignalSlot)QInputDialogQMessageBox)SpyderAPIError)on_plugin_availableon_plugin_teardown_)PluginsSpyderDockablePlugin)get_home_dirget_project_config_folderrunning_in_mac_apprunning_under_pytest)is_text_stringto_text_stringencoding)ima)getcwd_or_home)ApplicationMenusProjectsMenuSections)BaseProjectTypeEmptyProject	WORKSPACE)WorkspaceWatcher)ProjectExplorerWidget)ProjectDialog)CompletionRequestTypesFileChangeTypeWorkspaceUpdateKind)requesthandlesclass_registerc                       e Zd ZdZy)ProjectsMenuSubmenusrecent_projectsN)__name__
__module____qualname__RecentProjects     @/usr/lib/python3/dist-packages/spyder/plugins/projects/plugin.pyr)   r)   7   s    &Nr0   r)   c                   $    e Zd ZdZdZdZdZdZdZy)ProjectsActionsnew_project_actionopen_project_actionclose_project_actiondelete_project_actionclear_recent_projects_actionmax_recent_actionN)	r+   r,   r-   
NewProjectOpenProjectCloseProjectDeleteProjectClearRecentProjects	MaxRecentr/   r0   r1   r3   r3   ;   s!    %J'K)L+M8#Ir0   r3   c                       e Zd ZdZdZy)RecentProjectsMenuSectionsrecent_sectionextras_sectionN)r+   r,   r-   RecentExtrasr/   r0   r1   rA   rA   D   s    FFr0   rA   c                       e Zd ZdZdZeZdZg Zej                  ej                  ej                  ej                  gZeZ eeee      Z	  ee      Z	  eefef      Z	 dF fd	Zed        Zd Zd Zd	 Z eej                  
      d        Z eej                  
      d        Z eej                  
      d        Z  eej                  
      d        Z! e"ej                  
      d        Z# e"ej                  
      d        Z$ e"ej                  
      d        Z% e"ej                  
      d        Z&d Z'd Z(d Z)dGdZ*d Z+d Z,d Z- e.       d        Z/e0jb                  dfdZ2	 	 dHdZ3d Z4d Z5d Z6d  Z7d! Z8d" Z9d# Z:d$ Z;d% Z<d& Z=d' Z>d( Z?d) Z@d* ZAd+ ZBd, ZCd- ZDd. ZEd/ ZFd0 ZGd1 ZHd2 ZI e.eeJ      d3        ZK e.eee       eLeMj                  d4      d5               ZO eLeMj                  d4       e.ee      d6               ZP eLeMj                  d4       e.ee      d7               ZQ eLeMj                  d4       e.ee      d8               ZR eLeMj                  d4      d9        ZT eLeMj                  d4      d:        ZU eVeMj                         eLeMj                  d4      d;               ZXd< ZYd= ZZd> Z[d? Z\d@ Z]dA Z^dB Z_dC Z`dD ZadE Zb xZcS )IProjectszProjects plugin.project_explorerFNc                 L   t         |   ||       | j                  dg       | _        d| _        d| _        t        |       | _        d| _        | j                         j                  | j                                | j                  j                  |        t               | _        y)zInitialization.r*   NF)super__init__get_confr*   current_active_projectlatest_projectr   watchercompletions_available
get_widgetsetup_projectget_active_project_pathconnect_signalsr   _project_types)selfparentconfiguration	__class__s      r1   rK   zProjects.__init__{   s    /#}}->C&*#"'-%*"''(D(D(FG$$T*)mr0   c                      t        d      S )NrG   r   r/   r0   r1   get_namezProjects.get_name   s    }r0   c                     t        d      S )Nz.Create Spyder projects and manage their files.r   rV   s    r1   get_descriptionzProjects.get_description   s    ABBr0   c                 $    | j                  d      S )Nproject)create_iconr]   s    r1   get_iconzProjects.get_icon   s    	**r0   c                      j                         }|j                  }d _        d _        d _        |j
                  j                   j                         |j                  j                   j                          j                  j                   fd        j                  j                   j                          j                  r|j                  j                   j                  j                          j                  j                   fd        j                  j                   fd        j                  j                   j                   j                           j#                   t$                j'                          y)z'Register plugin in Spyder's main windowNc                 $    j                         S N)show_explorer)plugincheckrV   s     r1   <lambda>z(Projects.on_initialize.<locals>.<lambda>   s    $"4"4"6 r0   c                 8    j                   j                         S re   mainset_window_titlevrV   s    r1   ri   z(Projects.on_initialize.<locals>.<lambda>       $))446 r0   c                 8    j                   j                         S re   rk   rn   s    r1   ri   z(Projects.on_initialize.<locals>.<lambda>   rp   r0   )rQ   
treewidget
ipyconsoleeditorcompletionssig_delete_projectconnectdelete_projectsig_redirect_stdio_requestedsig_switch_to_plugin_requestedsig_project_loadedupdate_explorerrl   sig_open_file_requested	open_filesig_project_closedrestore_scrollbar_positionregister_project_typer   setuprV   widgetrr   s   `  r1   on_initializezProjects.on_initialize   s'   "&&
%%--d.A.AB//77--	/++336	8''(<(<=99**224993F3FG##++68##++68II0088//1 	""46

r0   )rg   c                 n   | j                  t        j                        | _        | j	                         }|j
                  }|j                  j                  | j                  j                         |j                  j                  | j                  j                         |j                  j                  | j                  j                         |j                  j                  | j                  j                         |j                  j                  | j                  j                          |j"                  j                  | j                  j$                         |j&                  j                  | j(                         | j*                  j                  | j,                         | j.                  t0           j                  | j,                         | j                  j3                  |        | j*                  j                  | j4                         | j.                  j                  | j6                         y re   )
get_pluginr   Editorrt   rQ   rr   r}   rw   loadsig_removedremovedsig_tree_removedremoved_treesig_renamedrenamedsig_tree_renamedrenamed_treesig_module_creatednewsig_file_created_new_editorr{   _setup_editor_filesr   boolset_projects_set_path_in_editor_unset_path_in_editorr   s      r1   on_editor_availablezProjects.on_editor_available   sx   oognn5"&&
**224;;3C3CD&&t{{':':;##++DKK,D,DE&&t{{':':;##++DKK,D,DE%%--dkkoo>##++D,<,<=''(@(@A%--d.F.FG  &''(@(@A''(B(BCr0   c                 >   | j                  t        j                        | _        | j                  j                  j                  | j                         | j                  j                  | j                         | j                  j                  | j                         y re   )r   r   Completionsru   sig_stop_completionsrw   stop_workspace_servicesr{   _add_path_to_completionsr   _remove_path_from_completionsr]   s    r1   on_completions_availablez!Projects.on_completions_available   sr    ??7+>+>? 	--55((	*''(E(EF''(J(JKr0   c                 ,   | j                  t        j                        | _        | j	                         }|j
                  }|j                  j                  | j                  j                         |j                  j                  | j                         y re   )r   r   IPythonConsolers   rQ   rr   sig_open_interpreter_requestedrw   create_client_from_pathsig_run_requested_run_file_in_ipyconsoler   s      r1   on_ipython_console_availablez%Projects.on_ipython_console_available   sj    //'*@*@A"&&
1199OO33	5$$,,T-I-IJr0   c                    | j                  t        j                        }| j                  t        j
                        }| j                  t        j                        }|j                  t        j                        }|j                  j                  | j                         |j                  |t        j                  t        j                         || j                   | j"                  fD ]2  }|j                  |t        j                  t        j$                         4 |j                  | j&                  t        j                  t        j(                         y )N)menu_idsection)r   r   MainMenu
get_actionr3   r:   r;   get_application_menur   rG   aboutToShowrw   is_invalid_active_projectadd_item_to_application_menur   Newr6   r7   Openrecent_project_menurE   )rV   	main_menur4   r5   projects_menuitems         r1   on_main_menu_availablezProjects.on_main_menu_available   s   OOG$4$45	!___-G-GH"ooo.I.IJ!66%%'!!))$*H*HI..$--(,, 	/ 	.
 )$*C*C//1 	3D22(11,11 3 3	3 	..$$$--(// 	/ 	1r0   c                 |   | j                  t        j                        | _        | j	                         }|j
                  }|j                  j                  | j                  j                         |j                  j                  | j                  j                         |j                  j                  | j                  j                         |j                  j                  | j                  j                         |j                  j                  | j                  j                          |j"                  j                  | j                  j$                         |j&                  j                  | j(                         | j*                  j                  | j,                         | j.                  t0           j                  | j,                         | j                  j3                  d        | j*                  j                  | j4                         | j.                  j                  | j6                         d | _        y re   )r   r   r   rt   rQ   rr   r}   
disconnectr   r   r   r   r   r   r   r   r   r   r   r   r   r{   r   r   r   r   r   r   r   s      r1   on_editor_teardownzProjects.on_editor_teardown   s   oognn5"&&
**55dkk6F6FG))$++*=*=>##..t{{/G/GH))$++*=*=>##..t{{/G/GH%%00A##..t/?/?@**4+C+CD%001I1IJ  &**4+C+CD**4+E+EFr0   c                 L   | j                  t        j                        | _        | j                  j                  j                  | j                         | j                  j                  | j                         | j                  j                  | j                         d | _        y re   )r   r   r   ru   r   r   r   r{   r   r   r   r]   s    r1   on_completions_teardownz Projects.on_completions_teardown  sz    ??7+>+>?--88((	* 	**4+H+HI**4+M+MNr0   c                 H   | j                  t        j                        | _        | j	                         }|j
                  }|j                  j                  | j                  j                         |j                  j                  | j                         d | _        d | _        y re   )r   r   r   rs   rQ   rr   r   r   r   r   r   _ipython_run_scriptr   s      r1   on_ipython_console_teardownz$Projects.on_ipython_console_teardown  sy    //'*@*@A"&&
11<<OO33	5$$//0L0LM#' r0   c                     | j                  t        j                        }|j                  t        j
                         y re   )r   r   r   remove_application_menur   rG   )rV   r   s     r1   on_main_menu_teardownzProjects.on_main_menu_teardown%  s+    OOG$4$45	))*:*C*CDr0   c                      j                  t        j                  t        d       j                          j                  t        j
                  t        d       fd        j                  t        j                  t        d       j                         _         j                  t        j                  t        d       j                         _         j                  t        j                  t        d       j                         _         j                  t        j                  t        d       j                          _         j%                         j'                  t(        j*                  t        d	             _         j,                  j.                  j1                   j2                          j3                          y
)zSetup the plugin actions.zNew Project...)text	triggeredzOpen Project...c                 $    j                         S re   open_projectrn   s    r1   ri   z Projects.setup.<locals>.<lambda>4  s     1 1 3 r0   zClose ProjectzDelete ProjectzClear this listz$Maximum number of recent projects...zRecent ProjectsN)create_actionr3   r:   r   create_new_projectr;   r<   close_projectr6   r=   rx   r7   r>   clear_recent_projectsr8   r?   change_max_recent_projectsr9   rQ   create_menur)   r.   r   r   rw   setup_menu_actionsr]   s   `r1   r   zProjects.setup*  s   &&#$-- 	 	/
 	''$%3 	 	5
 %)$6$6((?#(( %7 %*!
 &*%7%7))#$)) &8 &+"
 -1,>,>//$%00 -? -2)
 "&!3!3%%9:55 "4 "7
 $(??#4#@#@ // $
  	  ,,44T5L5LM!r0   c           
         | j                   r| j                   D ]  }| j                  |      st        j                  dk(  r|}n|j	                  t               d      }	 | j                  |      }| j                         j                  || j                  t        j                           | j"                  | j$                  fD ]<  }| j                         j                  || j                  t        j&                         > | j)                          y# t        $ r: | j                  ||t        j                  d      | j                  |            }Y w xY w)z"Setup and update the menu actions.nt~r`   )r   iconr   )menur   N)r*   is_valid_projectosnamereplacer   r   KeyErrorr   r   r   build_openerrQ   add_item_to_menur   rA   rD   r8   r9   rE   update_project_actions)rV   r`   r   actionr   s        r1   r   zProjects.setup_menu_actionsQ  s?   // C((1ww$&&|~sC!%!6 OO%66!55 : A A 7 CC( 66++- 	;DOO..--299 / ;	; 	##%% $ !%!3!3 !%!$)!4&*&7&7&@	 "4 "s   DA EEc                 (   | j                   r| j                  j                  d       n| j                  j                  d       t        | j	                               }| j
                  j                  |       | j                  j                  |       y)z#Update actions of the Projects menuTFN)r*   r8   
setEnabledr   rS   r6   r7   )rV   actives     r1   r   zProjects.update_project_actionsp  sn    --88>--88?d2245!!,,V4""--f5r0   c                 X    | j                          | j                  j                          y)z3Perform actions before parent main window is closedT)save_configrO   stop)rV   
cancelables     r1   on_closezProjects.on_close{  s!    r0   c                 b    | j                   r#| j                  t           j                  |        yy)z7Unmaximize the currently maximized plugin, if not self.N)rl   sig_unmaximize_plugin_requestedobjectemitr]   s    r1   
unmaximizezProjects.unmaximize  s'    99008==dC r0   c                       fd}|S )z%Build function opening passed projectc                  *    j                         y )N)pathr   )argskwargsr`   rV   s     r1   openerz%Projects.build_opener.<locals>.opener  s    7+r0   r/   )rV   r`   r   s   `` r1   r   zProjects.build_opener  s    	,r0   c                    | j                         }| j                  j                         }|j                  qt	               sft
        j                  d       t        j                  t        j                  ||j                              }| j                  ||j                         y y t
        j                  d       | j                          y )Nz%Opening project from the command line)workdirz#Reopening project from last session)get_command_line_options_mainget_initial_working_directoryr`   r   loggerdebugospnormpathjoinr   working_directoryreopen_last_project)rV   cli_optionsinitial_cwdr`   s       r1   on_mainwindow_visiblezProjects.on_mainwindow_visible  s    335jj>>@*%'DE,,HH[+*=*=> !!'99 "  ( LL>?$$&r0   c                    | j                          t        | j                         | j                               }|j	                         }|j
                  }|j                  dd      }|j                  dt        j                        }|r<t        j                  d|        | j                  ||       |j                          yy)zCreate new project.)project_types	root_pathNproject_typezCreating a project at )project_type_id)r   r!   rQ   get_project_typesexec_project_datagetr   IDr   r   _create_projectclose)rV   dlgresultdatar  r  s         r1   r   zProjects.create_new_project  s     	DOO-*.*@*@*BDHH[$/	xx@LL1)=>  L IIIK r0   c                    | j                         }||v r||   } |||j                        }|j                         \  }}|s=t        j                  | j                         d|       t        j                  |d       y| j                  j                  |||       | j                  ||       yt               sGt        j                  | j                         t        d      t        d      j                  |             yy)	zCreate a new project.r  parent_pluginzProject creationT)ignore_errorsN)r   r`   Errorz2<b>{}</b> is not a registered Spyder project type!)r  _PARENT_PLUGINcreate_projectr   warningrQ   shutilrmtreesig_project_createdr   r   r   criticalr   format)	rV   r  r  packagesr  project_type_classr`   created_succesfullymessages	            r1   r  zProjects._create_project  s     ..0m+!.!?(#0??G
 ,3+A+A+C(&##OO%'97Dit< $$)))_hO9g>')$$OO%gJ  %vo6	 *r0   c                    | j                          |t               }t        | j                         t	        d      |      }t        j                  |      }| j                  |      sR|r:t        j                  | j                         t	        d      t	        d      |z         yt        j                  |      }t        j                  d|        |%| j                  |      } |||j                        }| j                  r|r&| j                  | j                  j!                          | j                  | j#                  dt%               d	
       | j'                  d      r| j)                          n~| j                  )| j+                  | j                  j-                                | j.                  j1                  | j                  j2                         | j4                  j7                          || _        || _        | j;                  |       | j#                  d| j=                                | j?                          |r1tA        jB                  |      r| jD                  j1                  |       n| jD                  j1                  |       | j4                  jG                  |       |r| jI                          |jK                         \  }}	|s&t        jL                  | j                         d|	       yy)z#Open the project located in `path`.NzOpen project)rW   captionbasedirr  z"<b>%s</b> is not a Spyder project!zOpening project located at r  last_working_dirrt   )r   visible_if_project_opencurrent_project_pathzProject open)'r   r   r   rQ   r   r   to_unicode_from_fsr   r   r  r   r   _load_project_type_classr  rM   rt   save_open_filesset_confr   rL   rf   set_project_filenamesget_open_filenamesr   r   r  rO   r   rN   add_to_recentrS   r   r   isdirr{   startrestart_consolesr   r  )
rV   r   r`   r1  save_previous_filesr   r$  r  open_successfullyr!  s
             r1   r   zProjects.open_project  sr    	<"nG't/@01.0A079D ..t4D((.(()'
>?$F
 ..t4D24&9:?!%!>!>t!D(0??G &&."t{{'>++-{{&0.2B&.  0 }}67""$ {{&**4;;+I+I+KL ##((++557LL&-#%4 ,d.J.J.LM!syy)##((1##((.4 !!#%,%9%9%;"7  1>7K !r0   c                 8   | j                   r| j                          | j                  )| j                  | j                  j	                                | j                   j
                  }| j                   j                         \  }}|s%t        j                  | j                         d|       d| _         | j                  dd       | j                          | j                  j                  |       | j                  t           j                  d       | j                  d| j                         j                                | j!                  d       | j                         j#                          | j%                          | j&                  j)                          yy)z`
        Close current project and return to a window without an active
        project
        NzProject closer'  Tr&  F)rM   r   rt   r,  r-  r  r   r   r  rQ   r+  r   r   r   r   	isVisibletoggle_viewclearr1  rO   r   )rV   r   closed_sucessfullyr!  s       r1   r   zProjects.close_project  sD   
 &&OO{{&**KK2246..88D++99; (%##OO%A +/D'MM0$7##%##((.##D)..t4 MM3//+5579U#OO##%!!#LL5 'r0   c                    | j                   r| j                          | j                   j                  }t        j                  t        j
                  z  }t        j                  | j                         t        d      t        d      j                  t        j                  |            |      }|t        j                  k(  r;	 | j                          t        j                  t        j                  |d             yyy# t         $ r[}t        j"                  | j                         t        d      t        d      j                  |t%        |                   Y d}~yd}~ww xY w)	zY
        Delete the current project without deleting the files in the directory.
        DeletezDo you really want to delete <b>{filename}</b>?<br><br><b>Note:</b> This action will only delete the project. Its files are going to be preserved on disk.)filename.spyprojectzProject ExplorerzQ<b>Unable to delete <i>{varpath}</i></b><br><br>The error message was:<br>{error})varpatherrorN)rM   r   r  r   YesNor  rQ   r   r  r   basenamer   r  r  r   EnvironmentErrorr  r   )rV   r   buttonsanswerr>  s        r1   rx   zProjects.delete_project8  s!    &&OO..88D!oo6G ((!( A  FCLL$6F7F (	O&&(MM#((4"?@ ) '  ( O((),- F "F4~e7LFMO OOs   9C? ?	E#AEE#c                 j    g | _         | j                  d| j                          | j                          y)z!Clear the list of recent projectsr*   N)r*   r+  r   r]   s    r1   r   zProjects.clear_recent_projectsT  s+    !')=)=>!r0   c                     t        j                  | j                         t        d      t        d      | j	                  d      dd      \  }}|r| j                  d|       yy)z#Change max recent projects entries.rG   z!Maximum number of recent projectsmax_recent_projects   #   N)r   getIntrQ   r   rL   r+  )rV   mrfvalids      r1   r   z#Projects.change_max_recent_projectsZ  s^     "((OOjM12MM/0
U MM/5 r0   c                     | j                   S )zGet the active project)rM   r]   s    r1   get_active_projectzProjects.get_active_projecth  s    ***r0   c                     | j                  dd      }|rR| j                  |      r@| j                         }| j                  |dd|j                         | j                          yyy)zT
        Reopen the active project when Spyder was closed last time, if any
        r'  N)defaultTF)r   r1  r2  r   )rL   r   r   r   r   load_config)rV   r'  r   s      r1   r   zProjects.reopen_last_projectl  s}      $}}-C59  -  ;
 !!!"67779K)!%$)#55	    8 !r0   c                     g }| j                   r| j                   j                         }|S | j                  r| j                  j                         }|S )z-Get the list of recent filenames of a project)rM   get_recent_filesrN   rV   recent_filess     r1   get_project_filenameszProjects.get_project_filenames  sQ    &&66GGIL    ..??ALr0   c                     | j                   rB| j                  | j                   j                        r| j                   j                  |       yyy)z,Set the list of open file names in a projectN)rM   r   r  set_recent_filesrT  s     r1   r,  zProjects.set_project_filenames  sF    ''))33==?''88F? (r0   c                 N    d}| j                   r| j                   j                  }|S )zGet path of the active projectN)rM   r  )rV   active_project_paths     r1   rS   z Projects.get_active_project_path  s)    "&&"&"="="G"G""r0   c                 :    | j                  ddt                     S )z*Get the path of the last working directoryr%  rt   )r   rP  )rL   r   r]   s    r1   get_last_working_dirzProjects.get_last_working_dir  s$    }}.:J  L 	Lr0   c                    | j                  d| j                         | j                  d| j                         j                  j	                                | j                  d| j                         j                  j                                | j                  r/| j                  d| j                         j                                yy)z
        Save configuration: opened projects & tree widget state.

        Also save whether dock widget is visible if a project is open.
        r*   expanded_statescrollbar_positionr&  N)r+  r*   rQ   rr   get_expanded_stateget_scrollbar_positionrM   r5  r]   s    r1   r   zProjects.save_config  s     	')=)=>&oo'22EEG	I*oo'22IIK	M&&MM3//+5579 'r0   c                     | j                  dd      }t        |      rd}|*| j                         j                  j	                  |       yy)z7Load configuration: opened projects & tree widget stater^  N)rL   r   rQ   rr   set_expanded_state)rV   r^  s     r1   rQ  zProjects.load_config  sH    '7> .)!N%OO((;;NK &r0   c                     | j                  dd      }|*| j                         j                  j                  |       yy)z9Restoring scrollbar position after main window is visibler_  N)rL   rQ   rr   set_scrollbar_position)rV   scrollbar_poss     r1   r   z#Projects.restore_scrollbar_position  s9    &:DA$OO((??N %r0   c                 ^    | j                         j                  | j                                y)zUpdate explorer treeN)rQ   rR   rS   r]   s    r1   r|   zProjects.update_explorer  s     ''(D(D(FGr0   c                     | j                         m| j                  d       | j                         j                  d       | j                         j                          | j                         j	                          yy)zShow the explorerNT)rQ   r6  
setVisibleraise_updater]   s    r1   rf   zProjects.show_explorer  s]    ??(T"OO((.OO$$&OO$$&	 )r0   c                 R    | j                   | j                   j                          yy)z=Restart consoles when closing, opening and switching projectsN)rs   restartr]   s    r1   r1  zProjects.restart_consoles  s!    ??&OO##% 'r0   c                     t        j                  |d      }t        j                  |      xr t        j                  |      S )z.Check if a directory is a valid Spyder projectr<  )r   r   r/  )rV   r   spy_project_dirs      r1   r   zProjects.is_valid_project  s.    ((47yy=399_#==r0   c                 0   	 | j                         }t        |      rk| j                  |      sY|rFt	        j
                  | j                         t        d      t        d      j                  |             | j                          yyy# t        $ r Y yw xY w)z!Handle an invalid active project.Nr  zw<b>{}</b> is no longer a valid Spyder project! Since it is the current active project, it will be closed automatically.)
rS   AttributeErrorr   r   r   r  rQ   r   r  r   rV   r   s     r1   r   z"Projects.is_invalid_active_project  s    	//1D :((.(()'
 5 66<fTl ""$ /   		s   B	 		BBc                     || j                   vr| j                   j                  d|       t        | j                         | j                  d      kD  r| j                   j	                  d       yy)zs
        Add an entry to recent projetcs

        We only maintain the list of the 10 most recent projects
        r   rG  N)r*   insertlenrL   pop)rV   r`   s     r1   r.  zProjects.add_to_recent  s_     $...  ''73t##$t}}5J'KK  $$R( Lr0   c                 n    d| _         | j                  r"| j                         }| j                  |       yy)z#Enable LSP workspace functionality.TN)rP   rM   rS   notify_project_openrr  s     r1   start_workspace_servicesz!Projects.start_workspace_services  s4    %)"&&//1D$$T* 'r0   c                     d| _         y)z$Disable LSP workspace functionality.FN)rP   )rV   	_languages     r1   r   z Projects.stop_workspace_services  s
    %*"r0   c                 j    ||d<   | |d<   | j                   r| j                   j                  ||       yy)z6Send request/notification/response to all LSP servers.requires_responseresponse_instanceN)ru   broadcast_notification)rV   methodparamsr~  s       r1   emit_requestzProjects.emit_request  s<    &7"#&*"#33FFC r0   c                 h    || j                   v r$| j                   |   }t        | |      } ||       yy)z#Method dispatcher for LSP requests.N)handler_registrygetattr)rV   r  r  handler_namehandlers        r1   handle_responsezProjects.handle_response  s:     T***008LdL1GFO +r0   )r  r~  c                 h    |ry|t         j                  d}|t         j                  d}||g}d|i}|S )z-Notify LSP server about a file that is moved.Nfilekindr  )r#   DELETEDCREATED)rV   src_file	dest_fileis_dirdeletion_entryaddition_entryentriesr  s           r1   
file_movedzProjects.file_moved  sS      "**
 "**

 ">2g
 r0   c                 8    |ryd|t         j                  dgi}|S )z&Notify LSP server about file creation.Nr  r  )r#   r  rV   r  r  r  s       r1   file_createdzProjects.file_created$  3    
   &.. 
 r0   c                 8    |ryd|t         j                  dgi}|S )z&Notify LSP server about file deletion.Nr  r  )r#   r  r  s       r1   file_deletedzProjects.file_deleted4  r  r0   c                 8    |ryd|t         j                  dgi}|S )z*Notify LSP server about file modification.Nr  r  )r#   CHANGEDr  s       r1   file_modifiedzProjects.file_modifiedD  r  r0   c                     || dd}|S )z2Notify LSP server about project path availability.additionfolderinstancer  r/   rV   r   r  s      r1   ry  zProjects.notify_project_openT      
 

 r0   c                     || dd}|S )z-Notify LSP server to unregister project path.deletionr  r/   r  s      r1   notify_project_closezProjects.notify_project_close_  r  r0   c                 "    |d   }dd|d   d}|S )z>Apply edits to multiple files and notify server about success.r  FzNot implementedlanguage)appliedr>  r  r/   )rV   r  editsresponses       r1   handle_workspace_editzProjects.handle_workspace_editj  s*    
 x &j)

 r0   c                    t        j                  |t               dt        dz         }t        j
                  }t        j                  |      rPt        j                         }	 |j                  |d       	 |t           j                  dt        j
                        }| t        _        | j                         }|j                  |t              }|S # t        $ r Y fw xY w# t        $ r Y Mw xY w)a  
        Load a project type class from the config project folder directly.

        Notes
        -----
        This is done directly, since using the EmptyProject would rewrite the
        value in the constructor. If the project found has not been registered
        as a valid project type, the EmptyProject type will be returned.

        Returns
        -------
        spyder.plugins.projects.api.BaseProjectType
            Loaded project type class.
        configz.inizutf-8r   r  )r   r   r   r   r   r  isfileconfigparserConfigParserread	Exceptionr
  r  r  )rV   r   fpathr  r  r  r  s          r1   r)  z!Projects._load_project_type_classy  s     +-xV9KM '//::e!..0FEG4"("3"7"7"LOO#5
 '+#..0*..M!!    s$   "C 6'C 	CC	C+*C+c                     t        |t              st        d      |j                  }|| j                  v rt        dj                  |            ||_        || j                  |<   y)aK  
        Register a new project type.

        Parameters
        ----------
        parent_plugin: spyder.plugins.api.plugins.SpyderPluginV2
            The parent plugin instance making the project type registration.
        project_type: spyder.plugins.projects.api.BaseProjectType
            Project type to register.
        z-A project type must subclass BaseProjectType!z3A project type id '{}' has already been registered!N)
issubclassr   r	   r  rU   r  r  )rV   r  r  
project_ids       r1   r   zProjects.register_project_type  sq     ,8  "4 5 5 "__
,,,  "//5vj/AC C '4#*6J'r0   c                     | j                   S )z
        Return available registered project types.

        Returns
        -------
        dict
            Project types dictionary. Keys are project type IDs and values
            are project type classes.
        )rU   r]   s    r1   r  zProjects.get_project_types  s     """r0   c                 <    | j                   j                  |       y )N)r   )rt   r   )rV   r   s     r1   r   zProjects._new_editor  s    T"r0   c                 8    | j                   j                          y re   )rt   setup_open_filesrV   _Projects__unuseds     r1   r   zProjects._setup_editor_files  s    $$&r0   c                 :    | j                   j                  |       y re   rt   set_current_project_pathrr  s     r1   r   zProjects._set_path_in_editor  s    ,,T2r0   c                 8    | j                   j                          y re   r  r  s     r1   r   zProjects._unset_path_in_editor  s    ,,.r0   c                 \    | j                   j                  |t        j                  |        y N)update_kindr  )ru   project_path_updater$   ADDITIONrr  s     r1   r   z!Projects._add_path_to_completions  *    ,,+44 	- 	
r0   c                 \    | j                   j                  |t        j                  |        y r  )ru   r  r$   DELETIONrr  s     r1   r   z&Projects._remove_path_from_completions  r  r0   c           
      n    | j                   j                  |t        j                  |      dddddd       y )N FT)rs   
run_scriptr   dirname)rV   fnames     r1   r   z Projects._run_file_in_ipyconsole  s/    ""3;;u%r5%	
r0   )NN)F)NNTTN)dr+   r,   r-   __doc__NAMECONF_SECTION	CONF_FILEREQUIRESr   r   r   r   r   OPTIONALr    WIDGET_CLASSr   strr   r  r{   r   r   rK   staticmethodr[   r^   rb   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r  r  r   r   rx   r   r   rN  r   rV  r,  rS   r\  r   rQ  r   r|   rf   r1  r   r   r.  rz  r   r  dictr  r%   r"   WORKSPACE_WATCHED_FILES_UPDATEr  r  r  r  WORKSPACE_FOLDERS_CHANGEry  r  r&   WORKSPACE_APPLY_EDITr  r)  r   r  r   r   r   r   r   r   r   __classcell__)rY   s   @r1   rG   rG   I   s   DLIH##W%;%;W^^  "H(L !c62    	D73

,  C+8 /D 0D(  3 34L 5L  6 67K 8K  0 011 214 w~~. /* w223	  4	  w556
 7
 w//0E 1E%"N&>	6D
'* 
V  :F!%< FJ7;FLP BO8"6+*G#L
9	LOH'&
>
%&	)++D 
#t_  
#sD*II$&& , *II$&	#t_ & *II$&	#t_ & *II$&	#t_ & *CC$&& *CC$&& #889*??$&& :)"V7.
##'3/


r0   rG   )Fr  r  loggingr   os.pathr   r   r  collectionsr   qtpy.compatr   qtpy.QtCorer   r   qtpy.QtWidgetsr   r   spyder.api.exceptionsr	   )spyder.api.plugin_registration.decoratorsr
   r   spyder.api.translationsr   spyder.api.pluginsr   r   spyder.config.baser   r   r   r   spyder.py3compatr   r   spyder.utilsr   spyder.utils.icon_managerr   spyder.utils.miscr   spyder.plugins.mainmenu.apir   r   spyder.plugins.projects.apir   r   r   %spyder.plugins.projects.utils.watcherr   +spyder.plugins.projects.widgets.main_widgetr    -spyder.plugins.projects.widgets.projectdialogr!   spyder.plugins.completion.apir"   r#   r$   $spyder.plugins.completion.decoratorsr%   r&   r'   	getLoggerr+   r   r)   r3   rA   rG   r/   r0   r1   <module>r     s      	   # - $ 4 1- % <J J ; ! ) , N4 4 B M GA A& &
 
		8	$' '$ $ 
 ]
# ]
 ]
r0   