AutoHotkey: Makedir and file create history

From TotalcmdWiki
Jump to navigation Jump to search
/*

This script allows you to use directories and files creation
history in the F7 and Shift-F4 dialogs respectively. History
depth is defined by the "depth" parameters under appropriate
sections in the ini-file created in the script dir.

Up/Down : scrolls history in the edit box.
Alt-Down: shows a drop-down history list under the edit box.

Note: works ONLY via keypressing!

Written by Jungle, February 2006.
Send your comments and suggestions to: jungle-80@mail.ru

*/
;
;----------
;
$+F4::
  ; create file dialog is being opened
  if WinActive("ahk_class TTOTAL_CMD")
    hist_sec = file
  else ifWinNotActive, ahk_Class TSTDTREEDLG
    hist_sec =

  Send +{F4}
Return
;
;----------
;
$F7::
  ; create dir dialog is being opened
  if WinActive("ahk_class TTOTAL_CMD")
    hist_sec = dir
  else ifWinNotActive, ahk_Class TSTDTREEDLG
    hist_sec =

  Send {F7}
Return
;
;----------
;
~Up::
  if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
    ; scroll up history in the edit box
    take_hist( -1 )

Return
;
;----------
;
~Down::
  if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
    ; scroll down history in the edit box
    take_hist( 1 )

Return
;
;----------
;
~!Down::
  if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
    ; display history drop-down list
    GoSub tc_show_history_list
Return
;
;----------
;
$Enter::
  ; if Enter key pressed in dir history list
  if WinActive("ahk_class AutoHotkeyGUI")
  {
    GoSub GuiSubmit
    Return
  }
  ; if Enter key pressed in dir creation dialog
  else if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
  {
    ControlGetFocus, fc, A
    ; if Enter was pressed on the "Cancel" button
    if ( fc = "TButton1" )
      GoSub clear_mem
    else
      GoSub write_history
  }
  Send {Enter}
Return
;
;----------
;
~LButton::
  if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
  {
    MouseGetPos, , , ,m_ctrl
    ; if Button "OK" clicked instead of Enter
    if ( m_ctrl = "TButton2" )
      GoSub write_history
    ; if Button "Cancel" clicked instead of Esc
    else if ( m_ctrl = "TButton1" )
      GoSub clear_mem
  }
Return
;
;----------
;
$Space::
  if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
  {
    ControlGetFocus, fc, A
    ; if Space was pressed on the "OK" button
    if ( fc = "TButton2" )
      GoSub write_history
    ; if Space was pressed on the "Cancel" button
    else if ( fc = "TButton1" )
      GoSub clear_mem
  }

  Send {Space}
Return
;
;----------
;
$Esc::
  ; if Escape was pressed
  if WinActive("ahk_class TSTDTREEDLG") AND ( hist_sec <> space )
    GoSub clear_mem

  Send {Esc}
Return
;
;----------
;
write_history:
  if ( dir_win_id <> space )
    Return

  ; get dir create dialog id
  WinGet, dir_win_id, ID, A
  ; and wait until dialog is closed
  SetTimer, wait_dlg_close, 100

  ; Get new dir name...
  ControlGetText, cur_text, TEdit1
  ; if empty then exit

  if ( cur_text = space )
    Return ; ...and exit if it is blank

  ; if history is not loaded, load it
  if ( item_cnt = space )
    GoSub read_hist_file

  ; if history contains new dir name, then return
  Loop, %item_cnt%
    if ( cur_text = hist_array%A_Index% )
      Return

  ; write history depth value into the ini file
  IniWrite, %hist_depth%, %A_ScriptDir%\history.ini, %hist_sec%, depth
  ; write first dir history entry into the ini file
  IniWrite, %cur_text%, %A_ScriptDir%\history.ini, %hist_sec%, item1

  ; if history count is equal to history depth,
  ; last history entry will be deleted and each
  ; entry will be replaced by the previous one
  if ( item_cnt >= hist_depth )
    cnt := hist_depth - 1
  else
    cnt := item_cnt

  pos = 2

  ; save the rest dir history back to the ini-file
  Loop, %cnt%
  {
    IniWrite, % hist_array%A_Index%, %A_ScriptDir%\history.ini, %hist_sec%, item%pos%
    pos++
  }

Return
;
;----------
;
take_hist( inc )
{
  ; ensure all variables below are global
  global

  ; if history was not loaded then try to load
  if ( item_cnt = space )
  {
    GoSub read_hist_file

    if ( item_cnt < 1 )
      Return
  }

  ; calculate history item position
  item_pos += inc

  if ( item_pos > item_cnt )
    item_pos = 1
  else if ( item_pos < 1 )
    item_pos := item_cnt

  ; place history item to the edit
  ControlSetText, TEdit1, % hist_array%item_pos%
  ; set caret position to the end
  ControlSend, TEdit1, {End}

  Return
}
;
;----------
;
tc_show_history_list:
  ; if Alt+Down pressed in the dir creation dialog
  ; build history
  if ( item_cnt = space )
    GoSub read_hist_file

  ; if history is not empty, build history listbox
  if item_cnt > 0
  {
    ; create GUI listbox... (menu using causes some problems)
    WinGetPos, w_x, w_y, , ,ahk_Class TSTDTREEDLG
    ControlGetPos, c_x, c_y, c_w, c_h, TEdit1
    c_x += w_x
    c_y += w_y + c_h
    c_w -= 2
    Gui, Margin, 0, 0
    Gui, -Caption +Border +Delimiter`n
    Gui, Add, ListBox, +AltSubmit -E0x200 w%c_w% h100 vDirChoice gHistBox, %hist_array1%
    pos = 2
    Loop, % item_cnt - 1
    {
      GuiControl, ,ListBox1, % hist_array%pos%
      pos++
    }
    ; ...and show it under the edit field
    Gui, Show, x%c_x% y%c_y%
    ; wait for GUI to become inactive
    SetTimer, WaitGuiInactive, 100
    GuiControl, Choose, ListBox1, 1
  }
Return
;
;----------
;
read_hist_file:
  ; read history depth value from the ini-file
  IniRead, hist_depth, %A_ScriptDir%\history.ini, %hist_sec%, depth, 20
  if (hist_depth = space)
    hist_depth = 20

  ; history items counter
  item_cnt = 0
  ; trying to build history array
  Loop, %hist_depth%
  {
    IniRead, item, %A_ScriptDir%\history.ini, %hist_sec%, item%A_Index%
    ; skip empty entries
    if ( item <> "ERROR" AND item <> space)
    {
      item_cnt++
      hist_array%item_cnt% = %item%
    }
  }

  if ( item_cnt > 0 )
    ; current history item position
    item_pos = 0

Return
;
;----------
;
HistBox:
  ; if not Left Mouse button pressed then return
  hk := A_ThisHotKey
  if (hk <> "~LButton")
    Return
;
;----------
;
GuiSubmit:
  ; get current selection into variable
  GuiControlGet, item_pos, ,ListBox1
  GuiControl, -AltSubmit, ListBox1
  Gui, Submit

  ; wait for dir creation dialog to become active
  WinWaitActive, ahk_class TSTDTREEDLG
  ; Set edit text to the history entry
  ControlSetText, TEdit1, %DirChoice%
  ; Set caret position to the end of text
  ControlSend, TEdit1, {End}
  ; free memory
  DirChoice =
GuiEscape:
GuiClose:
  Gui, Destroy
Return
;
;----------
;
WaitGuiInactive:
  ; if GUI is inactive then destroy it
  ifWinNotActive, ahk_class AutoHotkeyGUI
  {
    Gui, Destroy
    ; turn off timer
    SetTimer, WaitGuiInactive, Off
  }
Return
;
;----------
;
wait_dlg_close:
  ; if dir creation dialog doesn't exist
  ifWinNotExist, ahk_id %dir_win_id%
  {
    ; turn off timer
    SetTimer, wait_dlg_close, Off
    ; clear windows id variable
    dir_win_id =

    Gosub clear_mem
  }
Return
;
;----------
;
clear_mem:
  ; clear history array (free memory)
  Loop, %item_cnt%
    hist_array%A_Index% =

  ; clear other vars
  item_cnt =
  item_pos =
  hist_sec =
Return


Warning: Redefining the Enter and Space keys results in that they will not work as a terminator for hotstrings, see here: http://www.autohotkey.com/forum/viewtopic.php?t=4232



Back to AutoHotkey