Re: command entry suggestion

From: Jay <robert.jay.go....at.gmail.com>
Date: Thu, 6 May 2010 05:34:09 -0700 (PDT)

Finished, sort of.

I got the 'use_tabs = 1' feature working by adding a __newindex to
the environment's metatable.
And luckily there are no clashes between 'textadept' and 'buffer',
woot!

however there are two conflicts:
  _G.io textadept.io
  _G.keys textadept.keys

First keys, 'textadept.keys' corresponds to the 'core/keys.lua',
'_G.keys' is 'core/ext/key_commands.lua'
Second io, '_G.io' is lua's basic io functionality, 'textadept.io' is
for file management.

One possible solution would be to rename 'textadept.io' to
'textadept.file' as that name is also appropriate and has no
conflicts,
and perhaps '_G.keys' could be 'commands' or something like that. this
way there would be no conflicts (although new one may still appear in
the future)

The next step would be to polish up utils, maybe rename to something
else and have it be easily extensible by calling user scripts like
other modules do right now.

Opinions?

And here is the beta code:

----------- command_entry.lua ---------------
-- Copyright 2007-2009 Mitchell Foral mitchell<att>caladbolg.net. See
LICENSE.

local util = {}

local textadept = _G.textadept
local locale = _G.locale
local type = _G.type
local rawget = _G.rawget
local rawset = _G.rawset
local select = _G.select
local ipairs = _G.ipairs
local tostring = _G.tostring
local unpack = _G.unpack

util.printf = function(text,...)
        textadept.print(tostring(text):format(...))
end

util.appendf = function (text,...)
        buffer:append_text(tostring(text):format(...))
end

util.insertf = function (text,...)
        buffer:insert_text(buffer.current_pos, tostring(text):format(...))
end

util.shell = function(text,...)
        return
textadept.iconv(_G.io.popen(text:format(...)):read("*all"),"UTF-8",_CHARSET)
end

util = setmetatable(util,{
__index = function(e,k)
        -- most operations are buffer shortcut
        local v = buffer[k]
        if type(v) ~= "nil" then
                if type(v)=="function" then
                        v = function(...)
                                buffer[k](buffer,...)
                        end
                end
        else -- or bindings to textadept
                v = textadept[k] or rawget(_G,k) -- if nothing was found default to
global
        end
        --e[k] = v --memoize the key (don't memoize the key so newindex will
work correctly)
        return v
end,
__newindex = function(e,k,v)
        -- most operations are buffer shortcut
        local old = buffer[k]
        if type(old) ~= "nil" then
                buffer[k] = v --replace current
                return
        end
        old = textadept[k]
        if type(old) ~= "nil" then
                textadept[k] = v --replace current
                return
        end
        rawset(e,k,v)
end,
})

textadept.events.add_handler('command_entry_command',
  function(command) -- execute a Lua command
    local f, err = loadstring(command)
    if err then error(err) end
    textadept.command_entry.focus() -- toggle focus to hide
    setfenv(f,util)
        f()
  end)

textadept.events.add_handler('command_entry_keypress',
  function(code)
    local ce = textadept.command_entry
    if code == 0xff1b then -- escape
      ce.focus() -- toggle focus to hide
      return true
    elseif code == 0xff09 then -- tab
      local substring = ce.entry_text:match('[%w_.:]+$') or ''
      local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)
([%w_]*)$')
      local ret, tbl = pcall(loadstring('return ('..path..')'))
      if not ret then tbl = getfenv(0) end
      if type(tbl) ~= 'table' then return end
      local cmpls = {}
      for k in pairs(tbl) do
        if type(k) == 'string' and k:find('^'..prefix) then
          cmpls[#cmpls + 1] = k
        end
      end
      if path == 'buffer' then
        if o == ':' then
          for f in pairs(textadept.buffer_functions) do
            if f:find('^'..prefix) then cmpls[#cmpls + 1] = f end
          end
        else
          for p in pairs(textadept.buffer_properties) do
            if p:find('^'..prefix) then cmpls[#cmpls + 1] = p end
          end
        end
      end
      table.sort(cmpls)
      ce.show_completions(cmpls)
      return true
    end
  end)

----------------- END ---------------------

On Apr 30, 2:10 pm, Jay <robert.jay.go....at.gmail.com> wrote:
> Mitchell,
>
> Glad you like it :)
> Yeah the name clashes happen, just had one yesterday.
> It happened while writing this shortcut for an an easy shell command
> [ insert(shell"grep stuff log.log") ] .
>
> -----
> util.shell = function(text,...)
>         return
> textadept.iconv(_G.io.popen(text:format(...)):read("*all"),"UTF-8",_CHARSET )
> -- Here was my first name clash, between textadept.io and _G.io
> end
> ----
>
> Well right I'm dog-food'ing myself with it, and I'll probably run into
> a few more surprises soon enough,
> but it does help bring productivity with TA up.
>
> I'll try to have a functional prototype with some of the obvious
> problems solved by next week
> so others can test it out and get more feedback to polish the system
> up for general use.
>
> -Jay
>
> On Apr 30, 3:21 am, mitchell <mforal.n....at.gmail.com> wrote:
>
>
>
>
>
> > Jay,
>
> > On Apr 28, 3:46 am, Jay <robert.jay.go....at.gmail.com> wrote:
>
> > > The last one for today...
> > > as I was fixing stuff here and there today I was using the "command
> > > entry" for debug purposes.
> > > and realized how much typing was required.
> > > so I came up with an idea to bind a utility environment to the
> > > incoming command functions
>
> > > my prototype yet functional code looks like this:
>
> > > local util = setmetatable({},{__index = function(e,k)
> > >         -- most operations are buffer shortcut
> > >         local v = buffer[k]
> > >         if v then
> > >                 if type(v)=="function" then
> > >                         v = function(...)
> > >                                 buffer[k](buffer,...)
> > >                         end
> > >                 end
> > >         else -- or bindings to textadept
> > >                 v = textadept[k] or _G[k] -- if nothing was found default to global
> > >         end
> > >         e[k] = v --memoize the key
> > >         return v
> > > end})
>
> > > textadept.events.add_handler('command_entry_command',
> > >   function(command) -- execute a Lua command
> > >     local f, err = loadstring(command)
> > >     if err then error(err) end
> > >     textadept.command_entry.focus() -- toggle focus to hide
> > >     setfenv(f,util)
> > >     f()
> > >   end)
>
> > > This way the command entry allows stuff like
> > >   > insert_text(current_pos,"hello")
> > > instead of the more verbose
> > >  > buffer:insert_text(buffer.current_pos,"hello")
>
> > > another cool feature of this is that we can define util functions for
> > > the command entry like this:
>
> > > util.insertf = function (text,...)
> > >         buffer:insert_text(buffer.current_pos, tostring(text):format(...))
> > > end
>
> > > so we can do this
> > >  > insertf("current position is: %d",current_pos)
>
> > > Any suggestions about what to do with this?
>
> > I REALLY like this idea. My only concern is name clashes between
> > textadept and buffer functions. I'd also like properties to be
> > accessible too, e.g. 'use_tabs = 1' enables tabs instead of spaces.
> > How do you propose to address these things? I think this would be a
> > great addition to a future release after its polished.
>
> > Mitchell
>
> > > -Jay
>
> > > --
> > > You received this message because you are subscribed to the Google Groups "textadept" group.
> > > To post to this group, send email to textadept.at.googlegroups.com.
> > > To unsubscribe from this group, send email to textadept+unsubscribe.at.googlegroups.com.
> > > For more options, visit this group athttp://groups.google.com/group/textadept?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups "textadept" group.
> > To post to this group, send email to textadept.at.googlegroups.com.
> > To unsubscribe from this group, send email to textadept+unsubscribe.at.googlegroups.com.
> > For more options, visit this group athttp://groups.google.com/group/textadept?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups "textadept" group.
> To post to this group, send email to textadept.at.googlegroups.com.
> To unsubscribe from this group, send email to textadept+unsubscribe.at.googlegroups.com.
> For more options, visit this group athttp://groups.google.com/group/textadept?hl=en.

-- 
You received this message because you are subscribed to the Google Groups "textadept" group.
To post to this group, send email to textadept.at.googlegroups.com.
To unsubscribe from this group, send email to textadept+unsubscribe.at.googlegroups.com.
For more options, visit this group at http://groups.google.com/group/textadept?hl=en.
Received on Thu 06 May 2010 - 08:34:09 EDT

This archive was generated by hypermail 2.2.0 : Thu 08 Mar 2012 - 11:44:11 EST