Add support for autocompletion of executables in PATH

This commit is contained in:
R. Tyler Croy 2017-01-14 18:28:35 -08:00
parent bfdce8bc38
commit 859787cdbb
No known key found for this signature in database
GPG Key ID: 1426C7DC3F51E16F
8 changed files with 110 additions and 8 deletions

View File

@ -2,11 +2,12 @@
GPRBUILD:=$(shell which gprbuild)
GPRCLEAN:=$(shell which gprclean)
EXE=obj/arun
GPRFILE=arun.gpr
all: $(EXE)
$(EXE): prepare
$(GPRBUILD) -Parun.gpr -cargs:c $(shell pkg-config --cflags gio-2.0)
$(GPRBUILD) -P$(GPRFILE) -cargs:c $(shell pkg-config --cflags gio-2.0)
prepare: src/arun-resources.c
mkdir -p obj
@ -17,8 +18,11 @@ src/arun-resources.c: arun.gresource.xml arun.glade
run: all
./$(EXE)
doc:
gnatdoc -P$(GPRFILE) --no-subprojects
clean:
$(GPRCLEAN) -Parun.gpr
$(GPRCLEAN) -p$(GPRFILE)
rm -f src/arun-resources.c
.PHONY: all clean prepare run
.PHONY: all clean prepare run doc

View File

@ -2,7 +2,6 @@
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkEntryCompletion" id="commandCompletion"/>
<object class="GtkWindow" id="commandWindow">
<property name="width_request">400</property>
<property name="can_focus">False</property>
@ -39,7 +38,6 @@
<property name="primary_icon_name">edit-find-symbolic</property>
<property name="primary_icon_activatable">False</property>
<property name="primary_icon_sensitive">False</property>
<property name="placeholder_text" translatable="yes">Enter a command to run</property>
<signal name="activate" handler="commandEntry_activate_cb" swapped="no"/>
<signal name="search-changed" handler="commandEntry_search_changed_cb" swapped="no"/>
</object>

View File

@ -96,7 +96,6 @@ package body Arun.Handlers is
use Ada.Text_IO;
use Gdk.Types;
use Gdk.Types.Keysyms;
begin
if Event.Keyval = GDK_Tab then

View File

@ -22,6 +22,7 @@ with Ada.Text_IO; use Ada.Text_IO;
with Ada.Command_Line.Environment;
with Ada.Environment_Variables;
with GNAT.Directory_Operations;
with GNAT.OS_Lib;
with GNAT.String_Split;
with Interfaces.C;
@ -38,7 +39,6 @@ package body Arun.Launchers.Unix is
begin
Create (L.Path_Components, PATH, Separator, Single);
L.Initialized := True;
end Initialize;
@ -118,4 +118,42 @@ package body Arun.Launchers.Unix is
end if;
end Execute;
function Discover_Executables (L : in UnixLauncher) return Arun.String_Vectors.Vector is
use GNAT.Directory_Operations;
use GNAT.OS_Lib;
use GNAT.String_Split;
use Ada.Strings.Unbounded;
Dir : Dir_Type;
File_Name : String (1 .. MAX_FILENAME_LENGTH);
File_Index : Natural := 0;
Executables : Arun.String_Vectors.Vector;
begin
for Index in 1 .. Slice_Count (L.Path_Components) loop
declare
Path_Dir : constant String := Slice (L.Path_Components, Index);
begin
if Is_Directory (Path_Dir) then
Open (Dir, Path_Dir);
loop
Read (Dir, File_Name, File_Index);
exit when File_Index = 0;
declare
Name : constant String := File_Name (1 .. File_Index);
Full_Path : constant String := Path_Dir & "/" & Name;
begin
if Is_Executable_File (Full_Path) then
Executables.Append (To_Unbounded_String (Name));
end if;
end;
end loop;
Close (Dir);
end if;
end;
end loop;
return Executables;
end Discover_Executables;
end Arun.Launchers.Unix;

View File

@ -22,6 +22,9 @@ with Arun;
with GNAT.String_Split;
package Arun.Launchers.Unix is
MAX_FILENAME_LENGTH : constant := 255;
type UnixLauncher is new Arun.Launcher_Type with private;
procedure Initialize (L : in out UnixLauncher);
@ -40,6 +43,8 @@ package Arun.Launchers.Unix is
-- Execute a command using the given UnixLauncher with an "Argv"
-- Slice_Set assuming the first argument is the command and subsequent values
-- are arguments for that command.
function Discover_Executables (L : in UnixLauncher) return Arun.String_Vectors.Vector;
private
type UnixLauncher is new Arun.Launcher_Type with record

View File

@ -19,6 +19,7 @@
with Gtk.Widget; use Gtk.Widget;
with Ada.Text_IO;
package body Arun.View is

View File

@ -18,9 +18,14 @@
------------------------------------------------------------------------------
with Gtk.Widget; use Gtk.Widget;
with Gtk.GEntry;
with Gtk.Entry_Completion;
with Gtk.Tree_Model;
with Gtk.List_Store;
with Glib; use Glib;
with Glib.Error; use Glib.Error;
with Glib.Values;
with Gtk.Main; use Gtk.Main;
with Gtkada.Builder; use Gtkada.Builder;
@ -28,7 +33,20 @@ with Ada.Text_IO;
with Arun.Handlers;
with Arun.View;
with GNAT.OS_Lib;
with GNAT.Directory_Operations;
with Ada.Strings.Unbounded;
package body Arun is
function Compare_Strings (Left : in Ada.Strings.Unbounded.Unbounded_String;
Right : in Ada.Strings.Unbounded.Unbounded_String) return Boolean is
use Ada.Strings.Unbounded;
begin
return Left = Right;
end Compare_Strings;
procedure Main is
use Ada.Text_IO;
use Gtkada.Builder;
@ -69,8 +87,32 @@ package body Arun is
-- Connect commandEntry specific signals
declare
Command_Entry : Gtk_Widget := Builder.From_Object ("commandEntry");
use Gtk.Entry_Completion;
use Gtk.List_Store;
use Gtk.Tree_Model;
use Ada.Strings.Unbounded;
Completion_Types : constant GType_Array (1 .. 1) := (1 => GType_String);
Items : Gtk_List_Store := Gtk_List_Store_Newv (Types => Completion_Types);
Iter : Gtk_Tree_Iter;
Command_Entry : Gtk.GEntry.Gtk_Entry := Gtk.GEntry.Gtk_Entry (Builder.From_Object ("commandEntry"));
Command_Completion : aliased Gtk_Entry_Completion := Gtk_Entry_Completion_New;
Completion_String : Glib.Values.GValue;
Executables : String_Vectors.Vector := Builder.Launcher.Discover_Executables;
begin
for Element of Executables loop
Items.Append (Iter);
Glib.Values.Init_Set_String (Completion_String,
To_String (Element));
Items.Set_Value (Iter, 0, Completion_String);
end loop;
Command_Completion.Set_Model (Items.To_Interface);
Command_Completion.Set_Text_Column (Column => 0);
Command_Completion.Set_Inline_Completion (True);
Command_Completion.Set_Inline_Selection (True);
Command_Entry.Set_Completion (Completion => Command_Completion);
Command_Entry.On_Key_Release_Event (Call => Arun.Handlers.Search_KeyPress'Access,
After => False);
end;

View File

@ -18,12 +18,18 @@
------------------------------------------------------------------------------
with GNAT.String_Split;
with Ada.Containers.Vectors;
with Ada.Strings.Unbounded;
package Arun is
procedure Main;
type Launcher_Type is interface;
type Discovered_Executable_Handler is access function (L : in Launcher_Type'Class;
Name : in String;
Full_Path : in String) return Boolean;
procedure Initialize (L : in Launcher_Type'Class) is abstract;
-- Launcher_Type-specific initialization routine
@ -39,4 +45,13 @@ package Arun is
Argv : in GNAT.String_Split.Slice_Set) is abstract;
-- Spawn the Executable in place of the current process
function Compare_Strings (Left : in Ada.Strings.Unbounded.Unbounded_String;
Right : in Ada.Strings.Unbounded.Unbounded_String) return Boolean;
package String_Vectors is new Ada.Containers.Vectors (Index_Type => Natural,
Element_Type => Ada.Strings.Unbounded.Unbounded_String,
"=" => Compare_Strings);
function Discover_Executables (L : in Launcher_Type) return String_Vectors.Vector is abstract;
-- Discover executables which can be launched by the configured Launcher_Type
end Arun;